device-mapper-multipath-0.8.7-29
Add 0110-libmultipath-keep-track-of-queueing-state-in-feature.patch Add 0111-libmultipath-export-partmap_in_use.patch Add 0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch Add 0113-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch * Fixes RHEL-30272 Add 0114-libmultipath-remove-pathgroup-wildcard-options.patch Add 0115-libmultipath-print-all-values-in-snprint_failback.patch Add 0116-multipathd-Stop-double-counting-map-failures-for-no_.patch Add 0117-multipath-tools-man-pages-add-missing-multipathd-com.patch Add 0118-libmultipath-change-the-vend-prod-rev-printing.patch Add 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch * Fixes RHEL-8304 Resolves: RHEL-8304 Resolves: RHEL-30272
This commit is contained in:
		
							parent
							
								
									2d7060ef7c
								
							
						
					
					
						commit
						9ae3e98286
					
				
							
								
								
									
										194
									
								
								0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Tue, 19 Dec 2023 17:51:50 -0500 | ||||||
|  | Subject: [PATCH] libmultipath: keep track of queueing state in features | ||||||
|  | 
 | ||||||
|  | Make multipathd update mpp->features when in enables or disables | ||||||
|  | queuing. This patch handles all the cases except failed removes by | ||||||
|  | dm_suspend_and_flush_map(), which is never called by multipathd. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Reviewed-by: Martin Wilck <mwilck@suse.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/configure.c   |  4 +--- | ||||||
|  |  libmultipath/devmapper.c   | 23 +++++++++++++++++++---- | ||||||
|  |  libmultipath/devmapper.h   |  2 +- | ||||||
|  |  libmultipath/structs_vec.c | 10 +++++----- | ||||||
|  |  multipathd/main.c          |  8 ++++---- | ||||||
|  |  5 files changed, 30 insertions(+), 17 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/configure.c b/libmultipath/configure.c
 | ||||||
|  | index bbdbb8ca..71acb968 100644
 | ||||||
|  | --- a/libmultipath/configure.c
 | ||||||
|  | +++ b/libmultipath/configure.c
 | ||||||
|  | @@ -1279,9 +1279,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
 | ||||||
|  |  			    mpp->no_path_retry != NO_PATH_RETRY_FAIL) | ||||||
|  |  				condlog(3, "%s: multipathd not running, unset " | ||||||
|  |  					"queue_if_no_path feature", mpp->alias); | ||||||
|  | -			if (!dm_queue_if_no_path(mpp->alias, 0))
 | ||||||
|  | -				remove_feature(&mpp->features,
 | ||||||
|  | -					       "queue_if_no_path");
 | ||||||
|  | +			dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		if (!is_daemon && mpp->action != ACT_NOTHING) | ||||||
|  | diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
 | ||||||
|  | index f9de3358..5711f0ee 100644
 | ||||||
|  | --- a/libmultipath/devmapper.c
 | ||||||
|  | +++ b/libmultipath/devmapper.c
 | ||||||
|  | @@ -57,6 +57,7 @@ static int dm_cancel_remove_partmaps(const char * mapname);
 | ||||||
|  |  static int do_foreach_partmaps(const char * mapname, | ||||||
|  |  			       int (*partmap_func)(const char *, void *), | ||||||
|  |  			       void *data); | ||||||
|  | +static int _dm_queue_if_no_path(const char *mapname, int enable);
 | ||||||
|  |   | ||||||
|  |  #ifndef LIBDM_API_COOKIE | ||||||
|  |  static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a) | ||||||
|  | @@ -1072,7 +1073,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
 | ||||||
|  |  	if (need_suspend && | ||||||
|  |  	    dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK && | ||||||
|  |  	    strstr(params, "queue_if_no_path")) { | ||||||
|  | -		if (!dm_queue_if_no_path(mapname, 0))
 | ||||||
|  | +		if (!_dm_queue_if_no_path(mapname, 0))
 | ||||||
|  |  			queue_if_no_path = 1; | ||||||
|  |  		else | ||||||
|  |  			/* Leave queue_if_no_path alone if unset failed */ | ||||||
|  | @@ -1121,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
 | ||||||
|  |  	} while (retries-- > 0); | ||||||
|  |   | ||||||
|  |  	if (queue_if_no_path == 1) | ||||||
|  | -		dm_queue_if_no_path(mapname, 1);
 | ||||||
|  | +		_dm_queue_if_no_path(mapname, 1);
 | ||||||
|  |   | ||||||
|  |  	return 1; | ||||||
|  |  } | ||||||
|  | @@ -1236,8 +1237,8 @@ dm_reinstate_path(const char * mapname, char * path)
 | ||||||
|  |  	return dm_message(mapname, message); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -int
 | ||||||
|  | -dm_queue_if_no_path(const char *mapname, int enable)
 | ||||||
|  | +static int
 | ||||||
|  | +_dm_queue_if_no_path(const char *mapname, int enable)
 | ||||||
