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@xxxxxxxxxxx> > Cc: Bart Van Assche <bvanassche@xxxxxxx> > Cc: Hannes Reinecke <hare@xxxxxxx> > Signed-off-by: Sebastian Riemer <sebastian.riemer@xxxxxxxxxxxxxxxx> > --- > 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); \ -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel