diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8458f5b2245b447159aa3583d76b7e55096c496c..860c9501ca60e0b436aece84bafebdf4e178a17c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14655,61 +14655,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_DEF_PARSE_SKIP_OSTYPE_CHECKS)) { + if (!virCapabilitiesSupportsGuestOSType(caps, def->os.type)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown architecture %s"), - tmp); + _("no support found for os '%s'"), + def->os.type); 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 (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; + 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; + } } - } 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.... @@ -21591,7 +21594,8 @@ virDomainObjListLoadConfig(virDomainObjListPtr doms, goto error; if (!(def = virDomainDefParseFile(configFile, caps, xmlopt, expectedVirtTypes, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) + VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS))) goto error; if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) @@ -21641,7 +21645,8 @@ virDomainObjListLoadStatus(virDomainObjListPtr doms, VIR_DOMAIN_DEF_PARSE_STATUS | VIR_DOMAIN_DEF_PARSE_ACTUAL_NET | VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES | - VIR_DOMAIN_DEF_PARSE_CLOCK_ADJUST))) + VIR_DOMAIN_DEF_PARSE_CLOCK_ADJUST | + VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS))) goto error; virUUIDFormat(obj->def->uuid, uuidstr); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e6fa3c922079a51b74ef86f81c56f366b3c35d80..30456524bba69256f345b6a52a8c89a1ed9d7175 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2530,6 +2530,10 @@ typedef enum { /* parse only source half of */ VIR_DOMAIN_DEF_PARSE_DISK_SOURCE = 1 << 7, VIR_DOMAIN_DEF_PARSE_VALIDATE = 1 << 8, + /* don't validate os.type and arch against capabilities. Prevents + * VMs from disappearing when qemu is removed and libvirtd is restarted + */ + VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS = 1 << 9, } virDomainDefParseFlags; typedef enum { diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index df19449b38d6d1897d5079990cac60d57179e812..e725a235fe4fe4665f2138046d7e751813aab37b 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -270,6 +270,9 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt, * clients will have to decide between best effort * initialization or outright failure. */ if ((tmp = virXPathString("string(./domain/@type)", ctxt))) { + int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE; + if (flags & VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL) + domainflags |= VIR_DOMAIN_DEF_PARSE_SKIP_OSTYPE_CHECKS; xmlNodePtr domainNode = virXPathNode("./domain", ctxt); VIR_FREE(tmp); @@ -280,8 +283,7 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt, } def->dom = virDomainDefParseNode(ctxt->node->doc, domainNode, caps, xmlopt, - expectedVirtTypes, - VIR_DOMAIN_DEF_PARSE_INACTIVE); + expectedVirtTypes, domainflags); if (!def->dom) goto cleanup; } else {