[libvirt] [PATCH v2 7/9] Implement basic virDomainGetState in all drivers

Jiri Denemark jdenemar at redhat.com
Tue May 10 13:39:09 UTC 2011


Reason is currently always set to 0 (i.e., *_UNKNOWN).
---
Notes:
    Version 2:
    - rebased
    - unsigned int flags
    - simplified implementation in esx driver per Matthias' suggestion
    - call internal xen drivers directly instead of going through xenUnifiedDriver

 src/esx/esx_driver.c       |   45 +++++++++++++++++++-
 src/libxl/libxl_driver.c   |   36 +++++++++++++++-
 src/lxc/lxc_driver.c       |   38 ++++++++++++++++-
 src/openvz/openvz_driver.c |   37 ++++++++++++++++-
 src/phyp/phyp_driver.c     |   17 +++++++-
 src/qemu/qemu_driver.c     |   38 ++++++++++++++++-
 src/test/test_driver.c     |   36 +++++++++++++++-
 src/uml/uml_driver.c       |   37 ++++++++++++++++-
 src/vbox/vbox_tmpl.c       |   61 ++++++++++++++++++++++++++-
 src/vmware/vmware_driver.c |   36 +++++++++++++++-
 src/xen/xen_driver.c       |   43 ++++++++++++++++++-
 src/xen/xen_hypervisor.c   |   36 ++++++++++++++++
 src/xen/xen_hypervisor.h   |    5 ++
 src/xen/xend_internal.c    |   99 +++++++++++++++++++++++++++++++++-----------
 src/xen/xend_internal.h    |    4 ++
 src/xen/xm_internal.c      |   20 +++++++++
 src/xen/xm_internal.h      |    4 ++
 src/xen/xs_internal.c      |   34 +++++++++++++++
 src/xen/xs_internal.h      |    4 ++
 src/xenapi/xenapi_driver.c |   50 ++++++++++++++++++++++-
 20 files changed, 644 insertions(+), 36 deletions(-)

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index ec2aaf9..d333877 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2452,6 +2452,49 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
 
 
 static int
+esxDomainGetState(virDomainPtr domain,
+                  int *state,
+                  int *reason,
+                  unsigned int flags)
+{
+    int result = -1;
+    esxPrivate *priv = domain->conn->privateData;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_ObjectContent *virtualMachine = NULL;
+    esxVI_VirtualMachinePowerState powerState;
+
+    virCheckFlags(0, -1);
+
+    if (esxVI_EnsureSession(priv->primary) < 0) {
+        return -1;
+    }
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+                                       "runtime.powerState") < 0 ||
+        esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+                                         propertyNameList, &virtualMachine,
+                                         esxVI_Occurrence_RequiredItem) < 0 ||
+        esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
+        goto cleanup;
+    }
+
+    *state = esxVI_VirtualMachinePowerState_ConvertToLibvirt(powerState);
+
+    if (reason)
+        *reason = 0;
+
+    result = 0;
+
+  cleanup:
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&virtualMachine);
+
+    return result;
+}
+
+
+
+static int
 esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
                        unsigned int flags)
 {
@@ -4623,7 +4666,7 @@ static virDriver esxDriver = {
     NULL,                            /* domainSetBlkioParameters */
     NULL,                            /* domainGetBlkioParameters */
     esxDomainGetInfo,                /* domainGetInfo */
-    NULL,                            /* domainGetState */
+    esxDomainGetState,               /* domainGetState */
     NULL,                            /* domainSave */
     NULL,                            /* domainRestore */
     NULL,                            /* domainCoreDump */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 794a9e7..1fcf723 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1608,6 +1608,40 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
 }
 
 static int
+libxlDomainGetState(virDomainPtr dom,
+                    int *state,
+                    int *reason,
+                    unsigned int flags)
+{
+    libxlDriverPrivatePtr driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    libxlDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    libxlDriverUnlock(driver);
+
+    if (!vm) {
+        libxlError(VIR_ERR_NO_DOMAIN, "%s",
+                   _("no domain with matching uuid"));
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+  cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
+static int
 libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
                          unsigned int flags)
 {
@@ -2714,7 +2748,7 @@ static virDriver libxlDriver = {
     NULL,                       /* domainSetBlkioParameters */
     NULL,                       /* domainGetBlkioParameters */
     libxlDomainGetInfo,         /* domainGetInfo */
-    NULL,                       /* domainGetState */
+    libxlDomainGetState,        /* domainGetState */
     NULL,                       /* domainSave */
     NULL,                       /* domainRestore */
     NULL,                       /* domainCoreDump */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 0dcaf4c..2d57eb2 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -564,6 +564,42 @@ cleanup:
     return ret;
 }
 
+static int
+lxcDomainGetState(virDomainPtr dom,
+                  int *state,
+                  int *reason,
+                  unsigned int flags)
+{
+    lxc_driver_t *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    lxcDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    lxcDriverUnlock(driver);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        lxcError(VIR_ERR_NO_DOMAIN,
+                 _("No domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 static char *lxcGetOSType(virDomainPtr dom)
 {
     lxc_driver_t *driver = dom->conn->privateData;
@@ -2829,7 +2865,7 @@ static virDriver lxcDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     lxcDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    lxcDomainGetState, /* domainGetState */
     NULL, /* domainSave */
     NULL, /* domainRestore */
     NULL, /* domainCoreDump */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 48a3aae..3ab72e8 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -377,6 +377,41 @@ cleanup:
 }
 
 
+static int
+openvzDomainGetState(virDomainPtr dom,
+                     int *state,
+                     int *reason,
+                     unsigned int flags)
+{
+    struct openvz_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    openvzDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    openvzDriverUnlock(driver);
+
+    if (!vm) {
+        openvzError(VIR_ERR_NO_DOMAIN, "%s",
+                    _("no domain with matching uuid"));
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
+
 static int openvzDomainIsActive(virDomainPtr dom)
 {
     struct openvz_driver *driver = dom->conn->privateData;
@@ -1591,7 +1626,7 @@ static virDriver openvzDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     openvzDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    openvzDomainGetState, /* domainGetState */
     NULL, /* domainSave */
     NULL, /* domainRestore */
     NULL, /* domainCoreDump */
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index abd3594..51c19f0 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -3471,6 +3471,21 @@ phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
 }
 
 static int
+phypDomainGetState(virDomainPtr dom,
+                   int *state,
+                   int *reason,
+                   unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+    *state = phypGetLparState(dom->conn, dom->id);
+    if (reason)
+        *reason = 0;
+
+    return 0;
+}
+
+static int
 phypDomainDestroy(virDomainPtr dom)
 {
     int result = -1;
@@ -3752,7 +3767,7 @@ static virDriver phypDriver = {
     NULL,                       /* domainSetBlkioParameters */
     NULL,                       /* domainGetBlkioParameters */
     phypDomainGetInfo,          /* domainGetInfo */
-    NULL,                       /* domainGetState */
+    phypDomainGetState,         /* domainGetState */
     NULL,                       /* domainSave */
     NULL,                       /* domainRestore */
     NULL,                       /* domainCoreDump */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 92c7f9a..a1617bc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1783,6 +1783,42 @@ cleanup:
     return ret;
 }
 
+static int
+qemuDomainGetState(virDomainPtr dom,
+                   int *state,
+                   int *reason,
+                   unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    qemuDriverUnlock(driver);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 
 #define QEMUD_SAVE_MAGIC "LibvirtQemudSave"
 #define QEMUD_SAVE_VERSION 2
@@ -7116,7 +7152,7 @@ static virDriver qemuDriver = {
     qemuDomainSetBlkioParameters, /* domainSetBlkioParameters */
     qemuDomainGetBlkioParameters, /* domainGetBlkioParameters */
     qemudDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    qemuDomainGetState, /* domainGetState */
     qemudDomainSave, /* domainSave */
     qemuDomainRestore, /* domainRestore */
     qemudDomainCoreDump, /* domainCoreDump */
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 6f4ae75..4ec2852 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1704,6 +1704,40 @@ cleanup:
     return ret;
 }
 
+static int
+testDomainGetState(virDomainPtr domain,
+                   int *state,
+                   int *reason,
+                   unsigned int flags)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    *state = privdom->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
 #define TEST_SAVE_MAGIC "TestGuestMagic"
 
 static int testDomainSave(virDomainPtr domain,
@@ -5371,7 +5405,7 @@ static virDriver testDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     testGetDomainInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    testDomainGetState, /* domainGetState */
     testDomainSave, /* domainSave */
     testDomainRestore, /* domainRestore */
     testDomainCoreDump, /* domainCoreDump */
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 6852a16..e6fe019 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1522,6 +1522,41 @@ cleanup:
 }
 
 
+static int
+umlDomainGetState(virDomainPtr dom,
+                  int *state,
+                  int *reason,
+                  unsigned int flags)
+{
+    struct uml_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    umlDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    umlDriverUnlock(driver);
+
+    if (!vm) {
+        umlReportError(VIR_ERR_NO_DOMAIN, "%s",
+                       _("no domain with matching uuid"));
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
+
 static char *umlDomainDumpXML(virDomainPtr dom,
                                 int flags ATTRIBUTE_UNUSED) {
     struct uml_driver *driver = dom->conn->privateData;
@@ -2177,7 +2212,7 @@ static virDriver umlDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     umlDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    umlDomainGetState, /* domainGetState */
     NULL, /* domainSave */
     NULL, /* domainRestore */
     NULL, /* domainCoreDump */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index d4a8924..9faaf5e 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -1909,6 +1909,65 @@ cleanup:
     return ret;
 }
 
+static int
+vboxDomainGetState(virDomainPtr dom,
+                   int *state,
+                   int *reason,
+                   unsigned int flags)
+{
+    VBOX_OBJECT_CHECK(dom->conn, int, -1);
+    vboxIID domiid = VBOX_IID_INITIALIZER;
+    IMachine *machine = NULL;
+    PRUint32 mstate = MachineState_Null;
+    nsresult rc;
+
+    virCheckFlags(0, -1);
+
+    vboxIIDFromUUID(&domiid, dom->uuid);
+    rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
+    if (NS_FAILED(rc)) {
+        vboxError(VIR_ERR_NO_DOMAIN, "%s",
+                  _("no domain with matching UUID"));
+        goto cleanup;
+    }
+
+    machine->vtbl->GetState(machine, &mstate);
+
+    switch (mstate) {
+    case MachineState_Running:
+        *state = VIR_DOMAIN_RUNNING;
+        break;
+    case MachineState_Stuck:
+        *state = VIR_DOMAIN_BLOCKED;
+        break;
+    case MachineState_Paused:
+        *state = VIR_DOMAIN_PAUSED;
+        break;
+    case MachineState_Stopping:
+        *state = VIR_DOMAIN_SHUTDOWN;
+        break;
+    case MachineState_PoweredOff:
+        *state = VIR_DOMAIN_SHUTOFF;
+        break;
+    case MachineState_Aborted:
+        *state = VIR_DOMAIN_CRASHED;
+        break;
+    case MachineState_Null:
+    default:
+        *state = VIR_DOMAIN_NOSTATE;
+        break;
+    }
+
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    vboxIIDUnalloc(&domiid);
+    return ret;
+}
+
 static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) {
     VBOX_OBJECT_CHECK(dom->conn, int, -1);
     IConsole *console    = NULL;
@@ -8566,7 +8625,7 @@ virDriver NAME(Driver) = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     vboxDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    vboxDomainGetState, /* domainGetState */
     vboxDomainSave, /* domainSave */
     NULL, /* domainRestore */
     NULL, /* domainCoreDump */
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index c6c92c6..743e136 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -896,6 +896,40 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
     return ret;
 }
 
+static int
+vmwareDomainGetState(virDomainPtr dom,
+                     int *state,
+                     int *reason,
+                     unsigned int flags)
+{
+    struct vmware_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    vmwareDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    vmwareDriverUnlock(driver);
+
+    if (!vm) {
+        vmwareError(VIR_ERR_NO_DOMAIN, "%s",
+                    _("no domain with matching uuid"));
+        goto cleanup;
+    }
+
+    *state = vm->state;
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+  cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 static virDriver vmwareDriver = {
     VIR_DRV_VMWARE,
     "VMWARE",
@@ -931,7 +965,7 @@ static virDriver vmwareDriver = {
     NULL,                       /* domainSetBlkioParameters */
     NULL,                       /* domainGetBlkioParameters */
     vmwareDomainGetInfo,        /* domainGetInfo */
-    NULL,                       /* domainGetState */
+    vmwareDomainGetState,       /* domainGetState */
     NULL,                       /* domainSave */
     NULL,                       /* domainRestore */
     NULL,                       /* domainCoreDump */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 1646828..a2728eb 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1010,6 +1010,47 @@ xenUnifiedDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
 }
 
 static int
+xenUnifiedDomainGetState(virDomainPtr dom,
+                         int *state,
+                         int *reason,
+                         unsigned int flags)
+{
+    GET_PRIVATE(dom->conn);
+    int ret;
+
+    virCheckFlags(0, -1);
+
+    /* trying drivers in the same order as GetInfo for consistent results:
+     * hypervisor, xend, xs, and xm */
+
+    if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET]) {
+        ret = xenHypervisorGetDomainState(dom, state, reason, flags);
+        if (ret >= 0)
+            return ret;
+    }
+
+    if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
+        ret = xenDaemonDomainGetState(dom, state, reason, flags);
+        if (ret >= 0)
+            return ret;
+    }
+
+    if (priv->opened[XEN_UNIFIED_XS_OFFSET]) {
+        ret = xenStoreDomainGetState(dom, state, reason, flags);
+        if (ret >= 0)
+            return ret;
+    }
+
+    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
+        ret = xenXMDomainGetState(dom, state, reason, flags);
+        if (ret >= 0)
+            return ret;
+    }
+
+    return -1;
+}
+
+static int
 xenUnifiedDomainSave (virDomainPtr dom, const char *to)
 {
     GET_PRIVATE(dom->conn);
@@ -2132,7 +2173,7 @@ static virDriver xenUnifiedDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     xenUnifiedDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    xenUnifiedDomainGetState, /* domainGetState */
     xenUnifiedDomainSave, /* domainSave */
     xenUnifiedDomainRestore, /* domainRestore */
     xenUnifiedDomainCoreDump, /* domainCoreDump */
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index 9a5b41d..1a245e5 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -3238,6 +3238,42 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
 }
 
 /**
+ * xenHypervisorGetDomainState:
+ * @domain: pointer to the domain block
+ * @state: returned state of the domain
+ * @reason: returned reason for the state
+ * @flags: additional flags, 0 for now
+ *
+ * Do a hypervisor call to get the related set of domain information.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+int
+xenHypervisorGetDomainState(virDomainPtr domain,
+                            int *state,
+                            int *reason,
+                            unsigned int flags ATTRIBUTE_UNUSED)
+{
+    xenUnifiedPrivatePtr priv = domain->conn->privateData;
+    virDomainInfo info;
+
+    if (domain->conn == NULL)
+        return -1;
+
+    if (priv->handle < 0 || domain->id < 0)
+        return -1;
+
+    if (xenHypervisorGetDomInfo(domain->conn, domain->id, &info) < 0)
+        return -1;
+
+    *state = info.state;
+    if (reason)
+        *reason = 0;
+
+    return 0;
+}
+
+/**
  * xenHypervisorNodeGetCellsFreeMemory:
  * @conn: pointer to the hypervisor connection
  * @freeMems: pointer to the array of unsigned long long
diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h
index 6018b84..f7e7699 100644
--- a/src/xen/xen_hypervisor.h
+++ b/src/xen/xen_hypervisor.h
@@ -66,6 +66,11 @@ int     xenHypervisorPauseDomain        (virDomainPtr domain)
 int     xenHypervisorGetDomainInfo        (virDomainPtr domain,
                                            virDomainInfoPtr info)
           ATTRIBUTE_NONNULL (1);
+int     xenHypervisorGetDomainState     (virDomainPtr domain,
+                                         int *state,
+                                         int *reason,
+                                         unsigned int flags)
+          ATTRIBUTE_NONNULL (1);
 int     xenHypervisorGetDomInfo         (virConnectPtr conn,
                                          int id,
                                          virDomainInfoPtr info);
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index a4420d8..2e87bd6 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1020,6 +1020,43 @@ xend_detect_config_version(virConnectPtr conn) {
 
 
 /**
+ * sexpr_to_xend_domain_state:
+ * @root: an S-Expression describing a domain
+ *
+ * Internal routine getting the domain's state from the domain root provided.
+ *
+ * Returns domain's state.
+ */
+static int
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root)
+{
+    const char *flags;
+    int state = VIR_DOMAIN_NOSTATE;
+
+    if ((flags = sexpr_node(root, "domain/state"))) {
+        if (strchr(flags, 'c'))
+            state = VIR_DOMAIN_CRASHED;
+        else if (strchr(flags, 's'))
+            state = VIR_DOMAIN_SHUTOFF;
+        else if (strchr(flags, 'd'))
+            state = VIR_DOMAIN_SHUTDOWN;
+        else if (strchr(flags, 'p'))
+            state = VIR_DOMAIN_PAUSED;
+        else if (strchr(flags, 'b'))
+            state = VIR_DOMAIN_BLOCKED;
+        else if (strchr(flags, 'r'))
+            state = VIR_DOMAIN_RUNNING;
+    } else if (domain->id < 0) {
+        /* Inactive domains don't have a state reported, so
+           mark them SHUTOFF, rather than NOSTATE */
+        state = VIR_DOMAIN_SHUTOFF;
+    }
+
+    return state;
+}
+
+/**
  * sexpr_to_xend_domain_info:
  * @root: an S-Expression describing a domain
  * @info: a info data structure to fill=up
@@ -1033,38 +1070,16 @@ static int
 sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root,
                           virDomainInfoPtr info)
 {
-    const char *flags;
     int vcpus;
 
     if ((root == NULL) || (info == NULL))
         return (-1);
 
+    info->state = sexpr_to_xend_domain_state(domain, root);
     info->memory = sexpr_u64(root, "domain/memory") << 10;
     info->maxMem = sexpr_u64(root, "domain/maxmem") << 10;
-    flags = sexpr_node(root, "domain/state");
-
-    if (flags) {
-        if (strchr(flags, 'c'))
-            info->state = VIR_DOMAIN_CRASHED;
-        else if (strchr(flags, 's'))
-            info->state = VIR_DOMAIN_SHUTOFF;
-        else if (strchr(flags, 'd'))
-            info->state = VIR_DOMAIN_SHUTDOWN;
-        else if (strchr(flags, 'p'))
-            info->state = VIR_DOMAIN_PAUSED;
-        else if (strchr(flags, 'b'))
-            info->state = VIR_DOMAIN_BLOCKED;
-        else if (strchr(flags, 'r'))
-            info->state = VIR_DOMAIN_RUNNING;
-    } else {
-        /* Inactive domains don't have a state reported, so
-           mark them SHUTOFF, rather than NOSTATE */
-        if (domain->id < 0)
-            info->state = VIR_DOMAIN_SHUTOFF;
-        else
-            info->state = VIR_DOMAIN_NOSTATE;
-    }
     info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000;
+
     vcpus = sexpr_int(root, "domain/vcpus");
     info->nrVirtCpu = count_one_bits_l(sexpr_u64(root, "domain/vcpu_avail"));
     if (!info->nrVirtCpu || vcpus < info->nrVirtCpu)
@@ -1894,6 +1909,42 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
 
 
 /**
+ * xenDaemonDomainGetState:
+ * @domain: a domain object
+ * @state: returned domain's state
+ * @reason: returned reason for the state
+ * @flags: additional flags, 0 for now
+ *
+ * This method looks up domain state and reason.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xenDaemonDomainGetState(virDomainPtr domain,
+                        int *state,
+                        int *reason,
+                        unsigned int flags ATTRIBUTE_UNUSED)
+{
+    xenUnifiedPrivatePtr priv = domain->conn->privateData;
+    struct sexpr *root;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
+        return -1;
+
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+    if (!root)
+        return -1;
+
+    *state = sexpr_to_xend_domain_state(domain, root);
+    if (reason)
+        *reason = 0;
+
+    sexpr_free(root);
+    return 0;
+}
+
+
+/**
  * xenDaemonLookupByName:
  * @conn: A xend instance
  * @name: The name of the domain
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index 805cf91..de9b1b9 100644
--- a/src/xen/xend_internal.h
+++ b/src/xen/xend_internal.h
@@ -110,6 +110,10 @@ int xenDaemonDomainRestore(virConnectPtr conn, const char *filename);
 int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory);
 int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
 int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info);
+int xenDaemonDomainGetState(virDomainPtr domain,
+                            int *state,
+                            int *reason,
+                            unsigned int flags);
 char *xenDaemonDomainDumpXML(virDomainPtr domain, int flags, const char *cpus);
 unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain);
 char **xenDaemonListDomainsOld(virConnectPtr xend);
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 07a0c0f..e68a043 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -469,6 +469,26 @@ int xenXMClose(virConnectPtr conn) {
 }
 
 /*
+ * Since these are all offline domains, the state is always SHUTOFF.
+ */
+int
+xenXMDomainGetState(virDomainPtr domain,
+                    int *state,
+                    int *reason,
+                    unsigned int flags ATTRIBUTE_UNUSED)
+{
+    if (domain->id != -1)
+        return -1;
+
+    *state = VIR_DOMAIN_SHUTOFF;
+    if (reason)
+        *reason = 0;
+
+    return 0;
+}
+
+
+/*
  * Since these are all offline domains, we only return info about
  * VCPUs and memory.
  */
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
index 695bb3e..2d37505 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -40,6 +40,10 @@ virDrvOpenStatus xenXMOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags
 int xenXMClose(virConnectPtr conn);
 const char *xenXMGetType(virConnectPtr conn);
 int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info);
+int xenXMDomainGetState(virDomainPtr domain,
+                        int *state,
+                        int *reason,
+                        unsigned int flags);
 char *xenXMDomainDumpXML(virDomainPtr domain, int flags);
 int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
 int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
index c318f6c..0db1c9f 100644
--- a/src/xen/xs_internal.c
+++ b/src/xen/xs_internal.c
@@ -449,6 +449,40 @@ xenStoreGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
 }
 
 /**
+ * xenStoreDomainGetState:
+ * @domain: pointer to the domain block
+ * @state: returned domain's state
+ * @reason: returned state reason
+ * @flags: additional flags, 0 for now
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+int
+xenStoreDomainGetState(virDomainPtr domain,
+                       int *state,
+                       int *reason,
+                       unsigned int flags ATTRIBUTE_UNUSED)
+{
+    char *running;
+
+    if (domain->id == -1)
+        return -1;
+
+    running = virDomainDoStoreQuery(domain->conn, domain->id, "running");
+
+    if (running && *running == '1')
+        *state = VIR_DOMAIN_RUNNING;
+    else
+        *state = VIR_DOMAIN_NOSTATE;
+    if (reason)
+        *reason = 0;
+
+    VIR_FREE(running);
+
+    return 0;
+}
+
+/**
  * xenStoreDomainSetMemory:
  * @domain: pointer to the domain block
  * @memory: the max memory size in kilobytes.
diff --git a/src/xen/xs_internal.h b/src/xen/xs_internal.h
index d58e6c0..efc4f9f 100644
--- a/src/xen/xs_internal.h
+++ b/src/xen/xs_internal.h
@@ -23,6 +23,10 @@ virDrvOpenStatus	xenStoreOpen	(virConnectPtr conn,
 int		xenStoreClose		(virConnectPtr conn);
 int		xenStoreGetDomainInfo	(virDomainPtr domain,
                                          virDomainInfoPtr info);
+int		xenStoreDomainGetState	(virDomainPtr domain,
+                                         int *state,
+                                         int *reason,
+                                         unsigned int flags);
 int		xenStoreNumOfDomains	(virConnectPtr conn);
 int		xenStoreListDomains	(virConnectPtr conn,
                                          int *ids,
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 83417df..87bba74 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -994,6 +994,54 @@ xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
     return -1;
 }
 
+/*
+ * xenapiDomainGetState:
+ *
+ * Retrieves domain status and its reason.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int
+xenapiDomainGetState(virDomainPtr dom,
+                     int *state,
+                     int *reason,
+                     unsigned int flags)
+{
+    struct _xenapiPrivate *priv = dom->conn->privateData;
+    enum xen_vm_power_state powerState = XEN_VM_POWER_STATE_UNDEFINED;
+    xen_vm_set *vms = NULL;
+    xen_vm vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    if (!xen_vm_get_by_name_label(priv->session, &vms, dom->name) ||
+        vms->size == 0) {
+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+
+    if (vms->size != 1) {
+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
+                                  _("Domain name is not unique"));
+        goto cleanup;
+    }
+
+    vm = vms->contents[0];
+    xen_vm_get_power_state(priv->session, &powerState, vm);
+
+    *state = mapPowerState(powerState);
+    if (reason)
+        *reason = 0;
+
+    ret = 0;
+
+cleanup:
+    if (vms)
+        xen_vm_set_free(vms);
+    return ret;
+}
+
 
 /*
  * xenapiDomainSetVcpusFlags
@@ -1813,7 +1861,7 @@ static virDriver xenapiDriver = {
     NULL, /* domainSetBlkioParameters */
     NULL, /* domainGetBlkioParameters */
     xenapiDomainGetInfo, /* domainGetInfo */
-    NULL, /* domainGetState */
+    xenapiDomainGetState, /* domainGetState */
     NULL, /* domainSave */
     NULL, /* domainRestore */
     NULL, /* domainCoreDump */
-- 
1.7.5.rc3




More information about the libvir-list mailing list