From patchwork Thu Oct 8 19:44:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 7355081 X-Patchwork-Delegate: bmarzins@redhat.com Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B684FBEEA4 for ; Thu, 8 Oct 2015 19:47:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B1052207BD for ; Thu, 8 Oct 2015 19:47:52 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E1935207C3 for ; Thu, 8 Oct 2015 19:47:50 +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 t98JjOex005201; Thu, 8 Oct 2015 15:45:24 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id t98JjJid005864 for ; Thu, 8 Oct 2015 15:45:19 -0400 Received: from redhat.com (octiron.msp.redhat.com [10.15.80.209]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id t98JjHJQ010797; Thu, 8 Oct 2015 15:45:18 -0400 Received: by redhat.com (sSMTP sendmail emulation); Thu, 08 Oct 2015 14:45:17 -0500 From: "Benjamin Marzinski" To: device-mapper development Date: Thu, 8 Oct 2015 14:44:46 -0500 Message-Id: <1444333491-16265-14-git-send-email-bmarzins@redhat.com> In-Reply-To: <1444333491-16265-1-git-send-email-bmarzins@redhat.com> References: <1444333491-16265-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 13/18] libmultipath: add ignore_new_boot_devs option 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 X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When multipath relies on the wwids file to determine whether a device is a multipath path (with "multipath -c"), it will fail the first time a new multipathable device is discovered, since the wwid clearly won't be in the wwids file. This is usually fine. Multipath will still set itself up on the device, and add the wwid to the wwids file. However, this causes a race, where multipath won't claim the path immediately, and something else may. Later multipath will try, and possibly succeed at, setting itself up on that device. I've seen cases where this can cause problems during boot on and immediately after install, where multipath racing with LVM on an already labelled device can get the machine into a state where boot fails. This can be avoided if multipath simply doesn't set itself up on any devices that it didn't claim (with "multipath -c") in the initramfs. It can still safely attempt to set itself up on these devices later in boot, after the regular filesystem has been set up. To allow this, this patch adds a new option, ignore_new_boot_devs. When enabled, this patch simply keeps multipath from being set up on devices that aren't already in the wwids file (along with all the other checks that multipath already does). This means that only devices that are claimed by "multipath -c" will be used by multipath. Signed-off-by: Benjamin Marzinski Reviewed-by: Hannes Reinecke --- libmultipath/config.c | 1 + libmultipath/config.h | 1 + libmultipath/configure.c | 3 +-- libmultipath/dict.c | 4 ++++ libmultipath/wwids.c | 21 ++++++++++++++------- multipathd/main.c | 3 +-- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libmultipath/config.c b/libmultipath/config.c index 746459c..773a17a 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -623,6 +623,7 @@ load_config (char * file, struct udev *udev) conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; conf->new_bindings_in_boot = 0; + conf->ignore_new_boot_devs = 0; /* * preload default hwtable diff --git a/libmultipath/config.h b/libmultipath/config.h index 05f1f6d..65a5978 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -138,6 +138,7 @@ struct config { int retrigger_tries; int retrigger_delay; int new_bindings_in_boot; + int ignore_new_boot_devs; unsigned int version[3]; char * dev; diff --git a/libmultipath/configure.c b/libmultipath/configure.c index 3c9badd..1ab3324 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -778,8 +778,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_r continue; /* If find_multipaths was selected check if the path is valid */ - if (conf->find_multipaths && !refwwid && - !should_multipath(pp1, pathvec)) { + if (!refwwid && !should_multipath(pp1, pathvec)) { orphan_path(pp1, "only one path"); continue; } diff --git a/libmultipath/dict.c b/libmultipath/dict.c index 1fabc54..e3a33c6 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -399,6 +399,9 @@ declare_def_snprint(retrigger_delay, print_int) declare_def_handler(new_bindings_in_boot, set_yes_no) declare_def_snprint(new_bindings_in_boot, print_yes_no) +declare_def_handler(ignore_new_boot_devs, set_yes_no) +declare_def_snprint(ignore_new_boot_devs, print_yes_no) + static int def_config_dir_handler(vector strvec) { @@ -1375,6 +1378,7 @@ init_keywords(void) install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries); install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay); install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot); + install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); __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); diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c index f6f8ea8..d862d9f 100644 --- a/libmultipath/wwids.c +++ b/libmultipath/wwids.c @@ -15,6 +15,7 @@ #include "wwids.h" #include "defaults.h" #include "config.h" +#include "util.h" /* * Copyright (c) 2010 Benjamin Marzinski, Redhat @@ -265,15 +266,21 @@ should_multipath(struct path *pp1, vector pathvec) { int i; struct path *pp2; + int ignore_new_devs = (conf->ignore_new_boot_devs && in_initrd()); + + if (!conf->find_multipaths && !ignore_new_devs) + return 1; condlog(4, "checking if %s should be multipathed", pp1->dev); - vector_foreach_slot(pathvec, pp2, i) { - if (pp1->dev == pp2->dev) - continue; - if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) { - condlog(3, "found multiple paths with wwid %s, " - "multipathing %s", pp1->wwid, pp1->dev); - return 1; + if (!ignore_new_devs) { + vector_foreach_slot(pathvec, pp2, i) { + if (pp1->dev == pp2->dev) + continue; + if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) { + condlog(3, "found multiple paths with wwid %s, " + "multipathing %s", pp1->wwid, pp1->dev); + return 1; + } } } if (check_wwids_file(pp1->wwid, 0) < 0) { diff --git a/multipathd/main.c b/multipathd/main.c index 09defc9..6c315ad 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -517,8 +517,7 @@ rescan: mpp->flush_on_last_del = FLUSH_UNDEF; mpp->action = ACT_RELOAD; } else { - if (conf->find_multipaths && - !should_multipath(pp, vecs->pathvec)) { + if (!should_multipath(pp, vecs->pathvec)) { orphan_path(pp, "only one path"); return 0; }