[dm-devel] [PATCH v2 11/20] libmultipath: don't try to set up failed wwids again

Benjamin Marzinski bmarzins at redhat.com
Mon Mar 26 18:47:19 UTC 2018


On Mon, Mar 19, 2018 at 04:01:46PM +0100, Martin Wilck wrote:
> Once setting up a map has failed, don't try to set it up again.
> This applies to "multipathd reconfigure" and even multipathd restart,
> too. That's deliberate - if a WWID is marked as failed, we don't wont
> to bother with it again, unless the admin explicitly tells us so.
> Specifically, the exceptions are:
> 
>  1) multipathd add map $MAP
>  2) multipathd add path $PATH
>  3) multipath $PATH
> 
> In these cases, addmap() will eventually be called again, and the failed
> flag will be set according to it's return status. Unless the reason for
> the previous failure has been fixed, it may well be "failed" again.
> 
> Inofficially, it's also possible to manually remove a failed marker under
> /dev/shm/multipath/failed_wwids and run "multipathd reconfigure".

The code looks fine, but I wonder why this is necessary.  You already
posted patches that let multipathd issue uevent to claim a path device
after if it was not previously claimed. I admit that you don't generally
see multipathd succeed in creating a device after failing to, but it's
easy to imagine situations where it could.  For instance, if a path
device appears and then disappears soon after, multipathd would fail to
create the device because when the path device finally reappeared for
good.

I see that this will keep multipathd from needlessly retrying in-use
devices whenever a path comes or goes, but I don't know of any harm that
has ever caused, and I can see this causing harm. Am I missing something
here?

-Ben

> 
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
>  libmultipath/configure.c  |  5 +++--
>  libmultipath/configure.h  |  3 ++-
>  libmultipath/wwids.c      |  7 ++++++-
>  libmultipath/wwids.h      |  3 ++-
>  multipath/main.c          | 12 +++++++++---
>  multipathd/cli_handlers.c |  5 +++--
>  multipathd/main.c         | 13 +++++++------
>  multipathd/main.h         |  8 ++++++++
>  8 files changed, 40 insertions(+), 16 deletions(-)
> 
> diff --git a/libmultipath/configure.c b/libmultipath/configure.c
> index 88e6687849f8..98b80337d899 100644
> --- a/libmultipath/configure.c
> +++ b/libmultipath/configure.c
> @@ -981,7 +981,7 @@ out:
>   * reloaded in DM if there's a difference. This is useful during startup.
>   */
>  int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> -		    int force_reload, enum mpath_cmds cmd)
> +		    int force_reload, bool retry_failed, enum mpath_cmds cmd)
>  {
>  	int r = 1;
>  	int k, i;
> @@ -1032,7 +1032,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
>  			continue;
>  
>  		/* If find_multipaths was selected check if the path is valid */
> -		if (!refwwid && !should_multipath(pp1, pathvec, curmp)) {
> +		if (!refwwid && !should_multipath(pp1, pathvec, curmp,
> +						  retry_failed)) {
>  			orphan_path(pp1, "only one path");
>  			continue;
>  		}
> diff --git a/libmultipath/configure.h b/libmultipath/configure.h
> index 8b56d33a1d0b..7e175c890d25 100644
> --- a/libmultipath/configure.h
> +++ b/libmultipath/configure.h
> @@ -32,7 +32,8 @@ int setup_map (struct multipath * mpp, char * params, int params_size,
>  	       struct vectors *vecs );
>  int domap (struct multipath * mpp, char * params, int is_daemon);
>  int reinstate_paths (struct multipath *mpp);
> -int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload, enum mpath_cmds cmd);
> +int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid,
> +		    int force_reload, bool retry_failed, enum mpath_cmds cmd);
>  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);
> diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
> index e0fdcb34dbc6..288a9ad50c73 100644
> --- a/libmultipath/wwids.c
> +++ b/libmultipath/wwids.c
> @@ -4,6 +4,7 @@
>  #include <string.h>
>  #include <limits.h>
>  #include <stdio.h>
> +#include <stdbool.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
>  
> @@ -273,12 +274,16 @@ out:
>  }
>  
>  int
> -should_multipath(struct path *pp1, vector pathvec, vector mpvec)
> +should_multipath(struct path *pp1, vector pathvec, vector mpvec,
> +		 bool retry_failed)
>  {
>  	int i, ignore_new;
>  	struct path *pp2;
>  	struct config *conf;
>  
> +	if (!retry_failed && is_failed_wwid(pp1->wwid))
> +		return 0;
> +
>  	conf = get_multipath_config();
>  	ignore_new = ignore_new_devs(conf);
>  	if (!find_multipaths_on(conf) && !ignore_new) {
> diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
> index d00e1f58137c..911e8da720c5 100644
> --- a/libmultipath/wwids.h
> +++ b/libmultipath/wwids.h
> @@ -12,7 +12,8 @@
>  "#\n" \
>  "# Valid WWIDs:\n"
>  
> -int should_multipath(struct path *pp, vector pathvec, vector mpvec);
> +int should_multipath(struct path *pp, vector pathvec, vector mpvec,
> +		     bool retry_failed);
>  int remember_wwid(char *wwid);
>  int check_wwids_file(char *wwid, int write_wwid);
>  int remove_wwid(char *wwid);
> diff --git a/multipath/main.c b/multipath/main.c
> index 3944fd504de2..566404e56ef4 100644
> --- a/multipath/main.c
> +++ b/multipath/main.c
> @@ -441,8 +441,12 @@ configure (struct config *conf, enum mpath_cmds cmd,
>  		 * Paths listed in the wwids file are always considered valid.
>  		 */
>  		if (cmd == CMD_VALID_PATH) {
> -			if ((!find_multipaths_on(conf) && ignore_wwids(conf)) ||
> -			    check_wwids_file(refwwid, 0) == 0)
> +			if (is_failed_wwid(refwwid)) {
> +				r = 1;
> +				goto print_valid;
> +			} else if ((!find_multipaths_on(conf) &&
> +				  ignore_wwids(conf)) ||
> +				 check_wwids_file(refwwid, 0) == 0)
>  				r = 0;
>  			if (r == 0 ||
>  			    !find_multipaths_on(conf) || !ignore_wwids(conf)) {
> @@ -504,9 +508,11 @@ configure (struct config *conf, enum mpath_cmds cmd,
>  
>  	/*
>  	 * core logic entry point
> +	 * If refwwid != NULL, user has given a device to multipath,
> +	 * so retry even if this ID has failed before.
>  	 */
>  	r = coalesce_paths(&vecs, NULL, refwwid,
> -			   conf->force_reload, cmd);
> +			   conf->force_reload, refwwid != NULL, cmd);
>  
>  out:
>  	if (refwwid)
> diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
> index 60ec48b9904a..202438795ee5 100644
> --- a/multipathd/cli_handlers.c
> +++ b/multipathd/cli_handlers.c
> @@ -750,7 +750,7 @@ cli_add_path (void * v, char ** reply, int * len, void * data)
>  		pp->checkint = conf->checkint;
>  	}
>  	put_multipath_config(conf);
> -	return ev_add_path(pp, vecs, 1);
> +	return ev_add_path(pp, vecs, ADD_PATH_DOMAP_FORCE);
>  blacklisted:
>  	*reply = strdup("blacklisted\n");
>  	*len = strlen(*reply) + 1;
> @@ -813,7 +813,8 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
>  					 vecs->pathvec, &refwwid);
>  			if (refwwid) {
>  				if (coalesce_paths(vecs, NULL, refwwid,
> -						   FORCE_RELOAD_NONE, CMD_NONE))
> +						   FORCE_RELOAD_NONE, true,
> +						   CMD_NONE))
>  					condlog(2, "%s: coalesce_paths failed",
>  									param);
>  				dm_lib_release();
> diff --git a/multipathd/main.c b/multipathd/main.c
> index ea8c413f28c6..8fd7d2b75cba 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -933,7 +933,8 @@ rescan:
>  		mpp->action = ACT_RELOAD;
>  		extract_hwe_from_path(mpp);
>  	} else {
> -		if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) {
> +		if (!should_multipath(pp, vecs->pathvec, vecs->mpvec,
> +				      need_do_map == ADD_PATH_DOMAP_FORCE)) {
>  			orphan_path(pp, "only one path");
>  			return 0;
>  		}
> @@ -953,7 +954,7 @@ rescan:
>  	/* persistent reservation check*/
>  	mpath_pr_event_handle(pp);
>  
> -	if (!need_do_map)
> +	if (need_do_map == ADD_PATH_DOMAP_NO)
>  		return 0;
>  
>  	if (!dm_map_present(mpp->alias)) {
> @@ -1863,7 +1864,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
>  			conf = get_multipath_config();
>  			ret = pathinfo(pp, conf, DI_ALL | DI_BLACKLIST);
>  			if (ret == PATHINFO_OK) {
> -				ev_add_path(pp, vecs, 1);
> +				ev_add_path(pp, vecs, ADD_PATH_DOMAP_YES);
>  				pp->tick = 1;
>  			} else if (ret == PATHINFO_SKIPPED) {
>  				put_multipath_config(conf);
> @@ -1989,7 +1990,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
>  		}
>  		if (!disable_reinstate && reinstate_path(pp, add_active)) {
>  			condlog(3, "%s: reload map", pp->dev);
> -			ev_add_path(pp, vecs, 1);
> +			ev_add_path(pp, vecs, ADD_PATH_DOMAP_YES);
>  			pp->tick = 1;
>  			return 0;
>  		}
> @@ -2012,7 +2013,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
>  			/* Clear IO errors */
>  			if (reinstate_path(pp, 0)) {
>  				condlog(3, "%s: reload map", pp->dev);
> -				ev_add_path(pp, vecs, 1);
> +				ev_add_path(pp, vecs, ADD_PATH_DOMAP_YES);
>  				pp->tick = 1;
>  				return 0;
>  			}
> @@ -2288,7 +2289,7 @@ configure (struct vectors * vecs)
>  	 * superfluous ACT_RELOAD ioctls. Later calls are done
>  	 * with FORCE_RELOAD_YES.
>  	 */
> -	ret = coalesce_paths(vecs, mpvec, NULL, force_reload, CMD_NONE);
> +	ret = coalesce_paths(vecs, mpvec, NULL, force_reload, false, CMD_NONE);
>  	if (force_reload == FORCE_RELOAD_WEAK)
>  		force_reload = FORCE_RELOAD_YES;
>  	if (ret) {
> diff --git a/multipathd/main.h b/multipathd/main.h
> index af395589ff93..a92650cd958b 100644
> --- a/multipathd/main.h
> +++ b/multipathd/main.h
> @@ -22,6 +22,14 @@ void exit_daemon(void);
>  const char * daemon_status(void);
>  int need_to_delay_reconfig (struct vectors *);
>  int reconfigure (struct vectors *);
> +/*
> + * 3rd argument of ev_add_path()
> + */
> +enum {
> +	ADD_PATH_DOMAP_NO = 0,	  /* don't call domap */
> +	ADD_PATH_DOMAP_YES = 1,	  /* call domap, don't retry failed */
> +	ADD_PATH_DOMAP_FORCE = 2, /* call domap, retry previously failed */
> +};
>  int ev_add_path (struct path *, struct vectors *, int);
>  int ev_remove_path (struct path *, struct vectors *, int);
>  int ev_add_map (char *, const char *, struct vectors *);
> -- 
> 2.16.1




More information about the dm-devel mailing list