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