parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE)
numaMemory = virDomainNumaGetMemorySize(def->numa);
+ /* calculate the sizes of hotplug memory */
+ for (i = 0; i < def->nmems; i++)
+ hotplugMemory += def->mems[i]->size;
+
if (numaMemory) {
- virDomainDefSetMemoryInitial(def, numaMemory);
+ /* update the sizes in XML if nothing was set in the XML or ABI update
+ * is supported*/
+ virDomainDefSetMemoryTotal(def, numaMemory + hotplugMemory);
} else {
- /* calculate the sizes of hotplug memory */
- for (i = 0; i < def->nmems; i++)
- hotplugMemory += def->mems[i]->size;
-
+ /* verify that the sum of memory modules doesn't exceed the total
+ * memory. This is necessary for virDomainDefGetMemoryInitial to work
+ * properly. */
if (hotplugMemory > def->mem.total_memory) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Total size of memory devices exceeds the total "
"memory size"));
return -1;
}
-
- virDomainDefSetMemoryInitial(def, def->mem.total_memory - hotplugMemory);
}
if (virDomainDefGetMemoryInitial(def) == 0) {
* @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 <memory> element
- * or the sum of memory sizes of NUMA nodes in case NUMA is enabled in @def.
+ * is the memory size excluding possible memory modules.
*/
unsigned long long
virDomainDefGetMemoryInitial(const virDomainDef *def)
{
- return def->mem.initial_memory;
+ size_t i;
+ unsigned long long ret = def->mem.total_memory;
+
+ for (i = 0; i < def->nmems; i++)
+ ret -= def->mems[i]->size;
+
+ return ret;
}
* @def: domain definition
* @size: size to set
*
- * Sets the total memory size in @def. This function should be used only by
- * hypervisors that don't support memory hotplug.
+ * Sets the total memory size in @def. This value needs to include possible
+ * additional memory modules.
*/
void
virDomainDefSetMemoryTotal(virDomainDefPtr def,
unsigned long long size)
{
def->mem.total_memory = size;
- def->mem.initial_memory = size;
-}
-
-
-/**
- * virDomainDefSetMemoryInitial:
- * @def: domain definition
- * @size: size to set
- *
- * Sets the initial memory size (without memory modules) in @def.
- */
-void
-virDomainDefSetMemoryInitial(virDomainDefPtr def,
- unsigned long long size)
-{
- def->mem.initial_memory = size;
}
* @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.
+ * @def. This size includes possible additional memory devices.
*/
unsigned long long
virDomainDefGetMemoryActual(virDomainDefPtr def)
{
- unsigned long long ret;
- size_t i;
-
- ret = def->mem.initial_memory;
-
- for (i = 0; i < def->nmems; i++)
- ret += def->mems[i]->size;
-
- return ret;
+ return def->mem.total_memory;
}
}
+/**
+ * virDomainMemoryInsert:
+ *
+ * Inserts a memory device definition into the domain definition. This helper
+ * should be used only in hot/cold-plug cases as it's blindly modifying the
+ * total memory size.
+ */
int
virDomainMemoryInsert(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
{
+ unsigned long long memory = virDomainDefGetMemoryActual(def);
int id = def->nmems;
if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
return -1;
}
- if (VIR_APPEND_ELEMENT(def->mems, def->nmems, mem) < 0)
+ if (VIR_APPEND_ELEMENT_COPY(def->mems, def->nmems, mem) < 0)
return -1;
+ virDomainDefSetMemoryTotal(def, memory + mem->size);
+
return id;
}
+/**
+ * virDomainMemoryRemove:
+ *
+ * Removes a memory device definition from the domain definition. This helper
+ * should be used only in hot/cold-plug cases as it's blindly modifying the
+ * total memory size.
+ */
virDomainMemoryDefPtr
virDomainMemoryRemove(virDomainDefPtr def,
int idx)
{
+ unsigned long long memory = virDomainDefGetMemoryActual(def);
virDomainMemoryDefPtr ret = def->mems[idx];
+
VIR_DELETE_ELEMENT(def->mems, idx, def->nmems);
/* fix up balloon size */
if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def))
def->mem.cur_balloon = virDomainDefGetMemoryActual(def);
+ /* fix total memory size of the domain */
+ virDomainDefSetMemoryTotal(def, memory - ret->size);
+
return ret;
}
unsigned long long maxmemkb = virMemoryMaxValue(false) >> 10;
unsigned long long maxmemcapped = virMemoryMaxValue(true) >> 10;
unsigned long long initialmem = 0;
+ unsigned long long hotplugmem = 0;
unsigned long long mem;
unsigned long long align = qemuDomainGetMemorySizeAlignment(def);
size_t ncells = virDomainNumaGetNodeCount(def->numa);
return -1;
}
- virDomainDefSetMemoryInitial(def, initialmem);
-
def->mem.max_memory = VIR_ROUND_UP(def->mem.max_memory, align);
if (def->mem.max_memory > maxmemkb) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
for (i = 0; i < def->nmems; i++) {
align = qemuDomainGetMemoryModuleSizeAlignment(def, def->mems[i]);
def->mems[i]->size = VIR_ROUND_UP(def->mems[i]->size, align);
+ hotplugmem += def->mems[i]->size;
if (def->mems[i]->size > maxmemkb) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
}
}
+ virDomainDefSetMemoryTotal(def, initialmem + hotplugmem);
+
return 0;
}