Commit 30da9dd8 authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Max Reitz
Browse files

block/crypto: implement blockdev-amend



Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Message-Id: <20200608094030.670121-13-mlevitsk@redhat.com>
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent ced914d0
Loading
Loading
Loading
Loading
+53 −19
Original line number Diff line number Diff line
@@ -791,32 +791,21 @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
}

static int
block_crypto_amend_options_luks(BlockDriverState *bs,
                                QemuOpts *opts,
                                BlockDriverAmendStatusCB *status_cb,
                                void *cb_opaque,
block_crypto_amend_options_generic_luks(BlockDriverState *bs,
                                        QCryptoBlockAmendOptions *amend_options,
                                        bool force,
                                        Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    QDict *cryptoopts = NULL;
    QCryptoBlockAmendOptions *amend_options = NULL;
    int ret;

    assert(crypto);
    assert(crypto->block);
    crypto->updating_keys = true;

    /* apply for exclusive read/write permissions to the underlying file*/
    crypto->updating_keys = true;
    ret = bdrv_child_refresh_perms(bs, bs->file, errp);
    if (ret < 0) {
        goto cleanup;
    }

    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    qdict_put_str(cryptoopts, "format", "luks");
    amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
    if (!amend_options) {
        ret = -EINVAL;
    if (ret) {
        goto cleanup;
    }

@@ -828,13 +817,57 @@ block_crypto_amend_options_luks(BlockDriverState *bs,
                                      force,
                                      errp);
cleanup:
    /* release exclusive read/write permissions to the underlying file*/
    crypto->updating_keys = false;
    bdrv_child_refresh_perms(bs, bs->file, errp);
    qapi_free_QCryptoBlockAmendOptions(amend_options);
    return ret;
}

static int
block_crypto_amend_options_luks(BlockDriverState *bs,
                                QemuOpts *opts,
                                BlockDriverAmendStatusCB *status_cb,
                                void *cb_opaque,
                                bool force,
                                Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    QDict *cryptoopts = NULL;
    QCryptoBlockAmendOptions *amend_options = NULL;
    int ret = -EINVAL;

    assert(crypto);
    assert(crypto->block);

    cryptoopts = qemu_opts_to_qdict(opts, NULL);
    qdict_put_str(cryptoopts, "format", "luks");
    amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
    qobject_unref(cryptoopts);
    if (!amend_options) {
        goto cleanup;
    }
    ret = block_crypto_amend_options_generic_luks(bs, amend_options,
                                                  force, errp);
cleanup:
    qapi_free_QCryptoBlockAmendOptions(amend_options);
    return ret;
}

static int
coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
                                        BlockdevAmendOptions *opts,
                                        bool force,
                                        Error **errp)
{
    QCryptoBlockAmendOptions amend_opts;

    amend_opts = (QCryptoBlockAmendOptions) {
        .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
        .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
    };
    return block_crypto_amend_options_generic_luks(bs, &amend_opts,
                                                   force, errp);
}

static void
block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
@@ -910,6 +943,7 @@ static BlockDriver bdrv_crypto_luks = {
    .bdrv_get_info      = block_crypto_get_info_luks,
    .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
    .bdrv_amend_options = block_crypto_amend_options_luks,
    .bdrv_co_amend      = block_crypto_co_amend_luks,

    .is_format          = true,

+13 −1
Original line number Diff line number Diff line
@@ -4674,6 +4674,18 @@
  'data': { 'job-id': 'str',
            'options': 'BlockdevCreateOptions' } }

##
# @BlockdevAmendOptionsLUKS:
#
# Driver specific image amend options for LUKS.
#
# Since: 5.1
##
{ 'struct': 'BlockdevAmendOptionsLUKS',
  'base': 'QCryptoBlockAmendOptionsLUKS',
  'data': { }
}

##
# @BlockdevAmendOptions:
#
@@ -4688,7 +4700,7 @@
      'driver':         'BlockdevDriver' },
  'discriminator': 'driver',
  'data': {
  } }
      'luks':           'BlockdevAmendOptionsLUKS' } }

##
# @x-blockdev-amend: