[RFC 8/8] block: Support Gluks format image creation using qemu-img

Hyman Huang posted 8 patches 11 months, 4 weeks ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>
There is a newer version of this series
[RFC 8/8] block: Support Gluks format image creation using qemu-img
Posted by Hyman Huang 11 months, 4 weeks ago
To create a Gluks header image, use the command as follows:
$ qemu-img create --object secret,id=sec0,data=abc123 -f gluks
> -o cipher-alg=aes-256,cipher-mode=xts -o key-secret=sec0
> cipher.gluks

Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
 block.c              |  5 +++++
 block/generic-luks.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index bfb0861ec6..cc9a517a25 100644
--- a/block.c
+++ b/block.c
@@ -7517,6 +7517,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
         goto out;
     }
 
+    if (!strcmp(fmt, "gluks")) {
+        qemu_opt_set(opts, "size", "0M", &local_err);
+        size = 0;
+    }
+
     if (size == -1) {
         error_setg(errp, "Image creation needs a size parameter");
         goto out;
diff --git a/block/generic-luks.c b/block/generic-luks.c
index 32cbedc86f..579f01c4b0 100644
--- a/block/generic-luks.c
+++ b/block/generic-luks.c
@@ -145,7 +145,58 @@ static int coroutine_fn GRAPH_UNLOCKED
 gluks_co_create_opts(BlockDriver *drv, const char *filename,
                      QemuOpts *opts, Error **errp)
 {
-    return 0;
+    QCryptoBlockCreateOptions *create_opts = NULL;
+    BlockDriverState *bs = NULL;
+    QDict *cryptoopts;
+    int ret;
+
+    if (qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) != 0) {
+        info_report("gluks format image need not size parameter, ignore it");
+    }
+
+    cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
+                                             &gluks_create_opts_luks,
+                                             true);
+
+    qdict_put_str(cryptoopts, "format",
+        QCryptoBlockFormat_str(Q_CRYPTO_BLOCK_FORMAT_GLUKS));
+
+    create_opts = block_crypto_create_opts_init(cryptoopts, errp);
+    if (!create_opts) {
+        ret = -EINVAL;
+        goto fail;
+    }
+
+    /* Create protocol layer */
+    ret = bdrv_co_create_file(filename, opts, errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    bs = bdrv_co_open(filename, NULL, NULL,
+                      BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
+    if (!bs) {
+        ret = -EINVAL;
+        goto fail;
+    }
+    /* Create format layer */
+    ret = block_crypto_co_create_generic(bs, 0, create_opts, 0, errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    ret = 0;
+fail:
+    /*
+     * If an error occurred, delete 'filename'. Even if the file existed
+     * beforehand, it has been truncated and corrupted in the process.
+     */
+    if (ret) {
+        bdrv_graph_co_rdlock();
+        bdrv_co_delete_file_noerr(bs);
+        bdrv_graph_co_rdunlock();
+    }
+    return ret;
 }
 
 static void
-- 
2.39.1