From 55540339e2b100d6bbab99e4e94094091120a610 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Fri, 17 Apr 2015 16:37:57 -0400 Subject: [PATCH] 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 f1a89a8b6d1a1097e41a171a13b1984b06e8ab3e) --- src/conf/domain_conf.c | 103 ++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e2514802cc..cfdf66c64a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -102,6 +102,7 @@ typedef enum { VIR_DOMAIN_XML_INTERNAL_CLOCK_ADJUST = 1 << 21, /* parse only source half of */ VIR_DOMAIN_XML_INTERNAL_DISK_SOURCE = 1 << 22, + VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS = 1 << 23, } virDomainXMLInternalFlags; #define DUMPXML_FLAGS \ @@ -116,7 +117,8 @@ verify(((VIR_DOMAIN_XML_INTERNAL_STATUS | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | 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); VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST, @@ -12941,61 +12943,64 @@ virDomainDefParseXML(xmlDocPtr xml, 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, - _("no support found for os '%s'"), - def->os.type); + _("Unknown architecture %s"), + tmp); goto error; } + VIR_FREE(tmp); - tmp = virXPathString("string(./os/type[1]/@arch)", ctxt); - if (tmp) { - def->os.arch = virArchFromString(tmp); - if (!def->os.arch) { + def->os.machine = virXPathString("string(./os/type[1]/@machine)", ctxt); + + if (!(flags & VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS)) { + if (!virCapabilitiesSupportsGuestOSType(caps, def->os.type)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown architecture %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'"), + _("no support found for os '%s'"), def->os.type); 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.... @@ -19364,7 +19369,8 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms, goto error; if (!(def = virDomainDefParseFile(configFile, caps, xmlopt, expectedVirtTypes, - VIR_DOMAIN_XML_INACTIVE))) + VIR_DOMAIN_XML_INACTIVE | + VIR_DOMAIN_XML_INTERNAL_SKIP_OSTYPE_CHECKS))) goto error; if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) @@ -19414,7 +19420,8 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms, VIR_DOMAIN_XML_INTERNAL_STATUS | VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET | 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; virUUIDFormat(obj->def->uuid, uuidstr);