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(a)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