[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