Add qemu-img measure support in the "luks" block driver.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/crypto.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/block/crypto.c b/block/crypto.c
index 24823835c1..453119875e 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -484,6 +484,67 @@ static int64_t block_crypto_getlength(BlockDriverState *bs)
}
+static BlockMeasureInfo *block_crypto_measure(QemuOpts *opts,
+ BlockDriverState *in_bs,
+ Error **errp)
+{
+ g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
+ Error *local_err = NULL;
+ BlockMeasureInfo *info;
+ uint64_t size;
+ size_t luks_payload_size;
+ QDict *cryptoopts;
+
+ /*
+ * Preallocation mode doesn't affect size requirements but we must consume
+ * the option.
+ */
+ g_free(qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC));
+
+ size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+
+ if (in_bs) {
+ int64_t ssize = bdrv_getlength(in_bs);
+
+ if (ssize < 0) {
+ error_setg_errno(&local_err, -ssize,
+ "Unable to get image virtual_size");
+ goto err;
+ }
+
+ size = ssize;
+ }
+
+ cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
+ &block_crypto_create_opts_luks, true);
+ qdict_put_str(cryptoopts, "format", "luks");
+ create_opts = block_crypto_create_opts_init(cryptoopts, errp);
+ qobject_unref(cryptoopts);
+ if (!create_opts) {
+ goto err;
+ }
+
+ if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
+ &luks_payload_size,
+ &local_err)) {
+ goto err;
+ }
+
+ /*
+ * Unallocated blocks are still encrypted so allocation status makes no
+ * difference to the file size.
+ */
+ info = g_new(BlockMeasureInfo, 1);
+ info->fully_allocated = luks_payload_size + size;
+ info->required = luks_payload_size + size;
+ return info;
+
+err:
+ error_propagate(errp, local_err);
+ return NULL;
+}
+
+
static int block_crypto_probe_luks(const uint8_t *buf,
int buf_size,
const char *filename) {
@@ -670,6 +731,7 @@ static BlockDriver bdrv_crypto_luks = {
.bdrv_co_preadv = block_crypto_co_preadv,
.bdrv_co_pwritev = block_crypto_co_pwritev,
.bdrv_getlength = block_crypto_getlength,
+ .bdrv_measure = block_crypto_measure,
.bdrv_get_info = block_crypto_get_info_luks,
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
--
2.24.1
On 11.02.20 17:03, Stefan Hajnoczi wrote:
> Add qemu-img measure support in the "luks" block driver.
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> block/crypto.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 62 insertions(+)
>
> diff --git a/block/crypto.c b/block/crypto.c
> index 24823835c1..453119875e 100644
> --- a/block/crypto.c
> +++ b/block/crypto.c
> @@ -484,6 +484,67 @@ static int64_t block_crypto_getlength(BlockDriverState *bs)
[...]
> + cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
> + &block_crypto_create_opts_luks, true);
> + qdict_put_str(cryptoopts, "format", "luks");
> + create_opts = block_crypto_create_opts_init(cryptoopts, errp);
It looks a bit weird to me to use errp here...
> + qobject_unref(cryptoopts);
> + if (!create_opts) {
> + goto err;
> + }
> +
> + if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
> + &luks_payload_size,
> + &local_err)) {
...and local_err here. Either works, but consistent style would be a
bit nicer.
But not more correct, so:
Reviewed-by: Max Reitz <mreitz@redhat.com>
> + goto err;
> + }
[...]
> +err:
> + error_propagate(errp, local_err);
> + return NULL;
> +}
On Wed, Feb 19, 2020 at 04:46:34PM +0100, Max Reitz wrote:
> On 11.02.20 17:03, Stefan Hajnoczi wrote:
> > Add qemu-img measure support in the "luks" block driver.
> >
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > ---
> > block/crypto.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 62 insertions(+)
> >
> > diff --git a/block/crypto.c b/block/crypto.c
> > index 24823835c1..453119875e 100644
> > --- a/block/crypto.c
> > +++ b/block/crypto.c
> > @@ -484,6 +484,67 @@ static int64_t block_crypto_getlength(BlockDriverState *bs)
>
> [...]
>
> > + cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
> > + &block_crypto_create_opts_luks, true);
> > + qdict_put_str(cryptoopts, "format", "luks");
> > + create_opts = block_crypto_create_opts_init(cryptoopts, errp);
>
> It looks a bit weird to me to use errp here...
>
> > + qobject_unref(cryptoopts);
> > + if (!create_opts) {
> > + goto err;
> > + }
> > +
> > + if (!qcrypto_block_calculate_payload_offset(create_opts, NULL,
> > + &luks_payload_size,
> > + &local_err)) {
>
> ...and local_err here. Either works, but consistent style would be a
> bit nicer.
>
> But not more correct, so:
>
> Reviewed-by: Max Reitz <mreitz@redhat.com>
Thanks, will fix!
Stefan
© 2016 - 2025 Red Hat, Inc.