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