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
|