From 3d4f6eeeae2b4c51560402ea8ec42e174b6f45b6 Mon Sep 17 00:00:00 2001 From: Matthias Bolte Date: Thu, 30 Dec 2010 01:36:31 +0100 Subject: [PATCH] esx: Add domain autostart support --- src/esx/esx_driver.c | 183 ++++++++++++++++++++++++++++++++- src/esx/esx_vi.c | 126 ++++++++++++++++++++++- src/esx/esx_vi.h | 6 ++ src/esx/esx_vi_generator.input | 60 +++++++++++ src/esx/esx_vi_generator.py | 5 +- src/esx/esx_vi_types.c | 6 ++ src/esx/esx_vi_types.h | 1 + 7 files changed, 382 insertions(+), 5 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 2241532d5e..67325de009 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -3199,6 +3199,185 @@ esxDomainUndefine(virDomainPtr domain) +static int +esxDomainGetAutostart(virDomainPtr domain, int *autostart) +{ + int result = -1; + esxPrivate *priv = domain->conn->privateData; + esxVI_AutoStartDefaults *defaults = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostAutoStartManager = NULL; + esxVI_AutoStartPowerInfo *powerInfo = NULL; + esxVI_AutoStartPowerInfo *powerInfoList = NULL; + esxVI_ObjectContent *virtualMachine = NULL; + + *autostart = 0; + + if (esxVI_EnsureSession(priv->primary) < 0) { + return -1; + } + + /* Check general autostart config */ + if (esxVI_LookupAutoStartDefaults(priv->primary, &defaults) < 0) { + goto cleanup; + } + + if (defaults->enabled != esxVI_Boolean_True) { + /* Autostart is disabled in general, exit early here */ + result = 0; + goto cleanup; + } + + /* Check specific autostart config */ + if (esxVI_LookupAutoStartPowerInfoList(priv->primary, &powerInfoList) < 0) { + goto cleanup; + } + + if (powerInfoList == NULL) { + /* powerInfo list is empty, exit early here */ + result = 0; + goto cleanup; + } + + if (esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, + NULL, &virtualMachine, + esxVI_Occurrence_RequiredItem) < 0) { + goto cleanup; + } + + for (powerInfo = powerInfoList; powerInfo != NULL; + powerInfo = powerInfo->_next) { + if (STREQ(powerInfo->key->value, virtualMachine->obj->value)) { + if (STRCASEEQ(powerInfo->startAction, "powerOn")) { + *autostart = 1; + } + + break; + } + } + + result = 0; + + cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostAutoStartManager); + esxVI_AutoStartDefaults_Free(&defaults); + esxVI_AutoStartPowerInfo_Free(&powerInfoList); + esxVI_ObjectContent_Free(&virtualMachine); + + return result; +} + + + +static int +esxDomainSetAutostart(virDomainPtr domain, int autostart) +{ + int result = -1; + esxPrivate *priv = domain->conn->privateData; + esxVI_ObjectContent *virtualMachine = NULL; + esxVI_HostAutoStartManagerConfig *spec = NULL; + esxVI_AutoStartDefaults *defaults = NULL; + esxVI_AutoStartPowerInfo *powerInfoList = NULL; + esxVI_AutoStartPowerInfo *powerInfo = NULL; + esxVI_AutoStartPowerInfo *newPowerInfo = NULL; + + if (esxVI_EnsureSession(priv->primary) < 0) { + return -1; + } + + if (esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, + NULL, &virtualMachine, + esxVI_Occurrence_RequiredItem) < 0 || + esxVI_HostAutoStartManagerConfig_Alloc(&spec) < 0) { + goto cleanup; + } + + if (autostart) { + /* + * There is a general autostart option that affects the autostart + * behavior of all domains. If it's disabled then no domain does + * autostart. If it's enabled then the autostart behavior depends on + * the per-domain autostart config. + */ + if (esxVI_LookupAutoStartDefaults(priv->primary, &defaults) < 0) { + goto cleanup; + } + + if (defaults->enabled != esxVI_Boolean_True) { + /* + * Autostart is disabled in general. Check if no other domain is + * in the list of autostarted domains, so it's safe to enable the + * general autostart option without affecting the autostart + * behavior of other domains. + */ + if (esxVI_LookupAutoStartPowerInfoList(priv->primary, + &powerInfoList) < 0) { + goto cleanup; + } + + for (powerInfo = powerInfoList; powerInfo != NULL; + powerInfo = powerInfo->_next) { + if (STRNEQ(powerInfo->key->value, virtualMachine->obj->value)) { + ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s", + _("Cannot enable general autostart option " + "without affecting other domains")); + goto cleanup; + } + } + + /* Enable autostart in general */ + if (esxVI_AutoStartDefaults_Alloc(&spec->defaults) < 0) { + goto cleanup; + } + + spec->defaults->enabled = esxVI_Boolean_True; + } + } + + if (esxVI_AutoStartPowerInfo_Alloc(&newPowerInfo) < 0 || + esxVI_Int_Alloc(&newPowerInfo->startOrder) < 0 || + esxVI_Int_Alloc(&newPowerInfo->startDelay) < 0 || + esxVI_Int_Alloc(&newPowerInfo->stopDelay) < 0 || + esxVI_AutoStartPowerInfo_AppendToList(&spec->powerInfo, + newPowerInfo) < 0) { + goto cleanup; + } + + newPowerInfo->key = virtualMachine->obj; + newPowerInfo->startOrder->value = -1; /* no specific start order */ + newPowerInfo->startDelay->value = -1; /* use system default */ + newPowerInfo->waitForHeartbeat = esxVI_AutoStartWaitHeartbeatSetting_SystemDefault; + newPowerInfo->startAction = autostart ? (char *)"powerOn" : (char *)"none"; + newPowerInfo->stopDelay->value = -1; /* use system default */ + newPowerInfo->stopAction = (char *)"none"; + + if (esxVI_ReconfigureAutostart + (priv->primary, + priv->primary->hostSystem->configManager->autoStartManager, + spec) < 0) { + goto cleanup; + } + + result = 0; + + cleanup: + if (newPowerInfo != NULL) { + newPowerInfo->key = NULL; + newPowerInfo->startAction = NULL; + newPowerInfo->stopAction = NULL; + } + + esxVI_ObjectContent_Free(&virtualMachine); + esxVI_HostAutoStartManagerConfig_Free(&spec); + esxVI_AutoStartDefaults_Free(&defaults); + esxVI_AutoStartPowerInfo_Free(&powerInfoList); + + return result; +} + + + /* * The scheduler interface exposes basically the CPU ResourceAllocationInfo: * @@ -4406,8 +4585,8 @@ static virDriver esxDriver = { NULL, /* domainDetachDevice */ NULL, /* domainDetachDeviceFlags */ NULL, /* domainUpdateDeviceFlags */ - NULL, /* domainGetAutostart */ - NULL, /* domainSetAutostart */ + esxDomainGetAutostart, /* domainGetAutostart */ + esxDomainSetAutostart, /* domainSetAutostart */ esxDomainGetSchedulerType, /* domainGetSchedulerType */ esxDomainGetSchedulerParameters, /* domainGetSchedulerParameters */ esxDomainSetSchedulerParameters, /* domainSetSchedulerParameters */ diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 5dbf744cbe..62b28a23c4 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -606,7 +606,8 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx, esxVI_String_Free(&propertyNameList); if (esxVI_String_AppendValueListToList(&propertyNameList, - "name\0") < 0 || + "name\0" + "configManager\0") < 0 || esxVI_LookupObjectContentByType(ctx, ctx->computeResource->_reference, "HostSystem", propertyNameList, &hostSystemList) < 0) { @@ -680,7 +681,8 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx, /* Lookup HostSystem */ if (esxVI_String_AppendValueListToList(&propertyNameList, - "name\0") < 0 || + "name\0" + "configManager\0") < 0 || esxVI_FindByIp(ctx, NULL, hostSystemIpAddress, esxVI_Boolean_False, &managedObjectReference) < 0 || esxVI_LookupObjectContentByType(ctx, managedObjectReference, @@ -3374,6 +3376,126 @@ esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx, +int +esxVI_LookupAutoStartDefaults(esxVI_Context *ctx, + esxVI_AutoStartDefaults **defaults) +{ + int result = -1; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostAutoStartManager = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + + if (defaults == NULL || *defaults != NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); + return -1; + } + + /* + * Lookup HostAutoStartManagerConfig from the HostAutoStartManager because + * for some reason this is much faster than looking up the same info from + * the HostSystem config. + */ + if (esxVI_String_AppendValueToList(&propertyNameList, + "config.defaults") < 0 || + esxVI_LookupObjectContentByType + (ctx, ctx->hostSystem->configManager->autoStartManager, + "HostAutoStartManager", propertyNameList, + &hostAutoStartManager) < 0) { + goto cleanup; + } + + if (hostAutoStartManager == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the HostAutoStartManager object")); + goto cleanup; + } + + for (dynamicProperty = hostAutoStartManager->propSet; + dynamicProperty != NULL; dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "config.defaults")) { + if (esxVI_AutoStartDefaults_CastFromAnyType(dynamicProperty->val, + defaults) < 0) { + goto cleanup; + } + + break; + } + } + + if (*defaults == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the AutoStartDefaults object")); + goto cleanup; + } + + result = 0; + + cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostAutoStartManager); + + return result; +} + + + +int +esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx, + esxVI_AutoStartPowerInfo **powerInfoList) +{ + int result = -1; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostAutoStartManager = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + + if (powerInfoList == NULL || *powerInfoList != NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); + return -1; + } + + /* + * Lookup HostAutoStartManagerConfig from the HostAutoStartManager because + * for some reason this is much faster than looking up the same info from + * the HostSystem config. + */ + if (esxVI_String_AppendValueToList(&propertyNameList, + "config.powerInfo") < 0 || + esxVI_LookupObjectContentByType + (ctx, ctx->hostSystem->configManager->autoStartManager, + "HostAutoStartManager", propertyNameList, + &hostAutoStartManager) < 0) { + goto cleanup; + } + + if (hostAutoStartManager == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the HostAutoStartManager object")); + goto cleanup; + } + + for (dynamicProperty = hostAutoStartManager->propSet; + dynamicProperty != NULL; dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "config.powerInfo")) { + if (esxVI_AutoStartPowerInfo_CastListFromAnyType + (dynamicProperty->val, powerInfoList) < 0) { + goto cleanup; + } + + break; + } + } + + result = 0; + + cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostAutoStartManager); + + return result; +} + + + int esxVI_HandleVirtualMachineQuestion (esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine, diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 553967b51a..b071c6c8a1 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -418,6 +418,12 @@ int esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx, const char *datastorePath, char **key); +int esxVI_LookupAutoStartDefaults(esxVI_Context *ctx, + esxVI_AutoStartDefaults **defaults); + +int esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx, + esxVI_AutoStartPowerInfo **powerInfoList); + int esxVI_HandleVirtualMachineQuestion (esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine, diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input index 2d903e4f05..44d1d9bec5 100644 --- a/src/esx/esx_vi_generator.input +++ b/src/esx/esx_vi_generator.input @@ -51,6 +51,13 @@ # Enumerations # +enum AutoStartWaitHeartbeatSetting + yes + no + systemDefault +end + + enum ManagedEntityStatus gray green @@ -140,6 +147,26 @@ object AboutInfo end +object AutoStartDefaults + Boolean enabled o + Int startDelay o + Int stopDelay o + Boolean waitForHeartbeat o + String stopAction o +end + + +object AutoStartPowerInfo + ManagedObjectReference key r + Int startOrder r + Int startDelay r + AutoStartWaitHeartbeatSetting waitForHeartbeat r + String startAction r + Int stopDelay r + String stopAction r +end + + object ChoiceOption extends OptionType ElementDescription choiceInfo rl Int defaultIndex o @@ -234,6 +261,33 @@ object FolderFileQuery extends FileQuery end +object HostAutoStartManagerConfig + AutoStartDefaults defaults o + AutoStartPowerInfo powerInfo ol +end + + +object HostConfigManager + ManagedObjectReference cpuScheduler o + ManagedObjectReference datastoreSystem o + ManagedObjectReference memoryManager o + ManagedObjectReference storageSystem o + ManagedObjectReference networkSystem o + ManagedObjectReference vmotionSystem o + ManagedObjectReference serviceSystem o + ManagedObjectReference firewallSystem o + ManagedObjectReference advancedOption o + ManagedObjectReference diagnosticSystem o + ManagedObjectReference autoStartManager o + ManagedObjectReference snmpSystem o + ManagedObjectReference dateTimeSystem o + ManagedObjectReference patchManager o + ManagedObjectReference bootDeviceSystem o + ManagedObjectReference firmwareSystem o + ManagedObjectReference healthStatusSystem o +end + + object HostCpuIdInfo Int level r String vendor o @@ -843,6 +897,12 @@ method ReconfigVM_Task returns ManagedObjectReference r end +method ReconfigureAutostart + ManagedObjectReference _this r + HostAutoStartManagerConfig spec r +end + + method RefreshDatastore ManagedObjectReference _this r end diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py index 4a8a9dc72e..3d068f3959 100755 --- a/src/esx/esx_vi_generator.py +++ b/src/esx/esx_vi_generator.py @@ -1148,11 +1148,14 @@ additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE "VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE } -additional_object_features = { "DatastoreHostMount" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE, +additional_object_features = { "AutoStartDefaults" : Object.FEATURE__ANY_TYPE, + "AutoStartPowerInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST, + "DatastoreHostMount" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE, "DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST, "Event" : Object.FEATURE__LIST, "FileInfo" : Object.FEATURE__DYNAMIC_CAST, "FileQuery" : Object.FEATURE__DYNAMIC_CAST, + "HostConfigManager" : Object.FEATURE__ANY_TYPE, "HostCpuIdInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST, "HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE, "ManagedObjectReference" : Object.FEATURE__ANY_TYPE, diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c index a70e1e05a1..4ee4110d57 100644 --- a/src/esx/esx_vi_types.c +++ b/src/esx/esx_vi_types.c @@ -1815,6 +1815,7 @@ ESX_VI__TEMPLATE__VALIDATE(HostSystem, ESX_VI__TEMPLATE__PROPERTY__REQUIRE(name); /* HostSystem */ + ESX_VI__TEMPLATE__PROPERTY__REQUIRE(configManager); }) int @@ -1851,6 +1852,11 @@ esxVI_HostSystem_CastFromObjectContent(esxVI_ObjectContent *objectContent, virReportOOMError(); goto failure; } + } else if (STREQ(dynamicProperty->name, "configManager")) { + if (esxVI_HostConfigManager_CastFromAnyType + (dynamicProperty->val, &(*hostSystem)->configManager) < 0) { + goto failure; + } } } diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h index 64bf2dc27e..1ab39dad76 100644 --- a/src/esx/esx_vi_types.h +++ b/src/esx/esx_vi_types.h @@ -412,6 +412,7 @@ struct _esxVI_HostSystem { char *name; /* required */ /* HostSystem */ + esxVI_HostConfigManager *configManager; /* required */ }; int esxVI_HostSystem_Alloc(esxVI_HostSystem **hostSystem);