Skip to content

Commit

Permalink
multipathd: trigger uevents for blacklisted paths in reconfigure
Browse files Browse the repository at this point in the history
If multipathd has already configured maps, and the user changes the
blacklist or other parameters that cause currently multipathed
devices to be skipped, and then runs "multipathd reconfigure"
or restarts multipathd, multipathd flushes the maps in question,
but doesn't trigger uevents for the now-blacklisted paths.

This is because the blacklisted paths are removed from the discovered
maps internally when update_pathvec_from_dm() is called through
map_discovery() and update_multipath_table(); when later
trigger_paths_udev_change() is called from coalesce_maps(), the
map contains no paths for which an uevent could be triggered.

The map_discovery() code flow is special, because we will call
coalesce_paths() afterwards anyway and reconstruct the mpvec. Unlike the
regular code flow, we don't want the maps to be "corrected" in this
case, because the maps discovered here aren't going to be reloaded.
We just want update_pathvec_from_dm() to populate the pathvec.

Therefore add a new flag DI_DISCOVERY, which is only set when
update_multipath_table() is called from map_discovery(), and if
this flag is set, keep PATHINFO_SKIPPED paths in the map's table in
update_pathvec_from_dm(). Later on, the paths will still be visible
in the old mpp (ompp) in coalesce_maps(), and uevents will be
triggered for them to release them to systemd.

We can't always do this for PATHINFO_SKIPPED, because in some cases
paths may be accepted in a map first and SKIPPED later (for example if
the WWID wasn't yet available at startup). Therefore the special
case for DI_DISCOVERY is necessary.

Signed-off-by: Martin Wilck <mwilck@suse.com>
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
  • Loading branch information
mwilck committed Jan 24, 2025
1 parent 6b9e2c2 commit d9c6133
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 2 deletions.
2 changes: 2 additions & 0 deletions libmultipath/discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum discovery_mode {
DI_BLACKLIST__,
DI_NOIO__,
DI_NOFALLBACK__,
DI_DISCOVERY__,
};

#define DI_SYSFS (1 << DI_SYSFS__)
Expand All @@ -84,6 +85,7 @@ enum discovery_mode {
#define DI_BLACKLIST (1 << DI_BLACKLIST__)
#define DI_NOIO (1 << DI_NOIO__) /* Avoid IO on the device */
#define DI_NOFALLBACK (1 << DI_NOFALLBACK__) /* do not allow wwid fallback */
#define DI_DISCOVERY (1 << DI_DISCOVERY__) /* set only during map discovery */

#define DI_ALL (DI_SYSFS | DI_IOCTL | DI_CHECKER | DI_PRIO | DI_WWID)

Expand Down
6 changes: 5 additions & 1 deletion libmultipath/structs_vec.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ static void update_pathvec_from_dm(vector pathvec, struct multipath *mpp,
bool mpp_has_wwid;
bool must_reload = false;
bool pg_deleted = false;
bool map_discovery = !!(pathinfo_flags & DI_DISCOVERY);

pathinfo_flags &= ~DI_DISCOVERY;

if (!mpp->pg)
return;
Expand Down Expand Up @@ -193,7 +196,8 @@ static void update_pathvec_from_dm(vector pathvec, struct multipath *mpp,
rc = pathinfo(pp, conf,
DI_SYSFS|DI_WWID|DI_BLACKLIST|DI_NOFALLBACK|pathinfo_flags);
pthread_cleanup_pop(1);
if (rc != PATHINFO_OK) {
if (rc == PATHINFO_FAILED ||
(rc == PATHINFO_SKIPPED && !map_discovery)) {
condlog(1, "%s: error %d in pathinfo, discarding path",
pp->dev, rc);
vector_del_slot(pgp->paths, j--);
Expand Down
2 changes: 1 addition & 1 deletion multipathd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,7 @@ map_discovery (struct vectors * vecs)
return 1;

vector_foreach_slot (vecs->mpvec, mpp, i)
if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) {
if (update_multipath_table(mpp, vecs->pathvec, DI_DISCOVERY) != DMP_OK) {
remove_map(mpp, vecs->pathvec, vecs->mpvec);
i--;
}
Expand Down

0 comments on commit d9c6133

Please sign in to comment.