mirror of https://gitee.com/openkylin/libvirt.git
Introduce public API for domain async job handling
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
This commit is contained in:
parent
84ef5aecca
commit
7d575e09e2
|
@ -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 */
|
||||
VIR_DOMAIN_JOB_CANCELLED = 5, /* 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 mill-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;
|
||||
};
|
||||
|
||||
int virDomainGetJobInfo(virDomainPtr dom,
|
||||
virDomainJobInfoPtr info);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -271,6 +271,7 @@ skip_impl = (
|
|||
'virConnGetLastError',
|
||||
'virGetLastError',
|
||||
'virDomainGetInfo',
|
||||
'virDomainGetJobInfo',
|
||||
'virNodeGetInfo',
|
||||
'virDomainGetUUID',
|
||||
'virDomainGetUUIDString',
|
||||
|
|
|
@ -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'/>
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@ libvirt_longlongWrap(long long val)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
libvirt_ulonglongWrap(unsigned long long val)
|
||||
{
|
||||
PyObject *ret;
|
||||
ret = PyLong_FromUnsignedLongLong(val);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
libvirt_charPtrWrap(char *str)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue