Blame SOURCES/0131-libmultipath-keep-renames-from-stopping-other-multip.patch

2e39a4
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2e39a4
From: Benjamin Marzinski <bmarzins@redhat.com>
2e39a4
Date: Tue, 31 Jan 2023 12:00:31 -0600
2e39a4
Subject: [PATCH] libmultipath: keep renames from stopping other multipath
2e39a4
 actions
2e39a4
2e39a4
If select_action() is called and a multipath device needs to be renamed,
2e39a4
the code currently checks if force_reload is set, and if so, does the
2e39a4
reload after the rename.  But if force_reload isn't set, only the rename
2e39a4
happens, regardless of what other actions are needed. This can happen if
2e39a4
multipathd starts up and a device needs both a reload and a rename.
2e39a4
2e39a4
Make multipath check for resize, reload, and switch pathgroup along with
2e39a4
rename, and do both if necessary.
2e39a4
2e39a4
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
2e39a4
---
2e39a4
 libmultipath/configure.c | 92 +++++++++++++++++++++-------------------
2e39a4
 libmultipath/configure.h |  4 +-
2e39a4
 2 files changed, 51 insertions(+), 45 deletions(-)
2e39a4
2e39a4
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
2e39a4
index 303d2380..65a0b208 100644
2e39a4
--- a/libmultipath/configure.c
2e39a4
+++ b/libmultipath/configure.c
2e39a4
@@ -690,6 +690,7 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 	struct multipath * cmpp_by_name;
2e39a4
 	char * mpp_feat, * cmpp_feat;
2e39a4
 
2e39a4
+	mpp->action = ACT_NOTHING;
2e39a4
 	cmpp = find_mp_by_wwid(curmp, mpp->wwid);
2e39a4
 	cmpp_by_name = find_mp_by_alias(curmp, mpp->alias);
2e39a4
 
2e39a4
@@ -712,14 +713,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 			mpp->alias);
2e39a4
 		strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
2e39a4
 		mpp->action = ACT_RENAME;
2e39a4
-		if (force_reload) {
2e39a4
-			mpp->force_udev_reload = 1;
2e39a4
-			mpp->action = ACT_FORCERENAME;
2e39a4
-		}
2e39a4
-		return;
2e39a4
-	}
2e39a4
-
2e39a4
-	if (cmpp != cmpp_by_name) {
2e39a4
+		/* don't return here. Check for other needed actions */
2e39a4
+	} else if (cmpp != cmpp_by_name) {
2e39a4
 		condlog(2, "%s: unable to rename %s to %s (%s is used by %s)",
2e39a4
 			mpp->wwid, cmpp->alias, mpp->alias,
2e39a4
 			mpp->alias, cmpp_by_name->wwid);
2e39a4
@@ -727,12 +722,13 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 		FREE(mpp->alias);
2e39a4
 		mpp->alias = STRDUP(cmpp->alias);
2e39a4
 		mpp->action = ACT_IMPOSSIBLE;
2e39a4
-		return;
2e39a4
+		/* don't return here. Check for other needed actions */
2e39a4
 	}
2e39a4
 
2e39a4
 	if (cmpp->size != mpp->size) {
2e39a4
 		mpp->force_udev_reload = 1;
2e39a4
-		mpp->action = ACT_RESIZE;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME :
2e39a4
+			      ACT_RESIZE;
2e39a4
 		condlog(3, "%s: set ACT_RESIZE (size change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
@@ -740,7 +736,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 
2e39a4
 	if (force_reload) {
2e39a4
 		mpp->force_udev_reload = 1;
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (forced by user)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
@@ -749,7 +746,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 	if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
2e39a4
 	    !!strstr(mpp->features, "queue_if_no_path") !=
2e39a4
 	    !!strstr(cmpp->features, "queue_if_no_path")) {
2e39a4
-		mpp->action =  ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (no_path_retry change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
@@ -759,7 +757,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 	    (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) ||
2e39a4
 	     strncmp(cmpp->hwhandler, mpp->hwhandler,
2e39a4
 		    strlen(mpp->hwhandler)))) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (hwhandler change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
@@ -769,7 +768,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 	    !!strstr(mpp->features, "retain_attached_hw_handler") !=
2e39a4
 	    !!strstr(cmpp->features, "retain_attached_hw_handler") &&
2e39a4
 	    get_linux_version_code() < KERNEL_VERSION(4, 3, 0)) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (retain_hwhandler change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
@@ -783,9 +783,13 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 		remove_feature(&cmpp_feat, "queue_if_no_path");
2e39a4
 		remove_feature(&cmpp_feat, "retain_attached_hw_handler");
2e39a4
 		if (strncmp(mpp_feat, cmpp_feat, PARAMS_SIZE)) {
2e39a4
-			mpp->action =  ACT_RELOAD;
2e39a4
+			mpp->action = mpp->action == ACT_RENAME ?
2e39a4
+				      ACT_RELOAD_RENAME : ACT_RELOAD;
2e39a4
 			condlog(3, "%s: set ACT_RELOAD (features change)",
2e39a4
 				mpp->alias);
2e39a4
+			FREE(cmpp_feat);
2e39a4
+			FREE(mpp_feat);
2e39a4
+			return;
2e39a4
 		}
2e39a4
 	}
2e39a4
 	FREE(cmpp_feat);
2e39a4
@@ -793,44 +797,49 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
2e39a4
 
2e39a4
 	if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector,
2e39a4
 		    strlen(mpp->selector))) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (selector change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
 	}
2e39a4
 	if (cmpp->minio != mpp->minio) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (minio change, %u->%u)",
2e39a4
 			mpp->alias, cmpp->minio, mpp->minio);
2e39a4
 		return;
2e39a4
 	}
2e39a4
 	if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (path group number change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
 	}
2e39a4
 	if (pgcmp(mpp, cmpp)) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME :
2e39a4
+			      ACT_RELOAD;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (path group topology change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
 	}
2e39a4
 	if (cmpp->nextpg != mpp->bestpg) {
2e39a4
-		mpp->action = ACT_SWITCHPG;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME :
2e39a4
+			      ACT_SWITCHPG;
2e39a4
 		condlog(3, "%s: set ACT_SWITCHPG (next path group change)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
 	}
2e39a4
 	if (!is_mpp_known_to_udev(cmpp)) {
2e39a4
-		mpp->action = ACT_RELOAD;
2e39a4
+		mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME :
2e39a4
+			      ACT_SWITCHPG;
2e39a4
 		condlog(3, "%s: set ACT_RELOAD (udev device not initialized)",
2e39a4
 			mpp->alias);
2e39a4
 		return;
2e39a4
 	}
2e39a4
-	mpp->action = ACT_NOTHING;
2e39a4
-	condlog(3, "%s: set ACT_NOTHING (map unchanged)",
2e39a4
-		mpp->alias);
2e39a4
+	if (mpp->action == ACT_NOTHING)
2e39a4
+		condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias);
2e39a4
 	return;
2e39a4
 }
2e39a4
 
2e39a4
@@ -924,6 +933,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
2e39a4
 		mpp->action = ACT_RELOAD;
2e39a4
 	}
2e39a4
 
