代码拉取完成,页面将自动刷新
同步操作将从 src-anolis-os/rasdaemon 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 07c3c72d18e5c7da2109b5afa918966733039f13 Mon Sep 17 00:00:00 2001
From: Bixuan Cui <cuibixuan@linux.alibaba.com>
Date: Sun, 5 Jun 2022 02:10:24 +0800
Subject: [PATCH] rasdaemon: Add notification support when page goes offline for Memory Corrected Error
When the page goes offline, it may affect the user's processes.
The user needs to do some special actions (such as restarting the
process) before or after going offline.
So add page-ce-offline-pre-notice and page-ce-offline-post-notice
to env file of rasdaemon for notifying the user when doing page
offline.
Signed-off-by: Bixuan Cui <cuibixuan@linux.alibaba.com>
---
Makefile.am | 2 +-
misc/notices/page-ce-offline-post-notice | 17 +++++
misc/notices/page-ce-offline-pre-notice | 17 +++++
misc/rasdaemon.env | 4 ++
misc/rasdaemon.spec.in | 3 +
ras-page-isolation.c | 90 ++++++++++++++++++++++++
6 files changed, 132 insertions(+), 1 deletion(-)
create mode 100755 misc/notices/page-ce-offline-post-notice
create mode 100755 misc/notices/page-ce-offline-pre-notice
diff --git a/Makefile.am b/Makefile.am
index de76301..701b120 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS=-I m4
SUBDIRS = libtrace util man
-SYSTEMD_SERVICES_IN = misc/rasdaemon.service.in misc/ras-mc-ctl.service.in misc/rasdaemon.env
+SYSTEMD_SERVICES_IN = misc/rasdaemon.service.in misc/ras-mc-ctl.service.in misc/rasdaemon.env misc/notices
SYSTEMD_SERVICES = $(SYSTEMD_SERVICES_IN:.service.in=.service)
EXTRA_DIST = $(SYSTEMD_SERVICES_IN)
diff --git a/misc/notices/page-ce-offline-post-notice b/misc/notices/page-ce-offline-post-notice
new file mode 100755
index 0000000..d78b1b0
--- /dev/null
+++ b/misc/notices/page-ce-offline-post-notice
@@ -0,0 +1,17 @@
+#!/bin/sh
+# This shell script can be executed by rasdaemon after a page goes offline.
+
+cd `dirname $0`
+
+[ -x ./page-ce-offline-post-notice.local ] && . ./page-ce-offline-post-notice.local $1
+
+if [ -d page-ce-offline-post-notice.extern ]
+then
+ ls page-ce-offline-post-notice.extern |
+ while read item
+ do
+ [ -x ./page-ce-offline-post-notice.extern/$item ] && . ./page-ce-offline-post-notice.extern/$item $1
+ done
+fi
+
+exit 0
diff --git a/misc/notices/page-ce-offline-pre-notice b/misc/notices/page-ce-offline-pre-notice
new file mode 100755
index 0000000..d1038a3
--- /dev/null
+++ b/misc/notices/page-ce-offline-pre-notice
@@ -0,0 +1,17 @@
+#!/bin/sh
+# This shell script can be executed by rasdaemon before a page goes offline.
+
+cd `dirname $0`
+
+[ -x ./page-ce-offline-pre-notice.local ] && . ./page-ce-offline-pre-notice.local $1
+
+if [ -d page-ce-offline-pre-notice.extern ]
+then
+ ls page-ce-offline-pre-notice.extern |
+ while read item
+ do
+ [ -x ./page-ce-offline-pre-notice.extern/$item ] && . ./page-ce-offline-pre-notice.extern/$item $1
+ done
+fi
+
+exit 0
diff --git a/misc/rasdaemon.env b/misc/rasdaemon.env
index 12fd766..713875a 100644
--- a/misc/rasdaemon.env
+++ b/misc/rasdaemon.env
@@ -27,3 +27,7 @@ PAGE_CE_THRESHOLD="50"
# soft-then-hard First try to soft offline, then try hard offlining.
# Note: default offline choice is "soft".
PAGE_CE_ACTION="soft"
+
+# Notices script when doing memory offline
+PAGE_CE_OFFLINE_PRE_NOTICE="page-ce-offline-pre-notice"
+PAGE_CE_OFFLINE_POST_NOTICE="page-ce-offline-post-notice"
diff --git a/misc/rasdaemon.spec.in b/misc/rasdaemon.spec.in
index eff9794..f690575 100644
--- a/misc/rasdaemon.spec.in
+++ b/misc/rasdaemon.spec.in
@@ -45,6 +45,8 @@ make install DESTDIR=%{buildroot}
install -D -p -m 0644 misc/rasdaemon.env %{buildroot}%{_sysconfdir}/sysconfig/%{name}
install -D -p -m 0644 misc/rasdaemon.service %{buildroot}/%{_unitdir}/rasdaemon.service
install -D -p -m 0644 misc/ras-mc-ctl.service %{buildroot}%{_unitdir}/ras-mc-ctl.service
+install -d %{buildroot}%{_sysconfdir}/rasdaemon_notices/
+install -D -p -m 0755 misc/notices/* %{buildroot}%{_sysconfdir}/rasdaemon_notices/
rm INSTALL %{buildroot}/usr/include/*.h
%files
@@ -56,6 +58,7 @@ rm INSTALL %{buildroot}/usr/include/*.h
%{_sharedstatedir}/rasdaemon
%{_sysconfdir}/ras/dimm_labels.d
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
+%config(noreplace) %{_sysconfdir}/rasdaemon_notices/*
%changelog
diff --git a/ras-page-isolation.c b/ras-page-isolation.c
index 50e4406..f4f3bc1 100644
--- a/ras-page-isolation.c
+++ b/ras-page-isolation.c
@@ -17,9 +17,13 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "ras-logger.h"
#include "ras-page-isolation.h"
+#define MAX_PATH_LEN 64
#define PARSED_ENV_LEN 50
static const struct config threshold_units[] = {
{ "m", 1000 },
@@ -73,6 +77,8 @@ static const char *page_state[] = {
static enum otype offline = OFFLINE_SOFT;
static struct rb_root page_records;
+static char pre_notice[MAX_PATH_LEN];
+static char post_notice[MAX_PATH_LEN];
static void page_offline_init(void)
{
@@ -202,16 +208,94 @@ static void page_isolation_init(void)
threshold_string, cycle_string);
}
+static void page_notice_init(void)
+{
+ char *notice_root = "/etc/rasdaemon_notices";
+ char *pre_re = getenv("PAGE_CE_OFFLINE_PRE_NOTICE");
+ char *post_re = getenv("PAGE_CE_OFFLINE_POST_NOTICE");
+
+ if (offline <= OFFLINE_ACCOUNT)
+ return;
+
+ snprintf(pre_notice, sizeof(pre_notice), "%s/%s", notice_root, pre_re);
+ if (access(pre_notice, R_OK|X_OK) < 0)
+ log(TERM, LOG_ERR, "cannot access page notice '%s'\n", pre_notice);
+
+ snprintf(post_notice, sizeof(post_notice), "%s/%s", notice_root, post_re);
+ if (access(post_notice, R_OK|X_OK) < 0)
+ log(TERM, LOG_ERR, "cannot access page notice '%s'\n", post_notice);
+}
+
void ras_page_account_init(void)
{
page_offline_init();
page_isolation_init();
+ page_notice_init();
+}
+
+static void finish_child(pid_t child, int status)
+{
+ if (WIFEXITED(status) && WEXITSTATUS(status)) {
+ log(TERM, LOG_INFO, "notice exited with status %d\n", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ log(TERM, LOG_INFO,"notice died with signal %s\n", strsignal(WTERMSIG(status)));
+ }
+
+ return;
+}
+
+static void __run_notice(char *argv[], char **env)
+{
+ pid_t child;
+ int status;
+
+ child = fork();
+ if (child < 0) {
+ log(TERM, LOG_ERR, "Cannot create process for offline notice");
+ return;
+ }
+ if (child == 0) {
+ execve(argv[0], argv, env);
+ _exit(127);
+ }
+ else {
+ waitpid(child, &status, 0);
+ finish_child(child, status);
+ }
+}
+
+static void run_notice(char *argv[])
+{
+ int MAX_ENV = 20;
+ char *env[MAX_ENV];
+ int ei = 0;
+ int i;
+
+ asprintf(&env[ei++], "PATH=%s", getenv("PATH") ?: "/sbin:/usr/sbin:/bin:/usr/bin");
+ env[ei] = NULL;
+ assert(ei < MAX_ENV);
+
+ __run_notice(argv, env);
+
+ for (i = 0; i < ei; i++)
+ free(env[i]);
}
static int do_page_offline(unsigned long long addr, enum otype type)
{
FILE *offline_file;
int err;
+ char *args;
+ char *argv[] = {
+ NULL,
+ NULL,
+ NULL,
+ };
+
+ asprintf(&args, "%llu", addr);
+ argv[0] = (char*)&pre_notice;
+ argv[1] = args;
+ run_notice(argv);
offline_file = fopen(kernel_offline[type], "w");
if (!offline_file)
@@ -221,6 +305,11 @@ static int do_page_offline(unsigned long long addr, enum otype type)
err = ferror(offline_file) ? -1 : 0;
fclose(offline_file);
+ argv[0] = (char*)&post_notice;
+ run_notice(argv);
+
+ free(args);
+
return err;
}
@@ -329,4 +418,5 @@ void ras_record_page_error(unsigned long long addr, unsigned count, time_t time)
pr->start = time;
page_record(pr, count, time);
}
+
}
--
2.27.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。