Since this cannot automatically recover from a crashed QEMU client with an RBD image, perhaps this RBD locking should not default to enabled. Additionally, this will conflict with the "exclusive-lock" feature available since the Ceph Hammer-release since both utilize the same locking construct.
As a quick background, the optional exclusive-lock feature can be enabled/disabled on image and safely/automatically handles the case of recovery from a crashed client. Under normal conditions, the RBD exclusive-lock feature automatically acquires the lock upon the first attempt to write to the image and transparently transitions ownership of the lock between two or more clients -- used for QEMU live-migration. I'd be happy to add a new librbd API method to explicitly expose acquiring and releasing the RBD exclusive lock since it certainly solves a couple compromises in our current QEMU integration. On Thu, Apr 14, 2016 at 11:27 PM, Fam Zheng <f...@redhat.com> wrote: > librbd has the locking API that can be used to implement .bdrv_lockf. > > Signed-off-by: Fam Zheng <f...@redhat.com> > --- > block/rbd.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/block/rbd.c b/block/rbd.c > index 5bc5b32..a495083 100644 > --- a/block/rbd.c > +++ b/block/rbd.c > @@ -810,6 +810,30 @@ static int qemu_rbd_truncate(BlockDriverState *bs, > int64_t offset) > return 0; > } > > +static int qemu_rbd_lockf(BlockDriverState *bs, BdrvLockfCmd cmd) > +{ > + int ret; > + BDRVRBDState *s = bs->opaque; > + > + /* XXX: RBD locks are not released automatically when program exits, > which > + * means if QEMU dies it cannot open the image next time until > manually > + * unlocked. */ > + switch (cmd) { > + case BDRV_LOCKF_RWLOCK: > + ret = rbd_lock_exclusive(s->image, NULL); > + break; > + case BDRV_LOCKF_ROLOCK: > + ret = rbd_lock_shared(s->image, NULL, NULL); > + break; > + case BDRV_LOCKF_UNLOCK: > + ret = rbd_unlock(s->image, NULL); > + break; > + default: > + abort(); > + } > + return ret; > +} > + > static int qemu_rbd_snap_create(BlockDriverState *bs, > QEMUSnapshotInfo *sn_info) > { > @@ -998,6 +1022,7 @@ static BlockDriver bdrv_rbd = { > .bdrv_aio_discard = qemu_rbd_aio_discard, > #endif > > + .bdrv_lockf = qemu_rbd_lockf, > .bdrv_snapshot_create = qemu_rbd_snap_create, > .bdrv_snapshot_delete = qemu_rbd_snap_remove, > .bdrv_snapshot_list = qemu_rbd_snap_list, > -- > 2.8.0 > > > -- Jason