Blame SOURCES/0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch

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