[libvirt] [PATCH 4/4] add a qemu-specific event register python binding API

shaohef at linux.vnet.ibm.com shaohef at linux.vnet.ibm.com
Fri Dec 16 16:59:01 UTC 2011


From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>


Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
---
 python/generator.py             |   28 +++++----
 python/libvirt-qemu-override.c  |  140 +++++++++++++++++++++++++++++++++++++++
 python/libvirt-qemu-override.py |   55 +++++++++++++++
 python/libvirt_qemu.py          |  105 +++++++++++++++++++++++++++++
 4 files changed, 316 insertions(+), 12 deletions(-)
 create mode 100644 python/libvirt-qemu-override.py
 create mode 100644 python/libvirt_qemu.py

diff --git a/python/generator.py b/python/generator.py
index 1657f4f..9a4cf83 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -234,6 +234,7 @@ skipped_types = {
 #    'int *': "usually a return type",
      'virConnectDomainEventCallback': "No function types in python",
      'virConnectDomainEventGenericCallback': "No function types in python",
+     'virConnectDomainQemuEventCallback': "No function types in python",
      'virConnectDomainEventRTCChangeCallback': "No function types in python",
      'virConnectDomainEventWatchdogCallback': "No function types in python",
      'virConnectDomainEventIOErrorCallback': "No function types in python",
@@ -477,6 +478,9 @@ skip_function = (
 
 qemu_skip_function = (
     #"virDomainQemuAttach",
+    'virConnectDomainQemuEventCallback',   # overridden in libvirt_qemu_override.py
+    'virConnectDomainQemuEventRegister',   # overridden in libvirt_qemu_override.py
+    'virConnectDomainQemuEventDeregister', # overridden in libvirt_qemu_override.py
 )
 
 # Generate C code, but skip python impl
@@ -1657,17 +1661,18 @@ def qemuBuildWrappers(module):
     if extra != None:
         extra.close()
 
-    fd.write("try:\n")
-    fd.write("    import libvirtmod_qemu\n")
-    fd.write("except ImportError, lib_e:\n")
-    fd.write("    try:\n")
-    fd.write("        import cygvirtmod_qemu as libvirtmod_qemu\n")
-    fd.write("    except ImportError, cyg_e:\n")
-    fd.write("        if str(cyg_e).count(\"No module named\"):\n")
-    fd.write("            raise lib_e\n\n")
-
-    fd.write("import libvirt\n\n");
-    fd.write("#\n# Functions from module %s\n#\n\n" % module)
+    if extra == None:
+        fd.write("try:\n")
+        fd.write("    import libvirtmod_qemu\n")
+        fd.write("except ImportError, lib_e:\n")
+        fd.write("    try:\n")
+        fd.write("        import cygvirtmod_qemu as libvirtmod_qemu\n")
+        fd.write("    except ImportError, cyg_e:\n")
+        fd.write("        if str(cyg_e).count(\"No module named\"):\n")
+        fd.write("            raise lib_e\n\n")
+
+        fd.write("import libvirt\n\n");
+        fd.write("#\n# Functions from module %s\n#\n\n" % module)
     #
     # Generate functions directly, no classes
     #
@@ -1727,7 +1732,6 @@ def qemuBuildWrappers(module):
         items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
         for name,value in items:
             fd.write("%s = %s\n" % (name,value))
-        fd.write("\n");
 
     fd.close()
 
diff --git a/python/libvirt-qemu-override.c b/python/libvirt-qemu-override.c
index 485c809..f5a8c09 100644
--- a/python/libvirt-qemu-override.c
+++ b/python/libvirt-qemu-override.c
@@ -18,6 +18,7 @@
 
 #include <Python.h>
 #include "libvirt/libvirt-qemu.h"
+#include "libvirt/libvirt.h"
 #include "libvirt/virterror.h"
 #include "typewrappers.h"
 #include "libvirt-qemu.h"
@@ -96,6 +97,143 @@ libvirt_qemu_virDomainQemuMonitorCommand(PyObject *self ATTRIBUTE_UNUSED,
     return(py_retval);
 }
 
+static void
+libvirt_qemu_virConnectDomainEventFreeFunc(void *opaque)
+{
+    PyObject *pyobj_conn = (PyObject*)opaque;
+    LIBVIRT_ENSURE_THREAD_STATE;
+    Py_DECREF(pyobj_conn);
+    LIBVIRT_RELEASE_THREAD_STATE;
+}
+
+static int
+libvirt_qemu_virConnectDomainEventUnknownCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                                  virDomainPtr dom,
+                                                  const char *eventName,
+                                                  const char *eventArgs,
+                                                  void *opaque)
+{
+    PyObject *pyobj_cbData = (PyObject*)opaque;
+    PyObject *pyobj_dom;
+    PyObject *pyobj_ret;
+    PyObject *pyobj_conn;
+    PyObject *dictKey;
+    int ret = -1;
+
+    LIBVIRT_ENSURE_THREAD_STATE;
+
+    /* Create a python instance of this virDomainPtr */
+    virDomainRef(dom);
+    pyobj_dom = libvirt_virDomainPtrWrap(dom);
+    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*)"_dispatchDomainEventUnknownCallback",
+                                    (char*)"OssO",
+                                    pyobj_dom, eventName, eventArgs, pyobj_cbData);
+
+    Py_DECREF(pyobj_cbData);
+    Py_DECREF(pyobj_dom);
+
+    if (!pyobj_ret) {
+#if DEBUG_ERROR
+        printf("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+#endif
+        PyErr_Print();
+    } else {
+        Py_DECREF(pyobj_ret);
+        ret = 0;
+    }
+
+    LIBVIRT_RELEASE_THREAD_STATE;
+    return ret;
+}
+
+static PyObject *
+libvirt_qemu_virConnectDomainQemuEventRegister(ATTRIBUTE_UNUSED PyObject * self,
+                                         PyObject * args)
+{
+    PyObject *py_retval;        /* return value */
+    PyObject *pyobj_conn;       /* virConnectPtr */
+    PyObject *pyobj_dom;
+    PyObject *pyobj_cbData;     /* hash of callback data */
+    char *eventName;
+    virConnectPtr conn;
+    int ret = 0;
+
+    virConnectDomainQemuEventCallback cb = NULL;
+    virDomainPtr dom;
+
+    if (!PyArg_ParseTuple
+        (args, (char *) "OOsO:virConnectDomainQemuEventRegister",
+        &pyobj_conn, &pyobj_dom, &eventName, &pyobj_cbData)) {
+        DEBUG("%s failed parsing tuple\n", __FUNCTION__);
+        return VIR_PY_INT_FAIL;
+    }
+
+    if (eventName == NULL)
+        return VIR_PY_INT_FAIL;
+
+    DEBUG("libvirt_qemu_virConnectDomainQemuEventRegister(%p %p %s %p) called\n",
+           pyobj_conn, pyobj_dom, eventName, pyobj_cbData);
+    conn = PyvirConnect_Get(pyobj_conn);
+    if (pyobj_dom == Py_None)
+        dom = NULL;
+    else
+        dom = PyvirDomain_Get(pyobj_dom);
+
+    cb = (virConnectDomainQemuEventCallback)(libvirt_qemu_virConnectDomainEventUnknownCallback);
+    if (!cb) {
+        return VIR_PY_INT_FAIL;
+    }
+
+    Py_INCREF(pyobj_cbData);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ret = virConnectDomainQemuEventRegister(conn, dom, eventName,
+                                           cb, pyobj_cbData,
+                                           libvirt_qemu_virConnectDomainEventFreeFunc);
+    LIBVIRT_END_ALLOW_THREADS;
+    if (ret < 0) {
+        Py_DECREF(pyobj_cbData);
+    }
+    py_retval = libvirt_intWrap(ret);
+    return (py_retval);
+}
+
+static PyObject *
+libvirt_qemu_virConnectDomainQemuEventDeregister(ATTRIBUTE_UNUSED PyObject * self,
+                                           PyObject * args)
+{
+    PyObject *py_retval;
+    PyObject *pyobj_conn;
+    int callbackID;
+    virConnectPtr conn;
+    int ret = 0;
+
+    if (!PyArg_ParseTuple
+        (args, (char *) "Oi:virConnectDomainQemuEventDeregister",
+        &pyobj_conn, &callbackID))
+        return (NULL);
+
+    DEBUG("libvirt_qemu_virConnectDomainQemuEventDeregister(%p) called\n", pyobj_conn);
+
+    conn   = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    ret = virConnectDomainQemuEventDeregister(conn, callbackID);
+
+    LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap(ret);
+    return (py_retval);
+}
+
 /************************************************************************
  *									*
  *			The registration stuff				*
@@ -104,6 +242,8 @@ libvirt_qemu_virDomainQemuMonitorCommand(PyObject *self ATTRIBUTE_UNUSED,
 static PyMethodDef libvirtQemuMethods[] = {
 #include "libvirt-qemu-export.c"
     {(char *) "virDomainQemuMonitorCommand", libvirt_qemu_virDomainQemuMonitorCommand, METH_VARARGS, NULL},
+    {(char *) "virConnectDomainQemuEventRegister", libvirt_qemu_virConnectDomainQemuEventRegister, METH_VARARGS, NULL},
+    {(char *) "virConnectDomainQemuEventDeregister", libvirt_qemu_virConnectDomainQemuEventDeregister, METH_VARARGS, NULL},
     {NULL, NULL, 0, NULL}
 };
 
diff --git a/python/libvirt-qemu-override.py b/python/libvirt-qemu-override.py
new file mode 100644
index 0000000..9838941
--- /dev/null
+++ b/python/libvirt-qemu-override.py
@@ -0,0 +1,55 @@
+#
+# Manually written part of python bindings for libvirt_qemu
+#
+
+# On cygwin, the DLL is called cygvirtmod.dll
+try:
+    import libvirtmod_qemu
+except ImportError, lib_e:
+    try:
+        import cygvirtmod_qemu as libvirtmod_qemu
+    except ImportError, cyg_e:
+        if str(cyg_e).count("No module named"):
+            raise lib_e
+
+import libvirt
+import types
+
+def _dispatchDomainEventUnknownCallback(dom, eventName, eventArgs, cbData):
+    """Dispatches events to python user unknown event callbacks
+    """
+    try:
+        cb = cbData["cb"]
+        opaque = cbData["opaque"]
+        conn = cbData["conn"]
+        cb(conn, libvirt.virDomain(conn, _obj=dom), eventName, eventArgs, opaque)
+        return 0
+    except AttributeError:
+        pass
+
+def domainQemuEventDeregister(conn, callbackID):
+    """Removes a Domain Event Callback. De-registering for a
+       domain callback will disable delivery of this event type """
+    try:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventDeregister(conn._o, callbackID)
+        if ret == -1: raise libvirt.libvirtError ('virConnectDomainQemuEventDeregister() failed', conn)
+        del conn.domainEventCallbackID[callbackID]
+    except AttributeError:
+        pass
+
+def domainQemuEventRegister(conn, dom, eventName, cb, opaque):
+    """Adds a Domain Event Callback. Registering for a domain
+       callback will enable delivery of the events """
+    if not hasattr(conn, 'domainEventCallbackID'):
+        conn.domainEventCallbackID = {}
+    if not hasattr(conn, '_dispatchDomainEventUnknownCallback'):
+        conn._dispatchDomainEventUnknownCallback = _dispatchDomainEventUnknownCallback
+    cbData = { "cb": cb, "conn": conn, "opaque": opaque }
+    if dom is None:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventRegister(conn._o, None, eventName, cbData)
+    else:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventRegister(conn._o, dom._o, eventName, cbData)
+    if ret == -1:
+        raise libvirt.libvirtError ('virConnectDomainQemuEventRegister() failed', conn)
+    conn.domainEventCallbackID[ret] = opaque
+    return ret
diff --git a/python/libvirt_qemu.py b/python/libvirt_qemu.py
new file mode 100644
index 0000000..9a2a8fd
--- /dev/null
+++ b/python/libvirt_qemu.py
@@ -0,0 +1,105 @@
+#! /usr/bin/python -i
+#
+# WARNING WARNING WARNING WARNING
+#
+# This file is automatically written by generator.py. Any changes
+# made here will be lost.
+#
+# To change the manually written methods edit libvirt-qemu-override.py
+# To change the automatically written methods edit generator.py
+#
+# WARNING WARNING WARNING WARNING
+#
+#
+# Manually written part of python bindings for libvirt_qemu
+#
+
+# On cygwin, the DLL is called cygvirtmod.dll
+try:
+    import libvirtmod_qemu
+except ImportError, lib_e:
+    try:
+        import cygvirtmod_qemu as libvirtmod_qemu
+    except ImportError, cyg_e:
+        if str(cyg_e).count("No module named"):
+            raise lib_e
+
+import libvirt
+import types
+
+def _dispatchDomainEventUnknownCallback(dom, eventName, eventArgs, cbData):
+    """Dispatches events to python user unknown event callbacks
+    """
+    try:
+        cb = cbData["cb"]
+        opaque = cbData["opaque"]
+        conn = cbData["conn"]
+        cb(conn, libvirt.virDomain(conn, _obj=dom), eventName, eventArgs, opaque)
+        return 0
+    except AttributeError:
+        pass
+
+def domainQemuEventDeregister(conn, callbackID):
+    """Removes a Domain Event Callback. De-registering for a
+       domain callback will disable delivery of this event type """
+    try:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventDeregister(conn._o, callbackID)
+        if ret == -1: raise libvirt.libvirtError ('virConnectDomainQemuEventDeregister() failed', conn)
+        del conn.domainEventCallbackID[callbackID]
+    except AttributeError:
+        pass
+
+def domainQemuEventRegister(conn, dom, eventName, cb, opaque):
+    """Adds a Domain Event Callback. Registering for a domain
+       callback will enable delivery of the events """
+    if not hasattr(conn, 'domainEventCallbackID'):
+        conn.domainEventCallbackID = {}
+    if not hasattr(conn, '_dispatchDomainEventUnknownCallback'):
+        conn._dispatchDomainEventUnknownCallback = _dispatchDomainEventUnknownCallback
+    cbData = { "cb": cb, "conn": conn, "opaque": opaque }
+    if dom is None:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventRegister(conn._o, None, eventName, cbData)
+    else:
+        ret = libvirtmod_qemu.virConnectDomainQemuEventRegister(conn._o, dom._o, eventName, cbData)
+    if ret == -1:
+        raise libvirt.libvirtError ('virConnectDomainQemuEventRegister() failed', conn)
+    conn.domainEventCallbackID[ret] = opaque
+    return ret
+#
+# WARNING WARNING WARNING WARNING
+#
+# Automatically written part of python bindings for libvirt
+#
+# WARNING WARNING WARNING WARNING
+def qemuMonitorCommand(domain, cmd, flags):
+    """Send an arbitrary monitor command through qemu monitor of domain """
+    ret = libvirtmod_qemu.virDomainQemuMonitorCommand(domain._o, cmd, flags)
+    if ret is None: raise libvirt.libvirtError('virDomainQemuMonitorCommand() failed')
+    return ret
+
+def qemuAttach(conn, pid, flags):
+    """This API is QEMU specific, so it will only work with hypervisor
+    connections to the QEMU driver.
+
+    This API will attach to an externally launched QEMU process
+    identified by @pid. There are several requirements to successfully
+    attach to an external QEMU process:
+
+      - It must have been started with a monitor socket using the UNIX
+        domain socket protocol.
+      - No device hotplug/unplug, or other configuration changes can
+        have been made via the monitor since it started.
+      - The '-name' and '-uuid' arguments should have been set (not
+        mandatory, but strongly recommended)
+
+    If successful, then the guest will appear in the list of running
+    domains for this connection, and other APIs should operate
+    normally (provided the above requirements were honored). """
+    ret = libvirtmod_qemu.virDomainQemuAttach(conn._o, pid, flags)
+    if ret is None: raise libvirt.libvirtError('virDomainQemuAttach() failed')
+    __tmp = virDomain(conn,_obj=ret)
+    return __tmp
+
+# virDomainQemuMonitorCommandFlags
+VIR_DOMAIN_QEMU_MONITOR_COMMAND_DEFAULT = 0
+VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP = 1
-- 
1.7.5.4




More information about the libvir-list mailing list