summaryrefslogtreecommitdiffstats
path: root/shlibs
diff options
context:
space:
mode:
authorKarel Zak2009-09-21 13:41:10 +0200
committerKarel Zak2009-09-21 13:48:55 +0200
commit4c4d3988f65bb19e2e4265e092590373218f5180 (patch)
tree40842bd6c721fd326620eb0305697ea42af80bfa /shlibs
parentlibblkid: add MD topology support (for old kernels) (diff)
downloadkernel-qcow2-util-linux-4c4d3988f65bb19e2e4265e092590373218f5180.tar.gz
kernel-qcow2-util-linux-4c4d3988f65bb19e2e4265e092590373218f5180.tar.xz
kernel-qcow2-util-linux-4c4d3988f65bb19e2e4265e092590373218f5180.zip
libblkid: add DM topology support (for old kernels)
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs')
-rw-r--r--shlibs/blkid/src/topology/Makefile.am3
-rw-r--r--shlibs/blkid/src/topology/dm.c143
-rw-r--r--shlibs/blkid/src/topology/topology.c3
-rw-r--r--shlibs/blkid/src/topology/topology.h1
4 files changed, 148 insertions, 2 deletions
diff --git a/shlibs/blkid/src/topology/Makefile.am b/shlibs/blkid/src/topology/Makefile.am
index 7464d2a8f..06927b287 100644
--- a/shlibs/blkid/src/topology/Makefile.am
+++ b/shlibs/blkid/src/topology/Makefile.am
@@ -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
index 000000000..138c9f4be
--- /dev/null
+++ b/shlibs/blkid/src/topology/dm.c
@@ -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
+};
+
diff --git a/shlibs/blkid/src/topology/topology.c b/shlibs/blkid/src/topology/topology.c
index adb59f129..d6132a8f3 100644
--- a/shlibs/blkid/src/topology/topology.c
+++ b/shlibs/blkid/src/topology/topology.c
@@ -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
};
diff --git a/shlibs/blkid/src/topology/topology.h b/shlibs/blkid/src/topology/topology.h
index ecebb3304..8cfcaf980 100644
--- a/shlibs/blkid/src/topology/topology.h
+++ b/shlibs/blkid/src/topology/topology.h
@@ -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 */