From: Olga Krishtal <okrish...@virtuozzo.com> While opening the image we want to be sure that we are the one who works with image, anf if it is not true - opening the image for writing should fail.
There are 2 ways at the moment: no lock at all and lock the file image. Signed-off-by: Olga Krishtal <okrish...@virtuozzo.com> Signed-off-by: Denis V. Lunev <d...@openvz.org> CC: Kevin Wolf <kw...@redhat.com> CC: Max Reitz <mre...@redhat.com> CC: Eric Blake <ebl...@redhat.com> CC: Fam Zheng <f...@redhat.com> --- block.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/block/block.h | 1 + include/block/block_int.h | 1 + qapi/block-core.json | 9 +++++++++ 4 files changed, 52 insertions(+) diff --git a/block.c b/block.c index 411edbf..74228b8 100644 --- a/block.c +++ b/block.c @@ -40,6 +40,8 @@ #include "qemu/timer.h" #include "qapi-event.h" #include "block/throttle-groups.h" +#include "qapi-types.h" +#include "qapi/util.h" #ifdef CONFIG_BSD #include <sys/types.h> @@ -895,6 +897,12 @@ static QemuOptsList bdrv_runtime_opts = { .type = QEMU_OPT_BOOL, .help = "Ignore flush requests", }, + { + .name = "lock", + .type = QEMU_OPT_STRING, + .help = "How to lock the image: none or lockfile", + .def_value_str = "none", + }, { /* end of list */ } }, }; @@ -914,6 +922,8 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file, QemuOpts *opts; BlockDriver *drv; Error *local_err = NULL; + const char *lock_image; + int lock; assert(bs->file == NULL); assert(options != NULL && bs->options != options); @@ -1020,6 +1030,18 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file, goto free_and_fail; } + lock_image = qemu_opt_get(opts, "lock"); + lock = qapi_enum_parse(BdrvLockImage_lookup, lock_image, + BDRV_LOCK_IMAGE__MAX, BDRV_LOCK_IMAGE_NONE, &local_err); + if (!bs->read_only && lock != BDRV_LOCK_IMAGE_NONE) { + ret = bdrv_lock_image(bs, lock); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not lock the image"); + bdrv_close(bs); + goto fail_opts; + } + } + if (bs->encrypted) { error_report("Encrypted images are deprecated"); error_printf("Support for them will be removed in a future release.\n" @@ -4320,3 +4342,22 @@ void bdrv_refresh_filename(BlockDriverState *bs) QDECREF(json); } } + +int bdrv_lock_image(BlockDriverState *bs, BdrvLockImage lock) +{ + BlockDriver *drv = bs->drv; + if (lock != BDRV_LOCK_IMAGE_LOCKFILE) { + return -EOPNOTSUPP; + } + if (drv != NULL && drv->bdrv_lock_image != NULL) { + return bs->drv->bdrv_lock_image(bs, lock); + } + if (bs->file == NULL) { + return -EOPNOTSUPP; + } + drv = bs->file->bs->drv; + if (drv != NULL && drv->bdrv_lock_image != NULL) { + return drv->bdrv_lock_image(bs, lock); + } + return -EOPNOTSUPP; +} diff --git a/include/block/block.h b/include/block/block.h index db8e096..27fc434 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -506,6 +506,7 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi); void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset); int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap); +int bdrv_lock_image(BlockDriverState *bs, BdrvLockImage lock); void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 256609d..755f342 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -135,6 +135,7 @@ struct BlockDriver { int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); int (*bdrv_make_empty)(BlockDriverState *bs); + int (*bdrv_lock_image)(BlockDriverState *bs, BdrvLockImage lock); void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options); diff --git a/qapi/block-core.json b/qapi/block-core.json index 1a5d9ce..b82589b 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2408,3 +2408,12 @@ ## { 'command': 'block-set-write-threshold', 'data': { 'node-name': 'str', 'write-threshold': 'uint64' } } + +## +# @BdrvLockImage: +# +#An enumeration of lock types to lock image file. +# @none - do not lock the image file +# @lockfile +## Since 2.6 +{ 'enum': 'BdrvLockImage', 'data':['none', 'lockfile']} -- 2.1.4