blob: 6add2f7aeafeafe7a5926d1a03df2522cb77c1d8 [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>
Ethan Yonkerfefe5912017-09-30 22:22:13 -050019#include <sys/sysmacros.h>
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050020#include <sys/types.h>
21#include <unistd.h>
22
23#include "topology.h"
24
25static int is_dm_device(dev_t devno)
26{
27 return blkid_driver_has_major("device-mapper", major(devno));
28}
29
30static int probe_dm_tp(blkid_probe pr,
31 const struct blkid_idmag *mag __attribute__((__unused__)))
32{
33 const char *paths[] = {
34 "/usr/local/sbin/dmsetup",
35 "/usr/sbin/dmsetup",
36 "/sbin/dmsetup"
37 };
38 int dmpipe[] = { -1, -1 }, stripes, stripesize;
39 char *cmd = NULL;
40 FILE *stream = NULL;
41 long long offset, size;
42 size_t i;
43 dev_t devno = blkid_probe_get_devno(pr);
44
45 if (!devno)
46 goto nothing; /* probably not a block device */
47 if (!is_dm_device(devno))
48 goto nothing;
49
50 for (i = 0; i < ARRAY_SIZE(paths); i++) {
51 struct stat sb;
52 if (stat(paths[i], &sb) == 0) {
53 cmd = (char *) paths[i];
54 break;
55 }
56 }
57
58 if (!cmd)
59 goto nothing;
60 if (pipe(dmpipe) < 0) {
bigbiff7b4c7a62015-01-01 19:44:14 -050061 DBG(LOWPROBE, ul_debug("Failed to open pipe: errno=%d", errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050062 goto nothing;
63 }
64
65 switch (fork()) {
66 case 0:
67 {
68 char *dmargv[7], maj[16], min[16];
69
70 /* Plumbing */
71 close(dmpipe[0]);
72
73 if (dmpipe[1] != STDOUT_FILENO)
74 dup2(dmpipe[1], STDOUT_FILENO);
75
76 /* The libblkid library could linked with setuid programs */
77 if (setgid(getgid()) < 0)
78 exit(1);
79 if (setuid(getuid()) < 0)
80 exit(1);
81
82 snprintf(maj, sizeof(maj), "%d", major(devno));
83 snprintf(min, sizeof(min), "%d", minor(devno));
84
85 dmargv[0] = cmd;
86 dmargv[1] = "table";
87 dmargv[2] = "-j";
88 dmargv[3] = maj;
89 dmargv[4] = "-m";
90 dmargv[5] = min;
91 dmargv[6] = NULL;
92
93 execv(dmargv[0], dmargv);
94
bigbiff7b4c7a62015-01-01 19:44:14 -050095 DBG(LOWPROBE, ul_debug("Failed to execute %s: errno=%d", cmd, errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050096 exit(1);
97 }
98 case -1:
bigbiff7b4c7a62015-01-01 19:44:14 -050099 DBG(LOWPROBE, ul_debug("Failed to forking: errno=%d", errno));
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500100 goto nothing;
101 default:
102 break;
103 }
104
bigbiff7b4c7a62015-01-01 19:44:14 -0500105 stream = fdopen(dmpipe[0], "r" UL_CLOEXECSTR);
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500106 if (!stream)
107 goto nothing;
108
109 if (fscanf(stream, "%lld %lld striped %d %d ",
110 &offset, &size, &stripes, &stripesize) != 0)
111 goto nothing;
112
113 blkid_topology_set_minimum_io_size(pr, stripesize << 9);
114 blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);
115
116 fclose(stream);
117 close(dmpipe[1]);
118 return 0;
119
120nothing:
121 if (stream)
122 fclose(stream);
123 else if (dmpipe[0] != -1)
124 close(dmpipe[0]);
125 if (dmpipe[1] != -1)
126 close(dmpipe[1]);
127 return 1;
128}
129
130const struct blkid_idinfo dm_tp_idinfo =
131{
132 .name = "dm",
133 .probefunc = probe_dm_tp,
134 .magics = BLKID_NONE_MAGIC
135};
136