提交 7d575e09 编写于 作者: D Daniel P. Berrange

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
上级 84ef5aec
...@@ -1787,6 +1787,55 @@ char *virConnectBaselineCPU(virConnectPtr conn, ...@@ -1787,6 +1787,55 @@ char *virConnectBaselineCPU(virConnectPtr conn,
unsigned int ncpus, unsigned int ncpus,
unsigned int flags); 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 #ifdef __cplusplus
} }
#endif #endif
......
...@@ -271,6 +271,7 @@ skip_impl = ( ...@@ -271,6 +271,7 @@ skip_impl = (
'virConnGetLastError', 'virConnGetLastError',
'virGetLastError', 'virGetLastError',
'virDomainGetInfo', 'virDomainGetInfo',
'virDomainGetJobInfo',
'virNodeGetInfo', 'virNodeGetInfo',
'virDomainGetUUID', 'virDomainGetUUID',
'virDomainGetUUIDString', 'virDomainGetUUIDString',
......
...@@ -48,6 +48,11 @@ ...@@ -48,6 +48,11 @@
<return type='int *' info='the list of information or None in case of error'/> <return type='int *' info='the list of information or None in case of error'/>
<arg name='domain' type='virDomainPtr' info='a domain object'/> <arg name='domain' type='virDomainPtr' info='a domain object'/>
</function> </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'> <function name='virNodeGetInfo' file='python'>
<info>Extract hardware information about the Node.</info> <info>Extract hardware information about the Node.</info>
<return type='int *' info='the list of information or None in case of error'/> <return type='int *' info='the list of information or None in case of error'/>
......
...@@ -2072,6 +2072,41 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, ...@@ -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 * Helper functions to avoid importing modules
* for every callback * for every callback
...@@ -2788,6 +2823,7 @@ static PyMethodDef libvirtMethods[] = { ...@@ -2788,6 +2823,7 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virConnectListInterfaces", libvirt_virConnectListInterfaces, METH_VARARGS, NULL}, {(char *) "virConnectListInterfaces", libvirt_virConnectListInterfaces, METH_VARARGS, NULL},
{(char *) "virConnectListDefinedInterfaces", libvirt_virConnectListDefinedInterfaces, METH_VARARGS, NULL}, {(char *) "virConnectListDefinedInterfaces", libvirt_virConnectListDefinedInterfaces, METH_VARARGS, NULL},
{(char *) "virConnectBaselineCPU", libvirt_virConnectBaselineCPU, METH_VARARGS, NULL}, {(char *) "virConnectBaselineCPU", libvirt_virConnectBaselineCPU, METH_VARARGS, NULL},
{(char *) "virDomainGetJobInfo", libvirt_virDomainGetJobInfo, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
......
...@@ -48,6 +48,14 @@ libvirt_longlongWrap(long long val) ...@@ -48,6 +48,14 @@ libvirt_longlongWrap(long long val)
return (ret); return (ret);
} }
PyObject *
libvirt_ulonglongWrap(unsigned long long val)
{
PyObject *ret;
ret = PyLong_FromUnsignedLongLong(val);
return (ret);
}
PyObject * PyObject *
libvirt_charPtrWrap(char *str) libvirt_charPtrWrap(char *str)
{ {
......
...@@ -138,6 +138,7 @@ PyObject * libvirt_intWrap(int val); ...@@ -138,6 +138,7 @@ PyObject * libvirt_intWrap(int val);
PyObject * libvirt_longWrap(long val); PyObject * libvirt_longWrap(long val);
PyObject * libvirt_ulongWrap(unsigned long val); PyObject * libvirt_ulongWrap(unsigned long val);
PyObject * libvirt_longlongWrap(long long val); PyObject * libvirt_longlongWrap(long long val);
PyObject * libvirt_ulonglongWrap(unsigned long long val);
PyObject * libvirt_charPtrWrap(char *str); PyObject * libvirt_charPtrWrap(char *str);
PyObject * libvirt_constcharPtrWrap(const char *str); PyObject * libvirt_constcharPtrWrap(const char *str);
PyObject * libvirt_charPtrConstWrap(const char *str); PyObject * libvirt_charPtrConstWrap(const char *str);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册