import device-mapper-multipath-0.8.0-5.el8
This commit is contained in:
commit
70e223f212
1
.device-mapper-multipath.metadata
Normal file
1
.device-mapper-multipath.metadata
Normal file
@ -0,0 +1 @@
|
||||
30bf38b713001c2b80b86d67473fbe20dc0f28cc SOURCES/multipath-tools-0.8.0.tgz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/multipath-tools-0.8.0.tgz
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 24 Jan 2019 14:09:23 -0600
|
||||
Subject: [PATCH] BZ 1668693: disable user_friendly_names for NetApp
|
||||
|
||||
NetApp has tools that rely on devices using WWID names. To avoid
|
||||
breaking these, NetApp devices should continue to use WWID names, even
|
||||
if the default config is set to enable user_friendly_names. If users
|
||||
want to use user_friendly_names on NetApp devices, the must specifically
|
||||
override the device config.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index d3a8d9b..8776411 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -719,6 +719,7 @@ static struct hwentry default_hw[] = {
|
||||
.flush_on_last_del = FLUSH_ENABLED,
|
||||
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||
.prio_name = PRIO_ONTAP,
|
||||
+ .user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||
},
|
||||
{
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 16:45:26 -0600
|
||||
Subject: [PATCH] libmultipath: handle existing paths in marginal_path enqueue
|
||||
|
||||
If the path that enqueue_io_err_stat_by_path() is trying to add
|
||||
is already on the list, just return success. There's no reason
|
||||
to fail in this case.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 02b1453..1cb3ffe 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -254,7 +254,6 @@ static void free_io_err_pathvec(struct io_err_stat_pathvec *p)
|
||||
* return value
|
||||
* 0: enqueue OK
|
||||
* 1: fails because of internal error
|
||||
- * 2: fails because of existing already
|
||||
*/
|
||||
static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
{
|
||||
@@ -264,7 +263,7 @@ static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
p = find_err_path_by_dev(paths->pathvec, path->dev);
|
||||
if (p) {
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
- return 2;
|
||||
+ return 0;
|
||||
}
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
|
||||
@@ -418,9 +417,8 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(3, "%s: enqueue fails, to recover",
|
||||
pp->dev);
|
||||
goto recover;
|
||||
- } else if (!r) {
|
||||
+ } else
|
||||
pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING;
|
||||
- }
|
||||
}
|
||||
|
||||
return 1;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 17:09:42 -0600
|
||||
Subject: [PATCH] multipathd: cleanup marginal paths checking timers
|
||||
|
||||
When a path gets recovered in hit_io_err_recheck_time(), it will
|
||||
continue running in check_path(), so there is no reason to schedule
|
||||
another path check as soon as possible (since one is currently
|
||||
happening).
|
||||
|
||||
Also, there isn't much point in restarting the io err stat checking when
|
||||
the path is down, so hit_io_err_recheck_time() should only be run when
|
||||
the path is up. Downed marginal paths can be treated just like any other
|
||||
downed path.
|
||||
|
||||
Finally, there is no reason to set reset pp->io_err_dis_reinstate_time
|
||||
when we decide to enqueue a path. Either th enqueue will fail and the
|
||||
path will get recovered, or it will succeed, and we won't check the
|
||||
reinstate time again until poll_io_err_stat() marks the path as needing
|
||||
a requeue.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 8 --------
|
||||
multipathd/main.c | 3 ++-
|
||||
2 files changed, 2 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 1cb3ffe..416e13a 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -400,13 +400,6 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(4, "%s: reschedule checking after %d seconds",
|
||||
pp->dev,
|
||||
pp->mpp->marginal_path_err_recheck_gap_time);
|
||||
- /*
|
||||
- * to reschedule io error checking again
|
||||
- * if the path is good enough, we claim it is good
|
||||
- * and can be reinsated as soon as possible in the
|
||||
- * check_path routine.
|
||||
- */
|
||||
- pp->io_err_dis_reinstate_time = curr_time.tv_sec;
|
||||
r = enqueue_io_err_stat_by_path(pp);
|
||||
/*
|
||||
* Enqueue fails because of internal error.
|
||||
@@ -426,7 +419,6 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
recover:
|
||||
pp->io_err_pathfail_cnt = 0;
|
||||
pp->io_err_disable_reinstate = 0;
|
||||
- pp->tick = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fb520b6..fe6d8ef 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2079,7 +2079,8 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
+ if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
+ pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
pp->state = PATH_SHAKY;
|
||||
/*
|
||||
* to reschedule as soon as possible,so that this path can
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,176 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 28 Jan 2019 00:20:53 -0600
|
||||
Subject: [PATCH] libmultipath: fix marginal paths queueing errors
|
||||
|
||||
The current marginal paths code tries to enqueue paths for io error
|
||||
checking when multipathd receives a uevent on path failure. This can run
|
||||
into a couple of problems. First, this uevent could happen before or
|
||||
after multipathd actually fails the path, so simply checking nr_active
|
||||
doesn't tell us if this is the last active path. Also, The code to fail
|
||||
the path in enqueue_io_err_stat_by_path() doesn't ever update the path
|
||||
state. This can cause the path to get failed twice, temporarily leading
|
||||
to incorrect nr_active counts. Further, The point when multipathd should
|
||||
care if this is the last active path is when the path has come up again,
|
||||
not when it goes down. Lastly, if the path is down, it is often
|
||||
impossible to open the path device, causing setup_directio_ctx() to
|
||||
fail, which causes multipathd to skip io error checking and mark the
|
||||
path as not marginal.
|
||||
|
||||
Instead, multipathd should just make sure that if the path is marginal,
|
||||
it gets failed in the uevent, so as not to race with the checkerloop
|
||||
thread. Then, when the path comes back up, check_path() can enqueue it,
|
||||
just like it does for paths that need to get rechecked. To make it
|
||||
obvious that the state PATH_IO_ERR_IN_POLLING_RECHECK and the function
|
||||
hit_io_err_recheck_time() now apply to paths waiting to be enqueued for
|
||||
the first time as well, I've also changed their names to
|
||||
PATH_IO_ERR_WAITING_TO_CHECK and need_io_err_check(), respectively.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 55 +++++++++++++++++---------------------
|
||||
libmultipath/io_err_stat.h | 2 +-
|
||||
multipathd/main.c | 2 +-
|
||||
3 files changed, 27 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 416e13a..72aacf3 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -41,7 +41,7 @@
|
||||
#define CONCUR_NR_EVENT 32
|
||||
|
||||
#define PATH_IO_ERR_IN_CHECKING -1
|
||||
-#define PATH_IO_ERR_IN_POLLING_RECHECK -2
|
||||
+#define PATH_IO_ERR_WAITING_TO_CHECK -2
|
||||
|
||||
#define io_err_stat_log(prio, fmt, args...) \
|
||||
condlog(prio, "io error statistic: " fmt, ##args)
|
||||
@@ -283,24 +283,6 @@ static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
vector_set_slot(paths->pathvec, p);
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
|
||||
- if (!path->io_err_disable_reinstate) {
|
||||
- /*
|
||||
- *fail the path in the kernel for the time of the to make
|
||||
- *the test more reliable
|
||||
- */
|
||||
- io_err_stat_log(3, "%s: fail dm path %s before checking",
|
||||
- path->mpp->alias, path->dev);
|
||||
- path->io_err_disable_reinstate = 1;
|
||||
- dm_fail_path(path->mpp->alias, path->dev_t);
|
||||
- update_queue_mode_del_path(path->mpp);
|
||||
-
|
||||
- /*
|
||||
- * schedule path check as soon as possible to
|
||||
- * update path state to delayed state
|
||||
- */
|
||||
- path->tick = 1;
|
||||
-
|
||||
- }
|
||||
io_err_stat_log(2, "%s: enqueue path %s to check",
|
||||
path->mpp->alias, path->dev);
|
||||
return 0;
|
||||
@@ -317,7 +299,6 @@ free_ioerr_path:
|
||||
int io_err_stat_handle_pathfail(struct path *path)
|
||||
{
|
||||
struct timespec curr_time;
|
||||
- int res;
|
||||
|
||||
if (uatomic_read(&io_err_thread_running) == 0)
|
||||
return 1;
|
||||
@@ -332,8 +313,6 @@ int io_err_stat_handle_pathfail(struct path *path)
|
||||
|
||||
if (!path->mpp)
|
||||
return 1;
|
||||
- if (path->mpp->nr_active <= 1)
|
||||
- return 1;
|
||||
if (path->mpp->marginal_path_double_failed_time <= 0 ||
|
||||
path->mpp->marginal_path_err_sample_time <= 0 ||
|
||||
path->mpp->marginal_path_err_recheck_gap_time <= 0 ||
|
||||
@@ -371,17 +350,33 @@ int io_err_stat_handle_pathfail(struct path *path)
|
||||
}
|
||||
path->io_err_pathfail_cnt++;
|
||||
if (path->io_err_pathfail_cnt >= FLAKY_PATHFAIL_THRESHOLD) {
|
||||
- res = enqueue_io_err_stat_by_path(path);
|
||||
- if (!res)
|
||||
- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING;
|
||||
- else
|
||||
- path->io_err_pathfail_cnt = 0;
|
||||
+ path->io_err_disable_reinstate = 1;
|
||||
+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
+ /* enqueue path as soon as it comes up */
|
||||
+ path->io_err_dis_reinstate_time = 0;
|
||||
+ if (path->state != PATH_DOWN) {
|
||||
+ struct config *conf;
|
||||
+ int oldstate = path->state;
|
||||
+ int checkint;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ checkint = conf->checkint;
|
||||
+ put_multipath_config(conf);
|
||||
+ io_err_stat_log(2, "%s: mark as failed", path->dev);
|
||||
+ path->mpp->stat_path_failures++;
|
||||
+ path->state = PATH_DOWN;
|
||||
+ path->dmstate = PSTATE_FAILED;
|
||||
+ if (oldstate == PATH_UP || oldstate == PATH_GHOST)
|
||||
+ update_queue_mode_del_path(path->mpp);
|
||||
+ if (path->tick > checkint)
|
||||
+ path->tick = checkint;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int hit_io_err_recheck_time(struct path *pp)
|
||||
+int need_io_err_check(struct path *pp)
|
||||
{
|
||||
struct timespec curr_time;
|
||||
int r;
|
||||
@@ -392,7 +387,7 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(2, "%s: recover path early", pp->dev);
|
||||
goto recover;
|
||||
}
|
||||
- if (pp->io_err_pathfail_cnt != PATH_IO_ERR_IN_POLLING_RECHECK)
|
||||
+ if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK)
|
||||
return 1;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 ||
|
||||
(curr_time.tv_sec - pp->io_err_dis_reinstate_time) >
|
||||
@@ -489,7 +484,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp)
|
||||
} else if (path->mpp && path->mpp->nr_active > 1) {
|
||||
io_err_stat_log(3, "%s: keep failing the dm path %s",
|
||||
path->mpp->alias, path->dev);
|
||||
- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_POLLING_RECHECK;
|
||||
+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
path->io_err_disable_reinstate = 1;
|
||||
path->io_err_dis_reinstate_time = currtime.tv_sec;
|
||||
io_err_stat_log(3, "%s: disable reinstating of %s",
|
||||
diff --git a/libmultipath/io_err_stat.h b/libmultipath/io_err_stat.h
|
||||
index bbf31b4..53d6d7d 100644
|
||||
--- a/libmultipath/io_err_stat.h
|
||||
+++ b/libmultipath/io_err_stat.h
|
||||
@@ -10,6 +10,6 @@ extern pthread_attr_t io_err_stat_attr;
|
||||
int start_io_err_stat_thread(void *data);
|
||||
void stop_io_err_stat_thread(void);
|
||||
int io_err_stat_handle_pathfail(struct path *path);
|
||||
-int hit_io_err_recheck_time(struct path *pp);
|
||||
+int need_io_err_check(struct path *pp);
|
||||
|
||||
#endif /* _IO_ERR_STAT_H */
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fe6d8ef..43830e8 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2080,7 +2080,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
}
|
||||
|
||||
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
- pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
+ pp->io_err_disable_reinstate && need_io_err_check(pp)) {
|
||||
pp->state = PATH_SHAKY;
|
||||
/*
|
||||
* to reschedule as soon as possible,so that this path can
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 29 Jan 2019 18:26:04 -0600
|
||||
Subject: [PATCH] libmultipath: fix marginal_paths nr_active check
|
||||
|
||||
Marginal paths are SHAKY, so they don't count towards the number of
|
||||
active paths. poll_io_err_stat() shouldn't automatically reinstate a
|
||||
marginal path if there already is an active path.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 72aacf3..554b777 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -481,7 +481,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp)
|
||||
*/
|
||||
path->tick = 1;
|
||||
|
||||
- } else if (path->mpp && path->mpp->nr_active > 1) {
|
||||
+ } else if (path->mpp && path->mpp->nr_active > 0) {
|
||||
io_err_stat_log(3, "%s: keep failing the dm path %s",
|
||||
path->mpp->alias, path->dev);
|
||||
path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
--
|
||||
2.17.2
|
||||
|
92
SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch
Normal file
92
SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 15 Feb 2019 17:19:46 -0600
|
||||
Subject: [PATCH] multipathd: Fix miscounting active paths
|
||||
|
||||
When multipathd gets a change uevent, it calls pathinfo with DI_NOIO.
|
||||
This sets the path state to the return value of path_offline(). If a
|
||||
path is in the PATH_DOWN state but path_offline() returns PATH_UP, when
|
||||
that path gets a change event, its state will get moved to PATH_UP
|
||||
without either reinstating the path, or reloading the map. The next
|
||||
call to check_path() will move the path back to PATH_DOWN. Since
|
||||
check_path() simply increments and decrements nr_active instead of
|
||||
calculating it based on the actual number of active paths, nr_active
|
||||
will get decremented a second time for this failed path, potentially
|
||||
putting the multipath device into recovery mode.
|
||||
|
||||
This commit does two things to avoid this situation. It makes the
|
||||
DI_NOIO flag only set pp->state in pathinfo() if DI_CHECKER is also set.
|
||||
This isn't set in uev_update_path() to avoid changing the path state in
|
||||
this case. Also, to guard against pp->state getting changed in some
|
||||
other code path without properly updating the map state, check_path()
|
||||
now calls set_no_path_retry, which recalculates nr_active based on the
|
||||
actual number of active paths, and makes sure that the queue_if_no_path
|
||||
value in the features line is correct.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 11 ++++++-----
|
||||
multipath/main.c | 2 +-
|
||||
multipathd/main.c | 4 +++-
|
||||
3 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 10bd8cd..729bcb9 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1914,11 +1914,12 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
if (path_state == PATH_REMOVED)
|
||||
goto blank;
|
||||
else if (mask & DI_NOIO) {
|
||||
- /*
|
||||
- * Avoid any IO on the device itself.
|
||||
- * Behave like DI_CHECKER in the "path unavailable" case.
|
||||
- */
|
||||
- pp->chkrstate = pp->state = path_state;
|
||||
+ if (mask & DI_CHECKER)
|
||||
+ /*
|
||||
+ * Avoid any IO on the device itself.
|
||||
+ * simply use the path_offline() return as its state
|
||||
+ */
|
||||
+ pp->chkrstate = pp->state = path_state;
|
||||
return PATHINFO_OK;
|
||||
}
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 5abb118..69141db 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -356,7 +356,7 @@ static int check_usable_paths(struct config *conf,
|
||||
pp->udev = get_udev_device(pp->dev_t, DEV_DEVT);
|
||||
if (pp->udev == NULL)
|
||||
continue;
|
||||
- if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) != PATHINFO_OK)
|
||||
+ if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO|DI_CHECKER) != PATHINFO_OK)
|
||||
continue;
|
||||
|
||||
if (pp->state == PATH_UP &&
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 43830e8..678ecf8 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -392,7 +392,8 @@ static void set_no_path_retry(struct multipath *mpp)
|
||||
default:
|
||||
if (mpp->nr_active > 0) {
|
||||
mpp->retry_tick = 0;
|
||||
- dm_queue_if_no_path(mpp->alias, 1);
|
||||
+ if (!is_queueing)
|
||||
+ dm_queue_if_no_path(mpp->alias, 1);
|
||||
} else if (is_queueing && mpp->retry_tick == 0)
|
||||
enter_recovery_mode(mpp);
|
||||
break;
|
||||
@@ -2072,6 +2073,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
/* if update_multipath_strings orphaned the path, quit early */
|
||||
if (!pp->mpp)
|
||||
return 0;
|
||||
+ set_no_path_retry(pp->mpp);
|
||||
|
||||
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
check_path_reinstate_state(pp)) {
|
||||
--
|
||||
2.17.2
|
||||
|
71
SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch
Normal file
71
SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 20 Feb 2019 17:05:08 -0600
|
||||
Subject: [PATCH] multipathd: ignore failed wwid recheck
|
||||
|
||||
If disable_changed_wwids is set, when multipathd gets a change event on
|
||||
a path, it verifies that the wwid hasn't changed in uev_update_path().
|
||||
If get_uid() failed, uev_update_path treated this as a wwid change to 0.
|
||||
This could cause paths to suddenly be dropped due to an issue with
|
||||
getting the wwid. Even if get_uid() failed because the path was down,
|
||||
it no change uevent happend when it later became active, multipathd
|
||||
would continue to ignore the path. Also, scsi_uid_fallback() clears the
|
||||
failure return if it doesn't attempt to fallback, causing get_uid()
|
||||
to return success, when it actually failed.
|
||||
|
||||
Multipathd should neither set nor clear wwid_changed if get_uid()
|
||||
returned failure. Also, scsi_uid_fallback() should retain the old return
|
||||
value if it doesn't attempt to fallback.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 6 +++---
|
||||
multipathd/main.c | 6 ++++--
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 729bcb9..b08cb2d 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1755,9 +1755,9 @@ get_vpd_uid(struct path * pp)
|
||||
}
|
||||
|
||||
static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin)
|
||||
+ const char **origin, ssize_t old_len)
|
||||
{
|
||||
- ssize_t len = 0;
|
||||
+ ssize_t len = old_len;
|
||||
int retrigger;
|
||||
struct config *conf;
|
||||
|
||||
@@ -1828,7 +1828,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
origin = "sysfs";
|
||||
}
|
||||
if (len <= 0 && pp->bus == SYSFS_BUS_SCSI)
|
||||
- len = scsi_uid_fallback(pp, path_state, &origin);
|
||||
+ len = scsi_uid_fallback(pp, path_state, &origin, len);
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 678ecf8..fd83a6a 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1234,9 +1234,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
goto out;
|
||||
|
||||
strcpy(wwid, pp->wwid);
|
||||
- get_uid(pp, pp->state, uev->udev);
|
||||
+ rc = get_uid(pp, pp->state, uev->udev);
|
||||
|
||||
- if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
+ if (rc != 0)
|
||||
+ strcpy(pp->wwid, wwid);
|
||||
+ else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
condlog(0, "%s: path wwid changed from '%s' to '%s'. %s",
|
||||
uev->kernel, wwid, pp->wwid,
|
||||
(disable_changed_wwids ? "disallowing" :
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 13:05:43 -0600
|
||||
Subject: [PATCH] libmutipath: continue to use old state on PATH_PENDING
|
||||
|
||||
When pathinfo() sets pp->state to PATH_PENDING, it can cause problems
|
||||
with path checking. It should act more like check_path(). When
|
||||
check_path() sees a new state of PATH_PENDING, it doesn't update the
|
||||
path state at all, so a path's old state is normally never PATH_PENDING.
|
||||
|
||||
As and example of the problems of setting a path to PATH_PENDING, If
|
||||
check_path() sets a path's state to PATH_UP, then a call to pathinfo()
|
||||
sets the state to PATH_PENDING, and then another call the check_path()
|
||||
sets the state to PATH_DOWN, multipathd won't fail the path in the
|
||||
kernel. Also, if a path's state is PATH_PENDING, and nr_active is
|
||||
recalculated, that path will count as down, even if the state was
|
||||
previously PATH_UP. If a path already has a state of PATH_WILD or
|
||||
PATH_UNCHECKED, changing it to PATH_PENDING won't hurt anything, and it
|
||||
will help anyone who sees it know what's actually happening. But
|
||||
otherwise, pathinfo() should leave the previous state alone.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index b08cb2d..28c00e5 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1946,8 +1946,11 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
|
||||
if (mask & DI_CHECKER) {
|
||||
if (path_state == PATH_UP) {
|
||||
- pp->chkrstate = pp->state = get_state(pp, conf, 0,
|
||||
- path_state);
|
||||
+ int newstate = get_state(pp, conf, 0, path_state);
|
||||
+ if (newstate != PATH_PENDING ||
|
||||
+ pp->state == PATH_UNCHECKED ||
|
||||
+ pp->state == PATH_WILD)
|
||||
+ pp->chkrstate = pp->state = newstate;
|
||||
if (pp->state == PATH_TIMEOUT)
|
||||
pp->state = PATH_DOWN;
|
||||
if (pp->state == PATH_UP && !pp->size) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,76 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 17:00:17 -0600
|
||||
Subject: [PATCH] multipathd: use update_path_groups instead of reload_map
|
||||
|
||||
reload_map() doesn't do the work to sync the state after reloading the
|
||||
map. Instead of calling it directly, cli_reload() and uev_update_path()
|
||||
should call update_path_groups(), which calls reload_map() with all the
|
||||
necessary syncing.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 2 +-
|
||||
multipathd/main.c | 13 ++++++++-----
|
||||
multipathd/main.h | 2 ++
|
||||
3 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index f95813e..60e17d6 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -877,7 +877,7 @@ cli_reload(void *v, char **reply, int *len, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- return reload_map(vecs, mpp, 0, 1);
|
||||
+ return update_path_groups(mpp, vecs, 0);
|
||||
}
|
||||
|
||||
int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fd83a6a..7a317d9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1273,10 +1273,13 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
else {
|
||||
if (ro == 1)
|
||||
pp->mpp->force_readonly = 1;
|
||||
- retval = reload_map(vecs, mpp, 0, 1);
|
||||
- pp->mpp->force_readonly = 0;
|
||||
- condlog(2, "%s: map %s reloaded (retval %d)",
|
||||
- uev->kernel, mpp->alias, retval);
|
||||
+ retval = update_path_groups(mpp, vecs, 0);
|
||||
+ if (retval == 2)
|
||||
+ condlog(2, "%s: map removed during reload", pp->dev);
|
||||
+ else {
|
||||
+ pp->mpp->force_readonly = 0;
|
||||
+ condlog(2, "%s: map %s reloaded (retval %d)", uev->kernel, mpp->alias, retval);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1832,7 +1835,7 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
|
||||
|
||||
dm_lib_release();
|
||||
if (setup_multipath(vecs, mpp) != 0)
|
||||
- return 1;
|
||||
+ return 2;
|
||||
sync_map_state(mpp);
|
||||
|
||||
return 0;
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index 8fd426b..e5c1398 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -43,5 +43,7 @@ int __setup_multipath (struct vectors * vecs, struct multipath * mpp,
|
||||
int reset);
|
||||
#define setup_multipath(vecs, mpp) __setup_multipath(vecs, mpp, 1)
|
||||
int update_multipath (struct vectors *vecs, char *mapname, int reset);
|
||||
+int update_path_groups(struct multipath *mpp, struct vectors *vecs,
|
||||
+ int refresh);
|
||||
|
||||
#endif /* MAIN_H */
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,56 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 26 Feb 2019 12:22:59 -0600
|
||||
Subject: [PATCH] multipath.conf: add missing options to man page
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.conf.5 | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 0fe8461..864d7eb 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1468,6 +1468,8 @@ section:
|
||||
.TP
|
||||
.B uid_attribute
|
||||
.TP
|
||||
+.B getuid_callout
|
||||
+.TP
|
||||
.B path_selector
|
||||
.TP
|
||||
.B path_checker
|
||||
@@ -1494,6 +1496,8 @@ section:
|
||||
.TP
|
||||
.B flush_on_last_del
|
||||
.TP
|
||||
+.B user_friendly_names
|
||||
+.TP
|
||||
.B retain_attached_hw_handler
|
||||
.TP
|
||||
.B detect_prio
|
||||
@@ -1525,6 +1529,8 @@ section:
|
||||
.B max_sectors_kb
|
||||
.TP
|
||||
.B ghost_delay
|
||||
+.TP
|
||||
+.B all_tg_pt
|
||||
.RE
|
||||
.PD
|
||||
.LP
|
||||
@@ -1604,7 +1610,11 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections:
|
||||
.TP
|
||||
.B skip_kpartx
|
||||
.TP
|
||||
+.B max_sectors_kb
|
||||
+.TP
|
||||
.B ghost_delay
|
||||
+.TP
|
||||
+.B all_tg_pt
|
||||
.RE
|
||||
.PD
|
||||
.LP
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 7 Mar 2019 16:14:35 -0600
|
||||
Subject: [PATCH] libmultipath: add get_uid fallback code for NVMe devices
|
||||
|
||||
If multipath can't get the uid for NVMe devices from udev, it can get it
|
||||
directly from sysfs.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 49 ++++++++++++++++++++++++++++------------
|
||||
1 file changed, 34 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 28c00e5..bece67c 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1754,8 +1754,8 @@ get_vpd_uid(struct path * pp)
|
||||
return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE);
|
||||
}
|
||||
|
||||
-static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin, ssize_t old_len)
|
||||
+static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
+ const char **origin, ssize_t old_len)
|
||||
{
|
||||
ssize_t len = old_len;
|
||||
int retrigger;
|
||||
@@ -1764,17 +1764,36 @@ static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
conf = get_multipath_config();
|
||||
retrigger = conf->retrigger_tries;
|
||||
put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger &&
|
||||
- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
- len = get_vpd_uid(pp);
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
- if (len < 0 && path_state == PATH_UP) {
|
||||
- condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
- pp->dev, strerror(-len));
|
||||
- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
- WWID_SIZE);
|
||||
- *origin = "sgio";
|
||||
+ if (pp->retriggers >= retrigger) {
|
||||
+ if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
+ len = get_vpd_uid(pp);
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
+ if (len < 0 && path_state == PATH_UP) {
|
||||
+ condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
+ pp->dev, strerror(-len));
|
||||
+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ WWID_SIZE);
|
||||
+ *origin = "sgio";
|
||||
+ }
|
||||
+ } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
+ char value[256];
|
||||
+ len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
+ sizeof(value));
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
+ len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
+ if (len >= WWID_SIZE) {
|
||||
+ len = fix_broken_nvme_wwid(pp, value,
|
||||
+ WWID_SIZE);
|
||||
+ if (len > 0)
|
||||
+ return len;
|
||||
+ condlog(0, "%s: wwid overflow", pp->dev);
|
||||
+ len = WWID_SIZE;
|
||||
+ }
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
@@ -1827,8 +1846,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0 && pp->bus == SYSFS_BUS_SCSI)
|
||||
- len = scsi_uid_fallback(pp, path_state, &origin, len);
|
||||
+ if (len <= 0)
|
||||
+ len = uid_fallback(pp, path_state, &origin, len);
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
--
|
||||
2.17.2
|
||||
|
129
SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch
Normal file
129
SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 27 Mar 2019 12:21:57 -0500
|
||||
Subject: [PATCH] libmulitpath: cleanup uid_fallback code
|
||||
|
||||
Instead of always calling uid_fallback() if the configured method to get
|
||||
the uid failed, get_uid now checks if the path supports fallbacks and if
|
||||
all the retriggers have occurred. If so, it calls uid_fallback(), which
|
||||
just attempts to get the uid using the appropriate fallback method. None
|
||||
of these changes should make the code function any differently.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 85 ++++++++++++++++++++++------------------
|
||||
1 file changed, 46 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index bece67c..3ec60d6 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1755,50 +1755,50 @@ get_vpd_uid(struct path * pp)
|
||||
}
|
||||
|
||||
static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin, ssize_t old_len)
|
||||
+ const char **origin)
|
||||
{
|
||||
- ssize_t len = old_len;
|
||||
- int retrigger;
|
||||
- struct config *conf;
|
||||
-
|
||||
- conf = get_multipath_config();
|
||||
- retrigger = conf->retrigger_tries;
|
||||
- put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger) {
|
||||
- if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
- len = get_vpd_uid(pp);
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
- if (len < 0 && path_state == PATH_UP) {
|
||||
- condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
- pp->dev, strerror(-len));
|
||||
- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ ssize_t len = -1;
|
||||
+
|
||||
+ if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
+ len = get_vpd_uid(pp);
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
+ if (len < 0 && path_state == PATH_UP) {
|
||||
+ condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
+ pp->dev, strerror(-len));
|
||||
+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ WWID_SIZE);
|
||||
+ *origin = "sgio";
|
||||
+ }
|
||||
+ } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
+ char value[256];
|
||||
+ len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
+ sizeof(value));
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
+ len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
+ if (len >= WWID_SIZE) {
|
||||
+ len = fix_broken_nvme_wwid(pp, value,
|
||||
WWID_SIZE);
|
||||
- *origin = "sgio";
|
||||
- }
|
||||
- } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
- char value[256];
|
||||
- len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
- sizeof(value));
|
||||
- if (len <= 0)
|
||||
- return -1;
|
||||
- len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
- if (len >= WWID_SIZE) {
|
||||
- len = fix_broken_nvme_wwid(pp, value,
|
||||
- WWID_SIZE);
|
||||
- if (len > 0)
|
||||
- return len;
|
||||
- condlog(0, "%s: wwid overflow", pp->dev);
|
||||
- len = WWID_SIZE;
|
||||
- }
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
+ if (len > 0)
|
||||
+ return len;
|
||||
+ condlog(0, "%s: wwid overflow", pp->dev);
|
||||
+ len = WWID_SIZE;
|
||||
}
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
+static int has_uid_fallback(struct path *pp)
|
||||
+{
|
||||
+ return ((pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) ||
|
||||
+ pp->bus == SYSFS_BUS_NVME);
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
{
|
||||
@@ -1846,8 +1846,15 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0)
|
||||
- len = uid_fallback(pp, path_state, &origin, len);
|
||||
+ if (len <= 0 && has_uid_fallback(pp)) {
|
||||
+ int retrigger_tries;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ retrigger_tries = conf->retrigger_tries;
|
||||
+ put_multipath_config(conf);
|
||||
+ if (pp->retriggers >= retrigger_tries)
|
||||
+ len = uid_fallback(pp, path_state, &origin);
|
||||
+ }
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,83 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 27 Mar 2019 23:27:47 -0500
|
||||
Subject: [PATCH] multipathd: handle changed wwids by removal and addition
|
||||
|
||||
If a path's WWID changes, it's not necessarily failed. But it certainly
|
||||
has to be removed from an existing map, otherwise data corruption is
|
||||
imminent. Instead of keeping the path in the map, failing it, and
|
||||
remembering the "changed WWID" state, this patch simply removes and
|
||||
re-adds the path.
|
||||
|
||||
This is patch is heavily based on the previous patch of the same name
|
||||
by Martin Wilck.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 28 ++++++----------------------
|
||||
1 file changed, 6 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 7a317d9..b3571d9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1191,7 +1191,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
int ro, retval = 0, rc;
|
||||
struct path * pp;
|
||||
struct config *conf;
|
||||
- int disable_changed_wwids;
|
||||
int needs_reinit = 0;
|
||||
|
||||
switch ((rc = change_foreign(uev->udev))) {
|
||||
@@ -1209,12 +1208,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
break;
|
||||
}
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- disable_changed_wwids = conf->disable_changed_wwids;
|
||||
- put_multipath_config(conf);
|
||||
-
|
||||
- ro = uevent_get_disk_ro(uev);
|
||||
-
|
||||
pthread_cleanup_push(cleanup_lock, &vecs->lock);
|
||||
lock(&vecs->lock);
|
||||
pthread_testcancel();
|
||||
@@ -1239,22 +1232,12 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
if (rc != 0)
|
||||
strcpy(pp->wwid, wwid);
|
||||
else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
- condlog(0, "%s: path wwid changed from '%s' to '%s'. %s",
|
||||
- uev->kernel, wwid, pp->wwid,
|
||||
- (disable_changed_wwids ? "disallowing" :
|
||||
- "continuing"));
|
||||
- strcpy(pp->wwid, wwid);
|
||||
- if (disable_changed_wwids) {
|
||||
- if (!pp->wwid_changed) {
|
||||
- pp->wwid_changed = 1;
|
||||
- pp->tick = 1;
|
||||
- if (pp->mpp)
|
||||
- dm_fail_path(pp->mpp->alias, pp->dev_t);
|
||||
- }
|
||||
- goto out;
|
||||
- }
|
||||
+ condlog(0, "%s: path wwid changed from '%s' to '%s'",
|
||||
+ uev->kernel, wwid, pp->wwid);
|
||||
+ ev_remove_path(pp, vecs, 1);
|
||||
+ needs_reinit = 1;
|
||||
+ goto out;
|
||||
} else {
|
||||
- pp->wwid_changed = 0;
|
||||
udev_device_unref(pp->udev);
|
||||
pp->udev = udev_device_ref(uev->udev);
|
||||
conf = get_multipath_config();
|
||||
@@ -1265,6 +1248,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
|
||||
+ ro = uevent_get_disk_ro(uev);
|
||||
if (mpp && ro >= 0) {
|
||||
condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro);
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 13:12:34 +0100
|
||||
Subject: [PATCH] multipathd: remove "wwid_changed" path attribute
|
||||
|
||||
This is now not needed any more.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs.h | 1 -
|
||||
multipathd/main.c | 6 ------
|
||||
2 files changed, 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index b794b0d..7879d76 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -280,7 +280,6 @@ struct path {
|
||||
int fd;
|
||||
int initialized;
|
||||
int retriggers;
|
||||
- int wwid_changed;
|
||||
unsigned int path_failures;
|
||||
time_t dis_reinstate_time;
|
||||
int disable_reinstate;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index b3571d9..e4f95a0 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2001,12 +2001,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
if (newstate == PATH_REMOVED)
|
||||
newstate = PATH_DOWN;
|
||||
|
||||
- if (pp->wwid_changed) {
|
||||
- condlog(2, "%s: path wwid has changed. Refusing to use",
|
||||
- pp->dev);
|
||||
- newstate = PATH_DOWN;
|
||||
- }
|
||||
-
|
||||
if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
|
||||
condlog(2, "%s: unusable path (%s) - checker failed",
|
||||
pp->dev, checker_state_name(newstate));
|
||||
--
|
||||
2.17.2
|
||||
|
98
SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch
Normal file
98
SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 13:12:35 +0100
|
||||
Subject: [PATCH] multipathd: ignore "disable_changed_wwids"
|
||||
|
||||
This option has no effect any more.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 1 -
|
||||
libmultipath/config.h | 1 -
|
||||
libmultipath/dict.c | 18 +++++++++++++++---
|
||||
multipath/multipath.conf.5 | 8 ++------
|
||||
4 files changed, 17 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 24d71ae..141f092 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -715,7 +715,6 @@ load_config (char * file)
|
||||
conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
|
||||
conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
|
||||
conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
|
||||
- conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS;
|
||||
conf->remove_retries = 0;
|
||||
conf->ghost_delay = DEFAULT_GHOST_DELAY;
|
||||
conf->all_tg_pt = DEFAULT_ALL_TG_PT;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index b938c26..f5bf5b1 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -182,7 +182,6 @@ struct config {
|
||||
int delayed_reconfig;
|
||||
int uev_wait_timeout;
|
||||
int skip_kpartx;
|
||||
- int disable_changed_wwids;
|
||||
int remove_retries;
|
||||
int max_sectors_kb;
|
||||
int ghost_delay;
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index eaad4f1..96815f8 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -156,6 +156,12 @@ out:
|
||||
return len;
|
||||
}
|
||||
|
||||
+static int
|
||||
+print_ignored (char *buff, int len)
|
||||
+{
|
||||
+ return snprintf(buff, len, "ignored");
|
||||
+}
|
||||
+
|
||||
static int
|
||||
print_yes_no (char *buff, int len, long v)
|
||||
{
|
||||
@@ -548,9 +554,15 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef)
|
||||
declare_hw_snprint(skip_kpartx, print_yes_no_undef)
|
||||
declare_mp_handler(skip_kpartx, set_yes_no_undef)
|
||||
declare_mp_snprint(skip_kpartx, print_yes_no_undef)
|
||||
-
|
||||
-declare_def_handler(disable_changed_wwids, set_yes_no)
|
||||
-declare_def_snprint(disable_changed_wwids, print_yes_no)
|
||||
+static int def_disable_changed_wwids_handler(struct config *conf, vector strvec)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int snprint_def_disable_changed_wwids(struct config *conf, char *buff,
|
||||
+ int len, const void *data)
|
||||
+{
|
||||
+ return print_ignored(buff, len);
|
||||
+}
|
||||
|
||||
declare_def_handler(remove_retries, set_int)
|
||||
declare_def_snprint(remove_retries, print_int)
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 864d7eb..646c156 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1148,12 +1148,8 @@ The default is: \fBno\fR
|
||||
.
|
||||
.TP
|
||||
.B disable_changed_wwids
|
||||
-If set to \fIyes\fR, multipathd will check the path wwid on change events, and
|
||||
-if it has changed from the wwid of the multipath device, multipathd will
|
||||
-disable access to the path until the wwid changes back.
|
||||
-.RS
|
||||
-.TP
|
||||
-The default is: \fBno\fR
|
||||
+This option is deprecated and ignored. If the WWID of a path suddenly changes,
|
||||
+multipathd handles it as if it was removed and then added again.
|
||||
.RE
|
||||
.
|
||||
.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 28 Mar 2019 15:17:48 -0500
|
||||
Subject: [PATCH] multipathd: Don't use fallback code after getting wwid
|
||||
|
||||
The fallback code is necessary to set up mutipath devices, if multipath
|
||||
temporarily can't get the information from udev. However, once the
|
||||
devices are set up, udev is the definitive source of this information.
|
||||
|
||||
The wwid gotten from the fallback code and the udev code should always
|
||||
be the same, in which case it doesn't matter where we get the wwid
|
||||
from. But if they are different, it's important to try to do the
|
||||
right thing.
|
||||
|
||||
Working under the assumption that udev will either never give us this
|
||||
information, or that it usually will. multipath should assume that if
|
||||
there are multiple paths to a device, either they will all never get
|
||||
a wwid from udev, or some of them will likely already have gotten the
|
||||
correct wwid from udev. In this case, we should fix this as soon as
|
||||
possible.
|
||||
|
||||
This does mean that devices where udev will never give out the uuid
|
||||
will not notice if the wwid changes, but that's a small price to pay
|
||||
for doing the right thing most of the time.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 22 +++++++++-------------
|
||||
libmultipath/discovery.h | 3 ++-
|
||||
multipathd/main.c | 2 +-
|
||||
3 files changed, 12 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 3ec60d6..744cf2c 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1763,7 +1763,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
!strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
len = get_vpd_uid(pp);
|
||||
*origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
if (len < 0 && path_state == PATH_UP) {
|
||||
condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
pp->dev, strerror(-len));
|
||||
@@ -1787,7 +1786,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
len = WWID_SIZE;
|
||||
}
|
||||
*origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@@ -1800,12 +1798,14 @@ static int has_uid_fallback(struct path *pp)
|
||||
}
|
||||
|
||||
int
|
||||
-get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
+get_uid (struct path * pp, int path_state, struct udev_device *udev,
|
||||
+ int allow_fallback)
|
||||
{
|
||||
char *c;
|
||||
const char *origin = "unknown";
|
||||
ssize_t len = 0;
|
||||
struct config *conf;
|
||||
+ int used_fallback = 0;
|
||||
|
||||
if (!pp->uid_attribute && !pp->getuid) {
|
||||
conf = get_multipath_config();
|
||||
@@ -1846,14 +1846,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0 && has_uid_fallback(pp)) {
|
||||
- int retrigger_tries;
|
||||
-
|
||||
- conf = get_multipath_config();
|
||||
- retrigger_tries = conf->retrigger_tries;
|
||||
- put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger_tries)
|
||||
- len = uid_fallback(pp, path_state, &origin);
|
||||
+ if (len <= 0 && allow_fallback && has_uid_fallback(pp)) {
|
||||
+ used_fallback = 1;
|
||||
+ len = uid_fallback(pp, path_state, &origin);
|
||||
}
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
@@ -1870,7 +1865,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
c--;
|
||||
}
|
||||
}
|
||||
- condlog(3, "%s: uid = %s (%s)", pp->dev,
|
||||
+ condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev,
|
||||
*pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
|
||||
return 0;
|
||||
}
|
||||
@@ -1994,7 +1989,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
}
|
||||
|
||||
if ((mask & DI_WWID) && !strlen(pp->wwid)) {
|
||||
- get_uid(pp, path_state, pp->udev);
|
||||
+ get_uid(pp, path_state, pp->udev,
|
||||
+ (pp->retriggers >= conf->retrigger_tries));
|
||||
if (!strlen(pp->wwid)) {
|
||||
if (pp->bus == SYSFS_BUS_UNDEF)
|
||||
return PATHINFO_SKIPPED;
|
||||
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
||||
index 9aacf75..8fd126b 100644
|
||||
--- a/libmultipath/discovery.h
|
||||
+++ b/libmultipath/discovery.h
|
||||
@@ -52,7 +52,8 @@ ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff,
|
||||
size_t len);
|
||||
int sysfs_get_asymmetric_access_state(struct path *pp,
|
||||
char *buff, int buflen);
|
||||
-int get_uid(struct path * pp, int path_state, struct udev_device *udev);
|
||||
+int get_uid(struct path * pp, int path_state, struct udev_device *udev,
|
||||
+ int allow_fallback);
|
||||
|
||||
/*
|
||||
* discovery bitmask
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index e4f95a0..1413c6d 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1227,7 +1227,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
goto out;
|
||||
|
||||
strcpy(wwid, pp->wwid);
|
||||
- rc = get_uid(pp, pp->state, uev->udev);
|
||||
+ rc = get_uid(pp, pp->state, uev->udev, 0);
|
||||
|
||||
if (rc != 0)
|
||||
strcpy(pp->wwid, wwid);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 28 Mar 2019 17:49:38 -0500
|
||||
Subject: [PATCH] libmultipath: silence dm_is_mpath error messages
|
||||
|
||||
When "multipath -F" is run, dm_is_mpath was printing error messages
|
||||
about partition devices, because they had already been removed, when
|
||||
it checked. Lower the error logging level so this doesn't happen on
|
||||
the default verbosity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 3294bd4..2e79667 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -746,7 +746,7 @@ out_task:
|
||||
dm_task_destroy(dmt);
|
||||
out:
|
||||
if (r < 0)
|
||||
- condlog(2, "%s: dm command failed in %s", name, __FUNCTION__);
|
||||
+ condlog(3, "%s: dm command failed in %s: %s", name, __FUNCTION__, strerror(errno));
|
||||
return r;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
66
SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch
Normal file
66
SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 13 Apr 2017 07:22:23 -0500
|
||||
Subject: [PATCH] RH: fixup udev rules for redhat
|
||||
|
||||
The multipath rules need to run after scsi_id is run. This means moving
|
||||
them after 60-persistent-storage.rules for redhat. Redhat also uses a
|
||||
different naming scheme for partitions than SuSE.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
kpartx/kpartx.rules | 2 +-
|
||||
multipath/Makefile | 4 ++--
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index fc728ca..2f0bcea 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -48,7 +48,7 @@ endif
|
||||
prefix =
|
||||
exec_prefix = $(prefix)
|
||||
usr_prefix = $(prefix)
|
||||
-bindir = $(exec_prefix)/sbin
|
||||
+bindir = $(exec_prefix)/usr/sbin
|
||||
libudevdir = $(prefix)/$(SYSTEMDPATH)/udev
|
||||
udevrulesdir = $(libudevdir)/rules.d
|
||||
multipathdir = $(TOPDIR)/libmultipath
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index 8f99049..8a3a171 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end"
|
||||
GOTO="kpartx_end"
|
||||
|
||||
LABEL="run_kpartx"
|
||||
-RUN+="/sbin/kpartx -un -p -part /dev/$name"
|
||||
+RUN+="/sbin/kpartx -un /dev/$name"
|
||||
|
||||
LABEL="kpartx_end"
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 0828a8f..b9bbb3c 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -24,7 +24,7 @@ install:
|
||||
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||
@@ -33,7 +33,7 @@ install:
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||
+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 2 Jul 2014 12:49:53 -0500
|
||||
Subject: [PATCH] RH: Remove the property blacklist exception builtin
|
||||
|
||||
Multipath set the default property blacklist exceptions to
|
||||
(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal
|
||||
devices. These devices may never have multiple paths, but it is nice
|
||||
to be able to set multipath up on them all the same. This patch simply
|
||||
removes the default, and makes it so that if no property
|
||||
blacklist_exception is given, then devices aren't failed for not matching
|
||||
it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 12 ++++--------
|
||||
multipath/multipath.conf.5 | 14 ++++++--------
|
||||
2 files changed, 10 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index e0d0279..556c0b9 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf)
|
||||
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
|
||||
- str = STRDUP("(SCSI_IDENT_|ID_WWN)");
|
||||
- if (!str)
|
||||
- return 1;
|
||||
- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -394,9 +388,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl)
|
||||
if (udev) {
|
||||
/*
|
||||
* This is the inverse of the 'normal' matching;
|
||||
- * the environment variable _has_ to match.
|
||||
+ * the environment variable _has_ to match
|
||||
+ * if a whitelist is present.
|
||||
*/
|
||||
- r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
+ if (VECTOR_SIZE(conf->elist_property))
|
||||
+ r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
udev_list_entry_foreach(list_entry,
|
||||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 646c156..768ab83 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1235,16 +1235,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
Regular expression for an udev property. All
|
||||
devices that have matching udev properties will be excluded/included.
|
||||
The handling of the \fIproperty\fR keyword is special,
|
||||
-because devices \fBmust\fR have at least one whitelisted udev property;
|
||||
+because if a property blacklist_exception is set, devices \fBmust\fR have at
|
||||
+least one whitelisted udev property;
|
||||
otherwise they're treated as blacklisted, and the message
|
||||
"\fIblacklisted, udev property missing\fR" is displayed in the logs.
|
||||
-.
|
||||
-.RS
|
||||
-.PP
|
||||
-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing
|
||||
-well-behaved SCSI devices and devices that provide a WWN (World Wide Number)
|
||||
-to be included, and all others to be excluded.
|
||||
-.RE
|
||||
+For example, setting the property blacklist_exception to
|
||||
+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices
|
||||
+that provide a WWN (World Wide Number) to be included, and all others to be
|
||||
+excluded. This works to exclude most non-multipathable devices.
|
||||
.TP
|
||||
.B protocol
|
||||
Regular expression for the protocol of a device to be excluded/included.
|
||||
--
|
||||
2.17.2
|
||||
|
106
SOURCES/0020-RH-don-t-start-without-a-config-file.patch
Normal file
106
SOURCES/0020-RH-don-t-start-without-a-config-file.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 15 Oct 2014 10:39:30 -0500
|
||||
Subject: [PATCH] RH: don't start without a config file
|
||||
|
||||
If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist
|
||||
all devices when running multipath. A completely blank configuration file
|
||||
is almost never what users want. Also, people may have the multipath
|
||||
packages installed but don't want to use them. This patch provides a
|
||||
simple way to disable multipath. Simply removing or renaming
|
||||
/etc/multipath.conf will keep multipath from doing anything.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 15 +++++++++++++++
|
||||
libmultipath/config.h | 1 +
|
||||
multipath/multipath.rules | 1 +
|
||||
multipathd/multipathd.8 | 2 ++
|
||||
multipathd/multipathd.service | 1 +
|
||||
5 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 141f092..544d2fb 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "devmapper.h"
|
||||
#include "mpath_cmd.h"
|
||||
#include "propsel.h"
|
||||
+#include "version.h"
|
||||
|
||||
static int
|
||||
hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2)
|
||||
@@ -745,6 +746,20 @@ load_config (char * file)
|
||||
goto out;
|
||||
}
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
+ } else {
|
||||
+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
+ if (conf->blist_devnode == NULL) {
|
||||
+ conf->blist_devnode = vector_alloc();
|
||||
+ if (!conf->blist_devnode) {
|
||||
+ condlog(0, "cannot allocate blacklist\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ if (store_ble(conf->blist_devnode, strdup(".*"),
|
||||
+ ORIGIN_NO_CONFIG)) {
|
||||
+ condlog(0, "cannot store default no-config blacklist\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
}
|
||||
|
||||
conf->processed_main_config = 1;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index f5bf5b1..8803967 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#define ORIGIN_DEFAULT 0
|
||||
#define ORIGIN_CONFIG 1
|
||||
+#define ORIGIN_NO_CONFIG 2
|
||||
|
||||
/*
|
||||
* In kernel, fast_io_fail == 0 means immediate failure on rport delete.
|
||||
diff --git a/multipath/multipath.rules b/multipath/multipath.rules
|
||||
index 9df11a9..0486bf7 100644
|
||||
--- a/multipath/multipath.rules
|
||||
+++ b/multipath/multipath.rules
|
||||
@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath"
|
||||
ENV{nompath}=="?*", GOTO="end_mpath"
|
||||
IMPORT{cmdline}="multipath"
|
||||
ENV{multipath}=="off", GOTO="end_mpath"
|
||||
+TEST!="/etc/multipath.conf", GOTO="end_mpath"
|
||||
|
||||
ENV{DEVTYPE}!="partition", GOTO="test_dev"
|
||||
IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH"
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||
index 94c3f97..ed13efd 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8
|
||||
@@ -38,6 +38,8 @@ map regains its maximum performance and redundancy.
|
||||
This daemon executes the external \fBmultipath\fR tool when events occur.
|
||||
In turn, the multipath tool signals the multipathd daemon when it is done with
|
||||
devmap reconfiguration, so that it can refresh its failed path list.
|
||||
+
|
||||
+In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists.
|
||||
.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index ba24983..17434ce 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
|
||||
After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service
|
||||
+ConditionPathExists=/etc/multipath.conf
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
ConditionKernelCommandLine=!nompath
|
||||
--
|
||||
2.17.2
|
||||
|
53
SOURCES/0021-RH-use-rpm-optflags-if-present.patch
Normal file
53
SOURCES/0021-RH-use-rpm-optflags-if-present.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 19 Apr 2017 06:10:01 -0500
|
||||
Subject: [PATCH] RH: use rpm optflags if present
|
||||
|
||||
Use the passed in optflags when compiling as an RPM, and keep the
|
||||
default flags as close as possible to the current fedora flags, while
|
||||
still being generic.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 2f0bcea..b98800a 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -83,15 +83,23 @@ TEST_CC_OPTION = $(shell \
|
||||
echo "$(2)"; \
|
||||
fi)
|
||||
|
||||
-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
-
|
||||
-OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
- -Werror=implicit-function-declaration -Werror=format-security \
|
||||
- -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \
|
||||
- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
- -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \
|
||||
- --param=ssp-buffer-size=4
|
||||
+ifndef RPM_OPT_FLAGS
|
||||
+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \
|
||||
+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
|
||||
+ $(STACKPROT) --param=ssp-buffer-size=4 \
|
||||
+ -grecord-gcc-switches
|
||||
+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1)
|
||||
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
|
||||
+ endif
|
||||
+else
|
||||
+ OPTFLAGS = $(RPM_OPT_FLAGS)
|
||||
+endif
|
||||
+OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \
|
||||
+ -Werror=implicit-function-declaration -Wno-sign-compare \
|
||||
+ -Wno-unused-parameter $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
+ -Werror=cast-qual
|
||||
|
||||
CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
-MMD -MP $(CFLAGS)
|
||||
--
|
||||
2.17.2
|
||||
|
667
SOURCES/0022-RH-add-mpathconf.patch
Normal file
667
SOURCES/0022-RH-add-mpathconf.patch
Normal file
@ -0,0 +1,667 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 Oct 2014 15:49:01 -0500
|
||||
Subject: [PATCH] RH: add mpathconf
|
||||
|
||||
mpathconf is a program (largely based on lvmcomf) to help users
|
||||
configure /etc/multipath.conf and enable or disable multipathing. It
|
||||
has a couple of built-in options that can be set directly from the
|
||||
command line. But, mostly it is used to get a multipath.conf file
|
||||
with the OS defaults, and to enable and disable multipathing via
|
||||
a single command.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 +
|
||||
multipath/Makefile | 5 +
|
||||
multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 119 +++++++++++
|
||||
4 files changed, 590 insertions(+)
|
||||
create mode 100644 multipath/mpathconf
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 544d2fb..deb80c2 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -748,6 +748,8 @@ load_config (char * file)
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
} else {
|
||||
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
+ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create");
|
||||
+ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details");
|
||||
if (conf->blist_devnode == NULL) {
|
||||
conf->blist_devnode = vector_alloc();
|
||||
if (!conf->blist_devnode) {
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index b9bbb3c..e720c7f 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS)
|
||||
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
||||
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
||||
+ $(GZIP) mpathconf.8 > mpathconf.8.gz
|
||||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
@@ -29,13 +31,16 @@ install:
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
||||
+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir)
|
||||
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
+ $(RM) $(DESTDIR)$(bindir)/mpathconf
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||
|
||||
clean: dep_clean
|
||||
$(RM) core *.o $(EXEC) *.gz
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
new file mode 100644
|
||||
index 0000000..e839134
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -0,0 +1,464 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
||||
+#
|
||||
+# This file is part of the device-mapper-multipath package.
|
||||
+#
|
||||
+# This copyrighted material is made available to anyone wishing to use,
|
||||
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||
+# of the GNU General Public License v.2.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software Foundation,
|
||||
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+
|
||||
+#
|
||||
+# Simple editting of /etc/multipath.conf
|
||||
+# This program was largely ripped off from lvmconf
|
||||
+#
|
||||
+
|
||||
+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST
|
||||
+
|
||||
+DEFAULT_CONFIG="# device-mapper-multipath configuration file
|
||||
+
|
||||
+# For a complete list of the default configuration values, run either:
|
||||
+# # multipath -t
|
||||
+# or
|
||||
+# # multipathd show config
|
||||
+
|
||||
+# For a list of configuration options with descriptions, see the
|
||||
+# multipath.conf man page.
|
||||
+
|
||||
+defaults {
|
||||
+ user_friendly_names yes
|
||||
+ find_multipaths yes
|
||||
+}
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+ property \"(SCSI_IDENT_|ID_WWN)\"
|
||||
+}"
|
||||
+
|
||||
+CONFIGFILE="/etc/multipath.conf"
|
||||
+OUTPUTFILE="/etc/multipath.conf"
|
||||
+MULTIPATHDIR="/etc/multipath"
|
||||
+TMPFILE="/etc/multipath/.multipath.conf.tmp"
|
||||
+WWIDS=0
|
||||
+
|
||||
+function usage
|
||||
+{
|
||||
+ echo "usage: $0 <command>"
|
||||
+ echo ""
|
||||
+ echo "Commands:"
|
||||
+ echo "Enable: --enable "
|
||||
+ 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 "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
+ echo "select output file (Default /etc/multipath.conf): --outfile <FILE>"
|
||||
+ echo ""
|
||||
+}
|
||||
+
|
||||
+function add_wwid
|
||||
+{
|
||||
+ INDEX=0
|
||||
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||
+ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then
|
||||
+ return
|
||||
+ fi
|
||||
+ ((INDEX++))
|
||||
+ done
|
||||
+ WWID_LIST[$WWIDS]="$1"
|
||||
+ ((WWIDS++))
|
||||
+}
|
||||
+
|
||||
+function get_dm_deps
|
||||
+{
|
||||
+ shift 3
|
||||
+ while [ -n "$1" -a -n "$2" ]; do
|
||||
+ MAJOR=$(echo $1 | tr -d '(,')
|
||||
+ MINOR=$(echo $2 | tr -d ')')
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||
+ if [ -n "$UUID" ] ; then
|
||||
+ set_dm_wwid $UUID
|
||||
+ fi
|
||||
+ shift 2
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function set_dm_wwid
|
||||
+{
|
||||
+ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then
|
||||
+ add_wwid "${1##part*-mpath-}"
|
||||
+ elif [[ "$1" =~ ^mpath- ]] ; then
|
||||
+ add_wwid "${1##mpath-}"
|
||||
+ else
|
||||
+ get_dm_deps `dmsetup deps -u $1`
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function set_wwid
|
||||
+{
|
||||
+ UUID=""
|
||||
+ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then
|
||||
+ MAJOR=${1%%:*}
|
||||
+ MINOR=${1##*:}
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||
+ else
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null`
|
||||
+ fi
|
||||
+ if [ -n "$UUID" ] ; then
|
||||
+ set_dm_wwid $UUID
|
||||
+ else
|
||||
+ add_wwid "$1"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function parse_args
|
||||
+{
|
||||
+ while [ -n "$1" ]; do
|
||||
+ case $1 in
|
||||
+ --enable)
|
||||
+ ENABLE=1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --disable)
|
||||
+ ENABLE=0
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --allow)
|
||||
+ ENABLE=2
|
||||
+ if [ -n "$2" ]; then
|
||||
+ set_wwid $2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --user_friendly_names)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FRIENDLY=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --find_multipaths)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FIND=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --with_module)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ MODULE=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --with_multipathd)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ MULTIPATHD=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --outfile)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ OUTPUTFILE=$2
|
||||
+ HAVE_OUTFILE=1
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ *)
|
||||
+ usage
|
||||
+ exit
|
||||
+ esac
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function validate_args
|
||||
+{
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then
|
||||
+ echo "ignoring extra parameters on disable"
|
||||
+ FRIENDLY=""
|
||||
+ FIND=""
|
||||
+ MODULE=""
|
||||
+ fi
|
||||
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
|
||||
+ 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'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
|
||||
+ SHOW_STATUS=1
|
||||
+ fi
|
||||
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
+ echo "--with_module must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
|
||||
+ echo "--with_multipathd must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then
|
||||
+ echo "Because --allow makes changes that cannot be automatically reversed,"
|
||||
+ echo "you must set --outfile when you set --allow"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function add_blacklist_exceptions
|
||||
+{
|
||||
+ INDEX=0
|
||||
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
|
||||
+ wwid '"\"${WWID_LIST[$INDEX]}\""'
|
||||
+' $TMPFILE
|
||||
+ ((INDEX++))
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+umask 0077
|
||||
+
|
||||
+parse_args "$@"
|
||||
+
|
||||
+validate_args
|
||||
+
|
||||
+if [ ! -d "$MULTIPATHDIR" ]; then
|
||||
+ echo "/etc/multipath/ does not exist. failing"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+rm $TMPFILE 2> /dev/null
|
||||
+echo "$DEFAULT_CONFIG" > $TMPFILE
|
||||
+if [ -f "$CONFIGFILE" ]; then
|
||||
+ cp $CONFIGFILE $TMPFILE
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_BLACKLIST=1
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_EXCEPTIONS=1
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_DEFAULTS=1
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
|
||||
+ if lsmod | grep -q "dm_multipath" ; then
|
||||
+ HAVE_MODULE=1
|
||||
+ else
|
||||
+ HAVE_MODULE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$MULTIPATHD" = "y" ]; then
|
||||
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||
+ HAVE_MULTIPATHD=1
|
||||
+ else
|
||||
+ HAVE_MULTIPATHD=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=0
|
||||
+ fi
|
||||
+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
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
|
||||
+ HAVE_FRIENDLY=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
|
||||
+ HAVE_FRIENDLY=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -n "$SHOW_STATUS" ]; then
|
||||
+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
|
||||
+ echo "multipath is enabled"
|
||||
+ else
|
||||
+ echo "multipath is disabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
|
||||
+ echo "find_multipaths is disabled"
|
||||
+ else
|
||||
+ echo "find_multipaths is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
|
||||
+ echo "user_friendly_names is disabled"
|
||||
+ else
|
||||
+ echo "user_friendly_names is enabled"
|
||||
+ fi
|
||||
+ if [ -n "$HAVE_MODULE" ]; then
|
||||
+ if [ "$HAVE_MODULE" = 1 ]; then
|
||||
+ echo "dm_multipath module is loaded"
|
||||
+ else
|
||||
+ echo "dm_multipath module is not loaded"
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_MULTIPATHD" ]; then
|
||||
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||
+ HAVE_MULTIPATHD=1
|
||||
+ else
|
||||
+ HAVE_MULTIPATHD=0
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ echo "multipathd is running"
|
||||
+ else
|
||||
+ echo "multipathd is not running"
|
||||
+ fi
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$HAVE_BLACKLIST" ]; then
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+blacklist {
|
||||
+}
|
||||
+_EOF_
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$HAVE_DEFAULTS" ]; then
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+defaults {
|
||||
+}
|
||||
+_EOF_
|
||||
+fi
|
||||
+
|
||||
+if [ "$ENABLE" = 2 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_WWID_DISABLE" ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
+ wwid ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
|
||||
+ else
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+}
|
||||
+_EOF_
|
||||
+ fi
|
||||
+ add_blacklist_exceptions
|
||||
+elif [ "$ENABLE" = 1 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+elif [ "$ENABLE" = 0 ]; then
|
||||
+ if [ -z "$HAVE_DISABLE" ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
+ devnode ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
+ 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 [ -z "$HAVE_FIND" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ find_multipaths yes
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FIND" = 0 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FRIENDLY" = "n" ]; then
|
||||
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FRIENDLY" = "y" ]; then
|
||||
+ if [ -z "$HAVE_FRIENDLY" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ user_friendly_names yes
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FRIENDLY" = 0 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -f "$OUTPUTFILE" ]; then
|
||||
+ cp $OUTPUTFILE $OUTPUTFILE.old
|
||||
+ if [ $? != 0 ]; then
|
||||
+ echo "failed to backup old config file, $OUTPUTFILE not updated"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+cp $TMPFILE $OUTPUTFILE
|
||||
+if [ $? != 0 ]; then
|
||||
+ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+rm -f $TMPFILE
|
||||
+
|
||||
+if [ "$ENABLE" = 1 ]; then
|
||||
+ if [ "$HAVE_MODULE" = 0 ]; then
|
||||
+ modprobe dm_multipath
|
||||
+ fi
|
||||
+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
|
||||
+ systemctl start multipathd.service
|
||||
+ fi
|
||||
+elif [ "$ENABLE" = 0 ]; then
|
||||
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ systemctl stop multipathd.service
|
||||
+ fi
|
||||
+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ systemctl reload multipathd.service
|
||||
+fi
|
||||
diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8
|
||||
new file mode 100644
|
||||
index 0000000..5b7ae0c
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf.8
|
||||
@@ -0,0 +1,119 @@
|
||||
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
|
||||
+.SH NAME
|
||||
+mpathconf - A tool for configuring device-mapper-multipath
|
||||
+.SH SYNOPSIS
|
||||
+.B mpathconf
|
||||
+.RB [\| commands \|]
|
||||
+.RB [\| options \|]
|
||||
+.SH DESCRIPTION
|
||||
+.B mpathconf
|
||||
+is a utility that creates or modifies
|
||||
+.B /etc/multipath.conf.
|
||||
+It can enable or disable multipathing and configure some common options.
|
||||
+.B mpathconf
|
||||
+can also load the
|
||||
+.B dm_multipath
|
||||
+module, start and stop the
|
||||
+.B multipathd
|
||||
+daemon, and configure the
|
||||
+.B multipathd
|
||||
+service to start automatically or not. If
|
||||
+.B mpathconf
|
||||
+is called with no commands, it will display the current configuration, but
|
||||
+will not create of modify
|
||||
+.B /etc/multipath.conf
|
||||
+
|
||||
+The default options for mpathconf are
|
||||
+.B --with_module
|
||||
+The
|
||||
+.B --with_multipathd
|
||||
+option is not set by default. Enabling multipathing will load the
|
||||
+.B dm_multipath
|
||||
+module but it will not immediately start it. This is so
|
||||
+that users can manually edit their config file if necessary, before starting
|
||||
+.B multipathd.
|
||||
+
|
||||
+If
|
||||
+.B /etc/multipath.conf
|
||||
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
|
||||
+create a default file with
|
||||
+.B user_friendly_names
|
||||
+and
|
||||
+.B find_multipaths
|
||||
+set. To disable these, use the
|
||||
+.B --user_friendly_names n
|
||||
+and
|
||||
+.B --find_multipaths n
|
||||
+options
|
||||
+.SH COMMANDS
|
||||
+.TP
|
||||
+.B --enable
|
||||
+Removes any line that blacklists all device nodes from the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist section. Also, creates
|
||||
+.B /etc/multipath.conf
|
||||
+if it doesn't exist.
|
||||
+.TP
|
||||
+.B --disable
|
||||
+Adds a line that blacklists all device nodes to the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist section. If no blacklist section exists, it will create one.
|
||||
+.TP
|
||||
+.B --allow \fB<device>\fP
|
||||
+Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all
|
||||
+wwids and the blacklist_exceptions to whitelist \fB<device>\fP. \fB<device>\fP
|
||||
+can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper
|
||||
+device, either a multipath device, or any device on stacked on top of one or
|
||||
+more multipath devices. This command can be used multiple times to allow
|
||||
+multiple devices. \fBNOTE:\fP This action will create a configuration file that
|
||||
+mpathconf will not be able to revert back to its previous state. Because
|
||||
+of this, \fB--outfile\fP is required when using \fB--allow\fP.
|
||||
+.TP
|
||||
+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B user_friendly_names yes
|
||||
+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.
|
||||
+.TP
|
||||
+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B find_multipaths yes
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. If set to \fBn\fP, this removes the line, if present. This
|
||||
+command can be used aldong with any other command.
|
||||
+.TP
|
||||
+.B --outfile \fB<filename>\fP
|
||||
+Write the resulting multipath configuration to \fB<filename>\fP instead of
|
||||
+\fB/etc/multipath.conf\fP.
|
||||
+.SH OPTIONS
|
||||
+.TP
|
||||
+.B --with_module\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this runs
|
||||
+.B modprobe dm_multipath
|
||||
+to install the multipath modules. This option only works with the
|
||||
+.B --enable
|
||||
+command. This option is set to \fBy\fP by default.
|
||||
+.TP
|
||||
+.B --with_multipathd { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this runs
|
||||
+.B service multipathd start
|
||||
+to start the multipathd daemon on \fB--enable\fP,
|
||||
+.B service multipathd stop
|
||||
+to stop the multipathd daemon on \fB--disable\fP, and
|
||||
+.B service multipathd reload
|
||||
+to reconfigure multipathd on \fB--user_frindly_names\fP and
|
||||
+\fB--find_multipaths\fP.
|
||||
+This option is set to \fBn\fP by default.
|
||||
+.SH FILES
|
||||
+.BR /etc/multipath.conf
|
||||
+.SH "SEE ALSO"
|
||||
+.BR multipath.conf (5),
|
||||
+.BR modprobe (8),
|
||||
+.BR multipath (8),
|
||||
+.BR multipathd (8),
|
||||
+.BR service (8),
|
||||
+.SH AUTHOR
|
||||
+Benjamin Marzinski <bmarzins@redhat.com>
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,169 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 17 Oct 2014 11:20:34 -0500
|
||||
Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A
|
||||
|
||||
This patch adds another option to multipath, "-A", which reads
|
||||
/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
|
||||
to /etc/multipath/wwids. While this isn't usually important during
|
||||
normal operation, since these wwids should already be added, it can be
|
||||
helpful during installation, to make sure that multipath can claim
|
||||
devices as its own, before LVM or something else makes use of them. The
|
||||
patch also execs "/sbin/multipath -A" before running multipathd in
|
||||
multipathd.service
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++
|
||||
libmultipath/wwids.h | 1 +
|
||||
multipath/main.c | 10 ++++++--
|
||||
multipath/multipath.8 | 7 +++++-
|
||||
multipathd/multipathd.service | 1 +
|
||||
5 files changed, 60 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 53e7951..39e08cd 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -443,3 +443,47 @@ int op ## _wwid(const char *wwid) \
|
||||
declare_failed_wwid_op(is_failed, false)
|
||||
declare_failed_wwid_op(mark_failed, true)
|
||||
declare_failed_wwid_op(unmark_failed, true)
|
||||
+
|
||||
+int remember_cmdline_wwid(void)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ char buf[LINE_MAX], *next, *ptr;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ f = fopen("/proc/cmdline", "re");
|
||||
+ if (!f) {
|
||||
+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(0, "read of /proc/cmdline failed : %s",
|
||||
+ strerror(errno));
|
||||
+ else
|
||||
+ condlog(0, "couldn't read /proc/cmdline");
|
||||
+ fclose(f);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ next = buf;
|
||||
+ while((ptr = strstr(next, "mpath.wwid="))) {
|
||||
+ ptr += 11;
|
||||
+ next = strpbrk(ptr, " \t\n");
|
||||
+ if (next) {
|
||||
+ *next = '\0';
|
||||
+ next++;
|
||||
+ }
|
||||
+ if (strlen(ptr)) {
|
||||
+ if (remember_wwid(ptr) != 0)
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+ else {
|
||||
+ condlog(0, "empty mpath.wwid kernel command line option");
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+ if (!next)
|
||||
+ break;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
|
||||
index 0c6ee54..e32a0b0 100644
|
||||
--- a/libmultipath/wwids.h
|
||||
+++ b/libmultipath/wwids.h
|
||||
@@ -17,6 +17,7 @@ int remember_wwid(char *wwid);
|
||||
int check_wwids_file(char *wwid, int write_wwid);
|
||||
int remove_wwid(char *wwid);
|
||||
int replace_wwids(vector mp);
|
||||
+int remember_cmdline_wwid(void);
|
||||
|
||||
enum {
|
||||
WWID_IS_NOT_FAILED = 0,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 69141db..e7771c0 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -133,7 +133,7 @@ usage (char * progname)
|
||||
{
|
||||
fprintf (stderr, VERSION_STRING);
|
||||
fprintf (stderr, "Usage:\n");
|
||||
- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
|
||||
+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
|
||||
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname);
|
||||
fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname);
|
||||
fprintf (stderr, " %s [-t|-T]\n", progname);
|
||||
@@ -147,6 +147,8 @@ usage (char * progname)
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
+ " -A add devices from kernel command line mpath.wwids\n"
|
||||
+ " parameters to wwids file\n"
|
||||
" -c check if a device should be a path in a multipath device\n"
|
||||
" -C check if a multipath device has usable paths\n"
|
||||
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||
@@ -870,7 +872,7 @@ main (int argc, char *argv[])
|
||||
exit(RTVL_FAIL);
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -940,6 +942,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
+ case 'A':
|
||||
+ if (remember_cmdline_wwid() != 0)
|
||||
+ exit(RTVL_FAIL);
|
||||
+ exit(RTVL_OK);
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 9cdd05a..8befc45 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
||||
.B multipath
|
||||
.RB [\| \-v\ \c
|
||||
.IR level \|]
|
||||
-.B -W
|
||||
+.RB [\| \-A | \-W \|]
|
||||
.
|
||||
.LP
|
||||
.B multipath
|
||||
@@ -145,6 +145,11 @@ device mapper, path checkers ...).
|
||||
Add the WWID for the specified device to the WWIDs file.
|
||||
.
|
||||
.TP
|
||||
+.B \-A
|
||||
+Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the
|
||||
+WWIDs file.
|
||||
+.
|
||||
+.TP
|
||||
.B \-w
|
||||
Remove the WWID for the specified device from the WWIDs file.
|
||||
.
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index 17434ce..0fbcc46 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -15,6 +15,7 @@ Type=notify
|
||||
NotifyAccess=main
|
||||
LimitCORE=infinity
|
||||
ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
|
||||
+ExecStartPre=-/sbin/multipath -A
|
||||
ExecStart=/sbin/multipathd -d -s
|
||||
ExecReload=/sbin/multipathd reconfigure
|
||||
TasksMax=infinity
|
||||
--
|
||||
2.17.2
|
||||
|
121
SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch
Normal file
121
SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 6 Nov 2017 21:39:28 -0600
|
||||
Subject: [PATCH] RH: warn on invalid regex instead of failing
|
||||
|
||||
multipath.conf used to allow "*" as a match everything regular expression,
|
||||
instead of requiring ".*". Instead of erroring when the old style
|
||||
regular expressions are used, it should print a warning and convert
|
||||
them.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 27 +++++++++++++++++++++------
|
||||
libmultipath/parser.c | 13 +++++++++++++
|
||||
libmultipath/parser.h | 1 +
|
||||
3 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 96815f8..3b1b652 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+set_regex(vector strvec, void *ptr)
|
||||
+{
|
||||
+ char **str_ptr = (char **)ptr;
|
||||
+
|
||||
+ if (*str_ptr)
|
||||
+ FREE(*str_ptr);
|
||||
+ *str_ptr = set_regex_value(strvec);
|
||||
+
|
||||
+ if (!*str_ptr)
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
set_yes_no(vector strvec, void *ptr)
|
||||
{
|
||||
@@ -1386,7 +1401,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
- buff = set_value(strvec); \
|
||||
+ buff = set_regex_value(strvec); \
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1402,7 +1417,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
- buff = set_value(strvec); \
|
||||
+ buff = set_regex_value(strvec); \
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1505,16 +1520,16 @@ device_handler(struct config *conf, vector strvec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-declare_hw_handler(vendor, set_str)
|
||||
+declare_hw_handler(vendor, set_regex)
|
||||
declare_hw_snprint(vendor, print_str)
|
||||
|
||||
-declare_hw_handler(product, set_str)
|
||||
+declare_hw_handler(product, set_regex)
|
||||
declare_hw_snprint(product, print_str)
|
||||
|
||||
-declare_hw_handler(revision, set_str)
|
||||
+declare_hw_handler(revision, set_regex)
|
||||
declare_hw_snprint(revision, print_str)
|
||||
|
||||
-declare_hw_handler(bl_product, set_str)
|
||||
+declare_hw_handler(bl_product, set_regex)
|
||||
declare_hw_snprint(bl_product, print_str)
|
||||
|
||||
declare_hw_handler(hwhandler, set_str)
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index 92ef7cf..4289336 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -384,6 +384,19 @@ set_value(vector strvec)
|
||||
return alloc;
|
||||
}
|
||||
|
||||
+void *
|
||||
+set_regex_value(vector strvec)
|
||||
+{
|
||||
+ char *buff = set_value(strvec);
|
||||
+
|
||||
+ if (buff && strcmp("*", buff) == 0) {
|
||||
+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\"");
|
||||
+ FREE(buff);
|
||||
+ return strdup(".*");
|
||||
+ }
|
||||
+ return buff;
|
||||
+}
|
||||
+
|
||||
/* non-recursive configuration stream handler */
|
||||
static int kw_level = 0;
|
||||
|
||||
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
|
||||
index 62906e9..b791705 100644
|
||||
--- a/libmultipath/parser.h
|
||||
+++ b/libmultipath/parser.h
|
||||
@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level);
|
||||
extern void free_keywords(vector keywords);
|
||||
extern vector alloc_strvec(char *string);
|
||||
extern void *set_value(vector strvec);
|
||||
+extern void *set_regex_value(vector strvec);
|
||||
extern int process_file(struct config *conf, char *conf_file);
|
||||
extern struct keyword * find_keyword(vector keywords, vector v, char * name);
|
||||
int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 7 Jun 2018 17:43:52 -0500
|
||||
Subject: [PATCH] RH: reset default find_mutipaths value to off
|
||||
|
||||
Upstream has changed to default find_multipaths to "strict". For now
|
||||
Redhat will retain the previous default of "off".
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/defaults.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index 6576939..2ad6308 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -17,7 +17,7 @@
|
||||
#define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF
|
||||
#define DEFAULT_VERBOSITY 2
|
||||
#define DEFAULT_REASSIGN_MAPS 0
|
||||
-#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT
|
||||
+#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF
|
||||
#define DEFAULT_FAST_IO_FAIL 5
|
||||
#define DEFAULT_DEV_LOSS_TMO 600
|
||||
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON
|
||||
--
|
||||
2.17.2
|
||||
|
26
SOURCES/0026-RH-Fix-nvme-compilation-warning.patch
Normal file
26
SOURCES/0026-RH-Fix-nvme-compilation-warning.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 14:54:56 -0600
|
||||
Subject: [PATCH] RH: Fix nvme compilation warning
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/nvme/argconfig.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h
|
||||
index adb192b..bfd10ef 100644
|
||||
--- a/libmultipath/nvme/argconfig.h
|
||||
+++ b/libmultipath/nvme/argconfig.h
|
||||
@@ -76,7 +76,7 @@ struct argconfig_commandline_options {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-typedef void argconfig_help_func();
|
||||
+typedef void argconfig_help_func(void);
|
||||
void argconfig_append_usage(const char *str);
|
||||
void argconfig_print_help(const char *program_desc,
|
||||
const struct argconfig_commandline_options *options);
|
||||
--
|
||||
2.17.2
|
||||
|
27
SOURCES/0027-Fix-systemd-version-detection.patch
Normal file
27
SOURCES/0027-Fix-systemd-version-detection.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
|
||||
Date: Tue, 26 Mar 2019 16:34:32 -0500
|
||||
Subject: [PATCH] Fix systemd version detection
|
||||
|
||||
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index b98800a..da49852 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -37,7 +37,7 @@ endif
|
||||
|
||||
ifndef SYSTEMD
|
||||
ifeq ($(shell systemctl --version > /dev/null 2>&1 && echo 1), 1)
|
||||
- SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\)/\1/p')
|
||||
+ SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p')
|
||||
endif
|
||||
endif
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 11 Apr 2019 13:25:42 -0500
|
||||
Subject: [PATCH] RH: attempt to get ANA info via sysfs first
|
||||
|
||||
When the ANA prioritizer is run, first see if the "ana_state" sysfs file
|
||||
exists, and if it does, try to read the state from there. If that fails,
|
||||
fallback to using an ioctl.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c
|
||||
index 990d935..d84571b 100644
|
||||
--- a/libmultipath/prioritizers/ana.c
|
||||
+++ b/libmultipath/prioritizers/ana.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "prio.h"
|
||||
#include "util.h"
|
||||
#include "structs.h"
|
||||
+#include "sysfs.h"
|
||||
|
||||
enum {
|
||||
ANA_ERR_GETCTRL_FAILED = 1,
|
||||
@@ -36,6 +37,7 @@ enum {
|
||||
ANA_ERR_GETNS_FAILED,
|
||||
ANA_ERR_NO_MEMORY,
|
||||
ANA_ERR_NO_INFORMATION,
|
||||
+ ANA_ERR_INVALID_STATE,
|
||||
};
|
||||
|
||||
static const char *ana_errmsg[] = {
|
||||
@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = {
|
||||
[ANA_ERR_GETNS_FAILED] = "couldn't get namespace info",
|
||||
[ANA_ERR_NO_MEMORY] = "out of memory",
|
||||
[ANA_ERR_NO_INFORMATION] = "invalid fd",
|
||||
+ [ANA_ERR_INVALID_STATE] = "invalid state",
|
||||
};
|
||||
|
||||
static const char *anas_string[] = {
|
||||
@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log,
|
||||
return -ANA_ERR_GETANAS_NOTFOUND;
|
||||
}
|
||||
|
||||
+int get_ana_info_sysfs(struct path *pp)
|
||||
+{
|
||||
+ char state[32];
|
||||
+
|
||||
+ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state,
|
||||
+ sizeof(state)) <= 0)
|
||||
+ return -ANA_ERR_NO_INFORMATION;
|
||||
+
|
||||
+ if (strcmp(state, "optimized") == 0)
|
||||
+ return NVME_ANA_OPTIMIZED;
|
||||
+ if (strcmp(state, "non-optimized") == 0)
|
||||
+ return NVME_ANA_NONOPTIMIZED;
|
||||
+ if (strcmp(state, "inaccessible") == 0)
|
||||
+ return NVME_ANA_INACCESSIBLE;
|
||||
+ if (strcmp(state, "persistent-loss") == 0)
|
||||
+ return NVME_ANA_PERSISTENT_LOSS;
|
||||
+ if (strcmp(state, "change") == 0)
|
||||
+ return NVME_ANA_CHANGE;
|
||||
+ return -ANA_ERR_INVALID_STATE;
|
||||
+}
|
||||
+
|
||||
int get_ana_info(struct path * pp, unsigned int timeout)
|
||||
{
|
||||
int rc;
|
||||
@@ -208,8 +232,11 @@ int getprio(struct path *pp, char *args, unsigned int timeout)
|
||||
|
||||
if (pp->fd < 0)
|
||||
rc = -ANA_ERR_NO_INFORMATION;
|
||||
- else
|
||||
- rc = get_ana_info(pp, timeout);
|
||||
+ else {
|
||||
+ rc = get_ana_info_sysfs(pp);
|
||||
+ if (rc < 0)
|
||||
+ rc = get_ana_info(pp, timeout);
|
||||
+ }
|
||||
|
||||
switch (rc) {
|
||||
case NVME_ANA_OPTIMIZED:
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,118 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 18 Apr 2019 12:49:46 -0500
|
||||
Subject: [PATCH] BZ 1700451: check on multipathd without starting it
|
||||
|
||||
When "multipath -u" is run, it checks if multipathd is running.
|
||||
Currently it does this by trying to connect to the mutipathd socket.
|
||||
This can cause problems during boot. The multipathd.socket systemd unit
|
||||
file will cause "multipath -u" to wait until multipathd has been started
|
||||
before continuing. If there is a lot of activity on the system,
|
||||
multipathd may not start up immediately, causing block device
|
||||
initialization to be delayed, potentially until after systemd times
|
||||
waiting for the device. To avoid this, multipath now checks if
|
||||
multipathd is running by reading /run/multipathd.pid and checking the
|
||||
/proc/<pid>/comm to verify that multipathd is really running with this
|
||||
pid. This avoids forcing "multipath -u" to wait on multipathd starting
|
||||
up.
|
||||
|
||||
As an alternative to this patch, multipath could simply switch the order
|
||||
of the calls to systemd_service_enabled() and mpath_connect(). This would
|
||||
make multipath only try to connect with multipathd if it wasn't enabled in
|
||||
systemd, so that it wouldn't autostart.
|
||||
|
||||
Another alternative is to do away with multipathd.socket. Since multipathd
|
||||
needs to always be running in order to get uevents, there isn't much value
|
||||
in having it autoactivate when it gets an interactive command.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 54 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index e7771c0..632ce4d 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -852,6 +852,58 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
+int is_multipathd_running(void)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ char buf[16];
|
||||
+ char path[PATH_MAX];
|
||||
+ int pid;
|
||||
+ char *end;
|
||||
+
|
||||
+ f = fopen(DEFAULT_PIDFILE, "r");
|
||||
+ if (!f) {
|
||||
+ if (errno != ENOENT)
|
||||
+ condlog(4, "can't open " DEFAULT_PIDFILE ": %s",
|
||||
+ strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(4, "read of " DEFAULT_PIDFILE " failed: %s",
|
||||
+ strerror(errno));
|
||||
+ fclose(f);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ errno = 0;
|
||||
+ strchop(buf);
|
||||
+ pid = strtol(buf, &end, 10);
|
||||
+ if (errno != 0 || pid <= 0 || *end != '\0') {
|
||||
+ condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'",
|
||||
+ buf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ snprintf(path, sizeof(path), "/proc/%d/comm", pid);
|
||||
+ f = fopen(path, "r");
|
||||
+ if (!f) {
|
||||
+ if (errno != ENOENT)
|
||||
+ condlog(4, "can't open %s: %s", path, strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(4, "read of %s failed: %s", path,
|
||||
+ strerror(errno));
|
||||
+ fclose(f);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ strchop(buf);
|
||||
+ if (strcmp(buf, "multipathd") != 0)
|
||||
+ return 0;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -1034,17 +1086,13 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (cmd == CMD_VALID_PATH &&
|
||||
dev_type == DEV_UEVENT) {
|
||||
- int fd;
|
||||
-
|
||||
- fd = mpath_connect();
|
||||
- if (fd == -1) {
|
||||
+ if (!is_multipathd_running()) {
|
||||
condlog(3, "%s: daemon is not running", dev);
|
||||
if (!systemd_service_enabled(dev)) {
|
||||
r = print_cmd_valid(RTVL_NO, NULL, conf);
|
||||
goto out;
|
||||
}
|
||||
- } else
|
||||
- mpath_disconnect(fd);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (cmd == CMD_REMOVE_WWID && !dev) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,223 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 24 Apr 2019 11:07:59 +0200
|
||||
Subject: [PATCH] BZ 1700451: test socket connection in non-blocking mode
|
||||
|
||||
Since commit d7188fcd "multipathd: start daemon after udev trigger",
|
||||
multipathd startup is delayed during boot until after "udev settle"
|
||||
terminates. But "multipath -u" is run by udev workers for storage devices,
|
||||
and attempts to connect to the multipathd socket. This causes a start job
|
||||
for multipathd to be scheduled by systemd, but that job won't be started
|
||||
until "udev settle" finishes. This is not a problem on systems with 129 or
|
||||
less storage units, because the connect() call of "multipath -u" will
|
||||
succeed anyway. But on larger systems, the listen backlog of the systemd
|
||||
socket can be exceeded, which causes connect() calls for the socket to
|
||||
block until multipathd starts up and begins calling accept(). This creates
|
||||
a deadlock situation, because "multipath -u" (called by udev workers)
|
||||
blocks, and thus "udev settle" doesn't finish, delaying multipathd
|
||||
startup. This situation then persists until either the workers or "udev
|
||||
settle" time out. In the former case, path devices might be misclassified
|
||||
as non-multipath devices by "multipath -u".
|
||||
|
||||
Fix this by using a non-blocking socket fd for connect() and interpret the
|
||||
errno appropriately.
|
||||
|
||||
This patch reverts most of the changes from commit 8cdf6661 "multipath:
|
||||
check on multipathd without starting it". Instead, "multipath -u" does
|
||||
access the socket and start multipath again (which is what we want IMO),
|
||||
but it is now able to detect and handle the "full backlog" situation.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
|
||||
V2:
|
||||
|
||||
Use same error reporting convention in __mpath_connect() as in
|
||||
mpath_connect() (Hannes Reinecke). We can't easily change the latter,
|
||||
because it's part of the "public" libmpathcmd API.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathcmd/mpath_cmd.c | 24 +++++++++++++-
|
||||
libmpathcmd/mpath_cmd.h | 15 +++++++++
|
||||
multipath/main.c | 70 +++++++++++++----------------------------
|
||||
3 files changed, 60 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
|
||||
index df4ca54..b681311 100644
|
||||
--- a/libmpathcmd/mpath_cmd.c
|
||||
+++ b/libmpathcmd/mpath_cmd.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include "mpath_cmd.h"
|
||||
|
||||
@@ -93,10 +94,11 @@ static size_t write_all(int fd, const void *buf, size_t len)
|
||||
/*
|
||||
* connect to a unix domain socket
|
||||
*/
|
||||
-int mpath_connect(void)
|
||||
+int __mpath_connect(int nonblocking)
|
||||
{
|
||||
int fd, len;
|
||||
struct sockaddr_un addr;
|
||||
+ int flags = 0;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_LOCAL;
|
||||
@@ -108,14 +110,34 @@ int mpath_connect(void)
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
+ if (nonblocking) {
|
||||
+ flags = fcntl(fd, F_GETFL, 0);
|
||||
+ if (flags != -1)
|
||||
+ (void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
|
||||
+ }
|
||||
+
|
||||
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
|
||||
+ int err = errno;
|
||||
+
|
||||
close(fd);
|
||||
+ errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ if (nonblocking && flags != -1)
|
||||
+ (void)fcntl(fd, F_SETFL, flags);
|
||||
+
|
||||
return fd;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * connect to a unix domain socket
|
||||
+ */
|
||||
+int mpath_connect(void)
|
||||
+{
|
||||
+ return __mpath_connect(0);
|
||||
+}
|
||||
+
|
||||
int mpath_disconnect(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h
|
||||
index 15aeb06..ccfd35f 100644
|
||||
--- a/libmpathcmd/mpath_cmd.h
|
||||
+++ b/libmpathcmd/mpath_cmd.h
|
||||
@@ -34,6 +34,21 @@ extern "C" {
|
||||
#define DEFAULT_REPLY_TIMEOUT 4000
|
||||
|
||||
|
||||
+/*
|
||||
+ * DESCRIPTION:
|
||||
+ * Same as mpath_connect() (see below) except for the "nonblocking"
|
||||
+ * parameter.
|
||||
+ * If "nonblocking" is set, connects in non-blocking mode. This is
|
||||
+ * useful to avoid blocking if the listening socket's backlog is
|
||||
+ * exceeded. In this case, errno will be set to EAGAIN.
|
||||
+ * In case of success, the returned file descriptor is in in blocking
|
||||
+ * mode, even if "nonblocking" was true.
|
||||
+ *
|
||||
+ * RETURNS:
|
||||
+ * A file descriptor on success. -1 on failure (with errno set).
|
||||
+ */
|
||||
+int __mpath_connect(int nonblocking);
|
||||
+
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
* Connect to the running multipathd daemon. On systems with the
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 632ce4d..3fb6699 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -852,55 +852,29 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
-int is_multipathd_running(void)
|
||||
+static int test_multipathd_socket(void)
|
||||
{
|
||||
- FILE *f = NULL;
|
||||
- char buf[16];
|
||||
- char path[PATH_MAX];
|
||||
- int pid;
|
||||
- char *end;
|
||||
+ int fd;
|
||||
+ /*
|
||||
+ * "multipath -u" may be run before the daemon is started. In this
|
||||
+ * case, systemd might own the socket but might delay multipathd
|
||||
+ * startup until some other unit (udev settle!) has finished
|
||||
+ * starting. With many LUNs, the listen backlog may be exceeded, which
|
||||
+ * would cause connect() to block. This causes udev workers calling
|
||||
+ * "multipath -u" to hang, and thus creates a deadlock, until "udev
|
||||
+ * settle" times out. To avoid this, call connect() in non-blocking
|
||||
+ * mode here, and take EAGAIN as indication for a filled-up systemd
|
||||
+ * backlog.
|
||||
+ */
|
||||
|
||||
- f = fopen(DEFAULT_PIDFILE, "r");
|
||||
- if (!f) {
|
||||
- if (errno != ENOENT)
|
||||
- condlog(4, "can't open " DEFAULT_PIDFILE ": %s",
|
||||
- strerror(errno));
|
||||
- return 0;
|
||||
- }
|
||||
- if (!fgets(buf, sizeof(buf), f)) {
|
||||
- if (ferror(f))
|
||||
- condlog(4, "read of " DEFAULT_PIDFILE " failed: %s",
|
||||
- strerror(errno));
|
||||
- fclose(f);
|
||||
- return 0;
|
||||
- }
|
||||
- fclose(f);
|
||||
- errno = 0;
|
||||
- strchop(buf);
|
||||
- pid = strtol(buf, &end, 10);
|
||||
- if (errno != 0 || pid <= 0 || *end != '\0') {
|
||||
- condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'",
|
||||
- buf);
|
||||
- return 0;
|
||||
- }
|
||||
- snprintf(path, sizeof(path), "/proc/%d/comm", pid);
|
||||
- f = fopen(path, "r");
|
||||
- if (!f) {
|
||||
- if (errno != ENOENT)
|
||||
- condlog(4, "can't open %s: %s", path, strerror(errno));
|
||||
- return 0;
|
||||
- }
|
||||
- if (!fgets(buf, sizeof(buf), f)) {
|
||||
- if (ferror(f))
|
||||
- condlog(4, "read of %s failed: %s", path,
|
||||
- strerror(errno));
|
||||
- fclose(f);
|
||||
- return 0;
|
||||
- }
|
||||
- fclose(f);
|
||||
- strchop(buf);
|
||||
- if (strcmp(buf, "multipathd") != 0)
|
||||
- return 0;
|
||||
+ fd = __mpath_connect(1);
|
||||
+ if (fd == -1) {
|
||||
+ if (errno == EAGAIN)
|
||||
+ condlog(3, "daemon backlog exceeded");
|
||||
+ else
|
||||
+ return 0;
|
||||
+ } else
|
||||
+ close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1060,7 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (cmd == CMD_VALID_PATH &&
|
||||
dev_type == DEV_UEVENT) {
|
||||
- if (!is_multipathd_running()) {
|
||||
+ if (!test_multipathd_socket()) {
|
||||
condlog(3, "%s: daemon is not running", dev);
|
||||
if (!systemd_service_enabled(dev)) {
|
||||
r = print_cmd_valid(RTVL_NO, NULL, conf);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 12:41:33 -0500
|
||||
Subject: [PATCH] libmultipath: handle clock_gettime failures in tur checker
|
||||
|
||||
If clock_gettime() fails, and multipathd can't figure out when it should
|
||||
time out, it should just default to assuming that it has already timed
|
||||
out. Found by coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/checkers/tur.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
||||
index 6b08dbb..717353e 100644
|
||||
--- a/libmultipath/checkers/tur.c
|
||||
+++ b/libmultipath/checkers/tur.c
|
||||
@@ -290,7 +290,12 @@ static void *tur_thread(void *ctx)
|
||||
|
||||
static void tur_timeout(struct timespec *tsp)
|
||||
{
|
||||
- clock_gettime(CLOCK_MONOTONIC, tsp);
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, tsp) != 0) {
|
||||
+ /* can't get time. clear tsp to not wait */
|
||||
+ tsp->tv_sec = 0;
|
||||
+ tsp->tv_nsec = 0;
|
||||
+ return;
|
||||
+ }
|
||||
tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
|
||||
normalize_timespec(tsp);
|
||||
}
|
||||
@@ -300,8 +305,12 @@ static void tur_set_async_timeout(struct checker *c)
|
||||
struct tur_checker_context *ct = c->context;
|
||||
struct timespec now;
|
||||
|
||||
- clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
- ct->time = now.tv_sec + c->timeout;
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
|
||||
+ /* can't get time. clear time to always timeout on
|
||||
+ * next path check */
|
||||
+ ct->time = 0;
|
||||
+ else
|
||||
+ ct->time = now.tv_sec + c->timeout;
|
||||
}
|
||||
|
||||
static int tur_check_async_timeout(struct checker *c)
|
||||
@@ -309,7 +318,9 @@ static int tur_check_async_timeout(struct checker *c)
|
||||
struct tur_checker_context *ct = c->context;
|
||||
struct timespec now;
|
||||
|
||||
- clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
|
||||
+ /* can't get time. assume we've timed out */
|
||||
+ return 1;
|
||||
return (now.tv_sec > ct->time);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 12:55:16 -0500
|
||||
Subject: [PATCH] kpartx: fail if dup() of dasd file descriptor fails
|
||||
|
||||
If kpartx fails to create a copy of the dasd file descriptor, it should
|
||||
fail, instead of treating the error value as a valid fd. Found by
|
||||
coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/dasd.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/kpartx/dasd.c b/kpartx/dasd.c
|
||||
index 61b609a..d95d8ca 100644
|
||||
--- a/kpartx/dasd.c
|
||||
+++ b/kpartx/dasd.c
|
||||
@@ -138,6 +138,8 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
|
||||
return -1;
|
||||
} else {
|
||||
fd_dasd = dup(fd);
|
||||
+ if (fd_dasd < 0)
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 13:31:35 -0500
|
||||
Subject: [PATCH] multipathd: fix REALLOC_REPLY with max length reply
|
||||
|
||||
Commit cd5a9797e added code to REALLOC_REPLY() that intended to stop
|
||||
growing the reply buffer after it reached a maximum size. However this
|
||||
coded didn't stop the realloc() from happening. Worse, if the realloci()
|
||||
failed, multipathd would double free the reply buffer. Found by
|
||||
Coverity.
|
||||
|
||||
Fixes: cd5a9797e "libmpathcmd(coverity): limit reply length"
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli.h | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli.h b/multipathd/cli.h
|
||||
index f3fa077..32dcffa 100644
|
||||
--- a/multipathd/cli.h
|
||||
+++ b/multipathd/cli.h
|
||||
@@ -100,15 +100,16 @@ enum {
|
||||
if (m >= MAX_REPLY_LEN) { \
|
||||
condlog(1, "Warning: max reply length exceeded"); \
|
||||
free(tmp); \
|
||||
- r = NULL; \
|
||||
+ (r) = NULL; \
|
||||
+ } else { \
|
||||
+ (r) = REALLOC((r), (m) * 2); \
|
||||
+ if ((r)) { \
|
||||
+ memset((r) + (m), 0, (m)); \
|
||||
+ (m) *= 2; \
|
||||
+ } \
|
||||
+ else \
|
||||
+ free(tmp); \
|
||||
} \
|
||||
- (r) = REALLOC((r), (m) * 2); \
|
||||
- if ((r)) { \
|
||||
- memset((r) + (m), 0, (m)); \
|
||||
- (m) *= 2; \
|
||||
- } \
|
||||
- else \
|
||||
- free(tmp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 15:44:20 -0500
|
||||
Subject: [PATCH] multipathd: handle NULL return from genhelp_handler
|
||||
|
||||
If parse_cmd() wasn't checking if genhelp_handler() returned NULL. It
|
||||
was simply assuming that it got a string. Instead, it should just return
|
||||
and error. Found by Coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||||
index ca176a9..17795b6 100644
|
||||
--- a/multipathd/cli.c
|
||||
+++ b/multipathd/cli.c
|
||||
@@ -467,6 +467,8 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
|
||||
|
||||
if (r) {
|
||||
*reply = genhelp_handler(cmd, r);
|
||||
+ if (*reply == NULL)
|
||||
+ return EINVAL;
|
||||
*len = strlen(*reply) + 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -474,9 +476,11 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
|
||||
h = find_handler(fingerprint(cmdvec));
|
||||
|
||||
if (!h || !h->fn) {
|
||||
+ free_keys(cmdvec);
|
||||
*reply = genhelp_handler(cmd, EINVAL);
|
||||
+ if (*reply == NULL)
|
||||
+ return EINVAL;
|
||||
*len = strlen(*reply) + 1;
|
||||
- free_keys(cmdvec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
50
SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch
Normal file
50
SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 12:24:45 +0100
|
||||
Subject: [PATCH] BZ 1700911: hwtable: add Lenovo DE series
|
||||
|
||||
I got this from Steven.
|
||||
|
||||
Cc: Steve.Schremmer@netapp.com
|
||||
Cc: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
|
||||
Cc: xose.vazquez@gmail.com
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index 8776411..f13591d 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -701,6 +701,26 @@ static struct hwentry default_hw[] = {
|
||||
.no_path_retry = (300 / DEFAULT_CHECKINT),
|
||||
.prio_name = PRIO_ALUA,
|
||||
},
|
||||
+ /*
|
||||
+ * Lenovo
|
||||
+ */
|
||||
+ {
|
||||
+ /*
|
||||
+ * DE Series
|
||||
+ *
|
||||
+ * Maintainer: ng-eseries-upstream-maintainers@netapp.com
|
||||
+ */
|
||||
+ .vendor = "LENOVO",
|
||||
+ .product = "DE_Series",
|
||||
+ .bl_product = "Universal Xport",
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .checker_name = RDAC,
|
||||
+ .features = "2 pg_init_retries 50",
|
||||
+ .hwhandler = "1 rdac",
|
||||
+ .prio_name = PRIO_RDAC,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .no_path_retry = 30,
|
||||
+ },
|
||||
/*
|
||||
* NetApp
|
||||
*/
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 24 May 2019 17:30:07 -0500
|
||||
Subject: [PATCH] libmultipath: make vector_foreach_slot_backwards work as
|
||||
expected
|
||||
|
||||
All of the code that uses vector_foreach_slot_backwards() treats "i" as
|
||||
the index of the entry "p", but the way it was coded, that wasn't the
|
||||
case. "i" was the number of the entry counting from 1, not 0.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/vector.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/vector.h b/libmultipath/vector.h
|
||||
index 41d2b89..344dffd 100644
|
||||
--- a/libmultipath/vector.h
|
||||
+++ b/libmultipath/vector.h
|
||||
@@ -40,7 +40,7 @@ typedef struct _vector *vector;
|
||||
#define vector_foreach_slot_after(v,p,i) \
|
||||
for (; (v) && i < VECTOR_SIZE(v) && ((p) = (v)->slot[i]); i++)
|
||||
#define vector_foreach_slot_backwards(v,p,i) \
|
||||
- for (i = VECTOR_SIZE(v); i > 0 && ((p) = (v)->slot[i-1]); i--)
|
||||
+ for (i = VECTOR_SIZE(v) - 1; (int)i >= 0 && ((p) = (v)->slot[i]); i--)
|
||||
|
||||
#define identity(x) (x)
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
93
SOURCES/multipath.conf
Normal file
93
SOURCES/multipath.conf
Normal file
@ -0,0 +1,93 @@
|
||||
# This is a basic configuration file with some examples, for device mapper
|
||||
# multipath.
|
||||
#
|
||||
# For a complete list of the default configuration values, run either
|
||||
# multipath -t
|
||||
# or
|
||||
# multipathd show config
|
||||
#
|
||||
# For a list of configuration options with descriptions, see the multipath.conf
|
||||
# man page
|
||||
|
||||
## By default, devices with vendor = "IBM" and product = "S/390.*" are
|
||||
## blacklisted. To enable mulitpathing on these devies, uncomment the
|
||||
## following lines.
|
||||
#blacklist_exceptions {
|
||||
# device {
|
||||
# vendor "IBM"
|
||||
# product "S/390.*"
|
||||
# }
|
||||
#}
|
||||
|
||||
## Use user friendly names, instead of using WWIDs as names.
|
||||
defaults {
|
||||
user_friendly_names yes
|
||||
find_multipaths yes
|
||||
}
|
||||
##
|
||||
## Here is an example of how to configure some standard options.
|
||||
##
|
||||
#
|
||||
#defaults {
|
||||
# udev_dir /dev
|
||||
# polling_interval 10
|
||||
# selector "round-robin 0"
|
||||
# path_grouping_policy multibus
|
||||
# prio alua
|
||||
# path_checker readsector0
|
||||
# rr_min_io 100
|
||||
# max_fds 8192
|
||||
# rr_weight priorities
|
||||
# failback immediate
|
||||
# no_path_retry fail
|
||||
# user_friendly_names yes
|
||||
#}
|
||||
##
|
||||
## The wwid line in the following blacklist section is shown as an example
|
||||
## of how to blacklist devices by wwid. The 2 devnode lines are the
|
||||
## compiled in default blacklist. If you want to blacklist entire types
|
||||
## of devices, such as all scsi devices, you should use a devnode line.
|
||||
## However, if you want to blacklist specific devices, you should use
|
||||
## a wwid line. Since there is no guarantee that a specific device will
|
||||
## not change names on reboot (from /dev/sda to /dev/sdb for example)
|
||||
## devnode lines are not recommended for blacklisting specific devices.
|
||||
##
|
||||
#blacklist {
|
||||
# wwid 26353900f02796769
|
||||
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
|
||||
# devnode "^hd[a-z]"
|
||||
#}
|
||||
#multipaths {
|
||||
# multipath {
|
||||
# wwid 3600508b4000156d700012000000b0000
|
||||
# alias yellow
|
||||
# path_grouping_policy multibus
|
||||
# path_checker readsector0
|
||||
# path_selector "round-robin 0"
|
||||
# failback manual
|
||||
# rr_weight priorities
|
||||
# no_path_retry 5
|
||||
# }
|
||||
# multipath {
|
||||
# wwid 1DEC_____321816758474
|
||||
# alias red
|
||||
# }
|
||||
#}
|
||||
#devices {
|
||||
# device {
|
||||
# vendor "COMPAQ "
|
||||
# product "HSV110 (C)COMPAQ"
|
||||
# path_grouping_policy multibus
|
||||
# path_checker readsector0
|
||||
# path_selector "round-robin 0"
|
||||
# hardware_handler "0"
|
||||
# failback 15
|
||||
# rr_weight priorities
|
||||
# no_path_retry queue
|
||||
# }
|
||||
# device {
|
||||
# vendor "COMPAQ "
|
||||
# product "MSA1000 "
|
||||
# path_grouping_policy multibus
|
||||
# }
|
||||
#}
|
1687
SPECS/device-mapper-multipath.spec
Normal file
1687
SPECS/device-mapper-multipath.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user