* Nikunj A. Dadhania <nikunj@xxxxxxxxxxxxxxxxxx> [2010-09-28 15:26:30]: > 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; > + Quick question, does 0 represent invalid values? I'd presume you'd want to use something like -1. We support unsigned long long for the values to be set (64 bit signed), unlimited translates to 2^63 - 1, is ULong sufficient to represent that value? > 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; The hard_limit, soft_limit, swap_hard_limit are s64 and the value is in bytes. What is the unit supported in this implementation? > + } 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 a240e6d..8977835 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 4247e0a..92cf4a1 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 f44a18f..bf4373a 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 906211c..7d4d119 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 1236abb..e195541 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 -- Three Cheers, Balbir -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list