Linux Device Mapper development
 help / color / mirror / Atom feed
From: "Benjamin Marzinski" <bmarzins@redhat.com>
To: Martin Wilck <mwilck@suse.com>
Cc: dm-devel@redhat.com, Julian Andres Klode <julian.klode@canonical.com>
Subject: Re: [PATCH v4 18/20] multipath -u: quick check if path is multipathed
Date: Thu, 12 Apr 2018 13:46:18 -0500	[thread overview]
Message-ID: <20180412184618.GT3103@octiron.msp.redhat.com> (raw)
In-Reply-To: <20180404161627.6244-19-mwilck@suse.com>

On Wed, Apr 04, 2018 at 06:16:25PM +0200, Martin Wilck wrote:
> 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.

I feel like this supports my idea from 17/20. I really think that in
smart mode, the only time we should be claiming a device as multipath is
on an add event, if it has always been claimed (or pretend claimed) as a
multipath path, or if it is currently a multipath path. Once we have let
a uevent go by for a path without setting SYSTEMD_READY=0, anything else
is free to use it, and we simply can't safely set SYSTEMD_READY=0,
unless we know that multipathd has already grabbed the device. I feel
like checking the wwids file should give you confidence that a device
either currently is a multipath path, or has always been claimed as one.
However, this patch can fix any loop holes where a device isn't in the
wwids file, but it multipathed (I don't know of any offhand).

-Ben


> 
> Signed-off-by: Martin Wilck <mwilck@suse.com>
> ---
>  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 <string.h>
>  #include <dirent.h>
>  #include <libudev.h>
> +#include <fnmatch.h>
>  
>  #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 <stdbool.h>
>  
>  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 a60a5f3..ae46e5a 100644
> --- a/multipath/main.c
> +++ b/multipath/main.c
> @@ -595,6 +595,15 @@ configure (struct config *conf, enum mpath_cmds cmd,
>  			    !ignore_wwids_on(conf)) {
>  				goto print_valid;
>  			}
> +			/*
> +			 * Shortcut for find_multipaths smart:
> +			 * Quick check if path is already multipathed.
> +			 */
> +			if (ignore_wwids_on(conf) &&
> +			    sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) {
> +				r = 0;
> +				goto print_valid;
> +			}
>  		}
>  	}
>  
> @@ -667,7 +676,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;
>  	}
> -- 
> 2.16.1

  reply	other threads:[~2018-04-12 18:46 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-04 16:16 [PATCH v4 00/20] multipath path classification Martin Wilck
2018-04-04 16:16 ` [PATCH v4 01/20] Revert "multipath: ignore -i if find_multipaths is set" Martin Wilck
2018-04-04 16:16 ` [PATCH v4 02/20] Revert "multipathd: imply -n " Martin Wilck
2018-04-04 16:16 ` [PATCH v4 03/20] libmultipath: should_multipath: keep existing maps Martin Wilck
2018-04-04 16:16 ` [PATCH v4 04/20] multipath -u -i: respect entries in WWIDs file Martin Wilck
2018-04-04 16:16 ` [PATCH v4 05/20] libmultipath: trigger change uevent on new device creation Martin Wilck
2018-04-04 16:16 ` [PATCH v4 06/20] libmultipath: trigger path uevent only when necessary Martin Wilck
2018-04-04 16:16 ` [PATCH v4 07/20] libmultipath: change find_multipaths option to multi-value Martin Wilck
2018-04-12 18:32   ` Benjamin Marzinski
2018-04-13 18:23   ` Martin Wilck
2018-04-04 16:16 ` [PATCH v4 08/20] libmultipath: use const char* in open_file() Martin Wilck
2018-04-04 16:16 ` [PATCH v4 09/20] libmultipath: functions to indicate mapping failure in /dev/shm Martin Wilck
2018-04-12 18:33   ` Benjamin Marzinski
2018-04-12 20:07     ` Martin Wilck
2018-04-12 21:27       ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 10/20] libmultipath: indicate wwid failure in dm_addmap_create() Martin Wilck
2018-04-12 18:33   ` Benjamin Marzinski
2018-04-12 20:16     ` Martin Wilck
2018-04-12 20:22       ` Martin Wilck
2018-04-12 21:32         ` Benjamin Marzinski
2018-04-12 22:43           ` Martin Wilck
2018-04-04 16:16 ` [PATCH v4 11/20] multipath -u: common code path for result message Martin Wilck
2018-04-12 18:34   ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 12/20] multipath -u: change output to environment/key format Martin Wilck
2018-04-12 18:35   ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 13/20] multipath -u: treat failed wwids as invalid Martin Wilck
2018-04-12 18:35   ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 14/20] multipath -u: add DM_MULTIPATH_DEVICE_PATH=2 for "maybe" Martin Wilck
2018-04-04 16:16 ` [PATCH v4 15/20] libmultipath: implement find_multipaths_timeout Martin Wilck
2018-04-12 18:35   ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 16/20] multipath -u : set FIND_MULTIPATHS_WAIT_UNTIL from /dev/shm Martin Wilck
2018-04-12 18:36   ` Benjamin Marzinski
2018-04-12 20:35     ` Martin Wilck
2018-04-12 21:35       ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 18/20] multipath -u: quick check if path is multipathed Martin Wilck
2018-04-12 18:46   ` Benjamin Marzinski [this message]
2018-04-12 22:19     ` Martin Wilck
2018-04-13 16:12       ` Benjamin Marzinski
2018-04-13 17:59         ` Martin Wilck
2018-04-04 16:16 ` [PATCH v4 19/20] libmultipath: enable find_multipaths "smart" Martin Wilck
2018-04-12 18:47   ` Benjamin Marzinski
2018-04-12 22:27     ` Martin Wilck
2018-04-13 15:59       ` Benjamin Marzinski
2018-04-04 16:16 ` [PATCH v4 20/20] multipath.rules: find_multipaths "smart" logic Martin Wilck
2018-04-12 18:48   ` Benjamin Marzinski
2018-04-13 16:01     ` Benjamin Marzinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180412184618.GT3103@octiron.msp.redhat.com \
    --to=bmarzins@redhat.com \
    --cc=dm-devel@redhat.com \
    --cc=julian.klode@canonical.com \
    --cc=mwilck@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox