
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@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