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(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/