summaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2017-07-17 20:34:22 -0400
committerKevin Wolf <kwolf@redhat.com>2017-07-18 15:27:37 +0200
commit6e6e55f5c2e5b520d6506c2716287ba3b5d1bbc8 (patch)
treeed30613055c350d84000cd205b35bd6ffc441054 /block.c
parent2a32c6e82ed24d837ce7af346ffc93113f0164b5 (diff)
downloadqemu-6e6e55f5c2e5b520d6506c2716287ba3b5d1bbc8.tar.gz
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.c94
1 files changed, 52 insertions, 42 deletions
diff --git a/block.c b/block.c
index 98a9209371..2dd9262cd0 100644
--- a/block.c
+++ b/block.c
@@ -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) {