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(a)redhat.com>
---
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