[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Execute xc_linux_restore in a seperate process so that it can't
ChangeSet 1.1513.1.1, 2005/05/23 23:34:18+01:00, cl349@xxxxxxxxxxxxxxxxxxxx Execute xc_linux_restore in a seperate process so that it can't crash xend. Also handle errors passed from xc_linux_restore and log info messages from xc_linux_restore. XendDomain.py: Popen xc_restore instead of calling xc_linux_restore directly. xc.c: Add pyxc_handle exporting the file descriptor to the control interface. Remove xc_linux_restore -- replaced by popen of xc_restore directly from python. xc_linux_restore.c: Enable debug output. xpopen.py: Add xpopen functionality: Optionally exclude a list of file descriptors from being closed, allowing access to those file descriptors from the command. Remove unused parts. xpopen.py, Makefile, xc_restore.c: new file Makefile: Add xcutils subdir. ignore: Add tools/xcutils/xc_restore. Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> Makefile | 1 libxc/xc_linux_restore.c | 4 - python/xen/lowlevel/xc/xc.c | 50 ++++-------------- python/xen/util/xpopen.py | 112 ++++++++++++++++++++++++++++++++++++++++++ python/xen/xend/XendDomain.py | 29 ++++++++++ xcutils/Makefile | 62 +++++++++++++++++++++++ xcutils/xc_restore.c | 30 +++++++++++ 7 files changed, 247 insertions(+), 41 deletions(-) diff -Nru a/tools/Makefile b/tools/Makefile --- a/tools/Makefile 2005-05-23 20:02:59 -04:00 +++ b/tools/Makefile 2005-05-23 20:02:59 -04:00 @@ -10,6 +10,7 @@ SUBDIRS += python SUBDIRS += xfrd SUBDIRS += xcs +SUBDIRS += xcutils SUBDIRS += pygrub .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff -Nru a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c 2005-05-23 20:02:59 -04:00 +++ b/tools/libxc/xc_linux_restore.c 2005-05-23 20:02:59 -04:00 @@ -11,7 +11,7 @@ #define MAX_BATCH_SIZE 1024 -#define DEBUG 0 +#define DEBUG 01 #if 1 #define ERR(_f, _a...) fprintf ( stderr, _f , ## _a ) @@ -20,7 +20,7 @@ #endif #if DEBUG -#define DPRINTF(_f, _a...) fprintf ( stderr, _f , ## _a ) +#define DPRINTF(_f, _a...) fprintf ( stdout, _f , ## _a ) #else #define DPRINTF(_f, _a...) ((void)0) #endif diff -Nru a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c 2005-05-23 20:02:59 -04:00 +++ b/tools/python/xen/lowlevel/xc/xc.c 2005-05-23 20:02:59 -04:00 @@ -63,6 +63,13 @@ return NULL; } +static PyObject *pyxc_handle(PyObject *self) +{ + XcObject *xc = (XcObject *)self; + + return PyInt_FromLong(xc->xc_handle); +} + static PyObject *pyxc_domain_create(PyObject *self, PyObject *args, PyObject *kwds) @@ -334,36 +341,6 @@ return val; } -static PyObject *pyxc_linux_restore(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - PyObject *val = NULL; - int rc =-1; - int io_fd, dom; - unsigned long nr_pfns; - - static char *kwd_list[] = { "fd", "dom", "pfns", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iil", kwd_list, - &io_fd, &dom, &nr_pfns) ) - goto exit; - - rc = xc_linux_restore(xc->xc_handle, io_fd, dom, nr_pfns); - if ( rc != 0 ) - { - PyErr_SetFromErrno(xc_error); - goto exit; - } - - Py_INCREF(zero); - val = zero; - - exit: - return val; -} - static PyObject *pyxc_linux_build(PyObject *self, PyObject *args, PyObject *kwds) @@ -938,6 +915,11 @@ static PyMethodDef pyxc_methods[] = { + { "handle", + (PyCFunction)pyxc_handle, + 0, "\n" + "Query the xc control interface file descriptor.\n\n" + "Returns: [int] file descriptor\n" }, { "domain_create", (PyCFunction)pyxc_domain_create, METH_VARARGS | METH_KEYWORDS, "\n" @@ -1025,14 +1007,6 @@ " state_file [str]: Name of state file. Must not currently exist.\n" " progress [int, 1]: Bool - display a running progress indication?\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, - - { "linux_restore", - (PyCFunction)pyxc_linux_restore, - METH_VARARGS | METH_KEYWORDS, "\n" - "Restore the CPU and memory state of a Linux guest OS.\n" - " dom [int]: Identifier of domain to be restored.\n" - " pfns [int]: Number of pages domain uses.\n" - "Returns: [int] new domain identifier on success; -1 on error.\n" }, { "linux_build", (PyCFunction)pyxc_linux_build, diff -Nru a/tools/python/xen/util/xpopen.py b/tools/python/xen/util/xpopen.py --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/tools/python/xen/util/xpopen.py 2005-05-23 20:02:59 -04:00 @@ -0,0 +1,112 @@ +"""Spawn a command with pipes to its stdin, stdout, and optionally stderr. + +The normal os.popen(cmd, mode) call spawns a shell command and provides a +file interface to just the input or output of the process depending on +whether mode is 'r' or 'w'. This module provides the functions xpopen2(cmd) +and xpopen3(cmd) which return two or three pipes to the spawned command. +Optionally exclude a list of file descriptors from being closed, allowing +access to those file descriptors from the command. +""" + +import os +import sys + +try: + MAXFD = os.sysconf('SC_OPEN_MAX') +except (AttributeError, ValueError): + MAXFD = 256 + +_active = [] + +def _cleanup(): + for inst in _active[:]: + inst.poll() + +class xPopen3: + """Class representing a child process. Normally instances are created + by the factory functions popen2() and popen3().""" + + sts = -1 # Child not completed yet + + def __init__(self, cmd, capturestderr=False, bufsize=-1, passfd=()): + """The parameter 'cmd' is the shell command to execute in a + sub-process. The 'capturestderr' flag, if true, specifies that + the object should capture standard error output of the child process. + The default is false. If the 'bufsize' parameter is specified, it + specifies the size of the I/O buffers to/from the child process.""" + _cleanup() + self.passfd = passfd + p2cread, p2cwrite = os.pipe() + c2pread, c2pwrite = os.pipe() + if capturestderr: + errout, errin = os.pipe() + self.pid = os.fork() + if self.pid == 0: + # Child + os.dup2(p2cread, 0) + os.dup2(c2pwrite, 1) + if capturestderr: + os.dup2(errin, 2) + self._run_child(cmd) + os.close(p2cread) + self.tochild = os.fdopen(p2cwrite, 'w', bufsize) + os.close(c2pwrite) + self.fromchild = os.fdopen(c2pread, 'r', bufsize) + if capturestderr: + os.close(errin) + self.childerr = os.fdopen(errout, 'r', bufsize) + else: + self.childerr = None + _active.append(self) + + def _run_child(self, cmd): + if isinstance(cmd, basestring): + cmd = ['/bin/sh', '-c', cmd] + for i in range(3, MAXFD): + if i in self.passfd: + continue + try: + os.close(i) + except OSError: + pass + try: + os.execvp(cmd[0], cmd) + finally: + os._exit(1) + + def poll(self): + """Return the exit status of the child process if it has finished, + or -1 if it hasn't finished yet.""" + if self.sts < 0: + try: + pid, sts = os.waitpid(self.pid, os.WNOHANG) + if pid == self.pid: + self.sts = sts + _active.remove(self) + except os.error: + pass + return self.sts + + def wait(self): + """Wait for and return the exit status of the child process.""" + if self.sts < 0: + pid, sts = os.waitpid(self.pid, 0) + if pid == self.pid: + self.sts = sts + _active.remove(self) + return self.sts + + +def xpopen2(cmd, bufsize=-1, mode='t', passfd=[]): + """Execute the shell command 'cmd' in a sub-process. If 'bufsize' is + specified, it sets the buffer size for the I/O pipes. The file objects + (child_stdout, child_stdin) are returned.""" + inst = xPopen3(cmd, False, bufsize, passfd) + return inst.fromchild, inst.tochild + +def xpopen3(cmd, bufsize=-1, mode='t', passfd=[]): + """Execute the shell command 'cmd' in a sub-process. If 'bufsize' is + specified, it sets the buffer size for the I/O pipes. The file objects + (child_stdout, child_stdin, child_stderr) are returned.""" + inst = xPopen3(cmd, True, bufsize, passfd) + return inst.fromchild, inst.tochild, inst.childerr diff -Nru a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py 2005-05-23 20:02:59 -04:00 +++ b/tools/python/xen/xend/XendDomain.py 2005-05-23 20:02:59 -04:00 @@ -25,7 +25,11 @@ import errno +import os +import select +from string import join from struct import pack, unpack, calcsize +from xen.util.xpopen import xPopen3 __all__ = [ "XendDomain" ] @@ -325,6 +329,7 @@ sizeof_int = calcsize("i") sizeof_unsigned_long = calcsize("L") PAGE_SIZE = 4096 + PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore" _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |