[dm-devel] [PATCH V4 09/14] libmultipath: check whether mpp->features is NUll in setup_map

Benjamin Marzinski bmarzins at redhat.com
Thu Sep 10 19:02:50 UTC 2020


On Thu, Sep 10, 2020 at 06:48:56PM +0200, Martin Wilck wrote:
> On Thu, 2020-09-10 at 18:51 +0800, lixiaokeng wrote:
> > In assemble_map func, f = STRDUP(mp->features) is just used
> > for APPEND(). We can directly pass mp->features to APPEND().
> > The mpp->features, hwhandler and selector got form strdup
> > should be check after select* function.
> > 
> > Signed-off-by: Zhiqiang Liu <liuzhiqiang26 at huawei.com>
> > Signed-off-by: Lixiaokeng <lixiaokeng at huawei.com>
> 
> Thanks for submitting the new version. Looking at your patch, I realize
> that my previous suggestion wasn't perfect. 
> 
> > ---
> >  libmultipath/configure.c |  5 +++++
> >  libmultipath/dmparser.c  | 11 ++++-------
> >  2 files changed, 9 insertions(+), 7 deletions(-)
> > 
> > diff --git a/libmultipath/configure.c b/libmultipath/configure.c
> > index 5bc65fd3..5d5d9415 100644
> > --- a/libmultipath/configure.c
> > +++ b/libmultipath/configure.c
> > @@ -355,6 +355,11 @@ int setup_map(struct multipath *mpp, char
> > *params, int params_size,
> >  	select_ghost_delay(conf, mpp);
> >  	select_flush_on_last_del(conf, mpp);
> > 
> > +	if (!mpp->features || !mpp->hwhandler || !mpp->selector) {
> > +		condlog(0, "%s: map select failed", mpp->alias);
> > +		return 1;
> > +	}
> > +
> 
> We have a new failure mode for setup_map() here. While this is a good
> thing in principle, there are issues. 
> 
>  1) by returning, we skip the rest of the initialization steps for the
> map. Thus paths and pathgroups may be set up wrongly after setup_map().
>  2) Not every caller deletes the map from the mpvec after setup_map()
> fails. For some callers like resize_map() or reload_map(), that's
> actually not possible.
> 
> 1) is a minor problem because no caller calls domap() after setup_map()
> failure, afaics. But 2) is a problem, because the broken, partially
> initialized struct multipath will remain in our data structures, and my
> assumption that features etc. are always valid will be violated.
> 2) is not a regression of this patch though, it has always been the
> case.
> 
> I'm not yet decided how to deal with this. Perhaps setup_map()
> shouldn't free features, hwhandler, and selector until the new values
> have been successfully obtained.
> 
> (Actually, what's the point in running through *all* select_xyz()
> functions just for a map resize?)
> 
> Ben?

I don't know of any reason why that's necessary, or why it was
originally done that way.  If we've already configured the device, and
we're not doing a reconfigure, there's not a lot to be gained by doing
configuring again. Some to the select_* functions grab stuff from sysfs,
and so could return different values, but I'm sure there is a lot of
work that could be cut out here, with no noticeable changes in behavior.

Ideally we should stick to a "do no harm" policy when updating the
device.  It seems better to have a device structure that's outdated than
one that's invalid.

But regardless of what we do in setup_map, the assemble_map() part of
this patch is correct, and as you said, the setup_map() changes don't
introduce any new problems. It seems like resolving the issue in
setup_map() should be seperate work.

Reviewed-by: Benjamin Marzinski <bmarzins at redhat.coM>
 
> Regards
> Martin
> 
> 
> 
> 
> 
> 
> >  	sysfs_set_scsi_tmo(mpp, conf->checkint);
> >  	marginal_pathgroups = conf->marginal_pathgroups;
> >  	pthread_cleanup_pop(1);
> > diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
> > index 482e9d0e..685918da 100644
> > --- a/libmultipath/dmparser.c
> > +++ b/libmultipath/dmparser.c
> > @@ -65,7 +65,7 @@ assemble_map (struct multipath * mp, char * params,
> > int len)
> >  	int i, j;
> >  	int minio;
> >  	int nr_priority_groups, initial_pg_nr;
> > -	char * p, * f;
> > +	char * p;
> >  	const char *const end = params + len;
> >  	char no_path_retry[] = "queue_if_no_path";
> >  	char retain_hwhandler[] = "retain_attached_hw_handler";
> > @@ -86,10 +86,9 @@ assemble_map (struct multipath * mp, char *
> > params, int len)
> >  	    get_linux_version_code() < KERNEL_VERSION(4, 3, 0))
> >  		add_feature(&mp->features, retain_hwhandler);
> > 
> > -	f = STRDUP(mp->features);
> > -
> > -	APPEND(p, end, "%s %s %i %i", f, mp->hwhandler,
> > nr_priority_groups,
> > -	       initial_pg_nr);
> > +	/* mp->features must not be NULL */
> > +	APPEND(p, end, "%s %s %i %i", mp->features, mp->hwhandler,
> > +		nr_priority_groups, initial_pg_nr);
> > 
> >  	vector_foreach_slot (mp->pg, pgp, i) {
> >  		pgp = VECTOR_SLOT(mp->pg, i);
> > @@ -110,12 +109,10 @@ assemble_map (struct multipath * mp, char *
> > params, int len)
> >  		}
> >  	}
> > 
> > -	FREE(f);
> >  	condlog(4, "%s: assembled map [%s]", mp->alias, params);
> >  	return 0;
> > 
> >  err:
> > -	FREE(f);
> >  	return 1;
> >  }
> > 
> 




More information about the dm-devel mailing list