From: Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
Adding parsing code for memory tunables in the domain xml file
v2:
+ Fix typo min_guarantee
Signed-off-by: Nikunj A. Dadhania <nikunj(a)linux.vnet.ibm.com>
---
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 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;