Commit 9ea2ea7146042d54fc3d17d0269ae865cbf55dcf
Committed by
Anthony Liguori
1 parent
0e7e1989
Convert qemu-img create to new bdrv_create
This patch changes qemu-img to actually use the new bdrv_create interface. It translates the old-style qemu-img options which have been bdrv_create2 parameters or flags so far to option structures. As the generic approach, it introduces an -o option which accepts any parameter the driver knows. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
87 additions
and
46 deletions
qemu-img.c
... | ... | @@ -22,6 +22,7 @@ |
22 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | 24 | #include "qemu-common.h" |
25 | +#include "qemu-option.h" | |
25 | 26 | #include "osdep.h" |
26 | 27 | #include "block_int.h" |
27 | 28 | #include <stdio.h> |
... | ... | @@ -221,14 +222,13 @@ static int img_create(int argc, char **argv) |
221 | 222 | const char *base_fmt = NULL; |
222 | 223 | const char *filename; |
223 | 224 | const char *base_filename = NULL; |
224 | - uint64_t size; | |
225 | - double sizef; | |
226 | - const char *p; | |
227 | 225 | BlockDriver *drv; |
226 | + QEMUOptionParameter *param = NULL; | |
227 | + char *options = NULL; | |
228 | 228 | |
229 | 229 | flags = 0; |
230 | 230 | for(;;) { |
231 | - c = getopt(argc, argv, "F:b:f:he6"); | |
231 | + c = getopt(argc, argv, "F:b:f:he6o:"); | |
232 | 232 | if (c == -1) |
233 | 233 | break; |
234 | 234 | switch(c) { |
... | ... | @@ -250,59 +250,100 @@ static int img_create(int argc, char **argv) |
250 | 250 | case '6': |
251 | 251 | flags |= BLOCK_FLAG_COMPAT6; |
252 | 252 | break; |
253 | + case 'o': | |
254 | + options = optarg; | |
255 | + break; | |
253 | 256 | } |
254 | 257 | } |
255 | 258 | if (optind >= argc) |
256 | 259 | help(); |
257 | 260 | filename = argv[optind++]; |
258 | - size = 0; | |
259 | - if (base_filename) { | |
260 | - BlockDriverState *bs; | |
261 | - BlockDriver *base_drv = NULL; | |
262 | 261 | |
263 | - if (base_fmt) { | |
264 | - base_drv = bdrv_find_format(base_fmt); | |
265 | - if (base_drv == NULL) | |
266 | - error("Unknown basefile format '%s'", base_fmt); | |
267 | - } | |
262 | + /* Find driver and parse its options */ | |
263 | + drv = bdrv_find_format(fmt); | |
264 | + if (!drv) | |
265 | + error("Unknown file format '%s'", fmt); | |
268 | 266 | |
269 | - bs = bdrv_new_open(base_filename, base_fmt); | |
270 | - bdrv_get_geometry(bs, &size); | |
271 | - size *= 512; | |
272 | - bdrv_delete(bs); | |
267 | + if (options) { | |
268 | + param = parse_option_parameters(options, drv->create_options, param); | |
269 | + if (param == NULL) { | |
270 | + error("Invalid options for file format '%s'.", fmt); | |
271 | + } | |
273 | 272 | } else { |
274 | - if (optind >= argc) | |
275 | - help(); | |
276 | - p = argv[optind]; | |
277 | - sizef = strtod(p, (char **)&p); | |
278 | - if (*p == 'M') { | |
279 | - size = (uint64_t)(sizef * 1024 * 1024); | |
280 | - } else if (*p == 'G') { | |
281 | - size = (uint64_t)(sizef * 1024 * 1024 * 1024); | |
282 | - } else if (*p == 'k' || *p == 'K' || *p == '\0') { | |
283 | - size = (uint64_t)(sizef * 1024); | |
284 | - } else { | |
285 | - help(); | |
273 | + param = parse_option_parameters("", drv->create_options, param); | |
274 | + } | |
275 | + | |
276 | + /* Add size to parameters */ | |
277 | + if (optind < argc) { | |
278 | + set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]); | |
279 | + } | |
280 | + | |
281 | + /* Add old-style options to parameters */ | |
282 | + if (flags & BLOCK_FLAG_ENCRYPT) { | |
283 | + if (set_option_parameter(param, BLOCK_OPT_ENCRYPT, "on")) { | |
284 | + error("Encryption not supported for file format '%s'", fmt); | |
286 | 285 | } |
287 | 286 | } |
288 | - drv = bdrv_find_format(fmt); | |
289 | - if (!drv) | |
290 | - error("Unknown file format '%s'", fmt); | |
291 | - printf("Formatting '%s', fmt=%s", | |
292 | - filename, fmt); | |
293 | - if (flags & BLOCK_FLAG_ENCRYPT) | |
294 | - printf(", encrypted"); | |
295 | - if (flags & BLOCK_FLAG_COMPAT6) | |
296 | - printf(", compatibility level=6"); | |
287 | + if (flags & BLOCK_FLAG_COMPAT6) { | |
288 | + if (set_option_parameter(param, BLOCK_OPT_COMPAT6, "on")) { | |
289 | + error("VMDK version 6 not supported for file format '%s'", fmt); | |
290 | + } | |
291 | + } | |
292 | + | |
297 | 293 | if (base_filename) { |
298 | - printf(", backing_file=%s", | |
299 | - base_filename); | |
300 | - if (base_fmt) | |
301 | - printf(", backing_fmt=%s", | |
302 | - base_fmt); | |
303 | - } | |
304 | - printf(", size=%" PRIu64 " kB\n", size / 1024); | |
305 | - ret = bdrv_create2(drv, filename, size / 512, base_filename, base_fmt, flags); | |
294 | + if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE, base_filename)) { | |
295 | + error("Backing file not supported for file format '%s'", fmt); | |
296 | + } | |
297 | + } | |
298 | + if (base_fmt) { | |
299 | + if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) { | |
300 | + error("Backing file format not supported for file format '%s'", fmt); | |
301 | + } | |
302 | + } | |
303 | + | |
304 | + // The size for the image must always be specified, with one exception: | |
305 | + // If we are using a backing file, we can obtain the size from there | |
306 | + if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == 0) { | |
307 | + | |
308 | + QEMUOptionParameter *backing_file = | |
309 | + get_option_parameter(param, BLOCK_OPT_BACKING_FILE); | |
310 | + QEMUOptionParameter *backing_fmt = | |
311 | + get_option_parameter(param, BLOCK_OPT_BACKING_FMT); | |
312 | + | |
313 | + if (backing_file && backing_file->value.s) { | |
314 | + BlockDriverState *bs; | |
315 | + uint64_t size; | |
316 | + const char *fmt = NULL; | |
317 | + char buf[32]; | |
318 | + | |
319 | + if (backing_fmt && backing_fmt->value.s) { | |
320 | + if (bdrv_find_format(backing_fmt->value.s)) { | |
321 | + fmt = backing_fmt->value.s; | |
322 | + } else { | |
323 | + error("Unknown backing file format '%s'", | |
324 | + backing_fmt->value.s); | |
325 | + } | |
326 | + } | |
327 | + | |
328 | + bs = bdrv_new_open(backing_file->value.s, fmt); | |
329 | + bdrv_get_geometry(bs, &size); | |
330 | + size *= 512; | |
331 | + bdrv_delete(bs); | |
332 | + | |
333 | + snprintf(buf, sizeof(buf), "%" PRId64, size); | |
334 | + set_option_parameter(param, BLOCK_OPT_SIZE, buf); | |
335 | + } else { | |
336 | + error("Image creation needs a size parameter"); | |
337 | + } | |
338 | + } | |
339 | + | |
340 | + printf("Formatting '%s', fmt=%s ", filename, fmt); | |
341 | + print_option_parameters(param); | |
342 | + puts(""); | |
343 | + | |
344 | + ret = bdrv_create(drv, filename, param); | |
345 | + free_option_parameters(param); | |
346 | + | |
306 | 347 | if (ret < 0) { |
307 | 348 | if (ret == -ENOTSUP) { |
308 | 349 | error("Formatting or formatting option not supported for file format '%s'", fmt); | ... | ... |