]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Bind connection close callback APIs to python binding
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 30 Jul 2012 16:30:42 +0000 (17:30 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 4 Dec 2012 13:50:11 +0000 (13:50 +0000)
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: Daniel P. Berrange <berrange@redhat.com>
examples/domain-events/events-python/event-test.py
python/generator.py
python/libvirt-override-virConnect.py
python/libvirt-override.c

index 9fa0ea675ec044fa5cbfc0080ed00f82254fd01d..3fb046e7a3ee91ba5fcb7445db6abb07b4a1b0da 100644 (file)
@@ -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)
 
 
index c76ff2a5b0170eb6d1a7a8704f2a3047d53fa596..e9b92709f2f53303d3f4ea78401ee291ad5dc5fd 100755 (executable)
@@ -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",
index cb8d892ac8acf79e4a59a300ba8201057a65555d..84d6cc33456b67375b9505f7ca4248cfd73f0319 100644 (file)
             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
index 169df11b34a66bbbfcff10b641fa54e527ce644c..573c0325eb64fa1993bbc43e6e6f9f15e7d26480 100644 (file)
@@ -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},