Reason is currently always set to 0 (i.e., *_UNKNOWN).
---
src/esx/esx_driver.c | 54 ++++++++++++++++++++++++-
src/libxl/libxl_driver.c | 31 +++++++++++++-
src/lxc/lxc_driver.c | 33 ++++++++++++++-
src/openvz/openvz_driver.c | 32 ++++++++++++++-
src/phyp/phyp_driver.c | 12 +++++-
src/qemu/qemu_driver.c | 33 ++++++++++++++-
src/test/test_driver.c | 31 +++++++++++++-
src/uml/uml_driver.c | 32 ++++++++++++++-
src/vbox/vbox_tmpl.c | 56 +++++++++++++++++++++++++-
src/vmware/vmware_driver.c | 31 +++++++++++++-
src/xen/xen_driver.c | 18 ++++++++-
src/xen/xen_hypervisor.c | 34 +++++++++++++++-
src/xen/xen_hypervisor.h | 4 ++
src/xen/xend_internal.c | 97 ++++++++++++++++++++++++++++++++-----------
src/xen/xend_internal.h | 1 +
src/xen/xm_internal.c | 19 ++++++++-
src/xen/xm_internal.h | 1 +
src/xen/xs_internal.c | 32 ++++++++++++++-
src/xen/xs_internal.h | 3 +
src/xenapi/xenapi_driver.c | 45 ++++++++++++++++++++-
20 files changed, 559 insertions(+), 40 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 543ebe6..94b0121 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2425,6 +2425,58 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
static int
+esxDomainGetState(virDomainPtr domain, int *state, int *reason)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_VirtualMachinePowerState powerState;
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueListToList(&propertyNameList,
+ "runtime.powerState\0") < 0 ||
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+ propertyNameList, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ *state = VIR_DOMAIN_NOSTATE;
+ if (reason)
+ *reason = 0;
+
+ for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "runtime.powerState")) {
+ if (esxVI_VirtualMachinePowerState_CastFromAnyType
+ (dynamicProperty->val, &powerState) < 0) {
+ goto cleanup;
+ }
+
+ *state = esxVI_VirtualMachinePowerState_ConvertToLibvirt
+ (powerState);
+ } else {
+ VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+
+ return result;
+}
+
+
+
+static int
esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
unsigned int flags)
{
@@ -4596,7 +4648,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 db6f99c..7d62ed5 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1566,6 +1566,35 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
}
static int
+libxlDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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)
{
@@ -2672,7 +2701,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 bc96ed4..ccedfe3 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -564,6 +564,37 @@ cleanup:
return ret;
}
+static int
+lxcDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ lxc_driver_t *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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;
@@ -2830,7 +2861,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 268e752..0e774d9 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -377,6 +377,36 @@ cleanup:
}
+static int
+openvzDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ struct openvz_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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 +1621,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 fb365ba..18331cd 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -3471,6 +3471,16 @@ phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
}
static int
+phypDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ *state = phypGetLparState(dom->conn, dom->id);
+ if (reason)
+ *reason = 0;
+
+ return 0;
+}
+
+static int
phypDomainDestroy(virDomainPtr dom)
{
int result = -1;
@@ -3752,7 +3762,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 549cb2f..1fc4a22 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1783,6 +1783,37 @@ cleanup:
return ret;
}
+static int
+qemuDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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
@@ -7140,7 +7171,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..1641747 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1704,6 +1704,35 @@ cleanup:
return ret;
}
+static int
+testDomainGetState(virDomainPtr domain, int *state, int *reason)
+{
+ testConnPtr privconn = domain->conn->privateData;
+ virDomainObjPtr privdom;
+ int ret = -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 +5400,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..cd659db 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1522,6 +1522,36 @@ cleanup:
}
+static int
+umlDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ struct uml_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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 +2207,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..26860c8 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -1909,6 +1909,60 @@ cleanup:
return ret;
}
+static int
+vboxDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ VBOX_OBJECT_CHECK(dom->conn, int, -1);
+ vboxIID domiid = VBOX_IID_INITIALIZER;
+ IMachine *machine = NULL;
+ PRUint32 mstate = MachineState_Null;
+ nsresult rc;
+
+ 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 +8620,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..9b22d4a 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -896,6 +896,35 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
return ret;
}
+static int
+vmwareDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ struct vmware_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -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 +960,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..bdf70ad 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1010,6 +1010,22 @@ xenUnifiedDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
}
static int
+xenUnifiedDomainGetState(virDomainPtr dom, int *state, int *reason)
+{
+ GET_PRIVATE(dom->conn);
+ int i;
+
+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) {
+ if (priv->opened[i] &&
+ drivers[i]->domainGetState &&
+ drivers[i]->domainGetState(dom, state, reason) == 0)
+ return 0;
+ }
+
+ return -1;
+}
+
+static int
xenUnifiedDomainSave (virDomainPtr dom, const char *to)
{
GET_PRIVATE(dom->conn);
@@ -2132,7 +2148,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 f5218bc..98ff157 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -821,7 +821,7 @@ struct xenUnifiedDriver xenHypervisorDriver = {
xenHypervisorSetMaxMemory, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
xenHypervisorGetDomainInfo, /* domainGetInfo */
- NULL, /* domainGetState */
+ xenHypervisorGetDomainState, /* domainGetState */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
@@ -3239,6 +3239,38 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr
info)
}
/**
+ * xenHypervisorGetDomainState:
+ * @domain: pointer to the domain block
+ * @state: returned state of the domain
+ * @reason: returned reason for the state
+ *
+ * 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)
+{
+ 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..e6b86b5 100644
--- a/src/xen/xen_hypervisor.h
+++ b/src/xen/xen_hypervisor.h
@@ -66,6 +66,10 @@ int xenHypervisorPauseDomain (virDomainPtr domain)
int xenHypervisorGetDomainInfo (virDomainPtr domain,
virDomainInfoPtr info)
ATTRIBUTE_NONNULL (1);
+int xenHypervisorGetDomainState (virDomainPtr domain,
+ int *state,
+ int *reason)
+ 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 1fbb8e6..789af83 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,38 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
/**
+ * xenDaemonDomainGetState:
+ * @domain: a domain object
+ * @state: returned domain's state
+ * @reason: returned reason for the state
+ *
+ * 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)
+{
+ 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
@@ -3861,7 +3908,7 @@ struct xenUnifiedDriver xenDaemonDriver = {
xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */
xenDaemonDomainSetMemory, /* domainMaxMemory */
xenDaemonDomainGetInfo, /* domainGetInfo */
- NULL, /* domainGetState */
+ xenDaemonDomainGetState, /* domainGetState */
xenDaemonDomainSave, /* domainSave */
xenDaemonDomainRestore, /* domainRestore */
xenDaemonDomainCoreDump, /* domainCoreDump */
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index 805cf91..087ce08 100644
--- a/src/xen/xend_internal.h
+++ b/src/xen/xend_internal.h
@@ -110,6 +110,7 @@ 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);
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 06334a4..47a2c46 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -100,7 +100,7 @@ struct xenUnifiedDriver xenXMDriver = {
xenXMDomainSetMaxMemory, /* domainSetMaxMemory */
xenXMDomainSetMemory, /* domainMaxMemory */
xenXMDomainGetInfo, /* domainGetInfo */
- NULL, /* domainGetState */
+ xenXMDomainGetState, /* domainGetState */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
@@ -470,6 +470,23 @@ int xenXMClose(virConnectPtr conn) {
}
/*
+ * Since these are all offline domains, the state is always SHUTOFF.
+ */
+int
+xenXMDomainGetState(virDomainPtr domain, int *state, int *reason)
+{
+ 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..a289d5b 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -40,6 +40,7 @@ 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);
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 127161c..d834d76 100644
--- a/src/xen/xs_internal.c
+++ b/src/xen/xs_internal.c
@@ -62,7 +62,7 @@ struct xenUnifiedDriver xenStoreDriver = {
NULL, /* domainSetMaxMemory */
xenStoreDomainSetMemory, /* domainSetMemory */
xenStoreGetDomainInfo, /* domainGetInfo */
- NULL, /* domainGetState */
+ xenStoreDomainGetState, /* domainGetState */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
@@ -450,6 +450,36 @@ xenStoreGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
}
/**
+ * xenStoreDomainGetState:
+ * @domain: pointer to the domain block
+ * @state: returned domain's state
+ * @reason: returned state reason
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
+int
+xenStoreDomainGetState(virDomainPtr domain, int *state, int *reason)
+{
+ 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..5c9fce4 100644
--- a/src/xen/xs_internal.h
+++ b/src/xen/xs_internal.h
@@ -23,6 +23,9 @@ virDrvOpenStatus xenStoreOpen (virConnectPtr conn,
int xenStoreClose (virConnectPtr conn);
int xenStoreGetDomainInfo (virDomainPtr domain,
virDomainInfoPtr info);
+int xenStoreDomainGetState (virDomainPtr domain,
+ int *state,
+ int *reason);
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..f863a54 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -994,6 +994,49 @@ 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)
+{
+ 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;
+
+ 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 +1856,7 @@ static virDriver xenapiDriver = {
NULL, /* domainSetBlkioParameters */
NULL, /* domainGetBlkioParameters */
xenapiDomainGetInfo, /* domainGetInfo */
- NULL, /* domainGetState */
+ xenapiDomainGetState, /* domainGetState */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
--
1.7.5.rc3