From patchwork Sat Jan 12 06:04:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 1968721 Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by patchwork2.kernel.org (Postfix) with ESMTP id F403BDF230 for ; Sat, 12 Jan 2013 06:09:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r0C66GiK018105; Sat, 12 Jan 2013 01:06:16 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r0C651KL006157 for ; Sat, 12 Jan 2013 01:05:01 -0500 Received: from ether.msp.redhat.com (ether.msp.redhat.com [10.15.80.119]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r0C651Js001879 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 12 Jan 2013 01:05:01 -0500 Received: from ether.msp.redhat.com (localhost.localdomain [127.0.0.1]) by ether.msp.redhat.com (8.14.1/8.14.1) with ESMTP id r0C6509b003436; Sat, 12 Jan 2013 00:05:00 -0600 Received: (from bmarzins@localhost) by ether.msp.redhat.com (8.14.1/8.14.1/Submit) id r0C6504s003435; Sat, 12 Jan 2013 00:05:00 -0600 From: Benjamin Marzinski To: device-mapper development Date: Sat, 12 Jan 2013 00:04:44 -0600 Message-Id: <1357970695-3396-7-git-send-email-bmarzins@redhat.com> In-Reply-To: <1357970695-3396-1-git-send-email-bmarzins@redhat.com> References: <1357970695-3396-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH V3 07/18] multipath: add detect_prio option to autodetect X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com This patch adds a new multipath.conf option, detect_prio. If set to yes, multipathd will try to determine the correct prioritizer for the device. If it finds one, that will be used instead of its configured prioritizer. If none is found, the configured prioritizer will be used. It can currently only detect ALUA devices. Also fixed and issue with select_prio where in the devices section, it was passing in the prio name string instead of the prio args string to prio_get() Signed-off-by: Benjamin Marzinski --- libmultipath/Makefile | 2 +- libmultipath/config.c | 3 ++ libmultipath/config.h | 2 ++ libmultipath/defaults.h | 1 + libmultipath/dict.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ libmultipath/discovery.c | 1 + libmultipath/propsel.c | 39 ++++++++++++++++++++++++- libmultipath/propsel.h | 1 + libmultipath/structs.h | 7 +++++ 9 files changed, 128 insertions(+), 2 deletions(-) diff --git a/libmultipath/Makefile b/libmultipath/Makefile index 0395602..22d3844 100644 --- a/libmultipath/Makefile +++ b/libmultipath/Makefile @@ -15,7 +15,7 @@ OBJS = memory.o parser.o vector.o devmapper.o \ pgpolicies.o debug.o regex.o defaults.o uevent.o \ switchgroup.o uxsock.o print.o alias.o log_pthread.o \ log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o waiter.o file.o wwids.o + lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h) diff --git a/libmultipath/config.c b/libmultipath/config.c index 50863b2..b317e32 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -333,6 +333,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) merge_num(dev_loss); merge_num(user_friendly_names); merge_num(retain_hwhandler); + merge_num(detect_prio); return 0; } @@ -393,6 +394,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe) hwe->dev_loss = dhwe->dev_loss; hwe->user_friendly_names = dhwe->user_friendly_names; hwe->retain_hwhandler = dhwe->retain_hwhandler; + hwe->detect_prio = dhwe->detect_prio; if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product))) goto out; @@ -533,6 +535,7 @@ load_config (char * file) conf->max_checkint = MAX_CHECKINT(conf->checkint); conf->fast_io_fail = DEFAULT_FAST_IO_FAIL; conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER; + conf->detect_prio = DEFAULT_DETECT_PRIO; /* * preload default hwtable diff --git a/libmultipath/config.h b/libmultipath/config.h index 7a1409f..4ade355 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -47,6 +47,7 @@ struct hwentry { unsigned int dev_loss; int user_friendly_names; int retain_hwhandler; + int detect_prio; char * bl_product; }; @@ -110,6 +111,7 @@ struct config { uint32_t cookie; int reassign_maps; int retain_hwhandler; + int detect_prio; unsigned int version[3]; char * dev; diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h index f8a8774..32948d8 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -17,6 +17,7 @@ #define DEFAULT_REASSIGN_MAPS 1 #define DEFAULT_FAST_IO_FAIL 5 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF +#define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF #define DEFAULT_CHECKINT 5 #define MAX_CHECKINT(a) (a << 2) diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 88b4aba..788ffae 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -652,6 +652,29 @@ def_retain_hwhandler_handler(vector strvec) return 0; } +static int +def_detect_prio_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->detect_prio = DETECT_PRIO_OFF; + else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || + (strlen(buff) == 1 && !strcmp(buff, "1"))) + conf->detect_prio = DETECT_PRIO_ON; + else + conf->detect_prio = DETECT_PRIO_UNDEF; + + FREE(buff); + return 0; +} + /* * blacklist block handlers */ @@ -1300,6 +1323,33 @@ hw_retain_hwhandler_handler(vector strvec) return 0; } +static int +hw_detect_prio_handler(vector strvec) +{ + struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); + char * buff; + + if (!hwe) + return 1; + + buff = set_value(strvec); + + if (!buff) + return 1; + + if ((strlen(buff) == 2 && !strcmp(buff, "no")) || + (strlen(buff) == 1 && !strcmp(buff, "0"))) + hwe->detect_prio = DETECT_PRIO_OFF; + else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || + (strlen(buff) == 1 && !strcmp(buff, "1"))) + hwe->detect_prio = DETECT_PRIO_ON; + else + hwe->detect_prio = DETECT_PRIO_UNDEF; + + FREE(buff); + return 0; +} + /* * multipaths block handlers */ @@ -2337,6 +2387,19 @@ snprint_hw_retain_hwhandler_handler(char * buff, int len, void * data) } static int +snprint_detect_prio(char * buff, int len, void * data) +{ + struct hwentry * hwe = (struct hwentry *)data; + + if (hwe->detect_prio == DETECT_PRIO_ON) + return snprintf(buff, len, "yes"); + else if (hwe->detect_prio == DETECT_PRIO_OFF) + return snprintf(buff, len, "no"); + else + return 0; +} + +static int snprint_def_polling_interval (char * buff, int len, void * data) { return snprintf(buff, len, "%i", conf->checkint); @@ -2671,6 +2734,15 @@ snprint_def_retain_hwhandler_handler(char * buff, int len, void * data) } static int +snprint_def_detect_prio(char * buff, int len, void * data) +{ + if (conf->detect_prio == DETECT_PRIO_ON) + return snprintf(buff, len, "yes"); + else + return snprintf(buff, len, "no"); +} + +static int snprint_ble_simple (char * buff, int len, void * data) { struct blentry * ble = (struct blentry *)data; @@ -2735,6 +2807,7 @@ init_keywords(void) install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err); 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); __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); @@ -2797,6 +2870,7 @@ init_keywords(void) install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names); install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler); + install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio); install_sublevel_end(); install_keyword_root("multipaths", &multipaths_handler); diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 3ffdc62..45570dc 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -782,6 +782,7 @@ get_prio (struct path * pp) struct prio * p = &pp->prio; if (!prio_selected(p)) { + select_detect_prio(pp); select_prio(pp); if (!prio_selected(p)) { condlog(3, "%s: no prio selected", pp->dev); diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index c03926a..a7e1fc2 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -17,6 +17,7 @@ #include "devmapper.h" #include "prio.h" #include "discovery.h" +#include "prioritizers/alua_rtpg.h" #include pgpolicyfn *pgpolicies[] = { @@ -382,12 +383,30 @@ select_getuid (struct path * pp) return 0; } +void +detect_prio(struct path * pp) +{ + struct prio *p = &pp->prio; + + if (get_target_port_group_support(pp->fd) > 0) + prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); +} + extern int select_prio (struct path * pp) { struct mpentry * mpe; struct prio * p = &pp->prio; + if (pp->detect_prio == DETECT_PRIO_ON) { + detect_prio(pp); + if (prio_selected(p)) { + condlog(3, "%s: prio = %s (detected setting)", + pp->dev, prio_name(p)); + return 0; + } + } + if ((mpe = find_mpe(pp->wwid))) { if (mpe->prio_name) { prio_get(p, mpe->prio_name, mpe->prio_args); @@ -398,7 +417,7 @@ select_prio (struct path * pp) } if (pp->hwe && pp->hwe->prio_name) { - prio_get(p, pp->hwe->prio_name, pp->hwe->prio_name); + prio_get(p, pp->hwe->prio_name, pp->hwe->prio_args); condlog(3, "%s: prio = %s (controller setting)", pp->dev, pp->hwe->prio_name); condlog(3, "%s: prio args = %s (controller setting)", @@ -706,3 +725,21 @@ select_retain_hwhandler (struct multipath * mp) condlog(3, "%s: retain_attached_hw_handler = %d (compiled in default)", mp->alias, mp->retain_hwhandler); return 0; } + +extern int +select_detect_prio (struct path * pp) +{ + if (pp->hwe && pp->hwe->detect_prio) { + pp->detect_prio = pp->hwe->detect_prio; + condlog(3, "%s: detect_prio = %d (controller default)", pp->dev, pp->detect_prio); + return 0; + } + if (conf->detect_prio) { + pp->detect_prio = conf->detect_prio; + condlog(3, "%s: detect_prio = %d (config file default)", pp->dev, pp->detect_prio); + return 0; + } + pp->detect_prio = 0; + condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio); + return 0; +} diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h index 1bf6e45..eb1e534 100644 --- a/libmultipath/propsel.h +++ b/libmultipath/propsel.h @@ -19,3 +19,4 @@ int select_fast_io_fail(struct multipath *mp); int select_dev_loss(struct multipath *mp); int select_reservation_key(struct multipath *mp); int select_retain_hwhandler (struct multipath * mp); +int select_detect_prio(struct path * pp); diff --git a/libmultipath/structs.h b/libmultipath/structs.h index 92cd2e4..2beccb3 100644 --- a/libmultipath/structs.h +++ b/libmultipath/structs.h @@ -107,6 +107,12 @@ enum retain_hwhandler_states { RETAIN_HWHANDLER_ON, }; +enum detect_prio_states { + DETECT_PRIO_UNDEF, + DETECT_PRIO_OFF, + DETECT_PRIO_ON, +}; + struct scsi_idlun { int dev_id; int host_unique_id; @@ -165,6 +171,7 @@ struct path { int failcount; int priority; int pgindex; + int detect_prio; char * uid_attribute; struct prio prio; char * prio_args;