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