libmultipath: coalesce_paths: trigger uevent if nothing done
authorMartin Wilck <mwilck@suse.de>
Tue, 28 Feb 2017 16:23:24 +0000 (17:23 +0100)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 23 Mar 2017 08:25:29 +0000 (09:25 +0100)
The previous patches skip RELOAD actions if there's nothing
to be done. I found a corner case where this may lead to imporperly
initialized device nodes (in my case a by-label link hadn't been
reset to the partition on the multipath device by udev).
Triggering an extra "change" event on the device fixes
this situation.

Signed-off-by: Martin Wilck <mwilck@suse.de>
libmultipath/configure.c

index 025947a..d955455 100644 (file)
@@ -411,6 +411,18 @@ get_udev_for_mpp(const struct multipath *mpp)
        return udd;
 }
 
+static void
+trigger_udev_change(const struct multipath *mpp)
+{
+       static const char change[] = "change";
+       struct udev_device *udd = get_udev_for_mpp(mpp);
+       if (!udd)
+               return;
+       condlog(3, "triggering %s uevent for %s", change, mpp->alias);
+       sysfs_attr_set_value(udd, "uevent", change, sizeof(change)-1);
+       udev_device_unref(udd);
+}
+
 static int
 is_mpp_known_to_udev(const struct multipath *mpp)
 {
@@ -949,6 +961,18 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
                if (r == DOMAP_DRY)
                        continue;
 
+               if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING &&
+                   force_reload == FORCE_RELOAD_WEAK)
+                       /*
+                        * First time we're called, and no changes applied.
+                        * domap() was a noop. But we can't be sure that
+                        * udev has already finished setting up this device
+                        * (udev in initrd may have been shut down while
+                        * processing this device or its children).
+                        * Trigger a change event, just in case.
+                        */
+                       trigger_udev_change(find_mp_by_wwid(curmp, mpp->wwid));
+
                conf = get_multipath_config();
                allow_queueing = conf->allow_queueing;
                put_multipath_config(conf);