- if (optind >= argc)
- help();
- p = argv[optind];
- sizef = strtod(p, (char **)&p);
- if (*p == 'M') {
- size = (uint64_t)(sizef * 1024 * 1024);
- } else if (*p == 'G') {
- size = (uint64_t)(sizef * 1024 * 1024 * 1024);
- } else if (*p == 'k' || *p == 'K' || *p == '\0') {
- size = (uint64_t)(sizef * 1024);
+ param = parse_option_parameters("", drv->create_options, param);
+ }
+
+ /* Add size to parameters */
+ if (optind < argc) {
+ set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
+ }
+
+ /* Add old-style options to parameters */
+ add_old_style_options(fmt, param, flags, base_filename, base_fmt);
+
+ // The size for the image must always be specified, with one exception:
+ // If we are using a backing file, we can obtain the size from there
+ if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == 0) {
+
+ QEMUOptionParameter *backing_file =
+ get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
+ QEMUOptionParameter *backing_fmt =
+ get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
+
+ if (backing_file && backing_file->value.s) {
+ BlockDriverState *bs;
+ uint64_t size;
+ const char *fmt = NULL;
+ char buf[32];
+
+ if (backing_fmt && backing_fmt->value.s) {
+ if (bdrv_find_format(backing_fmt->value.s)) {
+ fmt = backing_fmt->value.s;
+ } else {
+ error("Unknown backing file format '%s'",
+ backing_fmt->value.s);
+ }
+ }
+
+ bs = bdrv_new_open(backing_file->value.s, fmt);
+ bdrv_get_geometry(bs, &size);
+ size *= 512;
+ bdrv_delete(bs);
+
+ snprintf(buf, sizeof(buf), "%" PRId64, size);
+ set_option_parameter(param, BLOCK_OPT_SIZE, buf);