1 #include "ffdc_file.hpp"
2
3 #include <errno.h> // for errno
4 #include <fcntl.h> // for open()
5 #include <string.h> // for strerror()
6 #include <sys/stat.h> // for open()
7 #include <sys/types.h> // for open()
8
9 #include <phosphor-logging/lg2.hpp>
10
11 #include <stdexcept>
12 #include <string>
13
14 namespace watchdog
15 {
16 namespace dump
17 {
18
FFDCFile(const json & calloutDataObject)19 FFDCFile::FFDCFile(const json& calloutDataObject) :
20 calloutData(calloutDataObject.dump())
21 {
22 prepareFFDCFile();
23 }
24
~FFDCFile()25 FFDCFile::~FFDCFile()
26 {
27 // Close file descriptor. Does nothing if descriptor was already closed.
28 if (descriptor.close() == -1)
29 {
30 lg2::error("Unable to close FFDC file: errormsg({ERRORMSG})",
31 "ERRORMSG", strerror(errno));
32 }
33
34 // Delete temporary file. Does nothing if file was already deleted.
35 tempFile.remove();
36 }
37
prepareFFDCFile()38 void FFDCFile::prepareFFDCFile()
39 {
40 // Open the temporary file for both reading and writing
41 int fd = open(tempFile.getPath().c_str(), O_RDWR);
42 if (fd == -1)
43 {
44 throw std::runtime_error{
45 std::string{"Unable to open FFDC file: "} + strerror(errno)};
46 }
47
48 ssize_t rc = write(fd, calloutData.c_str(), calloutData.size());
49
50 if (rc == -1)
51 {
52 lg2::error("Failed to write callout info in file({FILE}), "
53 "errorno({ERRNO}), errormsg({ERRORMSG})",
54 "FILE", tempFile.getPath(), "ERRNO", errno, "ERRORMSG",
55 strerror(errno));
56
57 throw std::runtime_error("Failed to write phalPELCallouts info");
58 }
59 else if (rc != static_cast<ssize_t>(calloutData.size()))
60 {
61 lg2::warning("Could not write all callout info in file({FILE}), "
62 "written byte({WRITTEN}), total byte({TOTAL})",
63 "FILE", tempFile.getPath(), "WRITTEN", rc, "TOTAL",
64 calloutData.size());
65 }
66
67 int retCode = lseek(fd, 0, SEEK_SET);
68
69 if (retCode == -1)
70 {
71 lg2::error("Failed to seek file position to the beginning in "
72 "file({FILE}), errorno({ERRNO}), errormsg({ERRORMSG})",
73 "FILE", tempFile.getPath(), "ERRNO", errno, "ERRORMSG",
74 strerror(errno));
75
76 throw std::runtime_error(
77 "Failed to seek file position to the beginning of the file");
78 }
79
80 // Store file descriptor in FileDescriptor object
81 descriptor.set(fd);
82 }
83
84 } // namespace dump
85 } // namespace watchdog
86