blob: e061632cadd507d55dc6b540e36d34e53c3cb5c5 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * device-mapper (dm) topology
3 * -- this is fallback for old systems where the topology information is not
4 * exported by sysfs
5 *
6 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
7 *
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 *
11 */
12#include <errno.h>
13#include <fcntl.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <sys/stat.h>
19#include <sys/types.h>
20#include <unistd.h>
21
22#include "topology.h"
23
24static int is_dm_device(dev_t devno)
25{
26 return blkid_driver_has_major("device-mapper", major(devno));
27}
28
29static int probe_dm_tp(blkid_probe pr,
30 const struct blkid_idmag *mag __attribute__((__unused__)))
31{
32 const char *paths[] = {
33 "/usr/local/sbin/dmsetup",
34 "/usr/sbin/dmsetup",
35 "/sbin/dmsetup"
36 };
37 int dmpipe[] = { -1, -1 }, stripes, stripesize;
38 char *cmd = NULL;
39 FILE *stream = NULL;
40 long long offset, size;
41 size_t i;
42 dev_t devno = blkid_probe_get_devno(pr);
43
44 if (!devno)
45 goto nothing; /* probably not a block device */
46 if (!is_dm_device(devno))
47 goto nothing;
48
49 for (i = 0; i < ARRAY_SIZE(paths); i++) {
50 struct stat sb;
51 if (stat(paths[i], &sb) == 0) {
52 cmd = (char *) paths[i];
53 break;
54 }
55 }
56
57 if (!cmd)
58 goto nothing;
59 if (pipe(dmpipe) < 0) {
bigbiff7b4c7a62015-01-01 19:44:14 -050060 DBG(LOWPROBE, ul_debug("Failed to open pipe: errno=%d", errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050061 goto nothing;
62 }
63
64 switch (fork()) {
65 case 0:
66 {
67 char *dmargv[7], maj[16], min[16];
68
69 /* Plumbing */
70 close(dmpipe[0]);
71
72 if (dmpipe[1] != STDOUT_FILENO)
73 dup2(dmpipe[1], STDOUT_FILENO);
74
75 /* The libblkid library could linked with setuid programs */
76 if (setgid(getgid()) < 0)
77 exit(1);
78 if (setuid(getuid()) < 0)
79 exit(1);
80
81 snprintf(maj, sizeof(maj), "%d", major(devno));
82 snprintf(min, sizeof(min), "%d", minor(devno));
83
84 dmargv[0] = cmd;
85 dmargv[1] = "table";
86 dmargv[2] = "-j";
87 dmargv[3] = maj;
88 dmargv[4] = "-m";
89 dmargv[5] = min;
90 dmargv[6] = NULL;
91
92 execv(dmargv[0], dmargv);
93
bigbiff7b4c7a62015-01-01 19:44:14 -050094 DBG(LOWPROBE, ul_debug("Failed to execute %s: errno=%d", cmd, errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050095 exit(1);
96 }
97 case -1:
bigbiff7b4c7a62015-01-01 19:44:14 -050098 DBG(LOWPROBE, ul_debug("Failed to forking: errno=%d", errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050099 goto nothing;
100 default:
101 break;
102 }
103
bigbiff7b4c7a62015-01-01 19:44:14 -0500104 stream = fdopen(dmpipe[0], "r" UL_CLOEXECSTR);
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500105 if (!stream)
106 goto nothing;
107
108 if (fscanf(stream, "%lld %lld striped %d %d ",
109 &offset, &size, &stripes, &stripesize) != 0)
110 goto nothing;
111
112 blkid_topology_set_minimum_io_size(pr, stripesize << 9);
113 blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);
114
115 fclose(stream);
116 close(dmpipe[1]);
117 return 0;
118
119nothing:
120 if (stream)
121 fclose(stream);
122 else if (dmpipe[0] != -1)
123 close(dmpipe[0]);
124 if (dmpipe[1] != -1)
125 close(dmpipe[1]);
126 return 1;
127}
128
129const struct blkid_idinfo dm_tp_idinfo =
130{
131 .name = "dm",
132 .probefunc = probe_dm_tp,
133 .magics = BLKID_NONE_MAGIC
134};
135