From: Nikunj A. Dadhania <nikunj@xxxxxxxxxxxxxxxxxx> Adding parsing code for memory tunables in the domain xml file v2: + Fix typo min_guarantee Signed-off-by: Nikunj A. Dadhania <nikunj@xxxxxxxxxxxxxxxxxx> --- src/conf/domain_conf.c | 50 +++++++++++++++++++++++++++++++++++++------- src/conf/domain_conf.h | 12 ++++++++--- src/esx/esx_vmx.c | 30 +++++++++++++------------- src/lxc/lxc_controller.c | 2 +- src/lxc/lxc_driver.c | 12 +++++------ src/openvz/openvz_driver.c | 8 ++++--- src/qemu/qemu_conf.c | 8 ++++--- src/qemu/qemu_driver.c | 18 ++++++++-------- src/test/test_driver.c | 12 +++++------ src/uml/uml_conf.c | 2 +- src/uml/uml_driver.c | 14 ++++++------ 11 files changed, 104 insertions(+), 64 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e05d5d7..0dd74e4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4231,19 +4231,38 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, def->description = virXPathString("string(./description[1])", ctxt); /* Extract domain memory */ - if (virXPathULong("string(./memory[1])", ctxt, &def->maxmem) < 0) { + if (virXPathULong("string(./memory[1])", ctxt, + &def->mem.max_balloon) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing memory element")); goto error; } - if (virXPathULong("string(./currentMemory[1])", ctxt, &def->memory) < 0) - def->memory = def->maxmem; + if (virXPathULong("string(./currentMemory[1])", ctxt, + &def->mem.cur_balloon) < 0) + def->mem.cur_balloon = def->mem.max_balloon; node = virXPathNode("./memoryBacking/hugepages", ctxt); if (node) - def->hugepage_backed = 1; - + def->mem.hugepage_backed = 1; + + /* Extract other memory tunables */ + if (virXPathULong("string(./memtune/hard_limit)", ctxt, + &def->mem.hard_limit) < 0) + def->mem.hard_limit = 0; + + if (virXPathULong("string(./memtune/soft_limit[1])", ctxt, + &def->mem.soft_limit) < 0) + def->mem.soft_limit = 0; + + if (virXPathULong("string(./memtune/min_guarantee[1])", ctxt, + &def->mem.min_guarantee) < 0) + def->mem.min_guarantee = 0; + + if (virXPathULong("string(./memtune/swap_hard_limit[1])", ctxt, + &def->mem.swap_hard_limit) < 0) + def->mem.swap_hard_limit = 0; + if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0) def->vcpus = 1; @@ -6382,10 +6401,25 @@ char *virDomainDefFormat(virDomainDefPtr def, virBufferEscapeString(&buf, " <description>%s</description>\n", def->description); - virBufferVSprintf(&buf, " <memory>%lu</memory>\n", def->maxmem); + virBufferVSprintf(&buf, " <memory>%lu</memory>\n", def->mem.max_balloon); virBufferVSprintf(&buf, " <currentMemory>%lu</currentMemory>\n", - def->memory); - if (def->hugepage_backed) { + def->mem.cur_balloon); + virBufferVSprintf(&buf, " <memtune>\n"); + if (def->mem.hard_limit) { + virBufferVSprintf(&buf, " <hard_limit>%lu</hard_limit>\n", + def->mem.hard_limit); + } + if (def->mem.soft_limit) { + virBufferVSprintf(&buf, " <soft_limit>%lu</soft_limit>\n", + def->mem.soft_limit); + } + if (def->mem.swap_hard_limit) { + virBufferVSprintf(&buf, " <swap_hard_limit>%lu</swap_hard_limit>\n", + def->mem.swap_hard_limit); + } + virBufferVSprintf(&buf, " </memtune>\n"); + + if (def->mem.hugepage_backed) { virBufferAddLit(&buf, " <memoryBacking>\n"); virBufferAddLit(&buf, " <hugepages/>\n"); virBufferAddLit(&buf, " </memoryBacking>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7195c04..2ecc2af 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -864,9 +864,15 @@ struct _virDomainDef { char *name; char *description; - unsigned long memory; - unsigned long maxmem; - unsigned char hugepage_backed; + struct { + unsigned long max_balloon; + unsigned long cur_balloon; + unsigned long hugepage_backed; + unsigned long hard_limit; + unsigned long soft_limit; + unsigned long min_guarantee; + unsigned long swap_hard_limit; + } mem; unsigned long vcpus; int cpumasklen; char *cpumask; diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c index 59eb3b2..6f1eb17 100644 --- a/src/esx/esx_vmx.c +++ b/src/esx/esx_vmx.c @@ -48,8 +48,8 @@ domain-xml <=> vmx def->id = <value> <=> ??? # not representable def->uuid = <value> <=> uuid.bios = "<value>" def->name = <value> <=> displayName = "<value>" -def->maxmem = <value kilobyte> <=> memsize = "<value megabyte>" # must be a multiple of 4, defaults to 32 -def->memory = <value kilobyte> <=> sched.mem.max = "<value megabyte>" # defaults to "unlimited" -> def->memory = def->maxmem +def->mem.max_balloon = <value kilobyte> <=> memsize = "<value megabyte>" # must be a multiple of 4, defaults to 32 +def->mem.cur_balloon = <value kilobyte> <=> sched.mem.max = "<value megabyte>" # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon def->vcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1 def->cpumask = <uint list> <=> sched.cpu.affinity = "<uint list>" @@ -979,7 +979,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx, *tmp2 = '\0'; } - /* vmx:memsize -> def:maxmem */ + /* vmx:memsize -> def:mem.max_balloon */ if (esxUtil_GetConfigLong(conf, "memsize", &memsize, 32, true) < 0) { goto cleanup; } @@ -991,7 +991,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx, goto cleanup; } - def->maxmem = memsize * 1024; /* Scale from megabytes to kilobytes */ + def->mem.max_balloon = memsize * 1024; /* Scale from megabytes to kilobytes */ /* vmx:sched.mem.max -> def:memory */ if (esxUtil_GetConfigLong(conf, "sched.mem.max", &memory, memsize, @@ -1003,10 +1003,10 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx, memory = memsize; } - def->memory = memory * 1024; /* Scale from megabytes to kilobytes */ + def->mem.cur_balloon = memory * 1024; /* Scale from megabytes to kilobytes */ - if (def->memory > def->maxmem) { - def->memory = def->maxmem; + if (def->mem.cur_balloon > def->mem.max_balloon) { + def->mem.cur_balloon = def->mem.max_balloon; } /* vmx:numvcpus -> def:vcpus */ @@ -2469,32 +2469,32 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def, virBufferVSprintf(&buffer, "annotation = \"%s\"\n", annotation); } - /* def:maxmem -> vmx:memsize */ - if (def->maxmem <= 0 || def->maxmem % 4096 != 0) { + /* def:mem.max_balloon -> vmx:memsize */ + if (def->mem.max_balloon <= 0 || def->mem.max_balloon % 4096 != 0) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Expecting domain XML entry 'memory' to be an unsigned " "integer (multiple of 4096) but found %lld"), - (unsigned long long)def->maxmem); + (unsigned long long)def->mem.max_balloon); goto cleanup; } /* Scale from kilobytes to megabytes */ virBufferVSprintf(&buffer, "memsize = \"%d\"\n", - (int)(def->maxmem / 1024)); + (int)(def->mem.max_balloon / 1024)); /* def:memory -> vmx:sched.mem.max */ - if (def->memory < def->maxmem) { - if (def->memory <= 0 || def->memory % 1024 != 0) { + if (def->mem.cur_balloon < def->mem.max_balloon) { + if (def->mem.cur_balloon <= 0 || def->mem.cur_balloon % 1024 != 0) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Expecting domain XML entry 'currentMemory' to be an " "unsigned integer (multiple of 1024) but found %lld"), - (unsigned long long)def->memory); + (unsigned long long)def->mem.cur_balloon); goto cleanup; } /* Scale from kilobytes to megabytes */ virBufferVSprintf(&buffer, "sched.mem.max = \"%d\"\n", - (int)(def->memory / 1024)); + (int)(def->mem.cur_balloon / 1024)); } /* def:vcpus -> vmx:numvcpus */ diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 7dc51a5..82ecce0 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -102,7 +102,7 @@ static int lxcSetContainerResources(virDomainDefPtr def) goto cleanup; } - rc = virCgroupSetMemory(cgroup, def->maxmem); + rc = virCgroupSetMemory(cgroup, def->mem.max_balloon); if (rc != 0) { virReportSystemError(-rc, _("Unable to set memory limit for domain %s"), diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 9a4843d..9e37906 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -500,7 +500,7 @@ static int lxcDomainGetInfo(virDomainPtr dom, if (!virDomainObjIsActive(vm) || driver->cgroup == NULL) { info->cpuTime = 0; - info->memory = vm->def->memory; + info->memory = vm->def->mem.cur_balloon; } else { if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) { lxcError(VIR_ERR_INTERNAL_ERROR, @@ -520,7 +520,7 @@ static int lxcDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->maxmem; + info->maxMem = vm->def->mem.max_balloon; info->nrVirtCpu = 1; ret = 0; @@ -580,7 +580,7 @@ static unsigned long lxcDomainGetMaxMemory(virDomainPtr dom) { goto cleanup; } - ret = vm->def->maxmem; + ret = vm->def->mem.max_balloon; cleanup: if (vm) @@ -605,13 +605,13 @@ static int lxcDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) { goto cleanup; } - if (newmax < vm->def->memory) { + if (newmax < vm->def->mem.cur_balloon) { lxcError(VIR_ERR_INVALID_ARG, "%s", _("Cannot set max memory lower than current memory")); goto cleanup; } - vm->def->maxmem = newmax; + vm->def->mem.max_balloon = newmax; ret = 0; cleanup: @@ -637,7 +637,7 @@ static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) { goto cleanup; } - if (newmem > vm->def->maxmem) { + if (newmem > vm->def->mem.max_balloon) { lxcError(VIR_ERR_INVALID_ARG, "%s", _("Cannot set memory higher than max memory")); goto cleanup; diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index edef080..beee006 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -403,8 +403,8 @@ static int openvzDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->maxmem; - info->memory = vm->def->memory; + info->maxMem = vm->def->mem.max_balloon; + info->memory = vm->def->mem.cur_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; @@ -934,8 +934,8 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) } } - if (vm->def->memory > 0) { - if (openvzDomainSetMemoryInternal(vm, vm->def->memory) < 0) { + if (vm->def->mem.cur_balloon > 0) { + if (openvzDomainSetMemoryInternal(vm, vm->def->mem.cur_balloon) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not set memory size")); goto cleanup; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 7a37c70..731c554 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3846,7 +3846,7 @@ int qemudBuildCommandLine(virConnectPtr conn, * is set post-startup using the balloon driver. If balloon driver * is not supported, then they're out of luck anyway */ - snprintf(memory, sizeof(memory), "%lu", def->maxmem/1024); + snprintf(memory, sizeof(memory), "%lu", def->mem.max_balloon/1024); snprintf(domid, sizeof(domid), "%d", def->id); ADD_ENV_LIT("LC_ALL=C"); @@ -3892,7 +3892,7 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-enable-kvm"); ADD_ARG_LIT("-m"); ADD_ARG_LIT(memory); - if (def->hugepage_backed) { + if (def->mem.hugepage_backed) { if (!driver->hugetlbfs_mount) { qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("hugetlbfs filesystem is not mounted")); @@ -6119,7 +6119,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, virUUIDGenerate(def->uuid); def->id = -1; - def->memory = def->maxmem = 64 * 1024; + def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024; def->vcpus = 1; def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; def->features = (1 << VIR_DOMAIN_FEATURE_ACPI) @@ -6234,7 +6234,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, _("cannot parse memory level '%s'"), val); goto error; } - def->memory = def->maxmem = mem * 1024; + def->mem.cur_balloon = def->mem.max_balloon = mem * 1024; } else if (STREQ(arg, "-smp")) { WANT_VALUE(); if (qemuParseCommandLineSmp(def, val) < 0) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d6dd1da..17d4fbe 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3939,7 +3939,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, DEBUG0("Setting initial memory amount"); qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuMonitorSetBalloon(priv->mon, vm->def->memory) < 0) { + if (qemuMonitorSetBalloon(priv->mon, vm->def->mem.cur_balloon) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; } @@ -4862,7 +4862,7 @@ static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) { goto cleanup; } - ret = vm->def->maxmem; + ret = vm->def->mem.max_balloon; cleanup: if (vm) @@ -4893,7 +4893,7 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) { goto cleanup; } - if (newmem > vm->def->maxmem) { + if (newmem > vm->def->mem.max_balloon) { qemuReportError(VIR_ERR_INVALID_ARG, "%s", _("cannot set memory higher than max memory")); goto cleanup; @@ -4957,14 +4957,14 @@ static int qemudDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->maxmem; + info->maxMem = vm->def->mem.max_balloon; if (virDomainObjIsActive(vm)) { qemuDomainObjPrivatePtr priv = vm->privateData; if ((vm->def->memballoon != NULL) && (vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) { - info->memory = vm->def->maxmem; + info->memory = vm->def->mem.max_balloon; } else if (!priv->jobActive) { if (qemuDomainObjBeginJob(vm) < 0) goto cleanup; @@ -4980,7 +4980,7 @@ static int qemudDomainGetInfo(virDomainPtr dom, if (err == 0) /* Balloon not supported, so maxmem is always the allocation */ - info->memory = vm->def->maxmem; + info->memory = vm->def->mem.max_balloon; else info->memory = balloon; @@ -4989,10 +4989,10 @@ static int qemudDomainGetInfo(virDomainPtr dom, goto cleanup; } } else { - info->memory = vm->def->memory; + info->memory = vm->def->mem.cur_balloon; } } else { - info->memory = vm->def->memory; + info->memory = vm->def->mem.cur_balloon; } info->nrVirtCpu = vm->def->vcpus; @@ -6774,7 +6774,7 @@ static char *qemudDomainDumpXML(virDomainPtr dom, if (err < 0) goto cleanup; if (err > 0) - vm->def->memory = balloon; + vm->def->mem.cur_balloon = balloon; /* err == 0 indicates no balloon support, so ignore it */ } } diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 3560a19..382d5a8 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1681,8 +1681,8 @@ static int testGetDomainInfo (virDomainPtr domain, } info->state = privdom->state; - info->memory = privdom->def->memory; - info->maxMem = privdom->def->maxmem; + info->memory = privdom->def->mem.cur_balloon; + info->maxMem = privdom->def->mem.max_balloon; info->nrVirtCpu = privdom->def->vcpus; info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); ret = 0; @@ -1963,7 +1963,7 @@ static unsigned long testGetMaxMemory(virDomainPtr domain) { goto cleanup; } - ret = privdom->def->maxmem; + ret = privdom->def->mem.max_balloon; cleanup: if (privdom) @@ -1989,7 +1989,7 @@ static int testSetMaxMemory(virDomainPtr domain, } /* XXX validate not over host memory wrt to other domains */ - privdom->def->maxmem = memory; + privdom->def->mem.max_balloon = memory; ret = 0; cleanup: @@ -2015,12 +2015,12 @@ static int testSetMemory(virDomainPtr domain, goto cleanup; } - if (memory > privdom->def->maxmem) { + if (memory > privdom->def->mem.max_balloon) { testError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto cleanup; } - privdom->def->memory = memory; + privdom->def->mem.cur_balloon = memory; ret = 0; cleanup: diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index f2eaef5..33b2b04 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -502,7 +502,7 @@ int umlBuildCommandLine(virConnectPtr conn, } \ } while (0) - snprintf(memory, sizeof(memory), "%luK", vm->def->memory); + snprintf(memory, sizeof(memory), "%luK", vm->def->mem.cur_balloon); ADD_ENV_LIT("LC_ALL=C"); diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 50c8152..9003e9a 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1420,7 +1420,7 @@ static unsigned long umlDomainGetMaxMemory(virDomainPtr dom) { _("no domain with matching uuid '%s'"), uuidstr); goto cleanup; } - ret = vm->def->maxmem; + ret = vm->def->mem.max_balloon; cleanup: if (vm) @@ -1446,13 +1446,13 @@ static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) { goto cleanup; } - if (newmax < vm->def->memory) { + if (newmax < vm->def->mem.cur_balloon) { umlReportError(VIR_ERR_INVALID_ARG, "%s", _("cannot set max memory lower than current memory")); goto cleanup; } - vm->def->maxmem = newmax; + vm->def->mem.max_balloon = newmax; ret = 0; cleanup: @@ -1485,13 +1485,13 @@ static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) { goto cleanup; } - if (newmem > vm->def->maxmem) { + if (newmem > vm->def->mem.max_balloon) { umlReportError(VIR_ERR_INVALID_ARG, "%s", _("cannot set memory higher than max memory")); goto cleanup; } - vm->def->memory = newmem; + vm->def->mem.cur_balloon = newmem; ret = 0; cleanup: @@ -1528,8 +1528,8 @@ static int umlDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->maxmem; - info->memory = vm->def->memory; + info->maxMem = vm->def->mem.max_balloon; + info->memory = vm->def->mem.cur_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list