The qcow2 .bdrv_measure() code calculates the crypto payload offset.
This logic really belongs in block/crypto.c where it can be reused by
other image formats.
The "luks" block driver will need this same logic in order to implement
.bdrv_measure(), so extract the block_crypto_calculate_payload_offset()
function now.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
block/crypto.h | 5 ++++
block/qcow2.c | 59 ++++------------------------------------------
3 files changed, 73 insertions(+), 55 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 24823835c1..ed32202fa2 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -185,6 +185,70 @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
}
+static ssize_t block_crypto_headerlen_hdr_init_func(QCryptoBlock *block,
+ size_t headerlen, void *opaque, Error **errp)
+{
+ size_t *headerlenp = opaque;
+
+ /* Stash away the payload size */
+ *headerlenp = headerlen;
+ return 0;
+}
+
+
+static ssize_t block_crypto_headerlen_hdr_write_func(QCryptoBlock *block,
+ size_t offset, const uint8_t *buf, size_t buflen,
+ void *opaque, Error **errp)
+{
+ /* Discard the bytes, we're not actually writing to an image */
+ return buflen;
+}
+
+
+/* Determine the number of bytes for the crypto header */
+bool block_crypto_calculate_payload_offset(QemuOpts *opts,
+ const char *optprefix,
+ size_t *len,
+ Error **errp)
+{
+ QDict *cryptoopts_qdict;
+ QCryptoBlockCreateOptions *cryptoopts;
+ QCryptoBlock *crypto;
+
+ /* Extract options into a qdict */
+ if (optprefix) {
+ QDict *opts_qdict = qemu_opts_to_qdict(opts, NULL);
+
+ qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, optprefix);
+ qobject_unref(opts_qdict);
+ } else {
+ cryptoopts_qdict = qemu_opts_to_qdict(opts, NULL);
+ }
+
+ /* Build QCryptoBlockCreateOptions object from qdict */
+ qdict_put_str(cryptoopts_qdict, "format", "luks");
+
+ cryptoopts = block_crypto_create_opts_init(cryptoopts_qdict, errp);
+ qobject_unref(cryptoopts_qdict);
+ if (!cryptoopts) {
+ return false;
+ }
+
+ /* Fake LUKS creation in order to determine the payload size */
+ crypto = qcrypto_block_create(cryptoopts, optprefix,
+ block_crypto_headerlen_hdr_init_func,
+ block_crypto_headerlen_hdr_write_func,
+ len, errp);
+ qapi_free_QCryptoBlockCreateOptions(cryptoopts);
+ if (!crypto) {
+ return false;
+ }
+
+ qcrypto_block_free(crypto);
+ return true;
+}
+
+
static int block_crypto_open_generic(QCryptoBlockFormat format,
QemuOptsList *opts_spec,
BlockDriverState *bs,
diff --git a/block/crypto.h b/block/crypto.h
index b935695e79..5a39bee71b 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -94,4 +94,9 @@ block_crypto_create_opts_init(QDict *opts, Error **errp);
QCryptoBlockOpenOptions *
block_crypto_open_opts_init(QDict *opts, Error **errp);
+bool block_crypto_calculate_payload_offset(QemuOpts *opts,
+ const char *optprefix,
+ size_t *len,
+ Error **errp);
+
#endif /* BLOCK_CRYPTO_H */
diff --git a/block/qcow2.c b/block/qcow2.c
index cef9d72b3a..3aaf79bbf6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -4609,60 +4609,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
return ret;
}
-static ssize_t qcow2_measure_crypto_hdr_init_func(QCryptoBlock *block,
- size_t headerlen, void *opaque, Error **errp)
-{
- size_t *headerlenp = opaque;
-
- /* Stash away the payload size */
- *headerlenp = headerlen;
- return 0;
-}
-
-static ssize_t qcow2_measure_crypto_hdr_write_func(QCryptoBlock *block,
- size_t offset, const uint8_t *buf, size_t buflen,
- void *opaque, Error **errp)
-{
- /* Discard the bytes, we're not actually writing to an image */
- return buflen;
-}
-
-/* Determine the number of bytes for the LUKS payload */
-static bool qcow2_measure_luks_headerlen(QemuOpts *opts, size_t *len,
- Error **errp)
-{
- QDict *opts_qdict;
- QDict *cryptoopts_qdict;
- QCryptoBlockCreateOptions *cryptoopts;
- QCryptoBlock *crypto;
-
- /* Extract "encrypt." options into a qdict */
- opts_qdict = qemu_opts_to_qdict(opts, NULL);
- qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
- qobject_unref(opts_qdict);
-
- /* Build QCryptoBlockCreateOptions object from qdict */
- qdict_put_str(cryptoopts_qdict, "format", "luks");
- cryptoopts = block_crypto_create_opts_init(cryptoopts_qdict, errp);
- qobject_unref(cryptoopts_qdict);
- if (!cryptoopts) {
- return false;
- }
-
- /* Fake LUKS creation in order to determine the payload size */
- crypto = qcrypto_block_create(cryptoopts, "encrypt.",
- qcow2_measure_crypto_hdr_init_func,
- qcow2_measure_crypto_hdr_write_func,
- len, errp);
- qapi_free_QCryptoBlockCreateOptions(cryptoopts);
- if (!crypto) {
- return false;
- }
-
- qcrypto_block_free(crypto);
- return true;
-}
-
static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
Error **errp)
{
@@ -4715,7 +4661,10 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
if (has_luks) {
size_t headerlen;
- if (!qcow2_measure_luks_headerlen(opts, &headerlen, &local_err)) {
+ if (!block_crypto_calculate_payload_offset(opts,
+ "encrypt.",
+ &headerlen,
+ &local_err)) {
goto err;
}
--
2.24.1
On 09.01.20 12:10, Stefan Hajnoczi wrote:
> The qcow2 .bdrv_measure() code calculates the crypto payload offset.
> This logic really belongs in block/crypto.c where it can be reused by
> other image formats.
>
> The "luks" block driver will need this same logic in order to implement
> .bdrv_measure(), so extract the block_crypto_calculate_payload_offset()
> function now.
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> block/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
> block/crypto.h | 5 ++++
> block/qcow2.c | 59 ++++------------------------------------------
> 3 files changed, 73 insertions(+), 55 deletions(-)
>
> diff --git a/block/crypto.c b/block/crypto.c
> index 24823835c1..ed32202fa2 100644
> --- a/block/crypto.c
> +++ b/block/crypto.c
> @@ -185,6 +185,70 @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
[...]
> +/* Determine the number of bytes for the crypto header */
> +bool block_crypto_calculate_payload_offset(QemuOpts *opts,
> + const char *optprefix,
> + size_t *len,
> + Error **errp)
> +{
> + QDict *cryptoopts_qdict;
> + QCryptoBlockCreateOptions *cryptoopts;
> + QCryptoBlock *crypto;
> +
> + /* Extract options into a qdict */
> + if (optprefix) {
> + QDict *opts_qdict = qemu_opts_to_qdict(opts, NULL);
> +
> + qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, optprefix);
> + qobject_unref(opts_qdict);
> + } else {
> + cryptoopts_qdict = qemu_opts_to_qdict(opts, NULL);
> + }
> +
> + /* Build QCryptoBlockCreateOptions object from qdict */
> + qdict_put_str(cryptoopts_qdict, "format", "luks");
Should this be a parameter?
Max
On Tue, Jan 14, 2020 at 04:25:44PM +0100, Max Reitz wrote:
> On 09.01.20 12:10, Stefan Hajnoczi wrote:
> > The qcow2 .bdrv_measure() code calculates the crypto payload offset.
> > This logic really belongs in block/crypto.c where it can be reused by
> > other image formats.
> >
> > The "luks" block driver will need this same logic in order to implement
> > .bdrv_measure(), so extract the block_crypto_calculate_payload_offset()
> > function now.
> >
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > ---
> > block/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > block/crypto.h | 5 ++++
> > block/qcow2.c | 59 ++++------------------------------------------
> > 3 files changed, 73 insertions(+), 55 deletions(-)
> >
> > diff --git a/block/crypto.c b/block/crypto.c
> > index 24823835c1..ed32202fa2 100644
> > --- a/block/crypto.c
> > +++ b/block/crypto.c
> > @@ -185,6 +185,70 @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
>
> [...]
>
> > +/* Determine the number of bytes for the crypto header */
> > +bool block_crypto_calculate_payload_offset(QemuOpts *opts,
> > + const char *optprefix,
> > + size_t *len,
> > + Error **errp)
> > +{
> > + QDict *cryptoopts_qdict;
> > + QCryptoBlockCreateOptions *cryptoopts;
> > + QCryptoBlock *crypto;
> > +
> > + /* Extract options into a qdict */
> > + if (optprefix) {
> > + QDict *opts_qdict = qemu_opts_to_qdict(opts, NULL);
> > +
> > + qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, optprefix);
> > + qobject_unref(opts_qdict);
> > + } else {
> > + cryptoopts_qdict = qemu_opts_to_qdict(opts, NULL);
> > + }
> > +
> > + /* Build QCryptoBlockCreateOptions object from qdict */
> > + qdict_put_str(cryptoopts_qdict, "format", "luks");
>
> Should this be a parameter?
Maybe one day, but there are no users who need it yet.
Stefan
On 15.01.20 14:40, Stefan Hajnoczi wrote:
> On Tue, Jan 14, 2020 at 04:25:44PM +0100, Max Reitz wrote:
>> On 09.01.20 12:10, Stefan Hajnoczi wrote:
>>> The qcow2 .bdrv_measure() code calculates the crypto payload offset.
>>> This logic really belongs in block/crypto.c where it can be reused by
>>> other image formats.
>>>
>>> The "luks" block driver will need this same logic in order to implement
>>> .bdrv_measure(), so extract the block_crypto_calculate_payload_offset()
>>> function now.
>>>
>>> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
>>> ---
>>> block/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> block/crypto.h | 5 ++++
>>> block/qcow2.c | 59 ++++------------------------------------------
>>> 3 files changed, 73 insertions(+), 55 deletions(-)
>>>
>>> diff --git a/block/crypto.c b/block/crypto.c
>>> index 24823835c1..ed32202fa2 100644
>>> --- a/block/crypto.c
>>> +++ b/block/crypto.c
>>> @@ -185,6 +185,70 @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
>>
>> [...]
>>
>>> +/* Determine the number of bytes for the crypto header */
>>> +bool block_crypto_calculate_payload_offset(QemuOpts *opts,
>>> + const char *optprefix,
>>> + size_t *len,
>>> + Error **errp)
>>> +{
>>> + QDict *cryptoopts_qdict;
>>> + QCryptoBlockCreateOptions *cryptoopts;
>>> + QCryptoBlock *crypto;
>>> +
>>> + /* Extract options into a qdict */
>>> + if (optprefix) {
>>> + QDict *opts_qdict = qemu_opts_to_qdict(opts, NULL);
>>> +
>>> + qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, optprefix);
>>> + qobject_unref(opts_qdict);
>>> + } else {
>>> + cryptoopts_qdict = qemu_opts_to_qdict(opts, NULL);
>>> + }
>>> +
>>> + /* Build QCryptoBlockCreateOptions object from qdict */
>>> + qdict_put_str(cryptoopts_qdict, "format", "luks");
>>
>> Should this be a parameter?
>
> Maybe one day, but there are no users who need it yet.
Sure, but would it hurt? O:-)
I’m just asking because this file doesn’t implement luks crypto, so it
seems a bit strange to reference it here. Actually, now that I think
about it... This file only implements the luks block driver. Is this
even the right place for the common
block_crypto_calculate_payload_offset() function? Would it make more
sense in crypto/block.c or crypto/block-luks.c?
Max
© 2016 - 2026 Red Hat, Inc.