[libvirt PATCH 0/6] conf: split some funcs out of virDomainDefParseXML

Ján Tomko (6): conf: split out virDomainDefParseIDs conf: split out virDomainDefParseMemory conf: introduce virDomainDefTunablesParse conf: introduce virDomainDefLifecycleParse conf: introduce virDomainDefClockParse conf: introduce virDomainDefControllersParse src/conf/domain_conf.c | 728 ++++++++++++++++++++++++----------------- 1 file changed, 419 insertions(+), 309 deletions(-) -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 139 +++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 22c6ba3b0d..c208cb91a6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21011,6 +21011,83 @@ virDomainCachetuneDefParse(virDomainDefPtr def, } +static int +virDomainDefParseIDs(virDomainDefPtr def, + xmlXPathContextPtr ctxt, + unsigned int flags, + bool *uuid_generated) +{ + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + long id = -1; + int n; + + if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) + if (virXPathLong("string(./@id)", ctxt, &id) < 0) + id = -1; + def->id = (int)id; + + /* Extract domain name */ + if (!(def->name = virXPathString("string(./name[1])", ctxt))) { + virReportError(VIR_ERR_NO_NAME, NULL); + goto error; + } + + /* Extract domain uuid. If both uuid and sysinfo/system/entry/uuid + * exist, they must match; and if only the latter exists, it can + * also serve as the uuid. */ + tmp = virXPathString("string(./uuid[1])", ctxt); + if (!tmp) { + if (virUUIDGenerate(def->uuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Failed to generate UUID")); + goto error; + } + *uuid_generated = true; + } else { + if (virUUIDParse(tmp, def->uuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("malformed uuid element")); + goto error; + } + VIR_FREE(tmp); + } + + /* Extract domain genid - a genid can either be provided or generated */ + if ((n = virXPathNodeSet("./genid", ctxt, &nodes)) < 0) + goto error; + + if (n > 0) { + if (n != 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("element 'genid' can only appear once")); + goto error; + } + def->genidRequested = true; + if (!(tmp = virXPathString("string(./genid)", ctxt))) { + if (virUUIDGenerate(def->genid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Failed to generate genid")); + goto error; + } + def->genidGenerated = true; + } else { + if (virUUIDParse(tmp, def->genid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("malformed genid element")); + goto error; + } + VIR_FREE(tmp); + } + } + VIR_FREE(nodes); + return 0; + + error: + return -1; +} + + static int virDomainDefParseCaps(virDomainDefPtr def, xmlXPathContextPtr ctxt, @@ -21220,7 +21297,6 @@ virDomainDefParseXML(xmlDocPtr xml, xmlNodePtr node = NULL; size_t i, j; int n; - long id = -1; virDomainDefPtr def; bool uuid_generated = false; bool usb_none = false; @@ -21244,69 +21320,12 @@ virDomainDefParseXML(xmlDocPtr xml, if (!(def = virDomainDefNew())) return NULL; - if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) - if (virXPathLong("string(./@id)", ctxt, &id) < 0) - id = -1; - def->id = (int)id; + if (virDomainDefParseIDs(def, ctxt, flags, &uuid_generated) < 0) + goto error; if (virDomainDefParseCaps(def, ctxt, xmlopt) < 0) goto error; - /* Extract domain name */ - if (!(def->name = virXPathString("string(./name[1])", ctxt))) { - virReportError(VIR_ERR_NO_NAME, NULL); - goto error; - } - - /* Extract domain uuid. If both uuid and sysinfo/system/entry/uuid - * exist, they must match; and if only the latter exists, it can - * also serve as the uuid. */ - tmp = virXPathString("string(./uuid[1])", ctxt); - if (!tmp) { - if (virUUIDGenerate(def->uuid) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Failed to generate UUID")); - goto error; - } - uuid_generated = true; - } else { - if (virUUIDParse(tmp, def->uuid) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("malformed uuid element")); - goto error; - } - VIR_FREE(tmp); - } - - /* Extract domain genid - a genid can either be provided or generated */ - if ((n = virXPathNodeSet("./genid", ctxt, &nodes)) < 0) - goto error; - - if (n > 0) { - if (n != 1) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("element 'genid' can only appear once")); - goto error; - } - def->genidRequested = true; - if (!(tmp = virXPathString("string(./genid)", ctxt))) { - if (virUUIDGenerate(def->genid) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Failed to generate genid")); - goto error; - } - def->genidGenerated = true; - } else { - if (virUUIDParse(tmp, def->genid) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("malformed genid element")); - goto error; - } - VIR_FREE(tmp); - } - } - VIR_FREE(nodes); - /* Extract short description of domain (title) */ def->title = virXPathString("string(./title[1])", ctxt); if (def->title && strchr(def->title, '\n')) { -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 209 ++++++++++++++++++++++------------------- 1 file changed, 114 insertions(+), 95 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c208cb91a6..2d420458c6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21160,6 +21160,119 @@ virDomainDefParseCaps(virDomainDefPtr def, } +static int +virDomainDefParseMemory(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +{ + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + xmlNodePtr node = NULL; + size_t i; + int n; + + /* Extract domain memory */ + if (virDomainParseMemory("./memory[1]", NULL, ctxt, + &def->mem.total_memory, false, true) < 0) + goto error; + + if (virDomainParseMemory("./currentMemory[1]", NULL, ctxt, + &def->mem.cur_balloon, false, true) < 0) + goto error; + + if (virDomainParseMemory("./maxMemory[1]", NULL, ctxt, + &def->mem.max_memory, false, false) < 0) + goto error; + + if (virXPathUInt("string(./maxMemory[1]/@slots)", ctxt, &def->mem.memory_slots) == -2) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Failed to parse memory slot count")); + goto error; + } + + /* and info about it */ + if ((tmp = virXPathString("string(./memory[1]/@dumpCore)", ctxt)) && + (def->mem.dump_core = virTristateSwitchTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid memory core dump attribute value '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + + tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt); + if (tmp) { + if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/source/type '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } + + tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt); + if (tmp) { + if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/access/mode '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } + + tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt); + if (tmp) { + if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/allocation/mode '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } + + if (virXPathNode("./memoryBacking/hugepages", ctxt)) { + /* hugepages will be used */ + if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract hugepages nodes")); + goto error; + } + + if (n) { + if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) + goto error; + + for (i = 0; i < n; i++) { + if (virDomainHugepagesParseXML(nodes[i], ctxt, + &def->mem.hugepages[i]) < 0) + goto error; + def->mem.nhugepages++; + } + + VIR_FREE(nodes); + } else { + /* no hugepage pages */ + if (VIR_ALLOC(def->mem.hugepages) < 0) + goto error; + + def->mem.nhugepages = 1; + } + } + + if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt))) + def->mem.nosharepages = true; + + if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt)) + def->mem.locked = true; + + if (virXPathBoolean("boolean(./memoryBacking/discard)", ctxt)) + def->mem.discard = VIR_TRISTATE_BOOL_YES; + + return 0; + + error: + return -1; +} + + static int virDomainMemorytuneDefParseMemory(xmlXPathContextPtr ctxt, xmlNodePtr node, @@ -21344,102 +21457,8 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; } - /* Extract domain memory */ - if (virDomainParseMemory("./memory[1]", NULL, ctxt, - &def->mem.total_memory, false, true) < 0) + if (virDomainDefParseMemory(def, ctxt) < 0) goto error; - - if (virDomainParseMemory("./currentMemory[1]", NULL, ctxt, - &def->mem.cur_balloon, false, true) < 0) - goto error; - - if (virDomainParseMemory("./maxMemory[1]", NULL, ctxt, - &def->mem.max_memory, false, false) < 0) - goto error; - - if (virXPathUInt("string(./maxMemory[1]/@slots)", ctxt, &def->mem.memory_slots) == -2) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Failed to parse memory slot count")); - goto error; - } - - /* and info about it */ - if ((tmp = virXPathString("string(./memory[1]/@dumpCore)", ctxt)) && - (def->mem.dump_core = virTristateSwitchTypeFromString(tmp)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Invalid memory core dump attribute value '%s'"), tmp); - goto error; - } - VIR_FREE(tmp); - - tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt); - if (tmp) { - if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown memoryBacking/source/type '%s'"), tmp); - goto error; - } - VIR_FREE(tmp); - } - - tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt); - if (tmp) { - if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown memoryBacking/access/mode '%s'"), tmp); - goto error; - } - VIR_FREE(tmp); - } - - tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt); - if (tmp) { - if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown memoryBacking/allocation/mode '%s'"), tmp); - goto error; - } - VIR_FREE(tmp); - } - - if (virXPathNode("./memoryBacking/hugepages", ctxt)) { - /* hugepages will be used */ - if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot extract hugepages nodes")); - goto error; - } - - if (n) { - if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) - goto error; - - for (i = 0; i < n; i++) { - if (virDomainHugepagesParseXML(nodes[i], ctxt, - &def->mem.hugepages[i]) < 0) - goto error; - def->mem.nhugepages++; - } - - VIR_FREE(nodes); - } else { - /* no hugepage pages */ - if (VIR_ALLOC(def->mem.hugepages) < 0) - goto error; - - def->mem.nhugepages = 1; - } - } - - if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt))) - def->mem.nosharepages = true; - - if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt)) - def->mem.locked = true; - - if (virXPathBoolean("boolean(./memoryBacking/discard)", ctxt)) - def->mem.discard = VIR_TRISTATE_BOOL_YES; - /* Extract blkio cgroup tunables */ if (virXPathUInt("string(./blkiotune/weight)", ctxt, &def->blkio.weight) < 0) -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 129 ++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 54 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2d420458c6..c12cc1f216 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21401,64 +21401,16 @@ virDomainMemorytuneDefParse(virDomainDefPtr def, } -static virDomainDefPtr -virDomainDefParseXML(xmlDocPtr xml, - xmlXPathContextPtr ctxt, - virDomainXMLOptionPtr xmlopt, - unsigned int flags) +static int +virDomainDefTunablesParse(virDomainDefPtr def, + xmlXPathContextPtr ctxt, + virDomainXMLOptionPtr xmlopt, + unsigned int flags) { - xmlNodePtr node = NULL; + g_autofree xmlNodePtr *nodes = NULL; size_t i, j; int n; - virDomainDefPtr def; - bool uuid_generated = false; - bool usb_none = false; - bool usb_other = false; - bool usb_master = false; - g_autofree xmlNodePtr *nodes = NULL; - g_autofree char *tmp = NULL; - if (flags & VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA) { - g_autofree char *schema = NULL; - - schema = virFileFindResource("domain.rng", - abs_top_srcdir "/docs/schemas", - PKGDATADIR "/schemas"); - if (!schema) - return NULL; - if (virXMLValidateAgainstSchema(schema, xml) < 0) - return NULL; - } - - if (!(def = virDomainDefNew())) - return NULL; - - if (virDomainDefParseIDs(def, ctxt, flags, &uuid_generated) < 0) - goto error; - - if (virDomainDefParseCaps(def, ctxt, xmlopt) < 0) - goto error; - - /* Extract short description of domain (title) */ - def->title = virXPathString("string(./title[1])", ctxt); - if (def->title && strchr(def->title, '\n')) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Domain title can't contain newlines")); - goto error; - } - - /* Extract documentation if present */ - def->description = virXPathString("string(./description[1])", ctxt); - - /* analysis of security label, done early even though we format it - * late, so devices can refer to this for defaults */ - if (!(flags & VIR_DOMAIN_DEF_PARSE_SKIP_SECLABEL)) { - if (virSecurityLabelDefsParseXML(def, ctxt, xmlopt, flags) == -1) - goto error; - } - - if (virDomainDefParseMemory(def, ctxt) < 0) - goto error; /* Extract blkio cgroup tunables */ if (virXPathUInt("string(./blkiotune/weight)", ctxt, &def->blkio.weight) < 0) @@ -21687,6 +21639,75 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); + return 0; + + error: + return -1; +} + + +static virDomainDefPtr +virDomainDefParseXML(xmlDocPtr xml, + xmlXPathContextPtr ctxt, + virDomainXMLOptionPtr xmlopt, + unsigned int flags) +{ + xmlNodePtr node = NULL; + size_t i, j; + int n; + virDomainDefPtr def; + bool uuid_generated = false; + bool usb_none = false; + bool usb_other = false; + bool usb_master = false; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + + if (flags & VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA) { + g_autofree char *schema = NULL; + + schema = virFileFindResource("domain.rng", + abs_top_srcdir "/docs/schemas", + PKGDATADIR "/schemas"); + if (!schema) + return NULL; + if (virXMLValidateAgainstSchema(schema, xml) < 0) + return NULL; + } + + if (!(def = virDomainDefNew())) + return NULL; + + if (virDomainDefParseIDs(def, ctxt, flags, &uuid_generated) < 0) + goto error; + + if (virDomainDefParseCaps(def, ctxt, xmlopt) < 0) + goto error; + + /* Extract short description of domain (title) */ + def->title = virXPathString("string(./title[1])", ctxt); + if (def->title && strchr(def->title, '\n')) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Domain title can't contain newlines")); + goto error; + } + + /* Extract documentation if present */ + def->description = virXPathString("string(./description[1])", ctxt); + + /* analysis of security label, done early even though we format it + * late, so devices can refer to this for defaults */ + if (!(flags & VIR_DOMAIN_DEF_PARSE_SKIP_SECLABEL)) { + if (virSecurityLabelDefsParseXML(def, ctxt, xmlopt, flags) == -1) + goto error; + } + + if (virDomainDefParseMemory(def, ctxt) < 0) + goto error; + + if (virDomainDefTunablesParse(def, ctxt, xmlopt, flags) < 0) + goto error; + if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0) goto error; -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 86 ++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c12cc1f216..41dba831ce 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21646,6 +21646,55 @@ virDomainDefTunablesParse(virDomainDefPtr def, } +static int +virDomainDefLifecycleParse(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +{ + if (virDomainEventActionParseXML(ctxt, "on_reboot", + "string(./on_reboot[1])", + &def->onReboot, + VIR_DOMAIN_LIFECYCLE_ACTION_RESTART, + virDomainLifecycleActionTypeFromString) < 0) + goto error; + + if (virDomainEventActionParseXML(ctxt, "on_poweroff", + "string(./on_poweroff[1])", + &def->onPoweroff, + VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY, + virDomainLifecycleActionTypeFromString) < 0) + goto error; + + if (virDomainEventActionParseXML(ctxt, "on_crash", + "string(./on_crash[1])", + &def->onCrash, + VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY, + virDomainLifecycleActionTypeFromString) < 0) + goto error; + + if (virDomainEventActionParseXML(ctxt, "on_lockfailure", + "string(./on_lockfailure[1])", + &def->onLockFailure, + VIR_DOMAIN_LOCK_FAILURE_DEFAULT, + virDomainLockFailureTypeFromString) < 0) + goto error; + + if (virDomainPMStateParseXML(ctxt, + "string(./pm/suspend-to-mem/@enabled)", + &def->pm.s3) < 0) + goto error; + + if (virDomainPMStateParseXML(ctxt, + "string(./pm/suspend-to-disk/@enabled)", + &def->pm.s4) < 0) + goto error; + + return 0; + + error: + return -1; +} + + static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, xmlXPathContextPtr ctxt, @@ -21759,42 +21808,7 @@ virDomainDefParseXML(xmlDocPtr xml, if (virDomainFeaturesDefParse(def, ctxt) < 0) goto error; - if (virDomainEventActionParseXML(ctxt, "on_reboot", - "string(./on_reboot[1])", - &def->onReboot, - VIR_DOMAIN_LIFECYCLE_ACTION_RESTART, - virDomainLifecycleActionTypeFromString) < 0) - goto error; - - if (virDomainEventActionParseXML(ctxt, "on_poweroff", - "string(./on_poweroff[1])", - &def->onPoweroff, - VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY, - virDomainLifecycleActionTypeFromString) < 0) - goto error; - - if (virDomainEventActionParseXML(ctxt, "on_crash", - "string(./on_crash[1])", - &def->onCrash, - VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY, - virDomainLifecycleActionTypeFromString) < 0) - goto error; - - if (virDomainEventActionParseXML(ctxt, "on_lockfailure", - "string(./on_lockfailure[1])", - &def->onLockFailure, - VIR_DOMAIN_LOCK_FAILURE_DEFAULT, - virDomainLockFailureTypeFromString) < 0) - goto error; - - if (virDomainPMStateParseXML(ctxt, - "string(./pm/suspend-to-mem/@enabled)", - &def->pm.s3) < 0) - goto error; - - if (virDomainPMStateParseXML(ctxt, - "string(./pm/suspend-to-disk/@enabled)", - &def->pm.s4) < 0) + if (virDomainDefLifecycleParse(def, ctxt) < 0) goto error; if (virDomainPerfDefParseXML(def, ctxt) < 0) -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 185 +++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 83 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 41dba831ce..ccfe32685c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21695,6 +21695,107 @@ virDomainDefLifecycleParse(virDomainDefPtr def, } +static int +virDomainDefClockParse(virDomainDefPtr def, + xmlXPathContextPtr ctxt) +{ + size_t i; + int n; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *tmp = NULL; + + if ((tmp = virXPathString("string(./clock/@offset)", ctxt)) && + (def->clock.offset = virDomainClockOffsetTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown clock offset '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + + switch (def->clock.offset) { + case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: + case VIR_DOMAIN_CLOCK_OFFSET_UTC: + tmp = virXPathString("string(./clock/@adjustment)", ctxt); + if (tmp) { + if (STREQ(tmp, "reset")) { + def->clock.data.utc_reset = true; + } else { + if (virStrToLong_ll(tmp, NULL, 10, + &def->clock.data.variable.adjustment) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("unknown clock adjustment '%s'"), + tmp); + goto error; + } + switch (def->clock.offset) { + case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: + def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_LOCALTIME; + break; + case VIR_DOMAIN_CLOCK_OFFSET_UTC: + def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC; + break; + } + def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_VARIABLE; + } + VIR_FREE(tmp); + } else { + def->clock.data.utc_reset = false; + } + break; + + case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: + if (virXPathLongLong("number(./clock/@adjustment)", ctxt, + &def->clock.data.variable.adjustment) < 0) + def->clock.data.variable.adjustment = 0; + if (virXPathLongLong("number(./clock/@adjustment0)", ctxt, + &def->clock.data.variable.adjustment0) < 0) + def->clock.data.variable.adjustment0 = 0; + tmp = virXPathString("string(./clock/@basis)", ctxt); + if (tmp) { + if ((def->clock.data.variable.basis = virDomainClockBasisTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown clock basis '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } else { + def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC; + } + break; + + case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: + def->clock.data.timezone = virXPathString("string(./clock/@timezone)", ctxt); + if (!def->clock.data.timezone) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing 'timezone' attribute for clock with offset='timezone'")); + goto error; + } + break; + } + + if ((n = virXPathNodeSet("./clock/timer", ctxt, &nodes)) < 0) + goto error; + + if (n && VIR_ALLOC_N(def->clock.timers, n) < 0) + goto error; + + for (i = 0; i < n; i++) { + virDomainTimerDefPtr timer = virDomainTimerDefParseXML(nodes[i], + ctxt); + if (!timer) + goto error; + + def->clock.timers[def->clock.ntimers++] = timer; + } + VIR_FREE(nodes); + + return 0; + + error: + return -1; +} + + static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, xmlXPathContextPtr ctxt, @@ -21814,90 +21915,8 @@ virDomainDefParseXML(xmlDocPtr xml, if (virDomainPerfDefParseXML(def, ctxt) < 0) goto error; - if ((tmp = virXPathString("string(./clock/@offset)", ctxt)) && - (def->clock.offset = virDomainClockOffsetTypeFromString(tmp)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown clock offset '%s'"), tmp); + if (virDomainDefClockParse(def, ctxt) < 0) goto error; - } - VIR_FREE(tmp); - - switch (def->clock.offset) { - case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: - case VIR_DOMAIN_CLOCK_OFFSET_UTC: - tmp = virXPathString("string(./clock/@adjustment)", ctxt); - if (tmp) { - if (STREQ(tmp, "reset")) { - def->clock.data.utc_reset = true; - } else { - if (virStrToLong_ll(tmp, NULL, 10, - &def->clock.data.variable.adjustment) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("unknown clock adjustment '%s'"), - tmp); - goto error; - } - switch (def->clock.offset) { - case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME: - def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_LOCALTIME; - break; - case VIR_DOMAIN_CLOCK_OFFSET_UTC: - def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC; - break; - } - def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_VARIABLE; - } - VIR_FREE(tmp); - } else { - def->clock.data.utc_reset = false; - } - break; - - case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: - if (virXPathLongLong("number(./clock/@adjustment)", ctxt, - &def->clock.data.variable.adjustment) < 0) - def->clock.data.variable.adjustment = 0; - if (virXPathLongLong("number(./clock/@adjustment0)", ctxt, - &def->clock.data.variable.adjustment0) < 0) - def->clock.data.variable.adjustment0 = 0; - tmp = virXPathString("string(./clock/@basis)", ctxt); - if (tmp) { - if ((def->clock.data.variable.basis = virDomainClockBasisTypeFromString(tmp)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown clock basis '%s'"), tmp); - goto error; - } - VIR_FREE(tmp); - } else { - def->clock.data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC; - } - break; - - case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: - def->clock.data.timezone = virXPathString("string(./clock/@timezone)", ctxt); - if (!def->clock.data.timezone) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("missing 'timezone' attribute for clock with offset='timezone'")); - goto error; - } - break; - } - - if ((n = virXPathNodeSet("./clock/timer", ctxt, &nodes)) < 0) - goto error; - - if (n && VIR_ALLOC_N(def->clock.timers, n) < 0) - goto error; - - for (i = 0; i < n; i++) { - virDomainTimerDefPtr timer = virDomainTimerDefParseXML(nodes[i], - ctxt); - if (!timer) - goto error; - - def->clock.timers[def->clock.ntimers++] = timer; - } - VIR_FREE(nodes); if (virDomainDefParseBootOptions(def, ctxt) < 0) goto error; -- 2.26.2

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 122 +++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ccfe32685c..680524ce08 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -21795,6 +21795,75 @@ virDomainDefClockParse(virDomainDefPtr def, return -1; } +static int +virDomainDefControllersParse(virDomainDefPtr def, + xmlXPathContextPtr ctxt, + virDomainXMLOptionPtr xmlopt, + unsigned int flags, + bool *usb_none) +{ + g_autofree xmlNodePtr *nodes = NULL; + bool usb_other = false; + bool usb_master = false; + size_t i; + int n; + + if ((n = virXPathNodeSet("./devices/controller", ctxt, &nodes)) < 0) + goto error; + + if (n && VIR_ALLOC_N(def->controllers, n) < 0) + goto error; + + for (i = 0; i < n; i++) { + virDomainControllerDefPtr controller = virDomainControllerDefParseXML(xmlopt, + nodes[i], + ctxt, + flags); + + if (!controller) + goto error; + + /* sanitize handling of "none" usb controller */ + if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE) { + if (usb_other || *usb_none) { + virDomainControllerDefFree(controller); + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Can't add another USB controller: " + "USB is disabled for this domain")); + goto error; + } + *usb_none = true; + } else { + if (*usb_none) { + virDomainControllerDefFree(controller); + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Can't add another USB controller: " + "USB is disabled for this domain")); + goto error; + } + usb_other = true; + } + + if (controller->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_NONE) + usb_master = true; + } + + virDomainControllerInsertPreAlloced(def, controller); + } + VIR_FREE(nodes); + + if (usb_other && !usb_master) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("No master USB controller specified")); + goto error; + } + + return 0; + + error: + return -1; +} static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, @@ -21808,8 +21877,6 @@ virDomainDefParseXML(xmlDocPtr xml, virDomainDefPtr def; bool uuid_generated = false; bool usb_none = false; - bool usb_other = false; - bool usb_master = false; g_autofree xmlNodePtr *nodes = NULL; g_autofree char *tmp = NULL; @@ -21940,58 +22007,9 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); - /* analysis of the controller devices */ - if ((n = virXPathNodeSet("./devices/controller", ctxt, &nodes)) < 0) + if (virDomainDefControllersParse(def, ctxt, xmlopt, flags, &usb_none) < 0) goto error; - if (n && VIR_ALLOC_N(def->controllers, n) < 0) - goto error; - - for (i = 0; i < n; i++) { - virDomainControllerDefPtr controller = virDomainControllerDefParseXML(xmlopt, - nodes[i], - ctxt, - flags); - - if (!controller) - goto error; - - /* sanitize handling of "none" usb controller */ - if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { - if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE) { - if (usb_other || usb_none) { - virDomainControllerDefFree(controller); - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("Can't add another USB controller: " - "USB is disabled for this domain")); - goto error; - } - usb_none = true; - } else { - if (usb_none) { - virDomainControllerDefFree(controller); - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("Can't add another USB controller: " - "USB is disabled for this domain")); - goto error; - } - usb_other = true; - } - - if (controller->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_NONE) - usb_master = true; - } - - virDomainControllerInsertPreAlloced(def, controller); - } - VIR_FREE(nodes); - - if (usb_other && !usb_master) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("No master USB controller specified")); - goto error; - } - /* analysis of the resource leases */ if ((n = virXPathNodeSet("./devices/lease", ctxt, &nodes)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, -- 2.26.2

On 9/23/20 8:21 PM, Ján Tomko wrote:
Ján Tomko (6): conf: split out virDomainDefParseIDs conf: split out virDomainDefParseMemory conf: introduce virDomainDefTunablesParse conf: introduce virDomainDefLifecycleParse conf: introduce virDomainDefClockParse conf: introduce virDomainDefControllersParse
src/conf/domain_conf.c | 728 ++++++++++++++++++++++++----------------- 1 file changed, 419 insertions(+), 309 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Ján Tomko
-
Michal Prívozník