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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list