dm-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] libmultipath: setup_map(): don't break multipath attributes
@ 2020-09-10 19:56 mwilck
  2020-09-15 20:54 ` Benjamin Marzinski
  0 siblings, 1 reply; 2+ messages in thread
From: mwilck @ 2020-09-10 19:56 UTC (permalink / raw)
  To: Christophe Varoqui, Benjamin Marzinski, lixiaokeng
  Cc: linfeilong, dm-devel, Zhiqiang Liu, Martin Wilck

From: Martin Wilck <mwilck@suse.com>

setup_map() is called both for new maps (e.g. from coalesce_paths())
and existing maps (e.g. from reload_map(), resize_map()). In the former
case, the map will be removed from global data structures, so incomplete
initialization is not an issue. But In the latter case, removal isn't
generally possible. We expect that mpp->features, mpp->hwhandler,
mpp->selector have been initialized and are are non-NULL. We must make sure
not to break this assumption because of an error in this setup_map()
invocation. As these properties aren't likely to change during an update
operation, saving and restoring them is better than leaving the map
improperly initialized.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---

v1->v2: forgot to remove the call to free_multipath_attributes().

This is supposed to be applied on top of lixiaokeng's patch
"libmultipath: check whether mpp->features is NUll in setup_map".

 libmultipath/configure.c | 29 +++++++++++++++++++++++++----
 libmultipath/util.h      |  7 +++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index 5d5d941..8fd12df 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -298,6 +298,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
 	struct pathgroup * pgp;
 	struct config *conf;
 	int i, n_paths, marginal_pathgroups;
+	char *save_attr;
 
 	/*
 	 * don't bother if devmap size is unknown
@@ -307,10 +308,6 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
 		return 1;
 	}
 
-	/*
-	 * free features, selector, and hwhandler properties if they are being reused
-	 */
-	free_multipath_attributes(mpp);
 	if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0)
 		mpp->disable_queueing = 0;
 
@@ -328,11 +325,35 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
 
 	select_pgfailback(conf, mpp);
 	select_pgpolicy(conf, mpp);
+
+	/*
+	 * If setup_map() is called from e.g. from reload_map() or resize_map(),
+	 * make sure that we don't corrupt attributes.
+	 */
+	save_attr = steal_ptr(mpp->selector);
 	select_selector(conf, mpp);
+	if (!mpp->selector)
+		mpp->selector = save_attr;
+	else
+		free(save_attr);
+
 	select_no_path_retry(conf, mpp);
 	select_retain_hwhandler(conf, mpp);
+
+	save_attr = steal_ptr(mpp->features);
 	select_features(conf, mpp);
+	if (!mpp->features)
+		mpp->features = save_attr;
+	else
+		free(save_attr);
+
+	save_attr = steal_ptr(mpp->hwhandler);
 	select_hwhandler(conf, mpp);
+	if (!mpp->hwhandler)
+		mpp->hwhandler = save_attr;
+	else
+		free(save_attr);
+
 	select_rr_weight(conf, mpp);
 	select_minio(conf, mpp);
 	select_mode(conf, mpp);
diff --git a/libmultipath/util.h b/libmultipath/util.h
index 52aa559..045bbee 100644
--- a/libmultipath/util.h
+++ b/libmultipath/util.h
@@ -110,4 +110,11 @@ static inline void clear_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
 	bf->bits[bit / bits_per_slot] &= ~(1ULL << (bit % bits_per_slot));
 }
 
+#define steal_ptr(x)		       \
+	({			       \
+		void *___p = x;	       \
+		x = NULL;	       \
+		___p;		       \
+	})
+
 #endif /* _UTIL_H */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] libmultipath: setup_map(): don't break multipath attributes
  2020-09-10 19:56 [PATCH v2] libmultipath: setup_map(): don't break multipath attributes mwilck
@ 2020-09-15 20:54 ` Benjamin Marzinski
  0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Marzinski @ 2020-09-15 20:54 UTC (permalink / raw)
  To: mwilck; +Cc: lixiaokeng, dm-devel, Zhiqiang Liu, linfeilong

