1 #include "config.h" 2 3 #include "dump_manager_system.hpp" 4 5 #include "dump_utils.hpp" 6 #include "op_dump_consts.hpp" 7 #include "system_dump_entry.hpp" 8 #include "xyz/openbmc_project/Common/error.hpp" 9 10 #include <phosphor-logging/elog-errors.hpp> 11 #include <phosphor-logging/elog.hpp> 12 #include <phosphor-logging/lg2.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 // Get the timestamp 27 uint64_t timeStamp = 28 std::chrono::duration_cast<std::chrono::microseconds>( 29 std::chrono::system_clock::now().time_since_epoch()) 30 .count(); 31 32 // System dump can get created due to a fault in server 33 // or by request from user. A system dump by fault is 34 // first reported here, but for a user requested dump an 35 // entry will be created first with invalid source id. 36 // Since there can be only one system dump creation at a time, 37 // if there is an entry with invalid sourceId update that. 38 for (auto& entry : entries) 39 { 40 openpower::dump::system::Entry* sysEntry = 41 dynamic_cast<openpower::dump::system::Entry*>(entry.second.get()); 42 if (sysEntry->sourceDumpId() == INVALID_SOURCE_ID) 43 { 44 sysEntry->update(timeStamp, size, dumpId); 45 return; 46 } 47 } 48 49 // Get the id 50 auto id = lastEntryId + 1; 51 auto idString = std::to_string(id); 52 auto objPath = std::filesystem::path(baseEntryPath) / idString; 53 54 // TODO: Get the originator Id, Type from the persisted file. 55 // For now replacing it with null 56 try 57 { 58 entries.insert(std::make_pair( 59 id, std::make_unique<system::Entry>( 60 bus, objPath.c_str(), id, timeStamp, size, dumpId, 61 phosphor::dump::OperationStatus::Completed, std::string(), 62 originatorTypes::Internal, *this))); 63 } 64 catch (const std::invalid_argument& e) 65 { 66 lg2::error( 67 "Error in creating system dump entry, errormsg: {ERROR}, " 68 "OBJECTPATH: {OBJECT_PATH}, ID: {ID}, TIMESTAMP: {TIMESTAMP}, " 69 "SIZE: {SIZE}, SOURCEID: {SOURCE_ID}", 70 "ERROR", e, "OBJECT_PATH", objPath, "ID", id, "TIMESTAMP", 71 timeStamp, "SIZE", size, "SOURCE_ID", dumpId); 72 report<InternalFailure>(); 73 return; 74 } 75 lastEntryId++; 76 return; 77 } 78 79 sdbusplus::message::object_path 80 Manager::createDump(phosphor::dump::DumpCreateParams params) 81 { 82 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 83 constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1"; 84 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 85 constexpr auto DIAG_MOD_TARGET = "obmc-host-crash@0.target"; 86 87 if (params.size() > CREATE_DUMP_MAX_PARAMS) 88 { 89 lg2::warning( 90 "System dump accepts not more than 2 additional parameters"); 91 } 92 93 using NotAllowed = 94 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 95 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 96 97 // Allow creating system dump only when the host is up. 98 if (!phosphor::dump::isHostRunning()) 99 { 100 elog<NotAllowed>( 101 Reason("System dump can be initiated only when the host is up")); 102 return std::string(); 103 } 104 105 // Get the originator id and type from params 106 std::string originatorId; 107 originatorTypes originatorType; 108 109 phosphor::dump::extractOriginatorProperties(params, originatorId, 110 originatorType); 111 112 auto b = sdbusplus::bus::new_default(); 113 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH, 114 SYSTEMD_INTERFACE, "StartUnit"); 115 method.append(DIAG_MOD_TARGET); // unit to activate 116 method.append("replace"); 117 bus.call_noreply(method); 118 119 auto id = lastEntryId + 1; 120 auto idString = std::to_string(id); 121 auto objPath = std::filesystem::path(baseEntryPath) / idString; 122 uint64_t timeStamp = 123 std::chrono::duration_cast<std::chrono::microseconds>( 124 std::chrono::system_clock::now().time_since_epoch()) 125 .count(); 126 127 try 128 { 129 entries.insert(std::make_pair( 130 id, std::make_unique<system::Entry>( 131 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 132 phosphor::dump::OperationStatus::InProgress, originatorId, 133 originatorType, *this))); 134 } 135 catch (const std::invalid_argument& e) 136 { 137 lg2::error("Error in creating system dump entry, errormsg: {ERROR}, " 138 "OBJECTPATH: {OBJECT_PATH}, ID: {ID}", 139 "ERROR", e, "OBJECT_PATH", objPath, "ID", id); 140 elog<InternalFailure>(); 141 return std::string(); 142 } 143 lastEntryId++; 144 return objPath.string(); 145 } 146 147 } // namespace system 148 } // namespace dump 149 } // namespace openpower 150