mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
esx: Add support for memtune/min_guarantee
Also add a test case for the VMX handling of it.
This commit is contained in:
parent
38eec464f8
commit
809926db8f
@ -4149,6 +4149,135 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
|
||||
|
||||
|
||||
|
||||
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",
|
||||
@ -4251,8 +4380,8 @@ static virDriver esxDriver = {
|
||||
esxDomainRevertToSnapshot, /* domainRevertToSnapshot */
|
||||
esxDomainSnapshotDelete, /* domainSnapshotDelete */
|
||||
NULL, /* qemuDomainMonitorCommand */
|
||||
NULL, /* domainSetMemoryParameters */
|
||||
NULL, /* domainGetMemoryParameters */
|
||||
esxDomainSetMemoryParameters, /* domainSetMemoryParameters */
|
||||
esxDomainGetMemoryParameters, /* domainGetMemoryParameters */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1840,6 +1840,37 @@ esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
|
||||
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
|
||||
|
@ -302,6 +302,9 @@ int esxVI_GetBoolean(esxVI_ObjectContent *objectContent,
|
||||
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);
|
||||
|
@ -1235,6 +1235,11 @@ ESX_VI__TEMPLATE__VALIDATE(Long,
|
||||
/* 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,
|
||||
{
|
||||
|
@ -227,6 +227,7 @@ int esxVI_Long_Alloc(esxVI_Long **number);
|
||||
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,
|
||||
|
@ -50,6 +50,7 @@ def->uuid = <value> <=> uuid.bios = "<value>"
|
||||
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>"
|
||||
|
||||
@ -874,7 +875,8 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
|
||||
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;
|
||||
@ -1047,22 +1049,38 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
|
||||
|
||||
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;
|
||||
@ -2594,12 +2612,12 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
|
||||
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;
|
||||
}
|
||||
@ -2609,6 +2627,21 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
|
||||
(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",
|
||||
|
@ -52,7 +52,7 @@ snapshot.action = "keep"
|
||||
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 = "--------------------------------"
|
||||
|
@ -4,6 +4,9 @@
|
||||
<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>
|
||||
|
26
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-5.vmx
Normal file
26
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-5.vmx
Normal file
@ -0,0 +1,26 @@
|
||||
.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"
|
37
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-5.xml
Normal file
37
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-5.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<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>
|
@ -269,6 +269,7 @@ mymain(int argc, char **argv)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user