[PATCH 4/7] qemu: domain: Allow preserving translated disk type='volume' data into XML if needed

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

 



Re-translating a disk type='volume' definition from a storage pool is
not a good idea in cases when the volume might have changed or we might
not have access to the storage driver.

Specific cases are if a storage pool is not activated on daemon restart,
then re-connecting to a VM fails, or if the virt-aa-helper program tries
to setup labelling for apparmor.

Add a new flag which will preserve the translated data in the
definition.

Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx>
---
 src/conf/domain_conf.c | 69 ++++++++++++++++++++++++++++++------------
 src/conf/domain_conf.h |  4 +++
 2 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e128457b00..9b636215e9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7006,7 +7006,8 @@ virDomainLeaseDefParseXML(xmlNodePtr node,
 }

 static virStorageSourcePoolDef *
-virDomainDiskSourcePoolDefParse(xmlNodePtr node)
+virDomainDiskSourcePoolDefParse(xmlNodePtr node,
+                                virDomainDefParseFlags flags)
 {
     g_autoptr(virStorageSourcePoolDef) source = g_new0(virStorageSourcePoolDef, 1);

@@ -7029,6 +7030,14 @@ virDomainDiskSourcePoolDefParse(xmlNodePtr node)
                        &source->mode) < 0)
         return NULL;

+    if (flags & VIR_DOMAIN_DEF_PARSE_VOLUME_TRANSLATED) {
+        if (virXMLPropEnum(node, "actualType",
+                           virStorageTypeFromString,
+                           VIR_XML_PROP_NONZERO,
+                           &source->actualtype) < 0)
+            return NULL;
+    }
+
     return g_steal_pointer(&source);
 }