2e39a4
+	if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME ||
2e39a4
+	    mpp->action == ACT_RELOAD_RENAME ||
2e39a4
+	    mpp->action == ACT_RESIZE_RENAME) {
2e39a4
+		conf = get_multipath_config();
2e39a4
+		pthread_cleanup_push(put_multipath_config, conf);
2e39a4
+		r = dm_rename(mpp->alias_old, mpp->alias,
2e39a4
+			      conf->partition_delim, mpp->skip_kpartx);
2e39a4
+		pthread_cleanup_pop(1);
2e39a4
+		if (r == DOMAP_FAIL)
2e39a4
+			return r;
2e39a4
+	}
2e39a4
 	switch (mpp->action) {
2e39a4
 	case ACT_REJECT:
2e39a4
 	case ACT_NOTHING:
2e39a4
@@ -931,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
2e39a4
 		return DOMAP_EXIST;
2e39a4
 
2e39a4
 	case ACT_SWITCHPG:
2e39a4
+	case ACT_SWITCHPG_RENAME:
2e39a4
 		dm_switchgroup(mpp->alias, mpp->bestpg);
2e39a4
 		/*
2e39a4
 		 * we may have avoided reinstating paths because there where in
2e39a4
@@ -957,6 +978,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
2e39a4
 		break;
2e39a4
 
2e39a4
 	case ACT_RELOAD:
2e39a4
+	case ACT_RELOAD_RENAME:
2e39a4
 		sysfs_set_max_sectors_kb(mpp, 1);
2e39a4
 		if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP))
2e39a4
 			mpp->ghost_delay_tick = 0;
2e39a4
@@ -964,6 +986,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
2e39a4
 		break;
2e39a4
 
2e39a4
 	case ACT_RESIZE:
2e39a4
+	case ACT_RESIZE_RENAME:
2e39a4
 		sysfs_set_max_sectors_kb(mpp, 1);
2e39a4
 		if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP))
2e39a4
 			mpp->ghost_delay_tick = 0;
2e39a4
@@ -971,29 +994,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon)
2e39a4
 		break;
2e39a4
 
2e39a4
 	case ACT_RENAME:
2e39a4
-		conf = get_multipath_config();
2e39a4
-		pthread_cleanup_push(put_multipath_config, conf);
2e39a4
-		r = dm_rename(mpp->alias_old, mpp->alias,
2e39a4
-			      conf->partition_delim, mpp->skip_kpartx);
2e39a4
-		pthread_cleanup_pop(1);
2e39a4
-		break;
2e39a4
-
2e39a4
-	case ACT_FORCERENAME:
2e39a4
-		conf = get_multipath_config();
2e39a4
-		pthread_cleanup_push(put_multipath_config, conf);
2e39a4
-		r = dm_rename(mpp->alias_old, mpp->alias,
2e39a4
-			      conf->partition_delim, mpp->skip_kpartx);
2e39a4
-		pthread_cleanup_pop(1);
2e39a4
-		if (r) {
2e39a4
-			sysfs_set_max_sectors_kb(mpp, 1);
2e39a4
-			if (mpp->ghost_delay_tick > 0 &&
2e39a4
-			    pathcount(mpp, PATH_UP))
2e39a4
-				mpp->ghost_delay_tick = 0;
2e39a4
-			r = dm_addmap_reload(mpp, params, 0);
2e39a4
-		}
2e39a4
 		break;
2e39a4
 
2e39a4
 	default:
2e39a4
+		r = DOMAP_FAIL;
2e39a4
 		break;
2e39a4
 	}
2e39a4
 
2e39a4
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
2e39a4
index 5cf08d45..1a93f49d 100644
2e39a4
--- a/libmultipath/configure.h
2e39a4
+++ b/libmultipath/configure.h
2e39a4
@@ -18,9 +18,11 @@ enum actions {
2e39a4
 	ACT_RENAME,
2e39a4
 	ACT_CREATE,
2e39a4
 	ACT_RESIZE,
2e39a4
-	ACT_FORCERENAME,
2e39a4
+	ACT_RELOAD_RENAME,
2e39a4
 	ACT_DRY_RUN,
2e39a4
 	ACT_IMPOSSIBLE,
2e39a4
+	ACT_RESIZE_RENAME,
2e39a4
+	ACT_SWITCHPG_RENAME,
2e39a4
 };
2e39a4
 
2e39a4
 /*