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

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