device-mapper-multipath/0136-RHBZ-1304687-wait-for-map-add.patch
Benjamin Marzinski f9dfbb37ac device-mapper-multipath-0.4.9-86
Modify 0136-RHBZ-1304687-wait-for-map-add.patch
  * switch to missing_uev_wait_timeout to stop waiting for uev
Refresh 0137-RHBZ-1280524-clear-chkr-msg.patch
Refresh 0150-RHBZ-1253913-fix-startup-msg.patch
Refresh 0154-UPBZ-1291406-disable-reinstate.patch
Refresh 0156-UPBZ-1313324-dont-fail-discovery.patch
Refresh 0161-RHBZ-1311659-no-kpartx.patch
Refresh 0167-RHBZ-1335176-fix-show-cmds.patch
Add 0173-RH-update-man-page.patch
Add 0174-RHBZ-1362396-modprobe.patch
  * make starting the multipathd service modprobe dm-multipath in the
    sysvinit scripts
Add 0175-RHBZ-1357382-ordering.patch
  * force multipathd.service to start after systemd-udev-trigger.service
Add 0176-RHBZ-1363830-fix-rename.patch
  * initialized a variable to make dm_rename not fail randomly
Add 0177-libmultipath-correctly-initialize-pp-sg_id.patch
  * This and all the following patches add the rbd patch checker
Add 0178-libmultipath-add-rbd-discovery.patch
Add 0179-multipath-tools-add-checker-callout-to-repair-path.patch
Add 0180-multipath-tools-Add-rbd-checker.patch
Add 0181-multipath-tools-Add-rbd-to-the-hwtable.patch
Add 0182-multipath-tools-check-for-initialized-checker-before.patch
Add 0183-multipathd-Don-t-call-repair-on-blacklisted-path.patch
Add 0184-rbd-fix-sync-repair-support.patch
Add 0185-rbd-check-for-nonshared-clients.patch
Add 0186-rbd-check-for-exclusive-lock-enabled.patch
Add 0187-rbd-fixup-log-messages.patch
Add 0188-RHBZ-1368501-dont-exit.patch
  * make multipathd not exit if it encounters recoverable errors on startup
Add 0189-RHBZ-1368211-remove-retries.patch
  * add "remove_retries" multipath.conf parameter to make multiple attempts
    to remove a multipath device if it is busy.
Add 0190-RHBZ-1380602-rbd-lock-on-read.patch
  * pass lock_on_read when remapping image
Add 0191-RHBZ-1169168-disable-changed-paths.patch
  * add "disabled_changed_wwids" multipath.conf parameter to disable
    paths whose wwid changes
Add 0192-RHBZ-1362409-infinibox-config.patch
Add 0194-RHBZ-1351964-kpartx-recurse.patch
  * fix recursion on corrupt dos partitions
Add 0195-RHBZ-1359510-no-daemon-msg.patch
  * print a messages when multipathd isn't running
Add 0196-RHBZ-1239173-dont-set-flag.patch
  * don't set reload flag on reloads when you gain your first
    valid path
Add 0197-RHBZ-1394059-max-sectors-kb.patch
  * add "max_sectors_kb" multipath.conf parameter to set max_sectors_kb
    on a multipath device and all its path devices
Add 0198-RHBZ-1372032-detect-path-checker.patch
  * add "detect_checker" multipath.conf parameter to detect ALUA arrays
    and set the path checker to TUR
Add 0199-RHBZ-1279355-3pardata-config.patch
Add 0200-RHBZ-1402092-orphan-status.patch
  * clear status on orphan paths
Add 0201-RHBZ-1403552-silence-warning.patch
Add 0202-RHBZ-1362120-skip-prio.patch
  * don't run prio on failed paths
Add 0203-RHBZ-1363718-add-msgs.patch
Add 0204-RHBZ-1406226-nimble-config.patch
Add 0205-RHBZ-1416569-reset-stats.patch
  * add "reset maps stats" and "reset map <map> stats" multipathd
    interactive commands to reset the stats tracked by multipathd
Add 0206-RHBZ-1239173-pt2-no-paths.patch
  * make multipath correctly disable scanning and rules running when
    it gets a uevent and there are not valid paths.