@@ -7448,12 +7457,22 @@ virDomainStorageSourceParse(xmlNodePtr node,
                             unsigned int flags,
                             virDomainXMLOption *xmlopt)
 {
+    virStorageType actualType = src->type;
     VIR_XPATH_NODE_AUTORESTORE(ctxt)
     xmlNodePtr tmp;

     ctxt->node = node;

-    switch (src->type) {
+    if (src->type == VIR_STORAGE_TYPE_VOLUME) {
+        if (!(src->srcpool = virDomainDiskSourcePoolDefParse(node, flags)))
+            return -1;
+
+        /* If requested we need to also parse the translated volume runtime data */
+        if (flags & VIR_DOMAIN_DEF_PARSE_VOLUME_TRANSLATED)
+            actualType = virStorageSourceGetActualType(src);
+    }
+
+    switch (actualType) {
     case VIR_STORAGE_TYPE_FILE:
         src->path = virXMLPropString(node, "file");
         src->fdgroup = virXMLPropString(node, "fdgroup");
@@ -7469,8 +7488,7 @@ virDomainStorageSourceParse(xmlNodePtr node,
             return -1;
         break;
     case VIR_STORAGE_TYPE_VOLUME:
-        if (!(src->srcpool = virDomainDiskSourcePoolDefParse(node)))
-            return -1;
+        /* parsed above */
         break;
     case VIR_STORAGE_TYPE_NVME:
         if (virDomainDiskSourceNVMeParse(node, ctxt, src) < 0)
@@ -7488,7 +7506,7 @@ virDomainStorageSourceParse(xmlNodePtr node,
     case VIR_STORAGE_TYPE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected disk type %1$s"),
-                       virStorageTypeToString(src->type));
+                       virStorageTypeToString(actualType));
         return -1;
     }

@@ -8647,7 +8665,7 @@ virDomainFSDefParseXML(virDomainXMLOption *xmlopt,
             units = virXMLPropString(source_node, "units");
         } else if (def->type == VIR_DOMAIN_FS_TYPE_VOLUME) {
             def->src->type = VIR_STORAGE_TYPE_VOLUME;
-            if (!(def->src->srcpool = virDomainDiskSourcePoolDefParse(source_node)))
+            if (!(def->src->srcpool = virDomainDiskSourcePoolDefParse(source_node, flags)))
                 goto error;
         }
     }
@@ -22335,10 +22353,28 @@ virDomainDiskSourceFormat(virBuffer *buf,
                           bool skipEnc,
                           virDomainXMLOption *xmlopt)
 {
+    virStorageType actualType = src->type;
     g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
     g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);

-    switch (src->type) {
+    if (src->type == VIR_STORAGE_TYPE_VOLUME) {
+        if (src->srcpool) {
+            virBufferEscapeString(&attrBuf, " pool='%s'", src->srcpool->pool);
+            virBufferEscapeString(&attrBuf, " volume='%s'", src->srcpool->volume);
+            if (src->srcpool->mode)
+                virBufferAsprintf(&attrBuf, " mode='%s'",
+                                  virStorageSourcePoolModeTypeToString(src->srcpool->mode));
+        }
+
+        if (flags & VIR_DOMAIN_DEF_FORMAT_VOLUME_TRANSLATED &&
+            src->srcpool->actualtype != VIR_STORAGE_TYPE_NONE) {
+            virBufferAsprintf(&attrBuf, " actualType='%s'",
+                              virStorageTypeToString(src->srcpool->actualtype));
+            actualType = virStorageSourceGetActualType(src);
+        }
+    }
+
+    switch (actualType) {
     case VIR_STORAGE_TYPE_FILE:
         virBufferEscapeString(&attrBuf, " file='%s'", src->path);
         virBufferEscapeString(&attrBuf, " fdgroup='%s'", src->fdgroup);
@@ -22357,15 +22393,7 @@ virDomainDiskSourceFormat(virBuffer *buf,
         break;

     case VIR_STORAGE_TYPE_VOLUME:
-        if (src->srcpool) {
-            virBufferEscapeString(&attrBuf, " pool='%s'", src->srcpool->pool);
-            virBufferEscapeString(&attrBuf, " volume='%s'",
-                                  src->srcpool->volume);
-            if (src->srcpool->mode)
-                virBufferAsprintf(&attrBuf, " mode='%s'",
-                                  virStorageSourcePoolModeTypeToString(src->srcpool->mode));
-        }
-
+        /* formatted above */
         break;

     case VIR_STORAGE_TYPE_NVME:
@@ -22383,13 +22411,13 @@ virDomainDiskSourceFormat(virBuffer *buf,
     case VIR_STORAGE_TYPE_NONE:
     case VIR_STORAGE_TYPE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("unexpected disk type %1$d"), src->type);
+                       _("unexpected disk type %1$d"), actualType);
         return -1;
     }

     virDomainDiskSourceFormatSlices(&childBuf, src);

-    if (src->type != VIR_STORAGE_TYPE_NETWORK)
+    if (actualType != VIR_STORAGE_TYPE_NETWORK)
         virDomainSourceDefFormatSeclabel(&childBuf, src->nseclabels,
                                          src->seclabels, flags);

@@ -22408,7 +22436,7 @@ virDomainDiskSourceFormat(virBuffer *buf,
     if (src->pr)
         virStoragePRDefFormat(&childBuf, src->pr,
                               flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE);
-    if (policy && src->type != VIR_STORAGE_TYPE_NETWORK)
+    if (policy && actualType != VIR_STORAGE_TYPE_NETWORK)
         virBufferEscapeString(&attrBuf, " startupPolicy='%s'",
                               virDomainStartupPolicyTypeToString(policy));

@@ -27512,7 +27540,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
                   VIR_DOMAIN_DEF_FORMAT_STATUS |
                   VIR_DOMAIN_DEF_FORMAT_ACTUAL_NET |
                   VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES |
-                  VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST,
+                  VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST |
+                  VIR_DOMAIN_DEF_FORMAT_VOLUME_TRANSLATED,
                   -1);

     if (!(type = virDomainVirtTypeToString(def->virtType))) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 16289789c2..9e6dd930fa 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3734,6 +3734,8 @@ typedef enum {
      * post parse callbacks before starting. Failure of the post parse callback
      * is recorded as def->postParseFail */
     VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL = 1 << 11,
+    /* Parse the translated disk type='volume' data if present */
+    VIR_DOMAIN_DEF_PARSE_VOLUME_TRANSLATED = 1 << 12,
 } virDomainDefParseFlags;

 typedef enum {
@@ -3749,6 +3751,8 @@ typedef enum {
     VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM       = 1 << 6,
     VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT      = 1 << 7,
     VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST    = 1 << 8,
+    /* format disk type='volume' translated data if present */
+    VIR_DOMAIN_DEF_FORMAT_VOLUME_TRANSLATED = 1 << 9,
 } virDomainDefFormatFlags;

 /* Use these flags to skip specific domain ABI consistency checks done
-- 
2.41.0




[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