Also add a test case for the VMX handling of it.
+static int
+esxDomainSetMemoryParameters(virDomainPtr domain, virMemoryParameterPtr params,
+ int nparams, unsigned int flags)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_VirtualMachineConfigSpec *spec = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+ int i;
+
+ virCheckFlags(0, -1);
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
+ priv->autoAnswer) < 0 ||
+ esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
+ esxVI_ResourceAllocationInfo_Alloc(&spec->memoryAllocation) < 0) {
+ goto cleanup;
+ }
+
+ for (i = 0; i < nparams; ++i) {
+ if (STREQ (params[i].field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE) &&
+ params[i].type == VIR_DOMAIN_SCHED_FIELD_ULLONG) {
+ if (esxVI_Long_Alloc(&spec->memoryAllocation->reservation) < 0) {
+ goto cleanup;
+ }
+
+ spec->memoryAllocation->reservation->value =
+ params[i].value.ul / 1024; /* Scale from kilobytes to megabytes */
+ } else {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, _("Unknown field '%s'"),
+ params[i].field);
+ goto cleanup;
+ }
+ }
+
+ if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec,
+ &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
+ esxVI_Occurrence_RequiredItem,
+ priv->autoAnswer, &taskInfoState) < 0) {
+ goto cleanup;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not change memory parameters"));
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_VirtualMachineConfigSpec_Free(&spec);
+ esxVI_ManagedObjectReference_Free(&task);
+
+ return result;
+}
+
+
+
+static int
+esxDomainGetMemoryParameters(virDomainPtr domain, virMemoryParameterPtr params,
+ int *nparams, unsigned int flags)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_Long *reservation = NULL;
+
+ virCheckFlags(0, -1);
+
+ if (*nparams == 0) {
+ *nparams = 1; /* min_guarantee */
+ return 0;
+ }
+
+ if (*nparams < 1) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
+ _("Parameter array must have space for 1 item"));
+ return -1;
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueToList
+ (&propertyNameList, "config.memoryAllocation.reservation") < 0 ||
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+ propertyNameList, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_GetLong(virtualMachine, "config.memoryAllocation.reservation",
+ &reservation, esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ if (virStrcpyStatic(params[0].field,
+ VIR_DOMAIN_MEMORY_MIN_GUARANTEE) == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Field %s too big for destination"),
+ VIR_DOMAIN_MEMORY_MIN_GUARANTEE);
+ goto cleanup;
+ }
+
+ params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
+ params[0].value.ul = reservation->value * 1024; /* Scale from megabytes to kilobytes */
+
+ *nparams = 1;
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_Long_Free(&reservation);
+
+ return result;
+}
+
+
+
static virDriver esxDriver = {
VIR_DRV_ESX,
"ESX",
esxDomainRevertToSnapshot, /* domainRevertToSnapshot */
esxDomainSnapshotDelete, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
- NULL, /* domainSetMemoryParameters */
- NULL, /* domainGetMemoryParameters */
+ esxDomainSetMemoryParameters, /* domainSetMemoryParameters */
+ esxDomainGetMemoryParameters, /* domainGetMemoryParameters */
};
return 0;
}
+int
+esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
+ esxVI_Long **value, esxVI_Occurrence occurence)
+{
+ esxVI_DynamicProperty *dynamicProperty;
+
+ if (value == NULL || *value != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ for (dynamicProperty = objectContent->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, propertyName)) {
+ if (esxVI_Long_CastFromAnyType(dynamicProperty->val, value) < 0) {
+ return -1;
+ }
+
+ break;
+ }
+ }
+
+ if (*value == NULL && occurence == esxVI_Occurrence_RequiredItem) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Missing '%s' property"), propertyName);
+ return -1;
+ }
+
+ return 0;
+}
+
int
const char *propertyName,
esxVI_Boolean *value, esxVI_Occurrence occurence);
+int esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
+ esxVI_Long **value, esxVI_Occurrence occurence);
+
int esxVI_GetStringValue(esxVI_ObjectContent *objectContent,
const char *propertyName,
char **value, esxVI_Occurrence occurence);
/* esxVI_Long_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(Long)
+/* esxVI_Long_CastFromAnyType */
+ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(Long,
+{
+})
+
/* esxVI_Long_Serialize */
ESX_VI__TEMPLATE__SERIALIZE(Long,
{
void esxVI_Long_Free(esxVI_Long **numberList);
int esxVI_Long_Validate(esxVI_Long *number);
int esxVI_Long_AppendToList(esxVI_Long **numberList, esxVI_Long *number);
+int esxVI_Long_CastFromAnyType(esxVI_AnyType *anyType, esxVI_Long **number);
int esxVI_Long_Serialize(esxVI_Long *number, const char *element,
virBufferPtr output);
int esxVI_Long_SerializeList(esxVI_Long *numberList, const char *element,
def->name = <value> <=> displayName = "<value>"
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->mem.min_guarantee = <value kilobyte> <=> sched.mem.minsize = "<value megabyte>" # defaults to 0
def->maxvcpus = <value> <=> numvcpus = "<value>" # must be 1 or a multiple of 2, defaults to 1
def->cpumask = <uint list> <=> sched.cpu.affinity = "<uint list>"
long long config_version = 0;
long long virtualHW_version = 0;
long long memsize = 0;
- long long memory = 0;
+ long long sched_mem_max = 0;
+ long long sched_mem_minsize = 0;
long long numvcpus = 0;
char *sched_cpu_affinity = NULL;
char *guestOS = NULL;
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,
+ /* vmx:sched.mem.max -> def:mem.cur_balloon */
+ if (esxUtil_GetConfigLong(conf, "sched.mem.max", &sched_mem_max, memsize,
true) < 0) {
goto cleanup;
}
- if (memory < 0) {
- memory = memsize;
+ if (sched_mem_max < 0) {
+ sched_mem_max = memsize;
}
- def->mem.cur_balloon = memory * 1024; /* Scale from megabytes to kilobytes */
+ 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;
}
+ /* vmx:sched.mem.minsize -> def:mem.min_guarantee */
+ if (esxUtil_GetConfigLong(conf, "sched.mem.minsize", &sched_mem_minsize, 0,
+ true) < 0) {
+ goto cleanup;
+ }
+
+ if (sched_mem_minsize < 0) {
+ sched_mem_minsize = 0;
+ }
+
+ 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;
+ }
+
/* vmx:numvcpus -> def:vcpus */
if (esxUtil_GetConfigLong(conf, "numvcpus", &numvcpus, 1, true) < 0) {
goto cleanup;
virBufferVSprintf(&buffer, "memsize = \"%d\"\n",
(int)(def->mem.max_balloon / 1024));
- /* def:memory -> vmx:sched.mem.max */
+ /* def:mem.cur_balloon -> vmx:sched.mem.max */
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 integer (multiple of 1024) but found %llu"),
(unsigned long long)def->mem.cur_balloon);
goto cleanup;
}
(int)(def->mem.cur_balloon / 1024));
}
+ /* def:mem.min_guarantee -> vmx:sched.mem.minsize */
+ if (def->mem.min_guarantee > 0) {
+ if (def->mem.min_guarantee % 1024 != 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Expecting domain XML entry 'memtune/min_guarantee' to "
+ "be an unsigned integer (multiple of 1024) but found %llu"),
+ (unsigned long long)def->mem.min_guarantee);
+ goto cleanup;
+ }
+
+ /* Scale from kilobytes to megabytes */
+ virBufferVSprintf(&buffer, "sched.mem.minsize = \"%d\"\n",
+ (int)(def->mem.min_guarantee / 1024));
+ }
+
/* def:maxvcpus -> vmx:numvcpus */
if (def->vcpus != def->maxvcpus) {
ESX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
sched.cpu.min = "0"
sched.cpu.units = "mhz"
sched.cpu.shares = "normal"
-sched.mem.minsize = "0"
+sched.mem.minsize = "256"
sched.mem.shares = "normal"
tools.upgrade.policy = "manual"
cpuid.80000001.eax = "--------------------------------"
<description>Centos 5.5 64bit Server</description>
<memory>2097152</memory>
<currentMemory>2097152</currentMemory>
+ <memtune>
+ <min_guarantee>262144</min_guarantee>
+ </memtune>
<vcpu>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
--- /dev/null
+.encoding = "UTF-8"
+config.version = "8"
+virtualHW.version = "4"
+guestOS = "other-64"
+uuid.bios = "42 3e 94 a9 a1 c7 b3 1d-71 61 76 c7 58 6c 83 0e"
+displayName = "vmtest.local"
+annotation = "Centos 5.5 64bit Server"
+memsize = "2048"
+sched.mem.minsize = "256"
+numvcpus = "2"
+scsi0.present = "true"
+scsi0.virtualDev = "lsilogic"
+scsi0:0.present = "true"
+scsi0:0.deviceType = "scsi-hardDisk"
+scsi0:0.fileName = "/vmfs/volumes/datastore/directory/vmtest-000001.vmdk"
+ide0:0.present = "true"
+ide0:0.deviceType = "cdrom-image"
+ide0:0.fileName = "/vmfs/volumes/4af0231d-1eff559a-6369-0024e84773b6/isos/CentOS-5.5-x86_64-bin-DVD-1of2.iso"
+floppy0.present = "false"
+floppy1.present = "false"
+ethernet0.present = "true"
+ethernet0.virtualDev = "e1000"
+ethernet0.networkName = "VM-LAN"
+ethernet0.connectionType = "bridged"
+ethernet0.addressType = "vpx"
+ethernet0.generatedAddress = "00:50:56:BE:00:15"
--- /dev/null
+<domain type='vmware'>
+ <name>vmtest.local</name>
+ <uuid>423e94a9-a1c7-b31d-7161-76c7586c830e</uuid>
+ <description>Centos 5.5 64bit Server</description>
+ <memory>2097152</memory>
+ <currentMemory>2097152</currentMemory>
+ <memtune>
+ <min_guarantee>262144</min_guarantee>
+ </memtune>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <source file='[datastore] directory/vmtest-000001.vmdk'/>
+ <target dev='sda' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <source file='[4af0231d-1eff559a-6369-0024e84773b6] isos/CentOS-5.5-x86_64-bin-DVD-1of2.iso'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='scsi' index='0' model='lsilogic'/>
+ <controller type='ide' index='0'/>
+ <interface type='bridge'>
+ <mac address='00:50:56:be:00:15'/>
+ <source bridge='VM-LAN'/>
+ <model type='e1000'/>
+ </interface>
+ </devices>
+</domain>
DO_TEST("esx-in-the-wild-2", "esx-in-the-wild-2", esxVI_ProductVersion_ESX35);
DO_TEST("esx-in-the-wild-3", "esx-in-the-wild-3", esxVI_ProductVersion_ESX35);
DO_TEST("esx-in-the-wild-4", "esx-in-the-wild-4", esxVI_ProductVersion_ESX35);
+ DO_TEST("esx-in-the-wild-5", "esx-in-the-wild-5", esxVI_ProductVersion_ESX35);
DO_TEST("gsx-in-the-wild-1", "gsx-in-the-wild-1", esxVI_ProductVersion_ESX35);
DO_TEST("gsx-in-the-wild-2", "gsx-in-the-wild-2", esxVI_ProductVersion_ESX35);