Commit 9ea2ea7146042d54fc3d17d0269ae865cbf55dcf

Authored by Kevin Wolf
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);
... ...