63 lines
2.4 KiB
Diff
63 lines
2.4 KiB
Diff
|
|
From 72816e34d2e4a3197e4a590e573c4fc64a360145 Mon Sep 17 00:00:00 2001
|
|||
|
|
From: lixiaokeng <lixiaokeng@huawei.com>
|
|||
|
|
Date: Mon, 13 Jul 2020 13:07:40 +0200
|
|||
|
|
Subject: [PATCH] libmultipath: fix multipathd coredump in disassemble_map
|
|||
|
|
|
|||
|
|
Coredump appears when events are executed in a certain order.
|
|||
|
|
1. The sdc and sdd are added as paths of d1. The sdc is added
|
|||
|
|
firstly and d1->wait_for_udev be set to 1. Then sdd is added but
|
|||
|
|
it just adds to pathvec because d1->wait_for_udev is 1.
|
|||
|
|
2. The uev_remove_path(sdc) are executed. Because d1 has one
|
|||
|
|
path, d1 will be flushed.
|
|||
|
|
3. The uev_add_path(sdc) are executed. Now sdc and sdd will
|
|||
|
|
both add to d1 in adopt_paths because sdd->wwid is d1. And
|
|||
|
|
d1->wait_for_udev be set to 1.
|
|||
|
|
4. The uev_remove_path(sdd) are executed. Because d1->wait_for_udev
|
|||
|
|
is 1, domap doesn't executed and the major:minor of sdd(8:64)
|
|||
|
|
still exist in kernel d1. The sdd in pathvec is deleted.
|
|||
|
|
5. The uev_add_path(sdd) are executed. Now the sdd(8:64) is
|
|||
|
|
a path of d2. And new sdd is added to pathvec.
|
|||
|
|
6. The update_multipath_strings(d1) are executed. The d1 find
|
|||
|
|
sdd in pathvec by dev_t(8:64)and sdd will be add to d1. Now
|
|||
|
|
the pointer of sdd is store in paths of d1 and d2.
|
|||
|
|
7. When NIC is down and a new path add to d1, sdd will be freed
|
|||
|
|
in verify_paths (because sdd is actually a path of d2).
|
|||
|
|
8. When d2->hwe is sdd->hwe and setup_map(d2) is called. Core
|
|||
|
|
causes.
|
|||
|
|
|
|||
|
|
The path shouldn't be add to the mpp whose wwid is different
|
|||
|
|
with its. Here we add wwid check in disassemble_map. This bug
|
|||
|
|
has been solved in upstream in update_pathvec_from_dm. It is
|
|||
|
|
a great change, so we fix it with huawei patch. This patch could
|
|||
|
|
be discarded when multipath-tools update.
|
|||
|
|
|
|||
|
|
Signed-off-by:lixiaokeng<lixiaokeng@huawei.com>
|
|||
|
|
---
|
|||
|
|
libmultipath/dmparser.c | 10 ++++++++++
|
|||
|
|
1 file changed, 10 insertions(+)
|
|||
|
|
|
|||
|
|
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
|
|||
|
|
index 3ce6eb3..9aa6bc5 100644
|
|||
|
|
--- a/libmultipath/dmparser.c
|
|||
|
|
+++ b/libmultipath/dmparser.c
|
|||
|
|
@@ -332,6 +332,16 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp,
|
|||
|
|
goto out1;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
+ if (strlen(pp->wwid) && strlen(mpp->wwid) &&
|
|||
|
|
+ strcmp(pp->wwid, mpp->wwid) != 0) {
|
|||
|
|
+ condlog(0, "%s: path wwid is different with that of %s.\n", pp->dev_t, mpp->alias);
|
|||
|
|
+ FREE(word);
|
|||
|
|
+ for (k = 0; k < num_paths_args; k++) {
|
|||
|
|
+ p += get_word(p, NULL);
|
|||
|
|
+ }
|
|||
|
|
+ continue;
|
|||
|
|
+ }
|
|||
|
|
+
|
|||
|
|
if (!strlen(pp->wwid) &&
|
|||
|
|
strlen(mpp->wwid))
|
|||
|
|
strlcpy(pp->wwid, mpp->wwid,
|
|||
|
|
--
|
|||
|
|
2.14.3 (Apple Git-98)
|
|||
|
|
|