Introduce and use virDomainDiskEmptySource

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@redhat.com>
This commit is contained in:
Michal Privoznik 2017-03-31 15:59:54 +02:00
parent c3a83bad2a
commit 462c4b66fa
5 changed files with 14 additions and 2 deletions

View File

@ -1719,6 +1719,16 @@ virDomainDiskSetSource(virDomainDiskDefPtr def, const char *src)
} }
void
virDomainDiskEmptySource(virDomainDiskDefPtr def)
{
virStorageSourcePtr src = def->src;
virStorageSourceClear(src);
src->type = VIR_STORAGE_TYPE_FILE;
}
const char * const char *
virDomainDiskGetDriver(virDomainDiskDefPtr def) virDomainDiskGetDriver(virDomainDiskDefPtr def)
{ {

View File

@ -2590,6 +2590,7 @@ void virDomainDiskSetType(virDomainDiskDefPtr def, int type);
const char *virDomainDiskGetSource(virDomainDiskDef const *def); const char *virDomainDiskGetSource(virDomainDiskDef const *def);
int virDomainDiskSetSource(virDomainDiskDefPtr def, const char *src) int virDomainDiskSetSource(virDomainDiskDefPtr def, const char *src)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
void virDomainDiskEmptySource(virDomainDiskDefPtr def);
const char *virDomainDiskGetDriver(virDomainDiskDefPtr def); const char *virDomainDiskGetDriver(virDomainDiskDefPtr def);
int virDomainDiskSetDriver(virDomainDiskDefPtr def, const char *name) int virDomainDiskSetDriver(virDomainDiskDefPtr def, const char *name)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;

View File

@ -299,6 +299,7 @@ virDomainDiskDetectZeroesTypeFromString;
virDomainDiskDetectZeroesTypeToString; virDomainDiskDetectZeroesTypeToString;
virDomainDiskDeviceTypeToString; virDomainDiskDeviceTypeToString;
virDomainDiskDiscardTypeToString; virDomainDiskDiscardTypeToString;
virDomainDiskEmptySource;
virDomainDiskErrorPolicyTypeFromString; virDomainDiskErrorPolicyTypeFromString;
virDomainDiskErrorPolicyTypeToString; virDomainDiskErrorPolicyTypeToString;
virDomainDiskFindByBusAndDst; virDomainDiskFindByBusAndDst;

View File

@ -4908,7 +4908,7 @@ qemuDomainCheckRemoveOptionalDisk(virQEMUDriverPtr driver,
event = virDomainEventDiskChangeNewFromObj(vm, src, NULL, event = virDomainEventDiskChangeNewFromObj(vm, src, NULL,
disk->info.alias, disk->info.alias,
VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START); VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START);
ignore_value(virDomainDiskSetSource(disk, NULL)); virDomainDiskEmptySource(disk);
/* keeping the old startup policy would be invalid for new images */ /* keeping the old startup policy would be invalid for new images */
disk->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_DEFAULT; disk->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_DEFAULT;
} else { } else {

View File

@ -6804,7 +6804,7 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
if (info->removable) { if (info->removable) {
if (info->empty) if (info->empty)
ignore_value(virDomainDiskSetSource(disk, NULL)); virDomainDiskEmptySource(disk);
if (info->tray) { if (info->tray) {
if (info->tray_open) if (info->tray_open)