[libvirt] [Patch v2] vmware: detect when a domain was shut down from the inside
Michal Privoznik
mprivozn at redhat.com
Wed Jul 4 09:41:28 UTC 2012
On 02.04.2012 15:59, Jean-Baptiste Rouault wrote:
> This patch adds an internal function vmwareUpdateVMStatus to
> update the real state of the domain. This function is used in
> various places in the driver, in particular to detect when
> the domain has been shut down by the user with the "halt"
> command.
> ---
> v2:
> - Replace internal function vmwareGetVMStatus by vmwareUpdateVMStatus
> - Improve vmrun list output parsing
> - variable initialization and coding-style fixes
>
> src/vmware/vmware_driver.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 95 insertions(+), 0 deletions(-)
>
> diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
> index 8f9d922..53e28e7 100644
> --- a/src/vmware/vmware_driver.c
> +++ b/src/vmware/vmware_driver.c
> @@ -28,6 +28,7 @@
> #include "datatypes.h"
> #include "virfile.h"
> #include "memory.h"
> +#include "util.h"
> #include "uuid.h"
> #include "command.h"
> #include "vmx.h"
> @@ -181,6 +182,64 @@ vmwareGetVersion(virConnectPtr conn, unsigned long *version)
> }
>
> static int
> +vmwareUpdateVMStatus(struct vmware_driver *driver, virDomainObjPtr vm)
> +{
> + virCommandPtr cmd;
> + char *outbuf = NULL;
> + char *vmxAbsolutePath = NULL;
> + char *parsedVmxPath = NULL;
> + char *str;
> + char *saveptr = NULL;
> + bool found = false;
> + int oldState = virDomainObjGetState(vm, NULL);
> + int newState;
> + int ret = -1;
> +
> + cmd = virCommandNewArgList(VMRUN, "-T", vmw_types[driver->type],
> + "list", NULL);
> + virCommandSetOutputBuffer(cmd, &outbuf);
> + if (virCommandRun(cmd, NULL) < 0)
> + goto cleanup;
> +
> + if (virFileResolveAllLinks(((vmwareDomainPtr) vm->privateData)->vmxPath,
> + &vmxAbsolutePath) < 0)
> + goto cleanup;
> +
> + for(str = outbuf ; (parsedVmxPath = strtok_r(str, "\n", &saveptr)) != NULL;
> + str = NULL) {
> +
> + if (parsedVmxPath[0] != '/')
> + continue;
> +
> + if (STREQ(parsedVmxPath, vmxAbsolutePath)) {
> + found = true;
> + /* If the vmx path is in the output, the domain is running or
> + * is paused but we have no way to detect if it is paused or not. */
> + if (oldState == VIR_DOMAIN_PAUSED)
> + newState = oldState;
> + else
> + newState = VIR_DOMAIN_RUNNING;
> + break;
> + }
> + }
> +
> + if (!found) {
> + vm->def->id = -1;
> + newState = VIR_DOMAIN_SHUTOFF;
> + }
> +
> + virDomainObjSetState(vm, newState, 0);
> +
> + ret = 0;
> +
> +cleanup:
> + virCommandFree(cmd);
> + VIR_FREE(outbuf);
> + VIR_FREE(vmxAbsolutePath);
> + return ret;
> +}
> +
> +static int
> vmwareStopVM(struct vmware_driver *driver,
> virDomainObjPtr vm,
> virDomainShutoffReason reason)
> @@ -331,6 +390,9 @@ vmwareDomainShutdownFlags(virDomainPtr dom,
> goto cleanup;
> }
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
> +
> if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) {
> vmwareError(VIR_ERR_INTERNAL_ERROR, "%s",
> _("domain is not in running state"));
> @@ -485,6 +547,8 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags)
> vmwareSetSentinal(cmd, vmw_types[driver->type]);
> vmwareSetSentinal(cmd, vmxPath);
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
>
> if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) {
> vmwareError(VIR_ERR_INTERNAL_ERROR, "%s",
> @@ -596,6 +660,9 @@ vmwareDomainCreateWithFlags(virDomainPtr dom,
> goto cleanup;
> }
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
> +
> if (virDomainObjIsActive(vm)) {
> vmwareError(VIR_ERR_OPERATION_INVALID,
> "%s", _("Domain is already running"));
> @@ -645,6 +712,9 @@ vmwareDomainUndefineFlags(virDomainPtr dom,
> goto cleanup;
> }
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
> +
> if (virDomainObjIsActive(vm)) {
> vm->persistent = 0;
> } else {
> @@ -874,6 +944,21 @@ vmwareDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
> return xml;
> }
>
> +static void vmwareDomainObjListUpdateDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *data)
> +{
> + struct vmware_driver *driver = data;
> + virDomainObjPtr vm = payload;
> + virDomainObjLock(vm);
> + vmwareUpdateVMStatus(driver, vm);
> + virDomainObjUnlock(vm);
> +}
> +
> +static void
> +vmwareDomainObjListUpdateAll(virDomainObjListPtr doms, struct vmware_driver *driver)
> +{
> + virHashForEach(doms->objs, vmwareDomainObjListUpdateDomain, driver);
> +}
> +
> static int
> vmwareNumDefinedDomains(virConnectPtr conn)
> {
> @@ -881,6 +966,7 @@ vmwareNumDefinedDomains(virConnectPtr conn)
> int n;
>
> vmwareDriverLock(driver);
> + vmwareDomainObjListUpdateAll(&driver->domains, driver);
> n = virDomainObjListNumOfDomains(&driver->domains, 0);
> vmwareDriverUnlock(driver);
>
> @@ -894,6 +980,7 @@ vmwareNumDomains(virConnectPtr conn)
> int n;
>
> vmwareDriverLock(driver);
> + vmwareDomainObjListUpdateAll(&driver->domains, driver);
> n = virDomainObjListNumOfDomains(&driver->domains, 1);
> vmwareDriverUnlock(driver);
>
> @@ -908,6 +995,7 @@ vmwareListDomains(virConnectPtr conn, int *ids, int nids)
> int n;
>
> vmwareDriverLock(driver);
> + vmwareDomainObjListUpdateAll(&driver->domains, driver);
> n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
> vmwareDriverUnlock(driver);
>
> @@ -922,6 +1010,7 @@ vmwareListDefinedDomains(virConnectPtr conn,
> int n;
>
> vmwareDriverLock(driver);
> + vmwareDomainObjListUpdateAll(&driver->domains, driver);
> n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
> vmwareDriverUnlock(driver);
> return n;
> @@ -944,6 +1033,9 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
> goto cleanup;
> }
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
> +
> info->state = virDomainObjGetState(vm, NULL);
> info->cpuTime = 0;
> info->maxMem = vm->def->mem.max_balloon;
> @@ -979,6 +1071,9 @@ vmwareDomainGetState(virDomainPtr dom,
> goto cleanup;
> }
>
> + if (vmwareUpdateVMStatus(driver, vm) < 0)
> + goto cleanup;
> +
> *state = virDomainObjGetState(vm, reason);
> ret = 0;
>
>
Okay, but we must not forget to fix our new atomic list API too. So I am
squashing this in:
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index eb4811e..2b9a275 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -1101,6 +1101,7 @@ vmwareListAllDomains(virConnectPtr conn,
virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1);
vmwareDriverLock(driver);
+ vmwareDomainObjListUpdateAll(&driver->domains, driver);
ret = virDomainList(conn, driver->domains.objs, domains, flags);
vmwareDriverUnlock(driver);
return ret;
And pushed now. Thanks.
Michal
More information about the libvir-list
mailing list