|  |  { | ||||||
|  |  	char *message; | ||||||
|  |   | ||||||
|  | @@ -1249,6 +1250,20 @@ dm_queue_if_no_path(const char *mapname, int enable)
 | ||||||
|  |  	return dm_message(mapname, message); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int dm_queue_if_no_path(struct multipath *mpp, int enable)
 | ||||||
|  | +{
 | ||||||
|  | +	int r;
 | ||||||
|  | +	static const char no_path_retry[] = "queue_if_no_path";
 | ||||||
|  | +
 | ||||||
|  | +	if ((r = _dm_queue_if_no_path(mpp->alias, enable)) == 0) {
 | ||||||
|  | +		if (enable)
 | ||||||
|  | +			add_feature(&mpp->features, no_path_retry);
 | ||||||
|  | +		else
 | ||||||
|  | +			remove_feature(&mpp->features, no_path_retry);
 | ||||||
|  | +	}
 | ||||||
|  | +	return r;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static int | ||||||
|  |  dm_groupmsg (const char * msg, const char * mapname, int index) | ||||||
|  |  { | ||||||
|  | diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
 | ||||||
|  | index 808da28d..41b8c31d 100644
 | ||||||
|  | --- a/libmultipath/devmapper.h
 | ||||||
|  | +++ b/libmultipath/devmapper.h
 | ||||||
|  | @@ -58,7 +58,7 @@ int dm_cancel_deferred_remove(struct multipath *mpp);
 | ||||||
|  |  int dm_flush_maps (int retries); | ||||||
|  |  int dm_fail_path(const char * mapname, char * path); | ||||||
|  |  int dm_reinstate_path(const char * mapname, char * path); | ||||||
|  | -int dm_queue_if_no_path(const char *mapname, int enable);
 | ||||||
|  | +int dm_queue_if_no_path(struct multipath *mpp, int enable);
 | ||||||
|  |  int dm_switchgroup(const char * mapname, int index); | ||||||
|  |  int dm_enablegroup(const char * mapname, int index); | ||||||
|  |  int dm_disablegroup(const char * mapname, int index); | ||||||
|  | diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
 | ||||||
|  | index 86ad89ca..56915e96 100644
 | ||||||
|  | --- a/libmultipath/structs_vec.c
 | ||||||
|  | +++ b/libmultipath/structs_vec.c
 | ||||||
|  | @@ -579,7 +579,7 @@ static void leave_recovery_mode(struct multipath *mpp)
 | ||||||
|  |  	 */ | ||||||
|  |  	if (recovery && (mpp->no_path_retry == NO_PATH_RETRY_QUEUE || | ||||||
|  |  			 mpp->no_path_retry > 0)) { | ||||||
|  | -		dm_queue_if_no_path(mpp->alias, 1);
 | ||||||
|  | +		dm_queue_if_no_path(mpp, 1);
 | ||||||
|  |  		condlog(2, "%s: queue_if_no_path enabled", mpp->alias); | ||||||
|  |  		condlog(1, "%s: Recovered to normal mode", mpp->alias); | ||||||
|  |  	} | ||||||
|  | @@ -598,11 +598,11 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
 | ||||||
|  |  		break; | ||||||
|  |  	case NO_PATH_RETRY_FAIL: | ||||||
|  |  		if (!check_features || is_queueing) | ||||||
|  | -			dm_queue_if_no_path(mpp->alias, 0);
 | ||||||
|  | +			dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  		break; | ||||||
|  |  	case NO_PATH_RETRY_QUEUE: | ||||||
|  |  		if (!check_features || !is_queueing) | ||||||
|  | -			dm_queue_if_no_path(mpp->alias, 1);
 | ||||||
|  | +			dm_queue_if_no_path(mpp, 1);
 | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		if (count_active_paths(mpp) > 0) { | ||||||
|  | @@ -612,7 +612,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
 | ||||||
|  |  			 */ | ||||||
|  |  			if ((!check_features || !is_queueing) && | ||||||
|  |  			    !mpp->in_recovery) | ||||||
|  | -				dm_queue_if_no_path(mpp->alias, 1);
 | ||||||
|  | +				dm_queue_if_no_path(mpp, 1);
 | ||||||
|  |  			leave_recovery_mode(mpp); | ||||||
|  |  		} else { | ||||||
|  |  			/* | ||||||
|  | @@ -623,7 +623,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
 | ||||||
|  |  			 */ | ||||||
|  |  			if ((!check_features || is_queueing) && | ||||||
|  |  			    mpp->in_recovery && mpp->retry_tick == 0) | ||||||
|  | -				dm_queue_if_no_path(mpp->alias, 0);
 | ||||||
|  | +				dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  			if (pathcount(mpp, PATH_PENDING) == 0) | ||||||
|  |  				enter_recovery_mode(mpp); | ||||||
|  |  		} | ||||||
|  | diff --git a/multipathd/main.c b/multipathd/main.c
 | ||||||
|  | index 26be6dc3..74f8114c 100644
 | ||||||
|  | --- a/multipathd/main.c
 | ||||||
|  | +++ b/multipathd/main.c
 | ||||||
|  | @@ -502,7 +502,7 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
 | ||||||
|  |  		mpp->no_path_retry = NO_PATH_RETRY_FAIL; | ||||||
|  |  		mpp->disable_queueing = 1; | ||||||
|  |  		mpp->stat_map_failures++; | ||||||
|  | -		dm_queue_if_no_path(mpp->alias, 0);
 | ||||||
|  | +		dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  	} | ||||||
|  |  	r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); | ||||||
|  |  	if (r) { | ||||||
|  | @@ -833,7 +833,7 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	dm_queue_if_no_path(alias, 0);
 | ||||||
|  | +	dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  	remove_map_and_stop_waiter(mpp, vecs); | ||||||
|  |  out: | ||||||
|  |  	lock_cleanup_pop(vecs->lock); | ||||||
|  | @@ -2015,7 +2015,7 @@ retry_count_tick(vector mpvec)
 | ||||||
|  |  			condlog(4, "%s: Retrying.. No active path", mpp->alias); | ||||||
|  |  			if(--mpp->retry_tick == 0) { | ||||||
|  |  				mpp->stat_map_failures++; | ||||||
|  | -				dm_queue_if_no_path(mpp->alias, 0);
 | ||||||
|  | +				dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  				condlog(2, "%s: Disable queueing", mpp->alias); | ||||||
|  |  			} | ||||||
|  |  		} | ||||||
|  | @@ -3110,7 +3110,7 @@ static void cleanup_maps(struct vectors *vecs)
 | ||||||
|  |  	put_multipath_config(conf); | ||||||
|  |  	if (queue_without_daemon == QUE_NO_DAEMON_OFF) | ||||||
|  |  		vector_foreach_slot(vecs->mpvec, mpp, i) | ||||||
|  | -			dm_queue_if_no_path(mpp->alias, 0);
 | ||||||
|  | +			dm_queue_if_no_path(mpp, 0);
 | ||||||
|  |  	remove_maps_and_stop_waiters(vecs); | ||||||
|  |  	vecs->mpvec = NULL; | ||||||
|  |  } | ||||||
							
								
								
									
										54
									
								
								0111-libmultipath-export-partmap_in_use.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								0111-libmultipath-export-partmap_in_use.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Thu, 25 Apr 2024 19:35:13 -0400 | ||||||
|  | Subject: [PATCH] libmultipath: export partmap_in_use | ||||||
|  | 
 | ||||||
|  | A future commit will make use of this function | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Reviewed-by: Martin Wilck <mwilck@suse.com> | ||||||
|  | Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/devmapper.c          | 2 +- | ||||||
|  |  libmultipath/devmapper.h          | 1 + | ||||||
|  |  libmultipath/libmultipath.version | 5 +++++ | ||||||
|  |  3 files changed, 7 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
 | ||||||
|  | index 5711f0ee..4a66e2c4 100644
 | ||||||
|  | --- a/libmultipath/devmapper.c
 | ||||||
|  | +++ b/libmultipath/devmapper.c
 | ||||||
