On Wed, Feb 01, 2012 at 02:29:37PM +0100, Jean-Baptiste Rouault wrote: > This patch adds an internal function vmwareGetVMStatus to > get 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. > --- > src/vmware/vmware_driver.c | 83 +++++++++++++++++++++++++++++++++++++------- > 1 files changed, 70 insertions(+), 13 deletions(-) > > diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c > index 56e9d2d..6f75f86 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,50 @@ vmwareGetVersion(virConnectPtr conn, unsigned long *version) > } > > static int > +vmwareGetVMStatus(struct vmware_driver *driver, > + virDomainObjPtr vm, > + int *status, > + int *reason) > +{ > + virCommandPtr cmd; > + char *outbuf; > + char *vmxAbsolutePath; > + int state; > + int ret = -1; > + > + cmd = virCommandNewArgList(VMRUN, "-T", vmw_types[driver->type], > + "list", NULL); > + virCommandSetOutputBuffer(cmd, &outbuf); > + if (virCommandRun(cmd, NULL) < 0) > + goto cleanup; > + > + state = virDomainObjGetState(vm, reason); > + > + if (virFileResolveAllLinks(((vmwareDomainPtr) vm->privateData)->vmxPath, > + &vmxAbsolutePath) == -1) > + goto cleanup; > + > + if (strstr(outbuf, vmxAbsolutePath)) { > + /* 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 (state == VIR_DOMAIN_PAUSED) > + *status = state; > + else > + *status = VIR_DOMAIN_RUNNING; > + } else { > + *status = VIR_DOMAIN_SHUTOFF; > + } > + > + ret = 0; > + > +cleanup: > + virCommandFree(cmd); > + VIR_FREE(outbuf); > + VIR_FREE(vmxAbsolutePath); > + return ret; > +} > + > +static int > vmwareStopVM(struct vmware_driver *driver, > virDomainObjPtr vm, > virDomainShutoffReason reason) > @@ -212,12 +257,6 @@ vmwareStartVM(struct vmware_driver *driver, virDomainObjPtr vm) > }; > const char *vmxPath = ((vmwareDomainPtr) vm->privateData)->vmxPath; > > - if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_SHUTOFF) { > - vmwareError(VIR_ERR_OPERATION_INVALID, "%s", > - _("domain is not in shutoff state")); > - return -1; > - } > - > vmwareSetSentinal(cmd, vmw_types[driver->type]); > vmwareSetSentinal(cmd, vmxPath); > if (!((vmwareDomainPtr) vm->privateData)->gui) > @@ -317,6 +356,7 @@ vmwareDomainShutdownFlags(virDomainPtr dom, > { > struct vmware_driver *driver = dom->conn->privateData; > virDomainObjPtr vm; > + int status; > int ret = -1; > > virCheckFlags(0, -1); > @@ -331,7 +371,10 @@ vmwareDomainShutdownFlags(virDomainPtr dom, > goto cleanup; > } > > - if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { > + if (vmwareGetVMStatus(driver, vm, &status, NULL) == -1) > + goto cleanup; > + > + if (status != VIR_DOMAIN_RUNNING) { > vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", > _("domain is not in running state")); > goto cleanup; > @@ -467,6 +510,7 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags) > VMRUN, "-T", PROGRAM_SENTINAL, > "reset", PROGRAM_SENTINAL, "soft", NULL > }; > + int status; > int ret = -1; > > virCheckFlags(0, -1); > @@ -485,8 +529,10 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags) > vmwareSetSentinal(cmd, vmw_types[driver->type]); > vmwareSetSentinal(cmd, vmxPath); > > + if (vmwareGetVMStatus(driver, vm, &status, NULL) == -1) > + goto cleanup; > > - if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { > + if (status != VIR_DOMAIN_RUNNING) { > vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", > _("domain is not in running state")); > goto cleanup; > @@ -582,6 +628,7 @@ vmwareDomainCreateWithFlags(virDomainPtr dom, > { > struct vmware_driver *driver = dom->conn->privateData; > virDomainObjPtr vm; > + int status; > int ret = -1; > > virCheckFlags(0, -1); > @@ -596,7 +643,10 @@ vmwareDomainCreateWithFlags(virDomainPtr dom, > goto cleanup; > } > > - if (virDomainObjIsActive(vm)) { > + if (vmwareGetVMStatus(driver, vm, &status, NULL) == -1) > + goto cleanup; > + > + if (status != VIR_DOMAIN_SHUTOFF) { > vmwareError(VIR_ERR_OPERATION_INVALID, > "%s", _("Domain is already running")); > goto cleanup; > @@ -623,6 +673,7 @@ vmwareDomainUndefineFlags(virDomainPtr dom, > { > struct vmware_driver *driver = dom->conn->privateData; > virDomainObjPtr vm; > + int status; > int ret = -1; > > virCheckFlags(0, -1); > @@ -645,7 +696,10 @@ vmwareDomainUndefineFlags(virDomainPtr dom, > goto cleanup; > } > > - if (virDomainObjIsActive(vm)) { > + if (vmwareGetVMStatus(driver, vm, &status, NULL) == -1) > + goto cleanup; > + > + if (status == VIR_DOMAIN_RUNNING) { > vm->persistent = 0; > } else { > virDomainRemoveInactive(&driver->domains, vm); > @@ -902,6 +956,7 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) > { > struct vmware_driver *driver = dom->conn->privateData; > virDomainObjPtr vm; > + int state; > int ret = -1; > > vmwareDriverLock(driver); > @@ -914,7 +969,10 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) > goto cleanup; > } > > - info->state = virDomainObjGetState(vm, NULL); > + if (vmwareGetVMStatus(driver, vm, &state, NULL) == -1) > + goto cleanup; > + > + info->state = state; > info->cpuTime = 0; > info->maxMem = vm->def->mem.max_balloon; > info->memory = vm->def->mem.cur_balloon; > @@ -949,8 +1007,7 @@ vmwareDomainGetState(virDomainPtr dom, > goto cleanup; > } > > - *state = virDomainObjGetState(vm, reason); > - ret = 0; > + ret = vmwareGetVMStatus(driver, vm, state, reason); > > cleanup: > if (vm) That looks reasonable to me, there is a small hit due to the extra round trip to the server, but I would rather have the opinion of Mathias before pushing this :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list