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

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