lvm - use libdevattr for device cache checks
authorAlex Hornung <ahornung@gmail.com>
Sat, 10 Jul 2010 21:59:41 +0000 (22:59 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sun, 11 Jul 2010 21:05:57 +0000 (22:05 +0100)
* Improve the device checking of devices that go into that cache and
  that don't by using libdevattr and the tagged stuff.

contrib/lvm2/dist/lib/device/dev-cache.c
contrib/lvm2/dist/lib/dragonfly/dev.c [new file with mode: 0644]
gnu/lib/liblvm/Makefile
gnu/sbin/lvm/Makefile

index 6bedb29..403ae21 100644 (file)
@@ -404,6 +404,10 @@ static int _insert_file(const char *path)
        return 1;
 }
 
+#if defined(__DragonFly__)
+int dragonfly_check_dev(int major, const char *path);
+#endif
+
 static int _insert(const char *path, int rec)
 {
        struct stat info;
@@ -449,47 +453,11 @@ static int _insert(const char *path, int rec)
                /*
                 * This never happens, but oh well...
                 */
-               if (S_ISBLK(info.st_mode)) {
-                       log_debug("%s: Not a raw device", path);
-                       return_0;
-               }
-
-               /*
-                * We avoid adding devctl to the cache because reading from it
-                * locks lvm up. devctl doesn't seem to be caught later in the
-                * filter because it has major number 0, and lvm seems to assume
-                * dm also has major 0.
-                */
-               if (!strcmp(path, "/dev/devctl")) {
-                       log_debug("%s: It's devctl, no interest");
-                       return_0;
-               }
-
-               if (!strncmp(path, "/dev/tun", strlen("/dev/tun"))) {
-                       log_debug("%s: Not adding tun devices");
+               if (dragonfly_check_dev(MAJOR(info.st_rdev),path) < 0) {
+                       log_debug("%s: Device not added to cache", path);
                        return_0;
                }
 
-               if (!strncmp(path, "/dev/cd", strlen("/dev/cd")) ||
-                   !strncmp(path, "/dev/acd", strlen("/dev/acd"))) {
-                       log_debug("%s: Not adding CD drives");
-                       return_0;
-               }
-
-               if (!strcmp(path, "/dev/vn")) {
-                       log_debug("%s: Not adding vn autoclone dev");
-                       return_0;
-               }
-
-               if (!strncmp(path, "/dev/md", strlen("/dev/md"))) {
-                       log_debug("%s: Not adding malloc disks");
-                       return_0;
-               }
-
-               if (!strncmp(path, "/dev/fd", strlen("/dev/fd"))) {
-                       log_debug("%s: Not adding floppy disks or fds");
-                       return_0;
-               }
 #else
                if (!S_ISBLK(info.st_mode))
                        log_debug("%s: Not a block device", path);
diff --git a/contrib/lvm2/dist/lib/dragonfly/dev.c b/contrib/lvm2/dist/lib/dragonfly/dev.c
new file mode 100644 (file)
index 0000000..93eedeb
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * DragonFly specific device routines are added to this file.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/sysctl.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <devattr.h>
+
+
+#define LVM_FAILURE -1
+
+
+int
+dragonfly_check_dev(int major, const char *path)
+{
+       struct udev *udev;
+       struct udev_enumerate *udev_enum;
+       struct udev_list_entry *udev_le, *udev_le_first;
+       struct udev_monitor *udev_monitor;
+       struct udev_device *udev_dev;
+       const char *subsystem;
+       const char *driver;
+       const char *type;
+       int ret, result;
+
+       result = LVM_FAILURE;
+
+       if (!strncmp(path, "/dev/", strlen("/dev/"))) {
+               path += strlen("/dev/");
+       }
+
+       udev = udev_new();
+       if (udev == NULL) {
+               fprintf(stderr, "udev_new failed! Need udevd running.\n");
+               return LVM_FAILURE;
+       }
+
+       udev_enum = udev_enumerate_new(udev);
+       if (udev_enum == NULL) {
+               fprintf(stderr, "udev_enumerate_new failed!\n");
+               goto out2;
+       }
+
+       ret = udev_enumerate_add_match_expr(udev_enum, "name", __DECONST(char *, path));
+       if (ret != 0) {
+               fprintf(stderr, "udev_enumerate_add_match_expr failed!\n");
+               goto out;
+       }
+
+       ret = udev_enumerate_scan_devices(udev_enum);
+       if (ret != 0) {
+               fprintf(stderr, "udev_enumerate_scan_devices failed!\n");
+               goto out;
+       }
+
+       udev_le = udev_enumerate_get_list_entry(udev_enum);
+       if (udev_le == NULL) {
+#if 0
+               fprintf(stderr, "udev_enumerate_get_list_entry failed for %s!\n", path);
+#endif
+               goto out;
+       }
+
+       udev_dev = udev_list_entry_get_device(udev_le);
+       if (udev_dev == NULL) {
+               fprintf(stderr, "udev_list_entry_get_device failed!\n");
+               goto out;
+       }
+
+       subsystem = udev_device_get_subsystem(udev_dev);
+       driver = udev_device_get_driver(udev_dev);
+       type = udev_device_get_property_value(udev_dev, "disk-type");
+
+       /* If it's neither a disk driver nor a raid driver, stop here */
+       if ((subsystem == NULL) ||
+           ((strcmp(subsystem, "disk") != 0) &&
+           (strcmp(subsystem, "raid") != 0))) {
+               goto outdev;
+       }
+
+       /* We don't like malloc disks */
+       if (driver && (strcmp(driver, "md") == 0)) {
+               goto outdev;
+       }
+
+       /* Some disk-type checks... */
+       if (type && (strcmp(type, "optical") == 0)) {
+               goto outdev;
+       }
+
+       /* Some disk-type checks... */
+       if (type && (strcmp(type, "floppy") == 0)) {
+               goto outdev;
+       }
+
+       /* Some disk-type checks... */
+       if (type && (strcmp(type, "tape") == 0)) {
+               goto outdev;
+       }
+
+       /* Some disk-type checks... */
+       if (type && (strcmp(type, "memory") == 0)) {
+               goto outdev;
+       }
+
+       result = 0;
+
+outdev:
+       udev_device_unref(udev_dev);
+out:
+       udev_enumerate_unref(udev_enum);
+out2:
+       udev_unref(udev);
+       return result;
+}
+
+/*
+udev_enumerate_get_list_entry failed for bpf4 (/dev/bpf4)!
+udev_enumerate_get_list_entry failed for log (/dev/log)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001 (/dev/serno/00000000000000000001)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0 (/dev/serno/00000000000000000001.s0)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0a (/dev/serno/00000000000000000001.s0a)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0b (/dev/serno/00000000000000000001.s0b)!
+udev_enumerate_get_list_entry failed for serno/01000000000000000001 (/dev/serno/01000000000000000001)!
+udev_enumerate_get_list_entry failed for sga (/dev/sga)!
+udev_enumerate_get_list_entry failed for sgb (/dev/sgb)!
+udev_enumerate_get_list_entry failed for bpf4 (/dev/bpf4)!
+udev_enumerate_get_list_entry failed for log (/dev/log)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001 (/dev/serno/00000000000000000001)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0 (/dev/serno/00000000000000000001.s0)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0a (/dev/serno/00000000000000000001.s0a)!
+udev_enumerate_get_list_entry failed for serno/00000000000000000001.s0b (/dev/serno/00000000000000000001.s0b)!
+udev_enumerate_get_list_entry failed for serno/01000000000000000001 (/dev/serno/01000000000000000001)!
+udev_enumerate_get_list_entry failed for sga (/dev/sga)!
+udev_enumerate_get_list_entry failed for sgb (/dev/sgb)!
+*/
index 3cdff99..61407d3 100644 (file)
@@ -35,9 +35,9 @@ SRCS+=                activate.c lvmcache.c toolcontext.c config.c btree.c \
                import-extents.c layout.c lvm1-label.c vg_number.c \
                disk_rep.c format_pool.c import_export.c pool_label.c \
                filter_dragonfly.c snapshot.c mirrored.c dev_manager.c fs.c \
-               lvm-globals.c
+               lvm-globals.c dev.c
 
-LDADD+=                -lprop
+LDADD+=                -lprop -ldevattr
 
 .PATH: ${LVM2_DISTDIR}/lib/
 .PATH: ${LVM2_DISTDIR}/lib/activate
@@ -66,7 +66,7 @@ LDADD+=               -lprop
 .PATH: ${LVM2_DISTDIR}/lib/unknown
 .PATH: ${LVM2_DISTDIR}/lib/uuid
 .PATH: ${LVM2_DISTDIR}/lib/zero
-.PATH: ${LVM2_DISTDIR}/lib/netbsd
+.PATH: ${LVM2_DISTDIR}/lib/dragonfly
 
 .include <bsd.lib.mk>
 #.include <bsd.subdir.mk>
index 84a3c4c..0f30a2e 100644 (file)
@@ -137,7 +137,7 @@ DPADD+=         ${.CURDIR}/../../lib/liblvm/liblvm.a
 LDADD+=         -L${.CURDIR}/../../lib/libdevmapper -ldevmapper
 DPADD+=         ${.CURDIR}/../../lib/libdevmapper/libdevmapper.a
 
-LDADD+=                -lprop -ledit -ltermcap
+LDADD+=                -lprop -ledit -ltermcap -ldevattr
 
 .PATH: ${LVM2_DISTDIR}/tools