2 * libvir.c: this modules implements the main part of the glue of the
3 * libvir library and the Python interpreter. It provides the
4 * entry points where an automatically generated stub is
7 * Copyright (C) 2011-2019 Red Hat, Inc.
9 * Daniel Veillard <veillard@redhat.com>
12 /* Horrible kludge to work around even more horrible name-space pollution
13 via Python.h. That file includes /usr/include/python3.x/pyconfig*.h,
14 which has over 180 autoconf-style HAVE_* definitions. Shame on them. */
19 #include <libvirt/libvirt-qemu.h>
20 #include <libvirt/virterror.h>
21 #include "typewrappers.h"
22 #include "libvirt-utils.h"
23 #include "libvirt-qemu.h"
29 # define DEBUG_ERROR 1
33 # define DEBUG(fmt, ...) \
34 printf(fmt, __VA_ARGS__)
36 # define DEBUG(fmt, ...) \
37 while (0) {printf(fmt, __VA_ARGS__);}
40 /*******************************************
41 * Helper functions to avoid importing modules
43 *******************************************/
44 #if LIBVIR_CHECK_VERSION(1, 2, 3)
45 static PyObject
*libvirt_qemu_module
;
46 static PyObject
*libvirt_qemu_dict
;
49 getLibvirtQemuModuleObject(void)
51 if (libvirt_qemu_module
)
52 return libvirt_qemu_module
;
54 // PyImport_ImportModule returns a new reference
55 /* Bogus (char *) cast for RHEL-5 python API brokenness */
56 libvirt_qemu_module
= PyImport_ImportModule((char *)"libvirt_qemu");
57 if (!libvirt_qemu_module
) {
58 DEBUG("%s Error importing libvirt_qemu module\n", __FUNCTION__
);
63 return libvirt_qemu_module
;
67 getLibvirtQemuDictObject(void)
69 if (libvirt_qemu_dict
)
70 return libvirt_qemu_dict
;
72 // PyModule_GetDict returns a borrowed reference
73 libvirt_qemu_dict
= PyModule_GetDict(getLibvirtQemuModuleObject());
74 if (!libvirt_qemu_dict
) {
75 DEBUG("%s Error importing libvirt_qemu dictionary\n", __FUNCTION__
);
80 Py_INCREF(libvirt_qemu_dict
);
81 return libvirt_qemu_dict
;
86 libvirt_qemu_lookupPythonFunc(const char *funcname
)
90 /* Lookup the python callback */
91 python_cb
= PyDict_GetItemString(getLibvirtQemuDictObject(), funcname
);
94 DEBUG("%s: Error finding %s\n", __FUNCTION__
, funcname
);
100 if (!PyCallable_Check(python_cb
)) {
101 DEBUG("%s: %s is not callable\n", __FUNCTION__
, funcname
);
107 #endif /* LIBVIR_CHECK_VERSION(1, 2, 3) */
110 /************************************************************************
114 ************************************************************************/
117 libvirt_qemu_virDomainQemuMonitorCommand(PyObject
*self ATTRIBUTE_UNUSED
,
123 PyObject
*pyobj_domain
;
128 if (!PyArg_ParseTuple(args
, (char *)"OzI:virDomainQemuMonitorCommand",
129 &pyobj_domain
, &cmd
, &flags
))
131 domain
= (virDomainPtr
) PyvirDomain_Get(pyobj_domain
);
135 LIBVIRT_BEGIN_ALLOW_THREADS
;
136 c_retval
= virDomainQemuMonitorCommand(domain
, cmd
, &result
, flags
);
137 LIBVIRT_END_ALLOW_THREADS
;
142 py_retval
= libvirt_constcharPtrWrap(result
);
147 #if LIBVIR_CHECK_VERSION(0, 10, 0)
149 libvirt_qemu_virDomainQemuAgentCommand(PyObject
*self ATTRIBUTE_UNUSED
,
155 PyObject
*pyobj_domain
;
160 if (!PyArg_ParseTuple(args
, (char *)"OziI:virDomainQemuAgentCommand",
161 &pyobj_domain
, &cmd
, &timeout
, &flags
))
163 domain
= (virDomainPtr
) PyvirDomain_Get(pyobj_domain
);
167 LIBVIRT_BEGIN_ALLOW_THREADS
;
168 result
= virDomainQemuAgentCommand(domain
, cmd
, timeout
, flags
);
169 LIBVIRT_END_ALLOW_THREADS
;
174 py_retval
= libvirt_constcharPtrWrap(result
);
178 #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */
181 #if LIBVIR_CHECK_VERSION(1, 2, 3)
183 libvirt_qemu_virConnectDomainQemuMonitorEventFreeFunc(void *opaque
)
185 PyObject
*pyobj_conn
= (PyObject
*)opaque
;
186 LIBVIRT_ENSURE_THREAD_STATE
;
187 Py_DECREF(pyobj_conn
);
188 LIBVIRT_RELEASE_THREAD_STATE
;
192 libvirt_qemu_virConnectDomainQemuMonitorEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED
,
200 PyObject
*pyobj_cbData
= (PyObject
*)opaque
;
202 PyObject
*pyobj_ret
= NULL
;
203 PyObject
*pyobj_conn
;
207 LIBVIRT_ENSURE_THREAD_STATE
;
209 pyobj_cb
= libvirt_qemu_lookupPythonFunc("_dispatchQemuMonitorEventCallback");
213 dictKey
= libvirt_constcharPtrWrap("conn");
216 pyobj_conn
= PyDict_GetItem(pyobj_cbData
, dictKey
);
219 /* Create a python instance of this virDomainPtr */
221 if (!(pyobj_dom
= libvirt_virDomainPtrWrap(dom
))) {
225 Py_INCREF(pyobj_cbData
);
227 /* Call the Callback Dispatcher */
228 pyobj_ret
= PyObject_CallFunction(pyobj_cb
,
230 pyobj_conn
, pyobj_dom
, event
, seconds
,
231 micros
, details
, pyobj_cbData
);
233 Py_DECREF(pyobj_cbData
);
234 Py_DECREF(pyobj_dom
);
238 DEBUG("%s - ret:%p\n", __FUNCTION__
, pyobj_ret
);
241 Py_DECREF(pyobj_ret
);
244 LIBVIRT_RELEASE_THREAD_STATE
;
249 libvirt_qemu_virConnectDomainQemuMonitorEventRegister(PyObject
*self ATTRIBUTE_UNUSED
,
253 PyObject
*pyobj_conn
;
255 PyObject
*pyobj_cbData
;
259 virConnectDomainQemuMonitorEventCallback cb
= NULL
;
263 if (!PyArg_ParseTuple(args
, (char *) "OOzOI:virConnectDomainQemuMonitorEventRegister",
264 &pyobj_conn
, &pyobj_dom
,
265 &event
, &pyobj_cbData
, &flags
))
268 DEBUG("libvirt_qemu_virConnectDomainQemuMonitorEventRegister(%p %p %s %p %x) called\n",
269 pyobj_conn
, pyobj_dom
, NULLSTR(event
), pyobj_cbData
, flags
);
270 conn
= PyvirConnect_Get(pyobj_conn
);
271 if (pyobj_dom
== Py_None
)
274 dom
= PyvirDomain_Get(pyobj_dom
);
276 cb
= libvirt_qemu_virConnectDomainQemuMonitorEventCallback
;
278 Py_INCREF(pyobj_cbData
);
280 LIBVIRT_BEGIN_ALLOW_THREADS
;
281 ret
= virConnectDomainQemuMonitorEventRegister(conn
, dom
, event
,
283 libvirt_qemu_virConnectDomainQemuMonitorEventFreeFunc
,
285 LIBVIRT_END_ALLOW_THREADS
;
288 Py_DECREF(pyobj_cbData
);
291 py_retval
= libvirt_intWrap(ret
);
297 libvirt_qemu_virConnectDomainQemuMonitorEventDeregister(PyObject
*self ATTRIBUTE_UNUSED
,
301 PyObject
*pyobj_conn
;
306 if (!PyArg_ParseTuple(args
,
307 (char *) "Oi:virConnectDomainQemuMonitorEventDeregister",
308 &pyobj_conn
, &callbackID
))
311 DEBUG("libvirt_qemu_virConnectDomainQemuMonitorEventDeregister(%p) called\n",
314 conn
= PyvirConnect_Get(pyobj_conn
);
316 LIBVIRT_BEGIN_ALLOW_THREADS
;
318 ret
= virConnectDomainQemuMonitorEventDeregister(conn
, callbackID
);
320 LIBVIRT_END_ALLOW_THREADS
;
321 py_retval
= libvirt_intWrap(ret
);
324 #endif /* LIBVIR_CHECK_VERSION(1, 2, 3) */
326 #if LIBVIR_CHECK_VERSION(8, 2, 0)
328 libvirt_qemu_virDomainQemuMonitorCommandWithFiles(PyObject
*self ATTRIBUTE_UNUSED
,
331 PyObject
*pyobj_domain
;
333 PyObject
*pyobj_files
;
336 unsigned int ninfiles
;
338 unsigned int noutfiles
= 0;
339 int *outfiles
= NULL
;
342 PyObject
*py_outfiles
= NULL
;
343 PyObject
*py_retval
= NULL
;
346 if (!PyArg_ParseTuple(args
,
347 (char *) "Os|OI:virDomainQemuMonitorCommandWithFiles",
348 &pyobj_domain
, &cmd
, &pyobj_files
, &flags
))
350 domain
= (virDomainPtr
) PyvirDomain_Get(pyobj_domain
);
352 ninfiles
= PyList_Size(pyobj_files
);
354 if (VIR_ALLOC_N(infiles
, ninfiles
) < 0)
355 return PyErr_NoMemory();
357 for (i
= 0; i
< ninfiles
; i
++) {
361 pyfd
= PyList_GetItem(pyobj_files
, i
);
363 if (libvirt_intUnwrap(pyfd
, &fd
) < 0)
369 LIBVIRT_BEGIN_ALLOW_THREADS
;
370 c_retval
= virDomainQemuMonitorCommandWithFiles(domain
, cmd
, ninfiles
, infiles
,
371 &noutfiles
, &outfiles
, &result
, flags
);
372 LIBVIRT_END_ALLOW_THREADS
;
375 py_retval
= VIR_PY_NONE
;
379 if (!(py_outfiles
= PyList_New(0)) ||
380 !(py_retval
= PyTuple_New(2))) {
384 for (i
= 0; i
< noutfiles
; i
++) {
385 int fd
= outfiles
[i
];
386 const char *mode
= "r+b";
388 /* Since FD passing works only on UNIX-like systems, we can do this. */
392 if ((fflags
= fcntl(fd
, F_GETFL
)) < 0)
395 switch (fflags
& (O_ACCMODE
| O_APPEND
)) {
405 case O_WRONLY
| O_APPEND
:
408 case O_RDWR
| O_APPEND
:
414 VIR_PY_LIST_APPEND_GOTO(py_outfiles
, PyFile_FromFd(fd
, NULL
, mode
, 0, NULL
, NULL
, NULL
, 1), error
);
417 VIR_PY_TUPLE_SET_GOTO(py_retval
, 0, libvirt_charPtrWrap(result
), error
);
418 VIR_PY_TUPLE_SET_GOTO(py_retval
, 1, py_outfiles
, error
);
419 /* stolen by py_retval */
423 Py_XDECREF(py_outfiles
);
430 while (noutfiles
> 0) {
431 VIR_FORCE_CLOSE(outfiles
[--noutfiles
]);
436 #endif /* LIBVIR_CHECK_VERSION(8, 2, 0) */
438 /************************************************************************
440 * The registration stuff *
442 ************************************************************************/
443 static PyMethodDef libvirtQemuMethods
[] = {
444 #include "libvirt-qemu-export.c.inc"
445 {(char *) "virDomainQemuMonitorCommand", libvirt_qemu_virDomainQemuMonitorCommand
, METH_VARARGS
, NULL
},
446 #if LIBVIR_CHECK_VERSION(0, 10, 0)
447 {(char *) "virDomainQemuAgentCommand", libvirt_qemu_virDomainQemuAgentCommand
, METH_VARARGS
, NULL
},
448 #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */
449 #if LIBVIR_CHECK_VERSION(1, 2, 3)
450 {(char *) "virConnectDomainQemuMonitorEventRegister", libvirt_qemu_virConnectDomainQemuMonitorEventRegister
, METH_VARARGS
, NULL
},
451 {(char *) "virConnectDomainQemuMonitorEventDeregister", libvirt_qemu_virConnectDomainQemuMonitorEventDeregister
, METH_VARARGS
, NULL
},
452 #endif /* LIBVIR_CHECK_VERSION(1, 2, 3) */
453 #if LIBVIR_CHECK_VERSION(8, 2, 0)
454 {(char *) "virDomainQemuMonitorCommandWithFiles", libvirt_qemu_virDomainQemuMonitorCommandWithFiles
, METH_VARARGS
, NULL
},
455 #endif /* LIBVIR_CHECK_VERSION(8, 2, 0) */
456 {NULL
, NULL
, 0, NULL
}
459 static struct PyModuleDef moduledef
= {
460 PyModuleDef_HEAD_INIT
,
477 PyInit_libvirtmod_qemu
479 PyInit_cygvirtmod_qemu
485 if (virInitialize() < 0)
488 module
= PyModule_Create(&moduledef
);