From 4f9907cd11796d984ed08fcfb9852b10c62a9fb1 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 17 Feb 2015 18:01:09 +0100 Subject: [PATCH] conf: Replace access to def->mem.max_balloon with accessor functions As there are two possible approaches to define a domain's memory size - one used with legacy, non-NUMA VMs configured in the element and per-node based approach on NUMA machines - the user needs to make sure that both are specified correctly in the NUMA case. To avoid this burden on the user I'd like to replace the NUMA case with automatic totaling of the memory size. To achieve this I need to replace direct access to the virDomainMemtune's 'max_balloon' field with two separate getters depending on the desired size. The two sizes are needed as: 1) Startup memory size doesn't include memory modules in some hypervisors. 2) After startup these count as the usable memory size. Note that the comments for the functions are future aware and document state that will be present after a few later patches. --- src/bhyve/bhyve_command.c | 6 +-- src/bhyve/bhyve_driver.c | 2 +- src/conf/domain_conf.c | 66 +++++++++++++++++++++++++++----- src/conf/domain_conf.h | 4 ++ src/hyperv/hyperv_driver.c | 2 +- src/libvirt_private.syms | 3 ++ src/libxl/libxl_conf.c | 2 +- src/libxl/libxl_driver.c | 8 ++-- src/lxc/lxc_cgroup.c | 2 +- src/lxc/lxc_driver.c | 12 +++--- src/lxc/lxc_fuse.c | 4 +- src/lxc/lxc_native.c | 4 +- src/openvz/openvz_driver.c | 2 +- src/parallels/parallels_driver.c | 2 +- src/parallels/parallels_sdk.c | 12 +++--- src/phyp/phyp_driver.c | 11 ++++-- src/qemu/qemu_command.c | 18 ++++++--- src/qemu/qemu_driver.c | 21 +++++----- src/qemu/qemu_hotplug.c | 8 ++-- src/qemu/qemu_process.c | 2 +- src/test/test_driver.c | 8 ++-- src/uml/uml_driver.c | 8 ++-- src/vbox/vbox_common.c | 4 +- src/vmware/vmware_driver.c | 2 +- src/vmx/vmx.c | 12 +++--- src/xen/xm_internal.c | 14 +++---- src/xenapi/xenapi_driver.c | 2 +- src/xenapi/xenapi_utils.c | 4 +- src/xenconfig/xen_common.c | 8 ++-- src/xenconfig/xen_sxpr.c | 9 +++-- 30 files changed, 166 insertions(+), 96 deletions(-) diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 6e3bf0357b..5e31ca6434 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -237,7 +237,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, /* Memory */ virCommandAddArg(cmd, "-m"); virCommandAddArgFormat(cmd, "%llu", - VIR_DIV_UP(def->mem.max_balloon, 1024)); + VIR_DIV_UP(virDomainDefGetMemoryInitial(def), 1024)); /* Options */ if (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_TRISTATE_SWITCH_ON) @@ -322,7 +322,7 @@ virBhyveProcessBuildBhyveloadCmd(virDomainDefPtr def, virDomainDiskDefPtr disk) /* Memory (MB) */ virCommandAddArg(cmd, "-m"); virCommandAddArgFormat(cmd, "%llu", - VIR_DIV_UP(def->mem.max_balloon, 1024)); + VIR_DIV_UP(virDomainDefGetMemoryInitial(def), 1024)); /* Image path */ virCommandAddArg(cmd, "-d"); @@ -477,7 +477,7 @@ virBhyveProcessBuildGrubbhyveCmd(virDomainDefPtr def, /* Memory in MB */ virCommandAddArg(cmd, "--memory"); virCommandAddArgFormat(cmd, "%llu", - VIR_DIV_UP(def->mem.max_balloon, 1024)); + VIR_DIV_UP(virDomainDefGetMemoryInitial(def), 1024)); if ((bhyveDriverGetGrubCaps(conn) & BHYVE_GRUB_CAP_CONSDEV) != 0 && def->nserials > 0) { diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 2817f8e1c5..33a12be2d6 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -303,7 +303,7 @@ bhyveDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) } info->state = virDomainObjGetState(vm, NULL); - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); info->nrVirtCpu = vm->def->vcpus; ret = 0; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3d05844aa4..d27d42b920 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3208,24 +3208,26 @@ virDomainDefPostParseInternal(virDomainDefPtr def, return -1; } - if (def->mem.cur_balloon > def->mem.max_balloon) { + if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def)) { /* Older libvirt could get into this situation due to * rounding; if the discrepancy is less than 4MiB, we silently * round down, otherwise we flag the issue. */ if (VIR_DIV_UP(def->mem.cur_balloon, 4096) > - VIR_DIV_UP(def->mem.max_balloon, 4096)) { + VIR_DIV_UP(virDomainDefGetMemoryActual(def), 4096)) { virReportError(VIR_ERR_XML_ERROR, _("current memory '%lluk' exceeds " "maximum '%lluk'"), - def->mem.cur_balloon, def->mem.max_balloon); + def->mem.cur_balloon, + virDomainDefGetMemoryActual(def)); return -1; } else { VIR_DEBUG("Truncating current %lluk to maximum %lluk", - def->mem.cur_balloon, def->mem.max_balloon); - def->mem.cur_balloon = def->mem.max_balloon; + def->mem.cur_balloon, + virDomainDefGetMemoryActual(def)); + def->mem.cur_balloon = virDomainDefGetMemoryActual(def); } } else if (def->mem.cur_balloon == 0) { - def->mem.cur_balloon = def->mem.max_balloon; + def->mem.cur_balloon = virDomainDefGetMemoryActual(def); } /* @@ -6972,6 +6974,51 @@ virDomainParseMemoryLimit(const char *xpath, } +/** + * virDomainDefGetMemoryInitial: + * @def: domain definition + * + * Returns the size of the initial amount of guest memory. The initial amount + * is the memory size is either the configured amount in the element + * or the sum of memory sizes of NUMA nodes in case NUMA is enabled in @def. + */ +unsigned long long +virDomainDefGetMemoryInitial(virDomainDefPtr def) +{ + return def->mem.max_balloon; +} + + +/** + * virDomainDefSetMemoryInitial: + * @def: domain definition + * @size: size to set + * + * Sets the initial memory size in @def. + */ +void +virDomainDefSetMemoryInitial(virDomainDefPtr def, + unsigned long long size) +{ + def->mem.max_balloon = size; +} + + +/** + * virDomainDefGetMemoryActual: + * @def: domain definition + * + * Returns the current maximum memory size usable by the domain described by + * @def. This size is a sum of size returned by virDomainDefGetMemoryInitial + * and possible additional memory devices. + */ +unsigned long long +virDomainDefGetMemoryActual(virDomainDefPtr def) +{ + return virDomainDefGetMemoryInitial(def); +} + + static int virDomainControllerModelTypeFromString(const virDomainControllerDef *def, const char *model) @@ -16108,10 +16155,11 @@ virDomainDefCheckABIStability(virDomainDefPtr src, goto error; } - if (src->mem.max_balloon != dst->mem.max_balloon) { + if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain max memory %lld does not match source %lld"), - dst->mem.max_balloon, src->mem.max_balloon); + virDomainDefGetMemoryInitial(dst), + virDomainDefGetMemoryInitial(src)); goto error; } if (src->mem.cur_balloon != dst->mem.cur_balloon) { @@ -19885,7 +19933,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, " dumpCore='%s'", virTristateSwitchTypeToString(def->mem.dump_core)); virBufferAsprintf(buf, " unit='KiB'>%llu\n", - def->mem.max_balloon); + virDomainDefGetMemoryActual(def)); virBufferAsprintf(buf, "%llu\n", def->mem.cur_balloon); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a20507024c..319ec646ea 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2194,6 +2194,10 @@ struct _virDomainDef { xmlNodePtr metadata; }; +unsigned long long virDomainDefGetMemoryInitial(virDomainDefPtr def); +void virDomainDefSetMemoryInitial(virDomainDefPtr def, unsigned long long size); +unsigned long long virDomainDefGetMemoryActual(virDomainDefPtr def); + typedef enum { VIR_DOMAIN_TAINT_CUSTOM_ARGV, /* Custom ARGV passthrough from XML */ VIR_DOMAIN_TAINT_CUSTOM_MONITOR, /* Custom monitor commands issued */ diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 906c6032f2..00169c7d31 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -870,7 +870,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) if (VIR_STRDUP(def->description, virtualSystemSettingData->data->Notes) < 0) goto cleanup; - def->mem.max_balloon = memorySettingData->data->Limit * 1024; /* megabyte to kilobyte */ + virDomainDefSetMemoryInitial(def, memorySettingData->data->Limit * 1024); /* megabyte to kilobyte */ def->mem.cur_balloon = memorySettingData->data->VirtualQuantity * 1024; /* megabyte to kilobyte */ def->vcpus = processorSettingData->data->VirtualQuantity; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 63e378bf0a..ea3ffb0a79 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -198,6 +198,8 @@ virDomainDefFormatConvertXMLFlags; virDomainDefFormatInternal; virDomainDefFree; virDomainDefGetDefaultEmulator; +virDomainDefGetMemoryActual; +virDomainDefGetMemoryInitial; virDomainDefGetSecurityLabelDef; virDomainDefHasDeviceAddress; virDomainDefMaybeAddController; @@ -209,6 +211,7 @@ virDomainDefParseFile; virDomainDefParseNode; virDomainDefParseString; virDomainDefPostParse; +virDomainDefSetMemoryInitial; virDomainDeleteConfig; virDomainDeviceAddressIsValid; virDomainDeviceAddressTypeToString; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 50ef9d81a3..5ad453e22c 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -659,7 +659,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, } } b_info->sched_params.weight = 1000; - b_info->max_memkb = def->mem.max_balloon; + b_info->max_memkb = virDomainDefGetMemoryInitial(def); b_info->target_memkb = def->mem.cur_balloon; if (hvm) { char bootorder[VIR_DOMAIN_BOOT_LAST + 1]; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 54bbd3b29e..f4491d0b36 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1075,7 +1075,7 @@ libxlDomainGetMaxMemory(virDomainPtr dom) if (virDomainGetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - ret = vm->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(vm->def); cleanup: if (vm) @@ -1157,7 +1157,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (flags & VIR_DOMAIN_MEM_CONFIG) { /* Help clang 2.8 decipher the logic flow. */ sa_assert(persistentDef); - persistentDef->mem.max_balloon = newmem; + virDomainDefSetMemoryInitial(persistentDef, newmem); if (persistentDef->mem.cur_balloon > newmem) persistentDef->mem.cur_balloon = newmem; ret = virDomainSaveConfig(cfg->configDir, persistentDef); @@ -1167,7 +1167,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, } else { /* resize the current memory */ - if (newmem > vm->def->mem.max_balloon) { + if (newmem > virDomainDefGetMemoryActual(vm->def)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("cannot set memory higher than max memory")); goto endjob; @@ -1241,7 +1241,7 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) if (!virDomainObjIsActive(vm)) { info->cpuTime = 0; info->memory = vm->def->mem.cur_balloon; - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); } else { if (libxl_domain_info(priv->ctx, &d_info, vm->def->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 5a49e2d5a1..c1813e21fe 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -146,7 +146,7 @@ static int virLXCCgroupSetupMemTune(virDomainDefPtr def, { int ret = -1; - if (virCgroupSetMemory(cgroup, def->mem.max_balloon) < 0) + if (virCgroupSetMemory(cgroup, virDomainDefGetMemoryInitial(def)) < 0) goto cleanup; if (virMemoryLimitIsSet(def->mem.hard_limit)) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 6b0dea1628..98fbea848b 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -617,7 +617,7 @@ static int lxcDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); info->nrVirtCpu = vm->def->vcpus; ret = 0; @@ -686,7 +686,7 @@ lxcDomainGetMaxMemory(virDomainPtr dom) if (virDomainGetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - ret = vm->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(vm->def); cleanup: if (vm) @@ -735,7 +735,7 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, } if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - persistentDef->mem.max_balloon = newmem; + virDomainDefSetMemoryInitial(persistentDef, newmem); if (persistentDef->mem.cur_balloon > newmem) persistentDef->mem.cur_balloon = newmem; if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0) @@ -745,10 +745,10 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, unsigned long oldmax = 0; if (flags & VIR_DOMAIN_AFFECT_LIVE) - oldmax = vm->def->mem.max_balloon; + oldmax = virDomainDefGetMemoryActual(vm->def); if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - if (!oldmax || oldmax > persistentDef->mem.max_balloon) - oldmax = persistentDef->mem.max_balloon; + if (!oldmax || oldmax > virDomainDefGetMemoryActual(persistentDef)) + oldmax = virDomainDefGetMemoryActual(persistentDef); } if (newmem > oldmax) { diff --git a/src/lxc/lxc_fuse.c b/src/lxc/lxc_fuse.c index bc2b92c045..34a69cc219 100644 --- a/src/lxc/lxc_fuse.c +++ b/src/lxc/lxc_fuse.c @@ -166,12 +166,12 @@ static int lxcProcReadMeminfo(char *hostpath, virDomainDefPtr def, if (STREQ(line, "MemTotal") && (virMemoryLimitIsSet(def->mem.hard_limit) || - def->mem.max_balloon)) { + virDomainDefGetMemoryActual(def))) { virBufferAsprintf(new_meminfo, "MemTotal: %8llu kB\n", meminfo.memtotal); } else if (STREQ(line, "MemFree") && (virMemoryLimitIsSet(def->mem.hard_limit) || - def->mem.max_balloon)) { + virDomainDefGetMemoryActual(def))) { virBufferAsprintf(new_meminfo, "MemFree: %8llu kB\n", (meminfo.memtotal - meminfo.memusage)); } else if (STREQ(line, "Buffers")) { diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 2ebe6102bf..c15eb19f3d 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -772,7 +772,7 @@ lxcSetMemTune(virDomainDefPtr def, virConfPtr properties) if (lxcConvertSize(value->str, &size) < 0) return -1; size = size / 1024; - def->mem.max_balloon = size; + virDomainDefSetMemoryInitial(def, size); def->mem.hard_limit = virMemoryLimitTruncate(size); } @@ -1012,7 +1012,7 @@ lxcParseConfigString(const char *config) } vmdef->id = -1; - vmdef->mem.max_balloon = 64 * 1024; + virDomainDefSetMemoryInitial(vmdef, 64 * 1024); vmdef->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART; vmdef->onCrash = VIR_DOMAIN_LIFECYCLE_DESTROY; diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index a55e6a658f..71b0471e12 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -458,7 +458,7 @@ static int openvzDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); info->memory = vm->def->mem.cur_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index d2907cfa50..bf29a96f9b 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -534,7 +534,7 @@ parallelsDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) info->state = virDomainObjGetState(privdom, NULL); info->memory = privdom->def->mem.cur_balloon; - info->maxMem = privdom->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(privdom->def); info->nrVirtCpu = privdom->def->vcpus; info->cpuTime = 0; ret = 0; diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 89a9a58c75..0b2478e418 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -1211,9 +1211,9 @@ prlsdkLoadDomain(parallelsConnPtr privconn, /* get RAM parameters */ pret = PrlVmCfg_GetRamSize(sdkdom, &ram); prlsdkCheckRetGoto(pret, error); - def->mem.max_balloon = ram << 10; /* RAM size obtained in Mbytes, - convert to Kbytes */ - def->mem.cur_balloon = def->mem.max_balloon; + virDomainDefSetMemoryInitial(def, ram << 10); /* RAM size obtained in Mbytes, + convert to Kbytes */ + def->mem.cur_balloon = ram << 10; if (prlsdkConvertCpuInfo(sdkdom, def) < 0) goto error; @@ -1767,14 +1767,14 @@ prlsdkCheckUnsupportedParams(PRL_HANDLE sdkdom, virDomainDefPtr def) return -1; } - if (def->mem.max_balloon != def->mem.cur_balloon) { + if (virDomainDefGetMemoryActual(def) != def->mem.cur_balloon) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("changing balloon parameters is not supported " "by parallels driver")); return -1; } - if (def->mem.max_balloon % (1 << 10) != 0) { + if (virDomainDefGetMemoryActual(def) % (1 << 10) != 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Memory size should be multiple of 1Mb.")); return -1; @@ -2873,7 +2873,7 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, prlsdkCheckRetGoto(pret, error); } - pret = PrlVmCfg_SetRamSize(sdkdom, def->mem.max_balloon >> 10); + pret = PrlVmCfg_SetRamSize(sdkdom, virDomainDefGetMemoryActual(def) >> 10); prlsdkCheckRetGoto(pret, error); pret = PrlVmCfg_SetCpuCount(sdkdom, def->vcpus); diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index 28739988c2..60a47ad22a 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -3252,6 +3252,7 @@ phypDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) LIBSSH2_SESSION *session = phyp_driver->session; virDomainDef def; char *managed_system = phyp_driver->managed_system; + unsigned long long memory; /* Flags checked by virDomainDefFormat */ @@ -3273,12 +3274,13 @@ phypDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) goto err; } - if ((def.mem.max_balloon = - phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) { + if ((memory = phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) { VIR_ERROR(_("Unable to determine domain's max memory.")); goto err; } + virDomainDefSetMemoryInitial(&def, memory); + if ((def.mem.cur_balloon = phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) { VIR_ERROR(_("Unable to determine domain's memory.")); @@ -3491,7 +3493,7 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def) goto cleanup; } - if (!def->mem.max_balloon) { + if (!virDomainDefGetMemoryInitial(def)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Field on the domain XML file is missing or " "has invalid value")); @@ -3517,7 +3519,8 @@ phypBuildLpar(virConnectPtr conn, virDomainDefPtr def) virBufferAsprintf(&buf, " -r lpar -p %s -i min_mem=%lld,desired_mem=%lld," "max_mem=%lld,desired_procs=%d,virtual_scsi_adapters=%s", def->name, def->mem.cur_balloon, - def->mem.cur_balloon, def->mem.max_balloon, + def->mem.cur_balloon, + virDomainDefGetMemoryInitial(def), (int) def->vcpus, virDomainDiskGetSource(def->disks[0])); ret = phypExecBuffer(session, &buf, &exit_status, conn, false); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3f0a3065bb..958a5519b5 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8496,8 +8496,9 @@ qemuBuildCommandLine(virConnectPtr conn, * XML to reflect our rounding. */ virCommandAddArg(cmd, "-m"); - def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024; - virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024); + virDomainDefSetMemoryInitial(def, VIR_ROUND_UP(virDomainDefGetMemoryInitial(def), 1024)); + virCommandAddArgFormat(cmd, "%llu", virDomainDefGetMemoryInitial(def) / 1024); + if (def->mem.nhugepages && !virDomainNumaGetNodeCount(def->numa)) { const long system_page_size = virGetSystemPageSizeKB(); char *mem_path = NULL; @@ -10480,8 +10481,11 @@ qemuBuildCommandLine(virConnectPtr conn, * space just to be safe (some finer tuning might be * nice, though). */ - memKB = virMemoryLimitIsSet(def->mem.hard_limit) ? - def->mem.hard_limit : def->mem.max_balloon + 1024 * 1024; + if (virMemoryLimitIsSet(def->mem.hard_limit)) + memKB = def->mem.hard_limit; + else + memKB = virDomainDefGetMemoryActual(def) + 1024 * 1024; + virCommandSetMaxMemLock(cmd, memKB * 1024); } @@ -12045,7 +12049,8 @@ qemuParseCommandLine(virCapsPtr qemuCaps, } def->id = -1; - def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024; + def->mem.cur_balloon = 64 * 1024; + virDomainDefSetMemoryInitial(def, def->mem.cur_balloon); def->maxvcpus = 1; def->vcpus = 1; def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC; @@ -12253,7 +12258,8 @@ qemuParseCommandLine(virCapsPtr qemuCaps, _("cannot parse memory level '%s'"), val); goto error; } - def->mem.cur_balloon = def->mem.max_balloon = mem * 1024; + virDomainDefSetMemoryInitial(def, mem * 1024); + def->mem.cur_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 864ee50a39..7ca993dc6f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2259,7 +2259,7 @@ qemuDomainGetMaxMemory(virDomainPtr dom) if (virDomainGetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - ret = vm->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(vm->def); cleanup: qemuDomObjEndAPI(&vm); @@ -2321,7 +2321,8 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, goto endjob; } - persistentDef->mem.max_balloon = newmem; + virDomainDefSetMemoryInitial(persistentDef, newmem); + if (persistentDef->mem.cur_balloon > newmem) persistentDef->mem.cur_balloon = newmem; ret = virDomainSaveConfig(cfg->configDir, persistentDef); @@ -2333,10 +2334,10 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, unsigned long oldmax = 0; if (flags & VIR_DOMAIN_AFFECT_LIVE) - oldmax = vm->def->mem.max_balloon; + oldmax = virDomainDefGetMemoryActual(vm->def); if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - if (!oldmax || oldmax > persistentDef->mem.max_balloon) - oldmax = persistentDef->mem.max_balloon; + if (!oldmax || oldmax > virDomainDefGetMemoryActual(persistentDef)) + oldmax = virDomainDefGetMemoryActual(persistentDef); } if (newmem > oldmax) { @@ -2598,14 +2599,14 @@ static int qemuDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); 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->mem.max_balloon; + info->memory = virDomainDefGetMemoryActual(vm->def); } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT)) { info->memory = vm->def->mem.cur_balloon; } else if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) { @@ -2631,7 +2632,7 @@ static int qemuDomainGetInfo(virDomainPtr dom, info->memory = vm->def->mem.cur_balloon; } else if (err == 0) { /* Balloon not supported, so maxmem is always the allocation */ - info->memory = vm->def->mem.max_balloon; + info->memory = virDomainDefGetMemoryActual(vm->def); } else { info->memory = balloon; } @@ -18897,7 +18898,7 @@ qemuDomainGetStatsBalloon(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, if (dom->def->memballoon && dom->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE) { - cur_balloon = dom->def->mem.max_balloon; + cur_balloon = virDomainDefGetMemoryActual(dom->def); } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT)) { cur_balloon = dom->def->mem.cur_balloon; } else { @@ -18915,7 +18916,7 @@ qemuDomainGetStatsBalloon(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, &record->nparams, maxparams, "balloon.maximum", - dom->def->mem.max_balloon) < 0) + virDomainDefGetMemoryActual(dom->def)) < 0) return -1; return 0; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6ad48f7848..7845fd1ef1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1250,9 +1250,11 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, * Kibibytes, but virProcessSetMaxMemLock expects the value in * bytes. */ - memKB = virMemoryLimitIsSet(vm->def->mem.hard_limit) - ? vm->def->mem.hard_limit - : vm->def->mem.max_balloon + (1024 * 1024); + if (virMemoryLimitIsSet(vm->def->mem.hard_limit)) + memKB = vm->def->mem.hard_limit; + else + memKB = virDomainDefGetMemoryActual(vm->def) + (1024 * 1024); + virProcessSetMaxMemLock(vm->pid, memKB * 1024); break; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b841e8d135..2b4de310a7 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4568,7 +4568,7 @@ int qemuProcessStart(virConnectPtr conn, */ if (virDomainDefNeedsPlacementAdvice(vm->def)) { nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus, - vm->def->mem.max_balloon); + virDomainDefGetMemoryActual(vm->def)); if (!nodeset) goto cleanup; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 187bd3d744..1c9d573320 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2151,7 +2151,7 @@ static int testDomainGetInfo(virDomainPtr domain, info->state = virDomainObjGetState(privdom, NULL); info->memory = privdom->def->mem.cur_balloon; - info->maxMem = privdom->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(privdom->def); info->nrVirtCpu = privdom->def->vcpus; info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); ret = 0; @@ -2519,7 +2519,7 @@ testDomainGetMaxMemory(virDomainPtr domain) goto cleanup; } - ret = privdom->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(privdom->def); cleanup: if (privdom) @@ -2545,7 +2545,7 @@ static int testDomainSetMaxMemory(virDomainPtr domain, } /* XXX validate not over host memory wrt to other domains */ - privdom->def->mem.max_balloon = memory; + virDomainDefSetMemoryInitial(privdom->def, memory); ret = 0; cleanup: @@ -2571,7 +2571,7 @@ static int testDomainSetMemory(virDomainPtr domain, goto cleanup; } - if (memory > privdom->def->mem.max_balloon) { + if (memory > virDomainDefGetMemoryActual(privdom->def)) { virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto cleanup; } diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 68efd18671..27731f20bc 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1802,7 +1802,7 @@ umlDomainGetMaxMemory(virDomainPtr dom) if (virDomainGetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - ret = vm->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(vm->def); cleanup: if (vm) @@ -1838,7 +1838,7 @@ static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) goto cleanup; } - vm->def->mem.max_balloon = newmax; + virDomainDefSetMemoryInitial(vm->def, newmax); ret = 0; cleanup: @@ -1875,7 +1875,7 @@ static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) goto cleanup; } - if (newmem > vm->def->mem.max_balloon) { + if (newmem > virDomainDefGetMemoryActual(vm->def)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("cannot set memory higher than max memory")); goto cleanup; @@ -1922,7 +1922,7 @@ static int umlDomainGetInfo(virDomainPtr dom, } } - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); info->memory = vm->def->mem.cur_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 7ecefd6c8b..0fb53aae16 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -3894,7 +3894,7 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) * reading and while dumping xml */ /* def->mem.max_balloon = maxMemorySize * 1024; */ - def->mem.max_balloon = memorySize * 1024; + virDomainDefSetMemoryInitial(def, memorySize * 1024); gVBoxAPI.UIMachine.GetCPUCount(machine, &CPUCount); def->maxvcpus = def->vcpus = CPUCount; @@ -6055,7 +6055,7 @@ static char *vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, * the notation here seems to be inconsistent while * reading and while dumping xml */ - def->dom->mem.max_balloon = memorySize * 1024; + virDomainDefSetMemoryInitial(def->dom, memorySize * 1024); if (VIR_STRDUP(def->dom->os.type, "hvm") < 0) goto cleanup; def->dom->os.arch = virArchFromHost(); diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index fb7fa5b2f9..36f992b983 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -1126,7 +1126,7 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) info->state = virDomainObjGetState(vm, NULL); info->cpuTime = 0; - info->maxMem = vm->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(vm->def); info->memory = vm->def->mem.cur_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index fe6b8837b1..8cbf4d84f9 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -1375,7 +1375,7 @@ virVMXParseConfig(virVMXContext *ctx, goto cleanup; } - def->mem.max_balloon = memsize * 1024; /* Scale from megabytes to kilobytes */ + virDomainDefSetMemoryInitial(def, memsize * 1024); /* Scale from megabytes to kilobytes */ /* vmx:sched.mem.max -> def:mem.cur_balloon */ if (virVMXGetConfigLong(conf, "sched.mem.max", &sched_mem_max, memsize, @@ -1388,8 +1388,8 @@ virVMXParseConfig(virVMXContext *ctx, def->mem.cur_balloon = sched_mem_max * 1024; /* Scale from megabytes to kilobytes */ - if (def->mem.cur_balloon > def->mem.max_balloon) - def->mem.cur_balloon = def->mem.max_balloon; + if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def)) + def->mem.cur_balloon = virDomainDefGetMemoryActual(def); /* vmx:sched.mem.minsize -> def:mem.min_guarantee */ if (virVMXGetConfigLong(conf, "sched.mem.minsize", &sched_mem_minsize, 0, @@ -1402,8 +1402,8 @@ virVMXParseConfig(virVMXContext *ctx, def->mem.min_guarantee = sched_mem_minsize * 1024; /* Scale from megabytes to kilobytes */ - if (def->mem.min_guarantee > def->mem.max_balloon) - def->mem.min_guarantee = def->mem.max_balloon; + if (def->mem.min_guarantee > virDomainDefGetMemoryActual(def)) + def->mem.min_guarantee = virDomainDefGetMemoryActual(def); /* vmx:numvcpus -> def:vcpus */ if (virVMXGetConfigLong(conf, "numvcpus", &numvcpus, 1, true) < 0) @@ -3084,7 +3084,7 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDe /* def:mem.max_balloon -> vmx:memsize */ /* max-memory must be a multiple of 4096 kilobyte */ - max_balloon = VIR_DIV_UP(def->mem.max_balloon, 4096) * 4096; + max_balloon = VIR_DIV_UP(virDomainDefGetMemoryActual(def), 4096) * 4096; virBufferAsprintf(&buffer, "memsize = \"%llu\"\n", max_balloon / 1024); /* Scale from kilobytes to megabytes */ diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 354ab3f9de..64752dfa63 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -479,7 +479,7 @@ xenXMDomainGetInfo(virConnectPtr conn, goto error; memset(info, 0, sizeof(virDomainInfo)); - info->maxMem = entry->def->mem.max_balloon; + info->maxMem = virDomainDefGetMemoryActual(entry->def); info->memory = entry->def->mem.cur_balloon; info->nrVirtCpu = entry->def->vcpus; info->state = VIR_DOMAIN_SHUTOFF; @@ -557,8 +557,8 @@ xenXMDomainSetMemory(virConnectPtr conn, goto cleanup; 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 (entry->def->mem.cur_balloon > virDomainDefGetMemoryActual(entry->def)) + entry->def->mem.cur_balloon = virDomainDefGetMemoryActual(entry->def); /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! @@ -600,10 +600,10 @@ xenXMDomainSetMaxMemory(virConnectPtr conn, if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; - 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 (entry->def->mem.cur_balloon > memory) + entry->def->mem.cur_balloon = memory; + virDomainDefSetMemoryInitial(entry->def, memory); /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ @@ -636,7 +636,7 @@ xenXMDomainGetMaxMemory(virConnectPtr conn, if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; - ret = entry->def->mem.max_balloon; + ret = virDomainDefGetMemoryActual(entry->def); cleanup: xenUnifiedUnlock(priv); diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 8eb8d73ea1..affc153bb7 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1492,7 +1492,7 @@ xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) VIR_FREE(val); } memory = xenapiDomainGetMaxMemory(dom); - defPtr->mem.max_balloon = memory; + virDomainDefSetMemoryInitial(defPtr, memory); if (xen_vm_get_memory_dynamic_max(session, &dynamic_mem, vm)) { defPtr->mem.cur_balloon = (unsigned long) (dynamic_mem / 1024); } else { diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c index 21511e84f4..ce952608a1 100644 --- a/src/xenapi/xenapi_utils.c +++ b/src/xenapi/xenapi_utils.c @@ -499,8 +499,8 @@ createVMRecordFromXml(virConnectPtr conn, virDomainDefPtr def, 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); + if (virDomainDefGetMemoryActual(def)) + (*record)->memory_dynamic_max = (int64_t) (virDomainDefGetMemoryActual(def) * 1024); else (*record)->memory_dynamic_max = (*record)->memory_static_max; diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c index 079f77db5b..5f8eb71fef 100644 --- a/src/xenconfig/xen_common.c +++ b/src/xenconfig/xen_common.c @@ -305,16 +305,18 @@ xenConfigSetString(virConfPtr conf, const char *setting, const char *str) static int xenParseMem(virConfPtr conf, virDomainDefPtr def) { + unsigned long long memory; + if (xenConfigGetULongLong(conf, "memory", &def->mem.cur_balloon, MIN_XEN_GUEST_SIZE * 2) < 0) return -1; - if (xenConfigGetULongLong(conf, "maxmem", &def->mem.max_balloon, + if (xenConfigGetULongLong(conf, "maxmem", &memory, def->mem.cur_balloon) < 0) return -1; def->mem.cur_balloon *= 1024; - def->mem.max_balloon *= 1024; + virDomainDefSetMemoryInitial(def, memory * 1024); return 0; } @@ -1383,7 +1385,7 @@ static int xenFormatMem(virConfPtr conf, virDomainDefPtr def) { if (xenConfigSetInt(conf, "maxmem", - VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0) + VIR_DIV_UP(virDomainDefGetMemoryActual(def), 1024)) < 0) return -1; if (xenConfigSetInt(conf, "memory", diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c index 3e18a7e0c2..5a170d3f6b 100644 --- a/src/xenconfig/xen_sxpr.c +++ b/src/xenconfig/xen_sxpr.c @@ -1155,10 +1155,11 @@ xenParseSxpr(const struct sexpr *root, } } - def->mem.max_balloon = (sexpr_u64(root, "domain/maxmem") << 10); + virDomainDefSetMemoryInitial(def, (sexpr_u64(root, "domain/maxmem") << 10)); def->mem.cur_balloon = (sexpr_u64(root, "domain/memory") << 10); - if (def->mem.cur_balloon > def->mem.max_balloon) - def->mem.cur_balloon = def->mem.max_balloon; + + if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def)) + def->mem.cur_balloon = virDomainDefGetMemoryActual(def); if (cpus != NULL) { if (virBitmapParse(cpus, 0, &def->cpumask, @@ -2213,7 +2214,7 @@ xenFormatSxpr(virConnectPtr conn, virBufferEscapeSexpr(&buf, "(name '%s')", def->name); virBufferAsprintf(&buf, "(memory %llu)(maxmem %llu)", VIR_DIV_UP(def->mem.cur_balloon, 1024), - VIR_DIV_UP(def->mem.max_balloon, 1024)); + VIR_DIV_UP(virDomainDefGetMemoryActual(def), 1024)); virBufferAsprintf(&buf, "(vcpus %u)", def->maxvcpus); /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is either 32, or 64 on a platform where long is big enough. */