[libvirt] [PATCH v4 4/7] storage: Add support to create a luks volume
Ján Tomko
jtomko at redhat.com
Thu Jul 14 13:13:56 UTC 2016
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 at redhat.com>
>---
> 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
More information about the libvir-list
mailing list