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