block: add bdrv_open_backing_file
Mirroring runs without the backing file so that it can be copied outside QEMU. However, we need to add it at the time the job is completed and QEMU switches to the target. Factor out the common bits of opening an image and completing a mirroring operation. The new function does not assume that the file is closed immediately after it returns failure, so it keeps the BDRV_O_NO_BACKING flag up-to-date. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
9887b61661
commit
9156df12a4
56
block.c
56
block.c
@ -736,6 +736,42 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bdrv_open_backing_file(BlockDriverState *bs)
|
||||
{
|
||||
char backing_filename[PATH_MAX];
|
||||
int back_flags, ret;
|
||||
BlockDriver *back_drv = NULL;
|
||||
|
||||
if (bs->backing_hd != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bs->open_flags &= ~BDRV_O_NO_BACKING;
|
||||
if (bs->backing_file[0] == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bs->backing_hd = bdrv_new("");
|
||||
bdrv_get_full_backing_filename(bs, backing_filename,
|
||||
sizeof(backing_filename));
|
||||
|
||||
if (bs->backing_format[0] != '\0') {
|
||||
back_drv = bdrv_find_format(bs->backing_format);
|
||||
}
|
||||
|
||||
/* backing files always opened read-only */
|
||||
back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);
|
||||
|
||||
ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
|
||||
if (ret < 0) {
|
||||
bdrv_delete(bs->backing_hd);
|
||||
bs->backing_hd = NULL;
|
||||
bs->open_flags |= BDRV_O_NO_BACKING;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a disk image (raw, qcow2, vmdk, ...)
|
||||
*/
|
||||
@ -823,24 +859,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
|
||||
}
|
||||
|
||||
/* If there is a backing file, use it */
|
||||
if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {
|
||||
char backing_filename[PATH_MAX];
|
||||
int back_flags;
|
||||
BlockDriver *back_drv = NULL;
|
||||
|
||||
bs->backing_hd = bdrv_new("");
|
||||
bdrv_get_full_backing_filename(bs, backing_filename,
|
||||
sizeof(backing_filename));
|
||||
|
||||
if (bs->backing_format[0] != '\0') {
|
||||
back_drv = bdrv_find_format(bs->backing_format);
|
||||
}
|
||||
|
||||
/* backing files always opened read-only */
|
||||
back_flags =
|
||||
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
|
||||
|
||||
ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
|
||||
if ((flags & BDRV_O_NO_BACKING) == 0) {
|
||||
ret = bdrv_open_backing_file(bs);
|
||||
if (ret < 0) {
|
||||
bdrv_close(bs);
|
||||
return ret;
|
||||
|
1
block.h
1
block.h
@ -133,6 +133,7 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
|
||||
void bdrv_delete(BlockDriverState *bs);
|
||||
int bdrv_parse_cache_flags(const char *mode, int *flags);
|
||||
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
|
||||
int bdrv_open_backing_file(BlockDriverState *bs);
|
||||
int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
|
||||
BlockDriver *drv);
|
||||
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
||||
|
Loading…
Reference in New Issue
Block a user