提交 1465876a 编写于 作者: D Daniel P. Berrange

Bind connection close callback APIs to python binding

Add code in the python binding to cope with the new APIs
virConnectRegisterCloseCallback and
virConnectUnregisterCloseCallback. Also demonstrate their
use in the python domain events demo
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 b88b1717
......@@ -495,6 +495,16 @@ def myDomainEventBalloonChangeCallback(conn, dom, utcoffset, actual):
def myDomainEventPMSuspendDiskCallback(conn, dom, reason, opaque):
print "myDomainEventPMSuspendDiskCallback: Domain %s(%s) system pmsuspend_disk" % (
dom.name(), dom.ID())
run = True
def myConnectionCloseCallback(conn, reason, opaque):
reasonStrings = (
"Error", "End-of-file", "Keepalive", "Client",
)
print "myConnectionCloseCallback: %s: %s" % (conn.getURI(), reasonStrings[reason])
run = False
def usage(out=sys.stderr):
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]"
print >>out, " uri will default to qemu:///system"
......@@ -544,6 +554,8 @@ def main():
if (old_exitfunc): old_exitfunc()
sys.exitfunc = exit
vc.registerCloseCallback(myConnectionCloseCallback, None)
#Add 2 callbacks to prove this works with more than just one
vc.domainEventRegister(myDomainEventCallback1,None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2, None)
......@@ -565,7 +577,7 @@ def main():
# of demo we'll just go to sleep. The other option is to
# run the event loop in your main thread if your app is
# totally event based.
while vc.isAlive() == 1:
while run:
time.sleep(1)
......
......@@ -425,8 +425,6 @@ skip_impl = (
'virDomainGetInterfaceParameters',
'virDomainGetCPUStats',
'virDomainGetDiskErrors',
'virConnectUnregisterCloseCallback',
'virConnectRegisterCloseCallback',
'virNodeGetMemoryParameters',
'virNodeSetMemoryParameters',
'virNodeGetCPUMap',
......@@ -476,6 +474,9 @@ skip_function = (
'virStreamRecv', # overridden in libvirt-override-virStream.py
'virStreamSend', # overridden in libvirt-override-virStream.py
'virConnectUnregisterCloseCallback', # overriden in virConnect.py
'virConnectRegisterCloseCallback', # overriden in virConnect.py
# 'Ref' functions have no use for bindings users.
"virConnectRef",
"virDomainRef",
......
......@@ -287,3 +287,26 @@
retlist.append(virSecret(self, _obj=secret_ptr))
return retlist
def _dispatchCloseCallback(self, reason, cbData):
"""Dispatches events to python user close callback"""
cb = cbData["cb"]
opaque = cbData["opaque"]
cb(self, reason, opaque)
return 0
def unregisterCloseCallback(self):
"""Removes a close event callback"""
ret = libvirtmod.virConnectUnregisterCloseCallback(self._o)
if ret == -1: raise libvirtError ('virConnectUnregisterCloseCallback() failed', conn=self)
def registerCloseCallback(self, cb, opaque):
"""Adds a close event callback, providing a notification
when a connection fails / closes"""
cbData = { "cb": cb, "conn": self, "opaque": opaque }
ret = libvirtmod.virConnectRegisterCloseCallback(self._o, cbData)
if ret == -1:
raise libvirtError ('virConnectRegisterCloseCallback() failed', conn=self)
return ret
......@@ -6001,6 +6001,111 @@ libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self,
return py_retval;
}
static void
libvirt_virConnectCloseCallbackDispatch(virConnectPtr conn ATTRIBUTE_UNUSED,
int reason,
void *opaque)
{
PyObject *pyobj_cbData = (PyObject*)opaque;
PyObject *pyobj_ret;
PyObject *pyobj_conn;
PyObject *dictKey;
LIBVIRT_ENSURE_THREAD_STATE;
Py_INCREF(pyobj_cbData);
dictKey = libvirt_constcharPtrWrap("conn");
pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
Py_DECREF(dictKey);
/* Call the Callback Dispatcher */
pyobj_ret = PyObject_CallMethod(pyobj_conn,
(char*)"_dispatchCloseCallback",
(char*)"iO",
reason,
pyobj_cbData);
Py_DECREF(pyobj_cbData);
if(!pyobj_ret) {
DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
PyErr_Print();
} else {
Py_DECREF(pyobj_ret);
}
LIBVIRT_RELEASE_THREAD_STATE;
}
static PyObject *
libvirt_virConnectRegisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
{
PyObject *py_retval; /* return value */
PyObject *pyobj_conn; /* virConnectPtr */
PyObject *pyobj_cbData; /* hash of callback data */
virConnectPtr conn;
int ret = 0;
if (!PyArg_ParseTuple
(args, (char *) "OO:virConnectRegisterCloseCallback",
&pyobj_conn, &pyobj_cbData)) {
DEBUG("%s failed parsing tuple\n", __FUNCTION__);
return VIR_PY_INT_FAIL;
}
DEBUG("libvirt_virConnectRegisterCloseCallback(%p %p) called\n",
pyobj_conn, pyobj_cbData);
conn = PyvirConnect_Get(pyobj_conn);
Py_INCREF(pyobj_cbData);
LIBVIRT_BEGIN_ALLOW_THREADS;
ret = virConnectRegisterCloseCallback(conn,
libvirt_virConnectCloseCallbackDispatch,
pyobj_cbData,
libvirt_virConnectDomainEventFreeFunc);
LIBVIRT_END_ALLOW_THREADS;
if (ret < 0) {
Py_DECREF(pyobj_cbData);
}
py_retval = libvirt_intWrap(ret);
return py_retval;
}
static PyObject *
libvirt_virConnectUnregisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
{
PyObject *py_retval;
PyObject *pyobj_conn;
virConnectPtr conn;
int ret = 0;
if (!PyArg_ParseTuple
(args, (char *) "O:virConnectDomainEventUnregister",
&pyobj_conn))
return NULL;
DEBUG("libvirt_virConnectDomainEventUnregister(%p) called\n",
pyobj_conn);
conn = PyvirConnect_Get(pyobj_conn);
LIBVIRT_BEGIN_ALLOW_THREADS;
ret = virConnectUnregisterCloseCallback(conn,
libvirt_virConnectCloseCallbackDispatch);
LIBVIRT_END_ALLOW_THREADS;
py_retval = libvirt_intWrap(ret);
return py_retval;
}
static void
libvirt_virStreamEventFreeFunc(void *opaque)
{
......@@ -6502,6 +6607,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL},
{(char *) "virConnectRegisterCloseCallback", libvirt_virConnectRegisterCloseCallback, METH_VARARGS, NULL},
{(char *) "virConnectUnregisterCloseCallback", libvirt_virConnectUnregisterCloseCallback, METH_VARARGS, NULL},
{(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL},
{(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL},
{(char *) "virStreamSend", libvirt_virStreamSend, METH_VARARGS, NULL},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册