On Tue, May 10, 2011 at 03:39:09PM +0200, Jiri Denemark wrote: > 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 */ ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list