diff options
author | Karel Zak | 2009-09-21 13:41:10 +0200 |
---|---|---|
committer | Karel Zak | 2009-09-21 13:48:55 +0200 |
commit | 4c4d3988f65bb19e2e4265e092590373218f5180 (patch) | |
tree | 40842bd6c721fd326620eb0305697ea42af80bfa /shlibs | |
parent | libblkid: add MD topology support (for old kernels) (diff) | |
download | kernel-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.am | 3 | ||||
-rw-r--r-- | shlibs/blkid/src/topology/dm.c | 143 | ||||
-rw-r--r-- | shlibs/blkid/src/topology/topology.c | 3 | ||||
-rw-r--r-- | shlibs/blkid/src/topology/topology.h | 1 |
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 */ |