device-mapper-multipath-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
This commit is contained in:
Benjamin Marzinski 2021-02-11 13:53:51 -06:00
parent 13dea6f50c
commit 9fdf79cddf
31 changed files with 1601 additions and 41 deletions

View File

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lixiaokeng <lixiaokeng@huawei.com>
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 <mwilck@suse.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,274 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
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

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 18 Dec 2020 21:38:43 +0100
Subject: [PATCH] Added github action for building
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 18 Dec 2020 22:54:24 +0100
Subject: [PATCH] github workflow: use explicit Ubuntu version
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Fri, 18 Dec 2020 23:21:16 +0100
Subject: [PATCH] github workflow: add valgrind tests
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
---
.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

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
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

View File

@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,134 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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 <pthread.h>
+#include <unistd.h>
+#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

View File

@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,281 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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 <stdlib.h>
#include <errno.h>
#include <cmocka.h>
+#include <sys/sysmacros.h>
+
#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

View File

@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
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 <bmarzins@redhat.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -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

View File

@ -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 <WWID>"
+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
+ echo "Set find_multipaths (Default y): --find_multipaths <y|n>"
+ echo "Set find_multipaths (Default y): --find_multipaths <yes|no|strict|greedy|smart>"
+ echo "Set default property blacklist (Default y): --property_blacklist <y|n>"
+ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>"
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
@ -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<value>\fP, this adds the line
+.B find_multipaths <value>
+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

View File

@ -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

View File

@ -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 <bmarzins@redhat.com> - 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 <releng@fedoraproject.org> - 0.8.5-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild