[libvirt] [PATCH] esx: Add domain autostart support

--- As we're currently in feature freeze this patch is meant to be applied after the next release. Matthias src/esx/esx_driver.c | 209 +++++++++++++++++++++++++++++++++++++++- src/esx/esx_vi.c | 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 + 6 files changed, 282 insertions(+), 5 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 55847bc..bda5409 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -3193,6 +3193,211 @@ esxDomainUndefine(virDomainPtr domain) +static int +esxDomainGetAutostart(virDomainPtr domain, int *autostart) +{ + int result = -1; + esxPrivate *priv = domain->conn->privateData; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostAutoStartManager = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + esxVI_AutoStartDefaults *defaults = NULL; + esxVI_AutoStartPowerInfo *powerInfo = NULL; + esxVI_AutoStartPowerInfo *powerInfoList = NULL; + esxVI_ObjectContent *virtualMachine = NULL; + + *autostart = 0; + + if (esxVI_EnsureSession(priv->primary) < 0) { + 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. + */ + + /* Check general autostart config */ + if (esxVI_String_AppendValueToList(&propertyNameList, + "config.defaults") < 0 || + esxVI_LookupObjectContentByType + (priv->primary, + priv->primary->hostSystem->configManager->autoStartManager, + "HostAutoStartManager", propertyNameList, + &hostAutoStartManager) < 0) { + goto cleanup; + } + + if (hostAutoStartManager == NULL) { + ESX_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_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the AutoStartDefaults object")); + goto cleanup; + } + + if (defaults->enabled != esxVI_Boolean_True) { + /* Autostart is disabled in general, exit early here */ + result = 0; + goto cleanup; + } + + /* Check specific autostart config */ + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostAutoStartManager); + + if (esxVI_String_AppendValueToList(&propertyNameList, + "config.powerInfo") < 0 || + esxVI_LookupObjectContentByType + (priv->primary, + priv->primary->hostSystem->configManager->autoStartManager, + "HostAutoStartManager", propertyNameList, + &hostAutoStartManager) < 0) { + goto cleanup; + } + + if (hostAutoStartManager == NULL) { + ESX_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; + } + } + + 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_AutoStartPowerInfo *powerInfo = 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) { + /* Enable autostart in general */ + if (esxVI_AutoStartDefaults_Alloc(&spec->defaults) < 0) { + goto cleanup; + } + + spec->defaults->enabled = esxVI_Boolean_True; + } + + if (esxVI_AutoStartPowerInfo_Alloc(&powerInfo) < 0 || + esxVI_Int_Alloc(&powerInfo->startOrder) < 0 || + esxVI_Int_Alloc(&powerInfo->startDelay) < 0 || + esxVI_Int_Alloc(&powerInfo->stopDelay) < 0 || + esxVI_AutoStartPowerInfo_AppendToList(&spec->powerInfo, + powerInfo) < 0) { + goto cleanup; + } + + powerInfo->key = virtualMachine->obj; + powerInfo->startOrder->value = -1; /* no specific start order */ + powerInfo->startDelay->value = -1; /* use system default */ + powerInfo->waitForHeartbeat = esxVI_AutoStartWaitHeartbeatSetting_SystemDefault; + powerInfo->startAction = autostart ? (char *)"powerOn" : (char *)"none"; + powerInfo->stopDelay->value = -1; /* use system default */ + powerInfo->stopAction = (char *)"none"; + + if (esxVI_ReconfigureAutostart + (priv->primary, + priv->primary->hostSystem->configManager->autoStartManager, + spec) < 0) { + goto cleanup; + } + + result = 0; + + cleanup: + if (powerInfo != NULL) { + powerInfo->key = NULL; + powerInfo->startAction = NULL; + powerInfo->stopAction = NULL; + } + + esxVI_ObjectContent_Free(&virtualMachine); + esxVI_HostAutoStartManagerConfig_Free(&spec); + + return result; +} + + + /* * The scheduler interface exposes basically the CPU ResourceAllocationInfo: * @@ -4396,8 +4601,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 76be5a4..97e33c0 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, diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input index 2d903e4..44d1d9b 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 4a8a9dc..3d068f3 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 a70e1e0..4ee4110 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 64bf2dc..1ab39da 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); -- 1.7.0.4

On 12/29/2010 05:36 PM, Matthias Bolte wrote:
---
As we're currently in feature freeze this patch is meant to be applied after the next release.
And we're now out of feature freeze, so I'm reviewing this...
+ +static int +esxDomainSetAutostart(virDomainPtr domain, int autostart) +{ + int result = -1; + esxPrivate *priv = domain->conn->privateData; + esxVI_ObjectContent *virtualMachine = NULL; + esxVI_HostAutoStartManagerConfig *spec = NULL; + esxVI_AutoStartPowerInfo *powerInfo = 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) { + /* Enable autostart in general */ + if (esxVI_AutoStartDefaults_Alloc(&spec->defaults) < 0) { + goto cleanup; + } + + spec->defaults->enabled = esxVI_Boolean_True; + }
Can enabling the general autostart capability result in changing the default of an unrelated domain with no specific autostart preference to change over to doing autostart, as an unintended side effect of changing the given domain to have mandatory autostart? I'm hoping that the answer is that enabling the global autostart capability doesn't change the autostart behavior of any domains, in which case this patch looks fine. Conditional ACK, based on the answer to that behavior question. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

2011/1/4 Eric Blake <eblake@redhat.com>:
On 12/29/2010 05:36 PM, Matthias Bolte wrote:
---
As we're currently in feature freeze this patch is meant to be applied after the next release.
And we're now out of feature freeze, so I'm reviewing this...
+ +static int +esxDomainSetAutostart(virDomainPtr domain, int autostart) +{ + int result = -1; + esxPrivate *priv = domain->conn->privateData; + esxVI_ObjectContent *virtualMachine = NULL; + esxVI_HostAutoStartManagerConfig *spec = NULL; + esxVI_AutoStartPowerInfo *powerInfo = 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) { + /* Enable autostart in general */ + if (esxVI_AutoStartDefaults_Alloc(&spec->defaults) < 0) { + goto cleanup; + } + + spec->defaults->enabled = esxVI_Boolean_True; + }
Can enabling the general autostart capability result in changing the default of an unrelated domain with no specific autostart preference to change over to doing autostart, as an unintended side effect of changing the given domain to have mandatory autostart? I'm hoping that the answer is that enabling the global autostart capability doesn't change the autostart behavior of any domains, in which case this patch looks fine.
Well, you've spotted a problem there that I didn't think of before :) Domains are individually configured to autostart or not and there is also this general switch to turn on/off autostart capability in general. Now, if the ESX driver turns on general autostart capability then this may result in enabling autostart for other domains that were marked for autostart but didn't because autostart was turned off in general. This needs a v2 that doesn't enable general autostart capability when it's disabled and there are domains marked for autostart. In this case the driver needs to report an error, as it cannot achieve the desired result under the given conditions. It's still safe to enable general autostart capability when there is no domain marked for autostart, or when only the domain is marked for autostart already that we want to enable autostart for anyway. Matthias
participants (2)
-
Eric Blake
-
Matthias Bolte