int virDomainNumatuneSpecifiedMaxNode(virDomainNumaPtr numatune) { int ret = -1; virBitmapPtr nodemask = NULL; size_t i; int bit; if (!numatune) return ret; nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1); if (nodemask) ret = virBitmapLastSetBit(nodemask); for (i = 0; i < numatune->nmem_nodes; i++) { nodemask = numatune->mem_nodes[i].nodeset; if (!nodemask) continue; bit = virBitmapLastSetBit(nodemask); if (bit > ret) ret = bit; } return ret; }
int virDomainNumatuneMaybeGetNodeset(virDomainNumaPtr numatune, virBitmapPtr auto_nodeset, virBitmapPtr *retNodeset, int cellid) { *retNodeset = NULL; if (!numatune) return 0; if (!virDomainNumatuneNodeSpecified(numatune, cellid) && !numatune->memory.specified) return 0; if (numatune->memory.specified && numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO && !auto_nodeset) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Advice from numad is needed in case of " "automatic numa placement")); return -1; } *retNodeset = virDomainNumatuneGetNodeset(numatune, auto_nodeset, cellid); return 0; }
char * virDomainNumatuneFormatNodeset(virDomainNumaPtr numatune, virBitmapPtr auto_nodeset, int cellid) { return virBitmapFormat(virDomainNumatuneGetNodeset(numatune, auto_nodeset, cellid)); }
int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune, virBitmapPtr nodemask ATTRIBUTE_UNUSED) { if (virDomainNumatuneGetNodeset(numatune, NULL, -1)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libvirt is compiled without NUMA tuning support")); return -1; } return 0; }
bool virDomainNumatuneNodesetIsAvailable(virDomainNumaPtr numatune, virBitmapPtr auto_nodeset) { size_t i = 0; virBitmapPtr b = NULL; if (!numatune) return true; b = virDomainNumatuneGetNodeset(numatune, auto_nodeset, -1); if (!virNumaNodesetIsAvailable(b)) return false; for (i = 0; i < numatune->nmem_nodes; i++) { b = virDomainNumatuneGetNodeset(numatune, auto_nodeset, i); if (!virNumaNodesetIsAvailable(b)) return false; } return true; }
int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune, virBitmapPtr nodemask) { nodemask_t mask; int node = -1; int ret = -1; int bit = 0; size_t i; int maxnode = 0; virBitmapPtr tmp_nodemask = NULL; tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask, -1); if (!tmp_nodemask) return 0; if (numa_available() < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Host kernel is not aware of NUMA.")); return -1; } maxnode = numa_max_node(); maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES; /* Convert nodemask to NUMA bitmask. */ nodemask_zero(&mask); bit = -1; while ((bit = virBitmapNextSetBit(tmp_nodemask, bit)) >= 0) { if (bit > maxnode) { virReportError(VIR_ERR_INTERNAL_ERROR, _("NUMA node %d is out of range"), bit); return -1; } nodemask_set(&mask, bit); } switch (virDomainNumatuneGetMode(numatune, -1)) { case VIR_DOMAIN_NUMATUNE_MEM_STRICT: numa_set_bind_policy(1); numa_set_membind(&mask); numa_set_bind_policy(0); break; case VIR_DOMAIN_NUMATUNE_MEM_PREFERRED: { int nnodes = 0; for (i = 0; i < NUMA_NUM_NODES; i++) { if (nodemask_isset(&mask, i)) { node = i; nnodes++; } } if (nnodes != 1) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("NUMA memory tuning in 'preferred' mode " "only supports single node")); goto cleanup; } numa_set_bind_policy(0); numa_set_preferred(node); } break; case VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE: numa_set_interleave_mask(&mask); break; case VIR_DOMAIN_NUMATUNE_MEM_LAST: break; } ret = 0; cleanup: return ret; }
int lxctoolsSetBasicConfig(lxctoolsConffilePtr conffile, virDomainDefPtr def) { int ret = -1; char *item_str = NULL; /* if (lxctoolsConffileRemoveItems(conffile, "lxc.include") < 0) goto cleanup; if (def->metadata != NULL) { xmlNodePtr node = def->metadata->children; while (node != NULL) { if (node->children != NULL && node->children->type == XML_TEXT_NODE) { if (xmlStrcmp(node->children->name, (const xmlChar*)"lxctools:include")) { if (lxctoolsConffileSetItem(conffile, "lxc.include", (const char*)node->children->content) < 0) goto cleanup; } else if (xmlStrcmp(node->children->name, (const xmlChar*)"lxctools:livemigration-iterations")) { VIR_DEBUG("found migration iterations: %s", node->children->content); } } else { VIR_DEBUG("found include node but no child text node"); } node = node->next; } if (node == NULL) { virReportError(VIR_ERR_OPERATION_FAILED, "'%s'", "found metadata, but no known child element"); if (lxctoolsConffileRemoveItems(conffile, "lxc.include") < 0) goto cleanup; } } */ if (( item_str = lxctoolsConffileGetItem(conffile, "lxc.utsname")) == NULL) goto cleanup; if (item_str[0] == '\0') { if (lxctoolsConffileSetItem(conffile, "lxc.utsname", def->name) < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->os.arch == VIR_ARCH_I686) { if (lxctoolsConffileSetItem(conffile, "lxc.arch", "i686") < 0) goto cleanup; } else if (def->os.arch == VIR_ARCH_X86_64) { if (lxctoolsConffileSetItem(conffile, "lxc.arch", "x86_64") < 0) goto cleanup; } else { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Unknown architecture")); goto cleanup; } if ((item_str = virBitmapFormat(def->cpumask)) == NULL) goto cleanup; printf("'%s'\n", item_str); if (item_str[0] != '\0') { if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.cpuset.cpus", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.cpuset.cpus") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->cputune.sharesSpecified) { if (virAsprintf(&item_str, "%llu", def->cputune.shares) < 0) goto cleanup; if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.cpu.shares", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.cpu.shares") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->cputune.period != 0) { if (virAsprintf(&item_str, "%llu", def->cputune.period) < 0) goto cleanup; if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.cpu.cfs_period_us", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.cpu.cfs_period_us") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->cputune.quota != 0) { if (virAsprintf(&item_str, "%llu", def->cputune.quota) < 0) goto cleanup; if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.cpu.cfs_quota_us", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.cpu.cfs_quota_us") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->mem.total_memory != def->mem.cur_balloon) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("max_balloon and cur_balloon have to have the same value. Memory ballooning is not neccessary for containerss.")); goto cleanup; } if (def->mem.total_memory != 0) { if (virAsprintf(&item_str, "%lluk", def->mem.total_memory) < 0) goto cleanup; if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.memory.limit_in_bytes", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.memory.limit_in_bytes") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if (def->mem.soft_limit != 0 && def->mem.soft_limit < def->mem.cur_balloon) { if (virAsprintf(&item_str, "%lluk", def->mem.soft_limit) < 0) goto cleanup; if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.memory.soft_limit_in_bytes", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.memory.soft_limit_in_bytes") < 0) goto cleanup; } VIR_FREE(item_str); item_str = NULL; if ((item_str = virBitmapFormat(virDomainNumatuneGetNodeset(def->numa,NULL,0))) == NULL) goto cleanup; if (item_str[0] != '\0') { if (lxctoolsConffileSetItem(conffile, "lxc.cgroup.cpuset.mems", item_str) < 0) goto cleanup; } else { if (lxctoolsConffileRemoveItems(conffile, "lxc.cgroup.cpuset.mems") < 0) goto cleanup; } ret = 0; cleanup: VIR_FREE(item_str); return ret; }