blob: 72ec9bd8e25f6fa4e65ac73c5e7d7c7c30c1eea3 [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) {
60 DBG(DEBUG_LOWPROBE,
61 printf("Failed to open pipe: errno=%d", errno));
62 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
95 DBG(DEBUG_LOWPROBE,
96 printf("Failed to execute %s: errno=%d", cmd, errno));
97 exit(1);
98 }
99 case -1:
100 DBG(DEBUG_LOWPROBE,
101 printf("Failed to forking: errno=%d", errno));
102 goto nothing;
103 default:
104 break;
105 }
106
107 stream = fdopen(dmpipe[0], "r");
108 if (!stream)
109 goto nothing;
110
111 if (fscanf(stream, "%lld %lld striped %d %d ",
112 &offset, &size, &stripes, &stripesize) != 0)
113 goto nothing;
114
115 blkid_topology_set_minimum_io_size(pr, stripesize << 9);
116 blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);
117
118 fclose(stream);
119 close(dmpipe[1]);
120 return 0;
121
122nothing:
123 if (stream)
124 fclose(stream);
125 else if (dmpipe[0] != -1)
126 close(dmpipe[0]);
127 if (dmpipe[1] != -1)
128 close(dmpipe[1]);
129 return 1;
130}
131
132const struct blkid_idinfo dm_tp_idinfo =
133{
134 .name = "dm",
135 .probefunc = probe_dm_tp,
136 .magics = BLKID_NONE_MAGIC
137};
138