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

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