static int lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties) { VIR_AUTOFREE(char *) value = NULL; virBitmapPtr nodeset = NULL; if (virConfGetValueString(properties, "lxc.cgroup.cpuset.cpus", &value) > 0) { if (virBitmapParse(value, &def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) return -1; def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC; VIR_FREE(value); } if (virConfGetValueString(properties, "lxc.cgroup.cpuset.mems", &value) > 0) { if (virBitmapParse(value, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) return -1; if (virDomainNumatuneSet(def->numa, def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC, VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC, VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0) { virBitmapFree(nodeset); return -1; } virBitmapFree(nodeset); } return 0; }
static int lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties) { virConfValuePtr value; virBitmapPtr nodeset = NULL; if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.cpus")) && value->str) { if (virBitmapParse(value->str, 0, &def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) return -1; def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC; } if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.mems")) && value->str) { if (virBitmapParse(value->str, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) return -1; if (virDomainNumatuneSet(def->numa, def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC, VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC, VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0) { virBitmapFree(nodeset); return -1; } virBitmapFree(nodeset); } return 0; }
/* * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set * and max cpu is 7. The map file shows 0-4,6-7. This function parses * it and returns cpumap. */ static virBitmapPtr linuxParseCPUmap(int *max_cpuid, const char *path) { virBitmapPtr map = NULL; char *str = NULL; int max_id = 0, i; if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) { virReportOOMError(); goto error; } if (virBitmapParse(str, 0, &map, VIR_DOMAIN_CPUMASK_LEN) < 0) { goto error; } i = -1; while ((i = virBitmapNextSetBit(map, i)) >= 0) { max_id = i; } *max_cpuid = max_id; VIR_FREE(str); return map; error: VIR_FREE(str); virBitmapFree(map); return NULL; }
/* * Linux maintains cpu bit map under cpu/online. For example, if * cpuid=5's flag is not set and max cpu is 7, the map file shows * 0-4,6-7. This function parses it and returns cpumap. */ static virBitmapPtr linuxParseCPUmap(int max_cpuid, const char *path) { virBitmapPtr map = NULL; char *str = NULL; if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) goto error; if (virBitmapParse(str, 0, &map, max_cpuid) < 0) goto error; VIR_FREE(str); return map; error: VIR_FREE(str); virBitmapFree(map); return NULL; }
/* * Linux maintains cpu bit map under cpu/online. For example, if * cpuid=5's flag is not set and max cpu is 7, the map file shows * 0-4,6-7. This function parses it and returns cpumap. */ static virBitmapPtr virHostCPUParseMapLinux(int max_cpuid, const char *path) { virBitmapPtr map = NULL; char *str = NULL; if (virFileReadAll(path, 5 * VIR_HOST_CPU_MASK_LEN, &str) < 0) goto error; if (virBitmapParse(str, 0, &map, max_cpuid) < 0) goto error; VIR_FREE(str); return map; error: VIR_FREE(str); virBitmapFree(map); return NULL; }
virCPUDefPtr virCPUDefParseXML(xmlNodePtr node, xmlXPathContextPtr ctxt, enum virCPUType mode) { virCPUDefPtr def; xmlNodePtr *nodes = NULL; int n; size_t i; char *cpuMode; char *fallback = NULL; char *vendor_id = NULL; if (!xmlStrEqual(node->name, BAD_CAST "cpu")) { virReportError(VIR_ERR_XML_ERROR, "%s", _("XML does not contain expected 'cpu' element")); return NULL; } if (VIR_ALLOC(def) < 0) return NULL; if (mode == VIR_CPU_TYPE_AUTO) { if (virXPathBoolean("boolean(./arch)", ctxt)) { if (virXPathBoolean("boolean(./@match)", ctxt)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("'arch' element element cannot be used inside 'cpu'" " element with 'match' attribute'")); goto error; } def->type = VIR_CPU_TYPE_HOST; } else { def->type = VIR_CPU_TYPE_GUEST; } } else { def->type = mode; } if ((cpuMode = virXMLPropString(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 error; } else { def->mode = virCPUModeTypeFromString(cpuMode); if (def->mode < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid mode attribute '%s'"), cpuMode); VIR_FREE(cpuMode); goto error; } VIR_FREE(cpuMode); } } else { if (def->type == VIR_CPU_TYPE_HOST) def->mode = -1; else def->mode = VIR_CPU_MODE_CUSTOM; } if (def->type == VIR_CPU_TYPE_GUEST) { char *match = virXMLPropString(node, "match"); if (!match) { if (virXPathBoolean("boolean(./model)", ctxt)) def->match = VIR_CPU_MATCH_EXACT; else def->match = -1; } else { def->match = virCPUMatchTypeFromString(match); VIR_FREE(match); if (def->match < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid match attribute for CPU " "specification")); goto error; } } } if (def->type == VIR_CPU_TYPE_HOST) { char *arch = virXPathString("string(./arch[1])", ctxt); if (!arch) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing CPU architecture")); goto error; } if ((def->arch = virArchFromString(arch)) == VIR_ARCH_NONE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown architecture %s"), arch); VIR_FREE(arch); goto error; } VIR_FREE(arch); } if (!(def->model = virXPathString("string(./model[1])", ctxt)) && def->type == VIR_CPU_TYPE_HOST) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing CPU model name")); goto error; } if (def->type == VIR_CPU_TYPE_GUEST && def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { if ((fallback = virXPathString("string(./model[1]/@fallback)", ctxt))) { if ((def->fallback = virCPUFallbackTypeFromString(fallback)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Invalid fallback attribute")); goto error; } } if ((vendor_id = virXPathString("string(./model[1]/@vendor_id)", ctxt))) { if (strlen(vendor_id) != VIR_CPU_VENDOR_ID_LENGTH) { virReportError(VIR_ERR_XML_ERROR, _("vendor_id must be exactly %d characters long"), VIR_CPU_VENDOR_ID_LENGTH); goto error; } /* ensure that the string can be passed to qemu*/ if (strchr(vendor_id, ',')) { virReportError(VIR_ERR_XML_ERROR, "%s", _("vendor id is invalid")); goto error; } def->vendor_id = vendor_id; vendor_id = NULL; } } def->vendor = virXPathString("string(./vendor[1])", ctxt); if (def->vendor && !def->model) { virReportError(VIR_ERR_XML_ERROR, "%s", _("CPU vendor specified without CPU model")); goto error; } if (virXPathNode("./topology[1]", ctxt)) { int ret; unsigned long ul; ret = virXPathULong("string(./topology[1]/@sockets)", ctxt, &ul); if (ret < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'sockets' attribute in CPU topology")); goto error; } def->sockets = (unsigned int) ul; ret = virXPathULong("string(./topology[1]/@cores)", ctxt, &ul); if (ret < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'cores' attribute in CPU topology")); goto error; } def->cores = (unsigned int) ul; ret = virXPathULong("string(./topology[1]/@threads)", ctxt, &ul); if (ret < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'threads' attribute in CPU topology")); goto error; } def->threads = (unsigned int) ul; if (!def->sockets || !def->cores || !def->threads) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid CPU topology")); goto error; } } if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) < 0) goto error; if (n > 0) { if (!def->model && def->mode != VIR_CPU_MODE_HOST_MODEL) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Non-empty feature list specified without " "CPU model")); goto error; } if (VIR_RESIZE_N(def->features, def->nfeatures_max, def->nfeatures, n) < 0) goto error; def->nfeatures = n; } for (i = 0; i < n; i++) { char *name; int policy; /* enum virDomainCPUFeaturePolicy */ size_t j; if (def->type == VIR_CPU_TYPE_GUEST) { char *strpolicy; 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 error; } } 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 error; } for (j = 0; j < i; j++) { if (STREQ(name, def->features[j].name)) { virReportError(VIR_ERR_XML_ERROR, _("CPU feature `%s' specified more than once"), name); VIR_FREE(name); goto error; } } def->features[i].name = name; def->features[i].policy = policy; } if (virXPathNode("./numa[1]", ctxt)) { VIR_FREE(nodes); n = virXPathNodeSet("./numa[1]/cell", ctxt, &nodes); if (n <= 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("NUMA topology defined without NUMA cells")); goto error; } if (VIR_RESIZE_N(def->cells, def->ncells_max, def->ncells, n) < 0) goto error; def->ncells = n; for (i = 0; i < n; i++) { char *cpus, *memory; int ret, ncpus = 0; def->cells[i].cellid = i; cpus = virXMLPropString(nodes[i], "cpus"); if (!cpus) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'cpus' attribute in NUMA cell")); goto error; } def->cells[i].cpustr = cpus; ncpus = virBitmapParse(cpus, 0, &def->cells[i].cpumask, VIR_DOMAIN_CPUMASK_LEN); if (ncpus <= 0) goto error; def->cells_cpus += ncpus; memory = virXMLPropString(nodes[i], "memory"); if (!memory) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'memory' attribute in NUMA cell")); goto error; } ret = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem); if (ret == -1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid 'memory' attribute in NUMA cell")); VIR_FREE(memory); goto error; } VIR_FREE(memory); } } cleanup: VIR_FREE(fallback); VIR_FREE(vendor_id); VIR_FREE(nodes); return def; error: virCPUDefFree(def); def = NULL; goto cleanup; }
static int virDomainNumatuneNodeParseXML(virDomainNumaPtr numa, xmlXPathContextPtr ctxt) { char *tmp = NULL; int n = 0; int ret = -1; size_t i = 0; xmlNodePtr *nodes = NULL; if ((n = virXPathNodeSet("./numatune/memnode", ctxt, &nodes)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot extract memnode nodes")); goto cleanup; } if (!n) return 0; if (numa->memory.specified && numa->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Per-node binding is not compatible with " "automatic NUMA placement.")); goto cleanup; } if (!numa->nmem_nodes) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Element 'memnode' is invalid without " "any guest NUMA cells")); goto cleanup; } for (i = 0; i < n; i++) { int mode = 0; unsigned int cellid = 0; virDomainNumaNodePtr mem_node = NULL; xmlNodePtr cur_node = nodes[i]; tmp = virXMLPropString(cur_node, "cellid"); if (!tmp) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing required cellid attribute " "in memnode element")); goto cleanup; } if (virStrToLong_uip(tmp, NULL, 10, &cellid) < 0) { virReportError(VIR_ERR_XML_ERROR, _("Invalid cellid attribute in memnode element: %s"), tmp); goto cleanup; } VIR_FREE(tmp); if (cellid >= numa->nmem_nodes) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Argument 'cellid' in memnode element must " "correspond to existing guest's NUMA cell")); goto cleanup; } mem_node = &numa->mem_nodes[cellid]; if (mem_node->nodeset) { virReportError(VIR_ERR_XML_ERROR, _("Multiple memnode elements with cellid %u"), cellid); goto cleanup; } tmp = virXMLPropString(cur_node, "mode"); if (!tmp) { mem_node->mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; } else { if ((mode = virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid mode attribute in memnode element")); goto cleanup; } VIR_FREE(tmp); mem_node->mode = mode; } tmp = virXMLPropString(cur_node, "nodeset"); if (!tmp) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing required nodeset attribute " "in memnode element")); goto cleanup; } if (virBitmapParse(tmp, 0, &mem_node->nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) goto cleanup; if (virBitmapIsAllClear(mem_node->nodeset)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid value of 'nodeset': %s"), tmp); goto cleanup; } VIR_FREE(tmp); } ret = 0; cleanup: VIR_FREE(nodes); VIR_FREE(tmp); return ret; }
int virDomainNumaDefCPUParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt) { xmlNodePtr *nodes = NULL; xmlNodePtr oldNode = ctxt->node; char *tmp = NULL; int n; size_t i; int ret = -1; /* check if NUMA definition is present */ if (!virXPathNode("./cpu/numa[1]", ctxt)) return 0; if ((n = virXPathNodeSet("./cpu/numa[1]/cell", ctxt, &nodes)) <= 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("NUMA topology defined without NUMA cells")); goto cleanup; } if (VIR_ALLOC_N(def->mem_nodes, n) < 0) goto cleanup; def->nmem_nodes = n; for (i = 0; i < n; i++) { size_t j; int rc; unsigned int cur_cell = i; /* cells are in order of parsing or explicitly numbered */ if ((tmp = virXMLPropString(nodes[i], "id"))) { if (virStrToLong_uip(tmp, NULL, 10, &cur_cell) < 0) { virReportError(VIR_ERR_XML_ERROR, _("Invalid 'id' attribute in NUMA cell: '%s'"), tmp); goto cleanup; } if (cur_cell >= n) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Exactly one 'cell' element per guest " "NUMA cell allowed, non-contiguous ranges or " "ranges not starting from 0 are not allowed")); goto cleanup; } } VIR_FREE(tmp); if (def->mem_nodes[cur_cell].cpumask) { virReportError(VIR_ERR_XML_ERROR, _("Duplicate NUMA cell info for cell id '%u'"), cur_cell); goto cleanup; } if (!(tmp = virXMLPropString(nodes[i], "cpus"))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing 'cpus' attribute in NUMA cell")); goto cleanup; } if (virBitmapParse(tmp, 0, &def->mem_nodes[cur_cell].cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) goto cleanup; if (virBitmapIsAllClear(def->mem_nodes[cur_cell].cpumask)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("NUMA cell %d has no vCPUs assigned"), cur_cell); goto cleanup; } VIR_FREE(tmp); for (j = 0; j < i; j++) { if (virBitmapOverlaps(def->mem_nodes[j].cpumask, def->mem_nodes[i].cpumask)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("NUMA cells %zu and %zu have overlapping vCPU ids"), i, j); goto cleanup; } } ctxt->node = nodes[i]; if (virDomainParseMemory("./@memory", "./@unit", ctxt, &def->mem_nodes[cur_cell].mem, true, false) < 0) goto cleanup; if ((tmp = virXMLPropString(nodes[i], "memAccess"))) { if ((rc = virNumaMemAccessTypeFromString(tmp)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid 'memAccess' attribute value '%s'"), tmp); goto cleanup; } def->mem_nodes[cur_cell].memAccess = rc; VIR_FREE(tmp); } } ret = 0; cleanup: ctxt->node = oldNode; VIR_FREE(nodes); VIR_FREE(tmp); return ret; }
int virDomainNumatuneParseXML(virDomainNumaPtr numa, bool placement_static, xmlXPathContextPtr ctxt) { char *tmp = NULL; int mode = -1; int n = 0; int placement = -1; int ret = -1; virBitmapPtr nodeset = NULL; xmlNodePtr node = NULL; if (virXPathInt("count(./numatune)", ctxt, &n) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot extract numatune nodes")); goto cleanup; } else if (n > 1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("only one numatune is supported")); goto cleanup; } node = virXPathNode("./numatune/memory[1]", ctxt); if (!placement_static && !node) placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO; if (node) { if ((tmp = virXMLPropString(node, "mode")) && (mode = virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported NUMA memory tuning mode '%s'"), tmp); goto cleanup; } VIR_FREE(tmp); if ((tmp = virXMLPropString(node, "placement")) && (placement = virDomainNumatunePlacementTypeFromString(tmp)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported NUMA memory placement mode '%s'"), tmp); goto cleanup; } VIR_FREE(tmp); tmp = virXMLPropString(node, "nodeset"); if (tmp) { if (virBitmapParse(tmp, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) goto cleanup; if (virBitmapIsAllClear(nodeset)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid value of 'nodeset': %s"), tmp); goto cleanup; } VIR_FREE(tmp); } } if (virDomainNumatuneSet(numa, placement_static, placement, mode, nodeset) < 0) goto cleanup; if (virDomainNumatuneNodeParseXML(numa, ctxt) < 0) goto cleanup; ret = 0; cleanup: virBitmapFree(nodeset); VIR_FREE(tmp); return ret; }
int virDomainNumatuneParseXML(virDomainNumatunePtr *numatunePtr, bool placement_static, size_t ncells, xmlXPathContextPtr ctxt) { char *tmp = NULL; int mode = -1; int n = 0; int placement = -1; int ret = -1; virBitmapPtr nodeset = NULL; xmlNodePtr node = NULL; if (virXPathInt("count(./numatune)", ctxt, &n) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot extract numatune nodes")); goto cleanup; } else if (n > 1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("only one numatune is supported")); goto cleanup; } node = virXPathNode("./numatune/memory[1]", ctxt); if (*numatunePtr) { virDomainNumatuneFree(*numatunePtr); *numatunePtr = NULL; } if (!node && placement_static) { if (virDomainNumatuneNodeParseXML(numatunePtr, ncells, ctxt) < 0) goto cleanup; return 0; } if (!node) { /* We know that placement_mode is "auto" if we're here */ ret = virDomainNumatuneSet(numatunePtr, placement_static, VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO, -1, NULL); goto cleanup; } tmp = virXMLPropString(node, "mode"); if (tmp) { mode = virDomainNumatuneMemModeTypeFromString(tmp); if (mode < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported NUMA memory tuning mode '%s'"), tmp); goto cleanup; } } VIR_FREE(tmp); tmp = virXMLPropString(node, "placement"); if (tmp) { placement = virDomainNumatunePlacementTypeFromString(tmp); if (placement < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported NUMA memory placement mode '%s'"), tmp); goto cleanup; } } VIR_FREE(tmp); tmp = virXMLPropString(node, "nodeset"); if (tmp && virBitmapParse(tmp, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) goto cleanup; VIR_FREE(tmp); if (virDomainNumatuneSet(numatunePtr, placement_static, placement, mode, nodeset) < 0) goto cleanup; if (virDomainNumatuneNodeParseXML(numatunePtr, ncells, ctxt) < 0) goto cleanup; ret = 0; cleanup: virBitmapFree(nodeset); VIR_FREE(tmp); return ret; }
int lxctoolsReadConfig(struct lxc_container* cont, virDomainDefPtr def) { char* item_str = NULL; virNodeInfoPtr nodeinfo = NULL; lxctoolsConffilePtr conffile = NULL; if (VIR_ALLOC(nodeinfo) < 0) { goto error; } if (virCapabilitiesGetNodeInfo(nodeinfo) < 0) { goto error; } if (VIR_ALLOC(conffile) < 0) goto error; if (lxctoolsConffileRead(conffile, cont->config_file_name(cont)) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "'%s'", _("failed to read conffile")); goto error; } if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.arch")) == NULL) { goto error; } if (item_str[0] != '\0') { if (strcmp(item_str, "x86") == 0 || strcmp(item_str, "i686") == 0) { def->os.arch = VIR_ARCH_I686; } else if (strcmp(item_str, "x86_64") == 0 || strcmp(item_str, "amd64") == 0) { def->os.arch = VIR_ARCH_X86_64; } else { virReportError(VIR_ERR_OPERATION_FAILED, "Unknown architecture '%s'.", item_str); goto error; } } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.cpus")) == NULL){ goto error; } if (item_str[0] == '\0') { if (virDomainDefSetVcpusMax(def, nodeinfo->cpus, NULL) < 0) goto error; def->cpumask = virBitmapNew(nodeinfo->cpus); virBitmapSetAll(def->cpumask); } else { int cpunum; if ( (cpunum = virBitmapParse(item_str, &def->cpumask, nodeinfo->cpus) ) < 0) { goto error; } if (virDomainDefSetVcpusMax(def, cpunum, NULL) < 0) goto error; } if (virDomainDefSetVcpus(def, virDomainDefGetVcpusMax(def)) < 0) goto error; VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.shares")) == NULL) { goto error; } if (item_str[0] != '\0') { unsigned long shares; sscanf(item_str, "%lu", &shares); def->cputune.shares = shares; def->cputune.sharesSpecified = true; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_period_us")) == NULL) { goto error; } if (item_str[0] != '\0') { unsigned long long period; sscanf(item_str, "%llu", &period); def->cputune.period = period; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_quota_us")) == NULL) { goto error; } if (item_str[0] != '\0') { long long quota; sscanf(item_str, "%llu", "a); def->cputune.quota = quota; } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.limit_in_bytes")) == NULL) { goto error; } if (item_str[0] == '\0') { virDomainDefSetMemoryTotal(def, nodeinfo->memory); } else { virDomainDefSetMemoryTotal(def, memToULL(item_str)); } def->mem.cur_balloon = virDomainDefGetMemoryTotal(def); // def->mem.max_memory = nodeinfo->memory; // def->mem.memory_slots = 1; //maybe delete max_memory alltogether VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.soft_limit_in_bytes")) == NULL) { goto error; } if (item_str[0] != '\0') { def->mem.soft_limit = memToULL(item_str); } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.mems")) == NULL) { goto error; } if (item_str[0] != '\0') { virBitmapPtr nodeset; if (virBitmapParse(item_str, &nodeset, nodeinfo->nodes) < 0) { goto error; } if (virDomainNumatuneSet(def->numa, true, VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT, VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0 ) { goto error; } } VIR_FREE(item_str); item_str = NULL; if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.include")) == NULL) { goto error; } //lxc.include is optional! if (item_str[0] != '\0') { def->metadata = xmlNewNode(NULL, (const xmlChar*) "metadata"); xmlNewTextChild(def->metadata, NULL, (const xmlChar*) (const xmlChar*)"lxctools:include", (const xmlChar*)item_str); } VIR_FREE(item_str); item_str = NULL; if (lxctoolsReadFSConfig(conffile, def) < 0) goto error; if (lxctoolsReadNetConfig(cont, def) < 0) goto error; return 0; error: VIR_FREE(item_str); VIR_FREE(nodeinfo); return -1; }