qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 02/17] block: add ability to set a prefix for opt


From: Daniel P. Berrange
Subject: [Qemu-devel] [PATCH v2 02/17] block: add ability to set a prefix for opt names
Date: Tue, 24 Jan 2017 14:51:37 +0000

When integrating the crypto support with qcow/qcow2, we don't
want to use the bare LUKS option names "hash-alg", "key-secret",
etc. We want to namespace them "luks-hash-alg", "luks-key-secret"
so that they don't clash with any general qcow options at a later
date.

Reviewed-by: Max Reitz <address@hidden>
Signed-off-by: Daniel P. Berrange <address@hidden>
---
 block/crypto.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 block/crypto.h |  42 +++++++++++-----------
 2 files changed, 119 insertions(+), 34 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index d281de6..876eabc 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -27,6 +27,7 @@
 #include "qapi-visit.h"
 #include "qapi/error.h"
 #include "block/crypto.h"
+#include "qemu/cutils.h"
 
 typedef struct BlockCrypto BlockCrypto;
 
@@ -128,7 +129,7 @@ static QemuOptsList block_crypto_runtime_opts_luks = {
     .name = "crypto",
     .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
     .desc = {
-        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
+        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
         { /* end of list */ }
     },
 };
@@ -143,31 +144,101 @@ static QemuOptsList block_crypto_create_opts_luks = {
             .type = QEMU_OPT_SIZE,
             .help = "Virtual disk size"
         },
-        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG,
-        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME,
+        BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
+        BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
         { /* end of list */ }
     },
 };
 