Add 0207-UP-add-libmpathcmd.patch
  * New shared library, libmpathcmd, that sends and receives messages from
    multipathd. device-mapper-multipath now uses this library internally.
Add 0208-UPBZ-1430097-multipathd-IPC-changes.patch
  * validation that modifying commands are coming from root.
Add 0209-UPBZ-1430097-multipath-C-API.patch
  * New shared library. libdmmp, that presents the information from multipathd
    in a structured manner to make it easier for callers to use
Add 0210-RH-fix-uninstall.patch
  * Minor compilation fixes
Add 0211-RH-strlen-fix.patch
  * checks that variables are not NULL before passing them to strlen
Add 0212-RHBZ-1431562-for-read-only.patch
Make 3 new subpackages
  * device-mapper-multipath-devel, libdmmp, and libdmmp-devel. libmpathcmd
    and libmpathprio are in device-mapper-multipath-libs and
    device-mapper-multipath-devel. libdmmp is in its own subpackages
Move libmpathprio devel files to device-mapper-multipath-devel
Added BuildRequires on librados2-devel
2017-04-10 18:57:22 -04:00

509 lines
14 KiB
Diff

---
libmultipath/config.c | 1
libmultipath/config.h | 2
libmultipath/configure.c | 4 +
libmultipath/defaults.h | 1
libmultipath/dict.c | 25 ++++++++
libmultipath/structs.h | 2
multipath.conf.defaults | 1
multipath/multipath.conf.5 | 8 ++
multipathd/cli_handlers.c | 65 ++++++++++++++++++----
multipathd/main.c | 132 +++++++++++++++++++++++++++++++++++++++++++--
multipathd/main.h | 1
11 files changed, 229 insertions(+), 13 deletions(-)
Index: multipath-tools-130222/libmultipath/configure.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/configure.c
+++ multipath-tools-130222/libmultipath/configure.c
@@ -701,6 +701,10 @@ domap (struct multipath * mpp, char * pa
*/
if (mpp->action != ACT_CREATE)
mpp->action = ACT_NOTHING;
+ else {
+ mpp->wait_for_udev = 1;
+ mpp->uev_wait_tick = conf->uev_wait_timeout;
+ }
}
dm_setgeometry(mpp);
return DOMAP_OK;
Index: multipath-tools-130222/libmultipath/structs.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/structs.h
+++ multipath-tools-130222/libmultipath/structs.h
@@ -217,6 +217,8 @@ struct multipath {
int bestpg;
int queuedio;
int action;
+ int wait_for_udev;
+ int uev_wait_tick;
int pgfailback;
int failback_tick;
int rr_weight;
Index: multipath-tools-130222/multipathd/cli_handlers.c
===================================================================
--- multipath-tools-130222.orig/multipathd/cli_handlers.c
+++ multipath-tools-130222/multipathd/cli_handlers.c
@@ -548,6 +548,11 @@ cli_reload(void *v, char **reply, int *l
condlog(0, "%s: invalid map name. cannot reload", mapname);
return 1;
}
+ if (mpp->wait_for_udev) {
+ condlog(2, "%s: device not fully created, failing reload",
+ mpp->alias);
+ return 1;
+ }
return reload_map(vecs, mpp, 0);
}
@@ -592,6 +597,12 @@ cli_resize(void *v, char **reply, int *l
return 1;
}
+ if (mpp->wait_for_udev) {
+ condlog(2, "%s: device not fully created, failing resize",
+ mpp->alias);
+ return 1;
+ }
+
pgp = VECTOR_SLOT(mpp->pg, 0);
if (!pgp){
@@ -756,6 +767,12 @@ cli_reconfigure(void * v, char ** reply,
{
struct vectors * vecs = (struct vectors *)data;
+ if (need_to_delay_reconfig(vecs)) {
+ conf->delayed_reconfig = 1;
+ condlog(2, "delaying reconfigure (operator)");
+ return 0;
+ }
+
condlog(2, "reconfigure (operator)");
return reconfigure(vecs);
@@ -766,17 +783,25 @@ cli_suspend(void * v, char ** reply, int
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, MAP);
- int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
+ int r;
+ struct multipath * mpp;
param = convert_dev(param, 0);
- condlog(2, "%s: suspend (operator)", param);
+ mpp = find_mp_by_alias(vecs->mpvec, param);
+ if (!mpp)
+ return 1;
- if (!r) /* error */
+ if (mpp->wait_for_udev) {
+ condlog(2, "%s: device not fully created, failing suspend",
+ mpp->alias);
return 1;
+ }
- struct multipath * mpp = find_mp_by_alias(vecs->mpvec, param);
+ r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
- if (!mpp)
+ condlog(2, "%s: suspend (operator)", param);
+
+ if (!r) /* error */
return 1;
dm_get_info(param, &mpp->dmi);
@@ -788,17 +813,25 @@ cli_resume(void * v, char ** reply, int
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, MAP);
- int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
+ int r;
+ struct multipath * mpp;
param = convert_dev(param, 0);
- condlog(2, "%s: resume (operator)", param);
+ mpp = find_mp_by_alias(vecs->mpvec, param);
+ if (!mpp)
+ return 1;
- if (!r) /* error */
+ if (mpp->wait_for_udev) {
+ condlog(2, "%s: device not fully created, failing resume",
+ mpp->alias);
return 1;
+ }
- struct multipath * mpp = find_mp_by_alias(vecs->mpvec, param);
+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
- if (!mpp)
+ condlog(2, "%s: resume (operator)", param);
+
+ if (!r) /* error */
return 1;
dm_get_info(param, &mpp->dmi);
@@ -831,9 +864,21 @@ cli_reinstate(void * v, char ** reply, i
int
cli_reassign (void * v, char ** reply, int * len, void * data)
{
+ struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, MAP);
+ struct multipath *mpp;
param = convert_dev(param, 0);
+ mpp = find_mp_by_alias(vecs->mpvec, param);
+ if (!mpp)
+ return 1;
+
+ if (mpp->wait_for_udev) {
+ condlog(2, "%s: device not fully created, failing reassign",
+ mpp->alias);
+ return 1;
+ }
+
condlog(3, "%s: reset devices (operator)", param);
dm_reassign(param);
Index: multipath-tools-130222/libmultipath/config.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.h
+++ multipath-tools-130222/libmultipath/config.h
@@ -142,6 +142,8 @@ struct config {
int retrigger_tries;
int retrigger_delay;
int new_bindings_in_boot;
+ int delayed_reconfig;
+ int uev_wait_timeout;
unsigned int version[3];
char * dev;
Index: multipath-tools-130222/multipathd/main.c
===================================================================
--- multipath-tools-130222.orig/multipathd/main.c
+++ multipath-tools-130222/multipathd/main.c
@@ -251,6 +251,47 @@ flush_map(struct multipath * mpp, struct
return 0;
}
+int
+update_map (struct multipath *mpp, struct vectors *vecs)
+{
+ int retries = 3;
+ char params[PARAMS_SIZE] = {0};
+
+retry:
+ condlog(4, "%s: updating new map", mpp->alias);
+ if (adopt_paths(vecs->pathvec, mpp, 1)) {
+ condlog(0, "%s: failed to adopt paths for new map update",
+ mpp->alias);
+ retries = -1;
+ goto fail;
+ }
+ verify_paths(mpp, vecs, NULL);
+ mpp->flush_on_last_del = FLUSH_UNDEF;
+ mpp->action = ACT_RELOAD;
+
+ if (setup_map(mpp, params, PARAMS_SIZE)) {
+ condlog(0, "%s: failed to setup new map in update", mpp->alias);
+ retries = -1;
+ goto fail;
+ }
+ if (domap(mpp, params) <= 0 && retries-- > 0) {
+ condlog(0, "%s: map_udate sleep", mpp->alias);
+ sleep(1);
+ goto retry;
+ }
+ dm_lib_release();
+
+fail:
+ if (setup_multipath(vecs, mpp))
+ return 1;
+
+ sync_map_state(mpp);
+
+ if (retries < 0)
+ condlog(0, "%s: failed reload in new map update", mpp->alias);
+ return 0;
+}
+
static int
uev_add_map (struct uevent * uev, struct vectors * vecs)
{
@@ -293,6 +334,20 @@ ev_add_map (char * dev, char * alias, st
mpp = find_mp_by_alias(vecs->mpvec, alias);
if (mpp) {
+ if (mpp->wait_for_udev > 1) {
+ if (update_map(mpp, vecs))
+ /* setup multipathd removed the map */
+ return 1;
+ }
+ if (mpp->wait_for_udev) {
+ mpp->wait_for_udev = 0;
+ if (conf->delayed_reconfig &&
+ !need_to_delay_reconfig(vecs)) {
+ condlog(2, "reconfigure (delayed)");
+ reconfigure(vecs);
+ return 0;
+ }
+ }
/*
* Not really an error -- we generate our own uevent
* if we create a multipath mapped device as a result
@@ -471,7 +526,14 @@ ev_add_path (struct path * pp, struct ve
condlog(0, "%s: failed to get path uid", pp->dev);
goto fail; /* leave path added to pathvec */
}
- mpp = pp->mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
+ mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
+ if (mpp && mpp->wait_for_udev) {
+ mpp->wait_for_udev = 2;
+ orphan_path(pp);
+ return 0;
+ }
+
+ pp->mpp = mpp;
rescan:
if (mpp) {
if ((!pp->size) || (mpp->size != pp->size)) {
@@ -670,6 +732,12 @@ ev_remove_path (struct path *pp, struct
" removal of path %s", mpp->alias, pp->dev);
goto fail;
}
+
+ if (mpp->wait_for_udev) {
+ mpp->wait_for_udev = 2;
+ goto out;
+ }
+
/*
* reload the map
*/
@@ -731,6 +799,11 @@ uev_update_path (struct uevent *uev, str
condlog(2, "%s: update path write_protect to '%d' (uevent)",
uev->kernel, ro);
if (pp->mpp) {
+ if (pp->mpp->wait_for_udev) {
+ pp->mpp->wait_for_udev = 2;
+ return 0;
+ }
+
retval = reload_map(vecs, pp->mpp, 0);
condlog(2, "%s: map %s reloaded (retval %d)",
@@ -1063,6 +1136,33 @@ followover_should_failback(struct path *
}
static void
+missing_uev_wait_tick(struct vectors *vecs)
+{
+ struct multipath * mpp;
+ unsigned int i;
+ int timed_out = 0;
+
+ vector_foreach_slot (vecs->mpvec, mpp, i) {
+ if (mpp->wait_for_udev && --mpp->uev_wait_tick <= 0) {
+ timed_out = 1;
+ condlog(0, "%s: timeout waiting on creation uevent. enabling reloads", mpp->alias);
+ if (mpp->wait_for_udev > 1 && update_map(mpp, vecs)) {
+ /* update_map removed map */
+ i--;
+ continue;
+ }
+ mpp->wait_for_udev = 0;
+ }
+ }
+
+ if (timed_out && conf->delayed_reconfig &&
+ !need_to_delay_reconfig(vecs)) {
+ condlog(2, "reconfigure (delayed)");
+ reconfigure(vecs);
+ }
+}
+
+static void
defered_failback_tick (vector mpvec)
{
struct multipath * mpp;
@@ -1316,6 +1416,9 @@ check_path (struct vectors * vecs, struc
pp->state = newstate;
+
+ if (pp->mpp->wait_for_udev)
+ return;
/*
* path prio refreshing
*/
@@ -1369,6 +1472,7 @@ checkerloop (void *ap)
if (vecs->mpvec) {
defered_failback_tick(vecs->mpvec);
retry_count_tick(vecs->mpvec);
+ missing_uev_wait_tick(vecs);
}
if (count)
count--;
@@ -1465,6 +1569,22 @@ configure (struct vectors * vecs, int st
}
int
+need_to_delay_reconfig(struct vectors * vecs)
+{
+ struct multipath *mpp;
+ int i;
+
+ if (!VECTOR_SIZE(vecs->mpvec))
+ return 0;
+
+ vector_foreach_slot(vecs->mpvec, mpp, i) {
+ if (mpp->wait_for_udev)
+ return 1;
+ }
+ return 0;
+}
+
+int
reconfigure (struct vectors * vecs)
{
struct config * old = conf;
@@ -1544,12 +1664,18 @@ void
handle_signals(void)
{
if (reconfig_sig && running_state == DAEMON_RUNNING) {
- condlog(2, "reconfigure (signal)");
pthread_cleanup_push(cleanup_lock,
&gvecs->lock);
lock(gvecs->lock);
pthread_testcancel();
- reconfigure(gvecs);
+ if (need_to_delay_reconfig(gvecs)) {
+ conf->delayed_reconfig = 1;
+ condlog(2, "delaying reconfigure (signal)");
+ }
+ else {
+ condlog(2, "reconfigure (signal)");
+ reconfigure(gvecs);
+ }
lock_cleanup_pop(gvecs->lock);
}
if (log_reset_sig) {
Index: multipath-tools-130222/multipathd/main.h
===================================================================
--- multipath-tools-130222.orig/multipathd/main.h
+++ multipath-tools-130222/multipathd/main.h
@@ -18,6 +18,7 @@ extern pid_t daemon_pid;
void exit_daemon(void);
const char * daemon_status(void);
+int need_to_delay_reconfig (struct vectors *);
int reconfigure (struct vectors *);
int ev_add_path (struct path *, struct vectors *);
int ev_remove_path (struct path *, struct vectors *);
Index: multipath-tools-130222/libmultipath/config.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.c
+++ multipath-tools-130222/libmultipath/config.c
@@ -676,6 +676,7 @@ load_config (char * file, struct udev *u
conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
conf->new_bindings_in_boot = 0;
+ conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
/*
* preload default hwtable
Index: multipath-tools-130222/libmultipath/defaults.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/defaults.h
+++ multipath-tools-130222/libmultipath/defaults.h
@@ -23,6 +23,7 @@
#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
#define DEFAULT_RETRIGGER_DELAY 10
#define DEFAULT_RETRIGGER_TRIES 3
+#define DEFAULT_UEV_WAIT_TIMEOUT 30
#define DEFAULT_CHECKINT 5
#define MAX_CHECKINT(a) (a << 2)
Index: multipath-tools-130222/libmultipath/dict.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/dict.c
+++ multipath-tools-130222/libmultipath/dict.c
@@ -872,6 +872,24 @@ def_retrigger_delay_handler(vector strve
}
static int
+def_uev_wait_timeout_handler(vector strvec)
+{
+ char *buff;
+
+ buff = set_value(strvec);
+
+ if (!buff)
+ return 1;
+
+ conf->uev_wait_timeout = atoi(buff);
+ if (conf->uev_wait_timeout <= 0)
+ conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
+ FREE(buff);
+
+ return 0;
+}
+
+static int
def_new_bindings_in_boot_handler(vector strvec)
{
char * buff;
@@ -3261,6 +3279,12 @@ snprint_def_retrigger_delay (char * buff
}
static int
+snprint_def_uev_wait_timeout (char * buff, int len, void * data)
+{
+ return snprintf(buff, len, "%i", conf->uev_wait_timeout);
+}
+
+static int
snprint_def_new_bindings_in_boot(char * buff, int len, void * data)
{
if (conf->new_bindings_in_boot == 1)
@@ -3345,6 +3369,7 @@ init_keywords(void)
install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries);
install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay);
+ install_keyword("missing_uev_wait_timeout", &def_uev_wait_timeout_handler, &snprint_def_uev_wait_timeout);
install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
Index: multipath-tools-130222/multipath.conf.defaults
===================================================================
--- multipath-tools-130222.orig/multipath.conf.defaults
+++ multipath-tools-130222/multipath.conf.defaults
@@ -29,6 +29,7 @@
# config_dir "/etc/multipath/conf.d"
# delay_watch_checks no
# delay_wait_checks no
+# missing_uev_wait_timeout 30
#}
#blacklist {
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
Index: multipath-tools-130222/multipath/multipath.conf.5
===================================================================
--- multipath-tools-130222.orig/multipath/multipath.conf.5
+++ multipath-tools-130222/multipath/multipath.conf.5
@@ -478,6 +478,14 @@ used until it has passed
.I delay_wait_checks
checks. Default is
.I no
+.TP
+.B missing_uev_wait_timeout
+Controls how many seconds multipathd will wait, after a new multipath device
+is created, to receive a change event from udev for the device, before
+automatically enabling device reloads. Usually multipathd will delay reloads
+on a device until it receives a change uevent from the initial table load. The
+default is
+.I 30
.
.SH "blacklist section"
The