XML parsing for memory tunables

Adding parsing code for memory tunables in the domain xml file
also change the internal define structures used for domain memory
informations
Adds a new specific test
This commit is contained in:
Nikunj A. Dadhania 2010-10-12 16:43:39 +02:00 committed by Daniel Veillard
parent af996f5544
commit d390fce413
22 changed files with 191 additions and 108 deletions

View File

@ -4235,18 +4235,37 @@ 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;
@ -6384,10 +6403,29 @@ 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);
/* add memtune only if there are any */
if(def->mem.hard_limit || def->mem.hard_limit || def->mem.hard_limit)
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);
}
if(def->mem.hard_limit || def->mem.hard_limit || def->mem.hard_limit)
virBufferVSprintf(&buf, " </memtune>\n");
if (def->mem.hugepage_backed) {
virBufferAddLit(&buf, " <memoryBacking>\n");
virBufferAddLit(&buf, " <hugepages/>\n");
virBufferAddLit(&buf, " </memoryBacking>\n");

View File

@ -866,9 +866,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;

View File

@ -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>"
@ -1012,7 +1012,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;
}
@ -1024,7 +1024,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,
@ -1036,10 +1036,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 */
@ -2578,32 +2578,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 */

View File

@ -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"),

View File

@ -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;

View File

@ -172,7 +172,7 @@ char* xmlOneTemplate(virDomainDefPtr def)
virBufferVSprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
def->name,
def->vcpus,
(def->maxmem)/1024);
(def->mem.max_balloon)/1024);
/*Optional Booting OpenNebula Information:*/
if (def->os.kernel) {

View File

@ -357,7 +357,7 @@ static int oneDomainGetInfo(virDomainPtr dom,
cptr=strstr(vm_info,"MEMORY");
cptr=index(cptr,':');
cptr++;
vm->def->memory = atoi(cptr);
vm->def->mem.cur_balloon = atoi(cptr);
//run time:
cptr=strstr(vm_info,"START TIME");
@ -369,8 +369,8 @@ static int oneDomainGetInfo(virDomainPtr dom,
}
info->state = vm->state;
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;
virDomainObjUnlock(vm);
@ -818,6 +818,8 @@ static virDriver oneDriver = {
NULL, /* domainRevertToSnapshot */
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainSetMemoryParameters */
NULL, /* domainGetMemoryParameters */
};
static virStateDriver oneStateDriver = {

View File

@ -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;

View File

@ -3516,13 +3516,13 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
goto err;
}
if ((def.maxmem =
if ((def.mem.max_balloon =
phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
VIR_ERROR0(_("Unable to determine domain's max memory."));
goto err;
}
if ((def.memory =
if ((def.mem.cur_balloon =
phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
VIR_ERROR0(_("Unable to determine domain's memory."));
goto err;
@ -3701,14 +3701,14 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
int exit_status = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (!def->memory) {
if (!def->mem.cur_balloon) {
PHYP_ERROR(VIR_ERR_XML_ERROR,"%s",
_("Field \"<memory>\" on the domain XML file is missing or has "
"invalid value."));
goto err;
}
if (!def->maxmem) {
if (!def->mem.max_balloon) {
PHYP_ERROR(VIR_ERR_XML_ERROR,"%s",
_("Field \"<currentMemory>\" on the domain XML file is missing or"
" has invalid value."));
@ -3733,8 +3733,9 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
virBufferVSprintf(&buf, " -m %s", managed_system);
virBufferVSprintf(&buf, " -r lpar -p %s -i min_mem=%d,desired_mem=%d,"
"max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
def->name, (int) def->memory, (int) def->memory,
(int) def->maxmem, (int) def->vcpus, def->disks[0]->src);
def->name, (int) def->mem.cur_balloon,
(int) def->mem.cur_balloon, (int) def->mem.max_balloon,
(int) def->vcpus, def->disks[0]->src);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();

View File

@ -3849,7 +3849,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");
@ -3895,7 +3895,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"));
@ -6122,7 +6122,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)
@ -6237,7 +6237,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)

View File

@ -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 */
}
}

View File

@ -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:

View File

@ -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");

View File

@ -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;

View File

@ -1708,7 +1708,7 @@ static int vboxDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) {
if (STREQ(dom->name, machineName)) {
/* Get the Machine State (also match it with
* virDomainState). Get the Machine memory and
* for time being set maxmem and memory to same
* for time being set max_balloon and cur_balloon to same
* Also since there is no direct way of checking
* the cputime required (one condition being the
* VM is remote), return zero for cputime. Get the
@ -1734,8 +1734,8 @@ static int vboxDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) {
info->cpuTime = 0;
info->nrVirtCpu = CPUCount;
info->memory = memorySize * 1024;
info->maxMem = maxMemorySize * 1024;
info->mem.cur_balloon = memorySize * 1024;
info->mem.max_balloon = maxMemorySize * 1024;
switch(state) {
case MachineState_Running:
info->state = VIR_DOMAIN_RUNNING;
@ -1980,7 +1980,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
def->name = strdup(dom->name);
machine->vtbl->GetMemorySize(machine, &memorySize);
def->memory = memorySize * 1024;
def->mem.cur_balloon = memorySize * 1024;
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
if (systemProperties) {
@ -1996,8 +1996,8 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
* the notation here seems to be inconsistent while
* reading and while dumping xml
*/
/* def->maxmem = maxMemorySize * 1024; */
def->maxmem = memorySize * 1024;
/* def->mem.max_balloon = maxMemorySize * 1024; */
def->mem.max_balloon = memorySize * 1024;
machine->vtbl->GetCPUCount(machine, &CPUCount);
def->vcpus = CPUCount;
@ -4562,12 +4562,12 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
goto cleanup;
}
rc = machine->vtbl->SetMemorySize(machine, def->memory / 1024);
rc = machine->vtbl->SetMemorySize(machine, def->mem.cur_balloon / 1024);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_INTERNAL_ERROR,
_("could not set the memory size of the domain to: %lu Kb, "
"rc=%08x"),
def->memory, (unsigned)rc);
def->mem.cur_balloon, (unsigned)rc);
}
rc = machine->vtbl->SetCPUCount(machine, def->vcpus);

View File

@ -2167,10 +2167,12 @@ xenDaemonParseSxpr(virConnectPtr conn,
}
}
def->maxmem = (unsigned long) (sexpr_u64(root, "domain/maxmem") << 10);
def->memory = (unsigned long) (sexpr_u64(root, "domain/memory") << 10);
if (def->memory > def->maxmem)
def->maxmem = def->memory;
def->mem.max_balloon = (unsigned long)
(sexpr_u64(root, "domain/maxmem") << 10);
def->mem.cur_balloon = (unsigned long)
(sexpr_u64(root, "domain/memory") << 10);
if (def->mem.cur_balloon > def->mem.max_balloon)
def->mem.cur_balloon = def->mem.max_balloon;
if (cpus != NULL) {
def->cpumasklen = VIR_DOMAIN_CPUMASK_LEN;
@ -5663,7 +5665,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAddLit(&buf, "(vm ");
virBufferVSprintf(&buf, "(name '%s')", def->name);
virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)",
def->memory/1024, def->maxmem/1024);
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
virBufferVSprintf(&buf, "(vcpus %lu)", def->vcpus);
if (def->cpumask) {

View File

@ -644,8 +644,8 @@ int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) {
goto error;
memset(info, 0, sizeof(virDomainInfo));
info->maxMem = entry->def->maxmem;
info->memory = entry->def->memory;
info->maxMem = entry->def->mem.max_balloon;
info->memory = entry->def->mem.cur_balloon;
info->nrVirtCpu = entry->def->vcpus;
info->state = VIR_DOMAIN_SHUTOFF;
info->cpuTime = 0;
@ -759,14 +759,16 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
goto cleanup;
}
if (xenXMConfigGetULong(conf, "memory", &def->memory, MIN_XEN_GUEST_SIZE * 2) < 0)
if (xenXMConfigGetULong(conf, "memory", &def->mem.cur_balloon,
MIN_XEN_GUEST_SIZE * 2) < 0)
goto cleanup;
if (xenXMConfigGetULong(conf, "maxmem", &def->maxmem, def->memory) < 0)
if (xenXMConfigGetULong(conf, "maxmem", &def->mem.max_balloon,
def->mem.cur_balloon) < 0)
goto cleanup;
def->memory *= 1024;
def->maxmem *= 1024;
def->mem.cur_balloon *= 1024;
def->mem.max_balloon *= 1024;
if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
@ -1530,9 +1532,9 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) {
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
entry->def->memory = memory;
if (entry->def->memory > entry->def->maxmem)
entry->def->memory = entry->def->maxmem;
entry->def->mem.cur_balloon = memory;
if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
@ -1573,9 +1575,9 @@ int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) {
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
entry->def->maxmem = memory;
if (entry->def->memory > entry->def->maxmem)
entry->def->memory = entry->def->maxmem;
entry->def->mem.max_balloon = memory;
if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
@ -1614,7 +1616,7 @@ unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain) {
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
ret = entry->def->maxmem;
ret = entry->def->mem.max_balloon;
cleanup:
xenUnifiedUnlock(priv);
@ -2233,10 +2235,10 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "maxmem", def->maxmem / 1024) < 0)
if (xenXMConfigSetInt(conf, "maxmem", def->mem.max_balloon / 1024) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "memory", def->memory / 1024) < 0)
if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)

