All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, "Max Reitz" <mreitz@redhat.com>,
	"Kevin Wolf" <kwolf@redhat.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH 1/2] qcow2: include LUKS payload overhead in qemu-img measure
Date: Tue, 15 Jan 2019 11:10:06 +0000	[thread overview]
Message-ID: <20190115111007.27159-2-stefanha@redhat.com> (raw)
In-Reply-To: <20190115111007.27159-1-stefanha@redhat.com>

LUKS encryption reserves clusters for its own payload data.  The size of
this area must be included in the qemu-img measure calculation so that
we arrive at the correct minimum required image size.

(Ab)use the qcrypto_block_create() API to determine the payload
overhead.  We discard the payload data that qcrypto thinks will be
written to the image.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/qcow2.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 4897abae5e..7ab93a5d2f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -4231,6 +4231,24 @@ 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;
+}
+
 static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
                                        Error **errp)
 {
@@ -4240,11 +4258,13 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
     uint64_t virtual_size; /* disk size as seen by guest */
     uint64_t refcount_bits;
     uint64_t l2_tables;
+    uint64_t luks_payload_size = 0;
     size_t cluster_size;
     int version;
     char *optstr;
     PreallocMode prealloc;
     bool has_backing_file;
+    bool has_luks;
 
     /* Parse image creation options */
     cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err);
@@ -4274,6 +4294,35 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
     has_backing_file = !!optstr;
     g_free(optstr);
 
+    optstr = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT);
+    has_luks = optstr && strcmp(optstr, "luks") == 0;
+    g_free(optstr);
+
+    if (has_luks) {
+        QCryptoBlockCreateOptions cryptoopts = {
+            .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
+        };
+        QCryptoBlock *crypto;
+        size_t headerlen;
+
+        optstr = qemu_opt_get_del(opts, "encrypt.key-secret");
+        cryptoopts.u.luks.has_key_secret = !!optstr;
+        cryptoopts.u.luks.key_secret = optstr;
+
+        crypto = qcrypto_block_create(&cryptoopts, "encrypt.",
+                                      qcow2_measure_crypto_hdr_init_func,
+                                      qcow2_measure_crypto_hdr_write_func,
+                                      &headerlen, &local_err);
+
+        g_free(optstr);
+        if (!crypto) {
+            goto err;
+        }
+        qcrypto_block_free(crypto);
+
+        luks_payload_size = ROUND_UP(headerlen, cluster_size);
+    }
+
     virtual_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
     virtual_size = ROUND_UP(virtual_size, cluster_size);
 
@@ -4344,7 +4393,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
     info = g_new(BlockMeasureInfo, 1);
     info->fully_allocated =
         qcow2_calc_prealloc_size(virtual_size, cluster_size,
-                                 ctz32(refcount_bits));
+                                 ctz32(refcount_bits)) + luks_payload_size;
 
     /* Remove data clusters that are not required.  This overestimates the
      * required size because metadata needed for the fully allocated file is
-- 
2.20.1

  reply	other threads:[~2019-01-15 11:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-15 11:10 [Qemu-devel] [PATCH 0/2] qcow2: include LUKS payload overhead in qemu-img measure Stefan Hajnoczi
2019-01-15 11:10 ` Stefan Hajnoczi [this message]
2019-01-21 13:08   ` [Qemu-devel] [PATCH 1/2] " Max Reitz
2019-01-21 13:15     ` Max Reitz
2019-01-21 13:29       ` Max Reitz
2019-01-21 13:45       ` Daniel P. Berrangé
2019-01-21 14:46         ` Stefan Hajnoczi
2019-01-15 11:10 ` [Qemu-devel] [PATCH 2/2] iotests: add LUKS payload overhead to 178 qemu-img measure test Stefan Hajnoczi
2019-01-21 13:13   ` Max Reitz
2019-01-15 11:49 ` [Qemu-devel] [PATCH 0/2] qcow2: include LUKS payload overhead in qemu-img measure Philippe Mathieu-Daudé
2019-01-21  1:51 ` no-reply
2019-01-21 10:35   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190115111007.27159-2-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=berrange@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.