From 0a156fc43d498cc038ec56e34e3e7ad8937ea157 Mon Sep 17 00:00:00 2001 From: DistroBaker Date: Fri, 12 Feb 2021 19:25:37 +0000 Subject: [PATCH] Merged update from upstream sources This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/device-mapper-multipath.git#9fdf79cddf3be4e872b8d515e240dd533ea8dd34 --- ...-NULL-dereference-in-find_path_by_de.patch | 46 +++ ...print_devices-avoid-NULL-dereference.patch | 38 +++ ...fix-thread-safety-of-default-functio.patch | 274 +++++++++++++++++ 0106-Added-github-action-for-building.patch | 37 +++ ...use-zram-device-as-test-block-device.patch | 40 +++ ...workflow-use-explicit-Ubuntu-version.patch | 26 ++ 0109-github-workflow-add-valgrind-tests.patch | 36 +++ 0110-github-workflow-run-apt-get-update.patch | 28 ++ ...flow-add-tests-with-gcc-10-and-clang.patch | 90 ++++++ ...-Fix-multipathd-stopping-on-shutdown.patch | 38 +++ ...-3rd-digit-as-transport_id-for-expan.patch | 45 +++ ...fs_set_nexus_loss_tmo-support-SAS-ex.patch | 57 ++++ ...pathd-add-code-to-initalize-unwinder.patch | 134 +++++++++ ...ck-if-adopt_path-really-added-curren.patch | 57 ++++ ...d_path-fail-if-add_map_with_path-fai.patch | 31 ++ ...ck-return-value-of-udev_device_get_d.patch | 31 ++ ...filter_property-after-sysfs_pathinfo.patch | 281 ++++++++++++++++++ ...hinfo-call-filter_property-only-with.patch | 88 ++++++ ...h-w-allow-removing-blacklisted-paths.patch | 39 +++ ...h-fix-use-after-free-in-uev_add_path.patch | 53 ++++ ...loop-device-after-listing-partitions.patch | 61 ++++ ... 0124-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 4 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0128-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0129-RH-add-mpathconf.patch | 56 ++-- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 2 +- ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 device-mapper-multipath.spec | 50 +++- 31 files changed, 1601 insertions(+), 41 deletions(-) create mode 100644 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch create mode 100644 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch create mode 100644 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch create mode 100644 0106-Added-github-action-for-building.patch create mode 100644 0107-github-workflow-use-zram-device-as-test-block-device.patch create mode 100644 0108-github-workflow-use-explicit-Ubuntu-version.patch create mode 100644 0109-github-workflow-add-valgrind-tests.patch create mode 100644 0110-github-workflow-run-apt-get-update.patch create mode 100644 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch create mode 100644 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch create mode 100644 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch create mode 100644 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch create mode 100644 0115-multipathd-add-code-to-initalize-unwinder.patch create mode 100644 0116-libmultipath-check-if-adopt_path-really-added-curren.patch create mode 100644 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch create mode 100644 0118-libmultipath-check-return-value-of-udev_device_get_d.patch create mode 100644 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch create mode 100644 0120-libmultipath-pathinfo-call-filter_property-only-with.patch create mode 100644 0121-multipath-w-allow-removing-blacklisted-paths.patch create mode 100644 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch create mode 100644 0123-kpartx-free-loop-device-after-listing-partitions.patch rename 0103-RH-fixup-udev-rules-for-redhat.patch => 0124-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0104-RH-Remove-the-property-blacklist-exception-builtin.patch => 0125-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0105-RH-don-t-start-without-a-config-file.patch => 0126-RH-don-t-start-without-a-config-file.patch (97%) rename 0106-RH-Fix-nvme-function-missing-argument.patch => 0127-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0107-RH-use-rpm-optflags-if-present.patch => 0128-RH-use-rpm-optflags-if-present.patch (100%) rename 0108-RH-add-mpathconf.patch => 0129-RH-add-mpathconf.patch (93%) rename 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (99%) rename 0110-RH-reset-default-find_mutipaths-value-to-off.patch => 0131-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) diff --git a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch new file mode 100644 index 0000000..4dd4051 --- /dev/null +++ b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Sat, 23 Jan 2021 16:19:28 +0800 +Subject: [PATCH] libmultipath: fix NULL dereference in find_path_by_dev + +When I test the 0.8.5 code with iscsi login/out, multipathd command +and multipath command concurrently, there is a multipathd coredump. +The stack is shown: + +uxlsnrloop + ->cli_list_devices + ->show_devices + ->snprint_devices + ->find_path_by_dev + +The reason is that devname is NULL in snprint_devices, then it will +be dereference. Here we check dev in find_path_by_dev. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 464596fc..a3f27fd6 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -453,12 +453,12 @@ find_mp_by_str (const struct _vector *mpvec, const char * str) + } + + struct path * +-find_path_by_dev (const struct _vector *pathvec, const char * dev) ++find_path_by_dev (const struct _vector *pathvec, const char *dev) + { + int i; + struct path * pp; + +- if (!pathvec) ++ if (!pathvec || !dev) + return NULL; + + vector_foreach_slot (pathvec, pp, i) +-- +2.17.2 + diff --git a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch new file mode 100644 index 0000000..04ff739 --- /dev/null +++ b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Jan 2021 16:12:10 +0100 +Subject: [PATCH] libmultipath: snprint_devices(): avoid NULL dereference + +All libudev functions may return NULL. Watch out for it. + +Fixes: d041258 ("libmultipath: snprint_devices(): use udev_enumerate" +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 19de2c7c..8151e11e 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -2055,8 +2055,16 @@ int snprint_devices(struct config *conf, char *buff, size_t len, + struct udev_device *u_dev; + + path = udev_list_entry_get_name(item); ++ if (!path) ++ continue; + u_dev = udev_device_new_from_syspath(udev, path); ++ if (!u_dev) ++ continue; + devname = udev_device_get_sysname(u_dev); ++ if (!devname) { ++ udev_device_unref(u_dev); ++ continue; ++ } + + fwd += snprintf(buff + fwd, len - fwd, " %s", devname); + if (fwd >= len) +-- +2.17.2 + diff --git a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch new file mode 100644 index 0000000..dad9963 --- /dev/null +++ b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch @@ -0,0 +1,274 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 25 Jan 2021 23:31:04 -0600 +Subject: [PATCH] libmpathpersist: fix thread safety of default functions + +commit a839e39e ("libmpathpersist: factor out initialization and +teardown") made mpath_presistent_reserve_{in,out} use share variables +for curmp and pathvec. There are users of this library that call these +functions in a multi-threaded process, and this change causes their +application to crash. config and udev are also shared variables, but +libmpathpersist doesn't write to the config in +mpath_presistent_reserve_{in,out}, and looking into the libudev code, I +don't see any place where libmpathpersist uses the udev object in a way +that isn't thread-safe. + +This patch makes mpath_presistent_reserve_{in,out} go back to using +local variables for curmp and pathvec, so that multiple threads won't +be operating on these variables at the same time. + +Fixes: a839e39e ("libmpathpersist: factor out initialization and teardown") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist.c | 116 +++++++++++++++++++++----------- + libmpathpersist/mpath_persist.h | 24 +++++-- + 2 files changed, 94 insertions(+), 46 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 08077936..5c95af20 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -133,69 +133,57 @@ mpath_prin_activepath (struct multipath *mpp, int rq_servact, + return ret; + } + +-int mpath_persistent_reserve_in (int fd, int rq_servact, +- struct prin_resp *resp, int noisy, int verbose) +-{ +- int ret = mpath_persistent_reserve_init_vecs(verbose); +- +- if (ret != MPATH_PR_SUCCESS) +- return ret; +- ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy); +- mpath_persistent_reserve_free_vecs(); +- return ret; +-} +- +-int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, +- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) +-{ +- int ret = mpath_persistent_reserve_init_vecs(verbose); +- +- if (ret != MPATH_PR_SUCCESS) +- return ret; +- ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type, +- paramp, noisy); +- mpath_persistent_reserve_free_vecs(); +- return ret; +-} +- + static vector curmp; + static vector pathvec; + +-void mpath_persistent_reserve_free_vecs(void) ++static void __mpath_persistent_reserve_free_vecs(vector curmp, vector pathvec) + { + free_multipathvec(curmp, KEEP_PATHS); + free_pathvec(pathvec, FREE_PATHS); ++} ++ ++void mpath_persistent_reserve_free_vecs(void) ++{ ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); + curmp = pathvec = NULL; + } + +-int mpath_persistent_reserve_init_vecs(int verbose) ++static int __mpath_persistent_reserve_init_vecs(vector *curmp_p, ++ vector *pathvec_p, int verbose) + { + libmp_verbosity = verbose; + +- if (curmp) ++ if (*curmp_p) + return MPATH_PR_SUCCESS; + /* + * allocate core vectors to store paths and multipaths + */ +- curmp = vector_alloc (); +- pathvec = vector_alloc (); ++ *curmp_p = vector_alloc (); ++ *pathvec_p = vector_alloc (); + +- if (!curmp || !pathvec){ ++ if (!*curmp_p || !*pathvec_p){ + condlog (0, "vector allocation failed."); + goto err; + } + +- if (dm_get_maps(curmp)) ++ if (dm_get_maps(*curmp_p)) + goto err; + + return MPATH_PR_SUCCESS; + + err: +- mpath_persistent_reserve_free_vecs(); ++ __mpath_persistent_reserve_free_vecs(*curmp_p, *pathvec_p); ++ *curmp_p = *pathvec_p = NULL; + return MPATH_PR_DMMP_ERROR; + } + +-static int mpath_get_map(int fd, char **palias, struct multipath **pmpp) ++int mpath_persistent_reserve_init_vecs(int verbose) ++{ ++ return __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, verbose); ++} ++ ++static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, ++ struct multipath **pmpp) + { + int ret = MPATH_PR_DMMP_ERROR; + struct stat info; +@@ -255,13 +243,13 @@ out: + return ret; + } + +-int __mpath_persistent_reserve_in (int fd, int rq_servact, +- struct prin_resp *resp, int noisy) ++static int do_mpath_persistent_reserve_in (vector curmp, vector pathvec, ++ int fd, int rq_servact, struct prin_resp *resp, int noisy) + { + struct multipath *mpp; + int ret; + +- ret = mpath_get_map(fd, NULL, &mpp); ++ ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + +@@ -270,8 +258,17 @@ int __mpath_persistent_reserve_in (int fd, int rq_servact, + return ret; + } + +-int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, +- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) ++ ++int __mpath_persistent_reserve_in (int fd, int rq_servact, ++ struct prin_resp *resp, int noisy) ++{ ++ return do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, ++ resp, noisy); ++} ++ ++static int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd, ++ int rq_servact, int rq_scope, unsigned int rq_type, ++ struct prout_param_descriptor *paramp, int noisy) + { + struct multipath *mpp; + char *alias; +@@ -279,7 +276,7 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + uint64_t prkey; + struct config *conf; + +- ret = mpath_get_map(fd, &alias, &mpp); ++ ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + +@@ -349,6 +346,45 @@ out1: + return ret; + } + ++ ++int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, ++ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) ++{ ++ return do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, ++ rq_scope, rq_type, paramp, ++ noisy); ++} ++ ++int mpath_persistent_reserve_in (int fd, int rq_servact, ++ struct prin_resp *resp, int noisy, int verbose) ++{ ++ vector curmp = NULL, pathvec; ++ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, ++ verbose); ++ ++ if (ret != MPATH_PR_SUCCESS) ++ return ret; ++ ret = do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, ++ resp, noisy); ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); ++ return ret; ++} ++ ++int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, ++ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) ++{ ++ vector curmp = NULL, pathvec; ++ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, ++ verbose); ++ ++ if (ret != MPATH_PR_SUCCESS) ++ return ret; ++ ret = do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, ++ rq_scope, rq_type, paramp, noisy); ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); ++ return ret; ++} ++ + int + get_mpvec (vector curmp, vector pathvec, char * refwwid) + { +diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h +index 5435eae4..9e9c0a82 100644 +--- a/libmpathpersist/mpath_persist.h ++++ b/libmpathpersist/mpath_persist.h +@@ -246,9 +246,13 @@ extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp + + /* + * DESCRIPTION : +- * This function is like mpath_persistent_reserve_in(), except that it doesn't call +- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() +- * before and after the actual PR call. ++ * This function is like mpath_persistent_reserve_in(), except that it ++ * requires mpath_persistent_reserve_init_vecs() to be called before the ++ * PR call to set up internal variables. These must later be cleanup up ++ * by calling mpath_persistent_reserve_free_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + extern int __mpath_persistent_reserve_in(int fd, int rq_servact, + struct prin_resp *resp, int noisy); +@@ -280,9 +284,13 @@ extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + int verbose); + /* + * DESCRIPTION : +- * This function is like mpath_persistent_reserve_out(), except that it doesn't call +- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() +- * before and after the actual PR call. ++ * This function is like mpath_persistent_reserve_out(), except that it ++ * requires mpath_persistent_reserve_init_vecs() to be called before the ++ * PR call to set up internal variables. These must later be cleanup up ++ * by calling mpath_persistent_reserve_free_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, + unsigned int rq_type, struct prout_param_descriptor *paramp, +@@ -296,6 +304,7 @@ extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, + * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose + * + * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + * + * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status specified + * above in RETURN_STATUS. +@@ -306,6 +315,9 @@ int mpath_persistent_reserve_init_vecs(int verbose); + * DESCRIPTION : + * This function frees data structures allocated by + * mpath_persistent_reserve_init_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + void mpath_persistent_reserve_free_vecs(void); + +-- +2.17.2 + diff --git a/0106-Added-github-action-for-building.patch b/0106-Added-github-action-for-building.patch new file mode 100644 index 0000000..8a8a7d0 --- /dev/null +++ b/0106-Added-github-action-for-building.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 21:38:43 +0100 +Subject: [PATCH] Added github action for building + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + create mode 100644 .github/workflows/build-and-unittest.yaml + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +new file mode 100644 +index 00000000..2b13c65c +--- /dev/null ++++ b/.github/workflows/build-and-unittest.yaml +@@ -0,0 +1,17 @@ ++name: basic-build-and-ci ++on: [push] ++jobs: ++ build: ++ runs-on: ubuntu-latest ++ steps: ++ - uses: actions/checkout@v2 ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ make perl-base pkg-config ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test +-- +2.17.2 + diff --git a/0107-github-workflow-use-zram-device-as-test-block-device.patch b/0107-github-workflow-use-zram-device-as-test-block-device.patch new file mode 100644 index 0000000..5b25c29 --- /dev/null +++ b/0107-github-workflow-use-zram-device-as-test-block-device.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 22:18:20 +0100 +Subject: [PATCH] github workflow: use zram device as test block device + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 2b13c65c..ef55b8c1 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -5,6 +5,14 @@ jobs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: zram ++ run: sudo modprobe zram num_devices=0 ++ - name: zram-device ++ run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV ++ - name: set-zram-size ++ run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize + - name: dependencies + run: > + sudo apt-get install --yes gcc +@@ -15,3 +23,7 @@ jobs: + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test + run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test +-- +2.17.2 + diff --git a/0108-github-workflow-use-explicit-Ubuntu-version.patch b/0108-github-workflow-use-explicit-Ubuntu-version.patch new file mode 100644 index 0000000..ff565d6 --- /dev/null +++ b/0108-github-workflow-use-explicit-Ubuntu-version.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 22:54:24 +0100 +Subject: [PATCH] github workflow: use explicit Ubuntu version + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index ef55b8c1..577a14ac 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -2,7 +2,7 @@ name: basic-build-and-ci + on: [push] + jobs: + build: +- runs-on: ubuntu-latest ++ runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: mpath +-- +2.17.2 + diff --git a/0109-github-workflow-add-valgrind-tests.patch b/0109-github-workflow-add-valgrind-tests.patch new file mode 100644 index 0000000..5c4e366 --- /dev/null +++ b/0109-github-workflow-add-valgrind-tests.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:21:16 +0100 +Subject: [PATCH] github workflow: add valgrind tests + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 577a14ac..929f63a6 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -16,13 +16,17 @@ jobs: + - name: dependencies + run: > + sudo apt-get install --yes gcc +- make perl-base pkg-config ++ make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev + - name: build + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test + run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr + - name: clean-nonroot-artifacts + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test +-- +2.17.2 + diff --git a/0110-github-workflow-run-apt-get-update.patch b/0110-github-workflow-run-apt-get-update.patch new file mode 100644 index 0000000..d27f1ca --- /dev/null +++ b/0110-github-workflow-run-apt-get-update.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:26:16 +0100 +Subject: [PATCH] github workflow: run apt-get update + +E: Failed to fetch http://azure.archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6-dbg_2.27-3ubuntu1.3_amd64.deb 404 Not Found [IP: 52.252.75.106 80] +E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 929f63a6..389578be 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -13,6 +13,8 @@ jobs: + run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV + - name: set-zram-size + run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize ++ - name: update ++ run: sudo apt-get update + - name: dependencies + run: > + sudo apt-get install --yes gcc +-- +2.17.2 + diff --git a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch new file mode 100644 index 0000000..e95b3f8 --- /dev/null +++ b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:44:11 +0100 +Subject: [PATCH] github workflow: add tests with gcc 10 and clang + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 62 ++++++++++++++++++++++- + 1 file changed, 61 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 389578be..4173576f 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -1,7 +1,7 @@ + name: basic-build-and-ci + on: [push] + jobs: +- build: ++ bionic: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 +@@ -33,3 +33,63 @@ jobs: + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test + run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test ++ focal-gcc10: ++ runs-on: ubuntu-20.04 ++ steps: ++ - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: brd ++ run: sudo modprobe brd rd_nr=1 rd_size=65536 ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc-10 ++ make perl-base pkg-config valgrind ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: set CC ++ run: echo CC=gcc-10 >> $GITHUB_ENV ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/ram0 test ++ focal-clang10: ++ runs-on: ubuntu-20.04 ++ steps: ++ - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: brd ++ run: sudo modprobe brd rd_nr=1 rd_size=65536 ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes clang ++ make perl-base pkg-config valgrind ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: set CC ++ run: echo CC=clang >> $GITHUB_ENV ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/ram0 test +-- +2.17.2 + diff --git a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch new file mode 100644 index 0000000..49ea563 --- /dev/null +++ b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:41 -0600 +Subject: [PATCH] multipathd: Fix multipathd stopping on shutdown + +According to man "systemd.special" + +"shutdown.target: ... Services that shall be terminated on system +shutdown shall add Conflicts= and Before= dependencies to this unit for +their service unit, which is implicitly done when +DefaultDependencies=yes is set (the default)." + +multipathd.service sets DefaultDependencies=no and includes the +Conflits= dependency, but not the Before= one. This can cause multipathd +to continue running past when it is supposed to during shutdown. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/multipathd.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index ba24983e..7d547fa7 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -2,7 +2,7 @@ + Description=Device-Mapper Multipath Device Controller + Wants=systemd-udev-trigger.service systemd-udev-settle.service + Before=iscsi.service iscsid.service lvm2-activation-early.service +-Before=local-fs-pre.target blk-availability.service ++Before=local-fs-pre.target blk-availability.service shutdown.target + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service + DefaultDependencies=no + Conflicts=shutdown.target +-- +2.17.2 + diff --git a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch new file mode 100644 index 0000000..17d53ce --- /dev/null +++ b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Nov 2020 22:34:41 +0100 +Subject: [PATCH] libmultipath: use 3rd digit as transport_id for expanders + +On SAS expanders, node id's have 3 digits. sysfs paths look like this: + +/sys/devices/pci0000:80/0000:80:02.0/0000:8b:00.0/0000:8c:09.0/0000:8f:00.0/host9/port-9:0/expander-9:0/port-9:0:13/expander-9:1/port-9:1:12/expander-9:2/port-9:2:4/end_device-9:2:4/target9:0:29/9:0:29:0/block/sdac + +In that case, we should use the last digit as transport id. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e818585a..6d74cc07 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -358,10 +358,17 @@ sysfs_get_tgt_nodename(struct path *pp, char *node) + if (value) { + tgtdev = udev_device_get_parent(parent); + while (tgtdev) { ++ char c; ++ + tgtname = udev_device_get_sysname(tgtdev); +- if (tgtname && sscanf(tgtname, "end_device-%d:%d", +- &host, &tgtid) == 2) +- break; ++ if (tgtname) { ++ if (sscanf(tgtname, "end_device-%d:%d:%d%c", ++ &host, &channel, &tgtid, &c) == 3) ++ break; ++ if (sscanf(tgtname, "end_device-%d:%d%c", ++ &host, &tgtid, &c) == 2) ++ break; ++ } + tgtdev = udev_device_get_parent(tgtdev); + tgtid = -1; + } +-- +2.17.2 + diff --git a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch new file mode 100644 index 0000000..3207d2d --- /dev/null +++ b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Nov 2020 22:38:21 +0100 +Subject: [PATCH] libmultipath: sysfs_set_nexus_loss_tmo(): support SAS + expanders + +With SAS expanders, SAS node names have 3 digits. libmultipath +would fail to discover the sas_end_device matching a given SCSI +target in this case. Fix it. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 6d74cc07..921025d4 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -789,14 +789,28 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) + static void + sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) + { +- struct udev_device *sas_dev = NULL; +- char end_dev_id[64]; ++ struct udev_device *parent, *sas_dev = NULL; ++ const char *end_dev_id = NULL; + char value[11]; ++ static const char ed_str[] = "end_device-"; + +- if (mpp->dev_loss == DEV_LOSS_TMO_UNSET) ++ if (!pp->udev || mpp->dev_loss == DEV_LOSS_TMO_UNSET) + return; +- sprintf(end_dev_id, "end_device-%d:%d", +- pp->sg_id.host_no, pp->sg_id.transport_id); ++ ++ for (parent = udev_device_get_parent(pp->udev); ++ parent; ++ parent = udev_device_get_parent(parent)) { ++ const char *ed = udev_device_get_sysname(parent); ++ ++ if (!strncmp(ed, ed_str, sizeof(ed_str) - 1)) { ++ end_dev_id = ed; ++ break; ++ } ++ } ++ if (!end_dev_id) { ++ condlog(1, "%s: No SAS end device", pp->dev); ++ return; ++ } + sas_dev = udev_device_new_from_subsystem_sysname(udev, + "sas_end_device", end_dev_id); + if (!sas_dev) { +-- +2.17.2 + diff --git a/0115-multipathd-add-code-to-initalize-unwinder.patch b/0115-multipathd-add-code-to-initalize-unwinder.patch new file mode 100644 index 0000000..e231733 --- /dev/null +++ b/0115-multipathd-add-code-to-initalize-unwinder.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 17 Dec 2020 16:50:06 +0100 +Subject: [PATCH] multipathd: add code to initalize unwinder + +glibc's implementation of pthread_cancel() loads symbols from +libgcc_s.so using dlopen() when pthread_cancel() is called +for the first time. This happens even with LD_BIND_NOW=1. +This may imply the need for file system access when a thread is +cancelled, which in the case of multipath-tools might be in a +dangerous situation where multipathd must avoid blocking. + +Call load_unwinder() during startup to make sure the dynamic +linker has all necessary symbols resolved early on. + +This implementation simply creates a dummy thread and cancels +it. This way all necessary symbols for thread cancellation +will be loaded, no matter what the C library needs to implement +cancellation. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/Makefile | 2 +- + multipathd/init_unwinder.c | 34 ++++++++++++++++++++++++++++++++++ + multipathd/init_unwinder.h | 21 +++++++++++++++++++++ + multipathd/main.c | 2 ++ + 4 files changed, 58 insertions(+), 1 deletion(-) + create mode 100644 multipathd/init_unwinder.c + create mode 100644 multipathd/init_unwinder.h + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 632b82b1..d053c1ed 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -30,7 +30,7 @@ ifeq ($(ENABLE_DMEVENTS_POLL),0) + endif + + OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ +- dmevents.o ++ dmevents.o init_unwinder.o + + EXEC = multipathd + +diff --git a/multipathd/init_unwinder.c b/multipathd/init_unwinder.c +new file mode 100644 +index 00000000..14467f3d +--- /dev/null ++++ b/multipathd/init_unwinder.c +@@ -0,0 +1,34 @@ ++#include ++#include ++#include "init_unwinder.h" ++ ++static pthread_mutex_t dummy_mtx = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t dummy_cond = PTHREAD_COND_INITIALIZER; ++ ++static void *dummy_thread(void *arg __attribute__((unused))) ++{ ++ pthread_mutex_lock(&dummy_mtx); ++ pthread_cond_broadcast(&dummy_cond); ++ pthread_mutex_unlock(&dummy_mtx); ++ pause(); ++ return NULL; ++} ++ ++int init_unwinder(void) ++{ ++ pthread_t dummy; ++ int rc; ++ ++ pthread_mutex_lock(&dummy_mtx); ++ ++ rc = pthread_create(&dummy, NULL, dummy_thread, NULL); ++ if (rc != 0) { ++ pthread_mutex_unlock(&dummy_mtx); ++ return rc; ++ } ++ ++ pthread_cond_wait(&dummy_cond, &dummy_mtx); ++ pthread_mutex_unlock(&dummy_mtx); ++ ++ return pthread_cancel(dummy); ++} +diff --git a/multipathd/init_unwinder.h b/multipathd/init_unwinder.h +new file mode 100644 +index 00000000..ada09f82 +--- /dev/null ++++ b/multipathd/init_unwinder.h +@@ -0,0 +1,21 @@ ++#ifndef _INIT_UNWINDER_H ++#define _INIT_UNWINDER_H 1 ++ ++/* ++ * init_unwinder(): make sure unwinder symbols are loaded ++ * ++ * libc's implementation of pthread_cancel() loads symbols from ++ * libgcc_s.so using dlopen() when pthread_cancel() is called ++ * for the first time. This happens even with LD_BIND_NOW=1. ++ * This may imply the need for file system access when a thread is ++ * cancelled, which in the case of multipath-tools might be in a ++ * dangerous situation where multipathd must avoid blocking. ++ * ++ * Call load_unwinder() during startup to make sure the dynamic ++ * linker has all necessary symbols resolved early on. ++ * ++ * Return: 0 if successful, an error number otherwise. ++ */ ++int init_unwinder(void); ++ ++#endif +diff --git a/multipathd/main.c b/multipathd/main.c +index 99a89a69..6f851ae8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -83,6 +83,7 @@ + #include "wwids.h" + #include "foreign.h" + #include "../third-party/valgrind/drd.h" ++#include "init_unwinder.h" + + #define FILE_NAME_SIZE 256 + #define CMDSIZE 160 +@@ -3041,6 +3042,7 @@ child (__attribute__((unused)) void *param) + enum daemon_status state; + int exit_code = 1; + ++ init_unwinder(); + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); + mp_rcu_data = setup_rcu(); +-- +2.17.2 + diff --git a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch new file mode 100644 index 0000000..b656c08 --- /dev/null +++ b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 11:12:21 +0100 +Subject: [PATCH] libmultipath: check if adopt_path() really added current path + +The description of 2d32d6f ("libmultipath: adopt_paths(): don't bail out on +single path failure") said "we need to check after successful call to +adopt_paths() if that specific path had been actually added, and fail in the +caller otherwise". But the commit failed to actually implement this check. +Instead, it just checked if the path was member of the pathvec, which will +almost always be the case. + +Fix it by checking what actually needs to be checked, membership of the +path to be added in mpp->paths. + +Fixes: 2d32d6f ("libmultipath: adopt_paths(): don't bail out on single path failure") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 4 ++-- + multipathd/main.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index f7f45f11..47b1d03e 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -707,8 +707,8 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, + goto out; + mpp->size = pp->size; + +- if (adopt_paths(vecs->pathvec, mpp) || +- find_slot(vecs->pathvec, pp) == -1) ++ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ find_slot(mpp->paths, pp) == -1) + goto out; + + if (add_vec) { +diff --git a/multipathd/main.c b/multipathd/main.c +index 6f851ae8..43d77688 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1008,8 +1008,8 @@ rescan: + if (mpp) { + condlog(4,"%s: adopting all paths for path %s", + mpp->alias, pp->dev); +- if (adopt_paths(vecs->pathvec, mpp) || +- find_slot(vecs->pathvec, pp) == -1) ++ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ find_slot(mpp->paths, pp) == -1) + goto fail; /* leave path added to pathvec */ + + verify_paths(mpp); +-- +2.17.2 + diff --git a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch new file mode 100644 index 0000000..f223728 --- /dev/null +++ b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 1 Feb 2021 13:10:46 +0100 +Subject: [PATCH] multipathd: ev_add_path: fail if add_map_with_path() fails + +If start_waiter was set before and the "rescan" label was used, +we may try to set up an empty/invalid map. +Always fail if add_map_with_path() isn't successful. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 43d77688..425492a9 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1028,7 +1028,7 @@ rescan: + */ + start_waiter = 1; + } +- if (!start_waiter) ++ else + goto fail; /* leave path added to pathvec */ + } + +-- +2.17.2 + diff --git a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch new file mode 100644 index 0000000..fe69708 --- /dev/null +++ b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 15:18:33 +0100 +Subject: [PATCH] libmultipath: check return value of udev_device_get_devnum() + +udev_device_get_devnum() may fail, in which case it returns +makedev(0, 0). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 921025d4..15cf6413 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1659,6 +1659,9 @@ common_sysfs_pathinfo (struct path * pp) + return PATHINFO_FAILED; + } + devt = udev_device_get_devnum(pp->udev); ++ if (major(devt) == 0 && minor(devt) == 0) ++ return PATHINFO_FAILED; ++ + snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt)); + + condlog(4, "%s: dev_t = %s", pp->dev, pp->dev_t); +-- +2.17.2 + diff --git a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch new file mode 100644 index 0000000..cf106c2 --- /dev/null +++ b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch @@ -0,0 +1,281 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 17:07:37 +0100 +Subject: [PATCH] pathinfo: call filter_property() after sysfs_pathinfo() + +The of filter_property() depends on the value of pp->uid_attribute. +This may in turn depend on pp->hwe, which is initialized in +sysfs_pathinfo(). To obtain consistent results from pathinfo(), +make sure uid_attribute is correctly set before calling filter_property(). + +filter_property() is now called from pathinfo() with properly set +uid_attribute, thus we don't need to call it from is_path_valid() any more. + +Thes changes require modifications to the unit tests. The is_path_valid() +test now wouldn't need to test filter_property() any more, because +is_path_valid() calls filter_property() no more. But that doesn't feel +right. Instead, test_filter_property() is modified to test the behavior +with the filter_property() test called indirectly from pathinfo(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 21 +++++++++- + libmultipath/valid.c | 4 -- + tests/Makefile | 2 +- + tests/test-lib.c | 5 ++- + tests/valid.c | 91 ++++++++++++++++++++++++++++++++++++---- + 5 files changed, 105 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 15cf6413..febcd0ae 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2247,9 +2247,17 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + condlog(4, "%s: hidden", pp->dev); + return PATHINFO_SKIPPED; + } +- if (is_claimed_by_foreign(pp->udev) || +- filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) ++ ++ if (is_claimed_by_foreign(pp->udev)) + return PATHINFO_SKIPPED; ++ ++ /* ++ * uid_attribute is required for filter_property below, ++ * and needs access to pp->hwe. ++ */ ++ if (!(mask & DI_SYSFS) && !pp->uid_attribute && ++ VECTOR_SIZE(pp->hwe) == 0) ++ mask |= DI_SYSFS; + } + + if (strlen(pp->dev) != 0 && filter_devnode(conf->blist_devnode, +@@ -2287,6 +2295,15 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + } + ++ if (pp->udev) { ++ /* uid_attribute is required for filter_property() */ ++ if (!pp->uid_attribute) ++ select_getuid(conf, pp); ++ ++ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) ++ return PATHINFO_SKIPPED; ++ } ++ + if (mask & DI_BLACKLIST && mask & DI_SYSFS) { + if (filter_device(conf->blist_device, conf->elist_device, + pp->vendor_id, pp->product_id, pp->dev) > 0 || +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +index 456b1f6e..a6aa9215 100644 +--- a/libmultipath/valid.c ++++ b/libmultipath/valid.c +@@ -89,10 +89,6 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + if (pp->wwid[0] == '\0') + return PATH_IS_NOT_VALID; + +- if (pp->udev && pp->uid_attribute && +- filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) +- return PATH_IS_NOT_VALID; +- + r = is_failed_wwid(pp->wwid); + if (r != WWID_IS_NOT_FAILED) { + if (r == WWID_IS_FAILED) +diff --git a/tests/Makefile b/tests/Makefile +index 50673fae..11ca1be5 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -54,7 +54,7 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl +-valid-test_OBJDEPS := ../libmultipath/valid.o ++valid-test_OBJDEPS := ../libmultipath/valid.o ../libmultipath/discovery.o + valid-test_LIBDEPS := -ludev -lpthread -ldl + devt-test_LIBDEPS := -ludev + mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl +diff --git a/tests/test-lib.c b/tests/test-lib.c +index e7663f9a..960a7665 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -257,6 +257,9 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + } else + will_return(__wrap_udev_device_get_sysattr_value, "0"); + ++ if (mask & DI_SYSFS) ++ mock_sysfs_pathinfo(mp); ++ + /* filter_property */ + will_return(__wrap_udev_device_get_sysname, mp->devnode); + if (mp->flags & BL_BY_PROPERTY) { +@@ -265,8 +268,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + } else + will_return(__wrap_udev_list_entry_get_name, + "SCSI_IDENT_LUN_NAA_EXT"); +- if (mask & DI_SYSFS) +- mock_sysfs_pathinfo(mp); + + if (mp->flags & BL_BY_DEVICE && + (mask & DI_BLACKLIST && mask & DI_SYSFS)) +diff --git a/tests/valid.c b/tests/valid.c +index 693c72c5..8ec803e8 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -25,13 +25,18 @@ + #include + #include + #include ++#include ++ + #include "globals.c" + #include "util.h" + #include "discovery.h" + #include "wwids.h" + #include "blacklist.h" ++#include "foreign.h" + #include "valid.h" + ++#define PATHINFO_REAL 9999 ++ + int test_fd; + struct udev_device { + int unused; +@@ -78,12 +83,66 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u + return NULL; + } + ++/* For the "hidden" check in pathinfo() */ ++const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, ++ const char *sysattr) ++{ ++ check_expected(sysattr); ++ return mock_ptr_type(char *); ++} ++ ++/* For pathinfo() -> is_claimed_by_foreign() */ ++int __wrap_add_foreign(struct udev_device *udev_device) ++{ ++ return mock_type(int); ++} ++ ++/* called from pathinfo() */ ++int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, ++ const char *vendor, const char * product, const char *dev) ++{ ++ return mock_type(int); ++} ++ ++/* called from pathinfo() */ ++int __wrap_filter_device(const struct _vector *blist, const struct _vector *elist, ++ const char *vendor, const char * product, const char *dev) ++{ ++ return mock_type(int); ++} ++ ++/* for common_sysfs_pathinfo() */ ++dev_t __wrap_udev_device_get_devnum(struct udev_device *ud) ++{ ++ return mock_type(dev_t); ++} ++ ++/* for common_sysfs_pathinfo() */ ++int __wrap_sysfs_get_size(struct path *pp, unsigned long long * size) ++{ ++ return mock_type(int); ++} ++ ++/* called in pathinfo() before filter_property() */ ++int __wrap_select_getuid(struct config *conf, struct path *pp) ++{ ++ pp->uid_attribute = mock_ptr_type(char *); ++ return 0; ++} ++ ++int __real_pathinfo(struct path *pp, struct config *conf, int mask); ++ + int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) + { + int ret = mock_type(int); ++ + assert_string_equal(pp->dev, mock_ptr_type(char *)); + assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); +- if (ret == PATHINFO_OK) { ++ if (ret == PATHINFO_REAL) { ++ /* for test_filter_property() */ ++ ret = __real_pathinfo(pp, conf, mask); ++ return ret; ++ } else if (ret == PATHINFO_OK) { + pp->uid_attribute = "ID_TEST"; + strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); + } else +@@ -128,6 +187,7 @@ enum { + STAGE_IS_MULTIPATHED, + STAGE_CHECK_MULTIPATHD, + STAGE_GET_UDEV_DEVICE, ++ STAGE_PATHINFO_REAL, + STAGE_PATHINFO, + STAGE_FILTER_PROPERTY, + STAGE_IS_FAILED, +@@ -167,12 +227,25 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + name); + if (stage == STAGE_GET_UDEV_DEVICE) + return; ++ if (stage == STAGE_PATHINFO_REAL) { ++ /* special case for test_filter_property() */ ++ will_return(__wrap_pathinfo, PATHINFO_REAL); ++ will_return(__wrap_pathinfo, name); ++ expect_string(__wrap_udev_device_get_sysattr_value, ++ sysattr, "hidden"); ++ will_return(__wrap_udev_device_get_sysattr_value, NULL); ++ will_return(__wrap_add_foreign, FOREIGN_IGNORED); ++ will_return(__wrap_filter_devnode, MATCH_NOTHING); ++ will_return(__wrap_udev_device_get_devnum, makedev(259, 0)); ++ will_return(__wrap_sysfs_get_size, 0); ++ will_return(__wrap_select_getuid, "ID_TEST"); ++ return; ++ } + will_return(__wrap_pathinfo, PATHINFO_OK); + will_return(__wrap_pathinfo, name); + will_return(__wrap_pathinfo, wwid); + if (stage == STAGE_PATHINFO) + return; +- will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); + if (stage == STAGE_FILTER_PROPERTY) + return; + will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); +@@ -317,24 +390,24 @@ static void test_filter_property(void **state) + /* test blacklist property */ + memset(&pp, 0, sizeof(pp)); + conf.find_multipaths = FIND_MULTIPATHS_STRICT; +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); + assert_ptr_equal(pp.udev, &test_udev); +- assert_string_equal(pp.wwid, wwid); ++ + /* test missing property */ + memset(&pp, 0, sizeof(pp)); +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); +- /* test MATCH_NOTHING fail on is_failed_wwid */ ++ ++ /* test MATCH_NOTHING fail on filter_device */ + memset(&pp, 0, sizeof(pp)); +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_NOTHING); +- will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); +- will_return(__wrap_is_failed_wwid, wwid); ++ will_return(__wrap_filter_device, MATCH_DEVICE_BLIST); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); + } +-- +2.17.2 + diff --git a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch new file mode 100644 index 0000000..c4c8efc --- /dev/null +++ b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 19:55:28 +0100 +Subject: [PATCH] libmultipath: pathinfo: call filter_property only with + DI_BLACKLIST + +With the previous change to call filter_property() after sysfs_pathinfo(), +it can't happen any more that filter_property() is called from pathinfo +with uid_attribute not set. This may cause pathinfo() to return failure +in some cases where it should actually proceed (e.g. when called from +"multipath -m" -> get_refwwid(). Therefore, don't call filter_property() +any more unless DI_BLACKLIST is set. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 16 ++++++---------- + tests/test-lib.c | 17 +++++++++-------- + 2 files changed, 15 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index febcd0ae..9be94cd1 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2255,8 +2255,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + * uid_attribute is required for filter_property below, + * and needs access to pp->hwe. + */ +- if (!(mask & DI_SYSFS) && !pp->uid_attribute && +- VECTOR_SIZE(pp->hwe) == 0) ++ if (!(mask & DI_SYSFS) && (mask & DI_BLACKLIST) && ++ !pp->uid_attribute && VECTOR_SIZE(pp->hwe) == 0) + mask |= DI_SYSFS; + } + +@@ -2295,17 +2295,13 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + } + +- if (pp->udev) { ++ if (mask & DI_BLACKLIST && mask & DI_SYSFS) { + /* uid_attribute is required for filter_property() */ +- if (!pp->uid_attribute) ++ if (pp->udev && !pp->uid_attribute) + select_getuid(conf, pp); + +- if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) +- return PATHINFO_SKIPPED; +- } +- +- if (mask & DI_BLACKLIST && mask & DI_SYSFS) { +- if (filter_device(conf->blist_device, conf->elist_device, ++ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0 || ++ filter_device(conf->blist_device, conf->elist_device, + pp->vendor_id, pp->product_id, pp->dev) > 0 || + filter_protocol(conf->blist_protocol, conf->elist_protocol, + pp) > 0) +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 960a7665..f5542ed0 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -260,14 +260,15 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + if (mask & DI_SYSFS) + mock_sysfs_pathinfo(mp); + +- /* filter_property */ +- will_return(__wrap_udev_device_get_sysname, mp->devnode); +- if (mp->flags & BL_BY_PROPERTY) { +- will_return(__wrap_udev_list_entry_get_name, "BAZ"); +- return; +- } else +- will_return(__wrap_udev_list_entry_get_name, +- "SCSI_IDENT_LUN_NAA_EXT"); ++ if (mask & DI_BLACKLIST) { ++ will_return(__wrap_udev_device_get_sysname, mp->devnode); ++ if (mp->flags & BL_BY_PROPERTY) { ++ will_return(__wrap_udev_list_entry_get_name, "BAZ"); ++ return; ++ } else ++ will_return(__wrap_udev_list_entry_get_name, ++ "SCSI_IDENT_LUN_NAA_EXT"); ++ } + + if (mp->flags & BL_BY_DEVICE && + (mask & DI_BLACKLIST && mask & DI_SYSFS)) +-- +2.17.2 + diff --git a/0121-multipath-w-allow-removing-blacklisted-paths.patch b/0121-multipath-w-allow-removing-blacklisted-paths.patch new file mode 100644 index 0000000..db6fe52 --- /dev/null +++ b/0121-multipath-w-allow-removing-blacklisted-paths.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 21:54:37 +0100 +Subject: [PATCH] multipath -w: allow removing blacklisted paths + +multipath should allow removing WWIDs of paths even if they +are blacklisted. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 3263bb01..598efe05 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1441,7 +1441,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + return ret; + } + } +- if (pp->udev && pp->uid_attribute && ++ if (flags & DI_BLACKLIST && + filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) + return PATHINFO_SKIPPED; + refwwid = pp->wwid; +@@ -1466,7 +1466,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + refwwid = dev; + } + +- if (refwwid && strlen(refwwid) && ++ if (flags & DI_BLACKLIST && refwwid && strlen(refwwid) && + filter_wwid(conf->blist_wwid, conf->elist_wwid, refwwid, + NULL) > 0) + return PATHINFO_SKIPPED; +-- +2.17.2 + diff --git a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch new file mode 100644 index 0000000..6a5fcad --- /dev/null +++ b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 1 Feb 2021 19:47:11 -0600 +Subject: [PATCH] libmultipath: fix use-after-free in uev_add_path + +if ev_remove_path() returns success the path has very likely been +deleted. However, if pathinfo() returned something besides PATHINFO_OK, +but ev_remove_path() succeeded, uev_add_path() was still accessing the +the path afterwards, which would likely cause a use-after-free error. +Insted, uev_add_path() should only continue to access the path if +ev_remove_path() didn't succeed. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 425492a9..19679848 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -890,13 +890,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + */ + pp->mpp = prev_mpp; + ret = ev_remove_path(pp, vecs, true); +- if (r == PATHINFO_OK && !ret) +- /* +- * Path successfully freed, move on to +- * "new path" code path below +- */ +- pp = NULL; +- else { ++ if (ret != 0) { + /* + * Failure in ev_remove_path will keep + * path in pathvec in INIT_REMOVED state +@@ -907,7 +901,12 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + dm_fail_path(pp->mpp->alias, pp->dev_t); + condlog(1, "%s: failed to re-add path still mapped in %s", + pp->dev, pp->mpp->alias); +- } ++ } else if (r == PATHINFO_OK) ++ /* ++ * Path successfully freed, move on to ++ * "new path" code path below ++ */ ++ pp = NULL; + } else if (r == PATHINFO_SKIPPED) { + condlog(3, "%s: remove blacklisted path", + uev->kernel); +-- +2.17.2 + diff --git a/0123-kpartx-free-loop-device-after-listing-partitions.patch b/0123-kpartx-free-loop-device-after-listing-partitions.patch new file mode 100644 index 0000000..4db7cfd --- /dev/null +++ b/0123-kpartx-free-loop-device-after-listing-partitions.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Feb 2021 17:16:04 -0600 +Subject: [PATCH] kpartx: free loop device after listing partitions + +If "kpartx -l" is run on a file that doesn't already have a loop device +associated with it, it will create a loop device to run the command. +Starting with da59d15c6 ("Fix loopback file with kpartx -av"), it will +not free the loop device when exitting. This is because it checks if the +the file it stat()ed is a regular file, before freeing the loop device. +However, after da59d15c6, stat() is rerun on the loop device itself, so +the check fails. There is no need to check this, if loopcreated is +true, then the file will be a kpartx created loop device, and should be +freed. + +Also, keep kpartx from printing that the loop device has been removed +at normal verbosity. + +Fixes: da59d15c6 ("Fix loopback file with kpartx -av") +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 6a7933fa..8ff116b8 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -424,7 +424,7 @@ main(int argc, char **argv){ + fprintf(stderr, "can't del loop : %s\n", + loopdev); + r = 1; +- } else ++ } else if (verbose) + fprintf(stderr, "loop deleted : %s\n", loopdev); + } + goto end; +@@ -668,16 +668,17 @@ main(int argc, char **argv){ + if (n > 0) + break; + } +- if (what == LIST && loopcreated && S_ISREG (buf.st_mode)) { ++ if (what == LIST && loopcreated) { + if (fd != -1) + close(fd); + if (del_loop(device)) { + if (verbose) +- printf("can't del loop : %s\n", ++ fprintf(stderr, "can't del loop : %s\n", + device); + exit(1); + } +- printf("loop deleted : %s\n", device); ++ if (verbose) ++ fprintf(stderr, "loop deleted : %s\n", device); + } + + end: +-- +2.17.2 + diff --git a/0103-RH-fixup-udev-rules-for-redhat.patch b/0124-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0103-RH-fixup-udev-rules-for-redhat.patch rename to 0124-RH-fixup-udev-rules-for-redhat.patch diff --git a/0104-RH-Remove-the-property-blacklist-exception-builtin.patch b/0125-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0104-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0125-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0105-RH-don-t-start-without-a-config-file.patch b/0126-RH-don-t-start-without-a-config-file.patch similarity index 97% rename from 0105-RH-don-t-start-without-a-config-file.patch rename to 0126-RH-don-t-start-without-a-config-file.patch index 2f8d791..2931726 100644 --- a/0105-RH-don-t-start-without-a-config-file.patch +++ b/0126-RH-don-t-start-without-a-config-file.patch @@ -81,12 +81,12 @@ index 048a838d..8bd47a80 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index ba24983e..17434cef 100644 +index 7d547fa7..af592057 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service Before=iscsi.service iscsid.service lvm2-activation-early.service - Before=local-fs-pre.target blk-availability.service + Before=local-fs-pre.target blk-availability.service shutdown.target After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service +ConditionPathExists=/etc/multipath.conf DefaultDependencies=no diff --git a/0106-RH-Fix-nvme-function-missing-argument.patch b/0127-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0106-RH-Fix-nvme-function-missing-argument.patch rename to 0127-RH-Fix-nvme-function-missing-argument.patch diff --git a/0107-RH-use-rpm-optflags-if-present.patch b/0128-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0107-RH-use-rpm-optflags-if-present.patch rename to 0128-RH-use-rpm-optflags-if-present.patch diff --git a/0108-RH-add-mpathconf.patch b/0129-RH-add-mpathconf.patch similarity index 93% rename from 0108-RH-add-mpathconf.patch rename to 0129-RH-add-mpathconf.patch index 503fef2..346251a 100644 --- a/0108-RH-add-mpathconf.patch +++ b/0129-RH-add-mpathconf.patch @@ -69,7 +69,7 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..f34003c9 +index 00000000..2f4f3eaf --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,555 @@ @@ -129,7 +129,7 @@ index 00000000..f34003c9 + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default y): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " @@ -299,8 +299,12 @@ index 00000000..f34003c9 + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi -+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then -+ echo "--find_multipaths must be either 'y' or 'n'" ++ if [ "$FIND" = "y" ]; then ++ FIND="yes" ++ elif [ "$FIND" = "n" ]; then ++ FIND="no" ++ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -402,10 +406,11 @@ index 00000000..f34003c9 +fi + +if [ "$HAVE_DEFAULTS" = "1" ]; then -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then -+ HAVE_FIND=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then -+ HAVE_FIND=0 ++ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` ++ if [ "$HAVE_FIND" = "1" ]; then ++ HAVE_FIND="yes" ++ elif [ "$HAVE_FIND" = "0" ]; then ++ HAVE_FIND="no" + fi + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then + HAVE_FRIENDLY=1 @@ -435,10 +440,10 @@ index 00000000..f34003c9 + else + echo "multipath is disabled" + fi -+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then -+ echo "find_multipaths is disabled" ++ if [ -z "$HAVE_FIND" ]; then ++ echo "find_multipaths is no" + else -+ echo "find_multipaths is enabled" ++ echo "find_multipaths is $HAVE_FIND" + fi + if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then + echo "user_friendly_names is disabled" @@ -530,19 +535,14 @@ index 00000000..f34003c9 + fi +fi + -+if [ "$FIND" = "n" ]; then -+ if [ "$HAVE_FIND" = 1 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FIND" = "y" ]; then ++if [ -n "$FIND" ]; then + if [ -z "$HAVE_FIND" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ -+ find_multipaths yes ++ find_multipaths '"$FIND"' +' $TMPFILE + CHANGED_CONFIG=1 -+ elif [ "$HAVE_FIND" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE ++ elif [ "$FIND" != "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi @@ -630,7 +630,7 @@ index 00000000..f34003c9 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..b82961d6 +index 00000000..83515eb4 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,135 @@ @@ -674,9 +674,9 @@ index 00000000..b82961d6 +already exists, mpathconf will edit it. If it does not exist, mpathconf will +create a default file with +.B user_friendly_names -+and ++set and +.B find_multipaths -+set. To disable these, use the ++set to \fByes\fP. To disable these, use the +.B --user_friendly_names n +and +.B --find_multipaths n @@ -713,13 +713,13 @@ index 00000000..b82961d6 +defaults section. If set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP -+.B --find_multipaths\fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B find_multipaths yes ++.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++If set to \fB\fP, this adds the line ++.B find_multipaths +to the +.B /etc/multipath.conf -+defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used along with any other command. ++defaults section. This command can be used along with any other command. ++\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. +.TP +.B --property_blacklist \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line diff --git a/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 99% rename from 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index cdce408..3f0a9ad 100644 --- a/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -138,7 +138,7 @@ index 5b29a5d9..0478f4e7 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 17434cef..0fbcc46b 100644 +index af592057..bc8fa07a 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -15,6 +15,7 @@ Type=notify diff --git a/0110-RH-reset-default-find_mutipaths-value-to-off.patch b/0131-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0110-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0131-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 3969445..a304363 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -112,15 +112,36 @@ Patch0099: 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch Patch0100: 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch Patch0101: 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch Patch0102: 0102-multipathd-cleanup-logging-for-marginal-paths.patch -Patch0103: 0103-RH-fixup-udev-rules-for-redhat.patch -Patch0104: 0104-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0105: 0105-RH-don-t-start-without-a-config-file.patch -Patch0106: 0106-RH-Fix-nvme-function-missing-argument.patch -Patch0107: 0107-RH-use-rpm-optflags-if-present.patch -Patch0108: 0108-RH-add-mpathconf.patch -Patch0109: 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0110: 0110-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0111: 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0103: 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch +Patch0104: 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch +Patch0105: 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch +Patch0106: 0106-Added-github-action-for-building.patch +Patch0107: 0107-github-workflow-use-zram-device-as-test-block-device.patch +Patch0108: 0108-github-workflow-use-explicit-Ubuntu-version.patch +Patch0109: 0109-github-workflow-add-valgrind-tests.patch +Patch0110: 0110-github-workflow-run-apt-get-update.patch +Patch0111: 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch +Patch0112: 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch +Patch0113: 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch +Patch0114: 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch +Patch0115: 0115-multipathd-add-code-to-initalize-unwinder.patch +Patch0116: 0116-libmultipath-check-if-adopt_path-really-added-curren.patch +Patch0117: 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch +Patch0118: 0118-libmultipath-check-return-value-of-udev_device_get_d.patch +Patch0119: 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch +Patch0120: 0120-libmultipath-pathinfo-call-filter_property-only-with.patch +Patch0121: 0121-multipath-w-allow-removing-blacklisted-paths.patch +Patch0122: 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch +Patch0123: 0123-kpartx-free-loop-device-after-listing-partitions.patch +Patch0124: 0124-RH-fixup-udev-rules-for-redhat.patch +Patch0125: 0125-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0126: 0126-RH-don-t-start-without-a-config-file.patch +Patch0127: 0127-RH-Fix-nvme-function-missing-argument.patch +Patch0128: 0128-RH-use-rpm-optflags-if-present.patch +Patch0129: 0129-RH-add-mpathconf.patch +Patch0130: 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0131: 0131-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0132: 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -318,6 +339,15 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 11 2021 Benjamin Marzinski - 0.8.5-4 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0121 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream + * Patches 0122&0123 have been posted for upstream inclusion +- Rename files + * Previous patches 0103-0111 are now patches 0124-0132 + * Tue Jan 26 2021 Fedora Release Engineering - 0.8.5-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild