diff --git a/SOURCES/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch b/SOURCES/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch new file mode 100644 index 0000000..40b4f0e --- /dev/null +++ b/SOURCES/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 Jan 2022 14:45:38 -0600 +Subject: [PATCH] libmultipath: make helper function to trigger path uevents + +Pull the code that checks if a path needs to trigger a uevent, and +triggers, out of trigger_paths_udev_change() and into a new function, +trigger_path_udev_change(). This function will be used separately by +a future patch. No functional changes. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 79 +++++++++++++++++++++------------------- + libmultipath/configure.h | 1 + + 2 files changed, 43 insertions(+), 37 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 9c8d3e34..9a9890f5 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -545,11 +545,8 @@ unref: + } + + void +-trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) ++trigger_path_udev_change(struct path *pp, bool is_mpath) + { +- struct pathgroup *pgp; +- struct path *pp; +- int i, j; + /* + * If a path changes from multipath to non-multipath, we must + * synthesize an artificial "add" event, otherwise the LVM2 rules +@@ -557,6 +554,45 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + * irritate ourselves with an "add", so use "change". + */ + const char *action = is_mpath ? "change" : "add"; ++ const char *env; ++ ++ if (!pp->udev) ++ return; ++ /* ++ * Paths that are already classified as multipath ++ * members don't need another uevent. ++ */ ++ env = udev_device_get_property_value( ++ pp->udev, "DM_MULTIPATH_DEVICE_PATH"); ++ ++ if (is_mpath && env != NULL && !strcmp(env, "1")) { ++ /* ++ * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", ++ * path is in "maybe" state and timer is running ++ * Send uevent now (see multipath.rules). ++ */ ++ env = udev_device_get_property_value( ++ pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); ++ if (env == NULL || !strcmp(env, "0")) ++ return; ++ } else if (!is_mpath && ++ (env == NULL || !strcmp(env, "0"))) ++ return; ++ ++ condlog(3, "triggering %s uevent for %s (is %smultipath member)", ++ action, pp->dev, is_mpath ? "" : "no "); ++ sysfs_attr_set_value(pp->udev, "uevent", ++ action, strlen(action)); ++ trigger_partitions_udev_change(pp->udev, action, ++ strlen(action)); ++} ++ ++void ++trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) ++{ ++ struct pathgroup *pgp; ++ struct path *pp; ++ int i, j; + + if (!mpp || !mpp->pg) + return; +@@ -564,39 +600,8 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + vector_foreach_slot (mpp->pg, pgp, i) { + if (!pgp->paths) + continue; +- vector_foreach_slot(pgp->paths, pp, j) { +- const char *env; +- +- if (!pp->udev) +- continue; +- /* +- * Paths that are already classified as multipath +- * members don't need another uevent. +- */ +- env = udev_device_get_property_value( +- pp->udev, "DM_MULTIPATH_DEVICE_PATH"); +- +- if (is_mpath && env != NULL && !strcmp(env, "1")) { +- /* +- * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", +- * path is in "maybe" state and timer is running +- * Send uevent now (see multipath.rules). +- */ +- env = udev_device_get_property_value( +- pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); +- if (env == NULL || !strcmp(env, "0")) +- continue; +- } else if (!is_mpath && +- (env == NULL || !strcmp(env, "0"))) +- continue; +- +- condlog(3, "triggering %s uevent for %s (is %smultipath member)", +- action, pp->dev, is_mpath ? "" : "no "); +- sysfs_attr_set_value(pp->udev, "uevent", +- action, strlen(action)); +- trigger_partitions_udev_change(pp->udev, action, +- strlen(action)); +- } ++ vector_foreach_slot(pgp->paths, pp, j) ++ trigger_path_udev_change(pp, is_mpath); + } + + mpp->needs_paths_uevent = 0; +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 8a266d31..5cf08d45 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -56,6 +56,7 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type, + vector pathvec, char **wwid); + int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon); + struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); ++void trigger_path_udev_change(struct path *pp, bool is_mpath); + void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); + void trigger_partitions_udev_change(struct udev_device *dev, const char *action, + int len); diff --git a/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch b/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch new file mode 100644 index 0000000..3a8b2a3 --- /dev/null +++ b/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 Jan 2022 16:46:18 -0600 +Subject: [PATCH] multipathd: trigger udev change on path addition + +When a multipath device is created for the first time, there is a window +where some path devices way be added to the multipath device, but never +claimed in udev. This can allow other device owners, like lvm, to think +they can use the device. + +When a multipath device is first created, all the existing paths that +are not claimed by multipath have a uevent triggered so that they can +get claimed. After that, multipath assumes all future paths added to the +multipath device will have been claimed by multipath, since the device's +WWID is now in the wwids file. This doesn't work for any paths that +have already been processed by the multipath.rules udev rules before +the multipath device was created. + +To close this window, when path device is added, and a matching +multipath device already exists, multipathd now checks if the device is +claimed by multipath, and if not, triggers a uevent to claim it. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index e2b9d546..f4b79882 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1005,6 +1005,8 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + free_path(pp); + return 1; + } ++ if (mpp) ++ trigger_path_udev_change(pp, true); + if (mpp && mpp->wait_for_udev && + (pathcount(mpp, PATH_UP) > 0 || + (pathcount(mpp, PATH_GHOST) > 0 && diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 57f7000..1af50cb 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.8.4 -Release: 20%{?dist} +Release: 21%{?dist} License: GPLv2 Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -98,6 +98,8 @@ Patch00084: 0084-libmultipath-split-set_int-to-enable-reuse.patch Patch00085: 0085-libmultipath-cleanup-invalid-config-handling.patch Patch00086: 0086-libmultipath-don-t-return-error-on-invalid-values.patch Patch00087: 0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch +Patch00088: 0088-libmultipath-make-helper-function-to-trigger-path-ue.patch +Patch00089: 0089-multipathd-trigger-udev-change-on-path-addition.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -299,6 +301,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 18 2022 Benjamin Marzinski 0.8.4-21 +- Add 0088-libmultipath-make-helper-function-to-trigger-path-ue.patch +- Add 0089-multipathd-trigger-udev-change-on-path-addition.patch +- Resolves: bz #1862032 + * Thu Nov 18 2021 Benjamin Marzinski 0.8.4-20 - Add 0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch - Add 0080-libmultipath-print-the-correct-file-when-parsing-fai.patch