]> err.no Git - util-linux/commitdiff
libblkid: add DM topology support (for old kernels)
authorKarel Zak <kzak@redhat.com>
Mon, 21 Sep 2009 11:41:10 +0000 (13:41 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 21 Sep 2009 11:48:55 +0000 (13:48 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/blkid/src/topology/Makefile.am
shlibs/blkid/src/topology/dm.c [new file with mode: 0644]
shlibs/blkid/src/topology/topology.c
shlibs/blkid/src/topology/topology.h

index 7464d2a8f1c8a1b27d8bf2b009a2d09416ee5068..06927b28769abe507f9035c0b9a4e63edb32d28f 100644 (file)
@@ -7,4 +7,5 @@ noinst_LTLIBRARIES = libblkid_topology.la
 libblkid_topology_la_SOURCES = topology.c \
                                topology.h \
                                sysfs.c \
-                               md.c
+                               md.c \
+                               dm.c
diff --git a/shlibs/blkid/src/topology/dm.c b/shlibs/blkid/src/topology/dm.c
new file mode 100644 (file)
index 0000000..138c9f4
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * device-mapper (dm) topology
+ * -- this is fallback for old systems where the toplogy information are not
+ *    exported by sysfs
+ *
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "topology.h"
+
+
+static int is_dm_device(dev_t devno)
+{
+       if (blkid_driver_has_major("device-mapper", major(devno)))
+               return 1;
+       return 0;
+}
+
+static int probe_dm_tp(blkid_probe pr, const struct blkid_idmag *mag)
+{
+       const char *paths[] = {
+               "/usr/local/sbin/dmsetup",
+               "/usr/sbin/dmsetup",
+               "/sbin/dmsetup"
+       };
+       int i, dmpipe[] = { -1, -1 }, stripes, stripesize;
+       char *cmd = NULL;
+       FILE *stream;
+       long long  offset, size;
+       dev_t devno = blkid_probe_get_devno(pr);
+
+       if (!devno)
+               goto nothing;           /* probably not a block device */
+       if (!is_dm_device(devno))
+               goto nothing;
+
+       for (i = 0; i < ARRAY_SIZE(paths); i++) {
+               struct stat sb;
+               if (stat(paths[i], &sb) == 0) {
+                       cmd = (char *) paths[i];
+                       break;
+               }
+       }
+
+       if (!cmd)
+               goto nothing;
+       if (pipe(dmpipe) < 0) {
+               DBG(DEBUG_LOWPROBE,
+                       printf("Failed to open pipe: errno=%d", errno));
+               goto nothing;
+       }
+
+       switch (fork()) {
+       case 0:
+       {
+               char *dmargv[7], maj[16], min[16];
+
+               /* Plumbing */
+               close(dmpipe[0]);
+
+               if (dmpipe[1] != STDOUT_FILENO)
+                       dup2(dmpipe[1], STDOUT_FILENO);
+
+               /* The libblkid library could linked with setuid programs */
+               if (setgid(getgid()) < 0)
+                        exit(1);
+               if (setuid(getuid()) < 0)
+                        exit(1);
+
+               snprintf(maj, sizeof(maj), "%d", major(devno));
+               snprintf(min, sizeof(min), "%d", minor(devno));
+
+               dmargv[0] = cmd;
+               dmargv[1] = "table";
+               dmargv[2] = "-j";
+               dmargv[3] = maj;
+               dmargv[4] = "-m";
+               dmargv[5] = min;
+               dmargv[6] = NULL;
+
+               execv(dmargv[0], dmargv);
+
+               DBG(DEBUG_LOWPROBE,
+                       printf("Failed to execute %s: errno=%d", cmd, errno));
+               exit(1);
+       }
+       case -1:
+               DBG(DEBUG_LOWPROBE,
+                       printf("Failed to forking: errno=%d", errno));
+               goto nothing;
+       default:
+               break;
+       }
+
+       close(dmpipe[1]);
+       dmpipe[1] = -1;
+
+       stream = fdopen(dmpipe[0], "r");
+       if (!stream)
+               goto nothing;
+
+       i = fscanf(stream, "%lld %lld striped %d %d ",
+                       &offset, &size, &stripes, &stripesize);
+       fclose(stream);
+       dmpipe[0] = -1;
+
+       if (i != 4)
+               goto nothing;
+
+       blkid_topology_set_minimum_io_size(pr, stripesize << 9);
+       blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);
+
+       return 0;
+
+nothing:
+       if (dmpipe[0] != -1)
+               close(dmpipe[0]);
+       if (dmpipe[1] != -1)
+               close(dmpipe[1]);
+       return 1;
+}
+
+const struct blkid_idinfo dm_tp_idinfo =
+{
+       .name           = "dm",
+       .probefunc      = probe_dm_tp,
+       .magics         = BLKID_NONE_MAGIC
+};
+
index adb59f12944a7c37a919fe36fb8ab67506345854..d6132a8f3d49c186018fba1879e5a8f8a6c9bf99 100644 (file)
@@ -60,7 +60,8 @@ struct blkid_struct_topology {
 static const struct blkid_idinfo *idinfos[] =
 {
        &sysfs_tp_idinfo,
-       &md_tp_idinfo
+       &md_tp_idinfo,
+       &dm_tp_idinfo
 };
 
 
index ecebb33044d396fd4fbf71a39abbe2f2c9e0a761..8cfcaf9808218756143c62bcc5dbe9701ca7061d 100644 (file)
@@ -12,6 +12,7 @@ extern int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val)
  */
 extern const struct blkid_idinfo sysfs_tp_idinfo;
 extern const struct blkid_idinfo md_tp_idinfo;
+extern const struct blkid_idinfo dm_tp_idinfo;
 
 #endif /* BLKID_TOPOLOGY_H */