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

Reply via email to