| @@ -1,580 +1,579 @@ | | | @@ -1,580 +1,579 @@ |
1 | /* | | 1 | /* |
2 | * Copyright (c) 2010 The NetBSD Foundation, Inc. | | 2 | * Copyright (c) 2010 The NetBSD Foundation, Inc. |
3 | * All rights reserved. | | 3 | * All rights reserved. |
4 | * | | 4 | * |
5 | * This code is derived from software contributed to The NetBSD Foundation | | 5 | * This code is derived from software contributed to The NetBSD Foundation |
6 | * by Adam Hamsik. | | 6 | * by Adam Hamsik. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * | | 16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | * POSSIBILITY OF SUCH DAMAGE. | | 27 | * POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/types.h> | | 30 | #include <sys/types.h> |
31 | #include <sys/param.h> | | 31 | #include <sys/param.h> |
32 | | | 32 | |
33 | #include <ctype.h> | | 33 | #include <ctype.h> |
34 | #include <err.h> | | 34 | #include <err.h> |
35 | #include <errno.h> | | 35 | #include <errno.h> |
36 | #include <stdio.h> | | 36 | #include <stdio.h> |
37 | #include <stdlib.h> | | 37 | #include <stdlib.h> |
38 | #include <string.h> | | 38 | #include <string.h> |
39 | | | 39 | |
40 | #include <prop/proplib.h> | | 40 | #include <prop/proplib.h> |
41 | | | 41 | |
42 | #include <dm.h> | | 42 | #include <dm.h> |
43 | | | 43 | |
44 | #ifdef RUMP_ACTION | | 44 | #ifdef RUMP_ACTION |
45 | #include <rump/rump.h> | | 45 | #include <rump/rump.h> |
46 | #include <rump/rumpclient.h> | | 46 | #include <rump/rumpclient.h> |
47 | #include <rump/rump_syscalls.h> | | 47 | #include <rump/rump_syscalls.h> |
48 | #endif | | 48 | #endif |
49 | | | 49 | |
50 | /* dmctl command is used to communicate with device-mapper driver in NetBSD | | 50 | /* dmctl command is used to communicate with device-mapper driver in NetBSD |
51 | * it uses libdm library to create and send required data to kernel. | | 51 | * it uses libdm library to create and send required data to kernel. |
52 | * | | 52 | * |
53 | * Main purpose of dmctl is to add posibility to use device-mapper driver | | 53 | * Main purpose of dmctl is to add posibility to use device-mapper driver |
54 | * from outside of LVM scope. | | 54 | * from outside of LVM scope. |
55 | */ | | 55 | */ |
56 | | | 56 | |
57 | #define DMCTL_CMD_REQ_NODEVNAME 0 /* Command do not require device name */ | | 57 | #define DMCTL_CMD_REQ_NODEVNAME 0 /* Command do not require device name */ |
58 | #define DMCTL_CMD_REQ_DEVNAME 1 /* Command require device name to work */ | | 58 | #define DMCTL_CMD_REQ_DEVNAME 1 /* Command require device name to work */ |
59 | #define DMCTL_CMD_REQ_NEWNAME 2 /* Command require device name and | | 59 | #define DMCTL_CMD_REQ_NEWNAME 2 /* Command require device name and |
60 | newname to work */ | | 60 | newname to work */ |
61 | struct command { | | 61 | struct command { |
62 | const char *cmd_name; | | 62 | const char *cmd_name; |
63 | const char *cmd_help; | | 63 | const char *cmd_help; |
64 | const char *ioctl_cmd_name; | | 64 | const char *ioctl_cmd_name; |
65 | int min_args; | | 65 | int min_args; |
66 | int (*cmd_func)(int, char *[], libdm_task_t); | | 66 | int (*cmd_func)(int, char *[], libdm_task_t); |
67 | }; | | 67 | }; |
68 | | | 68 | |
69 | int fd; /* file descriptor for device */ | | 69 | static const char *dvname; /* device name */ |
70 | const char *dvname; /* device name */ | | 70 | static const char *cmdname; /* command user issued */ |
71 | const char *cmdname; /* command user issued */ | | | |
72 | | | 71 | |
73 | static char * parse_stdin(char *); | | 72 | static char * parse_stdin(char *); |
74 | | | 73 | |
75 | static int dmctl_get_version(int, char *[], libdm_task_t); | | 74 | static int dmctl_get_version(int, char *[], libdm_task_t); |
76 | static int dmctl_get_targets(int, char *[], libdm_task_t); | | 75 | static int dmctl_get_targets(int, char *[], libdm_task_t); |
77 | static int dmctl_get_device_info(int, char *[], libdm_task_t); | | 76 | static int dmctl_get_device_info(int, char *[], libdm_task_t); |
78 | static int dmctl_create_dev(int, char *[], libdm_task_t); | | 77 | static int dmctl_create_dev(int, char *[], libdm_task_t); |
79 | static int dmctl_dev_rename(int, char *[], libdm_task_t); | | 78 | static int dmctl_dev_rename(int, char *[], libdm_task_t); |
80 | static int dmctl_dev_remove(int, char *[], libdm_task_t); | | 79 | static int dmctl_dev_remove(int, char *[], libdm_task_t); |
81 | static int dmctl_dev_resume(int, char *[], libdm_task_t); | | 80 | static int dmctl_dev_resume(int, char *[], libdm_task_t); |
82 | static int dmctl_dev_suspend(int, char *[], libdm_task_t); | | 81 | static int dmctl_dev_suspend(int, char *[], libdm_task_t); |
83 | static int dmctl_dev_deps(int, char *[], libdm_task_t); | | 82 | static int dmctl_dev_deps(int, char *[], libdm_task_t); |
84 | static int dmctl_list_devices(int, char *[], libdm_task_t); | | 83 | static int dmctl_list_devices(int, char *[], libdm_task_t); |
85 | static int dmctl_table_reload(int, char *[], libdm_task_t); | | 84 | static int dmctl_table_reload(int, char *[], libdm_task_t); |
86 | static int dmctl_table_status(int, char *[], libdm_task_t); | | 85 | static int dmctl_table_status(int, char *[], libdm_task_t); |
87 | void usage(void); | | 86 | __dead static void usage(void); |
88 | | | 87 | |
89 | struct command commands[] = { | | 88 | static struct command commands[] = { |
90 | { "version", | | 89 | { "version", |
91 | "Print driver and lib version.", | | 90 | "Print driver and lib version.", |
92 | NULL, DMCTL_CMD_REQ_NODEVNAME, | | 91 | NULL, DMCTL_CMD_REQ_NODEVNAME, |
93 | dmctl_get_version }, | | 92 | dmctl_get_version }, |
94 | { "targets", | | 93 | { "targets", |
95 | "List available kernel targets.", | | 94 | "List available kernel targets.", |
96 | NULL, DMCTL_CMD_REQ_NODEVNAME, | | 95 | NULL, DMCTL_CMD_REQ_NODEVNAME, |
97 | dmctl_get_targets }, | | 96 | dmctl_get_targets }, |
98 | { "create", | | 97 | { "create", |
99 | "Create device with [dm device name].", | | 98 | "Create device with [dm device name].", |
100 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 99 | NULL, DMCTL_CMD_REQ_DEVNAME, |
101 | dmctl_create_dev }, | | 100 | dmctl_create_dev }, |
102 | { "ls", | | 101 | { "ls", |
103 | "List existing dm devices.", | | 102 | "List existing dm devices.", |
104 | "names", DMCTL_CMD_REQ_NODEVNAME, | | 103 | "names", DMCTL_CMD_REQ_NODEVNAME, |
105 | dmctl_list_devices }, | | 104 | dmctl_list_devices }, |
106 | { "info", | | 105 | { "info", |
107 | "Get info about device with [dm device name].", | | 106 | "Get info about device with [dm device name].", |
108 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 107 | NULL, DMCTL_CMD_REQ_DEVNAME, |
109 | dmctl_get_device_info }, | | 108 | dmctl_get_device_info }, |
110 | { "rename", | | 109 | { "rename", |
111 | "Rename device with [dm device name] to [dm device new name].", | | 110 | "Rename device with [dm device name] to [dm device new name].", |
112 | NULL, DMCTL_CMD_REQ_NEWNAME, | | 111 | NULL, DMCTL_CMD_REQ_NEWNAME, |
113 | dmctl_dev_rename }, | | 112 | dmctl_dev_rename }, |
114 | { "remove", | | 113 | { "remove", |
115 | "Remove device with [dm device name].", | | 114 | "Remove device with [dm device name].", |
116 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 115 | NULL, DMCTL_CMD_REQ_DEVNAME, |
117 | dmctl_dev_remove }, | | 116 | dmctl_dev_remove }, |
118 | { "resume", | | 117 | { "resume", |
119 | "Resume IO on dm device [dm device name].", | | 118 | "Resume IO on dm device [dm device name].", |
120 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 119 | NULL, DMCTL_CMD_REQ_DEVNAME, |
121 | dmctl_dev_resume }, | | 120 | dmctl_dev_resume }, |
122 | { "suspend", | | 121 | { "suspend", |
123 | "Suspend IO on dm device [dm device name].", | | 122 | "Suspend IO on dm device [dm device name].", |
124 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 123 | NULL, DMCTL_CMD_REQ_DEVNAME, |
125 | dmctl_dev_suspend }, | | 124 | dmctl_dev_suspend }, |
126 | { "deps", | | 125 | { "deps", |
127 | "Print physical dependiences for dm device [dm device name].", | | 126 | "Print physical dependiences for dm device [dm device name].", |
128 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 127 | NULL, DMCTL_CMD_REQ_DEVNAME, |
129 | dmctl_dev_deps }, | | 128 | dmctl_dev_deps }, |
130 | { "reload", | | 129 | { "reload", |
131 | "Switch active and passive tables for device with [dm device name].", | | 130 | "Switch active and passive tables for device with [dm device name].", |
132 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 131 | NULL, DMCTL_CMD_REQ_DEVNAME, |
133 | dmctl_table_reload }, | | 132 | dmctl_table_reload }, |
134 | { "status", | | 133 | { "status", |
135 | "Print status for device with [dm device name].", | | 134 | "Print status for device with [dm device name].", |
136 | "table", DMCTL_CMD_REQ_DEVNAME, | | 135 | "table", DMCTL_CMD_REQ_DEVNAME, |
137 | dmctl_table_status }, | | 136 | dmctl_table_status }, |
138 | { "table", | | 137 | { "table", |
139 | "Print active table for device with [dm device name].", | | 138 | "Print active table for device with [dm device name].", |
140 | NULL, DMCTL_CMD_REQ_DEVNAME, | | 139 | NULL, DMCTL_CMD_REQ_DEVNAME, |
141 | dmctl_table_status }, | | 140 | dmctl_table_status }, |
142 | { NULL, | | 141 | { NULL, |
143 | NULL, | | 142 | NULL, |
144 | NULL, 0, | | 143 | NULL, 0, |
145 | NULL }, | | 144 | NULL }, |
146 | }; | | 145 | }; |
147 | | | 146 | |
148 | int | | 147 | int |
149 | main(int argc, char *argv[]) | | 148 | main(int argc, char *argv[]) |
150 | { | | 149 | { |
151 | int i; | | 150 | int i; |
152 | int oargc; | | 151 | int oargc; |
153 | libdm_task_t task; | | 152 | libdm_task_t task; |
154 | | | 153 | |
155 | oargc = 0; | | 154 | oargc = 0; |
156 | | | 155 | |
157 | #ifdef RUMP_ACTION | | 156 | #ifdef RUMP_ACTION |
158 | if (rumpclient_init() == -1) | | 157 | if (rumpclient_init() == -1) |
159 | err(EXIT_FAILURE, "rump client init failed"); | | 158 | err(EXIT_FAILURE, "rump client init failed"); |
160 | #endif | | 159 | #endif |
161 | | | 160 | |
162 | /* Must have at least: device command */ | | 161 | /* Must have at least: device command */ |
163 | if (argc < 2) | | 162 | if (argc < 2) |
164 | usage(); | | 163 | usage(); |
165 | | | 164 | |
166 | /* Skip program name, get and skip device name and command. */ | | 165 | /* Skip program name, get and skip device name and command. */ |
167 | cmdname = argv[1]; | | 166 | cmdname = argv[1]; |
168 | if (argc > 2) { | | 167 | if (argc > 2) { |
169 | oargc = 1; | | 168 | oargc = 1; |
170 | dvname = argv[2]; | | 169 | dvname = argv[2]; |
171 | } | | 170 | } |
172 | | | 171 | |
173 | if (argc > 3) { | | 172 | if (argc > 3) { |
174 | argv += 3; | | 173 | argv += 3; |
175 | argc -= 3; | | 174 | argc -= 3; |
176 | oargc = 2; | | 175 | oargc = 2; |
177 | } else { | | 176 | } else { |
178 | argv = 0; | | 177 | argv = 0; |
179 | argc = 0; | | 178 | argc = 0; |
180 | } | | 179 | } |
181 | | | 180 | |
182 | for (i = 0; commands[i].cmd_name != NULL; i++) | | 181 | for (i = 0; commands[i].cmd_name != NULL; i++) |
183 | if (strcmp(cmdname, commands[i].cmd_name) == 0) | | 182 | if (strcmp(cmdname, commands[i].cmd_name) == 0) |
184 | break; | | 183 | break; |
185 | | | 184 | |
186 | if (commands[i].cmd_name == NULL) | | 185 | if (commands[i].cmd_name == NULL) |
187 | errx(EXIT_FAILURE, "unknown command: %s", cmdname); | | 186 | errx(EXIT_FAILURE, "unknown command: %s", cmdname); |
188 | | | 187 | |
189 | if (commands[i].ioctl_cmd_name != NULL) | | 188 | if (commands[i].ioctl_cmd_name != NULL) |
190 | cmdname = commands[i].ioctl_cmd_name; | | 189 | cmdname = commands[i].ioctl_cmd_name; |
191 | | | 190 | |
192 | if (oargc != commands[i].min_args) { | | 191 | if (oargc != commands[i].min_args) { |
193 | (void)fprintf(stderr, "Insufficient number of arguments for " | | 192 | (void)fprintf(stderr, "Insufficient number of arguments for " |
194 | "command: %s specified\n", commands[i].cmd_name); | | 193 | "command: %s specified\n", commands[i].cmd_name); |
195 | usage(); | | 194 | usage(); |
196 | } | | 195 | } |
197 | | | 196 | |
198 | /* | | 197 | /* |
199 | * Create libdm task, and pass it to command handler later. | | 198 | * Create libdm task, and pass it to command handler later. |
200 | * Don't release it here because it will be replaced by different | | 199 | * Don't release it here because it will be replaced by different |
201 | * dictionary received from kernel after libdm_task_run. | | 200 | * dictionary received from kernel after libdm_task_run. |
202 | */ | | 201 | */ |
203 | task = libdm_task_create(cmdname); | | 202 | task = libdm_task_create(cmdname); |
204 | | | 203 | |
205 | (*commands[i].cmd_func)(argc, argv, task); | | 204 | (*commands[i].cmd_func)(argc, argv, task); |
206 | | | 205 | |
207 | return 0; | | 206 | return 0; |
208 | } | | 207 | } |
209 | | | 208 | |
210 | /* | | 209 | /* |
211 | * Print library and kernel driver versions if command can be used only when | | 210 | * Print library and kernel driver versions if command can be used only when |
212 | * major, minor number of library version is <= kernel. | | 211 | * major, minor number of library version is <= kernel. |
213 | */ | | 212 | */ |
214 | static int | | 213 | static int |
215 | dmctl_get_version(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 214 | dmctl_get_version(int argc __unused, char *argv[] __unused, libdm_task_t task) |
216 | { | | 215 | { |
217 | uint32_t ver[3], size; | | 216 | uint32_t ver[3], size; |
218 | | | 217 | |
219 | size = libdm_task_get_cmd_version(task, ver, sizeof(ver)); | | 218 | size = libdm_task_get_cmd_version(task, ver, sizeof(ver)); |
220 | | | 219 | |
221 | printf("Library protocol version %d:%d:%d\n", ver[0], ver[1], ver[2]); | | 220 | printf("Library protocol version %d:%d:%d\n", ver[0], ver[1], ver[2]); |
222 | | | 221 | |
223 | if (libdm_task_run(task) != 0) | | 222 | if (libdm_task_run(task) != 0) |
224 | err(EXIT_FAILURE, "dmctl_get_version: libdm_task_run failed."); | | 223 | err(EXIT_FAILURE, "dmctl_get_version: libdm_task_run failed."); |
225 | | | 224 | |
226 | size = libdm_task_get_cmd_version(task, ver, 3); | | 225 | size = libdm_task_get_cmd_version(task, ver, 3); |
227 | printf("Kernel protocol version %d:%d:%d\n",ver[0], ver[1], ver[2]); | | 226 | printf("Kernel protocol version %d:%d:%d\n",ver[0], ver[1], ver[2]); |
228 | | | 227 | |
229 | libdm_task_destroy(task); | | 228 | libdm_task_destroy(task); |
230 | return 0; | | 229 | return 0; |
231 | } | | 230 | } |
232 | | | 231 | |
233 | /* | | 232 | /* |
234 | * Get list of available targets from kernel and print them. | | 233 | * Get list of available targets from kernel and print them. |
235 | */ | | 234 | */ |
236 | static int | | 235 | static int |
237 | dmctl_get_targets(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 236 | dmctl_get_targets(int argc __unused, char *argv[] __unused, libdm_task_t task) |
238 | { | | 237 | { |
239 | libdm_cmd_t cmd; | | 238 | libdm_cmd_t cmd; |
240 | libdm_iter_t iter; | | 239 | libdm_iter_t iter; |
241 | libdm_target_t target; | | 240 | libdm_target_t target; |
242 | uint32_t ver[3]; | | 241 | uint32_t ver[3]; |
243 | | | 242 | |
244 | if (libdm_task_run(task) != 0) | | 243 | if (libdm_task_run(task) != 0) |
245 | err(EXIT_FAILURE, "dmctl_get_targets: libdm_task_run failed."); | | 244 | err(EXIT_FAILURE, "dmctl_get_targets: libdm_task_run failed."); |
246 | | | 245 | |
247 | if ((cmd = libdm_task_get_cmd(task)) == NULL) | | 246 | if ((cmd = libdm_task_get_cmd(task)) == NULL) |
248 | return ENOENT; | | 247 | return ENOENT; |
249 | | | 248 | |
250 | iter = libdm_cmd_iter_create(cmd); | | 249 | iter = libdm_cmd_iter_create(cmd); |
251 | | | 250 | |
252 | while((target = libdm_cmd_get_target(iter)) != NULL){ | | 251 | while((target = libdm_cmd_get_target(iter)) != NULL){ |
253 | printf("Target name: %s\n", libdm_target_get_name(target)); | | 252 | printf("Target name: %s\n", libdm_target_get_name(target)); |
254 | | | 253 | |
255 | libdm_target_get_version(target, ver, sizeof(ver)); | | 254 | libdm_target_get_version(target, ver, sizeof(ver)); |
256 | printf("Target version %d.%d.%d\n\n", ver[0], ver[1], ver[2]); | | 255 | printf("Target version %d.%d.%d\n\n", ver[0], ver[1], ver[2]); |
257 | | | 256 | |
258 | libdm_target_destroy(target); | | 257 | libdm_target_destroy(target); |
259 | } | | 258 | } |
260 | | | 259 | |
261 | libdm_iter_destroy(iter); | | 260 | libdm_iter_destroy(iter); |
262 | libdm_cmd_destroy(cmd); | | 261 | libdm_cmd_destroy(cmd); |
263 | libdm_task_destroy(task); | | 262 | libdm_task_destroy(task); |
264 | | | 263 | |
265 | return 0; | | 264 | return 0; |
266 | } | | 265 | } |
267 | | | 266 | |
268 | /* | | 267 | /* |
269 | * Create device with name used as second parameter. | | 268 | * Create device with name used as second parameter. |
270 | * TODO: Support for UUIDs here. | | 269 | * TODO: Support for UUIDs here. |
271 | */ | | 270 | */ |
272 | static int | | 271 | static int |
273 | dmctl_create_dev(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 272 | dmctl_create_dev(int argc __unused, char *argv[] __unused, libdm_task_t task) |
274 | { | | 273 | { |
275 | | | 274 | |
276 | libdm_task_set_name(dvname, task); | | 275 | libdm_task_set_name(dvname, task); |
277 | | | 276 | |
278 | if (libdm_task_run(task) != 0) | | 277 | if (libdm_task_run(task) != 0) |
279 | err(EXIT_FAILURE, "dmctl_create_dev: libdm_task_run failed."); | | 278 | err(EXIT_FAILURE, "dmctl_create_dev: libdm_task_run failed."); |
280 | | | 279 | |
281 | libdm_task_destroy(task); | | 280 | libdm_task_destroy(task); |
282 | return 0; | | 281 | return 0; |
283 | } | | 282 | } |
284 | | | 283 | |
285 | /* | | 284 | /* |
286 | * Get basic device info from device-mapper driver. | | 285 | * Get basic device info from device-mapper driver. |
287 | */ | | 286 | */ |
288 | static int | | 287 | static int |
289 | dmctl_get_device_info(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 288 | dmctl_get_device_info(int argc __unused, char *argv[] __unused, libdm_task_t task) |
290 | { | | 289 | { |
291 | | | 290 | |
292 | libdm_task_set_name(dvname, task); | | 291 | libdm_task_set_name(dvname, task); |
293 | | | 292 | |
294 | if (libdm_task_run(task) != 0) | | 293 | if (libdm_task_run(task) != 0) |
295 | err(EXIT_FAILURE, "dmctl_get_device_info: libdm_task_run failed.\n"); | | 294 | err(EXIT_FAILURE, "dmctl_get_device_info: libdm_task_run failed.\n"); |
296 | | | 295 | |
297 | printf("Printing Device info for:\n"); | | 296 | printf("Printing Device info for:\n"); |
298 | printf("Device name: \t\t%s\n", libdm_task_get_name(task)); | | 297 | printf("Device name: \t\t%s\n", libdm_task_get_name(task)); |
299 | printf("Device uuid: \t\t%s\n", libdm_task_get_uuid(task)); | | 298 | printf("Device uuid: \t\t%s\n", libdm_task_get_uuid(task)); |
300 | printf("Device minor: \t\t%d\n", libdm_task_get_minor(task)); | | 299 | printf("Device minor: \t\t%d\n", libdm_task_get_minor(task)); |
301 | printf("Device target number: \t%d\n", libdm_task_get_target_num(task)); | | 300 | printf("Device target number: \t%d\n", libdm_task_get_target_num(task)); |
302 | printf("Device flags: \t\t%d\n", libdm_task_get_flags(task)); | | 301 | printf("Device flags: \t\t%d\n", libdm_task_get_flags(task)); |
303 | | | 302 | |
304 | libdm_task_destroy(task); | | 303 | libdm_task_destroy(task); |
305 | return 0; | | 304 | return 0; |
306 | } | | 305 | } |
307 | | | 306 | |
308 | /* | | 307 | /* |
309 | * List all device in device-mapper driver. | | 308 | * List all device in device-mapper driver. |
310 | */ | | 309 | */ |
311 | static int | | 310 | static int |
312 | dmctl_list_devices(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 311 | dmctl_list_devices(int argc __unused, char *argv[] __unused, libdm_task_t task) |
313 | { | | 312 | { |
314 | libdm_cmd_t cmd; | | 313 | libdm_cmd_t cmd; |
315 | libdm_iter_t iter; | | 314 | libdm_iter_t iter; |
316 | libdm_dev_t dev; | | 315 | libdm_dev_t dev; |
317 | | | 316 | |
318 | if (libdm_task_run(task) != 0) | | 317 | if (libdm_task_run(task) != 0) |
319 | err(EXIT_FAILURE, "dmctl_list_devices: libdm_task_run failed."); | | 318 | err(EXIT_FAILURE, "dmctl_list_devices: libdm_task_run failed."); |
320 | | | 319 | |
321 | if ((cmd = libdm_task_get_cmd(task)) == NULL) | | 320 | if ((cmd = libdm_task_get_cmd(task)) == NULL) |
322 | return ENOENT; | | 321 | return ENOENT; |
323 | | | 322 | |
324 | iter = libdm_cmd_iter_create(cmd); | | 323 | iter = libdm_cmd_iter_create(cmd); |
325 | | | 324 | |
326 | while((dev = libdm_cmd_get_dev(iter)) != NULL){ | | 325 | while((dev = libdm_cmd_get_dev(iter)) != NULL){ |
327 | printf("Device name: %s, device minor: %d \n", | | 326 | printf("Device name: %s, device minor: %d \n", |
328 | libdm_dev_get_name(dev), libdm_dev_get_minor(dev)); | | 327 | libdm_dev_get_name(dev), libdm_dev_get_minor(dev)); |
329 | libdm_dev_destroy(dev); | | 328 | libdm_dev_destroy(dev); |
330 | } | | 329 | } |
331 | | | 330 | |
332 | libdm_iter_destroy(iter); | | 331 | libdm_iter_destroy(iter); |
333 | libdm_cmd_destroy(cmd); | | 332 | libdm_cmd_destroy(cmd); |
334 | libdm_task_destroy(task); | | 333 | libdm_task_destroy(task); |
335 | | | 334 | |
336 | return 0; | | 335 | return 0; |
337 | } | | 336 | } |
338 | | | 337 | |
339 | /* | | 338 | /* |
340 | * Rename device to new name | | 339 | * Rename device to new name |
341 | */ | | 340 | */ |
342 | static int | | 341 | static int |
343 | dmctl_dev_rename(int argc __unused, char *argv[], libdm_task_t task) | | 342 | dmctl_dev_rename(int argc __unused, char *argv[], libdm_task_t task) |
344 | { | | 343 | { |
345 | libdm_cmd_t cmd; | | 344 | libdm_cmd_t cmd; |
346 | | | 345 | |
347 | libdm_task_set_name(dvname, task); | | 346 | libdm_task_set_name(dvname, task); |
348 | | | 347 | |
349 | cmd = libdm_cmd_create(); | | 348 | cmd = libdm_cmd_create(); |
350 | libdm_dev_set_newname(argv[0], cmd); | | 349 | libdm_dev_set_newname(argv[0], cmd); |
351 | libdm_task_set_cmd(cmd, task); | | 350 | libdm_task_set_cmd(cmd, task); |
352 | | | 351 | |
353 | if (libdm_task_run(task) != 0) | | 352 | if (libdm_task_run(task) != 0) |
354 | err(EXIT_FAILURE, "dmctl_dev_rename: libdm_task_run failed."); | | 353 | err(EXIT_FAILURE, "dmctl_dev_rename: libdm_task_run failed."); |
355 | | | 354 | |
356 | libdm_cmd_destroy(cmd); | | 355 | libdm_cmd_destroy(cmd); |
357 | libdm_task_destroy(task); | | 356 | libdm_task_destroy(task); |
358 | | | 357 | |
359 | return 0; | | 358 | return 0; |
360 | } | | 359 | } |
361 | | | 360 | |
362 | /* | | 361 | /* |
363 | * Remove device from dm device list. | | 362 | * Remove device from dm device list. |
364 | */ | | 363 | */ |
365 | static int | | 364 | static int |
366 | dmctl_dev_remove(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 365 | dmctl_dev_remove(int argc __unused, char *argv[] __unused, libdm_task_t task) |
367 | { | | 366 | { |
368 | | | 367 | |
369 | if (dvname == NULL) | | 368 | if (dvname == NULL) |
370 | return (ENOENT); | | 369 | return (ENOENT); |
371 | | | 370 | |
372 | libdm_task_set_name(dvname, task); | | 371 | libdm_task_set_name(dvname, task); |
373 | | | 372 | |
374 | if (libdm_task_run(task) != 0) | | 373 | if (libdm_task_run(task) != 0) |
375 | err(EXIT_FAILURE, "dmctl_dev_remove: libdm_task_run failed."); | | 374 | err(EXIT_FAILURE, "dmctl_dev_remove: libdm_task_run failed."); |
376 | | | 375 | |
377 | libdm_task_destroy(task); | | 376 | libdm_task_destroy(task); |
378 | return 0; | | 377 | return 0; |
379 | } | | 378 | } |
380 | | | 379 | |
381 | /* | | 380 | /* |
382 | * Resume device which was suspended or created right now. | | 381 | * Resume device which was suspended or created right now. |
383 | * Replace table in "active slot" witg table in "inactive slot". | | 382 | * Replace table in "active slot" witg table in "inactive slot". |
384 | */ | | 383 | */ |
385 | static int | | 384 | static int |
386 | dmctl_dev_resume(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 385 | dmctl_dev_resume(int argc __unused, char *argv[] __unused, libdm_task_t task) |
387 | { | | 386 | { |
388 | | | 387 | |
389 | libdm_task_set_name(dvname, task); | | 388 | libdm_task_set_name(dvname, task); |
390 | | | 389 | |
391 | if (libdm_task_run(task) != 0) | | 390 | if (libdm_task_run(task) != 0) |
392 | err(EXIT_FAILURE, "dmctl_dev_resume: libdm_task_run failed."); | | 391 | err(EXIT_FAILURE, "dmctl_dev_resume: libdm_task_run failed."); |
393 | | | 392 | |
394 | libdm_task_destroy(task); | | 393 | libdm_task_destroy(task); |
395 | return 0; | | 394 | return 0; |
396 | } | | 395 | } |
397 | | | 396 | |
398 | /* | | 397 | /* |
399 | * Resume device which was suspended or created right now. | | 398 | * Resume device which was suspended or created right now. |
400 | * Replace table in "active slot" with table in "inactive slot". | | 399 | * Replace table in "active slot" with table in "inactive slot". |
401 | */ | | 400 | */ |
402 | static int | | 401 | static int |
403 | dmctl_dev_suspend(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 402 | dmctl_dev_suspend(int argc __unused, char *argv[] __unused, libdm_task_t task) |
404 | { | | 403 | { |
405 | | | 404 | |
406 | libdm_task_set_name(dvname, task); | | 405 | libdm_task_set_name(dvname, task); |
407 | libdm_task_set_suspend_flag(task); | | 406 | libdm_task_set_suspend_flag(task); |
408 | | | 407 | |
409 | if (libdm_task_run(task) != 0) | | 408 | if (libdm_task_run(task) != 0) |
410 | err(EXIT_FAILURE, "dmctl_dev_suspend: libdm_task_run failed."); | | 409 | err(EXIT_FAILURE, "dmctl_dev_suspend: libdm_task_run failed."); |
411 | | | 410 | |
412 | libdm_task_destroy(task); | | 411 | libdm_task_destroy(task); |
413 | return 0; | | 412 | return 0; |
414 | } | | 413 | } |
415 | | | 414 | |
416 | /* | | 415 | /* |
417 | * Get device dependiences from device-mapper. Device dependency is physical | | 416 | * Get device dependiences from device-mapper. Device dependency is physical |
418 | * device on which dm device depends. | | 417 | * device on which dm device depends. |
419 | */ | | 418 | */ |
420 | static int | | 419 | static int |
421 | dmctl_dev_deps(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 420 | dmctl_dev_deps(int argc __unused, char *argv[] __unused, libdm_task_t task) |
422 | { | | 421 | { |
423 | libdm_cmd_t cmd; | | 422 | libdm_cmd_t cmd; |
424 | libdm_iter_t iter; | | 423 | libdm_iter_t iter; |
425 | dev_t dev_deps; | | 424 | dev_t dev_deps; |
426 | | | 425 | |
427 | libdm_task_set_name(dvname, task); | | 426 | libdm_task_set_name(dvname, task); |
428 | | | 427 | |
429 | if (libdm_task_run(task) != 0) | | 428 | if (libdm_task_run(task) != 0) |
430 | err(EXIT_FAILURE, "dmctl_dev_deps: libdm_task_run failed."); | | 429 | err(EXIT_FAILURE, "dmctl_dev_deps: libdm_task_run failed."); |
431 | | | 430 | |
432 | if ((cmd = libdm_task_get_cmd(task)) == NULL) | | 431 | if ((cmd = libdm_task_get_cmd(task)) == NULL) |
433 | return ENOENT; | | 432 | return ENOENT; |
434 | | | 433 | |
435 | iter = libdm_cmd_iter_create(cmd); | | 434 | iter = libdm_cmd_iter_create(cmd); |
436 | | | 435 | |
437 | printf("Device %s dependiences \n", dvname); | | 436 | printf("Device %s dependiences \n", dvname); |
438 | | | 437 | |
439 | while((dev_deps = libdm_cmd_get_deps(iter)) != 0) | | 438 | while((dev_deps = libdm_cmd_get_deps(iter)) != 0) |
440 | printf("major: %d minor: %d\n", major(dev_deps), minor(dev_deps)); | | 439 | printf("major: %d minor: %d\n", major(dev_deps), minor(dev_deps)); |
441 | | | 440 | |
442 | libdm_iter_destroy(iter); | | 441 | libdm_iter_destroy(iter); |
443 | libdm_cmd_destroy(cmd); | | 442 | libdm_cmd_destroy(cmd); |
444 | libdm_task_destroy(task); | | 443 | libdm_task_destroy(task); |
445 | | | 444 | |
446 | return 0; | | 445 | return 0; |
447 | } | | 446 | } |
448 | | | 447 | |
449 | /* | | 448 | /* |
450 | * Reload device table to get new one to use. | | 449 | * Reload device table to get new one to use. |
451 | */ | | 450 | */ |
452 | static int | | 451 | static int |
453 | dmctl_table_reload(int argc, char *argv[], libdm_task_t task) | | 452 | dmctl_table_reload(int argc, char *argv[], libdm_task_t task) |
454 | { | | 453 | { |
455 | libdm_cmd_t cmd; | | 454 | libdm_cmd_t cmd; |
456 | libdm_table_t table; | | 455 | libdm_table_t table; |
457 | | | 456 | |
458 | char *params; | | 457 | char *params; |
459 | char *file_path; | | 458 | char *file_path; |
460 | char target[128]; | | 459 | char target[128]; |
461 | int len; | | 460 | int len; |
462 | uint64_t start, length; | | 461 | uint64_t start, length; |
463 | | | 462 | |
464 | file_path = NULL; | | 463 | file_path = NULL; |
465 | params = NULL; | | 464 | params = NULL; |
466 | | | 465 | |
467 | cmd = libdm_cmd_create(); | | 466 | cmd = libdm_cmd_create(); |
468 | | | 467 | |
469 | libdm_task_set_name(dvname, task); | | 468 | libdm_task_set_name(dvname, task); |
470 | | | 469 | |
471 | if (argc != 0) | | 470 | if (argc != 0) |
472 | file_path = argv[0]; | | 471 | file_path = argv[0]; |
473 | | | 472 | |
474 | while ((params = parse_stdin(file_path)) != NULL) { | | 473 | while ((params = parse_stdin(file_path)) != NULL) { |
475 | table = libdm_table_create(); | | 474 | table = libdm_table_create(); |
476 | | | 475 | |
477 | sscanf(params, "%"PRIu64" %"PRIu64" %s %n", &start, &length, target, &len); | | 476 | sscanf(params, "%"PRIu64" %"PRIu64" %s %n", &start, &length, target, &len); |
478 | | | 477 | |
479 | libdm_table_set_start(start, table); | | 478 | libdm_table_set_start(start, table); |
480 | libdm_table_set_length(length, table); | | 479 | libdm_table_set_length(length, table); |
481 | libdm_table_set_target(target, table); | | 480 | libdm_table_set_target(target, table); |
482 | libdm_table_set_params(params + len, table); | | 481 | libdm_table_set_params(params + len, table); |
483 | libdm_cmd_set_table(table, cmd); | | 482 | libdm_cmd_set_table(table, cmd); |
484 | | | 483 | |
485 | libdm_table_destroy(table); | | 484 | libdm_table_destroy(table); |
486 | | | 485 | |
487 | free(params); | | 486 | free(params); |
488 | } | | 487 | } |
489 | | | 488 | |
490 | libdm_task_set_cmd(cmd, task); | | 489 | libdm_task_set_cmd(cmd, task); |
491 | | | 490 | |
492 | if (libdm_task_run(task) != 0) | | 491 | if (libdm_task_run(task) != 0) |
493 | err(EXIT_FAILURE, "libdm_task_run: from dmctl_table_reload failed."); | | 492 | err(EXIT_FAILURE, "libdm_task_run: from dmctl_table_reload failed."); |
494 | | | 493 | |
495 | libdm_cmd_destroy(cmd); | | 494 | libdm_cmd_destroy(cmd); |
496 | libdm_task_destroy(task); | | 495 | libdm_task_destroy(task); |
497 | free(params); | | 496 | free(params); |
498 | | | 497 | |
499 | return 0; | | 498 | return 0; |
500 | } | | 499 | } |
501 | | | 500 | |
502 | /* | | 501 | /* |
503 | * Get table status from device. | | 502 | * Get table status from device. |
504 | */ | | 503 | */ |
505 | static int | | 504 | static int |
506 | dmctl_table_status(int argc __unused, char *argv[] __unused, libdm_task_t task) | | 505 | dmctl_table_status(int argc __unused, char *argv[] __unused, libdm_task_t task) |
507 | { | | 506 | { |
508 | libdm_cmd_t cmd; | | 507 | libdm_cmd_t cmd; |
509 | libdm_table_t table; | | 508 | libdm_table_t table; |
510 | libdm_iter_t iter; | | 509 | libdm_iter_t iter; |
511 | | | 510 | |
512 | libdm_task_set_name(dvname, task); | | 511 | libdm_task_set_name(dvname, task); |
513 | libdm_task_set_status_flag(task); | | 512 | libdm_task_set_status_flag(task); |
514 | | | 513 | |
515 | if (libdm_task_run(task) != 0) | | 514 | if (libdm_task_run(task) != 0) |
516 | err(EXIT_FAILURE, "libdm_task_run"); | | 515 | err(EXIT_FAILURE, "libdm_task_run"); |
517 | | | 516 | |
518 | if ((cmd = libdm_task_get_cmd(task)) == NULL) | | 517 | if ((cmd = libdm_task_get_cmd(task)) == NULL) |
519 | return ENOENT; | | 518 | return ENOENT; |
520 | | | 519 | |
521 | iter = libdm_cmd_iter_create(cmd); | | 520 | iter = libdm_cmd_iter_create(cmd); |
522 | | | 521 | |
523 | printf("Getting device table for device %s\n", dvname); | | 522 | printf("Getting device table for device %s\n", dvname); |
524 | | | 523 | |
525 | while ((table = libdm_cmd_get_table(iter)) != NULL) { | | 524 | while ((table = libdm_cmd_get_table(iter)) != NULL) { |
526 | printf("%10"PRIu64" %10"PRIu64" %s\n", | | 525 | printf("%10"PRIu64" %10"PRIu64" %s\n", |
527 | libdm_table_get_start(table), | | 526 | libdm_table_get_start(table), |
528 | libdm_table_get_length(table), | | 527 | libdm_table_get_length(table), |
529 | libdm_table_get_target(table)); | | 528 | libdm_table_get_target(table)); |
530 | libdm_table_destroy(table); | | 529 | libdm_table_destroy(table); |
531 | } | | 530 | } |
532 | | | 531 | |
533 | libdm_iter_destroy(iter); | | 532 | libdm_iter_destroy(iter); |
534 | libdm_cmd_destroy(cmd); | | 533 | libdm_cmd_destroy(cmd); |
535 | libdm_task_destroy(task); | | 534 | libdm_task_destroy(task); |
536 | | | 535 | |
537 | return 0; | | 536 | return 0; |
538 | } | | 537 | } |
539 | | | 538 | |
540 | void | | 539 | static void |
541 | usage(void) | | 540 | usage(void) |
542 | { | | 541 | { |
543 | int i; | | 542 | int i; |
544 | | | 543 | |
545 | (void)fprintf(stderr, "usage: %s command [dm device name]\n" | | 544 | (void)fprintf(stderr, "usage: %s command [dm device name]\n" |
546 | "Available commands are:\n ", getprogname()); | | 545 | "Available commands are:\n ", getprogname()); |
547 | for (i = 0; commands[i].cmd_name != NULL; i++) | | 546 | for (i = 0; commands[i].cmd_name != NULL; i++) |
548 | (void)fprintf(stderr, "\t%s\t%s\n", commands[i].cmd_name, commands[i].cmd_help); | | 547 | (void)fprintf(stderr, "\t%s\t%s\n", commands[i].cmd_name, commands[i].cmd_help); |
549 | exit(EXIT_FAILURE); | | 548 | exit(EXIT_FAILURE); |
550 | } | | 549 | } |
551 | | | 550 | |
552 | static char * | | 551 | static char * |
553 | parse_stdin(char *file_path) | | 552 | parse_stdin(char *file_path) |
554 | { | | 553 | { |
555 | char *buf, *lbuf; | | 554 | char *buf, *lbuf; |
556 | size_t len; | | 555 | size_t len; |
557 | FILE *fp; | | 556 | FILE *fp; |
558 | | | 557 | |
559 | lbuf = NULL; | | 558 | lbuf = NULL; |
560 | | | 559 | |
561 | if (file_path) { | | 560 | if (file_path) { |
562 | if ((fp = fopen(file_path, "r")) == NULL) | | 561 | if ((fp = fopen(file_path, "r")) == NULL) |
563 | err(ENOENT, "Cannot open table file\n"); | | 562 | err(ENOENT, "Cannot open table file\n"); |
564 | } else | | 563 | } else |
565 | fp = stdin; | | 564 | fp = stdin; |
566 | | | 565 | |
567 | if ((buf = fgetln(fp, &len)) == NULL) | | 566 | if ((buf = fgetln(fp, &len)) == NULL) |
568 | return NULL; | | 567 | return NULL; |
569 | | | 568 | |
570 | if (buf[len - 1] != '\n') | | 569 | if (buf[len - 1] != '\n') |
571 | len++; | | 570 | len++; |
572 | | | 571 | |
573 | if ((lbuf = malloc(len)) == NULL) | | 572 | if ((lbuf = malloc(len)) == NULL) |
574 | err(EXIT_FAILURE, "malloc"); | | 573 | err(EXIT_FAILURE, "malloc"); |
575 | | | 574 | |
576 | memcpy(lbuf, buf, len); | | 575 | memcpy(lbuf, buf, len); |
577 | lbuf[len - 1] = '\0'; | | 576 | lbuf[len - 1] = '\0'; |
578 | | | 577 | |
579 | return lbuf; | | 578 | return lbuf; |
580 | } | | 579 | } |