[dm-devel] [PATCH] libmultipath/discovery: read sysfs files uncached

Christophe Varoqui christophe.varoqui at gmail.com
Tue Apr 2 21:00:48 UTC 2013


On mar., 2013-04-02 at 16:28 +0200, Sebastian Riemer wrote:
> The libudev function udev_device_get_sysattr_value() reads sysfs
> attributes cached. This is useless for checking a device state.
> There we want to see if it changes.
> 
> Unfortunately, libudev doesn't provide an uncached variant. This
> is why we have to reimplement the functionality and some libudev
> internal functions here.
> 
Hannes,

as the commit 058a0044cb2ab7cac6f7c3e2e17b16e00b5e57fa author, would you
sign-off this patch ? Or do you prefer the issue addressed on the udev
side ...

Best regards,
Christophe Varoqui
www.opensvc.com


> Cc: Christophe Varoqui <christophe.varoqui at opensvc.com>
> Cc: Bart Van Assche <bvanassche at acm.org>
> Cc: Hannes Reinecke <hare at suse.de>
> Signed-off-by: Sebastian Riemer <sebastian.riemer at profitbricks.com>
> ---
>  libmultipath/discovery.c |   78 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
> index 0b5fd1d..1cb1f15 100644
> --- a/libmultipath/discovery.c
> +++ b/libmultipath/discovery.c
> @@ -132,6 +132,82 @@ path_discovery (vector pathvec, struct config * conf, int flag)
>  	return r;
>  }
>  
> +/* helpers for get_udev_device_sysattr_value() */
> +static size_t
> +strpcpy(char **dest, size_t size, const char *src)
> +{
> +	size_t len;
> +
> +	len = strlen(src);
> +	if (len >= size) {
> +		if (size > 1)
> +			*dest = mempcpy(*dest, src, size-1);
> +		size = 0;
> +	} else {
> +		if (len > 0) {
> +			*dest = mempcpy(*dest, src, len);
> +			size -= len;
> +		}
> +	}
> +	*dest[0] = '\0';
> +	return size;
> +}
> +
> +static size_t
> +strscpyl(char *dest, size_t size, const char *src, ...)
> +{
> +	va_list va;
> +	char *s;
> +
> +	va_start(va, src);
> +	s = dest;
> +	do {
> +		size = strpcpy(&s, size, src);
> +		src = va_arg(va, char *);
> +	} while (src != NULL);
> +	va_end(va);
> +
> +	return size;
> +}
> +
> +static void
> +util_remove_trailing_chars(char *path, char c)
> +{
> +	size_t len;
> +
> +	if (path == NULL)
> +		return;
> +	len = strlen(path);
> +	while (len > 0 && path[len-1] == c)
> +		path[--len] = '\0';
> +}
> +
> +/* like udev_device_get_sysattr_value() but uncached */
> +static const char *
> +get_udev_device_sysattr_value(struct udev_device *udev,
> +			      const char *sysattr)
> +{
> +	const char *val = NULL;
> +	char path[1024];
> +	char value[4096];
> +	int fd;
> +	ssize_t size;
> +
> +	strscpyl(path, sizeof(path), udev_device_get_syspath(udev),
> +		 "/", sysattr, NULL);
> +	fd = open(path, O_RDONLY|O_CLOEXEC);
> +	if (fd >= 0) {
> +		size = read(fd, value, sizeof(value));
> +		close(fd);
> +		if (size >= 0 && size < sizeof(value)) {
> +			value[size] = '\0';
> +			util_remove_trailing_chars(value, '\n');
> +			val = value;
> +		}
> +	}
> +	return val;
> +}
> +
>  #define declare_sysfs_get_str(fname)					\
>  extern int								\
>  sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len)	\
> @@ -141,7 +217,7 @@ sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len)	\
>  									\
>  	devname = udev_device_get_sysname(udev);			\
>  									\
> -	attr = udev_device_get_sysattr_value(udev, #fname);		\
> +	attr = get_udev_device_sysattr_value(udev, #fname);		\
>  	if (!attr) {							\
>  		condlog(3, "%s: attribute %s not found in sysfs",	\
>  			devname, #fname);				\





More information about the dm-devel mailing list