WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Execute xc_linux_restore in a seperate process so that i

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Execute xc_linux_restore in a seperate process so that it can't
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Mon, 23 May 2005 22:34:18 +0000
Delivery-date: Tue, 24 May 2005 00:02:15 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Execute xc_linux_restore in a seperate process so that it can't, BitKeeper Bot <=