mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
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>
This commit is contained in:
parent
2a32c6e82e
commit
6e6e55f5c2
12 changed files with 85 additions and 61 deletions
98
block.c
98
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
bdrv_get_full_backing_filename_from_filename(filename, backing_file,
|
||||
full_backing, PATH_MAX,
|
||||
&local_err);
|
||||
if (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;
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
} /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
|
||||
|
||||
if (size == -1) {
|
||||
error_setg(errp, "Image creation needs a size parameter");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue