diff options
author | Matt Spinler <spinler@us.ibm.com> | 2020-01-22 14:55:07 -0600 |
---|---|---|
committer | Matt Spinler <spinler@us.ibm.com> | 2020-01-31 15:00:11 +0000 |
commit | 4dcd3f46599a8c702fca4b13e4370a0ec7f66ffd (patch) | |
tree | 618aebb1ccb9b5231f9c1e8d6c74658005ec6b68 /extensions/openpower-pels | |
parent | c7c3e40249fcba41b4c6b15676fc1054e6ce1049 (diff) | |
download | phosphor-logging-4dcd3f46599a8c702fca4b13e4370a0ec7f66ffd.tar.gz phosphor-logging-4dcd3f46599a8c702fca4b13e4370a0ec7f66ffd.zip |
PEL: Save process name in a UserData section
When creating a new PEL, add a UserData section that contains various
pieces of system information that will be saved in every error log.
In this first commit, just save the process name of the creator,
provided they passed in the '_PID' AdditionalData item containing their
PID.
Future commits will add other items like certain D-Bus properties.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I7139b4056e494277ff3388bfa8a00002c9c89dc1
Diffstat (limited to 'extensions/openpower-pels')
-rw-r--r-- | extensions/openpower-pels/data_interface.hpp | 23 | ||||
-rw-r--r-- | extensions/openpower-pels/pel.cpp | 63 | ||||
-rw-r--r-- | extensions/openpower-pels/pel.hpp | 12 |
3 files changed, 88 insertions, 10 deletions
diff --git a/extensions/openpower-pels/data_interface.hpp b/extensions/openpower-pels/data_interface.hpp index 88c590a..e690542 100644 --- a/extensions/openpower-pels/data_interface.hpp +++ b/extensions/openpower-pels/data_interface.hpp @@ -1,5 +1,6 @@ #pragma once +#include <filesystem> #include <phosphor-logging/log.hpp> #include <sdbusplus/bus.hpp> #include <sdbusplus/bus/match.hpp> @@ -135,6 +136,28 @@ class DataInterfaceBase return _serverFWVersion; } + /** + * @brief Returns the process name given its PID. + * + * @param[in] pid - The PID value as a string + * + * @return std::optional<std::string> - The name, or std::nullopt + */ + std::optional<std::string> getProcessName(const std::string& pid) const + { + namespace fs = std::filesystem; + + fs::path path{"/proc"}; + path /= fs::path{pid} / "exe"; + + if (fs::exists(path)) + { + return fs::read_symlink(path); + } + + return std::nullopt; + } + protected: /** * @brief Sets the host on/off state and runs any diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp index 625d177..0c05ac1 100644 --- a/extensions/openpower-pels/pel.cpp +++ b/extensions/openpower-pels/pel.cpp @@ -56,9 +56,12 @@ PEL::PEL(const message::Entry& entry, uint32_t obmcLogID, uint64_t timestamp, auto mtms = std::make_unique<FailingMTMS>(dataIface); _optionalSections.push_back(std::move(mtms)); + auto ud = util::makeSysInfoUserDataSection(additionalData, dataIface); + _optionalSections.push_back(std::move(ud)); + if (!additionalData.empty()) { - auto ud = util::makeADUserDataSection(additionalData); + ud = util::makeADUserDataSection(additionalData); // To be safe, check there isn't too much data if (size() + ud->header().size <= _maxPELSize) @@ -299,6 +302,23 @@ void PEL::toJSON() const namespace util { +std::unique_ptr<UserData> makeJSONUserDataSection(const nlohmann::json& json) +{ + auto jsonString = json.dump(); + std::vector<uint8_t> jsonData(jsonString.begin(), jsonString.end()); + + // Pad to a 4 byte boundary + while ((jsonData.size() % 4) != 0) + { + jsonData.push_back(0); + } + + return std::make_unique<UserData>( + static_cast<uint16_t>(ComponentID::phosphorLogging), + static_cast<uint8_t>(UserDataFormat::json), + static_cast<uint8_t>(UserDataFormatVersion::json), jsonData); +} + std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad) { assert(!ad.empty()); @@ -316,19 +336,42 @@ std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad) json = ad.toJSON(); } - auto jsonString = json.dump(); - std::vector<uint8_t> jsonData(jsonString.begin(), jsonString.end()); + return makeJSONUserDataSection(json); +} - // Pad to a 4 byte boundary - while ((jsonData.size() % 4) != 0) +void addProcessNameToJSON(nlohmann::json& json, + const std::optional<std::string>& pid, + const DataInterfaceBase& dataIface) +{ + std::string name = "Unknown"; + + try + { + if (pid) + { + auto n = dataIface.getProcessName(*pid); + if (n) + { + name = *n; + } + } + } + catch (std::exception& e) { - jsonData.push_back(0); } - return std::make_unique<UserData>( - static_cast<uint16_t>(ComponentID::phosphorLogging), - static_cast<uint8_t>(UserDataFormat::json), - static_cast<uint8_t>(UserDataFormatVersion::json), jsonData); + json["Process Name"] = std::move(name); +} + +std::unique_ptr<UserData> + makeSysInfoUserDataSection(const AdditionalData& ad, + const DataInterfaceBase& dataIface) +{ + nlohmann::json json; + + addProcessNameToJSON(json, ad.getValue("_PID"), dataIface); + + return makeJSONUserDataSection(json); } } // namespace util diff --git a/extensions/openpower-pels/pel.hpp b/extensions/openpower-pels/pel.hpp index 24e5e56..5f14354 100644 --- a/extensions/openpower-pels/pel.hpp +++ b/extensions/openpower-pels/pel.hpp @@ -344,6 +344,18 @@ namespace util */ std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad); +/** + * @brief Create a UserData section containing various useful pieces + * of system information as a JSON string. + * + * @param[in] ad - The AdditionalData contents + * @param[in] dataIface - The data interface object + * + * @return std::unique_ptr<UserData> - The section + */ +std::unique_ptr<UserData> + makeSysInfoUserDataSection(const AdditionalData& ad, + const DataInterfaceBase& dataIface); } // namespace util } // namespace pels |