Add multipath.conf force_sync option
authorBenjamin Marzinski <bmarzins@redhat.com>
Mon, 30 Jun 2014 05:14:03 +0000 (00:14 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 24 Jul 2014 08:51:06 +0000 (10:51 +0200)
Normally multipathd runs the path checkers asynchronously. However if there
are a lot of paths, this can cause large CPU spikes (for instance, in
cases where they are all competing for the Big Kernel Lock). In these
situations, overall machine performance is better if multipath doesn't have
hundreds or even thousands of path checkers running at the same time. This
patch lets users turn off the asynchronous mode of these checks if they
see this problem.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/config.c
libmultipath/config.h
libmultipath/dict.c
libmultipath/discovery.c
multipath.conf.annotated
multipath/multipath.conf.5

index e13c307..39963b4 100644 (file)
@@ -561,6 +561,7 @@ load_config (char * file, struct udev *udev)
        conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
        conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
        conf->detect_prio = DEFAULT_DETECT_PRIO;
+       conf->force_sync = 0;
 
        /*
         * preload default hwtable
index ca17f39..844ee12 100644 (file)
@@ -125,6 +125,7 @@ struct config {
        int reassign_maps;
        int retain_hwhandler;
        int detect_prio;
+       int force_sync;
        unsigned int version[3];
 
        char * dev;
index 91d9b83..7de7a67 100644 (file)
@@ -685,6 +685,29 @@ def_detect_prio_handler(vector strvec)
        return 0;
 }
 
+static int
+def_force_sync_handler(vector strvec)
+{
+       char * buff;
+
+       buff = set_value(strvec);
+
+       if (!buff)
+               return 1;
+
+       if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
+           (strlen(buff) == 1 && !strcmp(buff, "0")))
+               conf->force_sync = 0;
+       else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
+                (strlen(buff) == 1 && !strcmp(buff, "1")))
+               conf->force_sync = 1;
+       else
+               conf->force_sync = 0;
+
+       FREE(buff);
+       return 0;
+}
+
 /*
  * blacklist block handlers
  */
@@ -2782,6 +2805,15 @@ snprint_def_detect_prio(char * buff, int len, void * data)
                return snprintf(buff, len, "no");
 }
 
+static int
+snprint_def_force_sync(char * buff, int len, void * data)
+{
+       if (conf->force_sync)
+               return snprintf(buff, len, "yes");
+       else
+               return snprintf(buff, len, "no");
+}
+
 static int
 snprint_ble_simple (char * buff, int len, void * data)
 {
@@ -2849,6 +2881,7 @@ init_keywords(void)
        install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
        install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
        install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
+       install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
        __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
        __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
        __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
index 10b0b89..af2aa20 100644 (file)
@@ -1053,8 +1053,12 @@ get_state (struct path * pp, int daemon)
                }
        }
        checker_clear_message(c);
-       if (daemon)
-               checker_set_async(c);
+       if (daemon) {
+               if (conf->force_sync == 0)
+                       checker_set_async(c);
+               else
+                       checker_set_sync(c);
+       }
        if (!conf->checker_timeout &&
            sysfs_get_timeout(pp, &(c->timeout)) <= 0)
                c->timeout = DEF_TIMEOUT;
index f158746..0af1d4c 100644 (file)
 #      # default : determined by the OS
 #      dev_loss_tmo 600
 #
+#      #
 #      # name    : bindings_file
 #      # scope   : multipath
 #      # desc    : The location of the bindings file that is used with
 #      # default : "/var/lib/multipath/bindings"
 #      bindings_file "/etc/multipath/bindings"
 #
+#      #
 #      # name    : wwids_file
 #      # scope   : multipath
 #      # desc    : The location of the wwids file multipath uses to
 #      # default : "/var/lib/multipath/wwids"
 #      wwids_file "/etc/multipath/wwids"
 #
+#      #
 #      # name    : reservation_key
 #      # scope   : multipath
 #      # desc    : Service action reservation key used by mpathpersist.
 #      # default : (null)
 #      reservation_key "mpathkey"
 #
+#      #
+#      # name    : force_sync
+#      # scope   : multipathd
+#      # desc    : If set to yes, multipath will run all of the checkers in
+#      #           sync mode, even if the checker has an async mode.
+#      # values  : yes|no
+#      # default : no
+#      force_sync yes
 #}
 #      
 ##
index 195e663..cadb34d 100644 (file)
@@ -409,6 +409,15 @@ will automatically use the
 .I alua
 prioritizer. If not, the prioritizer will be selected as usual. Default is
 .I no
+.TP
+.B force_sync
+If set to
+.I yes
+, multipathd will call the path checkers in sync mode only.  This means that
+only one checker will run at a time.  This is useful in the case where many
+multipathd checkers running in parallel causes significant CPU pressure. The
+Default is
+.I no
 .
 .SH "blacklist section"
 The