Add compability flag LIBDM_API_COOKIE
[multipath-tools/.git] / kpartx / devmapper.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <libdevmapper.h>
9 #include <ctype.h>
10 #include <errno.h>
11 #include "devmapper.h"
12
13 #define UUID_PREFIX "part%d-"
14 #define MAX_PREFIX_LEN 8
15
16 #ifndef LIBDM_API_COOKIE
17 static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
18 {
19        return 1;
20 }
21 #endif
22
23 extern int
24 dm_prereq (char * str, int x, int y, int z)
25 {
26         int r = 1;
27         struct dm_task *dmt;
28         struct dm_versions *target;
29         struct dm_versions *last_target;
30
31         if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
32                 return 1;
33
34         dm_task_no_open_count(dmt);
35
36         if (!dm_task_run(dmt))
37                 goto out;
38
39         target = dm_task_get_versions(dmt);
40
41         /* Fetch targets and print 'em */
42         do {
43                 last_target = target;
44
45                 if (!strncmp(str, target->name, strlen(str)) &&
46                     /* dummy prereq on multipath version */
47                     target->version[0] >= x &&
48                     target->version[1] >= y &&
49                     target->version[2] >= z
50                    )
51                         r = 0;
52
53                 target = (void *) target + target->next;
54         } while (last_target != target);
55
56         out:
57         dm_task_destroy(dmt);
58         return r;
59 }
60
61 extern int
62 dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
63         int r = 0;
64         int udev_wait_flag = (task == DM_DEVICE_RESUME ||
65                               task == DM_DEVICE_REMOVE);
66         struct dm_task *dmt;
67
68         if (!(dmt = dm_task_create(task)))
69                 return 0;
70
71         if (!dm_task_set_name(dmt, name))
72                 goto out;
73
74         dm_task_no_open_count(dmt);
75         dm_task_skip_lockfs(dmt);
76
77         if (no_flush)
78                 dm_task_no_flush(dmt);
79
80         if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, 0))
81                 goto out;
82         r = dm_task_run(dmt);
83
84         out:
85         dm_task_destroy(dmt);
86         return r;
87 }
88
89 extern int
90 dm_addmap (int task, const char *name, const char *target,
91            const char *params, uint64_t size, int ro, const char *uuid, int part,
92            mode_t mode, uid_t uid, gid_t gid, uint32_t *cookie) {
93         int r = 0;
94         struct dm_task *dmt;
95         char *prefixed_uuid = NULL;
96
97         if (!(dmt = dm_task_create (task)))
98                 return 0;
99
100         if (!dm_task_set_name (dmt, name))
101                 goto addout;
102
103         if (!dm_task_add_target (dmt, 0, size, target, params))
104                 goto addout;
105
106         if (ro && !dm_task_set_ro (dmt))
107                         goto addout;
108
109         if (task == DM_DEVICE_CREATE && uuid) {
110                 prefixed_uuid = malloc(MAX_PREFIX_LEN + strlen(uuid) + 1);
111                 if (!prefixed_uuid) {
112                         fprintf(stderr, "cannot create prefixed uuid : %s\n",
113                                 strerror(errno));
114                         goto addout;
115                 }
116                 sprintf(prefixed_uuid, UUID_PREFIX "%s", part, uuid);
117                 if (!dm_task_set_uuid(dmt, prefixed_uuid))
118                         goto addout;
119         }
120
121         if (!dm_task_set_mode(dmt, mode))
122                 goto addout;
123         if (!dm_task_set_uid(dmt, uid))
124                 goto addout;
125         if (!dm_task_set_gid(dmt, gid))
126                 goto addout;
127
128         dm_task_no_open_count(dmt);
129
130         if (task == DM_DEVICE_CREATE && !dm_task_set_cookie(dmt, cookie, 0))
131                 goto addout;
132         r = dm_task_run (dmt);
133
134         addout:
135         dm_task_destroy (dmt);
136
137         return r;
138 }
139
140 extern int
141 dm_map_present (char * str)
142 {
143         int r = 0;
144         struct dm_task *dmt;
145         struct dm_info info;
146
147         if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
148                 return 0;
149
150         if (!dm_task_set_name(dmt, str))
151                 goto out;
152
153         dm_task_no_open_count(dmt);
154
155         if (!dm_task_run(dmt))
156                 goto out;
157
158         if (!dm_task_get_info(dmt, &info))
159                 goto out;
160
161         if (info.exists)
162                 r = 1;
163 out:
164         dm_task_destroy(dmt);
165         return r;
166 }
167
168
169 char *
170 dm_mapname(int major, int minor)
171 {
172         struct dm_task *dmt;
173         char *mapname = NULL;
174         const char *map;
175
176         if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
177                 return NULL;
178
179         dm_task_no_open_count(dmt);
180         dm_task_set_major(dmt, major);
181         dm_task_set_minor(dmt, minor);
182
183         if (!dm_task_run(dmt))
184                 goto out;
185
186         map = dm_task_get_name(dmt);
187         if (map && strlen(map))
188                 mapname = strdup(map);
189
190 out:
191         dm_task_destroy(dmt);
192         return mapname;
193 }
194
195 /*
196  * dm_get_first_dep
197  *
198  * Return the device number of the first dependend device
199  * for a given target.
200  */
201 dev_t dm_get_first_dep(char *devname)
202 {
203         struct dm_task *dmt;
204         struct dm_deps *dm_deps;
205         dev_t ret = 0;
206
207         if ((dmt = dm_task_create(DM_DEVICE_DEPS)) == NULL) {
208                 return ret;
209         }
210         if (!dm_task_set_name(dmt, devname)) {
211                 goto out;
212         }
213         if (!dm_task_run(dmt)) {
214                 goto out;
215         }
216         if ((dm_deps = dm_task_get_deps(dmt)) == NULL) {
217                 goto out;
218         }
219         if (dm_deps->count > 0) {
220                 ret = dm_deps->device[0];
221         }
222 out:
223         dm_task_destroy(dmt);
224
225         return ret;
226 }
227
228 char *
229 dm_mapuuid(int major, int minor)
230 {
231         struct dm_task *dmt;
232         const char *tmp;
233         char *uuid = NULL;
234
235         if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
236                 return NULL;
237
238         dm_task_no_open_count(dmt);
239         dm_task_set_major(dmt, major);
240         dm_task_set_minor(dmt, minor);
241
242         if (!dm_task_run(dmt))
243                 goto out;
244
245         tmp = dm_task_get_uuid(dmt);
246         if (tmp[0] != '\0')
247                 uuid = strdup(tmp);
248 out:
249         dm_task_destroy(dmt);
250         return uuid;
251 }
252
253 int
254 dm_devn (char * mapname, int *major, int *minor)
255 {
256         int r = 1;
257         struct dm_task *dmt;
258         struct dm_info info;
259
260         if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
261                 return 0;
262
263         if (!dm_task_set_name(dmt, mapname))
264                 goto out;
265
266         if (!dm_task_run(dmt))
267                 goto out;
268
269         if (!dm_task_get_info(dmt, &info))
270                 goto out;
271
272         *major = info.major;
273         *minor = info.minor;
274
275         r = 0;
276 out:
277         dm_task_destroy(dmt);
278         return r;
279 }
280