device-mapper-multipath/0020-libmultipath-fix-mpcontext-initialization.patch
Benjamin Marzinski 942c9b6ed8 device-mapper-multipath-0.8.2-1
Update Source to upstream version 0.8.2
  * Previoud patches 0001-0017 & 0027 are included in this commit
Rename files
  * Previous patches 0018-0026 & 0028 are not patches 0021-0030
Add 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch
Add 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch
Add 0003-tests-add-path-grouping-policy-unit-tests.patch
Add 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch
Add 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch
Add 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch
Add 0007-libmultipath-consolidate-group_by_-functions.patch
Add 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch
Add 0009-libmultipath-make-group_paths-handle-marginal-paths.patch
Add 0010-tests-add-tests-for-grouping-marginal-paths.patch
Add 0011-libmultipath-add-marginal_pathgroups-config-option.patch
Add 0012-libmutipath-deprecate-delay_-_checks.patch
Add 0013-multipathd-use-marginal_pathgroups.patch
Add 0014-multipath-update-man-pages.patch
  * The above 13 patches add the marinal_pathgroups option
Add 0015-multipath.conf-add-enable_foreign-parameter.patch
Add 0016-multipath.conf.5-document-foreign-library-support.patch
  * The above 2 patches add the enable_foreign option
Add 0017-mpathpersist-remove-broken-unused-code.patch
Add 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch
Add 0019-mpathpersist-fix-leaks.patch
Add 0020-libmultipath-fix-mpcontext-initialization.patch
  * The above 20 patches have been submitted upstream
2019-09-11 17:06:10 -05:00

233 lines
7.0 KiB
Diff

From 33a6f6b05d7041716142f080a2708db351c92eaa Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Tue, 10 Sep 2019 15:46:28 -0500
Subject: [PATCH] libmultipath: fix mpcontext initialization
If a path is discovered before there is a multipath device for it to
belong to, the checker will not have its mpcontext initialized, even if
that path later belongs to a multipath device. A checker's mpcontext is
only set when the checker is selected, and is set to NULL if there is no
multipath device associated with the path. This only impacts the emc
checker. However, it makes the emc checker unable to determine if a
passive path is connected to an inactive snapshot or not.
This can be solved by adding a new checker class function, mp_init().
This is called when the checker is first initialized, and whenever the
checker is called, if the checker's mpcontext hasn't been initialized.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/checkers.c | 29 ++++++++++++++++++++++++++--
libmultipath/checkers.h | 1 +
libmultipath/checkers/cciss_tur.c | 5 +++++
libmultipath/checkers/directio.c | 5 +++++
libmultipath/checkers/emc_clariion.c | 7 +++++++
libmultipath/checkers/hp_sw.c | 5 +++++
libmultipath/checkers/rdac.c | 5 +++++
libmultipath/checkers/readsector0.c | 5 +++++
libmultipath/checkers/tur.c | 5 +++++
libmultipath/discovery.c | 2 ++
10 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index f4fdcae9..240b0f29 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -16,6 +16,7 @@ struct checker_class {
char name[CHECKER_NAME_LEN];
int (*check)(struct checker *);
int (*init)(struct checker *); /* to allocate the context */
+ int (*mp_init)(struct checker *); /* to allocate the mpcontext */
void (*free)(struct checker *); /* to free the context */
const char **msgtable;
short msgtable_size;
@@ -140,6 +141,13 @@ static struct checker_class *add_checker_class(const char *multipath_dir,
if (!c->init)
goto out;
+ c->mp_init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_mp_init");
+ errstr = dlerror();
+ if (errstr != NULL)
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
+ if (!c->mp_init)
+ goto out;
+
c->free = (void (*)(struct checker *)) dlsym(c->handle, "libcheck_free");
errstr = dlerror();
if (errstr != NULL)
@@ -212,8 +220,25 @@ int checker_init (struct checker * c, void ** mpctxt_addr)
if (!c || !c->cls)
return 1;
c->mpcontext = mpctxt_addr;
- if (c->cls->init)
- return c->cls->init(c);
+ if (c->cls->init && c->cls->init(c) != 0)
+ return 1;
+ if (mpctxt_addr && *mpctxt_addr == NULL && c->cls->mp_init &&
+ c->cls->mp_init(c) != 0) /* continue even if mp_init fails */
+ c->mpcontext = NULL;
+ return 0;
+}
+
+int checker_mp_init(struct checker * c, void ** mpctxt_addr)
+{
+ if (!c || !c->cls)
+ return 1;
+ if (c->cls->mp_init && !c->mpcontext && mpctxt_addr) {
+ c->mpcontext = mpctxt_addr;
+ if (c->cls->mp_init(c) != 0) {
+ c->mpcontext = NULL;
+ return 1;
+ }
+ }
return 0;
}
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index dab197f9..5237e7ec 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -138,6 +138,7 @@ const char *checker_state_name(int);
int init_checkers(const char *);
void cleanup_checkers (void);
int checker_init (struct checker *, void **);
+int checker_mp_init(struct checker *, void **);
void checker_clear (struct checker *);
void checker_put (struct checker *);
void checker_reset (struct checker *);
diff --git a/libmultipath/checkers/cciss_tur.c b/libmultipath/checkers/cciss_tur.c
index ea843742..b570ed65 100644
--- a/libmultipath/checkers/cciss_tur.c
+++ b/libmultipath/checkers/cciss_tur.c
@@ -51,6 +51,11 @@ int libcheck_init (struct checker * c)
return 0;
}
+int libcheck_mp_init (struct checker * c)
+{
+ return 0;
+}
+
void libcheck_free (struct checker * c)
{
return;
diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
index 1b00b775..96f223b2 100644
--- a/libmultipath/checkers/directio.c
+++ b/libmultipath/checkers/directio.c
@@ -103,6 +103,11 @@ out:
return 1;
}
+int libcheck_mp_init(struct checker * c)
+{
+ return 0;
+}
+
void libcheck_free (struct checker * c)
{
struct directio_context * ct = (struct directio_context *)c->context;
diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c
index 6fc89113..5cd63aca 100644
--- a/libmultipath/checkers/emc_clariion.c
+++ b/libmultipath/checkers/emc_clariion.c
@@ -107,11 +107,18 @@ int libcheck_init (struct checker * c)
return 1;
((struct emc_clariion_checker_path_context *)c->context)->wwn_set = 0;
+ return 0;
+}
+
+int libcheck_mp_init (struct checker * c)
+{
/*
* Allocate and initialize the multi-path global context.
*/
if (c->mpcontext && *c->mpcontext == NULL) {
void * mpctxt = malloc(sizeof(int));
+ if (!mpctxt)
+ return 1;
*c->mpcontext = mpctxt;
CLR_INACTIVE_SNAP(c);
}
diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c
index 1a820223..35aca204 100644
--- a/libmultipath/checkers/hp_sw.c
+++ b/libmultipath/checkers/hp_sw.c
@@ -37,6 +37,11 @@ int libcheck_init (struct checker * c)
return 0;
}
+int libcheck_mp_init(struct checker * c)
+{
+ return 0;
+}
+
void libcheck_free (struct checker * c)
{
return;
diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
index 8a3b73ec..805d153e 100644
--- a/libmultipath/checkers/rdac.c
+++ b/libmultipath/checkers/rdac.c
@@ -133,6 +133,11 @@ out:
return 0;
}
+int libcheck_mp_init(struct checker * c)
+{
+ return 0;
+}
+
void libcheck_free (struct checker * c)
{
return;
diff --git a/libmultipath/checkers/readsector0.c b/libmultipath/checkers/readsector0.c
index cf79e067..71db9f80 100644
--- a/libmultipath/checkers/readsector0.c
+++ b/libmultipath/checkers/readsector0.c
@@ -15,6 +15,11 @@ int libcheck_init (struct checker * c)
return 0;
}
+int libcheck_mp_init(struct checker * c)
+{
+ return 0;
+}
+
void libcheck_free (struct checker * c)
{
return;
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
index 6b08dbbb..138b9e58 100644
--- a/libmultipath/checkers/tur.c
+++ b/libmultipath/checkers/tur.c
@@ -79,6 +79,11 @@ int libcheck_init (struct checker * c)
return 0;
}
+int libcheck_mp_init(struct checker * c)
+{
+ return 0;
+}
+
static void cleanup_context(struct tur_checker_context *ct)
{
pthread_mutex_destroy(&ct->lock);
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index acca466c..72f455e8 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -1608,6 +1608,8 @@ get_state (struct path * pp, struct config *conf, int daemon, int oldstate)
return PATH_UNCHECKED;
}
}
+ if (pp->mpp && !c->mpcontext)
+ checker_mp_init(c, &pp->mpp->mpcontext);
checker_clear_message(c);
if (daemon) {
if (conf->force_sync == 0)
--
2.17.2