diff options
-rw-r--r-- | libmultipath/config.h | 1 | ||||
-rw-r--r-- | libmultipath/dict.c | 35 | ||||
-rw-r--r-- | libmultipath/structs.h | 6 | ||||
-rw-r--r-- | multipath.conf.annotated | 9 | ||||
-rw-r--r-- | multipath.conf.synthetic | 1 | ||||
-rw-r--r-- | multipath/multipath.conf.5 | 13 | ||||
-rw-r--r-- | multipathd/main.c | 5 |
7 files changed, 70 insertions, 0 deletions
diff --git a/libmultipath/config.h b/libmultipath/config.h index 1d66cca..f6f39e6 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -74,6 +74,7 @@ struct config { int pg_timeout; int max_fds; int force_reload; + int queue_without_daemon; int daemon; int flush_on_last_del; int attribute_flags; diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 9782599..ab0c831 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -362,6 +362,28 @@ def_no_path_retry_handler(vector strvec) } static int +def_queue_without_daemon(vector strvec) +{ + char * buff; + + buff = set_value(strvec); + if (!buff) + return 1; + + if (!strncmp(buff, "off", 3) || !strncmp(buff, "no", 2) || + !strncmp(buff, "0", 1)) + conf->queue_without_daemon = QUE_NO_DAEMON_OFF; + else if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) || + !strncmp(buff, "1", 1)) + conf->queue_without_daemon = QUE_NO_DAEMON_ON; + else + conf->queue_without_daemon = QUE_NO_DAEMON_UNDEF; + + free(buff); + return 0; +} + +static int def_pg_timeout_handler(vector strvec) { int pg_timeout; @@ -1944,6 +1966,18 @@ snprint_def_no_path_retry (char * buff, int len, void * data) } static int +snprint_def_queue_without_daemon (char * buff, int len, void * data) +{ + switch (conf->queue_without_daemon) { + case QUE_NO_DAEMON_OFF: + return snprintf(buff, len, "no"); + case QUE_NO_DAEMON_ON: + return snprintf(buff, len, "yes"); + } + return 0; +} + +static int snprint_def_pg_timeout (char * buff, int len, void * data) { if (conf->pg_timeout == DEFAULT_PGTIMEOUT) @@ -2029,6 +2063,7 @@ init_keywords(void) install_keyword("max_fds", &max_fds_handler, &snprint_max_fds); install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight); install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry); + install_keyword("queue_without_daemon", &def_queue_without_daemon, &snprint_def_queue_without_daemon); install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout); install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del); install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names); diff --git a/libmultipath/structs.h b/libmultipath/structs.h index dfd0556..c559838 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -63,6 +63,12 @@ enum pgstates { PGSTATE_ACTIVE }; +enum queue_without_daemon_states { + QUE_NO_DAEMON_UNDEF, + QUE_NO_DAEMON_OFF, + QUE_NO_DAEMON_ON, +}; + enum pgtimeouts { PGTIMEOUT_UNDEF, PGTIMEOUT_NONE diff --git a/multipath.conf.annotated b/multipath.conf.annotated index bd04e70..6532622 100644 --- a/multipath.conf.annotated +++ b/multipath.conf.annotated @@ -153,6 +153,15 @@ # no_path_retry queue # # # +# # name : queue_without_daemon +# # scope : multipathd +# # desc : If set to "no", multipathd will disable queueing for all +# # devices when it is shut down. +# # values : yes|no +# # default : yes +# queue_without_daemon no +# +# # # # name : user_friendly_names # # scope : multipath # # desc : If set to "yes", using the bindings file diff --git a/multipath.conf.synthetic b/multipath.conf.synthetic index 3e0fd6e..44d1329 100644 --- a/multipath.conf.synthetic +++ b/multipath.conf.synthetic @@ -16,6 +16,7 @@ # rr_weight priorities # failback immediate # no_path_retry fail +# queue_without_daemon no # user_friendly_names no # mode 644 # uid 0 diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 index ed9b2d8..1dc1488 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -251,6 +251,19 @@ will disable the timeout. .B dev_loss_tmo Specify the number of seconds the scsi layer will wait after a problem has been detected on a FC remote port before removing it from the system. +.TP +.B queue_without_daemon +If set to +.I no +, when multipathd stops, queueing will be turned off for all devices. +This is useful for devices that set no_path_retry. If a machine is +shut down while all paths to a device are down, it is possible to hang waiting +for IO to return from the device after multipathd has been stopped. Without +multipathd running, access to the paths cannot be restored, and the kernel +cannot be told to stop queueing IO. Setting queue_without_daemon to +.I no +, avoids this problem. Default is +.I yes . .SH "blacklist section" The diff --git a/multipathd/main.c b/multipathd/main.c index 3f7eb49..8754144 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1359,6 +1359,8 @@ child (void * param) pthread_t check_thr, uevent_thr, uxlsnr_thr; pthread_attr_t log_attr, misc_attr; struct vectors * vecs; + struct multipath * mpp; + int i; mlockall(MCL_CURRENT | MCL_FUTURE); @@ -1448,6 +1450,9 @@ child (void * param) */ block_signal(SIGHUP, NULL); lock(vecs->lock); + if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF) + vector_foreach_slot(vecs->mpvec, mpp, i) + dm_queue_if_no_path(mpp->alias, 0); remove_maps_and_stop_waiters(vecs); free_pathvec(vecs->pathvec, FREE_PATHS); |