diff options
author | John Snow <jsnow@redhat.com> | 2017-07-17 20:34:22 -0400 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-07-18 15:27:37 +0200 |
commit | 6e6e55f5c2e5b520d6506c2716287ba3b5d1bbc8 (patch) | |
tree | ed30613055c350d84000cd205b35bd6ffc441054 /block.c | |
parent | 2a32c6e82ed24d837ce7af346ffc93113f0164b5 (diff) |
qemu-img: Check for backing image if specified during create
Or, rather, force the open of a backing image if one was specified
for creation. Using a similar -unsafe option as rebase, allow qemu-img
to ignore the backing file validation if possible.
It may not always be possible, as in the existing case when a filesize
for the new image was not specified.
This is accomplished by shifting around the conditionals in
bdrv_img_create, such that a backing file is always opened unless we
provide BDRV_O_NO_BACKING. qemu-img is adjusted to pass this new flag
when -u is provided to create.
Sorry for the heinous looking diffstat, but it's mostly whitespace.
Inspired by: https://bugzilla.redhat.com/show_bug.cgi?id=1213786
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 94 |
1 files changed, 52 insertions, 42 deletions
@@ -4396,55 +4396,65 @@ void bdrv_img_create(const char *filename, const char *fmt, backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_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 + /* The size for the image must always be specified, unless we have a backing + * file and we have not been forbidden from opening it. */ size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0); - if (size == -1) { - if (backing_file) { - BlockDriverState *bs; - char *full_backing = g_new0(char, PATH_MAX); - int64_t size; - int back_flags; - QDict *backing_options = NULL; - - bdrv_get_full_backing_filename_from_filename(filename, backing_file, - full_backing, PATH_MAX, - &local_err); - if (local_err) { - g_free(full_backing); - goto out; - } + if (backing_file && !(flags & BDRV_O_NO_BACKING)) { + BlockDriverState *bs; + char *full_backing = g_new0(char, PATH_MAX); + int back_flags; + QDict *backing_options = NULL; + + bdrv_get_full_backing_filename_from_filename(filename, backing_file, + full_backing, PATH_MAX, + &local_err); + if (local_err) { + g_free(full_backing); + goto out; + } - /* backing files always opened read-only */ - back_flags = flags; - back_flags &= ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); + /* backing files always opened read-only */ + back_flags = flags; + back_flags &= ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); - if (backing_fmt) { - backing_options = qdict_new(); - qdict_put_str(backing_options, "driver", backing_fmt); - } + if (backing_fmt) { + backing_options = qdict_new(); + qdict_put_str(backing_options, "driver", backing_fmt); + } - bs = bdrv_open(full_backing, NULL, backing_options, back_flags, - &local_err); - g_free(full_backing); - if (!bs) { - goto out; - } - size = bdrv_getlength(bs); - if (size < 0) { - error_setg_errno(errp, -size, "Could not get size of '%s'", - backing_file); - bdrv_unref(bs); - goto out; + bs = bdrv_open(full_backing, NULL, backing_options, back_flags, + &local_err); + g_free(full_backing); + if (!bs && size != -1) { + /* Couldn't open BS, but we have a size, so it's nonfatal */ + warn_reportf_err(local_err, + "Could not verify backing image. " + "This may become an error in future versions.\n"); + local_err = NULL; + } else if (!bs) { + /* Couldn't open bs, do not have size */ + error_append_hint(&local_err, + "Could not open backing image to determine size.\n"); + goto out; + } else { + if (size == -1) { + /* Opened BS, have no size */ + size = bdrv_getlength(bs); + if (size < 0) { + error_setg_errno(errp, -size, "Could not get size of '%s'", + backing_file); + bdrv_unref(bs); + goto out; + } + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort); } - - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort); - bdrv_unref(bs); - } else { - error_setg(errp, "Image creation needs a size parameter"); - goto out; } + } /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */ + + if (size == -1) { + error_setg(errp, "Image creation needs a size parameter"); + goto out; } if (!quiet) { |