summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am7
-rw-r--r--configure.ac7
-rw-r--r--log_manager.cpp148
-rw-r--r--log_manager.hpp70
-rw-r--r--log_manager_main.cpp22
-rw-r--r--xyz.openbmc_project.Logging.Internal.Manager.cpp91
-rw-r--r--xyz/openbmc_project/Logging/Internal/Manager/server.hpp81
7 files changed, 313 insertions, 113 deletions
diff --git a/Makefile.am b/Makefile.am
index ac50cc9..f96d2cf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,6 +8,12 @@ nodist_include_HEADERS = elog-gen.hpp
bin_PROGRAMS = logging-test
logging_test_SOURCES = logging_test.cpp
+sbin_PROGRAMS = phosphor-log-manager
+phosphor_log_manager_SOURCES = \
+ xyz.openbmc_project.Logging.Internal.Manager.cpp \
+ log_manager.cpp \
+ log_manager_main.cpp
+
# Be sure to build elog-gen.hpp before compiling
BUILT_SOURCES = elog-gen.hpp
@@ -15,6 +21,7 @@ CLEANFILES=elog-gen.hpp
# systemd required for journal interfaces
logging_test_LDFLAGS = $(SYSTEMD_LIBS)
+phosphor_log_manager_LDFLAGS = $(SYSTEMD_LIBS)
ELOG_YAML ?= xyz/openbmc_project/Example/Elog.errors.yaml
ELOG_MAKO ?= elog-gen-template.mako.hpp
diff --git a/configure.ac b/configure.ac
index 7f8a446..8ed1a3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,9 @@ PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221])
AC_CHECK_HEADER(systemd/sd-journal.h, ,[AC_MSG_ERROR([Could not find \
systemd/sd-journal.h...systemd developement package required])])
+AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find \
+systemd/sd-bus.h...systemd developement package required])])
+
# Check/set gtest specific functions.
AX_PTHREAD([GTEST_CPPFLAGS="-DGTEST_HAS_PTHREAD=1"],[GTEST_CPPFLAGS="-DGTEST_HAS_PTHREAD=0"])
@@ -43,6 +46,8 @@ AS_IF([test "x$enable_oe_sdk" == "xyes"],
AC_SUBST([OESDK_TESTCASE_FLAGS], [$testcase_flags])
)
+AC_DEFINE(BUSNAME, "xyz.openbmc_project.Logging.Internal.Manager", [The DBus busname to own.])
+AC_DEFINE(OBJ, "/xyz/openbmc_project/Logging/Internal", [The DBus object path.])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile test/Makefile])
-AC_OUTPUT \ No newline at end of file
+AC_OUTPUT
diff --git a/log_manager.cpp b/log_manager.cpp
index 21e99a8..a3e49e9 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -7,65 +7,38 @@
#include <systemd/sd-bus.h>
#include <systemd/sd-journal.h>
#include "log.hpp"
+#include "log_manager.hpp"
-using namespace phosphor;
+namespace phosphor
+{
+namespace logging
+{
-/*
- * @fn commit()
- * @brief Create an error/event log based on specified id and metadata variable
- * names that includes the journal message and the metadata values.
- */
-auto commit(sd_bus_message *msg, void *userdata, sd_bus_error *error)
+void Manager::commit(uint64_t transactionId, std::string errMsg)
{
// TODO Change /tmp path to a permanent location on flash
constexpr const auto path = "/tmp/elog";
constexpr const auto msgIdStr = "_PID";
- // Read PID
- int rc = -1;
- char *msgId = nullptr;
- rc = sd_bus_message_read(msg, "s", &msgId);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to read msg id",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- return sd_bus_reply_method_return(msg, "i", rc);
- }
-
// Create log file
std::string filename{};
filename.append(path);
// TODO Create error logs in their own separate dir once permanent location
- // on flash is determined. Ex: ../msgId/1
- filename.append(msgId);
+ // on flash is determined. Ex: ../transactionId/1
std::ofstream efile;
efile.open(filename);
efile << "{" << std::endl;
- // Read metadata variables passed as array of strings and store in vector
- // TODO Read required metadata fields from header file instead
- rc = sd_bus_message_enter_container(msg, SD_BUS_TYPE_ARRAY, "s");
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to read metadata vars",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- return sd_bus_reply_method_return(msg, nullptr);
- }
- const char* metaVar = nullptr;
+ //const char* metaVar = nullptr;
std::vector<const char*> metaList;
- while ((rc = sd_bus_message_read_basic(msg, 's', &metaVar)) > 0)
- {
- metaList.push_back(metaVar);
- }
- sd_bus_message_exit_container(msg);
sd_journal *j = nullptr;
- rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+ int rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (rc < 0)
{
logging::log<logging::level::ERR>("Failed to open journal",
logging::entry("DESCRIPTION=%s", strerror(-rc)));
- return sd_bus_reply_method_return(msg, nullptr);
+ return;
}
// Read the journal from the end to get the most recent entry first.
@@ -83,12 +56,16 @@ auto commit(sd_bus_message *msg, void *userdata, sd_bus_error *error)
continue;
}
std::string result(data);
- if (result.find(msgId) == std::string::npos)
+// TODO String msgid is now an int transaction id. This piece will be
+// uncommented and reworked with the upcoming change to read the metadata
+// fields from the header file.
+#if 0
+ if (result.find(msgid) == std::string::npos)
{
// Match not found, continue to next journal entry
continue;
}
-
+#endif
// Match found, write to file
// TODO This is a draft format based on the redfish event logs written
// in json, the final openbmc format is to be determined
@@ -128,87 +105,34 @@ auto commit(sd_bus_message *msg, void *userdata, sd_bus_error *error)
efile << "}" << std::endl;
efile.close();
- return sd_bus_reply_method_return(msg, nullptr);
+ return;
}
-constexpr sdbusplus::vtable::vtable_t log_vtable[] =
+Manager::Manager(sdbusplus::bus::bus &&bus,
+ const char* busname,
+ const char* obj) :
+ details::ServerObject<details::ManagerIface>(bus, obj),
+ _bus(std::move(bus)),
+ _manager(sdbusplus::server::manager::manager(_bus, obj))
{
- sdbusplus::vtable::start(),
- sdbusplus::vtable::method("Commit", "sas", "", commit),
- sdbusplus::vtable::end()
-};
+ _bus.request_name(busname);
+}
-int main(int argc, char *argv[])
+void Manager::run() noexcept
{
- constexpr const auto dbusLogObj = "/xyz/openbmc_project/Logging";
- constexpr const auto dbusLogName = "xyz.openbmc_project.Logging";
- int rc = -1;
- sd_bus *bus = nullptr;
-
- rc = sd_bus_open_system(&bus);
- if (rc < 0)
+ while(true)
{
- logging::log<logging::level::ERR>("Failed to open system bus",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- goto cleanup;
- }
-
- rc = sd_bus_add_object_manager(bus, nullptr, dbusLogObj);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to add object mgr",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- goto cleanup;
- }
-
- rc = sd_bus_add_object_vtable(bus,
- nullptr,
- dbusLogObj,
- dbusLogName,
- log_vtable,
- nullptr);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to add vtable",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- goto cleanup;
- }
-
- rc = sd_bus_request_name(bus, dbusLogName, 0);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to acquire service name",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- }
- else
- {
- for(;;)
+ try
{
- rc = sd_bus_process(bus, nullptr);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to connect to bus",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- break;
- }
- if (rc > 0)
- {
- continue;
- }
-
- rc = sd_bus_wait(bus, (uint64_t) - 1);
- if (rc < 0)
- {
- logging::log<logging::level::ERR>("Failed to wait on bus",
- logging::entry("DESCRIPTION=%s", strerror(-rc)));
- break;
- }
+ _bus.process_discard();
+ _bus.wait();
+ }
+ catch (std::exception &e)
+ {
+ std::cerr << e.what() << std::endl;
}
}
-
-cleanup:
- sd_bus_unref(bus);
-
- return rc;
}
+} // namespace logging
+} // namepsace phosphor
diff --git a/log_manager.hpp b/log_manager.hpp
new file mode 100644
index 0000000..2b4281d
--- /dev/null
+++ b/log_manager.hpp
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <sdbusplus/server.hpp>
+#include "xyz/openbmc_project/Logging/Internal/Manager/server.hpp"
+
+namespace phosphor
+{
+namespace logging
+{
+namespace details
+{
+
+template <typename T>
+using ServerObject = typename sdbusplus::server::object::object<T>;
+
+using ManagerIface =
+ sdbusplus::xyz::openbmc_project::Logging::Internal::server::Manager;
+
+} // namespace details
+
+/** @class Manager
+ * @brief OpenBMC logging manager implementation.
+ * @details A concrete implementation for the
+ * xyz.openbmc_project.Logging.Internal.Manager DBus API.
+ */
+class Manager final :
+ public details::ServerObject<details::ManagerIface>
+{
+ public:
+ Manager() = delete;
+ Manager(const Manager&) = delete;
+ Manager& operator=(const Manager&) = delete;
+ Manager(Manager&&) = default;
+ Manager& operator=(Manager&&) = default;
+ ~Manager() = default;
+
+ /** @brief Constructor for the Log Manager object
+ * @param[in] bus - DBus bus to attach to.
+ * @param[in] busname - Name of DBus bus to own.
+ * @param[in] obj - Object path to attach to.
+ */
+ Manager(sdbusplus::bus::bus&& bus,
+ const char* busname,
+ const char* obj);
+
+ /** @brief Start processing DBus messages. */
+ void run() noexcept;
+
+ /*
+ * @fn commit()
+ * @brief sd_bus Commit method implementation callback.
+ * @details Create an error/event log based on transaction id and
+ * error message.
+ * @param[in] transactionId - Unique identifier of the journal entries
+ * to be committed.
+ * @param[in] errMsg - The error exception message associated with the
+ * error log to be committed.
+ */
+ void commit(uint64_t transactionId, std::string errMsg) override;
+
+ private:
+ /** @brief Persistent sdbusplus DBus bus connection. */
+ sdbusplus::bus::bus _bus;
+
+ /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
+ sdbusplus::server::manager::manager _manager;
+};
+
+} // namespace logging
+} // namespace phosphor
diff --git a/log_manager_main.cpp b/log_manager_main.cpp
new file mode 100644
index 0000000..21c13ae
--- /dev/null
+++ b/log_manager_main.cpp
@@ -0,0 +1,22 @@
+#include "config.h"
+#include "log_manager.hpp"
+#include <sdbusplus/bus.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <exception>
+
+int main(int argc, char *argv[])
+{
+ try {
+ auto manager = phosphor::logging::Manager(
+ sdbusplus::bus::new_system(),
+ BUSNAME,
+ OBJ);
+ manager.run();
+ exit(EXIT_SUCCESS);
+ }
+ catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ }
+ exit(EXIT_FAILURE);
+}
diff --git a/xyz.openbmc_project.Logging.Internal.Manager.cpp b/xyz.openbmc_project.Logging.Internal.Manager.cpp
new file mode 100644
index 0000000..2afdb6d
--- /dev/null
+++ b/xyz.openbmc_project.Logging.Internal.Manager.cpp
@@ -0,0 +1,91 @@
+#include <algorithm>
+#include <sdbusplus/server.hpp>
+#include <sdbusplus/exception.hpp>
+#include <xyz/openbmc_project/Logging/Internal/Manager/server.hpp>
+
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Logging
+{
+namespace Internal
+{
+namespace server
+{
+
+Manager::Manager(bus::bus& bus, const char* path)
+ : _xyz_openbmc_project_Logging_Internal_Manager_interface(
+ bus, path, _interface, _vtable, this)
+{
+}
+
+
+int Manager::_callback_Commit(
+ sd_bus_message* msg, void* context, sd_bus_error* error)
+{
+ using sdbusplus::server::binding::details::convertForMessage;
+
+ try
+ {
+ auto m = message::message(sd_bus_message_ref(msg));
+
+ uint64_t transactionId{};
+ std::string errMsg{};
+
+ m.read(transactionId, errMsg);
+
+ auto o = static_cast<Manager*>(context);
+ o->commit(transactionId, errMsg);
+
+ auto reply = m.new_method_return();
+ // No data to append on reply.
+
+ reply.method_return();
+ }
+ catch(sdbusplus::internal_exception_t& e)
+ {
+ sd_bus_error_set_const(error, e.name(), e.description());
+ return -EINVAL;
+ }
+
+ return true;
+}
+
+namespace details
+{
+namespace Manager
+{
+static const auto _param_Commit =
+ utility::tuple_to_array(message::types::type_id<
+ uint64_t, std::string>());
+static const auto _return_Commit =
+ utility::tuple_to_array(std::make_tuple('\0'));
+}
+}
+
+
+
+
+const vtable::vtable_t Manager::_vtable[] = {
+ vtable::start(),
+
+ vtable::method("Commit",
+ details::Manager::_param_Commit
+ .data(),
+ details::Manager::_return_Commit
+ .data(),
+ _callback_Commit),
+ vtable::end()
+};
+
+} // namespace server
+} // namespace Internal
+} // namespace Logging
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
diff --git a/xyz/openbmc_project/Logging/Internal/Manager/server.hpp b/xyz/openbmc_project/Logging/Internal/Manager/server.hpp
new file mode 100644
index 0000000..3bec2a9
--- /dev/null
+++ b/xyz/openbmc_project/Logging/Internal/Manager/server.hpp
@@ -0,0 +1,81 @@
+#pragma once
+#include <tuple>
+#include <systemd/sd-bus.h>
+#include <sdbusplus/server.hpp>
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Logging
+{
+namespace Internal
+{
+namespace server
+{
+
+class Manager
+{
+ public:
+ /* Define all of the basic class operations:
+ * Not allowed:
+ * - Default constructor to avoid nullptrs.
+ * - Copy operations due to internal unique_ptr.
+ * Allowed:
+ * - Move operations.
+ * - Destructor.
+ */
+ Manager() = delete;
+ Manager(const Manager&) = delete;
+ Manager& operator=(const Manager&) = delete;
+ Manager(Manager&&) = default;
+ Manager& operator=(Manager&&) = default;
+ virtual ~Manager() = default;
+
+ /** @brief Constructor to put object onto bus at a dbus path.
+ * @param[in] bus - Bus to attach to.
+ * @param[in] path - Path to attach at.
+ */
+ Manager(bus::bus& bus, const char* path);
+
+
+
+ /** @brief Implementation for Commit
+ * Write the requested error/event entry with its associated metadata fields to flash.
+ *
+ * @param[in] transactionId - The unique identifier of the journal entry(ies) to be committed.
+ * @param[in] errMsg - The error exception message associated with the error event log to be committed.
+ */
+ virtual void commit(
+ uint64_t transactionId,
+ std::string errMsg) = 0;
+
+
+
+
+ private:
+
+ /** @brief sd-bus callback for Commit
+ */
+ static int _callback_Commit(
+ sd_bus_message*, void*, sd_bus_error*);
+
+
+ static constexpr auto _interface = "xyz.openbmc_project.Logging.Internal.Manager";
+ static const vtable::vtable_t _vtable[];
+ sdbusplus::server::interface::interface
+ _xyz_openbmc_project_Logging_Internal_Manager_interface;
+
+
+};
+
+
+} // namespace server
+} // namespace Internal
+} // namespace Logging
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
OpenPOWER on IntegriCloud