[PATCH v1 5/7] qemu: add multi-secret support in _qemuDomainStorageSourcePrivate

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

 



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




[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]

  Powered by Linux