1 #include "config.h" 2 3 #include "dump_manager_system.hpp" 4 5 #include "dump_utils.hpp" 6 #include "system_dump_entry.hpp" 7 #include "xyz/openbmc_project/Common/error.hpp" 8 9 #include <fmt/core.h> 10 11 #include <phosphor-logging/elog-errors.hpp> 12 #include <phosphor-logging/elog.hpp> 13 14 namespace openpower 15 { 16 namespace dump 17 { 18 namespace system 19 { 20 21 using namespace phosphor::logging; 22 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 23 24 void Manager::notify(uint32_t dumpId, uint64_t size) 25 { 26 27 // Get the timestamp 28 std::time_t timeStamp = std::time(nullptr); 29 30 // System dump can get created due to a fault in server 31 // or by request from user. A system dump by fault is 32 // first reported here, but for a user requested dump an 33 // entry will be created first with invalid source id. 34 // Since there can be only one system dump creation at a time, 35 // if there is an entry with invalid sourceId update that. 36 for (auto& entry : entries) 37 { 38 openpower::dump::system::Entry* sysEntry = 39 dynamic_cast<openpower::dump::system::Entry*>(entry.second.get()); 40 if (sysEntry->sourceDumpId() == INVALID_SOURCE_ID) 41 { 42 sysEntry->update(timeStamp, size, dumpId); 43 return; 44 } 45 } 46 47 // Get the id 48 auto id = lastEntryId + 1; 49 auto idString = std::to_string(id); 50 auto objPath = std::filesystem::path(baseEntryPath) / idString; 51 52 try 53 { 54 entries.insert(std::make_pair( 55 id, std::make_unique<system::Entry>( 56 bus, objPath.c_str(), id, timeStamp, size, dumpId, 57 phosphor::dump::OperationStatus::Completed, *this))); 58 } 59 catch (const std::invalid_argument& e) 60 { 61 log<level::ERR>( 62 fmt::format( 63 "Error in creating system dump entry, errormsg({}), " 64 "OBJECTPATH({}), ID({}), TIMESTAMP({}),SIZE({}), SOURCEID({})", 65 e.what(), objPath.c_str(), id, timeStamp, size, dumpId) 66 .c_str()); 67 report<InternalFailure>(); 68 return; 69 } 70 lastEntryId++; 71 return; 72 } 73 74 sdbusplus::message::object_path 75 Manager::createDump(phosphor::dump::DumpCreateParams params) 76 { 77 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 78 constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1"; 79 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 80 constexpr auto DIAG_MOD_TARGET = "obmc-host-crash@0.target"; 81 82 if (!params.empty()) 83 { 84 log<level::WARNING>("System dump accepts no additional parameters"); 85 } 86 87 using NotAllowed = 88 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 89 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 90 91 // Allow creating system dump only when the host is up. 92 if (!phosphor::dump::isHostRunning()) 93 { 94 elog<NotAllowed>( 95 Reason("System dump can be initiated only when the host is up")); 96 return std::string(); 97 } 98 99 auto b = sdbusplus::bus::new_default(); 100 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH, 101 SYSTEMD_INTERFACE, "StartUnit"); 102 method.append(DIAG_MOD_TARGET); // unit to activate 103 method.append("replace"); 104 bus.call_noreply(method); 105 106 auto id = lastEntryId + 1; 107 auto idString = std::to_string(id); 108 auto objPath = std::filesystem::path(baseEntryPath) / idString; 109 std::time_t timeStamp = std::time(nullptr); 110 111 try 112 { 113 entries.insert(std::make_pair( 114 id, std::make_unique<system::Entry>( 115 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 116 phosphor::dump::OperationStatus::InProgress, *this))); 117 } 118 catch (const std::invalid_argument& e) 119 { 120 log<level::ERR>( 121 fmt::format("Error in creating system dump entry, errormsg({}), " 122 "OBJECTPATH({}), ID({})", 123 e.what(), objPath.c_str(), id) 124 .c_str()); 125 elog<InternalFailure>(); 126 return std::string(); 127 } 128 lastEntryId++; 129 return objPath.string(); 130 } 131 132 } // namespace system 133 } // namespace dump 134 } // namespace openpower 135