This commit changes the _qemuDomainStorageSourcePrivate struct
to support multiple secrets (instead of a single one before this commit).
This will useful for storage encryption requiring more than a single secret.
Signed-off-by: Or Ozeri <oro(a)il.ibm.com>
---
src/qemu/qemu_block.c | 22 +++++++-----
src/qemu/qemu_command.c | 20 ++++++-----
src/qemu/qemu_domain.c | 75 ++++++++++++++++++++++++++++++++---------
src/qemu/qemu_domain.h | 3 +-
tests/qemublocktest.c | 7 ++--
5 files changed, 91 insertions(+), 36 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 2e3e0f6572..f6d21d2040 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -581,7 +581,7 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src,
if (virJSONValueObjectAdd(&encrypt,
"s:format", encformat,
- "s:key-secret",
srcPriv->encinfo->alias,
+ "s:key-secret",
srcPriv->encinfo[0]->alias,
NULL) < 0)
return NULL;
}
@@ -978,7 +978,7 @@ qemuBlockStorageSourceGetFormatLUKSProps(virStorageSource *src,
{
qemuDomainStorageSourcePrivate *srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
- if (!srcPriv || !srcPriv->encinfo || !srcPriv->encinfo->alias) {
+ if (!srcPriv || !srcPriv->encinfo || !srcPriv->encinfo[0]->alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("missing secret info for 'luks' driver"));
return -1;
@@ -986,7 +986,7 @@ qemuBlockStorageSourceGetFormatLUKSProps(virStorageSource *src,
if (virJSONValueObjectAdd(&props,
"s:driver", "luks",
- "s:key-secret", srcPriv->encinfo->alias,
+ "s:key-secret",
srcPriv->encinfo[0]->alias,
NULL) < 0)
return -1;
@@ -1054,7 +1054,7 @@ qemuBlockStorageSourceGetCryptoProps(virStorageSource *src,
return virJSONValueObjectAdd(encprops,
"s:format", encformat,
- "s:key-secret",
srcpriv->encinfo->alias,
+ "s:key-secret",
srcpriv->encinfo[0]->alias,
NULL);
}
@@ -1616,13 +1616,17 @@ qemuBlockStorageSourceDetachPrepare(virStorageSource *src)
data->authsecretAlias = g_strdup(srcpriv->secinfo->alias);
if (srcpriv->encinfo) {
+ size_t i;
+
if (!data->encryptsecretAlias) {
- data->encryptsecretCount = 1;
- data->encryptsecretProps = g_new0(virJSONValue *, 1);
- data->encryptsecretAlias = g_new0(char *, 1);
+ data->encryptsecretCount = srcpriv->enccount;
+ data->encryptsecretProps = g_new0(virJSONValue *,
srcpriv->enccount);
+ data->encryptsecretAlias = g_new0(char *, srcpriv->enccount);
}
- data->encryptsecretAlias[0] = g_strdup(srcpriv->encinfo->alias);
+ for (i = 0; i < srcpriv->enccount; ++i) {
+ data->encryptsecretAlias[i] =
g_strdup(srcpriv->encinfo[i]->alias);
+ }
}
if (srcpriv->httpcookie)
@@ -1987,7 +1991,7 @@ qemuBlockStorageSourceCreateGetEncryptionLUKS(virStorageSource
*src,
if (srcpriv &&
srcpriv->encinfo)
- keysecret = srcpriv->encinfo->alias;
+ keysecret = srcpriv->encinfo[0]->alias;
if (virJSONValueObjectAdd(&props,
"s:key-secret", keysecret,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f5dcb46e42..69f0d74b92 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1603,7 +1603,7 @@ qemuBuildDriveSourceStr(virDomainDiskDef *disk,
{
virStorageType actualType = virStorageSourceGetActualType(disk->src);
qemuDomainStorageSourcePrivate *srcpriv =
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
- qemuDomainSecretInfo *encinfo = NULL;
+ qemuDomainSecretInfo **encinfo = NULL;
g_autoptr(virJSONValue) srcprops = NULL;
bool rawluks = false;
@@ -1647,12 +1647,12 @@ qemuBuildDriveSourceStr(virDomainDiskDef *disk,
if (encinfo) {
if (disk->src->format == VIR_STORAGE_FILE_RAW) {
- virBufferAsprintf(buf, "key-secret=%s,", encinfo->alias);
+ virBufferAsprintf(buf, "key-secret=%s,", encinfo[0]->alias);
rawluks = true;
} else if (disk->src->format == VIR_STORAGE_FILE_QCOW2 &&
disk->src->encryption->format ==
VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
virBufferAddLit(buf, "encrypt.format=luks,");
- virBufferAsprintf(buf, "encrypt.key-secret=%s,",
encinfo->alias);
+ virBufferAsprintf(buf, "encrypt.key-secret=%s,",
encinfo[0]->alias);
}
}
@@ -10644,14 +10644,18 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSource
*src,
return -1;
if (srcpriv->encinfo) {
+ size_t i;
+
if (!data->encryptsecretProps) {
- data->encryptsecretCount = 1;
- data->encryptsecretProps = g_new0(virJSONValue *, 1);
- data->encryptsecretAlias = g_new0(char *, 1);
+ data->encryptsecretCount = srcpriv->enccount;
+ data->encryptsecretProps = g_new0(virJSONValue *,
srcpriv->enccount);
+ data->encryptsecretAlias = g_new0(char *, srcpriv->enccount);
}
- if (qemuBuildSecretInfoProps(srcpriv->encinfo,
&data->encryptsecretProps[0]) < 0)
- return -1;
+ for (i = 0; i < srcpriv->enccount; ++i) {
+ if (qemuBuildSecretInfoProps(srcpriv->encinfo[i],
&data->encryptsecretProps[i]) < 0)
+ return -1;
+ }
}
if (srcpriv->httpcookie &&
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 80c9852dae..a3b9b57cfa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -872,7 +872,13 @@ qemuDomainStorageSourcePrivateDispose(void *obj)
qemuDomainStorageSourcePrivate *priv = obj;
g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
- g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree);
+ if (priv->encinfo) {
+ size_t i;
+ for (i = 0; i < priv->enccount; ++i) {
+ g_clear_pointer(&priv->encinfo[i], qemuDomainSecretInfoFree);
+ }
+ priv->encinfo = NULL;
+ }
g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree);
g_clear_pointer(&priv->tlsKeySecret, qemuDomainSecretInfoFree);
g_clear_pointer(&priv->fdpass, qemuFDPassFree);
@@ -1401,7 +1407,13 @@ qemuDomainSecretDiskDestroy(virDomainDiskDef *disk)
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
if ((srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(n))) {
qemuDomainSecretInfoDestroy(srcPriv->secinfo);
- qemuDomainSecretInfoDestroy(srcPriv->encinfo);
+ if (srcPriv->encinfo) {
+ size_t i;
+
+ for (i = 0; i < srcPriv->enccount; ++i) {
+ qemuDomainSecretInfoDestroy(srcPriv->encinfo[i]);
+ }
+ }
qemuDomainSecretInfoDestroy(srcPriv->tlsKeySecret);
}
}
@@ -1470,12 +1482,14 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivate *priv,
}
if (hasEnc) {
- if (!(srcPriv->encinfo = qemuDomainSecretInfoSetupFromSecret(priv,
aliasformat,
-
"encryption", 0,
-
VIR_SECRET_USAGE_TYPE_VOLUME,
- NULL,
-
&src->encryption->secrets[0]->seclookupdef)))
- return -1;
+ srcPriv->enccount = 1;
+ srcPriv->encinfo = g_new0(qemuDomainSecretInfo *, 1);
+ if (!(srcPriv->encinfo[0] = qemuDomainSecretInfoSetupFromSecret(priv,
aliasformat,
+
"encryption", 0,
+
VIR_SECRET_USAGE_TYPE_VOLUME,
+ NULL,
+
&src->encryption->secrets[0]->seclookupdef)))
+ return -1;
}
if (src->ncookies &&
@@ -1964,13 +1978,14 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
virStorageSource *src)
{
qemuDomainStorageSourcePrivate *priv;
+ g_autofree xmlNodePtr *encnodes = NULL;
g_autofree char *authalias = NULL;
- g_autofree char *encalias = NULL;
g_autofree char *httpcookiealias = NULL;
g_autofree char *tlskeyalias = NULL;
g_autofree char *thresholdEventWithIndex = NULL;
bool fdsetPresent = false;
unsigned int fdSetID;
+ int enccount;
src->nodestorage =
virXPathString("string(./nodenames/nodename[@type='storage']/@name)",
ctxt);
src->nodeformat =
virXPathString("string(./nodenames/nodename[@type='format']/@name)",
ctxt);
@@ -1983,13 +1998,16 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
src->pr->mgralias =
virXPathString("string(./reservations/@mgralias)", ctxt);
authalias =
virXPathString("string(./objects/secret[@type='auth']/@alias)", ctxt);
- encalias =
virXPathString("string(./objects/secret[@type='encryption']/@alias)",
ctxt);
+ if ((enccount =
virXPathNodeSet("./objects/secret[@type='encryption']", ctxt,
&encnodes)) < 0)
+ return -1;
httpcookiealias =
virXPathString("string(./objects/secret[@type='httpcookie']/@alias)",
ctxt);
tlskeyalias =
virXPathString("string(./objects/secret[@type='tlskey']/@alias)",
ctxt);
fdsetPresent =
virXPathUInt("string(./fdsets/fdset[@type='storage']/@id)", ctxt,
&fdSetID) == 0;
- if (authalias || encalias || httpcookiealias || tlskeyalias || fdsetPresent) {
+ if (authalias || (enccount > 0) || httpcookiealias || tlskeyalias || fdsetPresent)
{
+ size_t i;
+
if (!src->privateData &&
!(src->privateData = qemuDomainStorageSourcePrivateNew()))
return -1;
@@ -1999,8 +2017,27 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->secinfo,
&authalias) < 0)
return -1;
- if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo,
&encalias) < 0)
- return -1;
+ if (enccount > 0) {
+ xmlNodePtr tmp = ctxt->node;
+
+ priv->enccount = enccount;
+ priv->encinfo = g_new0(qemuDomainSecretInfo *, enccount);
+ for (i = 0; i < enccount; ++i) {
+ g_autofree char *encalias = NULL;
+
+ ctxt->node = encnodes[i];
+ if (!(encalias = virXMLPropString(encnodes[i], "alias"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing alias on encryption secret
#%lu"), i);
+ return -1;
+ }
+
+ if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo[i],
&encalias) < 0)
+ return -1;
+ }
+
+ ctxt->node = tmp;
+ }
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->httpcookie,
&httpcookiealias) < 0)
return -1;
@@ -2061,10 +2098,13 @@ qemuStorageSourcePrivateDataFormat(virStorageSource *src,
return -1;
if (srcPriv) {
+ size_t i;
unsigned int fdSetID;
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf,
srcPriv->secinfo, "auth");
- qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf,
srcPriv->encinfo, "encryption");
+ for (i = 0; i < srcPriv->enccount; ++i) {
+ qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf,
srcPriv->encinfo[i], "encryption");
+ }
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf,
srcPriv->httpcookie, "httpcookie");
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf,
srcPriv->tlsKeySecret, "tlskey");
@@ -5631,9 +5671,14 @@ qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDomainDiskDef
*disk,
}
if (restoreEncSecret) {
+ if (!priv->encinfo) {
+ priv->enccount = 1;
+ priv->encinfo = g_new0(qemuDomainSecretInfo *, 1);
+ }
+
encalias = g_strdup_printf("%s-luks-secret0", disk->info.alias);
- if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo,
&encalias) < 0)
+ if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo[0],
&encalias) < 0)
return -1;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 550397ee50..dda92b5da3 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -295,7 +295,8 @@ struct _qemuDomainStorageSourcePrivate {
qemuDomainSecretInfo *secinfo;
/* data required for decryption of encrypted storage source */
- qemuDomainSecretInfo *encinfo;
+ size_t enccount;
+ qemuDomainSecretInfo **encinfo;
/* secure passthrough of the http cookie */
qemuDomainSecretInfo *httpcookie;
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index 010b52f4b3..2d790e2b2e 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -237,10 +237,11 @@ testQemuDiskXMLToJSONFakeSecrets(virStorageSource *src)
}
if (src->encryption) {
- srcpriv->encinfo = g_new0(qemuDomainSecretInfo, 1);
+ srcpriv->encinfo = g_new0(qemuDomainSecretInfo *, 1);
+ srcpriv->encinfo[0] = g_new0(qemuDomainSecretInfo, 1);
- srcpriv->encinfo->alias = g_strdup_printf("%s-encalias",
- NULLSTR(src->nodeformat));
+ srcpriv->encinfo[0]->alias = g_strdup_printf("%s-encalias",
+ NULLSTR(src->nodeformat));
}
return 0;
--
2.25.1