The API can be used to query current state of an interface to VMM used to control a domain. In QEMU world this translates into monitor connection. --- Notes: Version 2: - really implement python binding include/libvirt/libvirt.h.in | 40 ++++++++++++++++++++++++++++++++ python/generator.py | 1 + python/libvirt-override-api.xml | 6 +++++ python/libvirt-override.c | 27 ++++++++++++++++++++++ src/driver.h | 5 ++++ src/libvirt.c | 48 +++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 7 files changed, 132 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index df213f1..1454ca0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -141,6 +141,43 @@ typedef enum { VIR_DOMAIN_CRASHED_UNKNOWN = 0, /* crashed for unknown reason */ } virDomainCrashedReason; + +/** + * virDomainControlState: + * + * Current state of a control interface to the domain. + */ +typedef enum { + VIR_DOMAIN_CONTROL_OK = 0, /* operational, ready to accept commands */ + VIR_DOMAIN_CONTROL_JOB = 1, /* background job is running (can be + monitored by virDomainGetJobInfo); only + limited set of commands may be allowed */ + VIR_DOMAIN_CONTROL_OCCUPIED = 2, /* occupied by a running command */ + VIR_DOMAIN_CONTROL_ERROR = 3, /* unusable, domain cannot be fully operated */ +} virDomainControlState; + +/** + * virDomainControlInfo: + * + * Structure filled in by virDomainGetControlInfo and providing details about + * current state of control interface to a domain. + */ +typedef struct _virDomainControlInfo virDomainControlInfo; +struct _virDomainControlInfo { + unsigned int state; /* control state, one of virDomainControlState */ + unsigned int details; /* state details, currently 0 */ + unsigned long long stateTime; /* for how long (in msec) control interface + has been in current state (except for OK + and ERROR states) */ +}; + +/** + * virDomainControlInfoPtr: + * + * Pointer to virDomainControlInfo structure. + */ +typedef virDomainControlInfo *virDomainControlInfoPtr; + /** * virDomainModificationImpact: * @@ -781,6 +818,9 @@ int virDomainGetState (virDomainPtr domain, int *state, int *reason, unsigned int flags); +int virDomainGetControlInfo (virDomainPtr domain, + virDomainControlInfoPtr info, + unsigned int flags); /* * Return scheduler type in effect 'sedf', 'credit', 'linux' diff --git a/python/generator.py b/python/generator.py index 7c38fdd..4e3e9fa 100755 --- a/python/generator.py +++ b/python/generator.py @@ -306,6 +306,7 @@ skip_impl = ( 'virGetLastError', 'virDomainGetInfo', 'virDomainGetState', + 'virDomainGetControlInfo', 'virDomainGetBlockInfo', 'virDomainGetJobInfo', 'virNodeGetInfo', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index ec08e69..01207d6 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -54,6 +54,12 @@ <arg name='domain' type='virDomainPtr' info='a domain object'/> <arg name='flags' type='unsigned int' info='additional flags'/> </function> + <function name='virDomainGetControlInfo' file='python'> + <info>Extract details about current state of control interface to 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'/> + <arg name='flags' type='unsigned int' info='additional flags'/> + </function> <function name='virDomainGetBlockInfo' file='python'> <info>Extract information about a domain block device size</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 974decb..c6a1d4f 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -1100,6 +1100,32 @@ libvirt_virDomainGetState(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) } static PyObject * +libvirt_virDomainGetControlInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + virDomainPtr domain; + PyObject *pyobj_domain; + virDomainControlInfo info; + unsigned int flags; + + if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetControlInfo", + &pyobj_domain, &flags)) + return NULL; + domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virDomainGetControlInfo(domain, &info, flags); + LIBVIRT_END_ALLOW_THREADS; + if (c_retval < 0) + return VIR_PY_NONE; + py_retval = PyList_New(3); + PyList_SetItem(py_retval, 0, libvirt_intWrap(info.state)); + PyList_SetItem(py_retval, 1, libvirt_intWrap(info.details)); + PyList_SetItem(py_retval, 2, libvirt_longlongWrap(info.stateTime)); + return py_retval; +} + +static PyObject * libvirt_virDomainGetBlockInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; int c_retval; @@ -3555,6 +3581,7 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL}, {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetState", libvirt_virDomainGetState, METH_VARARGS, NULL}, + {(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetBlockInfo", libvirt_virDomainGetBlockInfo, METH_VARARGS, NULL}, {(char *) "virNodeGetInfo", libvirt_virNodeGetInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL}, diff --git a/src/driver.h b/src/driver.h index 5df798a..ca49b08 100644 --- a/src/driver.h +++ b/src/driver.h @@ -171,6 +171,10 @@ typedef int int *reason, unsigned int flags); typedef int + (*virDrvDomainGetControlInfo) (virDomainPtr domain, + virDomainControlInfoPtr info, + unsigned int flags); +typedef int (*virDrvDomainSave) (virDomainPtr domain, const char *to); typedef int @@ -663,6 +667,7 @@ struct _virDriver { virDrvDomainGetBlkioParameters domainGetBlkioParameters; virDrvDomainGetInfo domainGetInfo; virDrvDomainGetState domainGetState; + virDrvDomainGetControlInfo domainGetControlInfo; virDrvDomainSave domainSave; virDrvDomainRestore domainRestore; virDrvDomainCoreDump domainCoreDump; diff --git a/src/libvirt.c b/src/libvirt.c index 997d4a2..83adf33 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3274,6 +3274,54 @@ error: } /** + * virDomainGetControlInfo: + * @domain: a domain object + * @info: pointer to a virDomainControlInfo structure allocated by the user + * @flags: additional flags, 0 for now + * + * Extract details about current state of control interface to a domain. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainGetControlInfo(virDomainPtr domain, + virDomainControlInfoPtr info, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "info=%p", info); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (!info) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + conn = domain->conn; + if (conn->driver->domainGetControlInfo) { + int ret; + ret = conn->driver->domainGetControlInfo(domain, info, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainGetXMLDesc: * @domain: a domain object * @flags: an OR'ed set of virDomainXMLFlags diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 4d4299a..0e55097 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -450,4 +450,9 @@ LIBVIRT_0.9.2 { virInterfaceChangeRollback; } LIBVIRT_0.9.0; +LIBVIRT_0.9.3 { + global: + virDomainGetControlInfo; +} LIBVIRT_0.9.2; + # .... define new API here using predicted next version number .... -- 1.7.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list