From patchwork Tue Jun 20 11:46:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 9799289 X-Patchwork-Delegate: snitzer@redhat.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4B1B7603F1 for ; Tue, 20 Jun 2017 11:47:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C53428451 for ; Tue, 20 Jun 2017 11:47:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 30FE628472; Tue, 20 Jun 2017 11:47:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B344428453 for ; Tue, 20 Jun 2017 11:47:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9B9CB80C15; Tue, 20 Jun 2017 11:47:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9B9CB80C15 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dm-devel-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 9B9CB80C15 Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 262E0867CA; Tue, 20 Jun 2017 11:47:18 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E2C1C4E984; Tue, 20 Jun 2017 11:47:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v5KBku0t026904 for ; Tue, 20 Jun 2017 07:46:56 -0400 Received: by smtp.corp.redhat.com (Postfix) id 7E3C689404; Tue, 20 Jun 2017 11:46:56 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.29]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 99B82893E8; Tue, 20 Jun 2017 11:46:54 +0000 (UTC) Received: from prv3-mh.provo.novell.com (victor.provo.novell.com [137.65.250.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F14FA4F3; Tue, 20 Jun 2017 11:46:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com F14FA4F3 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=mwilck@suse.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com F14FA4F3 Received: from apollon.suse.de.de (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by prv3-mh.provo.novell.com with ESMTP (TLS encrypted); Tue, 20 Jun 2017 05:46:39 -0600 From: Martin Wilck To: Christophe Varoqui , Hannes Reinecke Date: Tue, 20 Jun 2017 13:46:09 +0200 Message-Id: <20170620114614.26261-4-mwilck@suse.com> In-Reply-To: <20170620114614.26261-1-mwilck@suse.com> References: <20170620114614.26261-1-mwilck@suse.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 203 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 20 Jun 2017 11:46:53 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 20 Jun 2017 11:46:53 +0000 (UTC) for IP:'137.65.250.26' DOMAIN:'victor.provo.novell.com' HELO:'prv3-mh.provo.novell.com' FROM:'mwilck@suse.com' RCPT:'' X-RedHat-Spam-Score: -1.501 (BAYES_50, RCVD_IN_DNSWL_MED, SPF_PASS) 137.65.250.26 victor.provo.novell.com 137.65.250.26 victor.provo.novell.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.29 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Xose Vazquez Perez Subject: [dm-devel] [PATCH v2 3/8] libmultipath: clarify option conflicts for "features" X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk 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 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 20 Jun 2017 11:47:19 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP The "features" option in multipath.conf can possibly conflict with "no_path_retry" and "retain_attached_hw_handler". Currently, "no_path_retry" takes precedence, unless it is set to "fail", in which case it's overridden by "queue_if_no_path". This is odd, either "features" or "no_path_retry" should take precedence. No precedence rules are defined for "retain_attached_hw_handler". Make this behavior more consistent by always giving precedence to the explicit config file options, and improve logging. Put this logic into a separate function, which can be used from other places in the code. Signed-off-by: Martin Wilck --- libmultipath/configure.c | 4 +-- libmultipath/propsel.c | 68 +++++++++++++++++++++++++++++++++++++----------- libmultipath/propsel.h | 3 +++ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/libmultipath/configure.c b/libmultipath/configure.c index bd090d9a..fd4721dd 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -280,11 +280,11 @@ int setup_map(struct multipath *mpp, char *params, int params_size) select_pgfailback(conf, mpp); select_pgpolicy(conf, mpp); select_selector(conf, mpp); - select_features(conf, mpp); select_hwhandler(conf, mpp); + select_no_path_retry(conf, mpp); + select_features(conf, mpp); select_rr_weight(conf, mpp); select_minio(conf, mpp); - select_no_path_retry(conf, mpp); select_mode(conf, mpp); select_uid(conf, mpp); select_gid(conf, mpp); diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index 68436433..ccd067f5 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -269,6 +269,55 @@ out: return mp->alias ? 0 : 1; } +void reconcile_features_with_options(const char *id, char **features, int* no_path_retry, + int *retain_hwhandler) +{ + static const char q_i_n_p[] = "queue_if_no_path"; + static const char r_a_h_h[] = "retain_attached_hw_handler"; + char buff[12]; + + if (*features == NULL) + return; + if (id == NULL) + id = "UNKNOWN"; + + /* + * We only use no_path_retry internally. The "queue_if_no_path" + * device-mapper feature is derived from it when the map is loaded. + * For consistency, "queue_if_no_path" is removed from the + * internal libmultipath features string. + * For backward compatibility we allow 'features "1 queue_if_no_path"'; + * it's translated into "no_path_retry queue" here. + */ + if (strstr(*features, q_i_n_p)) { + if (*no_path_retry == NO_PATH_RETRY_UNDEF) { + *no_path_retry = NO_PATH_RETRY_QUEUE; + print_no_path_retry(buff, sizeof(buff), + no_path_retry); + condlog(3, "%s: no_path_retry = %s (inherited setting from feature '%s')", + id, buff, q_i_n_p); + }; + /* Warn only if features string is overridden */ + if (*no_path_retry != NO_PATH_RETRY_QUEUE) { + print_no_path_retry(buff, sizeof(buff), + no_path_retry); + condlog(2, "%s: ignoring feature '%s' because no_path_retry is set to '%s'", + id, q_i_n_p, buff); + } + remove_feature(features, q_i_n_p); + } + if (strstr(*features, r_a_h_h)) { + if (*retain_hwhandler == RETAIN_HWHANDLER_UNDEF) { + condlog(3, "%s: %s = on (inherited setting from feature '%s')", + id, r_a_h_h, r_a_h_h); + *retain_hwhandler = RETAIN_HWHANDLER_ON; + } else if (*retain_hwhandler == RETAIN_HWHANDLER_OFF) + condlog(2, "%s: ignoring feature '%s' because %s is set to 'off'", + id, r_a_h_h, r_a_h_h); + remove_feature(features, r_a_h_h); + } +} + int select_features(struct config *conf, struct multipath *mp) { char *origin; @@ -280,19 +329,11 @@ int select_features(struct config *conf, struct multipath *mp) mp_set_default(features, DEFAULT_FEATURES); out: mp->features = STRDUP(mp->features); - condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin); - if (strstr(mp->features, "queue_if_no_path")) { - if (mp->no_path_retry == NO_PATH_RETRY_UNDEF) - mp->no_path_retry = NO_PATH_RETRY_QUEUE; - else if (mp->no_path_retry == NO_PATH_RETRY_FAIL) { - condlog(1, "%s: config error, overriding 'no_path_retry' value", - mp->alias); - mp->no_path_retry = NO_PATH_RETRY_QUEUE; - } else if (mp->no_path_retry != NO_PATH_RETRY_QUEUE) - condlog(1, "%s: config error, ignoring 'queue_if_no_path' because no_path_retry=%d", - mp->alias, mp->no_path_retry); - } + reconcile_features_with_options(mp->alias, &mp->features, + &mp->no_path_retry, + &mp->retain_hwhandler); + condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin); return 0; } @@ -469,9 +510,6 @@ out: if (origin) condlog(3, "%s: no_path_retry = %s %s", mp->alias, buff, origin); - else if (mp->no_path_retry != NO_PATH_RETRY_UNDEF) - condlog(3, "%s: no_path_retry = %s (inherited setting)", - mp->alias, buff); else condlog(3, "%s: no_path_retry = undef (setting: multipath internal)", mp->alias); diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h index 58a32f3c..f8e96d85 100644 --- a/libmultipath/propsel.h +++ b/libmultipath/propsel.h @@ -28,3 +28,6 @@ int select_max_sectors_kb (struct config *conf, struct multipath * mp); int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp); int select_san_path_err_threshold(struct config *conf, struct multipath *mp); int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp); +void reconcile_features_with_options(const char *id, char **features, + int* no_path_retry, + int *retain_hwhandler);