On Thu, Sep 10, 2020 at 09:56:11PM +0200, mwilck@suse.com wrote:
> From: Martin Wilck <mwilck@suse.com>
> 
> setup_map() is called both for new maps (e.g. from coalesce_paths())
> and existing maps (e.g. from reload_map(), resize_map()). In the former
> case, the map will be removed from global data structures, so incomplete
> initialization is not an issue. But In the latter case, removal isn't
> generally possible. We expect that mpp->features, mpp->hwhandler,
> mpp->selector have been initialized and are are non-NULL. We must make sure
> not to break this assumption because of an error in this setup_map()
> invocation. As these properties aren't likely to change during an update
> operation, saving and restoring them is better than leaving the map
> improperly initialized.
> 
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
> Signed-off-by: Martin Wilck <mwilck@suse.com>
> ---
> 
> v1->v2: forgot to remove the call to free_multipath_attributes().
> 
> This is supposed to be applied on top of lixiaokeng's patch
> "libmultipath: check whether mpp->features is NUll in setup_map".
> 
>  libmultipath/configure.c | 29 +++++++++++++++++++++++++----
>  libmultipath/util.h      |  7 +++++++
>  2 files changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/libmultipath/configure.c b/libmultipath/configure.c
> index 5d5d941..8fd12df 100644
> --- a/libmultipath/configure.c
> +++ b/libmultipath/configure.c
> @@ -298,6 +298,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
>  	struct pathgroup * pgp;
>  	struct config *conf;
>  	int i, n_paths, marginal_pathgroups;
> +	char *save_attr;
>  
>  	/*
>  	 * don't bother if devmap size is unknown
> @@ -307,10 +308,6 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
>  		return 1;
>  	}
>  
> -	/*
> -	 * free features, selector, and hwhandler properties if they are being reused
> -	 */
> -	free_multipath_attributes(mpp);
>  	if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0)
>  		mpp->disable_queueing = 0;
>  
> @@ -328,11 +325,35 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
>  
>  	select_pgfailback(conf, mpp);
>  	select_pgpolicy(conf, mpp);
> +
> +	/*
> +	 * If setup_map() is called from e.g. from reload_map() or resize_map(),
> +	 * make sure that we don't corrupt attributes.
> +	 */
> +	save_attr = steal_ptr(mpp->selector);
>  	select_selector(conf, mpp);
> +	if (!mpp->selector)
> +		mpp->selector = save_attr;
> +	else
> +		free(save_attr);
> +
>  	select_no_path_retry(conf, mpp);
>  	select_retain_hwhandler(conf, mpp);
> +
> +	save_attr = steal_ptr(mpp->features);
>  	select_features(conf, mpp);
> +	if (!mpp->features)
> +		mpp->features = save_attr;
> +	else
> +		free(save_attr);
> +
> +	save_attr = steal_ptr(mpp->hwhandler);
>  	select_hwhandler(conf, mpp);
> +	if (!mpp->hwhandler)
> +		mpp->hwhandler = save_attr;
> +	else
> +		free(save_attr);
> +
>  	select_rr_weight(conf, mpp);
>  	select_minio(conf, mpp);
>  	select_mode(conf, mpp);
> diff --git a/libmultipath/util.h b/libmultipath/util.h
> index 52aa559..045bbee 100644
> --- a/libmultipath/util.h
> +++ b/libmultipath/util.h
> @@ -110,4 +110,11 @@ static inline void clear_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
>  	bf->bits[bit / bits_per_slot] &= ~(1ULL << (bit % bits_per_slot));
>  }
>  
> +#define steal_ptr(x)		       \
> +	({			       \
> +		void *___p = x;	       \
> +		x = NULL;	       \
> +		___p;		       \
> +	})
> +
>  #endif /* _UTIL_H */
> -- 
> 2.28.0

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-15 20:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-10 19:56 [PATCH v2] libmultipath: setup_map(): don't break multipath attributes mwilck
2020-09-15 20:54 ` Benjamin Marzinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).