Re: [PATCH 14/35] multipathd: add "force_reconfigure" option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Sep 10, 2021 at 01:40:59PM +0200, mwilck@xxxxxxxx wrote:
> From: Martin Wilck <mwilck@xxxxxxxx>
> 
> Since e3270f7 ("multipathd: use weaker "force_reload" at startup"),
> (multipath-tools 0.7.0), we only reload those maps that must be
> reloaded during startup. "multipath reconfigure", OTOH, reloads
> every map, which may take a long time on systems with lots of
> storage devices, as every DM_DEVICE_RELOAD ioctl involves a
> suspend/resume cycle.
> 
> The logic we use during startup is actually very robust and catches
> all cases in which a reload is necessary. "reconfigure" operations
> are often done because of configuration changes, and usually don't
> require a full reload of every map.
> 
> This patch changes the default behavior of "multipath reconfigure"
> to "weak" reload, like we do on startup since e3270f7. The behavior
> can be changed by setting the configuration option
> "force_reconfigure yes" before starting the reconfigure operation.
> "multipath -r" is also affected, but "multipath -D -r" is not.
> 
> It would have been nice to have introduced a new cli command
> "reconfigure force" instead, but the way "reconfigure" is
> implemented, that would have required a major rewrite of the code.

This looks o.k. But I don't think it would be that hard to add a new
multipathd command to reconfigure all the devices.  My personal
preference would be to leave force_reconfigure off by default, so that
we keep the same behavior, and add a command to force a full reconfig.
I'll try to work up a patch with my idea that can apply on top of this.

But the code itself looks fine, and if we don't agree on my patch, I can
always just change the default for the RHEL version, at least until the
next major release, so

Reviewed-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx>

