domain: conf: Don't validate VM ostype/arch at daemon startup

When parsing XML, we validate the passed ostype + arch combo against
the detected hypervisor capabilities. This has led to the following
problem:

- Define x86 qemu guest
- qemu is inadvertently removed from the host
- libvirtd is restarted. fails to parse VM config since arch is removed
- 'virsh list --all' is now empty, user is wondering where their VMs went

Add a new internal flag VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS. Use
it when loading VM and snapshot configs from disk.

https://bugzilla.redhat.com/show_bug.cgi?id=1043572
(cherry picked from commit f1a89a8b6d)
This commit is contained in:
Cole Robinson 2015-04-17 16:37:57 -04:00
parent 7d9739f26d
commit 55540339e2

View File

@ -102,6 +102,7 @@ typedef enum {
VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST = 1 << 21, VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST = 1 << 21,
/* parse only source half of <disk> */ /* parse only source half of <disk> */
VIR_DOMAIN_XML_INTERNAL_DISK_SOURCE = 1 << 22, VIR_DOMAIN_XML_INTERNAL_DISK_SOURCE = 1 << 22,
VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS = 1 << 23,
} virDomainXMLInternalFlags; } virDomainXMLInternalFlags;
#define DUMPXML_FLAGS \ #define DUMPXML_FLAGS \
@ -116,7 +117,8 @@ verify(((VIR_DOMAIN_XML_INTERNAL_STATUS |
VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM |
VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT |
VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST | VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST |
VIR_DOMAIN_XML_INTERNAL_DISK_SOURCE) VIR_DOMAIN_XML_INTERNAL_DISK_SOURCE |
VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS)
& DUMPXML_FLAGS) == 0); & DUMPXML_FLAGS) == 0);
VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST, VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST,
@ -12941,61 +12943,64 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error; goto error;
} }
if (!virCapabilitiesSupportsGuestOSType(caps, def->os.type)) { tmp = virXPathString("string(./os/type[1]/@arch)", ctxt);
if (tmp && !(def->os.arch = virArchFromString(tmp))) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("no support found for os <type> '%s'"), _("Unknown architecture %s"),
def->os.type); tmp);
goto error; goto error;
} }
VIR_FREE(tmp);
tmp = virXPathString("string(./os/type[1]/@arch)", ctxt); def->os.machine = virXPathString("string(./os/type[1]/@machine)", ctxt);
if (tmp) {
def->os.arch = virArchFromString(tmp); if (!(flags & VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS)) {
if (!def->os.arch) { if (!virCapabilitiesSupportsGuestOSType(caps, def->os.type)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown architecture %s"), _("no support found for os <type> '%s'"),
tmp);
goto error;
}
VIR_FREE(tmp);
if (!virCapabilitiesSupportsGuestArch(caps, def->os.arch)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("No guest options available for arch '%s'"),
virArchToString(def->os.arch));
goto error;
}
if (!virCapabilitiesSupportsGuestOSTypeArch(caps,
def->os.type,
def->os.arch)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("No os type '%s' available for arch '%s'"),
def->os.type, virArchToString(def->os.arch));
goto error;
}
} else {
def->os.arch =
virCapabilitiesDefaultGuestArch(caps,
def->os.type,
virDomainVirtTypeToString(def->virtType));
if (!def->os.arch) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("no supported architecture for os type '%s'"),
def->os.type); def->os.type);
goto error; goto error;
} }
if (def->os.arch) {
if (!virCapabilitiesSupportsGuestArch(caps, def->os.arch)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("No guest options available for arch '%s'"),
virArchToString(def->os.arch));
goto error;
}
if (!virCapabilitiesSupportsGuestOSTypeArch(caps,
def->os.type,
def->os.arch)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("No os type '%s' available for arch '%s'"),
def->os.type, virArchToString(def->os.arch));
goto error;
}
} else {
def->os.arch =
virCapabilitiesDefaultGuestArch(caps,
def->os.type,
virDomainVirtTypeToString(def->virtType));
if (!def->os.arch) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("no supported architecture for os type '%s'"),
def->os.type);
goto error;
}
}
if (!def->os.machine) {
const char *defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
def->os.type,
def->os.arch,
virDomainVirtTypeToString(def->virtType));
if (VIR_STRDUP(def->os.machine, defaultMachine) < 0)
goto error;
}
} }
def->os.machine = virXPathString("string(./os/type[1]/@machine)", ctxt);
if (!def->os.machine) {
const char *defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
def->os.type,
def->os.arch,
virDomainVirtTypeToString(def->virtType));
if (VIR_STRDUP(def->os.machine, defaultMachine) < 0)
goto error;
}
/* /*
* Booting options for different OS types.... * Booting options for different OS types....
@ -19364,7 +19369,8 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms,
goto error; goto error;
if (!(def = virDomainDefParseFile(configFile, caps, xmlopt, if (!(def = virDomainDefParseFile(configFile, caps, xmlopt,
expectedVirtTypes, expectedVirtTypes,
VIR_DOMAIN_XML_INACTIVE))) VIR_DOMAIN_XML_INACTIVE |
VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS)))
goto error; goto error;
if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL)
@ -19414,7 +19420,8 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms,
VIR_DOMAIN_XML_INTERNAL_STATUS | VIR_DOMAIN_XML_INTERNAL_STATUS |
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET | VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET |
VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES | VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES |
VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST))) VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST |
VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS)))
goto error; goto error;
virUUIDFormat(obj->def->uuid, uuidstr); virUUIDFormat(obj->def->uuid, uuidstr);