diff mbox

[26/33] libmultipath: reload map if not known to udev

Message ID 20170228162329.14517-27-mwilck@suse.com (mailing list archive)
State Superseded, archived
Delegated to: Mike Snitzer
Headers show

Commit Message

Martin Wilck Feb. 28, 2017, 4:23 p.m. UTC
From: Martin Wilck <mwilck@suse.de>

The previous changes skip map reload if the existing kernel
state appears correct. Sometimes, boot time race conditions
may cause a device to be correctly set up in the kernel but
not in udev. Check this condition, and reload map in this case.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---
 libmultipath/configure.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
diff mbox

Patch

diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index fb5a5a92..b400bb96 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -39,6 +39,7 @@ 
 #include "util.h"
 #include "uxsock.h"
 #include "wwids.h"
+#include "sysfs.h"
 
 /* group paths in pg by host adapter
  */
@@ -390,6 +391,35 @@  pgcmp (struct multipath * mpp, struct multipath * cmpp)
 	return r;
 }
 
+static struct udev_device *
+get_udev_for_mpp(const struct multipath *mpp)
+{
+	dev_t devnum;
+	struct udev_device *udd;
+
+	if (!mpp || !mpp->dmi) {
+		condlog(1, "%s called with empty mpp", __func__);
+		return NULL;
+	}
+
+	devnum = makedev(mpp->dmi->major, mpp->dmi->minor);
+	udd = udev_device_new_from_devnum(udev, 'b', devnum);
+	if (!udd) {
+		condlog(1, "failed to get udev device for %s", mpp->alias);
+		return NULL;
+	}
+	return udd;
+}
+
+static int
+is_mpp_known_to_udev(const struct multipath *mpp)
+{
+	struct udev_device *udd = get_udev_for_mpp(mpp);
+	int ret = (udd != NULL);
+	udev_device_unref(udd);
+	return ret;
+}
+
 static void
 select_action (struct multipath * mpp, vector curmp, int force_reload)
 {
@@ -529,6 +559,12 @@  select_action (struct multipath * mpp, vector curmp, int force_reload)
 			mpp->alias);
 		return;
 	}
+	if (!is_mpp_known_to_udev(cmpp)) {
+		mpp->action = ACT_RELOAD;
+		condlog(3, "%s: set ACT_RELOAD (udev device not initialized)",
+			mpp->alias);
+		return;
+	}
 	mpp->action = ACT_NOTHING;
 	condlog(3, "%s: set ACT_NOTHING (map unchanged)",
 		mpp->alias);