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