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