[dm-devel] [PATCH v2] libmultipath: setup_map(): don't break multipath attributes
Benjamin Marzinski
bmarzins at redhat.com
Tue Sep 15 20:54:38 UTC 2020
On Thu, Sep 10, 2020 at 09:56:11PM +0200, mwilck at suse.com wrote:
> From: Martin Wilck <mwilck at 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 at redhat.com>
> Signed-off-by: Martin Wilck <mwilck at 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
More information about the dm-devel
mailing list