Re: [PATCH v4 4/7] storage: Add support to create a luks volume

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

 



On Mon, Jul 11, 2016 at 02:07:55PM -0400, John Ferlan wrote:
Partially resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1301021

If the volume xml was looking to create a luks volume take the necessary
steps in order to make that happen.

The processing will be:
1. create a temporary file (virStorageBackendCreateQemuImgSecretPath)
  1a. use the storage driver state dir path that uses the pool and
      volume name as a base.

2. create a secret object (virStorageBackendCreateQemuImgSecretObject)
  2a. use an alias combinding the volume name and "_luks0"
  2b. add the file to the object

3. create/add luks options to the commandline (virQEMUBuildLuksOpts)
  3a. at the very least a "key-secret=%s" using the secret object alias
  3b. if found in the XML the various "cipher" and "ivgen" options

Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx>
---
src/libvirt_private.syms       |   1 +
src/storage/storage_backend.c  | 218 ++++++++++++++++++++++++++++++++++++++---
src/storage/storage_backend.h  |   3 +-
src/util/virqemu.c             |  23 +++++
src/util/virqemu.h             |   6 ++
tests/storagevolxml2argvtest.c |   3 +-
6 files changed, 240 insertions(+), 14 deletions(-)


@@ -1140,6 +1186,43 @@ virStorageBackendCreateQemuImgSetOptions(virCommandPtr cmd,
}


+/* Add a secret object to the command line:
+ *    --object secret,id=$secretAlias,file=$secretPath
+ *
+ *    NB: format=raw is assumed
+ */
+static int
+virStorageBackendCreateQemuImgSecretObject(virCommandPtr cmd,
+                                           virStorageVolDefPtr vol,
+                                           struct _virStorageBackendQemuImgInfo *info)
+{
+    char *str = NULL;

This variable is unused.

+    virJSONValuePtr props = NULL;
+    char *commandStr = NULL;
+

+    if (virAsprintf(&info->secretAlias, "%s_luks0", vol->name) < 0) {
+        VIR_FREE(str);
+        return -1;
+    }
+    VIR_FREE(str);
+
+    if (virJSONValueObjectCreate(&props, "s:file", info->secretPath, NULL) < 0)
+        return -1;
+
+    if (!(commandStr = virQEMUBuildObjectCommandlineFromJSON("secret",
+                                                             info->secretAlias,
+                                                             props))) {
+        virJSONValueFree(props);
+        return -1;
+    }
+    virJSONValueFree(props);
+

So, this will generate:
--object secret,id=volume_luks0,file=/path/to/tmp/luksfile

Since we only have one property and one alias here, there is no need to
go through JSON, it can be just a single virCommandAddArgFormat call.

(or we need to go through a virBuffer to use qemuBufferEscapeComma in
case we allow commas in storage pool names).

+    virCommandAddArgList(cmd, "--object", commandStr, NULL);
+ + return 0;
+}
+
+
/* Create a qemu-img virCommand from the supplied binary path,
 * volume definitions and imgformat
 */
@@ -1150,7 +1233,8 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
                                         virStorageVolDefPtr inputvol,
                                         unsigned int flags,
                                         const char *create_tool,
-                                         int imgformat)
+                                         int imgformat,
+                                         const char *secretPath)
{
    virCommandPtr cmd = NULL;
    const char *type;
@@ -1162,7 +1246,10 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
        .compat = vol->target.compat,
        .features = vol->target.features,
        .nocow = vol->target.nocow,
+        .secretPath = secretPath,
+        .secretAlias = NULL,

Since we only ever give one secret on the command line, this can be a
static string.

    };
+    virStorageEncryptionInfoDefPtr enc = NULL;

    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);


diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 895168e..dd7a59f 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -140,3 +140,26 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
    virBufferFreeAndReset(&buf);
    return ret;
}
+
+
+void
+virQEMUBuildLuksOpts(virBufferPtr buf,
+                     virStorageEncryptionInfoDefPtr enc,
+                     const char *alias)
+{
+    virBufferAsprintf(buf, "key-secret=%s,", alias);
+
+    /* If there's any cipher, then add that to the command line */

+    if (enc->cipher_name) {
+        virBufferEscapeString(buf, "cipher-alg=%s-", enc->cipher_name);
+        virBufferAsprintf(buf, "%u,", enc->cipher_size);
+        if (enc->cipher_mode)
+            virBufferEscapeString(buf, "cipher-mode=%s,", enc->cipher_mode);
+        if (enc->cipher_hash)
+            virBufferEscapeString(buf, "hash-alg=%s,", enc->cipher_hash);
+        if (enc->ivgen_name)
+            virBufferEscapeString(buf, "ivgen-alg=%s,", enc->ivgen_name);
+        if (enc->ivgen_hash)
+            virBufferEscapeString(buf, "ivgen-hash-alg=%s,", enc->ivgen_hash);

s/virBufferEscapeString/qemuBufferEscapeComma/

This is QEMU command line, not XML. Also, both of the functions are
no-ops if the string is NULL, so the ifs are not necessary.

ACK with that fixed and the unused 'str' variable removed.

Jan

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]