|
|
8e8941 |
From 185ec4397e61ad00dd68c841e15eaa8629eb9514 Mon Sep 17 00:00:00 2001
|
|
|
8e8941 |
From: Coly Li <colyli@suse.de>
|
|
|
8e8941 |
Date: Sat, 11 Apr 2020 00:24:46 +0800
|
|
|
8e8941 |
Subject: [RHEL7.9 PATCH 71/77] Monitor: improve check_one_sharer() for
|
|
|
8e8941 |
checking duplicated process
|
|
|
8e8941 |
|
|
|
8e8941 |
When running mdadm monitor with scan mode, only one autorebuild process
|
|
|
8e8941 |
is allowed. check_one_sharer() checks duplicated process by following
|
|
|
8e8941 |
steps,
|
|
|
8e8941 |
1) Read autorebuild.pid file,
|
|
|
8e8941 |
- if file does not exist, no duplicated process, go to 3).
|
|
|
8e8941 |
- if file exists, continue to next step.
|
|
|
8e8941 |
2) Read pid number from autorebuild.pid file, then check procfs pid
|
|
|
8e8941 |
directory /proc/<PID>,
|
|
|
8e8941 |
- if the directory does not exist, no duplicated process, go to 3)
|
|
|
8e8941 |
- if the directory exists, print error message for duplicated process
|
|
|
8e8941 |
and exit this mdadm.
|
|
|
8e8941 |
3) Write current pid into autorebuild.pid file, continue to monitor in
|
|
|
8e8941 |
scan mode.
|
|
|
8e8941 |
|
|
|
8e8941 |
The problem for the above step 2) is, if after system reboots and
|
|
|
8e8941 |
another different process happens to have exact same pid number which
|
|
|
8e8941 |
autorebuild.pid file records, check_one_sharer() will treat it as a
|
|
|
8e8941 |
duplicated mdadm process and returns error with message "Only one
|
|
|
8e8941 |
autorebuild process allowed in scan mode, aborting".
|
|
|
8e8941 |
|
|
|
8e8941 |
This patch tries to fix the above same-pid-but-different-process issue
|
|
|
8e8941 |
by one more step to check the process command name,
|
|
|
8e8941 |
1) Read autorebuild.pid file
|
|
|
8e8941 |
- if file does not exist, no duplicated process, go to 4).
|
|
|
8e8941 |
- if file exists, continue to next step.
|
|
|
8e8941 |
2) Read pid number from autorebuild.pid file, then check procfs file
|
|
|
8e8941 |
comm with the specific pid directory /proc/<PID>/comm
|
|
|
8e8941 |
- if the file does not exit, it means the directory /proc/<PID> does
|
|
|
8e8941 |
not exist, go to 4)
|
|
|
8e8941 |
- if the file exits, continue next step
|
|
|
8e8941 |
3) Read process command name from /proc/<PIC>/comm, compare the command
|
|
|
8e8941 |
name with "mdadm" process name,
|
|
|
8e8941 |
- if not equal, no duplicated process, goto 4)
|
|
|
8e8941 |
- if strings are equal, print error message for duplicated process
|
|
|
8e8941 |
and exit this mdadm.
|
|
|
8e8941 |
4) Write current pid into autorebuild.pid file, continue to monitor in
|
|
|
8e8941 |
scan mode.
|
|
|
8e8941 |
|
|
|
8e8941 |
Now check_one_sharer() returns error for duplicated process only when
|
|
|
8e8941 |
the recorded pid from autorebuild.pid exists, and the process has exact
|
|
|
8e8941 |
same command name as "mdadm".
|
|
|
8e8941 |
|
|
|
8e8941 |
Reported-by: Shinkichi Yamazaki <shinkichi.yamazaki@suse.com>
|
|
|
8e8941 |
Signed-off-by: Coly Li <colyli@suse.de>
|
|
|
8e8941 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
8e8941 |
---
|
|
|
8e8941 |
Monitor.c | 32 ++++++++++++++++++++------------
|
|
|
8e8941 |
1 file changed, 20 insertions(+), 12 deletions(-)
|
|
|
8e8941 |
|
|
|
8e8941 |
diff --git a/Monitor.c b/Monitor.c
|
|
|
8e8941 |
index b527165..2d6b3b9 100644
|
|
|
8e8941 |
--- a/Monitor.c
|
|
|
8e8941 |
+++ b/Monitor.c
|
|
|
8e8941 |
@@ -301,26 +301,34 @@ static int make_daemon(char *pidfile)
|
|
|
8e8941 |
|
|
|
8e8941 |
static int check_one_sharer(int scan)
|
|
|
8e8941 |
{
|
|
|
8e8941 |
- int pid, rv;
|
|
|
8e8941 |
+ int pid;
|
|
|
8e8941 |
+ FILE *comm_fp;
|
|
|
8e8941 |
FILE *fp;
|
|
|
8e8941 |
- char dir[20];
|
|
|
8e8941 |
+ char comm_path[100];
|
|
|
8e8941 |
char path[100];
|
|
|
8e8941 |
- struct stat buf;
|
|
|
8e8941 |
+ char comm[20];
|
|
|
8e8941 |
+
|
|
|
8e8941 |
sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
|
|
|
8e8941 |
fp = fopen(path, "r");
|
|
|
8e8941 |
if (fp) {
|
|
|
8e8941 |
if (fscanf(fp, "%d", &pid) != 1)
|
|
|
8e8941 |
pid = -1;
|
|
|
8e8941 |
- sprintf(dir, "/proc/%d", pid);
|
|
|
8e8941 |
- rv = stat(dir, &buf;;
|
|
|
8e8941 |
- if (rv != -1) {
|
|
|
8e8941 |
- if (scan) {
|
|
|
8e8941 |
- pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
|
|
|
8e8941 |
- fclose(fp);
|
|
|
8e8941 |
- return 1;
|
|
|
8e8941 |
- } else {
|
|
|
8e8941 |
- pr_err("Warning: One autorebuild process already running.\n");
|
|
|
8e8941 |
+ snprintf(comm_path, sizeof(comm_path),
|
|
|
8e8941 |
+ "/proc/%d/comm", pid);
|
|
|
8e8941 |
+ comm_fp = fopen(comm_path, "r");
|
|
|
8e8941 |
+ if (comm_fp) {
|
|
|
8e8941 |
+ if (fscanf(comm_fp, "%s", comm) &&
|
|
|
8e8941 |
+ strncmp(basename(comm), Name, strlen(Name)) == 0) {
|
|
|
8e8941 |
+ if (scan) {
|
|
|
8e8941 |
+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
|
|
|
8e8941 |
+ fclose(comm_fp);
|
|
|
8e8941 |
+ fclose(fp);
|
|
|
8e8941 |
+ return 1;
|
|
|
8e8941 |
+ } else {
|
|
|
8e8941 |
+ pr_err("Warning: One autorebuild process already running.\n");
|
|
|
8e8941 |
+ }
|
|
|
8e8941 |
}
|
|
|
8e8941 |
+ fclose(comm_fp);
|
|
|
8e8941 |
}
|
|
|
8e8941 |
fclose(fp);
|
|
|
8e8941 |
}
|
|
|
8e8941 |
--
|
|
|
8e8941 |
2.7.5
|
|
|
8e8941 |
|