mirror of
https://gitlab.com/libvirt/libvirt-python.git
synced 2024-10-26 07:55:06 +03:00
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In common with what was done for QEMU, this creates a libvirt_lxc.so library and libvirt/libvirt-lxc.h header file. The actual APIs are int virDomainLxcOpenNamespace(virDomainPtr domain, int **fdlist, unsigned int flags); int virDomainLxcEnterNamespace(virDomainPtr domain, unsigned int nfdlist, int *fdlist, unsigned int *noldfdlist, int **oldfdlist, unsigned int flags); which provide a way to use the setns() system call to move the calling process into the container's namespace. It is not practical to write in a generically applicable manner. The nearest that we could get to such an API would be an API which allows to pass a command + argv to be executed inside a container. Even if we had such a generic API, this LXC specific API is still useful, because it allows the caller to maintain the current process context, in particular any I/O streams they have open. NB the virDomainLxcEnterNamespace() API is special in that it runs client side, so does not involve the internal driver API. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
9ad1c7f711
commit
d18147940f
35
Makefile.am
35
Makefile.am
@ -35,6 +35,8 @@ EXTRA_DIST = \
|
||||
libvirt-override.c \
|
||||
libvirt-override.py \
|
||||
libvirt-override-api.xml \
|
||||
libvirt-lxc-override.c \
|
||||
libvirt-lxc-override-api.xml \
|
||||
libvirt-qemu-override.c \
|
||||
libvirt-qemu-override-api.xml \
|
||||
$(CLASSES_EXTRA) \
|
||||
@ -47,10 +49,13 @@ mylibs = \
|
||||
myqemulibs = \
|
||||
$(top_builddir)/src/libvirt-qemu.la \
|
||||
$(top_builddir)/gnulib/lib/libgnu.la
|
||||
mylxclibs = \
|
||||
$(top_builddir)/src/libvirt-lxc.la \
|
||||
$(top_builddir)/gnulib/lib/libgnu.la
|
||||
|
||||
all-local: libvirt.py libvirt_qemu.py
|
||||
all-local: libvirt.py libvirt_qemu.py libvirt_lxc.py
|
||||
|
||||
pyexec_LTLIBRARIES = libvirtmod.la libvirtmod_qemu.la
|
||||
pyexec_LTLIBRARIES = libvirtmod.la libvirtmod_qemu.la libvirtmod_lxc.la
|
||||
|
||||
libvirtmod_la_SOURCES = libvirt-override.c typewrappers.c
|
||||
nodist_libvirtmod_la_SOURCES = libvirt.c libvirt.h
|
||||
@ -74,6 +79,17 @@ libvirtmod_qemu_la_LDFLAGS = -module -avoid-version -shared -L$(top_builddir)/sr
|
||||
libvirtmod_qemu_la_LIBADD = $(myqemulibs) \
|
||||
$(CYGWIN_EXTRA_LIBADD) $(CYGWIN_EXTRA_PYTHON_LIBADD)
|
||||
|
||||
libvirtmod_lxc_la_SOURCES = libvirt-lxc-override.c typewrappers.c
|
||||
nodist_libvirtmod_lxc_la_SOURCES = libvirt-lxc.c libvirt-lxc.h
|
||||
# Python <= 2.4 header files contain a redundant decl, hence we
|
||||
# need extra flags here
|
||||
libvirtmod_lxc_la_CFLAGS = $(WARN_PYTHON_CFLAGS)
|
||||
|
||||
libvirtmod_lxc_la_LDFLAGS = -module -avoid-version -shared -L$(top_builddir)/src/.libs \
|
||||
$(CYGWIN_EXTRA_LDFLAGS)
|
||||
libvirtmod_lxc_la_LIBADD = $(mylxclibs) \
|
||||
$(CYGWIN_EXTRA_LIBADD) $(CYGWIN_EXTRA_PYTHON_LIBADD)
|
||||
|
||||
GENERATE = generator.py
|
||||
API_DESC = $(top_srcdir)/docs/libvirt-api.xml $(srcdir)/libvirt-override-api.xml
|
||||
GENERATED= libvirt-export.c \
|
||||
@ -87,18 +103,26 @@ QEMU_GENERATED= libvirt-qemu-export.c \
|
||||
libvirt-qemu.h \
|
||||
libvirt_qemu.py
|
||||
|
||||
$(GENERATE).stamp: $(srcdir)/$(GENERATE) $(API_DESC) $(QEMU_API_DESC)
|
||||
LXC_API_DESC = $(top_srcdir)/docs/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-override-api.xml
|
||||
LXC_GENERATED= libvirt-lxc-export.c \
|
||||
libvirt-lxc.c \
|
||||
libvirt-lxc.h \
|
||||
libvirt_lxc.py
|
||||
|
||||
$(GENERATE).stamp: $(srcdir)/$(GENERATE) $(API_DESC) $(QEMU_API_DESC) $(LXC_API_DESC)
|
||||
$(AM_V_GEN)$(PYTHON) $(srcdir)/$(GENERATE) $(PYTHON) && \
|
||||
touch $@
|
||||
|
||||
$(GENERATED) $(QEMU_GENERATED): $(GENERATE).stamp
|
||||
$(GENERATED) $(QEMU_GENERATED) $(LXC_GENERATED): $(GENERATE).stamp
|
||||
|
||||
$(libvirtmod_la_OBJECTS): $(GENERATED)
|
||||
$(libvirtmod_qemu_la_OBJECTS): $(QEMU_GENERATED)
|
||||
$(libvirtmod_lxc_la_OBJECTS): $(LXC_GENERATED)
|
||||
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(pyexecdir)
|
||||
$(INSTALL) -m 0644 libvirt.py $(DESTDIR)$(pyexecdir)
|
||||
$(INSTALL) -m 0644 libvirt_lxc.py $(DESTDIR)$(pyexecdir)
|
||||
$(INSTALL) -m 0644 libvirt_qemu.py $(DESTDIR)$(pyexecdir)
|
||||
$(mkinstalldirs) $(DESTDIR)$(DOCS_DIR)
|
||||
@(for doc in $(DOCS) ; \
|
||||
@ -106,9 +130,10 @@ install-data-local:
|
||||
|
||||
uninstall-local:
|
||||
rm -f $(DESTDIR)$(pyexecdir)/libvirt.py
|
||||
rm -f $(DESTDIR)$(pyexecdir)/libvirt_lxc.py
|
||||
rm -f $(DESTDIR)$(pyexecdir)/libvirt_qemu.py
|
||||
|
||||
CLEANFILES= $(GENERATED) $(QEMU_GENERATED) $(GENERATE).stamp
|
||||
CLEANFILES= $(GENERATED) $(QEMU_GENERATED) $(LXC_GENERATED) $(GENERATE).stamp
|
||||
|
||||
else
|
||||
all:
|
||||
|
172
generator.py
172
generator.py
@ -4,8 +4,10 @@
|
||||
#
|
||||
|
||||
functions = {}
|
||||
lxc_functions = {}
|
||||
qemu_functions = {}
|
||||
enums = {} # { enumType: { enumConstant: enumValue } }
|
||||
lxc_enums = {} # { enumType: { enumConstant: enumValue } }
|
||||
qemu_enums = {} # { enumType: { enumConstant: enumValue } }
|
||||
|
||||
import os
|
||||
@ -123,6 +125,8 @@ class docParser(xml.sax.handler.ContentHandler):
|
||||
if (attrs['file'] == "libvirt" or
|
||||
attrs['file'] == "virterror"):
|
||||
enum(attrs['type'],attrs['name'],attrs['value'])
|
||||
elif attrs['file'] == "libvirt-lxc":
|
||||
lxc_enum(attrs['type'],attrs['name'],attrs['value'])
|
||||
elif attrs['file'] == "libvirt-qemu":
|
||||
qemu_enum(attrs['type'],attrs['name'],attrs['value'])
|
||||
|
||||
@ -138,6 +142,11 @@ class docParser(xml.sax.handler.ContentHandler):
|
||||
self.function_return, self.function_args,
|
||||
self.function_file, self.function_module,
|
||||
self.function_cond)
|
||||
elif self.function_module == "libvirt-lxc":
|
||||
lxc_function(self.function, self.function_descr,
|
||||
self.function_return, self.function_args,
|
||||
self.function_file, self.function_module,
|
||||
self.function_cond)
|
||||
elif self.function_module == "libvirt-qemu":
|
||||
qemu_function(self.function, self.function_descr,
|
||||
self.function_return, self.function_args,
|
||||
@ -148,6 +157,11 @@ class docParser(xml.sax.handler.ContentHandler):
|
||||
self.function_return, self.function_args,
|
||||
self.function_file, self.function_module,
|
||||
self.function_cond)
|
||||
elif self.function_file == "python-lxc":
|
||||
lxc_function(self.function, self.function_descr,
|
||||
self.function_return, self.function_args,
|
||||
self.function_file, self.function_module,
|
||||
self.function_cond)
|
||||
elif self.function_file == "python-qemu":
|
||||
qemu_function(self.function, self.function_descr,
|
||||
self.function_return, self.function_args,
|
||||
@ -184,6 +198,9 @@ def function(name, desc, ret, args, file, module, cond):
|
||||
def qemu_function(name, desc, ret, args, file, module, cond):
|
||||
qemu_functions[name] = (desc, ret, args, file, module, cond)
|
||||
|
||||
def lxc_function(name, desc, ret, args, file, module, cond):
|
||||
lxc_functions[name] = (desc, ret, args, file, module, cond)
|
||||
|
||||
def enum(type, name, value):
|
||||
if not enums.has_key(type):
|
||||
enums[type] = {}
|
||||
@ -208,6 +225,11 @@ def enum(type, name, value):
|
||||
if name[-5:] != '_LAST':
|
||||
enums[type][name] = value
|
||||
|
||||
def lxc_enum(type, name, value):
|
||||
if not lxc_enums.has_key(type):
|
||||
lxc_enums[type] = {}
|
||||
lxc_enums[type][name] = value
|
||||
|
||||
def qemu_enum(type, name, value):
|
||||
if not qemu_enums.has_key(type):
|
||||
qemu_enums[type] = {}
|
||||
@ -222,10 +244,12 @@ def qemu_enum(type, name, value):
|
||||
#######################################################################
|
||||
|
||||
functions_failed = []
|
||||
lxc_functions_failed = []
|
||||
qemu_functions_failed = []
|
||||
functions_skipped = [
|
||||
"virConnectListDomains",
|
||||
]
|
||||
lxc_functions_skipped = []
|
||||
qemu_functions_skipped = []
|
||||
|
||||
skipped_modules = {
|
||||
@ -430,6 +454,10 @@ skip_impl = (
|
||||
'virNodeGetCPUMap',
|
||||
)
|
||||
|
||||
lxc_skip_impl = (
|
||||
'virDomainLxcOpenNamespace',
|
||||
)
|
||||
|
||||
qemu_skip_impl = (
|
||||
'virDomainQemuMonitorCommand',
|
||||
'virDomainQemuAgentCommand',
|
||||
@ -501,6 +529,8 @@ skip_function = (
|
||||
"virStorageVolGetConnect",
|
||||
)
|
||||
|
||||
lxc_skip_function = (
|
||||
)
|
||||
qemu_skip_function = (
|
||||
#"virDomainQemuAttach",
|
||||
)
|
||||
@ -511,6 +541,7 @@ function_skip_python_impl = (
|
||||
# be exposed in bindings
|
||||
)
|
||||
|
||||
lxc_function_skip_python_impl = ()
|
||||
qemu_function_skip_python_impl = ()
|
||||
|
||||
function_skip_index_one = (
|
||||
@ -521,6 +552,7 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
global py_types
|
||||
global unknown_types
|
||||
global functions
|
||||
global lxc_functions
|
||||
global qemu_functions
|
||||
global skipped_modules
|
||||
global function_skip_python_impl
|
||||
@ -528,6 +560,8 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
try:
|
||||
if module == "libvirt":
|
||||
(desc, ret, args, file, mod, cond) = functions[name]
|
||||
if module == "libvirt-lxc":
|
||||
(desc, ret, args, file, mod, cond) = lxc_functions[name]
|
||||
if module == "libvirt-qemu":
|
||||
(desc, ret, args, file, mod, cond) = qemu_functions[name]
|
||||
except:
|
||||
@ -543,6 +577,12 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
if name in skip_impl:
|
||||
# Don't delete the function entry in the caller.
|
||||
return 1
|
||||
elif module == "libvirt-lxc":
|
||||
if name in lxc_skip_function:
|
||||
return 0
|
||||
if name in lxc_skip_impl:
|
||||
# Don't delete the function entry in the caller.
|
||||
return 1
|
||||
elif module == "libvirt-qemu":
|
||||
if name in qemu_skip_function:
|
||||
return 0
|
||||
@ -643,6 +683,10 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name));
|
||||
export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
|
||||
(name, name))
|
||||
elif module == "libvirt-lxc":
|
||||
include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name));
|
||||
export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
|
||||
(name, name))
|
||||
elif module == "libvirt-qemu":
|
||||
include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name));
|
||||
export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
|
||||
@ -666,6 +710,8 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
output.write("PyObject *\n")
|
||||
if module == "libvirt":
|
||||
output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
|
||||
elif module == "libvirt-lxc":
|
||||
output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
|
||||
elif module == "libvirt-qemu":
|
||||
output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
|
||||
output.write(" PyObject *args")
|
||||
@ -698,6 +744,9 @@ def print_function_wrapper(module, name, output, export, include):
|
||||
if module == "libvirt":
|
||||
if name in function_skip_python_impl:
|
||||
return 0
|
||||
elif module == "libvirt-lxc":
|
||||
if name in lxc_function_skip_python_impl:
|
||||
return 0
|
||||
elif module == "libvirt-qemu":
|
||||
if name in qemu_function_skip_python_impl:
|
||||
return 0
|
||||
@ -708,7 +757,7 @@ def buildStubs(module):
|
||||
global py_return_types
|
||||
global unknown_types
|
||||
|
||||
if module not in ["libvirt", "libvirt-qemu"]:
|
||||
if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
|
||||
print "ERROR: Unknown module type: %s" % module
|
||||
return None
|
||||
|
||||
@ -716,6 +765,10 @@ def buildStubs(module):
|
||||
funcs = functions
|
||||
funcs_failed = functions_failed
|
||||
funcs_skipped = functions_skipped
|
||||
elif module == "libvirt-lxc":
|
||||
funcs = lxc_functions
|
||||
funcs_failed = lxc_functions_failed
|
||||
funcs_skipped = functions_skipped
|
||||
elif module == "libvirt-qemu":
|
||||
funcs = qemu_functions
|
||||
funcs_failed = qemu_functions_failed
|
||||
@ -1111,6 +1164,8 @@ def functionCompare(info1, info2):
|
||||
def writeDoc(module, name, args, indent, output):
|
||||
if module == "libvirt":
|
||||
funcs = functions
|
||||
elif module == "libvirt-lxc":
|
||||
funcs = lxc_functions
|
||||
elif module == "libvirt-qemu":
|
||||
funcs = qemu_functions
|
||||
if funcs[name][0] is None or funcs[name][0] == "":
|
||||
@ -1762,11 +1817,126 @@ def qemuBuildWrappers(module):
|
||||
fd.close()
|
||||
|
||||
|
||||
def lxcBuildWrappers(module):
|
||||
global lxc_functions
|
||||
|
||||
if not module == "libvirt-lxc":
|
||||
print "ERROR: only libvirt-lxc is supported"
|
||||
return None
|
||||
|
||||
extra_file = os.path.join(srcPref, "%s-override.py" % module)
|
||||
extra = None
|
||||
|
||||
fd = open("libvirt_lxc.py", "w")
|
||||
|
||||
if os.path.exists(extra_file):
|
||||
extra = open(extra_file, "r")
|
||||
fd.write("#! " + python + " -i\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# WARNING WARNING WARNING WARNING\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# This file is automatically written by generator.py. Any changes\n")
|
||||
fd.write("# made here will be lost.\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# To change the manually written methods edit " + module + "-override.py\n")
|
||||
fd.write("# To change the automatically written methods edit generator.py\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# WARNING WARNING WARNING WARNING\n")
|
||||
fd.write("#\n")
|
||||
if extra != None:
|
||||
fd.writelines(extra.readlines())
|
||||
fd.write("#\n")
|
||||
fd.write("# WARNING WARNING WARNING WARNING\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# Automatically written part of python bindings for libvirt\n")
|
||||
fd.write("#\n")
|
||||
fd.write("# WARNING WARNING WARNING WARNING\n")
|
||||
if extra != None:
|
||||
extra.close()
|
||||
|
||||
fd.write("try:\n")
|
||||
fd.write(" import libvirtmod_lxc\n")
|
||||
fd.write("except ImportError, lib_e:\n")
|
||||
fd.write(" try:\n")
|
||||
fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\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
|
||||
#
|
||||
for name in lxc_functions.keys():
|
||||
func = nameFixup(name, 'None', None, None)
|
||||
(desc, ret, args, file, mod, cond) = lxc_functions[name]
|
||||
fd.write("def %s(" % func)
|
||||
n = 0
|
||||
for arg in args:
|
||||
if n != 0:
|
||||
fd.write(", ")
|
||||
fd.write("%s" % arg[0])
|
||||
n = n + 1
|
||||
fd.write("):\n")
|
||||
writeDoc(module, name, args, ' ', fd);
|
||||
|
||||
if ret[0] != "void":
|
||||
fd.write(" ret = ");
|
||||
else:
|
||||
fd.write(" ");
|
||||
fd.write("libvirtmod_lxc.%s(" % name)
|
||||
n = 0
|
||||
|
||||
conn = None
|
||||
|
||||
for arg in args:
|
||||
if arg[1] == "virConnectPtr":
|
||||
conn = arg[0]
|
||||
|
||||
if n != 0:
|
||||
fd.write(", ");
|
||||
if arg[1] in ["virDomainPtr", "virConnectPtr"]:
|
||||
# FIXME: This might have problem if the function
|
||||
# has multiple args which are objects.
|
||||
fd.write("%s.%s" % (arg[0], "_o"))
|
||||
else:
|
||||
fd.write("%s" % arg[0])
|
||||
n = n + 1
|
||||
fd.write(")\n");
|
||||
|
||||
if ret[0] != "void":
|
||||
fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
|
||||
if ret[0] == "virDomainPtr":
|
||||
fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n")
|
||||
fd.write(" return __tmp\n")
|
||||
else:
|
||||
fd.write(" return ret\n")
|
||||
|
||||
fd.write("\n")
|
||||
|
||||
#
|
||||
# Generate enum constants
|
||||
#
|
||||
for type,enum in lxc_enums.items():
|
||||
fd.write("# %s\n" % type)
|
||||
items = enum.items()
|
||||
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()
|
||||
|
||||
|
||||
quiet = 0
|
||||
if buildStubs("libvirt") < 0:
|
||||
sys.exit(1)
|
||||
if buildStubs("libvirt-lxc") < 0:
|
||||
sys.exit(1)
|
||||
if buildStubs("libvirt-qemu") < 0:
|
||||
sys.exit(1)
|
||||
buildWrappers("libvirt")
|
||||
lxcBuildWrappers("libvirt-lxc")
|
||||
qemuBuildWrappers("libvirt-qemu")
|
||||
sys.exit(0)
|
||||
|
19
libvirt-lxc-override-api.xml
Normal file
19
libvirt-lxc-override-api.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0"?>
|
||||
<api name='libvir-lxc-python'>
|
||||
<symbols>
|
||||
<function name='virDomainLxcOpenNamespace' file='python-lxc'>
|
||||
<info><![CDATA[This API is LXC specific, so it will only work with hypervisor
|
||||
connections to the LXC driver.
|
||||
|
||||
Open the namespaces associated with the container @domain
|
||||
and return a list of file descriptors associated with the
|
||||
container.
|
||||
|
||||
The returned file descriptors are intended to be used with
|
||||
the setns() system call.]]></info>
|
||||
<return type='int' info='the list of open file descriptors, or -1 on error'/>
|
||||
<arg name='domain' type='virDomainPtr' info='a domain object'/>
|
||||
<arg name='flags' type='unsigned int' info='currently unused, pass 0'/>
|
||||
</function>
|
||||
</symbols>
|
||||
</api>
|
141
libvirt-lxc-override.c
Normal file
141
libvirt-lxc-override.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* libvir.c: this modules implements the main part of the glue of the
|
||||
* libvir library and the Python interpreter. It provides the
|
||||
* entry points where an automatically generated stub is
|
||||
* unpractical
|
||||
*
|
||||
* Copyright (C) 2012-2013 Red Hat, Inc.
|
||||
*
|
||||
* Daniel Veillard <veillard@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Horrible kludge to work around even more horrible name-space pollution
|
||||
via Python.h. That file includes /usr/include/python2.5/pyconfig*.h,
|
||||
which has over 180 autoconf-style HAVE_* definitions. Shame on them. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
#include <Python.h>
|
||||
#include "libvirt/libvirt-lxc.h"
|
||||
#include "libvirt/virterror.h"
|
||||
#include "typewrappers.h"
|
||||
#include "libvirt-lxc.h"
|
||||
#include "viralloc.h"
|
||||
#include "virfile.h"
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
extern void initlibvirtmod_lxc(void);
|
||||
#else
|
||||
extern void initcygvirtmod_lxc(void);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
# define DEBUG_ERROR 1
|
||||
#endif
|
||||
|
||||
#if DEBUG_ERROR
|
||||
# define DEBUG(fmt, ...) \
|
||||
printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
# define DEBUG(fmt, ...) \
|
||||
do {} while (0)
|
||||
#endif
|
||||
|
||||
/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
|
||||
is so common that we encapsulate it here. Now, each use is simply
|
||||
return VIR_PY_NONE; */
|
||||
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
|
||||
#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
|
||||
#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Statistics *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
static PyObject *
|
||||
libvirt_lxc_virDomainLxcOpenNamespace(PyObject *self ATTRIBUTE_UNUSED,
|
||||
PyObject *args) {
|
||||
PyObject *py_retval;
|
||||
virDomainPtr domain;
|
||||
PyObject *pyobj_domain;
|
||||
unsigned int flags;
|
||||
int c_retval;
|
||||
int *fdlist = NULL;
|
||||
int i;
|
||||
|
||||
if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainLxcOpenNamespace",
|
||||
&pyobj_domain, &flags))
|
||||
return NULL;
|
||||
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
||||
|
||||
if (domain == NULL)
|
||||
return VIR_PY_NONE;
|
||||
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||
c_retval = virDomainLxcOpenNamespace(domain, &fdlist, flags);
|
||||
LIBVIRT_END_ALLOW_THREADS;
|
||||
|
||||
if (c_retval < 0)
|
||||
return VIR_PY_NONE;
|
||||
|
||||
py_retval = PyList_New(c_retval);
|
||||
for (i = 0 ; i < c_retval ; i++) {
|
||||
PyObject *item = NULL;
|
||||
|
||||
if ((item = PyInt_FromLong(fdlist[i])) == NULL)
|
||||
goto error;
|
||||
|
||||
if (PyList_Append(py_retval, item) < 0) {
|
||||
Py_DECREF(item);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return py_retval;
|
||||
|
||||
error:
|
||||
for (i = 0 ; i < c_retval ; i++) {
|
||||
VIR_FORCE_CLOSE(fdlist[i]);
|
||||
}
|
||||
VIR_FREE(fdlist);
|
||||
return VIR_PY_NONE;
|
||||
}
|
||||
/************************************************************************
|
||||
* *
|
||||
* The registration stuff *
|
||||
* *
|
||||
************************************************************************/
|
||||
static PyMethodDef libvirtLxcMethods[] = {
|
||||
#include "libvirt-lxc-export.c"
|
||||
{(char *) "virDomainLxcOpenNamespace", libvirt_lxc_virDomainLxcOpenNamespace, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
void
|
||||
#ifndef __CYGWIN__
|
||||
initlibvirtmod_lxc
|
||||
#else
|
||||
initcygvirtmod_lxc
|
||||
#endif
|
||||
(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized != 0)
|
||||
return;
|
||||
|
||||
if (virInitialize() < 0)
|
||||
return;
|
||||
|
||||
/* initialize the python extension module */
|
||||
Py_InitModule((char *)
|
||||
#ifndef __CYGWIN__
|
||||
"libvirtmod_lxc"
|
||||
#else
|
||||
"cygvirtmod_lxc"
|
||||
#endif
|
||||
, libvirtLxcMethods);
|
||||
|
||||
initialized = 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user