Collect ramoops data into BMC dump
- Add ramoops file monitor and support to enable ramoops data
collection for kernel dump.
- Systemd will collect ramoops data and write it into
/var/lib/systemd/pstore when a system kernel oops/panics.
- Today, need to grab everything in that directory, put it in a dump
and then delete everything in that directory.
Tested:
- Simulate a kernel panic by creating similar data in the expected
location.
`dmesg > /var/lib/systemd/pstore/dmesg1.txt`
`dmesg > /var/lib/systemd/pstore/dmesg2.txt`
`dmesg > /var/lib/systemd/pstore/dmesg3.txt`
`dmesg > /var/lib/systemd/pstore/dmesg4.txt`
tar -tvf obmcdump_1_248.tar.xz:
drwxr-xr-x 0/0 0 1970-01-01 00:01:32 obmcdump_1_248/
-rw-r--r-- 0/0 21239 1970-01-01 00:01:32 obmcdump_1_248/dmesg1.txt
-rw-r--r-- 0/0 21239 1970-01-01 00:01:32 obmcdump_1_248/dmesg2.txt
-rw-r--r-- 0/0 21239 1970-01-01 00:01:32 obmcdump_1_248/dmesg3.txt
-rw-r--r-- 0/0 21239 1970-01-01 00:01:32 obmcdump_1_248/dmesg4.txt
-rw-r--r-- 0/0 162 1970-01-01 00:01:32 obmcdump_1_248/dreport.log
-rw-r--r-- 0/0 294 1970-01-01 00:01:31 obmcdump_1_248/os-release
-rw-r--r-- 0/0 278 1970-01-01 00:01:31 obmcdump_1_248/summary.log
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I05bca408f4dcc2b62350104a0c5f757d740dde22
diff --git a/dump_manager_bmc.hpp b/dump_manager_bmc.hpp
index 7a94889..604012b 100644
--- a/dump_manager_bmc.hpp
+++ b/dump_manager_bmc.hpp
@@ -37,7 +37,8 @@
{Type::ApplicationCored, "core"},
{Type::UserRequested, "user"},
{Type::InternalFailure, "elog"},
- {Type::Checkstop, "checkstop"}};
+ {Type::Checkstop, "checkstop"},
+ {Type::Ramoops, "ramoops"}};
/** @class Manager
* @brief OpenBMC Dump manager implementation.
diff --git a/meson.build b/meson.build
index e1b06b7..fcb3004 100644
--- a/meson.build
+++ b/meson.build
@@ -62,6 +62,8 @@
)
conf_data.set_quoted('BMC_DUMP_PATH', get_option('BMC_DUMP_PATH'),
description : 'Directory where bmc dumps are placed')
+conf_data.set_quoted('SYSTEMD_PSTORE_PATH', get_option('SYSTEMD_PSTORE_PATH'),
+ description : 'Path to the systemd pstore directory')
conf_data.set('BMC_DUMP_MAX_SIZE', get_option('BMC_DUMP_MAX_SIZE'),
description : 'Maximum size of one bmc dump in kilo bytes'
)
@@ -163,6 +165,22 @@
phosphor_dump_monitor_incdir = []
+phosphor_ramoops_monitor_sources = [
+ 'ramoops_manager.cpp',
+ 'ramoops_manager_main.cpp',
+ 'watch.cpp'
+ ]
+
+phosphor_ramoops_monitor_dependency = [
+ phosphor_dbus_interfaces,
+ phosphor_logging,
+ cppfs
+ ]
+
+phosphor_ramoops_monitor_install = true
+
+phosphor_ramoops_monitor_incdir = []
+
executables = [[ 'phosphor-dump-manager',
phosphor_dump_manager_sources,
phosphor_dump_manager_dependency,
@@ -174,6 +192,12 @@
phosphor_dump_monitor_dependency,
phosphor_dump_monitor_install,
phosphor_dump_monitor_incdir
+ ],
+ [ 'phosphor-ramoops-monitor',
+ phosphor_ramoops_monitor_sources,
+ phosphor_ramoops_monitor_dependency,
+ phosphor_ramoops_monitor_install,
+ phosphor_ramoops_monitor_incdir
]
]
diff --git a/meson_options.txt b/meson_options.txt
index de4a7ee..93c8fc4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -63,6 +63,11 @@
description : 'Directory where bmc dumps are placed'
)
+option('SYSTEMD_PSTORE_PATH', type : 'string',
+ value : '/var/lib/systemd/pstore/',
+ description : 'Path to the systemd pstore directory'
+)
+
option('BMC_DUMP_MAX_SIZE', type : 'integer',
value : 200,
description : 'Maximum size of one bmc dump in kilo bytes'
diff --git a/ramoops_manager.cpp b/ramoops_manager.cpp
new file mode 100644
index 0000000..a9f15c3
--- /dev/null
+++ b/ramoops_manager.cpp
@@ -0,0 +1,75 @@
+#include "config.h"
+
+#include "ramoops_manager.hpp"
+
+#include <sdbusplus/exception.hpp>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace ramoops
+{
+
+Manager::Manager(const std::string& filePath)
+{
+ std::vector<std::string> files;
+ files.push_back(filePath);
+
+ createHelper(files);
+}
+
+void Manager::createHelper(const std::vector<std::string>& files)
+{
+ if (files.empty())
+ {
+ return;
+ }
+
+ constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+ constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
+ constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+ constexpr auto IFACE_INTERNAL("xyz.openbmc_project.Dump.Internal.Create");
+ constexpr auto RAMOOPS =
+ "xyz.openbmc_project.Dump.Internal.Create.Type.Ramoops";
+
+ auto b = sdbusplus::bus::new_default();
+ auto mapper = b.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
+ MAPPER_INTERFACE, "GetObject");
+ mapper.append(OBJ_INTERNAL, std::set<std::string>({IFACE_INTERNAL}));
+
+ auto mapperResponseMsg = b.call(mapper);
+ if (mapperResponseMsg.is_method_error())
+ {
+ log<level::ERR>("Error in mapper call");
+ return;
+ }
+
+ std::map<std::string, std::set<std::string>> mapperResponse;
+ try
+ {
+ mapperResponseMsg.read(mapperResponse);
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ log<level::ERR>(
+ "Failed to parse dump create message", entry("ERROR=%s", e.what()),
+ entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
+ return;
+ }
+ if (mapperResponse.empty())
+ {
+ log<level::ERR>("Error reading mapper response");
+ return;
+ }
+
+ const auto& host = mapperResponse.cbegin()->first;
+ auto m =
+ b.new_method_call(host.c_str(), OBJ_INTERNAL, IFACE_INTERNAL, "Create");
+ m.append(RAMOOPS, files);
+ b.call_noreply(m);
+}
+
+} // namespace ramoops
+} // namespace dump
+} // namespace phosphor
diff --git a/ramoops_manager.hpp b/ramoops_manager.hpp
new file mode 100644
index 0000000..7982bce
--- /dev/null
+++ b/ramoops_manager.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "config.h"
+
+#include <phosphor-logging/log.hpp>
+
+#include <filesystem>
+#include <string>
+#include <vector>
+
+namespace fs = std::filesystem;
+using namespace phosphor::logging;
+
+namespace phosphor
+{
+namespace dump
+{
+namespace ramoops
+{
+
+/** @class Manager
+ * @brief OpenBMC Core manager implementation.
+ */
+class Manager
+{
+ public:
+ Manager() = delete;
+ Manager(const Manager&) = default;
+ Manager& operator=(const Manager&) = delete;
+ Manager(Manager&&) = delete;
+ Manager& operator=(Manager&&) = delete;
+ virtual ~Manager() = default;
+
+ /** @brief Constructor to create ramoops
+ * @param[in] filePath - Path where the ramoops are stored.
+ */
+ Manager(const std::string& filePath);
+
+ private:
+ /** @brief Helper function for initiating dump request using
+ * D-bus internal create interface.
+ * @param [in] files - ramoops files list
+ */
+ void createHelper(const std::vector<std::string>& files);
+};
+
+} // namespace ramoops
+} // namespace dump
+} // namespace phosphor
diff --git a/ramoops_manager_main.cpp b/ramoops_manager_main.cpp
new file mode 100644
index 0000000..6a06386
--- /dev/null
+++ b/ramoops_manager_main.cpp
@@ -0,0 +1,20 @@
+#include "config.h"
+
+#include "ramoops_manager.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+
+int main()
+{
+ fs::path filePath(SYSTEMD_PSTORE_PATH);
+ if (!fs::exists(filePath))
+ {
+ log<level::ERR>("Pstore file path is not exists",
+ entry("FILE_PATH = %s", SYSTEMD_PSTORE_PATH));
+ return EXIT_FAILURE;
+ }
+
+ phosphor::dump::ramoops::Manager manager(SYSTEMD_PSTORE_PATH);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/dreport.d/dreport b/tools/dreport.d/dreport
index d831191..3009b80 100755
--- a/tools/dreport.d/dreport
+++ b/tools/dreport.d/dreport
@@ -44,6 +44,7 @@
declare -rx TYPE_CORE="core"
declare -rx TYPE_ELOG="elog"
declare -rx TYPE_CHECKSTOP="checkstop"
+declare -rx TYPE_RAMOOPS="ramoops"
declare -rx SUMMARY_LOG="summary.log"
declare -rx DREPORT_LOG="dreport.log"
declare -rx TMP_DIR="/tmp"
@@ -91,6 +92,9 @@
log_summary "Core: $optional_path"
set_core_pid
;;
+ $TYPE_RAMOOPS)
+ log_summary "Ramoops: $optional_path"
+ ;;
$TYPE_ELOG)
log_summary "ELOG: $optional_path"
elog_id=$(basename "$optional_path")
@@ -198,6 +202,7 @@
if [[ ! ($dump_type = $TYPE_USER || \
$dump_type = $TYPE_CORE || \
$dump_type = $TYPE_ELOG || \
+ $dump_type = $TYPE_RAMOOPS || \
$dump_type = $TYPE_CHECKSTOP) ]]; then
log_error "Invalid -type, Only summary log is available"
dump_type=$SUMMARY_DUMP
diff --git a/tools/dreport.d/plugins.d/osrelease b/tools/dreport.d/plugins.d/osrelease
index 7cf9a43..00cb22c 100644
--- a/tools/dreport.d/plugins.d/osrelease
+++ b/tools/dreport.d/plugins.d/osrelease
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# config: 1234 1
+# config: 12345 1
# @brief: Collect OS release information.
#
diff --git a/tools/dreport.d/plugins.d/ramoops b/tools/dreport.d/plugins.d/ramoops
new file mode 100644
index 0000000..66324f0
--- /dev/null
+++ b/tools/dreport.d/plugins.d/ramoops
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# config: 5 1
+# @brief: Move the ramoops data file to the dreport packaging.
+#
+
+. $DREPORT_INCLUDE/functions
+
+desc="Ramoops file"
+
+for path in ${optional_path}/*
+do
+ if [ -f $path ]; then
+ # Remove the file from path after successful copy
+ if add_copy_file "$path" "$desc"; then
+ rm "$path"
+ fi
+ fi
+done
diff --git a/tools/dreport.d/sample.conf b/tools/dreport.d/sample.conf
index 45f5e59..9490d05 100644
--- a/tools/dreport.d/sample.conf
+++ b/tools/dreport.d/sample.conf
@@ -9,3 +9,4 @@
2: user
3: elog
4: checkstop
+5: ramoops
diff --git a/xyz/openbmc_project/Dump/Internal/Create.interface.yaml b/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
index ddb405f..1f4ee4f 100644
--- a/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
+++ b/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
@@ -37,5 +37,8 @@
- name: Checkstop
description: >
Dump triggered due to Checkstop type error commit.
+ - name: Ramoops
+ description: >
+ Dump triggered due to Ramoops type error commit.
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4