diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-05-23 22:34:38 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-05-23 22:34:38 +0000 |
commit | a822a7d28ecd945472fe2ba581a3ff1c9c1c6943 (patch) | |
tree | 07ef23f88fc5ad8984744b153d801d88385ed7a6 | |
parent | 5d89aeeda94dbdc5526f26c01fd6a22311ccdb05 (diff) | |
parent | 35db9d71b6f65c80fce40a110d0e8a58af8437b5 (diff) | |
download | xen-a822a7d28ecd945472fe2ba581a3ff1c9c1c6943.tar.gz xen-a822a7d28ecd945472fe2ba581a3ff1c9c1c6943.tar.bz2 xen-a822a7d28ecd945472fe2ba581a3ff1c9c1c6943.zip |
bitkeeper revision 1.1519 (42925a7e5ZIo431XTUQd8kj6omAbZA)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into firebug.cl.cam.ac.uk:/local/scratch/cl349/xen-unstable.bk-clean
-rw-r--r-- | .rootkeys | 3 | ||||
-rw-r--r-- | BitKeeper/etc/ignore | 3 | ||||
-rw-r--r-- | tools/Makefile | 1 | ||||
-rw-r--r-- | tools/libxc/xc_linux_restore.c | 4 | ||||
-rw-r--r-- | tools/python/xen/lowlevel/xc/xc.c | 50 | ||||
-rw-r--r-- | tools/python/xen/util/xpopen.py | 112 | ||||
-rw-r--r-- | tools/python/xen/xend/XendDomain.py | 29 | ||||
-rw-r--r-- | tools/xcutils/Makefile | 62 | ||||
-rw-r--r-- | tools/xcutils/xc_restore.c | 30 |
9 files changed, 252 insertions, 42 deletions
@@ -863,6 +863,7 @@ 41dde8b0yuJX-S79w4xJKxBQ-Mhp1A tools/python/xen/util/memmap.py 4288c6fcB1kUAqX0gzU85GGxmamS4Q tools/python/xen/util/process.py 4059c6a0pnxhG8hwSOivXybbGOwuXw tools/python/xen/util/tempfile.py +4292565fDy2PaatawinIckKB0cKusg tools/python/xen/util/xpopen.py 4267a9b16u4IEPhjRryesk6A17sobA tools/python/xen/web/SrvBase.py 4267a9b1FfCUjW7m9anLERcx9lwhJg tools/python/xen/web/SrvDir.py 4267a9b1uMXIfzB6-81ZLqMCyTgJmw tools/python/xen/web/__init__.py @@ -1029,6 +1030,8 @@ 41d58ba6R6foSMtSFEcu-yxWFrT8VQ tools/xcs/xcs.h 41d58ba6qyr2BkTcH2WlNBYLRyl2Yw tools/xcs/xcs_proto.h 41d58ba6ijEF6fedqRO5vFu7uCirZg tools/xcs/xcsdump.c +4292540couq-V0TPwyQ6bspNEWNcvw tools/xcutils/Makefile +42925407VysDb9O06OK_RUzTZxfLoA tools/xcutils/xc_restore.c 403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile 40a107afN60pFdURgBv9KwEzgRl5mQ tools/xentrace/formats 420d52d2_znVbT4JAPIU36vQOme83g tools/xentrace/xenctx.c diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index ad45f21a5f..a48ab6cff9 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -10,6 +10,7 @@ *~ BLOG BitKeeper/*/* +Makefile.rej PENDING/* TAGS Twisted-1.3.0.tar.gz @@ -125,6 +126,7 @@ tools/web-shutdown.tap tools/x2d2/minixend tools/xcs/xcs tools/xcs/xcsdump +tools/xcutils/xc_restore tools/xentrace/xentrace tools/xfrd/xfrd xen/BLOG @@ -149,4 +151,3 @@ xen/tools/figlet/figlet xen/xen xen/xen-syms xen/xen.* -Makefile.rej diff --git a/tools/Makefile b/tools/Makefile index 52ddb9f24b..9e6c159050 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,6 +10,7 @@ SUBDIRS += xentrace SUBDIRS += python SUBDIRS += xfrd SUBDIRS += xcs +SUBDIRS += xcutils SUBDIRS += pygrub .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 7d6aec2859..c679e9dd5a 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -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 --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 9e6396c75b..8132ff1047 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -63,6 +63,13 @@ static PyObject *pyxc_domain_dumpcore(PyObject *self, 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 @@ static PyObject *pyxc_linux_save(PyObject *self, 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 PyObject *pyxc_domain_memory_increase_reservation(PyObject *self, 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" @@ -1026,14 +1008,6 @@ static PyMethodDef pyxc_methods[] = { " 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, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/python/xen/util/xpopen.py b/tools/python/xen/util/xpopen.py new file mode 100644 index 0000000000..6b15121f09 --- /dev/null +++ b/tools/python/xen/util/xpopen.py @@ -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 --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index d45a3547df..2320e8758d 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -25,7 +25,11 @@ from xen.xend.server import channel 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 @@ class XendDomain: sizeof_int = calcsize("i") sizeof_unsigned_long = calcsize("L") PAGE_SIZE = 4096 + PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore" class XendFile(file): def read_exact(self, size, error_msg): @@ -367,7 +372,29 @@ class XendDomain: # underlying file descriptor ignore = fd.tell() - xc.linux_restore(fd.fileno(), int(dominfo.id), nr_pfns) + cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd.fileno()), + dominfo.id, str(nr_pfns)] + log.info("[xc_restore] " + join(cmd)) + child = xPopen3(cmd, True, -1, [fd.fileno(), xc.handle()]) + child.tochild.close() + + lasterr = "" + p = select.poll() + p.register(child.fromchild.fileno()) + p.register(child.childerr.fileno()) + while True: + r = p.poll() + for l in child.childerr.readlines(): + log.error(l.rstrip()) + lasterr = l.rstrip() + for l in child.fromchild.readlines(): + log.info(l.rstrip()) + if filter(lambda (fd, event): event & select.POLLHUP, r): + break + + if child.wait() != 0: + raise XendError("xc_restore failed: %s" % lasterr) + return dominfo except IOError, ex: diff --git a/tools/xcutils/Makefile b/tools/xcutils/Makefile new file mode 100644 index 0000000000..dbdc45d496 --- /dev/null +++ b/tools/xcutils/Makefile @@ -0,0 +1,62 @@ +# +# tools/xcutils/Makefile +# +# This file is subject to the terms and conditions of the GNU General +# Public License. See the file "COPYING" in the main directory of +# this archive for more details. +# +# Copyright (C) 2005 by Christian Limpach +# + +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 + +XEN_ROOT = ../.. +include $(XEN_ROOT)/tools/Rules.mk + +PROGRAMS_INSTALL_DIR = /usr/libexec/xen + +vpath %.h $(XEN_LIBXC) +INCLUDES += -I $(XEN_LIBXC) + +CC := gcc + +CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing +CFLAGS += $(INCLUDES) + +# Make gcc generate dependencies. +CFLAGS += -Wp,-MD,.$(@F).d +PROG_DEP = .*.d + +PROGRAMS = xc_restore + +xc_restore_OBJS = xc_restore.o +xc_restore_LIBS = xc + +.PHONY: all +all: build +build: $(PROGRAMS) + +define PROGRAM_template + $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) + ALL_OBJS += $$($(1)_OBJS) +endef + +$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) + +$(PROGRAMS): + $(LINK.o) $^ $(LDLIBS) -o $@ + +.PHONY: install +install: build + [ -d $(DESTDIR)$(PROGRAMS_INSTALL_DIR) ] || \ + $(INSTALL_DIR) $(DESTDIR)$(PROGRAMS_INSTALL_DIR) + $(INSTALL_PROG) $(PROGRAMS) $(DESTDIR)$(PROGRAMS_INSTALL_DIR) + + +clean: + $(RM) $(ALL_OBJS) $(PROGRAMS) + $(RM) $(PROG_DEP) + +-include $(PROG_DEP) diff --git a/tools/xcutils/xc_restore.c b/tools/xcutils/xc_restore.c new file mode 100644 index 0000000000..ebba6d698f --- /dev/null +++ b/tools/xcutils/xc_restore.c @@ -0,0 +1,30 @@ +/* + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of + * this archive for more details. + * + * Copyright (C) 2005 by Christian Limpach + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <err.h> + +#include <xc.h> + +int +main(int argc, char **argv) +{ + unsigned int xc_fd, io_fd, domid, nr_pfns; + + if (argc != 5) + errx(1, "usage: %s xcfd iofd domid nr_pfns", argv[0]); + + xc_fd = atoi(argv[1]); + io_fd = atoi(argv[2]); + domid = atoi(argv[3]); + nr_pfns = atoi(argv[4]); + + return xc_linux_restore(xc_fd, io_fd, domid, nr_pfns); +} |