View File

@ -1284,12 +1284,12 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
}
unsigned long memory=0;
memory = xenapiDomainGetMaxMemory(dom);
defPtr->maxmem = memory;
defPtr->mem.max_balloon = memory;
int64_t dynamic_mem=0;
if (xen_vm_get_memory_dynamic_max(session, &dynamic_mem, vm)) {
defPtr->memory = (unsigned long) (dynamic_mem / 1024);
defPtr->mem.cur_balloon = (unsigned long) (dynamic_mem / 1024);
} else {
defPtr->memory = memory;
defPtr->mem.cur_balloon = memory;
}
defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
enum xen_on_normal_exit action;

View File

@ -503,10 +503,10 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
if (!((*record)->pv_bootloader_args = strdup(def->os.bootloaderArgs)))
goto error_cleanup;
if (def->memory)
(*record)->memory_static_max = (int64_t) (def->memory * 1024);
if (def->maxmem)
(*record)->memory_dynamic_max = (int64_t) (def->maxmem * 1024);
if (def->mem.cur_balloon)
(*record)->memory_static_max = (int64_t) (def->mem.cur_balloon * 1024);
if (def->mem.max_balloon)
(*record)->memory_dynamic_max = (int64_t) (def->mem.max_balloon * 1024);
else
(*record)->memory_dynamic_max = (*record)->memory_static_max;

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -name QEMUGuest1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb

View File

@ -0,0 +1,30 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<memtune>
<hard_limit>512000</hard_limit>
<soft_limit>128000</soft_limit>
<swap_hard_limit>1024000</swap_hard_limit>
</memtune>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -178,6 +178,7 @@ mymain(int argc, char **argv)
DO_TEST("hostdev-pci-address");
DO_TEST("encrypted-disk");
DO_TEST("memtune");
/* These tests generate different XML */
DO_TEST_DIFFERENT("balloon-device-auto");