> 
> Signed-off-by: Martin Wilck <mwilck@xxxxxxxx>
> ---
>  libmultipath/config.c      |  1 +
>  libmultipath/config.h      |  1 +
>  libmultipath/configure.c   | 19 ++++++++++++++++++-
>  libmultipath/defaults.h    |  1 +
>  libmultipath/dict.c        |  4 ++++
>  multipath/multipath.8      |  6 ++++--
>  multipath/multipath.conf.5 | 17 +++++++++++++++++
>  multipathd/main.c          | 18 +++++-------------
>  multipathd/multipathd.8    |  6 ++++--
>  9 files changed, 55 insertions(+), 18 deletions(-)
> 
> diff --git a/libmultipath/config.c b/libmultipath/config.c
> index 30046a1..a1ef4c3 100644
> --- a/libmultipath/config.c
> +++ b/libmultipath/config.c
> @@ -869,6 +869,7 @@ int _init_config (const char *file, struct config *conf)
>  	conf->ghost_delay = DEFAULT_GHOST_DELAY;
>  	conf->all_tg_pt = DEFAULT_ALL_TG_PT;
>  	conf->recheck_wwid = DEFAULT_RECHECK_WWID;
> +	conf->force_reconfigure = DEFAULT_FORCE_RECONFIGURE;
>  	/*
>  	 * preload default hwtable
>  	 */
> diff --git a/libmultipath/config.h b/libmultipath/config.h
> index 933fe0d..4617177 100644
> --- a/libmultipath/config.h
> +++ b/libmultipath/config.h
> @@ -189,6 +189,7 @@ struct config {
>  	int skip_delegate;
>  	unsigned int sequence_nr;
>  	int recheck_wwid;
> +	int force_reconfigure;
>  
>  	char * multipath_dir;
>  	char * selector;
> diff --git a/libmultipath/configure.c b/libmultipath/configure.c
> index 7edb355..262657e 100644
> --- a/libmultipath/configure.c
> +++ b/libmultipath/configure.c
> @@ -1093,12 +1093,27 @@ out:
>  	return ret;
>  }
>  
> +static const char* reconfigure_str(int force)
> +{
> +	switch(force) {
> +	case FORCE_RELOAD_NONE:
> +		return "new";
> +	case FORCE_RELOAD_WEAK:
> +		return "changed";
> +	case FORCE_RELOAD_YES:
> +		return "all";
> +	default:
> +		return "<undefined>";
> +	}
> +}
> +
>  /*
>   * The force_reload parameter determines how coalesce_paths treats existing maps.
>   * FORCE_RELOAD_NONE: existing maps aren't touched at all
>   * FORCE_RELOAD_YES: all maps are rebuilt from scratch and (re)loaded in DM
>   * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only
> - * reloaded in DM if there's a difference. This is useful during startup.
> + * reloaded in DM if there's a difference. This is normally sufficient.
> + * This is controlled by the "force_reconfigure" config option.
>   */
>  int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
>  		    int force_reload, enum mpath_cmds cmd)
> @@ -1117,6 +1132,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
>  	int allow_queueing;
>  	struct bitfield *size_mismatch_seen;
>  
> +	condlog(2, "%s: reloading %s maps", __func__,
> +		reconfigure_str(force_reload));
>  	/* ignore refwwid if it's empty */
>  	if (refwwid && !strlen(refwwid))
>  		refwwid = NULL;
> diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
> index c27946c..eab08a0 100644
> --- a/libmultipath/defaults.h
> +++ b/libmultipath/defaults.h
> @@ -56,6 +56,7 @@
>  #define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF
>  /* Enable no foreign libraries by default */
>  #define DEFAULT_ENABLE_FOREIGN "NONE"
> +#define DEFAULT_FORCE_RECONFIGURE YN_NO
>  
>  #define CHECKINT_UNDEF		UINT_MAX
>  #define DEFAULT_CHECKINT	5
> diff --git a/libmultipath/dict.c b/libmultipath/dict.c
> index 7a72738..fee08cf 100644
> --- a/libmultipath/dict.c
> +++ b/libmultipath/dict.c
> @@ -299,6 +299,9 @@ declare_def_snprint(verbosity, print_int)
>  declare_def_handler(reassign_maps, set_yes_no)
>  declare_def_snprint(reassign_maps, print_yes_no)
>  
> +declare_def_handler(force_reconfigure, set_yes_no)
> +declare_def_snprint(force_reconfigure, print_yes_no)
> +
>  declare_def_handler(multipath_dir, set_str)
>  declare_def_snprint(multipath_dir, print_str)
>  
> @@ -1713,6 +1716,7 @@ init_keywords(vector keywords)
>  	install_keyword("polling_interval", &checkint_handler, &snprint_def_checkint);
>  	install_keyword("max_polling_interval", &def_max_checkint_handler, &snprint_def_max_checkint);
>  	install_keyword("reassign_maps", &def_reassign_maps_handler, &snprint_def_reassign_maps);
> +	install_keyword("force_reconfigure", &def_force_reconfigure_handler, &snprint_def_force_reconfigure);
>  	install_keyword("multipath_dir", &def_multipath_dir_handler, &snprint_def_multipath_dir);
>  	install_keyword("path_selector", &def_selector_handler, &snprint_def_selector);
>  	install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_pgpolicy);
> diff --git a/multipath/multipath.8 b/multipath/multipath.8
> index 17df59f..b3980c0 100644
> --- a/multipath/multipath.8
> +++ b/multipath/multipath.8
> @@ -264,9 +264,11 @@ Force new maps to use the specified policy, overriding the configuration in
>  .
>  .TP
>  .B \-r
> -Force a reload of all existing multipath maps. This command is delegated to
> +Reload existing multipath maps. This command is delegated to
>  the multipathd daemon if it's running. In this case, other command line
> -switches of the \fImultipath\fR command have no effect.
> +switches of the \fImultipath\fR command have no effect, and multipathd
> +executes a \fIreconfigure\fR command. See the \fIforce_reconfigure\fR option
> +in \fBmultipath.conf(5)\fR.
>  .
>  .TP
>  .BI \-R " retries"
> diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
> index 42a15ff..814de66 100644
> --- a/multipath/multipath.conf.5
> +++ b/multipath/multipath.conf.5
> @@ -34,6 +34,7 @@ or \fBmultipathd show config\fR command.
>  .SH SYNTAX
>  .\" ----------------------------------------------------------------------------
>  .
> +.
>  The configuration file contains entries of the form:
>  .RS
>  .nf
> @@ -165,6 +166,22 @@ The default is: \fB4 * polling_interval\fR
>  .
>  .
>  .TP
> +.B force_reconfigure
> +This controls what happens when \fBmultipathd reconfigure\fR or
> +\fBmultipath -r\fR is executed. If set to \fIyes\fR, all multipath
> +maps will be reloaded, regardless if this is necessary or not, which
> +may take a lot of time on large systems. This used to be the default
> +on previous versions of multipath-tools. If set to \fIno\fR,
> +only those maps will be reloaded for which some parameters
> +have changed that are relevant for the device-mapper configuration of the map.
> +This is the behavior during \fImultipathd\fR startup.
> +.RS
> +.TP
> +The default is: \fBno\fR
> +.RE
> +.
> +.
> +.TP
>  .B reassign_maps
>  Enable reassigning of device-mapper maps. With this option multipathd
>  will remap existing device-mapper maps to always point to multipath
> diff --git a/multipathd/main.c b/multipathd/main.c
> index bda51c9..6d7c8c9 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -2594,14 +2594,13 @@ checkerloop (void *ap)
>  }
>  
>  int
> -configure (struct vectors * vecs)
> +configure (struct vectors *vecs, bool force)
>  {
>  	struct multipath * mpp;
>  	struct path * pp;
>  	vector mpvec;
>  	int i, ret;
>  	struct config *conf;
> -	static int force_reload = FORCE_RELOAD_WEAK;
>  
>  	if (!vecs->pathvec && !(vecs->pathvec = vector_alloc())) {
>  		condlog(0, "couldn't allocate path vec in configure");
> @@ -2649,15 +2648,9 @@ configure (struct vectors * vecs)
>  	if (should_exit())
>  		goto fail;
>  
> -	/*
> -	 * create new set of maps & push changed ones into dm
> -	 * In the first call, use FORCE_RELOAD_WEAK to avoid making
> -	 * superfluous ACT_RELOAD ioctls. Later calls are done
> -	 * with FORCE_RELOAD_YES.
> -	 */
> -	ret = coalesce_paths(vecs, mpvec, NULL, force_reload, CMD_NONE);
> -	if (force_reload == FORCE_RELOAD_WEAK)
> -		force_reload = FORCE_RELOAD_YES;
> +	ret = coalesce_paths(vecs, mpvec, NULL,
> +			     force ? FORCE_RELOAD_YES : FORCE_RELOAD_WEAK,
> +			     CMD_NONE);
>  	if (ret != CP_OK) {
>  		condlog(0, "configure failed while coalescing paths");
>  		goto fail;
> @@ -2769,8 +2762,7 @@ reconfigure (struct vectors * vecs)
>  	rcu_assign_pointer(multipath_conf, conf);
>  	call_rcu(&old->rcu, rcu_free_config);
>  
> -	configure(vecs);
> -
> +	configure(vecs, conf->force_reconfigure == YN_YES);
>  
>  	return 0;
>  }
> diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
> index 048a838..b52a617 100644
> --- a/multipathd/multipathd.8
> +++ b/multipathd/multipathd.8
> @@ -195,8 +195,10 @@ group index, starting with 1.
>  .
>  .TP
>  .B reconfigure
> -Reconfigures the multipaths. This should be triggered automatically after anyi
> -hotplug event.
> +Reconfigure the multipaths. This is only necessary after applying configuration
> +changes, as multipathd sets up new devices automatically. See the
> +\fIforce_reconfigure\fR option in \fBmultipath.conf(5)\fR. Note that multipathd
> +can't process most commands while reconfiguring.
>  .
>  .TP
>  .B suspend map|multipath $map
> -- 
> 2.33.0

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/dm-devel




[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux