[prev in list] [next in list] [prev in thread] [next in thread] 

List:       libvir-list
Subject:    Re: [libvirt] [PATCH 1/9] Introduce public API for domain async job handling
From:       Daniel Veillard <veillard () redhat ! com>
Date:       2010-02-26 17:40:10
Message-ID: 20100226174010.GI5281 () redhat ! com
[Download RAW message or body]

On Thu, Feb 18, 2010 at 03:56:07PM +0000, Daniel P. Berrange wrote:
> Introduce a new public API that provides a way to get progress
> info on currently running jobs on a virDomainpPtr. APIs that
> are initially within scope of this idea are
> 
> virDomainMigrate
> virDomainMigrateToURI
> virDomainSave
> virDomainRestore
> virDomainCoreDump
> 
> These all take a potentially long time and benefit from monitoring.
> The virDomainJobInfo struct allows for various pieces of information
> to be reported
> 
> - Percentage completion
> - Time
> - Overall data
> - Guest memory data
> - Guest disk/file data
> 
> * include/libvirt/libvirt.h.in: Add virDomainGetJobInfo
> * python/generator.py, python/libvirt-override-api.xml,
> python/libvirt-override.c: Override for virDomainGetJobInfo API
> * python/typewrappers.c, python/typewrappers.h: Introduce wrapper
> for unsigned long long type
> ---
> include/libvirt/libvirt.h.in    |   49 +++++++++++++++++++++++++++++++++++++++
> python/generator.py             |    1 +
> python/libvirt-override-api.xml |    5 ++++
> python/libvirt-override.c       |   36 ++++++++++++++++++++++++++++
> python/typewrappers.c           |    8 ++++++
> python/typewrappers.h           |    1 +
> 6 files changed, 100 insertions(+), 0 deletions(-)
> 
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 260505e..51c0844 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -1787,6 +1787,55 @@ char *virConnectBaselineCPU(virConnectPtr conn,
> unsigned int ncpus,
> unsigned int flags);
> 
> +typedef enum {
> +    VIR_DOMAIN_JOB_NONE      = 0, /* No job is active */
> +    VIR_DOMAIN_JOB_BOUNDED   = 1, /* Job with a finite completion time */
> +    VIR_DOMAIN_JOB_UNBOUNDED = 2, /* Job without a finite completion time */
> +    VIR_DOMAIN_JOB_COMPLETED = 3, /* Job has finished, but isn't cleaned up */
> +    VIR_DOMAIN_JOB_FAILED    = 4, /* Job hit error, but isn't cleaned up */


  5 disapeared ?

> +    VIR_DOMAIN_JOB_CANCELLED = 6, /* Job was aborted, but isn't cleaned up */
> +} virDomainJobType;
> +
> +typedef struct _virDomainJobInfo virDomainJobInfo;
> +typedef virDomainJobInfo *virDomainJobInfoPtr;
> +struct _virDomainJobInfo {
> +    /* One of virDomainJobType */
> +    int type;
> +
> +    /* Time is measured in seconds */
> +    unsigned long long timeElapsed;    /* Always set */
> +    unsigned long long timeRemaining;  /* Only for VIR_DOMAIN_JOB_BOUNDED */
> +
> +    /* Data is measured in bytes unless otherwise specified
> +     * and is measuring the job as a whole
> +     *
> +     * For VIR_DOMAIN_JOB_UNBOUNDED, dataTotal may be less
> +     * than the final sum of dataProcessed + dataRemaining
> +     * in the event that the hypervisor has to repeat some
> +     * data eg due to dirtied pages during migration
> +     *
> +     * For VIR_DOMAIN_JOB_BOUNDED, dataTotal shall always
> +     * equal sum of dataProcessed + dataRemaining
> +     */
> +    unsigned long long dataTotal;
> +    unsigned long long dataProcessed;
> +    unsigned long long dataRemaining;
> +
> +    /* As above, but only tracking guest memory progress */
> +    unsigned long long memTotal;
> +    unsigned long long memProcessed;
> +    unsigned long long memRemaining;
> +
> +    /* As above, but only tracking guest disk file progress */
> +    unsigned long long fileTotal;
> +    unsigned long long fileProcessed;
> +    unsigned long long fileRemaining;
> +};

  I wonder if we should not somehow provide an unit for the items being
measured. Maybe we don't want bytes in the future

> +int virDomainGetJobInfo(virDomainPtr dom,
> +                        virDomainJobInfoPtr info);
> +
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/python/generator.py b/python/generator.py
> index 24eaf50..f7625fd 100755
> --- a/python/generator.py
> +++ b/python/generator.py
> @@ -271,6 +271,7 @@ skip_impl = (
> 'virConnGetLastError',
> 'virGetLastError',
> 'virDomainGetInfo',
> +    'virDomainGetJobInfo',
> 'virNodeGetInfo',
> 'virDomainGetUUID',
> 'virDomainGetUUIDString',
> diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
> index 76a6fd5..1260c0c 100644
> --- a/python/libvirt-override-api.xml
> +++ b/python/libvirt-override-api.xml
> @@ -48,6 +48,11 @@
> <return type='int *' info='the list of information or None in case of error'/>
> <arg name='domain' type='virDomainPtr' info='a domain object'/>
> </function>
> +    <function name='virDomainGetJobInfo' file='python'>
> +      <info>Extract information about an active job being processed for a \
> domain.</info> +      <return type='int *' info='the list of information or None in \
> case of error'/> +      <arg name='domain' type='virDomainPtr' info='a domain \
> object'/> +    </function>
> <function name='virNodeGetInfo' file='python'>
> <info>Extract hardware information about the Node.</info>
> <return type='int *' info='the list of information or None in case of error'/>
> diff --git a/python/libvirt-override.c b/python/libvirt-override.c
> index 2447ad7..e27bce6 100644
> --- a/python/libvirt-override.c
> +++ b/python/libvirt-override.c
> @@ -2072,6 +2072,41 @@ libvirt_virConnectBaselineCPU(PyObject *self \
> ATTRIBUTE_UNUSED, }
> 
> 
> +static PyObject *
> +libvirt_virDomainGetJobInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
> +    PyObject *py_retval;
> +    int c_retval;
> +    virDomainPtr domain;
> +    PyObject *pyobj_domain;
> +    virDomainJobInfo info;
> +
> +    if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetJobInfo", &pyobj_domain))
> +        return(NULL);
> +    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
> +
> +    LIBVIRT_BEGIN_ALLOW_THREADS;
> +    c_retval = virDomainGetJobInfo(domain, &info);
> +    LIBVIRT_END_ALLOW_THREADS;
> +    if (c_retval < 0)
> +        return VIR_PY_NONE;
> +    py_retval = PyList_New(12);
> +    PyList_SetItem(py_retval, 0, libvirt_intWrap((int) info.type));
> +    PyList_SetItem(py_retval, 1, libvirt_ulonglongWrap(info.timeElapsed));
> +    PyList_SetItem(py_retval, 2, libvirt_ulonglongWrap(info.timeRemaining));
> +    PyList_SetItem(py_retval, 3, libvirt_ulonglongWrap(info.dataTotal));
> +    PyList_SetItem(py_retval, 4, libvirt_ulonglongWrap(info.dataProcessed));
> +    PyList_SetItem(py_retval, 5, libvirt_ulonglongWrap(info.dataRemaining));
> +    PyList_SetItem(py_retval, 6, libvirt_ulonglongWrap(info.memTotal));
> +    PyList_SetItem(py_retval, 7, libvirt_ulonglongWrap(info.memProcessed));
> +    PyList_SetItem(py_retval, 8, libvirt_ulonglongWrap(info.memRemaining));
> +    PyList_SetItem(py_retval, 9, libvirt_ulonglongWrap(info.fileTotal));
> +    PyList_SetItem(py_retval, 10, libvirt_ulonglongWrap(info.fileProcessed));
> +    PyList_SetItem(py_retval, 11, libvirt_ulonglongWrap(info.fileRemaining));
> +
> +    return(py_retval);
> +}
> +
> +
> /*******************************************
> * Helper functions to avoid importing modules
> * for every callback
> @@ -2788,6 +2823,7 @@ static PyMethodDef libvirtMethods[] = {
> {(char *) "virConnectListInterfaces", libvirt_virConnectListInterfaces, \
> METH_VARARGS, NULL}, {(char *) "virConnectListDefinedInterfaces", \
> libvirt_virConnectListDefinedInterfaces, METH_VARARGS, NULL}, {(char *) \
> "virConnectBaselineCPU", libvirt_virConnectBaselineCPU, METH_VARARGS, NULL}, +    \
> {(char *) "virDomainGetJobInfo", libvirt_virDomainGetJobInfo, METH_VARARGS, NULL}, \
> {NULL, NULL, 0, NULL} };
> 
> diff --git a/python/typewrappers.c b/python/typewrappers.c
> index 9ba99de..b33822c 100644
> --- a/python/typewrappers.c
> +++ b/python/typewrappers.c
> @@ -49,6 +49,14 @@ libvirt_longlongWrap(long long val)
> }
> 
> PyObject *
> +libvirt_ulonglongWrap(unsigned long long val)
> +{
> +    PyObject *ret;
> +    ret = PyLong_FromUnsignedLongLong(val);
> +    return (ret);
> +}
> +
> +PyObject *
> libvirt_charPtrWrap(char *str)
> {
> PyObject *ret;
> diff --git a/python/typewrappers.h b/python/typewrappers.h
> index 61f7249..dadcdd4 100644
> --- a/python/typewrappers.h
> +++ b/python/typewrappers.h
> @@ -138,6 +138,7 @@ PyObject * libvirt_intWrap(int val);
> PyObject * libvirt_longWrap(long val);
> PyObject * libvirt_ulongWrap(unsigned long val);
> PyObject * libvirt_longlongWrap(long long val);
> +PyObject * libvirt_ulonglongWrap(unsigned long long val);
> PyObject * libvirt_charPtrWrap(char *str);
> PyObject * libvirt_constcharPtrWrap(const char *str);
> PyObject * libvirt_charPtrConstWrap(const char *str);

  The unit is more a question, I don't see an use right now, but
it sounds like it can make the API more flexible if we want to use
it for "something else"

  Basically looks fine ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic