diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 1d02e231750884568b58a14d62caac72c10ad2d6..25648a946c3099b6434d5df814ffc8fa31846b62 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -324,29 +324,26 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, virCPUType type, virCPUDefPtr *cpu) { - virCPUDefPtr def = NULL; - xmlNodePtr *nodes = NULL; + g_autoptr(virCPUDef) def = NULL; + g_autofree xmlNodePtr *nodes = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt); int n; size_t i; - char *cpuMode; - char *fallback = NULL; - char *vendor_id = NULL; - char *tscScaling = NULL; + g_autofree char *cpuMode = NULL; + g_autofree char *fallback = NULL; + g_autofree char *vendor_id = NULL; + g_autofree char *tscScaling = NULL; virHostCPUTscInfoPtr tsc = NULL; - int ret = -1; *cpu = NULL; - if (xpath && !(ctxt->node = virXPathNode(xpath, ctxt))) { - ret = 0; - goto cleanup; - } + if (xpath && !(ctxt->node = virXPathNode(xpath, ctxt))) + return 0; if (!virXMLNodeNameEqual(ctxt->node, "cpu")) { virReportError(VIR_ERR_XML_ERROR, "%s", _("XML does not contain expected 'cpu' element")); - goto cleanup; + return -1; } def = virCPUDefNew(); @@ -357,7 +354,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, virReportError(VIR_ERR_XML_ERROR, "%s", _("'arch' element cannot be used inside 'cpu'" " element with 'match' attribute'")); - goto cleanup; + return -1; } def->type = VIR_CPU_TYPE_HOST; } else { @@ -369,10 +366,9 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if ((cpuMode = virXMLPropString(ctxt->node, "mode"))) { if (def->type == VIR_CPU_TYPE_HOST) { - VIR_FREE(cpuMode); virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Attribute mode is only allowed for guest CPU")); - goto cleanup; + return -1; } else { def->mode = virCPUModeTypeFromString(cpuMode); @@ -380,10 +376,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid mode attribute '%s'"), cpuMode); - VIR_FREE(cpuMode); - goto cleanup; + return -1; } - VIR_FREE(cpuMode); } } else { if (def->type == VIR_CPU_TYPE_HOST) @@ -393,67 +387,60 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, } if (def->type == VIR_CPU_TYPE_GUEST) { - char *match = virXMLPropString(ctxt->node, "match"); - char *check; + g_autofree char *match = virXMLPropString(ctxt->node, "match"); + g_autofree char *check = NULL; if (match) { def->match = virCPUMatchTypeFromString(match); - VIR_FREE(match); - if (def->match < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid match attribute for CPU " "specification")); - goto cleanup; + return -1; } } if ((check = virXMLPropString(ctxt->node, "check"))) { int value = virCPUCheckTypeFromString(check); - VIR_FREE(check); - if (value < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid check attribute for CPU " "specification")); - goto cleanup; + return -1; } def->check = value; } } if (def->type == VIR_CPU_TYPE_HOST) { - char *arch = virXPathString("string(./arch[1])", ctxt); + g_autofree char *arch = virXPathString("string(./arch[1])", ctxt); if (!arch) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing CPU architecture")); - goto cleanup; + return -1; } if ((def->arch = virArchFromString(arch)) == VIR_ARCH_NONE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown architecture %s"), arch); - VIR_FREE(arch); - goto cleanup; + return -1; } - VIR_FREE(arch); if (virXPathBoolean("boolean(./microcode[1]/@version)", ctxt) > 0 && virXPathUInt("string(./microcode[1]/@version)", ctxt, &def->microcodeVersion) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("invalid microcode version")); - goto cleanup; + return -1; } if (virXPathBoolean("boolean(./counter[@name='tsc'])", ctxt) > 0) { - if (VIR_ALLOC(tsc) < 0) - goto cleanup; + tsc = g_new0(virHostCPUTscInfo, 1); if (virXPathULongLong("string(./counter[@name='tsc']/@frequency)", ctxt, &tsc->frequency) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid TSC frequency")); - goto cleanup; + return -1; } tscScaling = virXPathString("string(./counter[@name='tsc']/@scaling)", @@ -463,7 +450,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (scaling < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid TSC scaling attribute")); - goto cleanup; + return -1; } tsc->scaling = scaling; } @@ -476,7 +463,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, def->type == VIR_CPU_TYPE_HOST) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing CPU model name")); - goto cleanup; + return -1; } if (def->type == VIR_CPU_TYPE_GUEST && @@ -486,7 +473,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if ((def->fallback = virCPUFallbackTypeFromString(fallback)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid fallback attribute")); - goto cleanup; + return -1; } } @@ -496,18 +483,17 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, virReportError(VIR_ERR_XML_ERROR, _("vendor_id must be exactly %d characters long"), VIR_CPU_VENDOR_ID_LENGTH); - goto cleanup; + return -1; } /* ensure that the string can be passed to qemu */ if (strchr(vendor_id, ',')) { virReportError(VIR_ERR_XML_ERROR, "%s", _("vendor id is invalid")); - goto cleanup; + return -1; } - def->vendor_id = vendor_id; - vendor_id = NULL; + def->vendor_id = g_steal_pointer(&vendor_id); } } @@ -515,7 +501,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (def->vendor && !def->model) { virReportError(VIR_ERR_XML_ERROR, "%s", _("CPU vendor specified without CPU model")); - goto cleanup; + return -1; } if (virXPathNode("./topology[1]", ctxt)) { @@ -524,7 +510,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (virXPathULong("string(./topology[1]/@sockets)", ctxt, &ul) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'sockets' attribute in CPU topology")); - goto cleanup; + return -1; } def->sockets = (unsigned int) ul; @@ -532,7 +518,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (virXPathULong("string(./topology[1]/@dies)", ctxt, &ul) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Malformed 'dies' attribute in CPU topology")); - goto cleanup; + return -1; } def->dies = (unsigned int) ul; } else { @@ -542,71 +528,69 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (virXPathULong("string(./topology[1]/@cores)", ctxt, &ul) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'cores' attribute in CPU topology")); - goto cleanup; + return -1; } def->cores = (unsigned int) ul; if (virXPathULong("string(./topology[1]/@threads)", ctxt, &ul) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'threads' attribute in CPU topology")); - goto cleanup; + return -1; } def->threads = (unsigned int) ul; if (!def->sockets || !def->cores || !def->threads || !def->dies) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid CPU topology")); - goto cleanup; + return -1; } } if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) < 0) - goto cleanup; + return -1; if (n > 0) { if (!def->model && def->mode == VIR_CPU_MODE_CUSTOM) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Non-empty feature list specified without " "CPU model")); - goto cleanup; + return -1; } if (VIR_RESIZE_N(def->features, def->nfeatures_max, def->nfeatures, n) < 0) - goto cleanup; + return -1; def->nfeatures = n; } for (i = 0; i < n; i++) { - char *name; + g_autofree char *name = NULL; int policy; /* enum virDomainCPUFeaturePolicy */ size_t j; if (def->type == VIR_CPU_TYPE_GUEST) { - char *strpolicy; + g_autofree char *strpolicy = NULL; strpolicy = virXMLPropString(nodes[i], "policy"); if (strpolicy == NULL) policy = VIR_CPU_FEATURE_REQUIRE; else policy = virCPUFeaturePolicyTypeFromString(strpolicy); - VIR_FREE(strpolicy); if (policy < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid CPU feature policy")); - goto cleanup; + return -1; } } else { policy = -1; } if (!(name = virXMLPropString(nodes[i], "name")) || *name == 0) { - VIR_FREE(name); virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid CPU feature name")); - goto cleanup; + return -1; } for (j = 0; j < i; j++) { @@ -614,24 +598,23 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, virReportError(VIR_ERR_XML_ERROR, _("CPU feature '%s' specified more than once"), name); - VIR_FREE(name); - goto cleanup; + return -1; } } - def->features[i].name = name; + def->features[i].name = g_steal_pointer(&name); def->features[i].policy = policy; } if (virXPathInt("count(./cache)", ctxt, &n) < 0) { - goto cleanup; + return -1; } else if (n > 1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("at most one CPU cache element may be specified")); - goto cleanup; + return -1; } else if (n == 1) { int level = -1; - char *strmode; + g_autofree char *strmode = NULL; int mode; if (virXPathBoolean("boolean(./cache[1]/@level)", ctxt) == 1 && @@ -639,36 +622,23 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, level < 1 || level > 3)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid CPU cache level, must be in range [1,3]")); - goto cleanup; + return -1; } if (!(strmode = virXPathString("string(./cache[1]/@mode)", ctxt)) || (mode = virCPUCacheModeTypeFromString(strmode)) < 0) { - VIR_FREE(strmode); virReportError(VIR_ERR_XML_ERROR, "%s", _("missing or invalid CPU cache mode")); - goto cleanup; + return -1; } - VIR_FREE(strmode); - - if (VIR_ALLOC(def->cache) < 0) - goto cleanup; + def->cache = g_new0(virCPUCacheDef, 1); def->cache->level = level; def->cache->mode = mode; } *cpu = g_steal_pointer(&def); - ret = 0; - - cleanup: - VIR_FREE(fallback); - VIR_FREE(vendor_id); - VIR_FREE(nodes); - VIR_FREE(tscScaling); - VIR_FREE(tsc); - virCPUDefFree(def); - return ret; + return 0; }