Blame SOURCES/0029-BZ-1700451-check-on-multipathd-without-starting-it.patch

b7ef27
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b7ef27
From: Benjamin Marzinski <bmarzins@redhat.com>
b7ef27
Date: Thu, 18 Apr 2019 12:49:46 -0500
b7ef27
Subject: [PATCH] BZ 1700451: check on multipathd without starting it
b7ef27
b7ef27
When "multipath -u" is run, it checks if multipathd is running.
b7ef27
Currently it does this by trying to connect to the mutipathd socket.
b7ef27
This can cause problems during boot.  The multipathd.socket systemd unit
b7ef27
file will cause "multipath -u" to wait until multipathd has been started
b7ef27
before continuing.  If there is a lot of activity on the system,
b7ef27
multipathd may not start up immediately, causing block device
b7ef27
initialization to be delayed, potentially until after systemd times
b7ef27
waiting for the device.  To avoid this, multipath now checks if
b7ef27
multipathd is running by reading /run/multipathd.pid and checking the
b7ef27
/proc/<pid>/comm to verify that multipathd is really running with this
b7ef27
pid. This avoids forcing "multipath -u" to wait on multipathd starting
b7ef27
up.
b7ef27
b7ef27
As an alternative to this patch, multipath could simply switch the order
b7ef27
of the calls to systemd_service_enabled() and mpath_connect(). This would
b7ef27
make multipath only try to connect with multipathd if it wasn't enabled in
b7ef27
systemd, so that it wouldn't autostart.
b7ef27
b7ef27
Another alternative is to do away with multipathd.socket. Since multipathd
b7ef27
needs to always be running in order to get uevents, there isn't much value
b7ef27
in having it autoactivate when it gets an interactive command.
b7ef27
b7ef27
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
b7ef27
---
b7ef27
 multipath/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++-----
b7ef27
 1 file changed, 54 insertions(+), 6 deletions(-)
b7ef27
b7ef27
diff --git a/multipath/main.c b/multipath/main.c
b7ef27
index e7771c0..632ce4d 100644
b7ef27
--- a/multipath/main.c
b7ef27
+++ b/multipath/main.c
b7ef27
@@ -852,6 +852,58 @@ out:
b7ef27
 	return r;
b7ef27
 }
b7ef27
 
b7ef27
+int is_multipathd_running(void)
b7ef27
+{
b7ef27
+	FILE *f = NULL;
b7ef27
+	char buf[16];
b7ef27
+	char path[PATH_MAX];
b7ef27
+	int pid;
b7ef27
+	char *end;
b7ef27
+
b7ef27
+	f = fopen(DEFAULT_PIDFILE, "r");
b7ef27
+	if (!f) {
b7ef27
+		if (errno != ENOENT)
b7ef27
+			condlog(4, "can't open " DEFAULT_PIDFILE ": %s",
b7ef27
+				strerror(errno));
b7ef27
+		return 0;
b7ef27
+	}
b7ef27
+	if (!fgets(buf, sizeof(buf), f)) {
b7ef27
+		if (ferror(f))
b7ef27
+			condlog(4, "read of " DEFAULT_PIDFILE " failed: %s",
b7ef27
+				strerror(errno));
b7ef27
+		fclose(f);
b7ef27
+		return 0;
b7ef27
+	}
b7ef27
+	fclose(f);
b7ef27
+	errno = 0;
b7ef27
+	strchop(buf);
b7ef27
+	pid = strtol(buf, &end, 10);
b7ef27
+	if (errno != 0 || pid <= 0 || *end != '\0') {
b7ef27
+		condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'",
b7ef27
+			buf);
b7ef27
+		return 0;
b7ef27
+	}
b7ef27
+	snprintf(path, sizeof(path), "/proc/%d/comm", pid);
b7ef27
+	f = fopen(path, "r");
b7ef27
+	if (!f) {
b7ef27
+		if (errno != ENOENT)
b7ef27
+			condlog(4, "can't open %s: %s", path, strerror(errno));
b7ef27
+		return 0;
b7ef27
+	}
b7ef27
+	if (!fgets(buf, sizeof(buf), f)) {
b7ef27
+		if (ferror(f))
b7ef27
+			condlog(4, "read of %s failed: %s", path,
b7ef27
+				strerror(errno));
b7ef27
+		fclose(f);
b7ef27
+		return 0;
b7ef27
+	}
b7ef27
+	fclose(f);
b7ef27
+	strchop(buf);
b7ef27
+	if (strcmp(buf, "multipathd") != 0)
b7ef27
+		return 0;
b7ef27
+	return 1;
b7ef27
+}
b7ef27
+
b7ef27
 int
b7ef27
 main (int argc, char *argv[])
b7ef27
 {
b7ef27
@@ -1034,17 +1086,13 @@ main (int argc, char *argv[])
b7ef27
 	}
b7ef27
 	if (cmd == CMD_VALID_PATH &&
b7ef27
 	    dev_type == DEV_UEVENT) {
b7ef27
-		int fd;
b7ef27
-
b7ef27
-		fd = mpath_connect();
b7ef27
-		if (fd == -1) {
b7ef27
+		if (!is_multipathd_running()) {
b7ef27
 			condlog(3, "%s: daemon is not running", dev);
b7ef27
 			if (!systemd_service_enabled(dev)) {
b7ef27
 				r = print_cmd_valid(RTVL_NO, NULL, conf);
b7ef27
 				goto out;
b7ef27
 			}
b7ef27
-		} else
b7ef27
-			mpath_disconnect(fd);
b7ef27
+		}
b7ef27
 	}
b7ef27
 
b7ef27
 	if (cmd == CMD_REMOVE_WWID && !dev) {
b7ef27
-- 
b7ef27
2.17.2
b7ef27