Currently, if we want to zero out disk source (e,g, due to
startupPolicy when starting up a domain) we use
virDomainDiskSetSource(disk, NULL). This works well for file
based storage (storage type file, dir, or block). But it doesn't
work at all for other types like volume and network.
So imagine that you have a domain that has a CDROM configured
which source is a volume from an inactive pool. Because it is
startupPolicy='optional', the CDROM is empty when the domain
starts. However, the source element is not cleared out in the
status XML and thus when the daemon restarts and tries to
reconnect to the domain it refreshes the disks (which fails - the
storage pool is still not running) and thus the domain is killed.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/domain_conf.c | 23 +++++++++++++++++++++++
src/conf/domain_conf.h | 1 +
src/libvirt_private.syms | 1 +
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_process.c | 2 +-
src/vmx/vmx.c | 6 +++---
src/xenconfig/xen_xm.c | 2 +-
7 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 01553b5..a60a456 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1719,6 +1719,29 @@ virDomainDiskSetSource(virDomainDiskDefPtr def, const char *src)
}
+void
+virDomainDiskZeroSource(virDomainDiskDefPtr def)
+{
+ switch ((virStorageType) def->src->type) {
+ case VIR_STORAGE_TYPE_DIR:
+ case VIR_STORAGE_TYPE_FILE:
+ case VIR_STORAGE_TYPE_BLOCK:
+ VIR_FREE(def->src->path);
+ break;
+ case VIR_STORAGE_TYPE_NETWORK:
+ VIR_FREE(def->src->volume);
+ break;
+ case VIR_STORAGE_TYPE_VOLUME:
+ virStorageSourcePoolDefFree(def->src->srcpool);
+ def->src->srcpool = NULL;
+ break;
+ case VIR_STORAGE_TYPE_NONE:
+ case VIR_STORAGE_TYPE_LAST:
+ break;
+ }
+}
+
+
const char *
virDomainDiskGetDriver(virDomainDiskDefPtr def)
{
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 47eaace..05b544c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2590,6 +2590,7 @@ void virDomainDiskSetType(virDomainDiskDefPtr def, int type);
const char *virDomainDiskGetSource(virDomainDiskDef const *def);
int virDomainDiskSetSource(virDomainDiskDefPtr def, const char *src)
ATTRIBUTE_RETURN_CHECK;
+void virDomainDiskZeroSource(virDomainDiskDefPtr def);
const char *virDomainDiskGetDriver(virDomainDiskDefPtr def);
int virDomainDiskSetDriver(virDomainDiskDefPtr def, const char *name)
ATTRIBUTE_RETURN_CHECK;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b551cb8..60c90d1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -324,6 +324,7 @@ virDomainDiskSetDriver;
virDomainDiskSetFormat;
virDomainDiskSetSource;
virDomainDiskSetType;
+virDomainDiskZeroSource;
virDomainFSDefFree;
virDomainFSDefNew;
virDomainFSIndexByName;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 589eb18..a50b3aa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4908,7 +4908,7 @@ qemuDomainCheckRemoveOptionalDisk(virQEMUDriverPtr driver,
event = virDomainEventDiskChangeNewFromObj(vm, src, NULL,
disk->info.alias,
VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START);
- ignore_value(virDomainDiskSetSource(disk, NULL));
+ virDomainDiskZeroSource(disk);
/* keeping the old startup policy would be invalid for new images */
disk->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_DEFAULT;
} else {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a20beb1..6be0b51 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6804,7 +6804,7 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
if (info->removable) {
if (info->empty)
- ignore_value(virDomainDiskSetSource(disk, NULL));
+ virDomainDiskZeroSource(disk);
if (info->tray) {
if (info->tray_open)
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 31af2e9..5c833b8 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -2283,7 +2283,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt,
virConfPtr con
virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
if (STRCASEEQ(fileName, "auto detect")) {
- ignore_value(virDomainDiskSetSource(*def, NULL));
+ virDomainDiskZeroSource(*def);
(*def)->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_OPTIONAL;
} else if (virDomainDiskSetSource(*def, fileName) < 0) {
goto cleanup;
@@ -2294,7 +2294,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt,
virConfPtr con
virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
if (STRCASEEQ(fileName, "auto detect")) {
- ignore_value(virDomainDiskSetSource(*def, NULL));
+ virDomainDiskZeroSource(*def);
(*def)->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_OPTIONAL;
} else if (virDomainDiskSetSource(*def, fileName) < 0) {
goto cleanup;
@@ -2326,7 +2326,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt,
virConfPtr con
}
virDomainDiskSetType(*def, VIR_STORAGE_TYPE_FILE);
- ignore_value(virDomainDiskSetSource(*def, NULL));
+ virDomainDiskZeroSource(*def);
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid or not yet handled value '%s' "
diff --git a/src/xenconfig/xen_xm.c b/src/xenconfig/xen_xm.c
index 8ef68bb..327cb65 100644
--- a/src/xenconfig/xen_xm.c
+++ b/src/xenconfig/xen_xm.c
@@ -140,7 +140,7 @@ xenParseXMDisk(virConfPtr conf, virDomainDefPtr def)
if (offset == head) {
/* No source file given, eg CDROM with no media */
- ignore_value(virDomainDiskSetSource(disk, NULL));
+ virDomainDiskZeroSource(disk);
} else {
if (VIR_STRNDUP(tmp, head, offset - head) < 0)
goto cleanup;
--
2.10.2