+static QemuOptsList empty_opts = {
+    .name = "crypto-empty",
+    .merge_lists = false,
+    .head = QTAILQ_HEAD_INITIALIZER(empty_opts.head),
+    .desc = {
+        /* no elements => accept any params */
+        { /* end of list */ }
+    },
+};
+
+
+struct BlockCryptoCopyData {
+    QemuOpts *opts;
+    const char *prefix;
+};
+
+static int block_crypto_copy_value(void *opaque, const char *name,
+                                   const char *value, Error **errp)
+{
+    struct BlockCryptoCopyData *data = opaque;
+    const char *newname;
+
+    if (strstart(name, data->prefix, &newname)) {
+        Error *local_err = NULL;
+
+        qemu_opt_set(data->opts, newname, value, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Create a copy of @opts containing only the fields with
+ * a prefix of @prefix, stripping the prefix in the returned
+ * opts
+ */
+static QemuOpts *
+block_crypto_copy_opts(QemuOpts *opts,
+                       const char *prefix,
+                       Error **errp)
+{
+    struct BlockCryptoCopyData data = {
+        .opts = qemu_opts_create(&empty_opts, NULL, false, errp),
+        .prefix = prefix
+    };
+    if (!data.opts) {
+        return NULL;
+    }
+
+    if (qemu_opt_foreach(opts, block_crypto_copy_value, &data, errp) < 0) {
+        qemu_opts_del(data.opts);
+        return NULL;
+    }
+
+    return data.opts;
+}
 
 QCryptoBlockOpenOptions *
 block_crypto_open_opts_init(QCryptoBlockFormat format,
                             QemuOpts *opts,
+                            const char *prefix,
                             Error **errp)
 {
-    Visitor *v;
+    Visitor *v = NULL;
     QCryptoBlockOpenOptions *ret = NULL;
     Error *local_err = NULL;
+    QemuOpts *newopts = NULL;
 
     ret = g_new0(QCryptoBlockOpenOptions, 1);
     ret->format = format;
 
-    v = opts_visitor_new(opts);
+    if (prefix != NULL) {
+        newopts = block_crypto_copy_opts(opts, prefix, &local_err);
+        if (local_err) {
+            goto out;
+        }
+        v = opts_visitor_new(newopts);
+    } else {
+        v = opts_visitor_new(opts);
+    }
 
     visit_start_struct(v, NULL, NULL, 0, &local_err);
     if (local_err) {
@@ -196,6 +267,7 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
         qapi_free_QCryptoBlockOpenOptions(ret);
         ret = NULL;
     }
+    qemu_opts_del(newopts);
     visit_free(v);
     return ret;
 }
@@ -204,16 +276,26 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
 QCryptoBlockCreateOptions *
 block_crypto_create_opts_init(QCryptoBlockFormat format,
                               QemuOpts *opts,
+                              const char *prefix,
                               Error **errp)
 {
-    Visitor *v;
+    Visitor *v = NULL;
     QCryptoBlockCreateOptions *ret = NULL;
     Error *local_err = NULL;
+    QemuOpts *newopts = NULL;
 
     ret = g_new0(QCryptoBlockCreateOptions, 1);
     ret->format = format;
 
-    v = opts_visitor_new(opts);
+    if (prefix != NULL) {
+        newopts = block_crypto_copy_opts(opts, prefix, &local_err);
+        if (local_err) {
+            goto out;
+        }
+        v = opts_visitor_new(newopts);
+    } else {
+        v = opts_visitor_new(opts);
+    }
 
     visit_start_struct(v, NULL, NULL, 0, &local_err);
     if (local_err) {
@@ -242,6 +324,7 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
         qapi_free_QCryptoBlockCreateOptions(ret);
         ret = NULL;
     }
+    qemu_opts_del(newopts);
     visit_free(v);
     return ret;
 }
@@ -268,7 +351,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat 
format,
         goto cleanup;
     }
 
-    open_opts = block_crypto_open_opts_init(format, opts, errp);
+    open_opts = block_crypto_open_opts_init(format, opts, NULL, errp);
     if (!open_opts) {
         goto cleanup;
     }
@@ -312,7 +395,7 @@ static int block_crypto_create_generic(QCryptoBlockFormat 
format,
         .filename = filename,
     };
 
-    create_opts = block_crypto_create_opts_init(format, opts, errp);
+    create_opts = block_crypto_create_opts_init(format, opts, NULL, errp);
     if (!create_opts) {
         return -1;
     }
diff --git a/block/crypto.h b/block/crypto.h
index e42f20e..e70e2f0 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -29,51 +29,51 @@
 #define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
 #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET                            \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix)                    \
     {                                                                   \
-        .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,                       \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,                \
         .type = QEMU_OPT_STRING,                                        \
         .help = "ID of the secret that provides the keyslot passphrase", \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG               \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix)       \
     {                                                      \
-        .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG,          \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG,   \
         .type = QEMU_OPT_STRING,                           \
         .help = "Name of encryption cipher algorithm",     \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE         \
-    {                                                 \
-        .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE,    \
-        .type = QEMU_OPT_STRING,                      \
-        .help = "Name of encryption cipher mode",     \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(prefix)      \
+    {                                                      \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE,  \
+        .type = QEMU_OPT_STRING,                           \
+        .help = "Name of encryption cipher mode",          \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG           \
-    {                                                 \
-        .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG,      \
-        .type = QEMU_OPT_STRING,                      \
-        .help = "Name of IV generator algorithm",     \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(prefix)     \
+    {                                                   \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \
+        .type = QEMU_OPT_STRING,                        \
+        .help = "Name of IV generator algorithm",       \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG                \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(prefix)        \
     {                                                           \
-        .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG,           \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG,    \
         .type = QEMU_OPT_STRING,                                \
         .help = "Name of IV generator hash algorithm",          \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG               \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(prefix)       \
     {                                                    \
-        .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG,          \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_HASH_ALG,   \
         .type = QEMU_OPT_STRING,                         \
         .help = "Name of encryption hash algorithm",     \
     }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME                   \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(prefix)           \
     {                                                         \
-        .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME,              \
+        .name = prefix BLOCK_CRYPTO_OPT_LUKS_ITER_TIME,       \
         .type = QEMU_OPT_NUMBER,                              \
         .help = "Time to spend in PBKDF in milliseconds",     \
     }
@@ -81,11 +81,13 @@
 QCryptoBlockCreateOptions *
 block_crypto_create_opts_init(QCryptoBlockFormat format,
                               QemuOpts *opts,
+                              const char *prefix,
                               Error **errp);
 
 QCryptoBlockOpenOptions *
 block_crypto_open_opts_init(QCryptoBlockFormat format,
                             QemuOpts *opts,
+                            const char *prefix,
                             Error **errp);
 
 #endif /* BLOCK_CRYPTO_H__ */
-- 
2.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]