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

Daniel P. Berrange berrange at redhat.com
Fri May 13 09:54:20 UTC 2011


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 :|




More information about the libvir-list mailing list