From patchwork Mon Apr 2 19:50:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 10320271 X-Patchwork-Delegate: christophe.varoqui@free.fr 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 E2C2A60532 for ; Mon, 2 Apr 2018 19:52:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDAAC20856 for ; Mon, 2 Apr 2018 19:52:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C215325E13; Mon, 2 Apr 2018 19:52:43 +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 5185920856 for ; Mon, 2 Apr 2018 19:52:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9B7F7C051668; Mon, 2 Apr 2018 19:52:42 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7B47612A79; Mon, 2 Apr 2018 19:52:42 +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 510361800C9E; Mon, 2 Apr 2018 19:52:42 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w32JqcrF027616 for ; Mon, 2 Apr 2018 15:52:38 -0400 Received: by smtp.corp.redhat.com (Postfix) id CFF0A5D9CC; Mon, 2 Apr 2018 19:52:38 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C633E5D9C7; Mon, 2 Apr 2018 19:52:38 +0000 (UTC) Received: from prv3-mh.provo.novell.com (prv3-mh.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 ABD15804EB; Mon, 2 Apr 2018 19:52:37 +0000 (UTC) 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); Mon, 02 Apr 2018 13:52:31 -0600 From: Martin Wilck To: Christophe Varoqui , Benjamin Marzinski Date: Mon, 2 Apr 2018 21:50:49 +0200 Message-Id: <20180402195051.26854-19-mwilck@suse.com> In-Reply-To: <20180402195051.26854-1-mwilck@suse.com> References: <20180402195051.26854-1-mwilck@suse.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 02 Apr 2018 19:52:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 02 Apr 2018 19:52:38 +0000 (UTC) for IP:'137.65.250.26' DOMAIN:'prv3-mh.provo.novell.com' HELO:'prv3-mh.provo.novell.com' FROM:'mwilck@suse.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 137.65.250.26 prv3-mh.provo.novell.com 137.65.250.26 prv3-mh.provo.novell.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.27 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: dm-devel@redhat.com Cc: Julian Andres Klode , dm-devel@redhat.com, Martin Wilck Subject: [dm-devel] [PATCH v3 18/20] multipath -u: quick check if path is multipathed 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 02 Apr 2018 19:52:42 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP With "find_multipaths smart", we accept paths as valid if they are already part of a multipath map. This patch avoids doing a full path and device-mapper map scan for this case, speeding up "multipath -u" considerably. Signed-off-by: Martin Wilck --- libmultipath/sysfs.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libmultipath/sysfs.h | 2 ++ multipath/main.c | 14 ++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c index 97e0997..589eeaf 100644 --- a/libmultipath/sysfs.c +++ b/libmultipath/sysfs.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "checkers.h" #include "vector.h" @@ -287,3 +288,68 @@ int sysfs_check_holders(char * check_devt, char * new_devt) return 0; } + +static int select_dm_devs(const struct dirent *di) +{ + return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0; +} + +static void close_fd(void *arg) +{ + close((long)arg); +} + +bool sysfs_is_multipathed(const struct path *pp) +{ + char pathbuf[PATH_MAX]; + struct dirent **di; + int n, r, i; + bool found = false; + + n = snprintf(pathbuf, sizeof(pathbuf), "/sys/block/%s/holders", + pp->dev); + + if (n >= sizeof(pathbuf)) { + condlog(1, "%s: pathname overflow", __func__); + return false; + } + + r = scandir(pathbuf, &di, select_dm_devs, alphasort); + if (r == 0) + return false; + else if (r < 0) { + condlog(1, "%s: error scanning %s", __func__, pathbuf); + return false; + } + + pthread_cleanup_push(free, di); + for (i = 0; i < r && !found; i++) { + long fd; + int nr; + char uuid[6]; + + if (snprintf(pathbuf + n, sizeof(pathbuf) - n, + "/%s/dm/uuid", di[i]->d_name) + >= sizeof(pathbuf) - n) + continue; + + fd = open(pathbuf, O_RDONLY); + if (fd == -1) { + condlog(1, "%s: error opening %s", __func__, pathbuf); + continue; + } + + pthread_cleanup_push(close_fd, (void*)fd); + nr = read(fd, uuid, sizeof(uuid)); + if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid))) + found = true; + else if (nr < 0) { + condlog(1, "%s: error reading from %s: %s", + __func__, pathbuf, strerror(errno)); + } + pthread_cleanup_pop(1); + } + pthread_cleanup_pop(1); + + return found; +} diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h index 75c0f9c..9ae30b3 100644 --- a/libmultipath/sysfs.h +++ b/libmultipath/sysfs.h @@ -4,6 +4,7 @@ #ifndef _LIBMULTIPATH_SYSFS_H #define _LIBMULTIPATH_SYSFS_H +#include ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, const char * value, size_t value_len); @@ -13,4 +14,5 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, unsigned char * value, size_t value_len); int sysfs_get_size (struct path *pp, unsigned long long * size); int sysfs_check_holders(char * check_devt, char * new_devt); +bool sysfs_is_multipathed(const struct path *pp); #endif diff --git a/multipath/main.c b/multipath/main.c index 392d5f0..c21ee28 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -594,6 +594,15 @@ configure (struct config *conf, enum mpath_cmds cmd, !find_multipaths_on(conf) || !ignore_wwids(conf)) { goto print_valid; } + /* + * Shortcut for find_multipaths smart: + * Quick check if path is already multipathed. + */ + if (ignore_wwids(conf) && + sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) { + r = 0; + goto print_valid; + } } } @@ -666,7 +675,10 @@ configure (struct config *conf, enum mpath_cmds cmd, condlog(3, "%s: path %s is in use: %s", __func__, pp->dev, strerror(errno)); - r = 1; + /* + * Check if we raced with multipathd + */ + r = !sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)); } goto print_valid; }