]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
rasdaemon: add mem_fail_event trigger
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 16 Jul 2024 05:05:32 +0000 (05:05 +0000)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 16 Jul 2024 05:44:10 +0000 (07:44 +0200)
This event is somewhat similar to mc_event, except that this one
occurs on ARM platforms and the fields are different.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
contrib/mem_fail_trigger.sh [new file with mode: 0755]
ras-events.c
ras-memory-failure-handler.c
ras-memory-failure-handler.h

diff --git a/contrib/mem_fail_trigger.sh b/contrib/mem_fail_trigger.sh
new file mode 100755 (executable)
index 0000000..a3ac362
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+#  This shell script can be executed by rasdaemon in daemon mode when a
+#  memory_failure_event is occured, environment variables include all
+#  information reported by tracepoint.
+#
+
+echo TIMESTAMP: $TIMESTAMP
+echo PFN: $PFN
+echo PAGE_TYPE: $PAGE_TYPE
+echo ACTION_RESULT: $ACTION_RESULT
+
+exit 0
index 3c778e8f6d9b0e392d7dc5a95696b6f935d91d4a..2b4130bc76c086798332f4febfe079c948eb6fad 100644 (file)
@@ -64,6 +64,7 @@ extern char *choices_disable;
 
 static const struct event_trigger event_triggers[] = {
        { "mc_event", &mc_event_trigger_setup },
+       { "memory_failure_event", &mem_fail_event_trigger_setup },
 };
 
 static int get_debugfs_dir(char *tracing_dir, size_t len)
index a5acc085b15b6d42553db8888a06d79e7eacb0f2..562796147b363d434f12c9baefdac2f8ce621a5d 100644 (file)
  * GNU General Public License for more details.
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "ras-record.h"
+
 #include "ras-logger.h"
-#include "ras-report.h"
 #include "ras-memory-failure-handler.h"
+#include "ras-record.h"
+#include "ras-report.h"
+#include "trigger.h"
 
 /* Memory failure - various types of pages */
 enum mf_action_page_type {
@@ -90,6 +93,59 @@ static const struct {
        { MF_RECOVERED, "Recovered" },
 };
 
+#define MAX_ENV 6
+static const char *mf_trigger = NULL;
+
+void mem_fail_event_trigger_setup(void)
+{
+       const char *trigger;
+
+       trigger = getenv("MEM_FAIL_TRIGGER");
+       if (trigger && strcmp(trigger, "")) {
+               mf_trigger = trigger_check(trigger);
+
+               if (!mf_trigger) {
+                       log(ALL, LOG_ERR,
+                           "Cannot access memory_fail_event trigger `%s`\n",
+                           trigger);
+               } else {
+                       log(ALL, LOG_INFO,
+                           "Setup memory_fail_event trigger `%s`\n",
+                           trigger);
+               }
+       }
+}
+
+static void run_mf_trigger(struct ras_mf_event *ev)
+{
+       char *env[MAX_ENV];
+       int ei = 0;
+       int i;
+
+       if (!mf_trigger)
+               return;
+
+       if (asprintf(&env[ei++], "PATH=%s", getenv("PATH") ?: "/sbin:/usr/sbin:/bin:/usr/bin") < 0)
+               goto free;
+       if (asprintf(&env[ei++], "TIMESTAMP=%s", ev->timestamp) < 0)
+               goto free;
+       if (asprintf(&env[ei++], "PFN=%s", ev->pfn) < 0)
+               goto free;
+       if (asprintf(&env[ei++], "PAGE_TYPE=%s", ev->page_type) < 0)
+               goto free;
+       if (asprintf(&env[ei++], "ACTION_RESULT=%s", ev->action_result) < 0)
+               goto free;
+
+       env[ei] = NULL;
+       assert(ei < MAX_ENV);
+
+       run_trigger(mf_trigger, NULL, env, "memory_fail_event");
+
+free:
+       for (i = 0; i < ei; i++)
+               free(env[i]);
+}
+
 static const char *get_page_type(int page_type)
 {
        unsigned int i;
@@ -168,6 +224,7 @@ int ras_memory_failure_event_handler(struct trace_seq *s,
        /* Report event to ABRT */
        ras_report_mf_event(ras, &ev);
 #endif
+       run_mf_trigger(&ev);
 
        return 0;
 }
index a28ca24d962b8527c3cd02b9170f512bc452f214..7fbfd337a883c770c2f422c778663d7c08423e73 100644 (file)
@@ -18,6 +18,7 @@
 #include "ras-events.h"
 #include <traceevent/event-parse.h>
 
+void mem_fail_event_trigger_setup(void);
 int ras_memory_failure_event_handler(struct trace_seq *s,
                                     struct tep_record *record,
                                     struct tep_event *event, void *context);