dcavalca / rpms / mdadm

Forked from rpms/mdadm 3 years ago
Clone

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

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