|  | @@ -1028,7 +1028,7 @@ has_partmap(const char *name __attribute__((unused)),
 | ||||||
|  |  	return 1; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int
 | ||||||
|  | +int
 | ||||||
|  |  partmap_in_use(const char *name, void *data) | ||||||
|  |  { | ||||||
|  |  	int part_count, *ret_count = (int *)data; | ||||||
|  | diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
 | ||||||
|  | index 41b8c31d..88e0b114 100644
 | ||||||
|  | --- a/libmultipath/devmapper.h
 | ||||||
|  | +++ b/libmultipath/devmapper.h
 | ||||||
|  | @@ -48,6 +48,7 @@ int dm_get_map(const char *, unsigned long long *, char **);
 | ||||||
|  |  int dm_get_status(const char *, char **); | ||||||
|  |  int dm_type(const char *, char *); | ||||||
|  |  int dm_is_mpath(const char *); | ||||||
|  | +int partmap_in_use(const char *name, void *data);
 | ||||||
|  |  int _dm_flush_map (const char *, int, int, int, int); | ||||||
|  |  int dm_flush_map_nopaths(const char * mapname, int deferred_remove); | ||||||
|  |  #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) | ||||||
|  | diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
 | ||||||
|  | index 1d018eab..40d9246d 100644
 | ||||||
|  | --- a/libmultipath/libmultipath.version
 | ||||||
|  | +++ b/libmultipath/libmultipath.version
 | ||||||
|  | @@ -302,3 +302,8 @@ LIBMULTIPATH_9.1.2 {
 | ||||||
|  |  global: | ||||||
|  |  	cleanup_mutex; | ||||||
|  |  } LIBMULTIPATH_9.1.1; | ||||||
|  | +
 | ||||||
|  | +LIBMULTIPATH_9.1.3 {
 | ||||||
|  | +global:
 | ||||||
|  | +	partmap_in_use;
 | ||||||
|  | +} LIBMULTIPATH_9.1.2;
 | ||||||
							
								
								
									
										346
									
								
								0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,346 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Thu, 25 Apr 2024 19:35:14 -0400 | ||||||
|  | Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd | ||||||
|  |  hang | ||||||
|  | 
 | ||||||
|  | Commit 9bd3482e ("multipathd: make flush_map() delete maps like the | ||||||
|  | multipath command") fixed an issue where deleting a queueing multipath | ||||||
|  | device through multipathd could hang because the multipath device had | ||||||
|  | outstanding IO, even though the only openers of it at the time of | ||||||
|  | deletion were the kpartx partition devices. However it is still possible | ||||||
|  | to hang multipathd, because autoremoving the device when all paths have | ||||||
|  | been deleted doesn't disable queueing. To reproduce this hang: | ||||||
|  | 
 | ||||||
|  | 1. create a multipath device with a kpartx partition on top of it and | ||||||
|  | no_path_retry set to either "queue" or something long enough to run all | ||||||
|  | the commands in the reproducer before it disables queueing. | ||||||
|  | 2. disable all the paths to the device with something like: | ||||||
|  |  # echo offline > /sys/block/<path_dev>/device/state | ||||||
|  | 3. Write directly to the multipath device with something like: | ||||||
|  |  # dd if=/dev/zero of=/dev/mapper/<mpath_dev> bs=4K count=1 | ||||||
|  | 4. delete all the paths to the device with something like: | ||||||
|  |  # echo 1 > /sys/block/<path_dev>/device/delete | ||||||
|  | 
 | ||||||
|  | Multipathd will hang trying to delete the kpartx device because, as the | ||||||
|  | last opener, it must flush the multipath device before closing it. | ||||||
|  | Because it hangs holding the vecs_lock, multipathd will never disable | ||||||
|  | queueing on the device, so it will hang forever, even if no_path_retry | ||||||
|  | is set to a number. | ||||||
|  | 
 | ||||||
|  | This hang can occur, even if deferred_remove is set. Since nothing has | ||||||
|  | the kpartx device opened, device-mapper does an immediate remove, which | ||||||
|  | will still hang. This means that even if deferred_remove is set, | ||||||
|  | multipathd still cannot delete a map while queueing is enabled. It must | ||||||
|  | either disable queueing or skip the autoremove. | ||||||
|  | 
 | ||||||
|  | Mulitpath can currently be configured to avoid this hang by setting | ||||||
|  | 
 | ||||||
|  | flush_on_last_del yes | ||||||
|  | 
 | ||||||
|  | However there are good reasons why users wouldn't want to set that. They | ||||||
|  | may need to be able to survive having all paths getting temporarily | ||||||
|  | deleted.  I should note that this is a pretty rare corner case, since | ||||||
|  | multipath automatically sets dev_loss_tmo so that it should not trigger | ||||||
|  | before queueing is disabled. | ||||||
|  | 
 | ||||||
|  | This commit avoids the hang by changing the possible values for | ||||||
|  | flush_on_last_del to "never", "unused", and "always", and sets the | ||||||
|  | default to "unused".  "always" works like "yes" did, "never" will not | ||||||
|  | disable queueing, and "unused" will only disable queueing if nothing has | ||||||
|  | the kpartx devices or the multipath device open. In order to be safe, if | ||||||
|  | the device has queue_if_no_paths set (and in case of "unused", the | ||||||
|  | device is in-use) the autoremove will be skipped. Also, instead of just | ||||||
|  | trusting the lack of "queue_if_no_paths" in the current mpp->features, | ||||||
|  | multipathd will tell the kernel to disable queueing, just to be sure it | ||||||
|  | actually is. | ||||||
|  | 
 | ||||||
|  | I chose "unused" as the default because this should generally only cause | ||||||
|  | multipathd to work differently from the users perspective when nothing | ||||||
|  | has the multipath device open but it is queueing and there is | ||||||
|  | outstanding IO. Without this change, it would have hung instead of | ||||||
|  | failing the outstanding IO. However, I do understand that an argument | ||||||
|  | could be made that "never" makes more sense as default, even though it | ||||||
|  | will cause multipathd to skip autoremoves in cases where it wouldn't | ||||||
|  | before. The change to the behavior of deffered_remove will be | ||||||
|  | noticeable, but skipping an autoremove is much better than hanging. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Reviewed-by: Martin Wilck <mwilck@suse.com> | ||||||
|  | Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/defaults.h    |  2 +- | ||||||
|  |  libmultipath/dict.c        | 72 +++++++++++++++++++++++++++++++++----- | ||||||
|  |  libmultipath/dict.h        |  1 + | ||||||
|  |  libmultipath/hwtable.c     |  6 ++-- | ||||||
|  |  libmultipath/propsel.c     |  4 ++- | ||||||
|  |  libmultipath/structs.h     |  7 ++-- | ||||||
|  |  multipath/multipath.conf.5 | 20 ++++++++--- | ||||||
|  |  multipathd/main.c          | 39 ++++++++++++++++----- | ||||||
|  |  8 files changed, 122 insertions(+), 29 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
 | ||||||
|  | index c3788bbc..5e77387e 100644
 | ||||||
|  | --- a/libmultipath/defaults.h
 | ||||||
|  | +++ b/libmultipath/defaults.h
 | ||||||
|  | @@ -41,7 +41,7 @@
 | ||||||
|  |  #define DEFAULT_PRIO		PRIO_CONST | ||||||
|  |  #define DEFAULT_PRIO_ARGS	"" | ||||||
|  |  #define DEFAULT_CHECKER		TUR | ||||||
|  | -#define DEFAULT_FLUSH		FLUSH_DISABLED
 | ||||||
|  | +#define DEFAULT_FLUSH		FLUSH_UNUSED
 | ||||||
|  |  #define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF | ||||||
|  |  #define DEFAULT_FORCE_SYNC	0 | ||||||
|  |  #define UNSET_PARTITION_DELIM "/UNSET/" | ||||||
|  | diff --git a/libmultipath/dict.c b/libmultipath/dict.c
 | ||||||
|  | index ce1b6c99..3c011ece 100644
 | ||||||
|  | --- a/libmultipath/dict.c
 | ||||||
|  | +++ b/libmultipath/dict.c
 | ||||||
|  | @@ -825,14 +825,70 @@ declare_def_snprint(checker_timeout, print_nonzero)
 | ||||||
|  |  declare_def_handler(allow_usb_devices, set_yes_no) | ||||||
|  |  declare_def_snprint(allow_usb_devices, print_yes_no) | ||||||
|  |   | ||||||
|  | -declare_def_handler(flush_on_last_del, set_yes_no_undef)
 | ||||||
|  | -declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH)
 | ||||||
|  | -declare_ovr_handler(flush_on_last_del, set_yes_no_undef)
 | ||||||
|  | -declare_ovr_snprint(flush_on_last_del, print_yes_no_undef)
 | ||||||
|  | -declare_hw_handler(flush_on_last_del, set_yes_no_undef)
 | ||||||
|  | -declare_hw_snprint(flush_on_last_del, print_yes_no_undef)
 | ||||||
|  | -declare_mp_handler(flush_on_last_del, set_yes_no_undef)
 | ||||||
|  | -declare_mp_snprint(flush_on_last_del, print_yes_no_undef)
 | ||||||
|  | +
 | ||||||
|  | +static const char * const flush_on_last_del_optvals[] = {
 | ||||||
|  | +	[FLUSH_NEVER] = "never",
 | ||||||
|  | +	[FLUSH_ALWAYS] = "always",
 | ||||||
|  | +	[FLUSH_UNUSED] = "unused",
 | ||||||
|  | +};
 | ||||||
|  | +
 | ||||||
|  | +static int
 | ||||||
|  | +set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr)
 | ||||||
|  | +{
 | ||||||
|  | +	int i;
 | ||||||
|  | +	int *flush_val_ptr = (int *)ptr;
 | ||||||
|  | +	char *buff;
 | ||||||
|  | +
 | ||||||
|  | +	buff = set_value(strvec);
 | ||||||
|  | +	if (!buff)
 | ||||||
|  | +		return 1;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) {
 | ||||||
|  | +		if (flush_on_last_del_optvals[i] != NULL &&
 | ||||||
|  | +		    !strcmp(buff, flush_on_last_del_optvals[i])) {
 | ||||||
|  | +			*flush_val_ptr = i;
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (i > FLUSH_UNUSED) {
 | ||||||
|  | +		bool deprecated = true;
 | ||||||
|  | +		if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
 | ||||||
|  | +			*flush_val_ptr = FLUSH_UNUSED;
 | ||||||
|  | +		else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
 | ||||||
|  | +			*flush_val_ptr = FLUSH_ALWAYS;
 | ||||||
|  | +		else {
 | ||||||
|  | +			deprecated = false;
 | ||||||
|  | +			condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"",
 | ||||||
|  | +				file, line_nr, buff);
 | ||||||
|  | +		}
 | ||||||
|  | +		if (deprecated)
 | ||||||
|  | +			condlog(3, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"",
 | ||||||
|  | +				file, line_nr, buff,
 | ||||||
|  | +				flush_on_last_del_optvals[*flush_val_ptr]);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	free(buff);
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +print_flush_on_last_del(struct strbuf *buff, long v)
 | ||||||
|  | +{
 | ||||||
|  | +	if (v == FLUSH_UNDEF)
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +declare_def_handler(flush_on_last_del, set_flush_on_last_del)
 | ||||||
|  | +declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del,
 | ||||||
|  | +			   DEFAULT_FLUSH)
 | ||||||
|  | +declare_ovr_handler(flush_on_last_del, set_flush_on_last_del)
 | ||||||
|  | +declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del)
 | ||||||
|  | +declare_hw_handler(flush_on_last_del, set_flush_on_last_del)
 | ||||||
|  | +declare_hw_snprint(flush_on_last_del, print_flush_on_last_del)
 | ||||||
|  | +declare_mp_handler(flush_on_last_del, set_flush_on_last_del)
 | ||||||
|  | +declare_mp_snprint(flush_on_last_del, print_flush_on_last_del)
 | ||||||
|  |   | ||||||
|  |  declare_def_handler(user_friendly_names, set_yes_no_undef) | ||||||
|  |  declare_def_snprint_defint(user_friendly_names, print_yes_no_undef, | ||||||
|  | diff --git a/libmultipath/dict.h b/libmultipath/dict.h
 | ||||||
|  | index d963b4ad..6b1aae5c 100644
 | ||||||
|  | --- a/libmultipath/dict.h
 | ||||||
|  | +++ b/libmultipath/dict.h
 | ||||||
|  | @@ -20,4 +20,5 @@ int print_reservation_key(struct strbuf *buff,
 | ||||||
|  |  			  struct be64 key, uint8_t flags, int source); | ||||||
|  |  int print_off_int_undef(struct strbuf *buff, long v); | ||||||
|  |  int print_auto_resize(struct strbuf *buff, long v); | ||||||
|  | +int print_flush_on_last_del(struct strbuf *buff, long v);
 | ||||||
|  |  #endif /* _DICT_H */ | ||||||
|  | diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
 | ||||||
|  | index 78ac7988..94012d50 100644
 | ||||||
|  | --- a/libmultipath/hwtable.c
 | ||||||
|  | +++ b/libmultipath/hwtable.c
 | ||||||
|  | @@ -60,7 +60,7 @@
 | ||||||
|  |  		.no_path_retry = NO_PATH_RETRY_UNDEF, | ||||||
|  |  		.minio         = 1000, | ||||||
|  |  		.minio_rq      = 1, | ||||||
|  | -		.flush_on_last_del = FLUSH_DISABLED,
 | ||||||
|  | +		.flush_on_last_del = FLUSH_UNUSED,
 | ||||||
|  |  		.user_friendly_names = USER_FRIENDLY_NAMES_OFF, | ||||||
|  |  		.fast_io_fail  = 5, | ||||||
|  |  		.dev_loss      = 600, | ||||||
|  | @@ -800,7 +800,7 @@ static struct hwentry default_hw[] = {
 | ||||||
|  |  		.no_path_retry = NO_PATH_RETRY_QUEUE, | ||||||
|  |  		.pgpolicy      = GROUP_BY_PRIO, | ||||||
|  |  		.pgfailback    = -FAILBACK_IMMEDIATE, | ||||||
|  | -		.flush_on_last_del = FLUSH_ENABLED,
 | ||||||
|  | +		.flush_on_last_del = FLUSH_ALWAYS,
 | ||||||
|  |  		.dev_loss      = MAX_DEV_LOSS_TMO, | ||||||
|  |  		.prio_name     = PRIO_ONTAP, | ||||||
|  |  		.user_friendly_names = USER_FRIENDLY_NAMES_OFF, | ||||||
|  | @@ -1122,7 +1122,7 @@ static struct hwentry default_hw[] = {
 | ||||||
|  |  		.no_path_retry = NO_PATH_RETRY_FAIL, | ||||||
|  |  		.minio         = 1, | ||||||
|  |  		.minio_rq      = 1, | ||||||
|  | -		.flush_on_last_del = FLUSH_ENABLED,
 | ||||||
|  | +		.flush_on_last_del = FLUSH_ALWAYS,
 | ||||||
|  |  		.fast_io_fail  = 15, | ||||||
|  |  		.dev_loss      = 15, | ||||||
|  |  	}, | ||||||
|  | diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
 | ||||||
|  | index 9dea6f92..be781ff7 100644
 | ||||||
|  | --- a/libmultipath/propsel.c
 | ||||||
|  | +++ b/libmultipath/propsel.c
 | ||||||
|  | @@ -902,6 +902,7 @@ out:
 | ||||||
|  |  int select_flush_on_last_del(struct config *conf, struct multipath *mp) | ||||||
|  |  { | ||||||
|  |  	const char *origin; | ||||||
|  | +	STRBUF_ON_STACK(buff);
 | ||||||
|  |   | ||||||
|  |  	mp_set_mpe(flush_on_last_del); | ||||||
|  |  	mp_set_ovr(flush_on_last_del); | ||||||
|  | @@ -909,8 +910,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp)
 | ||||||
|  |  	mp_set_conf(flush_on_last_del); | ||||||
|  |  	mp_set_default(flush_on_last_del, DEFAULT_FLUSH); | ||||||
|  |  out: | ||||||
|  | +	print_flush_on_last_del(&buff, mp->flush_on_last_del);
 | ||||||
|  |  	condlog(3, "%s: flush_on_last_del = %s %s", mp->alias, | ||||||
|  | -		(mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
 | ||||||
|  | +		get_strbuf_str(&buff), origin);
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --git a/libmultipath/structs.h b/libmultipath/structs.h
 | ||||||
|  | index d2ad4867..4bf8c93a 100644
 | ||||||
|  | --- a/libmultipath/structs.h
 | ||||||
|  | +++ b/libmultipath/structs.h
 | ||||||
|  | @@ -109,9 +109,10 @@ enum marginal_pathgroups_mode {
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  enum flush_states { | ||||||
|  | -	FLUSH_UNDEF = YNU_UNDEF,
 | ||||||
|  | -	FLUSH_DISABLED = YNU_NO,
 | ||||||
|  | -	FLUSH_ENABLED = YNU_YES,
 | ||||||
|  | +	FLUSH_UNDEF,
 | ||||||
|  | +	FLUSH_NEVER,
 | ||||||
|  | +	FLUSH_ALWAYS,
 | ||||||
|  | +	FLUSH_UNUSED,
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  enum log_checker_err_states { | ||||||
|  | diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
 | ||||||
|  | index 38eb5c90..10eddc0c 100644
 | ||||||
|  | --- a/multipath/multipath.conf.5
 | ||||||
|  | +++ b/multipath/multipath.conf.5
 | ||||||
|  | @@ -672,12 +672,22 @@ The default is: \fBno\fR
 | ||||||
|  |  .TP | ||||||
|  |  .B flush_on_last_del | ||||||
|  |  If set to | ||||||
|  | -.I yes
 | ||||||
|  | +.I always
 | ||||||
|  |  , multipathd will disable queueing when the last path to a device has been | ||||||
|  | -deleted.
 | ||||||
|  | -.RS
 | ||||||
|  | -.TP
 | ||||||
|  | -The default is: \fBno\fR
 | ||||||
|  | +deleted. If set to
 | ||||||
|  | +.I never
 | ||||||
|  | +, multipathd will not disable queueing when the last path to a device has
 | ||||||
|  | +been deleted. Since multipath cannot safely remove a device while queueing
 | ||||||
|  | +is enabled, setting this to \fInever\fR means that multipathd will not
 | ||||||
|  | +automatically remove an unused multipath device whose paths are all deleted if
 | ||||||
|  | +it is currently set to queue_if_no_path. If set to
 | ||||||
|  | +.I unused
 | ||||||
|  | +, multipathd will only disable queueing when the last path is removed if
 | ||||||
|  | +nothing currently has the multipath device or any of the kpartx partition
 | ||||||
|  | +devices on top of it open.
 | ||||||
|  | +.RS
 | ||||||
|  | +.TP
 | ||||||
|  | +The default is: \fBunused\fR
 | ||||||
|  |  .RE | ||||||
|  |  . | ||||||
|  |  . | ||||||
|  | diff --git a/multipathd/main.c b/multipathd/main.c
 | ||||||
|  | index 74f8114c..8ec58f5d 100644
 | ||||||
|  | --- a/multipathd/main.c
 | ||||||
|  | +++ b/multipathd/main.c
 | ||||||
|  | @@ -491,19 +491,42 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)
 | ||||||
|  |  static bool | ||||||
|  |  flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { | ||||||
|  |  	int r; | ||||||
|  | +	bool is_queueing = true;
 | ||||||
|  |   | ||||||
|  | +	if (mpp->features)
 | ||||||
|  | +		is_queueing = strstr(mpp->features, "queue_if_no_path");
 | ||||||
|  | +
 | ||||||
|  | +	/* It's not safe to do a remove of a map that has "queue_if_no_path"
 | ||||||
|  | +	 * set, since there could be outstanding IO which will cause
 | ||||||
|  | +	 * multipathd to hang while attempting the remove */
 | ||||||
|  | +	if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) {
 | ||||||
|  | +		condlog(2, "%s: map is queueing, can't remove", mpp->alias);
 | ||||||
|  | +		return false;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (mpp->flush_on_last_del == FLUSH_UNUSED &&
 | ||||||
|  | +            partmap_in_use(mpp->alias, NULL) && is_queueing) {
 | ||||||
|  | +		condlog(2, "%s: map in use and queueing, can't remove",
 | ||||||
|  | +			mpp->alias);
 | ||||||
|  | +		return false;
 | ||||||
|  | +	}
 | ||||||
|  |  	/* | ||||||
|  | -	 * flush_map will fail if the device is open
 | ||||||
|  | +	 * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices
 | ||||||
|  | +	 * that are in use, but only if they are already marked as not
 | ||||||
|  | +	 * queueing. That is just to make absolutely certain that they
 | ||||||
|  | +	 * really are not queueing, like they claim.
 | ||||||
|  |  	 */ | ||||||
|  | -	if (mpp->flush_on_last_del == FLUSH_ENABLED) {
 | ||||||
|  | -		condlog(2, "%s Last path deleted, disabling queueing",
 | ||||||
|  | +	condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing",
 | ||||||
|  | +		mpp->alias);
 | ||||||
|  | +	mpp->retry_tick = 0;
 | ||||||
|  | +	mpp->no_path_retry = NO_PATH_RETRY_FAIL;
 | ||||||
|  | +	mpp->disable_queueing = 1;
 | ||||||
|  | +	mpp->stat_map_failures++;
 | ||||||
|  | +	if (dm_queue_if_no_path(mpp, 0) != 0) {
 | ||||||
|  | +		condlog(0, "%s: failed to disable queueing. Not removing",
 | ||||||
|  |  			mpp->alias); | ||||||
|  | -		mpp->retry_tick = 0;
 | ||||||
|  | -		mpp->no_path_retry = NO_PATH_RETRY_FAIL;
 | ||||||
|  | -		mpp->disable_queueing = 1;
 | ||||||
|  | -		mpp->stat_map_failures++;
 | ||||||
|  | -		dm_queue_if_no_path(mpp, 0);
 | ||||||
|  | +		return false;
 | ||||||
|  |  	} | ||||||
|  | +
 | ||||||
|  |  	r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); | ||||||
|  |  	if (r) { | ||||||
|  |  		if (r == 1) | ||||||
| @ -0,0 +1,40 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Thu, 25 Apr 2024 19:35:16 -0400 | ||||||
|  | Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with | ||||||
|  |  no_path_retry | ||||||
|  | 
 | ||||||
|  | Currently multipath makes sure that dev_loss_tmo is at least as long as | ||||||
|  | the configured no path queueing time. The goal is to make sure that path | ||||||
|  | devices aren't removed while the multipath device is still queueing in | ||||||
|  | hopes that they will become usable again. | ||||||
|  | 
 | ||||||
|  | This is racy. Multipathd may take longer to check the paths than | ||||||
|  | configured. If strict_timing isn't set, it will definitely take longer. | ||||||
|  | To account for this, pad the minimum dev_loss_tmo value by five seconds | ||||||
|  | (one default checker interval) plus one second per minute of no path | ||||||
|  | queueing time. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Reviewed-by: Martin Wilck <mwilck@suse.com> | ||||||
|  | Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/discovery.c | 5 +++++ | ||||||
|  |  1 file changed, 5 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
 | ||||||
|  | index ae7eb7e6..b24594cd 100644
 | ||||||
|  | --- a/libmultipath/discovery.c
 | ||||||
|  | +++ b/libmultipath/discovery.c
 | ||||||
|  | @@ -884,6 +884,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
 | ||||||
|  |  		uint64_t no_path_retry_tmo = | ||||||
|  |  			(uint64_t)mpp->no_path_retry * conf->checkint; | ||||||
|  |   | ||||||
|  | +		/* pad no_path_retry_tmo by one standard check interval
 | ||||||
|  | +		 * plus one second per minute to account for timing
 | ||||||
|  | +		 * issues with the rechecks */
 | ||||||
|  | +		no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT;
 | ||||||
|  | +
 | ||||||
|  |  		if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) | ||||||
|  |  			min_dev_loss = MAX_DEV_LOSS_TMO; | ||||||
|  |  		else | ||||||
							
								
								
									
										32
									
								
								0114-libmultipath-remove-pathgroup-wildcard-options.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								0114-libmultipath-remove-pathgroup-wildcard-options.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Nitin Yewale <nyewale@redhat.com> | ||||||
|  | Date: Thu, 12 Jan 2023 14:28:49 -0600 | ||||||
|  | Subject: [PATCH] libmultipath: remove pathgroup wildcard options | ||||||
|  | 
 | ||||||
|  | The multipathd command "multipathd show wildcards" shows the pathgroup | ||||||
|  | format wildcards, but there is no way to use them in a multipathd | ||||||
|  | command. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/print.c | 7 ------- | ||||||
|  |  1 file changed, 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/print.c b/libmultipath/print.c
 | ||||||
|  | index 082e4e30..a6e4c774 100644
 | ||||||
|  | --- a/libmultipath/print.c
 | ||||||
|  | +++ b/libmultipath/print.c
 | ||||||
|  | @@ -803,13 +803,6 @@ int snprint_wildcards(struct strbuf *buff)
 | ||||||
|  |  				       pd[i].wildcard, pd[i].header)) < 0) | ||||||
|  |  			return rc; | ||||||
|  |   | ||||||
|  | -	if ((rc = append_strbuf_str(buff, "\npathgroup format wildcards:\n")) < 0)
 | ||||||
|  | -		return rc;
 | ||||||
|  | -	for (i = 0; pgd[i].header; i++)
 | ||||||
|  | -		if ((rc = print_strbuf(buff, "%%%c  %s\n",
 | ||||||
|  | -				       pgd[i].wildcard, pgd[i].header)) < 0)
 | ||||||
|  | -			return rc;
 | ||||||
|  | -
 | ||||||
|  |  	return get_strbuf_len(buff) - initial_len; | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										32
									
								
								0115-libmultipath-print-all-values-in-snprint_failback.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								0115-libmultipath-print-all-values-in-snprint_failback.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Wed, 8 May 2024 19:02:30 -0400 | ||||||
|  | Subject: [PATCH] libmultipath: print all values in snprint_failback | ||||||
|  | 
 | ||||||
|  | Add the missing output for manual failback and print the defferral time | ||||||
|  | for deferred failbacks, if one isn't currently in progress. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/print.c | 6 +++++- | ||||||
|  |  1 file changed, 5 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/print.c b/libmultipath/print.c
 | ||||||
|  | index a6e4c774..535e0271 100644
 | ||||||
|  | --- a/libmultipath/print.c
 | ||||||
|  | +++ b/libmultipath/print.c
 | ||||||
|  | @@ -199,9 +199,13 @@ snprint_failback (struct strbuf *buff, const struct multipath * mpp)
 | ||||||
|  |  		return append_strbuf_str(buff, "immediate"); | ||||||
|  |  	if (mpp->pgfailback == -FAILBACK_FOLLOWOVER) | ||||||
|  |  		return append_strbuf_str(buff, "followover"); | ||||||
|  | +	if (mpp->pgfailback == -FAILBACK_MANUAL)
 | ||||||
|  | +		return append_strbuf_str(buff, "manual");
 | ||||||
|  | +	if (mpp->pgfailback == FAILBACK_UNDEF)
 | ||||||
|  | +		return append_strbuf_str(buff, "undef");
 | ||||||
|  |   | ||||||
|  |  	if (!mpp->failback_tick) | ||||||
|  | -		return append_strbuf_str(buff, "-");
 | ||||||
|  | +		return print_strbuf(buff, "%i", mpp->pgfailback);
 | ||||||
|  |  	else | ||||||
|  |  		return snprint_progress(buff, mpp->failback_tick, | ||||||
|  |  					mpp->pgfailback); | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Thu, 9 May 2024 12:58:11 -0400 | ||||||
|  | Subject: [PATCH] multipathd: Stop double counting map failures for | ||||||
|  |  no_path_retry > 0 | ||||||
|  | 
 | ||||||
|  | If no_path_retry was greater than 0, multipathd was counting a map | ||||||
|  | failure when recovery mode was entered, and again when queueing was | ||||||
|  | disabled. The first one is incorrect, since the map is still queueing. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/structs_vec.c | 5 ++++- | ||||||
|  |  1 file changed, 4 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
 | ||||||
|  | index 56915e96..b8e304e0 100644
 | ||||||
|  | --- a/libmultipath/structs_vec.c
 | ||||||
|  | +++ b/libmultipath/structs_vec.c
 | ||||||
|  | @@ -781,10 +781,13 @@ int verify_paths(struct multipath *mpp)
 | ||||||
|  |  void update_queue_mode_del_path(struct multipath *mpp) | ||||||
|  |  { | ||||||
|  |  	int active = count_active_paths(mpp); | ||||||
|  | +	bool is_queueing = mpp->features &&
 | ||||||
|  | +			   strstr(mpp->features, "queue_if_no_path");
 | ||||||
|  |   | ||||||
|  |  	if (active == 0) { | ||||||
|  |  		enter_recovery_mode(mpp); | ||||||
|  | -		if (mpp->no_path_retry != NO_PATH_RETRY_QUEUE)
 | ||||||
|  | +		if (mpp->no_path_retry == NO_PATH_RETRY_FAIL ||
 | ||||||
|  | +		    (mpp->no_path_retry == NO_PATH_RETRY_UNDEF && !is_queueing))
 | ||||||
|  |  			mpp->stat_map_failures++; | ||||||
|  |  	} | ||||||
|  |  	condlog(2, "%s: remaining active paths: %d", mpp->alias, active); | ||||||
							
								
								
									
										102
									
								
								0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Thu, 9 May 2024 17:15:34 -0400 | ||||||
|  | Subject: [PATCH] multipath-tools man pages: add missing multipathd commands | ||||||
|  | 
 | ||||||
|  | Also, the description for "del map $map" was incorrect. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  multipathd/multipathd.8 | 42 ++++++++++++++++++++++++++++++++++++----- | ||||||
|  |  1 file changed, 37 insertions(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
 | ||||||
|  | index 8bd47a80..40a8dc6d 100644
 | ||||||
|  | --- a/multipathd/multipathd.8
 | ||||||
|  | +++ b/multipathd/multipathd.8
 | ||||||
|  | @@ -100,18 +100,24 @@ The following commands can be used in interactive mode:
 | ||||||
|  |  Show the paths that multipathd is monitoring, and their state. | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  | -.B list|show paths format $format
 | ||||||
|  | +.B list|show paths [raw] format $format
 | ||||||
|  |  Show the paths that multipathd is monitoring, using a format string with path | ||||||
|  | -format wildcards.
 | ||||||
|  | +format wildcards. Adding \fIraw\fR will remove the headers and alignment
 | ||||||
|  | +padding from the ouput.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B list|show path $path
 | ||||||
|  | +Show whether path $path is offline or running.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show maps|multipaths | ||||||
|  |  Show the multipath devices that the multipathd is monitoring. | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  | -.B list|show maps|multipaths format $format
 | ||||||
|  | +.B list|show maps|multipaths [raw] format $format
 | ||||||
|  |  Show the status of all multipath devices that the multipathd is monitoring, | ||||||
|  | -using a format string with multipath format wildcards.
 | ||||||
|  | +using a format string with multipath format wildcards. Adding \fIraw\fR will
 | ||||||
|  | +remove the headers and alignment padding from the output.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show maps|multipaths status | ||||||
|  | @@ -124,6 +130,10 @@ Show some statistics of all multipath devices that the multipathd is monitoring.
 | ||||||
|  |  .TP | ||||||
|  |  .B list|show maps|multipaths topology | ||||||
|  |  Show the current multipath topology. Same as '\fImultipath \-ll\fR'. | ||||||
|  | +.TP
 | ||||||
|  | +.
 | ||||||
|  | +.B list|show maps|multipaths json
 | ||||||
|  | +Show information about all multipath devices in JSON format.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show topology | ||||||
|  | @@ -135,6 +145,16 @@ Show topology of a single multipath device specified by $map, for example
 | ||||||
|  |  36005076303ffc56200000000000010aa. This map could be obtained from '\fIlist maps\fR'. | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  | +.B list|show map|multipath $map [raw] format $format.
 | ||||||
|  | +Show the status of multipath device $map, using a format string with multipath
 | ||||||
|  | +format wildcards. Adding \fIraw\fR will remove the headers and alignment
 | ||||||
|  | +padding from the output.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B list|show map|multipath $map json
 | ||||||
|  | +Show information about multipath device $map in JSON format.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  |  .B list|show wildcards | ||||||
|  |  Show the format wildcards used in interactive commands taking $format. | ||||||
|  |  . | ||||||
|  | @@ -168,6 +188,14 @@ paths, and whether multipathd is currently handling a uevent.
 | ||||||
|  |  Show the current state of the multipathd daemon. | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  | +.B reset maps|multipaths stats
 | ||||||
|  | +Reset the statistics of all multipath devices.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B reset map|multipath $map stats
 | ||||||
|  | +Reset the statistics of multipath device $map.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  |  .B add path $path | ||||||
|  |  Add a path to the list of monitored paths. $path is as listed in /sys/block (e.g. sda). | ||||||
|  |  . | ||||||
|  | @@ -183,8 +211,12 @@ for the multipath device (e.g. mpath1) or the uid of the multipath device
 | ||||||
|  |  (e.g. 36005076303ffc56200000000000010aa). | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  | +.B remove|del maps|multipaths
 | ||||||
|  | +Remove all multipath devices.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  |  .B remove|del map|multipath $map | ||||||
|  | -Stop monitoring a multipath device.
 | ||||||
|  | +Remove the multipath device $map.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B resize map|multipath $map | ||||||
							
								
								
									
										54
									
								
								0118-libmultipath-change-the-vend-prod-rev-printing.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								0118-libmultipath-change-the-vend-prod-rev-printing.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Fri, 10 May 2024 15:36:10 -0400 | ||||||
|  | Subject: [PATCH] libmultipath: change the vend/prod/rev printing | ||||||
|  | 
 | ||||||
|  | The %s multipath and path wildcards both say they print the device | ||||||
|  | vend/prod/rev string, but neither of them do. The multipath wildcards | ||||||
|  | already provide a way to print the revision string and the %s wildcard | ||||||
|  | is used in the multipath -l output, so leave the wildcard output alone, | ||||||
|  | and change the description to only mention the vendor and product. There | ||||||
|  | is no other way to print the revision by path, and the path %s wildcard | ||||||
|  | is only used in the verbose multipath output, so make it actually print | ||||||
|  | the revision. Also check for unset strings, and print "##" instead of | ||||||
|  | nothing. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  libmultipath/print.c | 9 ++++++--- | ||||||
|  |  1 file changed, 6 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/libmultipath/print.c b/libmultipath/print.c
 | ||||||
|  | index 535e0271..4552fd43 100644
 | ||||||
|  | --- a/libmultipath/print.c
 | ||||||
|  | +++ b/libmultipath/print.c
 | ||||||
|  | @@ -309,7 +309,7 @@ snprint_multipath_uuid (struct strbuf *buff, const struct multipath * mpp)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  | -snprint_multipath_vpr (struct strbuf *buff, const struct multipath * mpp)
 | ||||||
|  | +snprint_multipath_vp (struct strbuf *buff, const struct multipath * mpp)
 | ||||||
|  |  { | ||||||
|  |  	struct pathgroup * pgp; | ||||||
|  |  	struct path * pp; | ||||||
|  | @@ -511,7 +511,10 @@ snprint_dm_path_state (struct strbuf *buff, const struct path * pp)
 | ||||||
|  |  static int | ||||||
|  |  snprint_vpr (struct strbuf *buff, const struct path * pp) | ||||||
|  |  { | ||||||
|  | -	return print_strbuf(buff, "%s,%s", pp->vendor_id, pp->product_id);
 | ||||||
|  | +	return print_strbuf(buff, "%s,%s,%s",
 | ||||||
|  | +			    strlen(pp->vendor_id) ? pp->vendor_id : "##",
 | ||||||
|  | +			    strlen(pp->product_id) ? pp->product_id : "##",
 | ||||||
|  | +			    strlen(pp->rev) ? pp->rev : "##");
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  | @@ -743,7 +746,7 @@ struct multipath_data mpd[] = {
 | ||||||
|  |  	{'2', "map_loads",     0, snprint_map_loads}, | ||||||
|  |  	{'3', "total_q_time",  0, snprint_total_q_time}, | ||||||
|  |  	{'4', "q_timeouts",    0, snprint_q_timeouts}, | ||||||
|  | -	{'s', "vend/prod/rev", 0, snprint_multipath_vpr},
 | ||||||
|  | +	{'s', "vend/prod",     0, snprint_multipath_vp},
 | ||||||
|  |  	{'v', "vend",          0, snprint_multipath_vend}, | ||||||
|  |  	{'p', "prod",          0, snprint_multipath_prod}, | ||||||
|  |  	{'e', "rev",           0, snprint_multipath_rev}, | ||||||
							
								
								
									
										243
									
								
								0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | Date: Fri, 10 May 2024 20:53:33 -0400 | ||||||
|  | Subject: [PATCH] multipath-tools man pages: Add format wildcard descriptions | ||||||
|  | 
 | ||||||
|  | Suggested-by: Nitin Yewale <nyewale@redhat.com> | ||||||
|  | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  multipathd/multipathd.8 | 193 +++++++++++++++++++++++++++++++++++++++- | ||||||
|  |  1 file changed, 189 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
 | ||||||
|  | index 40a8dc6d..d834f89e 100644
 | ||||||
|  | --- a/multipathd/multipathd.8
 | ||||||
|  | +++ b/multipathd/multipathd.8
 | ||||||
|  | @@ -103,7 +103,7 @@ Show the paths that multipathd is monitoring, and their state.
 | ||||||
|  |  .B list|show paths [raw] format $format | ||||||
|  |  Show the paths that multipathd is monitoring, using a format string with path | ||||||
|  |  format wildcards. Adding \fIraw\fR will remove the headers and alignment | ||||||
|  | -padding from the ouput.
 | ||||||
|  | +padding from the output. See "Path format wildcards" below.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show path $path | ||||||
|  | @@ -117,7 +117,8 @@ Show the multipath devices that the multipathd is monitoring.
 | ||||||
|  |  .B list|show maps|multipaths [raw] format $format | ||||||
|  |  Show the status of all multipath devices that the multipathd is monitoring, | ||||||
|  |  using a format string with multipath format wildcards. Adding \fIraw\fR will | ||||||
|  | -remove the headers and alignment padding from the output.
 | ||||||
|  | +remove the headers and alignment padding from the output. See "Multipath
 | ||||||
|  | +format wildcards" below.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show maps|multipaths status | ||||||
|  | @@ -148,7 +149,7 @@ Show topology of a single multipath device specified by $map, for example
 | ||||||
|  |  .B list|show map|multipath $map [raw] format $format. | ||||||
|  |  Show the status of multipath device $map, using a format string with multipath | ||||||
|  |  format wildcards. Adding \fIraw\fR will remove the headers and alignment | ||||||
|  | -padding from the output.
 | ||||||
|  | +padding from the output. See "Multipath format wildcards" below.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show map|multipath $map json | ||||||
|  | @@ -156,7 +157,8 @@ Show information about multipath device $map in JSON format.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show wildcards | ||||||
|  | -Show the format wildcards used in interactive commands taking $format.
 | ||||||
|  | +Show the format wildcards used in interactive commands taking $format. See
 | ||||||
|  | +"Format Wildcards" below.
 | ||||||
|  |  . | ||||||
|  |  .TP | ||||||
|  |  .B list|show config | ||||||
|  | @@ -339,6 +341,189 @@ Stop multipathd.
 | ||||||
|  |  . | ||||||
|  |  . | ||||||
|  |  .\" ---------------------------------------------------------------------------- | ||||||
|  | +.SH "Format Wildcards"
 | ||||||
|  | +.\" ----------------------------------------------------------------------------
 | ||||||
|  | +.
 | ||||||
|  | +Multipathd commands that take a $format option require a format string. This
 | ||||||
|  | +string controls how a device is printed and should include format wildcards.
 | ||||||
|  | +When the devices are printed, these wildcards will be replaced by the
 | ||||||
|  | +appropriate device information. The following wildcards are supported.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B Multipath format wildcards
 | ||||||
|  | +.RS
 | ||||||
|  | +.TP 12
 | ||||||
|  | +.B %n
 | ||||||
|  | +The device name.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %w
 | ||||||
|  | +The device WWID (uuid).
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %d
 | ||||||
|  | +The device sysfs name (dm-<minor_nr>).
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %F
 | ||||||
|  | +The device \fBfailback\fR setting. For deferred failbacks, it will either
 | ||||||
|  | +print the configured time if a deferred failback is not in progress, or
 | ||||||
|  | +it will show the current progress of a deferred failback.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %Q
 | ||||||
|  | +The device \fBno_path_retry\fR setting. If no_path_retry is set to a
 | ||||||
|  | +number of retires, it will either print the configured number of checker
 | ||||||
|  | +retries if the device is not in recovery mode, the number of seconds until
 | ||||||
|  | +queueing is disabled if the device is queueing in recovery mode, or \fIoff\fR
 | ||||||
|  | +if the device has disabled queueing.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %N
 | ||||||
|  | +The number of active paths for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %r
 | ||||||
|  | +The device write-protect setting, either \fIro\fR or \fIrw\fR.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %t
 | ||||||
|  | +The device-mapper state of the device, either \fIsuspend\fR or \fIactive\fR.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %S
 | ||||||
|  | +The device size.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %f
 | ||||||
|  | +The device table features string.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %x
 | ||||||
|  | +The number of times the device has entered a state where it will fail IO.
 | ||||||
|  | +This is an alias for the \fB%4\fR wildcard.
 | ||||||
|  | +This value can be reset with the '\fIreset map $map stats\fR' command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %h
 | ||||||
|  | +The device table hardware handler string.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %A
 | ||||||
|  | +The last action multipathd took on the device. This wildcard is for debugging
 | ||||||
|  | +use, as understanding its meaning requires looking at the code.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %0
 | ||||||
|  | +The number of times a path in the device has failed.
 | ||||||
|  | +This value can be reset with the '\fIreset map $map stats\fR' command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %1
 | ||||||
|  | +The number of times multipathd has initiated a pathgroup switch for the device.
 | ||||||
|  | +This value can be reset with the '\fIreset map $map stats\fR' command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %2
 | ||||||
|  | +The number of times multipathd has loaded a new table for the device.
 | ||||||
|  | +This value can be reset with the '\fIreset map $map stats\fR' command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %3
 | ||||||
|  | +The approximate number of seconds that multipathd has spent queueing with
 | ||||||
|  | +no usable paths. This value can be reset with the '\fIreset map $map stats\fR'
 | ||||||
|  | +command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %4
 | ||||||
|  | +The number of times the device has entered a state where it will fail IO.
 | ||||||
|  | +This is an alias for the \fB%x\fR wildcard.
 | ||||||
|  | +This value can be reset with the '\fIreset map $map stats\fR' command.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %s
 | ||||||
|  | +The vendor/product string for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %v
 | ||||||
|  | +The array vendor string for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %p
 | ||||||
|  | +The array product string for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %e
 | ||||||
|  | +The array firmware revision string for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %G
 | ||||||
|  | +The foreign library used for the device, or \fB--\fR for native device-mapper
 | ||||||
|  | +multipath devices.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %g
 | ||||||
|  | +Data from vendor specific vpd pages for the device, if any.
 | ||||||
|  | +.RE
 | ||||||
|  | +.
 | ||||||
|  | +.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B Path format wildcards
 | ||||||
|  | +.RS
 | ||||||
|  | +.TP 12
 | ||||||
|  | +.B %w
 | ||||||
|  | +The device WWID (uuid).
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %i
 | ||||||
|  | +The device Host:Channel:Id:Lun
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %d
 | ||||||
|  | +The device sysfs name.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %D
 | ||||||
|  | +The device major:minor
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %t
 | ||||||
|  | +The device-mapper state of the device, either \fIactive\fR or \fIfailed\fR.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %o
 | ||||||
|  | +Whether the device is \fIoffline\fR or \fIrunning\fR.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %T
 | ||||||
|  | +The multipathd path checker state of the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %s
 | ||||||
|  | +The vendor/product/revision string for the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %c
 | ||||||
|  | +The device's path checker name.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %C
 | ||||||
|  | +The progress towards the next path checker run on the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %p
 | ||||||
|  | +The device priority.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %S
 | ||||||
|  | +The device size.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %z
 | ||||||
|  | +The device serial number.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %M
 | ||||||
|  | +The device marginal state, either \fImarginal\fR or \fInormal\fR.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %m
 | ||||||
|  | +The multipath device that this device is a path of.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %N
 | ||||||
|  | +The host World Wide Node Name (WWNN) of the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %n
 | ||||||
|  | +The target World Wide Node Name (WWNN) of the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %R
 | ||||||
|  | +The host World Wide Port Name (WWPN) of the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %r
 | ||||||
|  | +The target World Wide Port Name (WWPN) of the device.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %a
 | ||||||
|  | +The host adapter name for the device (only SCSI devices).
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %G
 | ||||||
|  | +The foreign library used for the device, or \fB--\fR for paths of native
 | ||||||
|  | +device-mapper multipath devices.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %g
 | ||||||
|  | +Data from vendor specific vpd pages for the device, if any.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %0
 | ||||||
|  | +The number of times this device has failed.
 | ||||||
|  | +.TP
 | ||||||
|  | +.B %P
 | ||||||
|  | +The device protocol. This output can be used for \fIprotocol\fR blacklist
 | ||||||
|  | +entries.
 | ||||||
|  | +.RE
 | ||||||
|  | +.
 | ||||||
|  | +.
 | ||||||
|  | +.\" ----------------------------------------------------------------------------
 | ||||||
|  |  .SH "SYSTEMD INTEGRATION" | ||||||
|  |  .\" ---------------------------------------------------------------------------- | ||||||
|  |  . | ||||||
| @ -1,6 +1,6 @@ | |||||||
| Name:    device-mapper-multipath | Name:    device-mapper-multipath | ||||||
| Version: 0.8.7 | Version: 0.8.7 | ||||||
| Release: 28%{?dist} | Release: 29%{?dist} | ||||||
| Summary: Tools to manage multipath devices using device-mapper | Summary: Tools to manage multipath devices using device-mapper | ||||||
| License: GPLv2 | License: GPLv2 | ||||||
| URL:     http://christophe.varoqui.free.fr/ | URL:     http://christophe.varoqui.free.fr/ | ||||||
| @ -119,6 +119,16 @@ Patch0106: 0106-multipathd-fix-auto-resize-configuration.patch | |||||||
| Patch0107: 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch | Patch0107: 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch | ||||||
| Patch0108: 0108-libmultipath-actually-truncate-too-large-vpd-page.patch | Patch0108: 0108-libmultipath-actually-truncate-too-large-vpd-page.patch | ||||||
| Patch0109: 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch | Patch0109: 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch | ||||||
|  | Patch0110: 0110-libmultipath-keep-track-of-queueing-state-in-feature.patch | ||||||
|  | Patch0111: 0111-libmultipath-export-partmap_in_use.patch | ||||||
|  | Patch0112: 0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch | ||||||
|  | Patch0113: 0113-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch | ||||||
|  | Patch0114: 0114-libmultipath-remove-pathgroup-wildcard-options.patch | ||||||
|  | Patch0115: 0115-libmultipath-print-all-values-in-snprint_failback.patch | ||||||
|  | Patch0116: 0116-multipathd-Stop-double-counting-map-failures-for-no_.patch | ||||||
|  | Patch0117: 0117-multipath-tools-man-pages-add-missing-multipathd-com.patch | ||||||
|  | Patch0118: 0118-libmultipath-change-the-vend-prod-rev-printing.patch | ||||||
|  | Patch0119: 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # runtime | # runtime | ||||||
| @ -322,6 +332,22 @@ fi | |||||||
| %{_pkgconfdir}/libdmmp.pc | %{_pkgconfdir}/libdmmp.pc | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Tue May 21 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-29 | ||||||
|  | - Add 0110-libmultipath-keep-track-of-queueing-state-in-feature.patch | ||||||
|  | - Add 0111-libmultipath-export-partmap_in_use.patch | ||||||
|  | - Add 0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch | ||||||
|  | - Add 0113-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch | ||||||
|  |   * Fixes RHEL-30272 | ||||||
|  | - Add 0114-libmultipath-remove-pathgroup-wildcard-options.patch | ||||||
|  | - Add 0115-libmultipath-print-all-values-in-snprint_failback.patch | ||||||
|  | - Add 0116-multipathd-Stop-double-counting-map-failures-for-no_.patch | ||||||
|  | - Add 0117-multipath-tools-man-pages-add-missing-multipathd-com.patch | ||||||
|  | - Add 0118-libmultipath-change-the-vend-prod-rev-printing.patch | ||||||
|  | - Add 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch | ||||||
|  |   * Fixes RHEL-8304 | ||||||
|  | - Resolves: RHEL-8304 | ||||||
|  | - Resolves: RHEL-30272 | ||||||
|  | 
 | ||||||
| * Tue Apr  9 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-28 | * Tue Apr  9 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-28 | ||||||
| - Add 0108-libmultipath-actually-truncate-too-large-vpd-page.patch | - Add 0108-libmultipath-actually-truncate-too-large-vpd-page.patch | ||||||
| - Add 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch | - Add 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user