summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2010-03-23 17:04:00 -0500
committerChristophe Varoqui <christophe.varoqui@opensvc.com>2010-03-25 20:18:04 +0100
commit6ec48625e68f66e993178348a4a1e7916ac1222d (patch)
treef0adcb366e4d32f15b3fa688e81521290ed4ac3f
parentca2e0bced9985b3d2a43c942a367dd9f2540cf00 (diff)
downloadmultipath-tools-6ec48625e68f66e993178348a4a1e7916ac1222d.tar.gz
multipath-tools-6ec48625e68f66e993178348a4a1e7916ac1222d.tar.bz2
multipath-tools-6ec48625e68f66e993178348a4a1e7916ac1222d.zip
multipath: add queue_without_daemon config parameter
This patch adds a new multipath.conf default paramter, queue_without_daemon. If this is set to "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 "no" makes multipathd turn off queueing on all devices when it stops, avoiding the problem. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
-rw-r--r--libmultipath/config.h1
-rw-r--r--libmultipath/dict.c35
-rw-r--r--libmultipath/structs.h6
-rw-r--r--multipath.conf.annotated9
-rw-r--r--multipath.conf.synthetic1
-rw-r--r--multipath/multipath.conf.513
-rw-r--r--multipathd/main.c5
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);