ci: refresh with 'lcitool manifest'
[libvirt-python.git] / libvirt-qemu-override.c
blobd741990761c1f479353730fb7bc5748082248ed2
1 /*
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
5 * unpractical
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. */
15 #undef HAVE_PTHREAD_H
17 #include <stdio.h>
18 #include <Python.h>
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"
24 #ifndef __CYGWIN__
25 # include <fcntl.h>
26 #endif
28 #if 0
29 # define DEBUG_ERROR 1
30 #endif
32 #if DEBUG_ERROR
33 # define DEBUG(fmt, ...) \
34 printf(fmt, __VA_ARGS__)
35 #else
36 # define DEBUG(fmt, ...) \
37 while (0) {printf(fmt, __VA_ARGS__);}
38 #endif
40 /*******************************************
41 * Helper functions to avoid importing modules
42 * for every callback
43 *******************************************/
44 #if LIBVIR_CHECK_VERSION(1, 2, 3)
45 static PyObject *libvirt_qemu_module;
46 static PyObject *libvirt_qemu_dict;
48 static PyObject *
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__);
59 PyErr_Print();
60 return NULL;
63 return libvirt_qemu_module;
66 static PyObject *
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__);
76 PyErr_Print();
77 return NULL;
80 Py_INCREF(libvirt_qemu_dict);
81 return libvirt_qemu_dict;
85 static PyObject *
86 libvirt_qemu_lookupPythonFunc(const char *funcname)
88 PyObject *python_cb;
90 /* Lookup the python callback */
91 python_cb = PyDict_GetItemString(getLibvirtQemuDictObject(), funcname);
93 if (!python_cb) {
94 DEBUG("%s: Error finding %s\n", __FUNCTION__, funcname);
95 PyErr_Print();
96 PyErr_Clear();
97 return NULL;
100 if (!PyCallable_Check(python_cb)) {
101 DEBUG("%s: %s is not callable\n", __FUNCTION__, funcname);
102 return NULL;
105 return python_cb;
107 #endif /* LIBVIR_CHECK_VERSION(1, 2, 3) */
110 /************************************************************************
112 * Statistics *
114 ************************************************************************/
116 static PyObject *
117 libvirt_qemu_virDomainQemuMonitorCommand(PyObject *self ATTRIBUTE_UNUSED,
118 PyObject *args)
120 PyObject *py_retval;
121 char *result = NULL;
122 virDomainPtr domain;
123 PyObject *pyobj_domain;
124 unsigned int flags;
125 char *cmd;
126 int c_retval;
128 if (!PyArg_ParseTuple(args, (char *)"OzI:virDomainQemuMonitorCommand",
129 &pyobj_domain, &cmd, &flags))
130 return NULL;
131 domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
133 if (domain == NULL)
134 return VIR_PY_NONE;
135 LIBVIRT_BEGIN_ALLOW_THREADS;
136 c_retval = virDomainQemuMonitorCommand(domain, cmd, &result, flags);
137 LIBVIRT_END_ALLOW_THREADS;
139 if (c_retval < 0)
140 return VIR_PY_NONE;
142 py_retval = libvirt_constcharPtrWrap(result);
143 VIR_FREE(result);
144 return py_retval;
147 #if LIBVIR_CHECK_VERSION(0, 10, 0)
148 static PyObject *
149 libvirt_qemu_virDomainQemuAgentCommand(PyObject *self ATTRIBUTE_UNUSED,
150 PyObject *args)
152 PyObject *py_retval;
153 char *result = NULL;
154 virDomainPtr domain;
155 PyObject *pyobj_domain;
156 int timeout;
157 unsigned int flags;
158 char *cmd;
160 if (!PyArg_ParseTuple(args, (char *)"OziI:virDomainQemuAgentCommand",
161 &pyobj_domain, &cmd, &timeout, &flags))
162 return NULL;
163 domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
165 if (domain == NULL)
166 return VIR_PY_NONE;
167 LIBVIRT_BEGIN_ALLOW_THREADS;
168 result = virDomainQemuAgentCommand(domain, cmd, timeout, flags);
169 LIBVIRT_END_ALLOW_THREADS;
171 if (!result)
172 return VIR_PY_NONE;
174 py_retval = libvirt_constcharPtrWrap(result);
175 VIR_FREE(result);
176 return py_retval;
178 #endif /* LIBVIR_CHECK_VERSION(0, 10, 0) */
181 #if LIBVIR_CHECK_VERSION(1, 2, 3)
182 static void
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;
191 static void
192 libvirt_qemu_virConnectDomainQemuMonitorEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
193 virDomainPtr dom,
194 const char *event,
195 long long seconds,
196 unsigned int micros,
197 const char *details,
198 void *opaque)
200 PyObject *pyobj_cbData = (PyObject*)opaque;
201 PyObject *pyobj_dom;
202 PyObject *pyobj_ret = NULL;
203 PyObject *pyobj_conn;
204 PyObject *dictKey;
205 PyObject *pyobj_cb;
207 LIBVIRT_ENSURE_THREAD_STATE;
209 pyobj_cb = libvirt_qemu_lookupPythonFunc("_dispatchQemuMonitorEventCallback");
210 if (!pyobj_cb)
211 goto cleanup;
213 dictKey = libvirt_constcharPtrWrap("conn");
214 if (!dictKey)
215 goto cleanup;
216 pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
217 Py_DECREF(dictKey);
219 /* Create a python instance of this virDomainPtr */
220 virDomainRef(dom);
221 if (!(pyobj_dom = libvirt_virDomainPtrWrap(dom))) {
222 virDomainFree(dom);
223 goto cleanup;
225 Py_INCREF(pyobj_cbData);
227 /* Call the Callback Dispatcher */
228 pyobj_ret = PyObject_CallFunction(pyobj_cb,
229 (char *)"OOsLIsO",
230 pyobj_conn, pyobj_dom, event, seconds,
231 micros, details, pyobj_cbData);
233 Py_DECREF(pyobj_cbData);
234 Py_DECREF(pyobj_dom);
236 cleanup:
237 if (!pyobj_ret) {
238 DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
239 PyErr_Print();
240 } else {
241 Py_DECREF(pyobj_ret);
244 LIBVIRT_RELEASE_THREAD_STATE;
248 static PyObject *
249 libvirt_qemu_virConnectDomainQemuMonitorEventRegister(PyObject *self ATTRIBUTE_UNUSED,
250 PyObject *args)
252 PyObject *py_retval;
253 PyObject *pyobj_conn;
254 PyObject *pyobj_dom;
255 PyObject *pyobj_cbData;
256 const char *event;
257 virConnectPtr conn;
258 int ret = 0;
259 virConnectDomainQemuMonitorEventCallback cb = NULL;
260 virDomainPtr dom;
261 unsigned int flags;
263 if (!PyArg_ParseTuple(args, (char *) "OOzOI:virConnectDomainQemuMonitorEventRegister",
264 &pyobj_conn, &pyobj_dom,
265 &event, &pyobj_cbData, &flags))
266 return NULL;
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)
272 dom = NULL;
273 else
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,
282 cb, pyobj_cbData,
283 libvirt_qemu_virConnectDomainQemuMonitorEventFreeFunc,
284 flags);
285 LIBVIRT_END_ALLOW_THREADS;
287 if (ret < 0) {
288 Py_DECREF(pyobj_cbData);
291 py_retval = libvirt_intWrap(ret);
292 return py_retval;
296 static PyObject *
297 libvirt_qemu_virConnectDomainQemuMonitorEventDeregister(PyObject *self ATTRIBUTE_UNUSED,
298 PyObject *args)
300 PyObject *py_retval;
301 PyObject *pyobj_conn;
302 int callbackID;
303 virConnectPtr conn;
304 int ret = 0;
306 if (!PyArg_ParseTuple(args,
307 (char *) "Oi:virConnectDomainQemuMonitorEventDeregister",
308 &pyobj_conn, &callbackID))
309 return NULL;
311 DEBUG("libvirt_qemu_virConnectDomainQemuMonitorEventDeregister(%p) called\n",
312 pyobj_conn);
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);
322 return py_retval;
324 #endif /* LIBVIR_CHECK_VERSION(1, 2, 3) */
326 #if LIBVIR_CHECK_VERSION(8, 2, 0)
327 static PyObject *
328 libvirt_qemu_virDomainQemuMonitorCommandWithFiles(PyObject *self ATTRIBUTE_UNUSED,
329 PyObject *args)
331 PyObject *pyobj_domain;
332 const char *cmd;
333 PyObject *pyobj_files;
334 unsigned int flags;
335 virDomainPtr domain;
336 unsigned int ninfiles;
337 int *infiles = NULL;
338 unsigned int noutfiles = 0;
339 int *outfiles = NULL;
340 char *result = NULL;
341 size_t i;
342 PyObject *py_outfiles = NULL;
343 PyObject *py_retval = NULL;
344 int c_retval;
346 if (!PyArg_ParseTuple(args,
347 (char *) "Os|OI:virDomainQemuMonitorCommandWithFiles",
348 &pyobj_domain, &cmd, &pyobj_files, &flags))
349 return NULL;
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++) {
358 PyObject *pyfd;
359 int fd;
361 pyfd = PyList_GetItem(pyobj_files, i);
363 if (libvirt_intUnwrap(pyfd, &fd) < 0)
364 goto cleanup;
366 infiles[i] = fd;
369 LIBVIRT_BEGIN_ALLOW_THREADS;
370 c_retval = virDomainQemuMonitorCommandWithFiles(domain, cmd, ninfiles, infiles,
371 &noutfiles, &outfiles, &result, flags);
372 LIBVIRT_END_ALLOW_THREADS;
374 if (c_retval < 0) {
375 py_retval = VIR_PY_NONE;
376 goto cleanup;
379 if (!(py_outfiles = PyList_New(0)) ||
380 !(py_retval = PyTuple_New(2))) {
381 goto error;
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. */
389 #ifndef __CYGWIN__
390 int fflags;
392 if ((fflags = fcntl(fd, F_GETFL)) < 0)
393 goto error;
395 switch (fflags & (O_ACCMODE | O_APPEND)) {
396 case O_RDONLY:
397 mode = "rb";
398 break;
399 case O_WRONLY:
400 mode = "wb";
401 break;
402 case O_RDWR:
403 mode = "r+b";
404 break;
405 case O_WRONLY | O_APPEND:
406 mode = "ab";
407 break;
408 case O_RDWR | O_APPEND:
409 mode = "a+b";
410 break;
412 #endif
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 */
420 py_outfiles = NULL;
422 cleanup:
423 Py_XDECREF(py_outfiles);
424 VIR_FREE(result);
425 VIR_FREE(outfiles);
426 VIR_FREE(infiles);
427 return py_retval;
429 error:
430 while (noutfiles > 0) {
431 VIR_FORCE_CLOSE(outfiles[--noutfiles]);
433 Py_CLEAR(py_retval);
434 goto cleanup;
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,
461 #ifndef __CYGWIN__
462 "libvirtmod_qemu",
463 #else
464 "cygvirtmod_qemu",
465 #endif
466 NULL,
468 libvirtQemuMethods,
469 NULL,
470 NULL,
471 NULL,
472 NULL
475 PyMODINIT_FUNC
476 #ifndef __CYGWIN__
477 PyInit_libvirtmod_qemu
478 #else
479 PyInit_cygvirtmod_qemu
480 #endif
481 (void)
483 PyObject *module;
485 if (virInitialize() < 0)
486 return NULL;
488 module = PyModule_Create(&moduledef);
490 return module;