ia64/xen-unstable
changeset 4677:20d715ae2dfb
bitkeeper revision 1.1327.2.13 (4270d6c35WpxFmhdkREjmSvk82s-Bg)
Merge Jeremy's pygrub bootloader patch.
Signed-off-by: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Mike Wray <mike.wray@hp.com>
Merge Jeremy's pygrub bootloader patch.
Signed-off-by: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Mike Wray <mike.wray@hp.com>
author | mjw@wray-m-3.hpl.hp.com |
---|---|
date | Thu Apr 28 12:27:47 2005 +0000 (2005-04-28) |
parents | 6639dd8a166b |
children | ed1b8fd45247 |
files | .rootkeys tools/Makefile tools/pygrub/Makefile tools/pygrub/setup.py tools/pygrub/src/GrubConf.py tools/pygrub/src/__init__.py tools/pygrub/src/fsys/__init__.py tools/pygrub/src/fsys/ext2/__init__.py tools/pygrub/src/fsys/ext2/ext2module.c tools/pygrub/src/fsys/ext2/test.py tools/pygrub/src/pygrub tools/python/xen/xend/XendBootloader.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/blkif.py tools/python/xen/xm/create.py tools/xfrd/xfrd.c |
line diff
1.1 --- a/.rootkeys Thu Apr 28 08:59:31 2005 +0000 1.2 +++ b/.rootkeys Thu Apr 28 12:27:47 2005 +0000 1.3 @@ -799,6 +799,15 @@ 41adc641dV-0cDLSyzMs5BT8nL7v3Q tools/mis 1.4 4107986eMWVdBoz4tXYoOscpN_BCYg tools/misc/xensv 1.5 4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops 1.6 40cf2937dqM1jWW87O5OoOYND8leuA tools/misc/xm 1.7 +4270cc81g3nSNYCZ1ryCMDEbLtMtbQ tools/pygrub/Makefile 1.8 +4270cc81EIl7NyaS3Av6IPRk2c2a6Q tools/pygrub/setup.py 1.9 +4270cc81t7eNCDp4Bhbh58p1CNxaCQ tools/pygrub/src/GrubConf.py 1.10 +4270d6c2fWF4r5-zF1pSuAFwUZS0aA tools/pygrub/src/__init__.py 1.11 +4270cc81CzKMiujDPWcaYhu709vGXw tools/pygrub/src/fsys/__init__.py 1.12 +4270cc81RTIiq9si0dI4YRTRE4KRMw tools/pygrub/src/fsys/ext2/__init__.py 1.13 +4270cc81YCYa4pexivBD2NdLE2F_Pg tools/pygrub/src/fsys/ext2/ext2module.c 1.14 +4270cc81o4BL5e8Cs87aSi8EXA5NtQ tools/pygrub/src/fsys/ext2/test.py 1.15 +4270cc81TS6L_tEO6wSp5wcURcpldQ tools/pygrub/src/pygrub 1.16 40c9c468icGyC5RAF1bRKsCXPDCvsA tools/python/Makefile 1.17 40ffc44dOwe1CcYXGCkYHdG_NxcccA tools/python/logging/logging-0.4.9.2/PKG-INFO 1.18 40ffc44dpqpgqgrnLfR70PsiBc3liA tools/python/logging/logging-0.4.9.2/README.txt 1.19 @@ -896,6 +905,7 @@ 41597996WNvJA-DVCBmc0xU9w_XmoA tools/pyt 1.20 40c9c468Um_qc66OQeLEceIz1pgD5g tools/python/xen/xend/EventServer.py 1.21 40c9c468QJTEuk9g4qHxGpmIi70PEQ tools/python/xen/xend/PrettyPrint.py 1.22 40e15b7eeQxWE_hUPB2YTgM9fsZ1PQ tools/python/xen/xend/Vifctl.py 1.23 +4270cc81xbweGYhsM4326N3dX1bGHQ tools/python/xen/xend/XendBootloader.py 1.24 40c9c4688m3eqnC8fhLu1APm36VOVA tools/python/xen/xend/XendClient.py 1.25 40c9c468t6iIKTjwuYoe-UMCikDcOQ tools/python/xen/xend/XendConsole.py 1.26 40c9c468WnXs6eOUSff23IIGI4kMfQ tools/python/xen/xend/XendDB.py
2.1 --- a/tools/Makefile Thu Apr 28 08:59:31 2005 +0000 2.2 +++ b/tools/Makefile Thu Apr 28 12:27:47 2005 +0000 2.3 @@ -11,6 +11,7 @@ SUBDIRS += python 2.4 SUBDIRS += xfrd 2.5 SUBDIRS += xcs 2.6 SUBDIRS += ioemu 2.7 +SUBDIRS += pygrub 2.8 2.9 .PHONY: all install clean check check_clean 2.10
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/pygrub/Makefile Thu Apr 28 12:27:47 2005 +0000 3.3 @@ -0,0 +1,18 @@ 3.4 + 3.5 +XEN_ROOT = ../.. 3.6 +include $(XEN_ROOT)/tools/Rules.mk 3.7 + 3.8 +all: build 3.9 +build: 3.10 + CFLAGS="$(CFLAGS)" python setup.py build 3.11 + 3.12 +ifndef XEN_PYTHON_NATIVE_INSTALL 3.13 +install: all 3.14 + CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" 3.15 +else 3.16 +install: all 3.17 + CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" 3.18 +endif 3.19 + 3.20 +clean: 3.21 + rm -rf build *.pyc *.pyo *.o *.a *~
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/tools/pygrub/setup.py Thu Apr 28 12:27:47 2005 +0000 4.3 @@ -0,0 +1,25 @@ 4.4 +from distutils.core import setup, Extension 4.5 +import os 4.6 + 4.7 +extra_compile_args = [ "-fno-strict-aliasing", "-Wall", "-Werror" ] 4.8 + 4.9 +# in a perfect world, we'd figure out the fsys modules dynamically 4.10 +ext2 = Extension("grub.fsys.ext2._pyext2", 4.11 + extra_compile_args = extra_compile_args, 4.12 + libraries = ["ext2fs"], 4.13 + sources = ["src/fsys/ext2/ext2module.c"]) 4.14 + 4.15 +setup(name='pygrub', 4.16 + version='0.1', 4.17 + description='Boot loader that looks a lot like grub for Xen', 4.18 + author='Jeremy Katz', 4.19 + author_email='katzj@redhat.com', 4.20 + license='GPL', 4.21 + package_dir={'grub': 'src'}, 4.22 + scripts = ["src/pygrub"], 4.23 + packages=['grub', 4.24 + 'grub.fsys', 4.25 + 'grub.fsys.ext2'], 4.26 + ext_modules = [ext2] 4.27 + ) 4.28 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/pygrub/src/GrubConf.py Thu Apr 28 12:27:47 2005 +0000 5.3 @@ -0,0 +1,229 @@ 5.4 +# 5.5 +# GrubConf.py - Simple grub.conf parsing 5.6 +# 5.7 +# Copyright 2005 Red Hat, Inc. 5.8 +# Jeremy Katz <katzj@redhat.com> 5.9 +# 5.10 +# This software may be freely redistributed under the terms of the GNU 5.11 +# general public license. 5.12 +# 5.13 +# You should have received a copy of the GNU General Public License 5.14 +# along with this program; if not, write to the Free Software 5.15 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 5.16 +# 5.17 + 5.18 +import os, sys 5.19 +import logging 5.20 + 5.21 +def grub_split(s, maxsplit = -1): 5.22 + """Split a grub option screen separated with either '=' or whitespace.""" 5.23 + eq = s.find('=') 5.24 + if eq == -1: 5.25 + return s.split(None, maxsplit) 5.26 + 5.27 + # see which of a space or tab is first 5.28 + sp = s.find(' ') 5.29 + tab = s.find('\t') 5.30 + if (tab != -1 and tab < sp) or (tab != -1 and sp == -1): 5.31 + sp = tab 5.32 + 5.33 + if eq != -1 and eq < sp or (eq != -1 and sp == -1): 5.34 + return s.split('=', maxsplit) 5.35 + else: 5.36 + return s.split(None, maxsplit) 5.37 + 5.38 +def get_path(s): 5.39 + """Returns a tuple of (GrubDiskPart, path) corresponding to string.""" 5.40 + if not s.startswith('('): 5.41 + return (None, s) 5.42 + idx = s.find(')') 5.43 + if idx == -1: 5.44 + raise ValueError, "Unable to find matching ')'" 5.45 + d = s[:idx] 5.46 + return (GrubDiskPart(d), s[idx + 1:]) 5.47 + 5.48 +class GrubDiskPart(object): 5.49 + def __init__(self, str): 5.50 + if str.find(',') != -1: 5.51 + (self.disk, self.part) = str.split(",", 2) 5.52 + else: 5.53 + self.disk = str 5.54 + self.part = None 5.55 + 5.56 + def __repr__(self): 5.57 + if self.part is not None: 5.58 + return "d%dp%d" %(self.disk, self.part) 5.59 + else: 5.60 + return "d%d" %(self,disk,) 5.61 + 5.62 + def get_disk(self): 5.63 + return self._disk 5.64 + def set_disk(self, val): 5.65 + val = val.replace("(", "").replace(")", "") 5.66 + self._disk = int(val[2:]) 5.67 + disk = property(get_disk, set_disk) 5.68 + 5.69 + def get_part(self): 5.70 + return self._part 5.71 + def set_part(self, val): 5.72 + if val is None: 5.73 + self._part = val 5.74 + return 5.75 + val = val.replace("(", "").replace(")", "") 5.76 + self._part = int(val) 5.77 + part = property(get_part, set_part) 5.78 + 5.79 +class GrubImage(object): 5.80 + def __init__(self, lines): 5.81 + self._root = self._initrd = self._kernel = self._args = None 5.82 + for l in lines: 5.83 + (com, arg) = grub_split(l, 1) 5.84 + 5.85 + if self.commands.has_key(com): 5.86 + if self.commands[com] is not None: 5.87 + exec("%s = r\"%s\"" %(self.commands[com], arg.strip())) 5.88 + else: 5.89 + logging.info("Ignored image directive %s" %(com,)) 5.90 + else: 5.91 + logging.warning("Unknown image directive %s" %(com,)) 5.92 + 5.93 + def __repr__(self): 5.94 + return ("title: %s\n" 5.95 + " root: %s\n" 5.96 + " kernel: %s\n" 5.97 + " args: %s\n" 5.98 + " initrd: %s" %(self.title, self.root, self.kernel, 5.99 + self.args, self.initrd)) 5.100 + 5.101 + def set_root(self, val): 5.102 + self._root = GrubDiskPart(val) 5.103 + def get_root(self): 5.104 + return self._root 5.105 + root = property(get_root, set_root) 5.106 + 5.107 + def set_kernel(self, val): 5.108 + if val.find(" ") == -1: 5.109 + self._kernel = get_path(val) 5.110 + self._args = None 5.111 + return 5.112 + (kernel, args) = val.split(None, 1) 5.113 + self._kernel = get_path(kernel) 5.114 + self._args = args 5.115 + def get_kernel(self): 5.116 + return self._kernel 5.117 + def get_args(self): 5.118 + return self._args 5.119 + kernel = property(get_kernel, set_kernel) 5.120 + args = property(get_args) 5.121 + 5.122 + def set_initrd(self, val): 5.123 + self._initrd = get_path(val) 5.124 + def get_initrd(self): 5.125 + return self._initrd 5.126 + initrd = property(get_initrd, set_initrd) 5.127 + 5.128 + # set up command handlers 5.129 + commands = { "title": "self.title", 5.130 + "root": "self.root", 5.131 + "rootnoverify": "self.root", 5.132 + "kernel": "self.kernel", 5.133 + "initrd": "self.initrd", 5.134 + "chainloader": None, 5.135 + "module": None} 5.136 + 5.137 + 5.138 +class GrubConfigFile(object): 5.139 + def __init__(self, fn = None): 5.140 + self.filename = fn 5.141 + self.images = [] 5.142 + self.timeout = -1 5.143 + 5.144 + if fn is not None: 5.145 + self.parse() 5.146 + 5.147 + def parse(self, buf = None): 5.148 + if buf is None: 5.149 + if self.filename is None: 5.150 + raise ValueError, "No config file defined to parse!" 5.151 + 5.152 + f = open(self.filename, 'r') 5.153 + lines = f.readlines() 5.154 + f.close() 5.155 + else: 5.156 + lines = buf.split("\n") 5.157 + 5.158 + img = [] 5.159 + for l in lines: 5.160 + l = l.strip() 5.161 + # skip blank lines 5.162 + if len(l) == 0: 5.163 + continue 5.164 + # skip comments 5.165 + if l.startswith('#'): 5.166 + continue 5.167 + # new image 5.168 + if l.startswith("title"): 5.169 + if len(img) > 0: 5.170 + self.images.append(GrubImage(img)) 5.171 + img = [l] 5.172 + continue 5.173 + 5.174 + if len(img) > 0: 5.175 + img.append(l) 5.176 + continue 5.177 + 5.178 + try: 5.179 + (com, arg) = grub_split(l, 1) 5.180 + except ValueError: 5.181 + com = l 5.182 + arg = "" 5.183 + 5.184 + if self.commands.has_key(com): 5.185 + if self.commands[com] is not None: 5.186 + exec("%s = r\"%s\"" %(self.commands[com], arg.strip())) 5.187 + else: 5.188 + logging.info("Ignored directive %s" %(com,)) 5.189 + else: 5.190 + logging.warning("Unknown directive %s" %(com,)) 5.191 + 5.192 + if len(img) > 0: 5.193 + self.images.append(GrubImage(img)) 5.194 + 5.195 + def _get_default(self): 5.196 + return self._default 5.197 + def _set_default(self, val): 5.198 + if val == "saved": 5.199 + self._default = -1 5.200 + else: 5.201 + self._default = int(val) 5.202 + 5.203 + if self._default < 0: 5.204 + raise ValueError, "default must be positive number" 5.205 + default = property(_get_default, _set_default) 5.206 + 5.207 + def set_splash(self, val): 5.208 + self._splash = get_path(val) 5.209 + def get_splash(self): 5.210 + return self._splash 5.211 + splash = property(get_splash, set_splash) 5.212 + 5.213 + # set up command handlers 5.214 + commands = { "default": "self.default", 5.215 + "timeout": "self.timeout", 5.216 + "fallback": "self.fallback", 5.217 + "hiddenmenu": "self.hiddenmenu", 5.218 + "splashimage": "self.splash", 5.219 + "password": "self.password" } 5.220 + for c in ("bootp", "color", "device", "dhcp", "hide", "ifconfig", 5.221 + "pager", "partnew", "parttype", "rarp", "serial", 5.222 + "setkey", "terminal", "terminfo", "tftpserver", "unhide"): 5.223 + commands[c] = None 5.224 + del c 5.225 + 5.226 + 5.227 +if __name__ == "__main__": 5.228 + if sys.argv < 2: 5.229 + raise RuntimeError, "Need a grub.conf to read" 5.230 + g = GrubConfigFile(sys.argv[1]) 5.231 + for i in g.images: 5.232 + print i #, i.title, i.root, i.kernel, i.args, i.initrd
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tools/pygrub/src/fsys/__init__.py Thu Apr 28 12:27:47 2005 +0000 7.3 @@ -0,0 +1,61 @@ 7.4 +# 7.5 +# Copyright 2005 Red Hat, Inc. 7.6 +# Jeremy Katz <katzj@xxxxxxxxxx> 7.7 +# 7.8 +# This software may be freely redistributed under the terms of the GNU 7.9 +# general public license. 7.10 +# 7.11 +# You should have received a copy of the GNU General Public License 7.12 +# along with this program; if not, write to the Free Software 7.13 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 7.14 +# 7.15 + 7.16 +import os 7.17 +import sys 7.18 + 7.19 +fstypes = {} 7.20 + 7.21 +def register_fstype(x): 7.22 + if x.name in fstypes.keys(): 7.23 + return 7.24 + fstypes[x.name] = x 7.25 + 7.26 +class FileSystemType(object): 7.27 + """A simple representation for a file system that gives a fs name 7.28 + and a method for sniffing a file to see if it's of the given fstype.""" 7.29 + def __init__(self): 7.30 + self.name = "" 7.31 + 7.32 + def sniff_magic(self, fn, offset = 0): 7.33 + """Look at the filesystem at fn for the appropriate magic starting at 7.34 + offset offset.""" 7.35 + raise RuntimeError, "sniff_magic not implemented" 7.36 + 7.37 + def open_fs(self, fn, offset = 0): 7.38 + """Open the given filesystem and return a filesystem object.""" 7.39 + raise RuntimeError, "open_fs not implemented" 7.40 + 7.41 +class FileSystem(object): 7.42 + def open(self, name, flags = 0, block_size = 0): 7.43 + """Open the fsys on name with given flags and block_size.""" 7.44 + raise RuntimeError, "open not implemented" 7.45 + 7.46 + def close(self): 7.47 + """Close the fsys.""" 7.48 + raise RuntimeError, "close not implemented" 7.49 + 7.50 + def open_file(self, file, flags = None): 7.51 + """Open the file 'name' with the given flags. The returned object 7.52 + should look similar to a native file object.""" 7.53 + raise RuntimeError, "open_file not implemented" 7.54 + 7.55 + 7.56 + 7.57 +mydir = sys.modules['grub.fsys'].__path__[0] 7.58 +for f in os.listdir(mydir): 7.59 + if not os.path.isdir("%s/%s" %(mydir, f)): 7.60 + continue 7.61 + try: 7.62 + exec "import grub.fsys.%s" %(f,) 7.63 + except ImportError, e: 7.64 + pass
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/tools/pygrub/src/fsys/ext2/__init__.py Thu Apr 28 12:27:47 2005 +0000 8.3 @@ -0,0 +1,38 @@ 8.4 +# Copyright 2005 Red Hat, Inc. 8.5 +# Jeremy Katz <katzj@redhat.com> 8.6 +# 8.7 +# This software may be freely redistributed under the terms of the GNU 8.8 +# general public license. 8.9 +# 8.10 +# You should have received a copy of the GNU General Public License 8.11 +# along with this program; if not, write to the Free Software 8.12 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 8.13 +# 8.14 + 8.15 +from grub.fsys import register_fstype, FileSystemType 8.16 +from _pyext2 import * 8.17 + 8.18 +import os, struct 8.19 + 8.20 +class Ext2FileSystemType(FileSystemType): 8.21 + def __init__(self): 8.22 + FileSystemType.__init__(self) 8.23 + self.name = "ext2" 8.24 + 8.25 + def sniff_magic(self, fn, offset = 0): 8.26 + fd = os.open(fn, os.O_RDONLY) 8.27 + os.lseek(fd, offset, 0) 8.28 + buf = os.read(fd, 2048) 8.29 + 8.30 + if len(buf) > 1082 and \ 8.31 + struct.unpack("<H", buf[1080:1082]) == (0xef53,): 8.32 + return True 8.33 + return False 8.34 + 8.35 + def open_fs(self, fn, offset = 0): 8.36 + if not self.sniff_magic(fn, offset): 8.37 + raise ValueError, "Not an ext2 filesystem" 8.38 + return Ext2Fs(fn) 8.39 + 8.40 +register_fstype(Ext2FileSystemType()) 8.41 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/pygrub/src/fsys/ext2/ext2module.c Thu Apr 28 12:27:47 2005 +0000 9.3 @@ -0,0 +1,332 @@ 9.4 +/* 9.5 + * ext2module.c - simple python binding for libext2fs 9.6 + * 9.7 + * Copyright 2005 Red Hat, Inc. 9.8 + * Jeremy Katz <katzj@redhat.com> 9.9 + * 9.10 + * This software may be freely redistributed under the terms of the GNU 9.11 + * general public license. 9.12 + * 9.13 + * You should have received a copy of the GNU General Public License 9.14 + * along with this program; if not, write to the Free Software 9.15 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 9.16 + */ 9.17 + 9.18 +#include <Python.h> 9.19 + 9.20 +#include <ext2fs/ext2fs.h> 9.21 +#include <stdlib.h> 9.22 +#include <stdio.h> 9.23 + 9.24 +#if (PYTHON_API_VERSION >= 1011) 9.25 +#define PY_PAD 0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L,0L 9.26 +#else 9.27 +#define PY_PAD 0L,0L,0L,0L 9.28 +#endif 9.29 + 9.30 + 9.31 +/* global error object */ 9.32 +PyObject *Ext2Error; 9.33 + 9.34 +typedef struct _Ext2Fs Ext2Fs; 9.35 +struct _Ext2Fs { 9.36 + PyObject_HEAD; 9.37 + ext2_filsys fs; 9.38 +}; 9.39 + 9.40 +typedef struct _Ext2File Ext2File; 9.41 +struct _Ext2File { 9.42 + PyObject_HEAD; 9.43 + ext2_file_t file; 9.44 +}; 9.45 + 9.46 +/* ext2 file object */ 9.47 + 9.48 +static PyObject * 9.49 +ext2_file_close (Ext2File *file, PyObject *args) 9.50 +{ 9.51 + if (file->file != NULL) 9.52 + ext2fs_file_close(file->file); 9.53 + Py_INCREF(Py_None); 9.54 + return Py_None; 9.55 +} 9.56 + 9.57 +static PyObject * 9.58 +ext2_file_read (Ext2File *file, PyObject *args) 9.59 +{ 9.60 + int err, size = 0; 9.61 + size_t n, total = 0; 9.62 + PyObject * buffer = NULL; 9.63 + 9.64 + if (file->file == NULL) { 9.65 + PyErr_SetString(PyExc_ValueError, "Cannot read from closed file"); 9.66 + return NULL; 9.67 + } 9.68 + 9.69 + if (!PyArg_ParseTuple(args, "|i", &size)) 9.70 + return NULL; 9.71 + 9.72 + buffer = PyString_FromStringAndSize((char *) NULL, (size) ? size : 4096); 9.73 + if (buffer == NULL) 9.74 + return buffer; 9.75 + 9.76 + while (1) { 9.77 + err = ext2fs_file_read(file->file, PyString_AS_STRING(buffer) + total, 9.78 + (size) ? size : 4096, &n); 9.79 + if (err) { 9.80 + if (buffer != NULL) { Py_DECREF(buffer); } 9.81 + Py_DECREF(buffer); 9.82 + PyErr_SetString(PyExc_ValueError, "read error"); 9.83 + return NULL; 9.84 + } 9.85 + 9.86 + total += n; 9.87 + if (n == 0) 9.88 + break; 9.89 + 9.90 + if (size && size == total) 9.91 + break; 9.92 + 9.93 + if (!size) { 9.94 + _PyString_Resize(&buffer, total + 4096); 9.95 + } 9.96 + } 9.97 + 9.98 + _PyString_Resize(&buffer, total); 9.99 + return buffer; 9.100 +} 9.101 + 9.102 +static void 9.103 +ext2_file_dealloc (Ext2File * file) 9.104 +{ 9.105 + if (file->file != NULL) 9.106 + ext2fs_file_close(file->file); 9.107 + PyMem_DEL(file); 9.108 +} 9.109 + 9.110 +static struct PyMethodDef Ext2FileMethods[] = { 9.111 + { "close", 9.112 + (PyCFunction) ext2_file_close, 9.113 + METH_VARARGS, NULL }, 9.114 + { "read", 9.115 + (PyCFunction) ext2_file_read, 9.116 + METH_VARARGS, NULL }, 9.117 + { NULL, NULL, 0, NULL } 9.118 +}; 9.119 + 9.120 +static PyObject * 9.121 +ext2_file_getattr (Ext2File * file, char * name) 9.122 +{ 9.123 + return Py_FindMethod (Ext2FileMethods, (PyObject *) file, name); 9.124 +} 9.125 + 9.126 +static char Ext2FileType__doc__[] = "This is the ext2 filesystem object"; 9.127 +PyTypeObject Ext2FileType = { 9.128 + PyObject_HEAD_INIT(&PyType_Type) 9.129 + 0, /* ob_size */ 9.130 + "Ext2File", /* tp_name */ 9.131 + sizeof(Ext2File), /* tp_size */ 9.132 + 0, /* tp_itemsize */ 9.133 + (destructor) ext2_file_dealloc, /* tp_dealloc */ 9.134 + 0, /* tp_print */ 9.135 + (getattrfunc) ext2_file_getattr, /* tp_getattr */ 9.136 + 0, /* tp_setattr */ 9.137 + 0, /* tp_compare */ 9.138 + 0, /* tp_repr */ 9.139 + 0, /* tp_as_number */ 9.140 + 0, /* tp_as_sequence */ 9.141 + 0, /* tp_as_mapping */ 9.142 + 0, /* tp_hash */ 9.143 + 0, /* tp_call */ 9.144 + 0, /* tp_str */ 9.145 + 0, /* tp_getattro */ 9.146 + 0, /* tp_setattro */ 9.147 + 0, /* tp_as_buffer */ 9.148 + 0L, /* tp_flags */ 9.149 + Ext2FileType__doc__, 9.150 + PY_PAD 9.151 +}; 9.152 + 9.153 +static PyObject * 9.154 +ext2_file_open (Ext2Fs *fs, char * name, int flags) 9.155 +{ 9.156 + int err; 9.157 + ext2_file_t f; 9.158 + ext2_ino_t ino; 9.159 + Ext2File * file; 9.160 + 9.161 + file = (Ext2File *) PyObject_NEW(Ext2File, &Ext2FileType); 9.162 + file->file = NULL; 9.163 + 9.164 + err = ext2fs_namei_follow(fs->fs, EXT2_ROOT_INO, EXT2_ROOT_INO, name, &ino); 9.165 + if (err) { 9.166 + PyErr_SetString(PyExc_ValueError, "unable to open file"); 9.167 + return NULL; 9.168 + } 9.169 + 9.170 + err = ext2fs_file_open(fs->fs, ino, flags, &f); 9.171 + if (err) { 9.172 + PyErr_SetString(PyExc_ValueError, "unable to open file"); 9.173 + return NULL; 9.174 + } 9.175 + 9.176 + file->file = f; 9.177 + return (PyObject *) file; 9.178 +} 9.179 + 9.180 +/* ext2fs object */ 9.181 + 9.182 +static PyObject * 9.183 +ext2_fs_close (Ext2Fs *fs, PyObject *args) 9.184 +{ 9.185 + if (fs->fs != NULL) 9.186 + ext2fs_close(fs->fs); 9.187 + Py_INCREF(Py_None); 9.188 + return Py_None; 9.189 +} 9.190 + 9.191 +static PyObject * 9.192 +ext2_fs_open (Ext2Fs *fs, PyObject *args, PyObject *kwargs) 9.193 +{ 9.194 + static char *kwlist[] = { "name", "flags", "superblock", 9.195 + "block_size", NULL }; 9.196 + char * name; 9.197 + int flags = 0, superblock = 0, err; 9.198 + unsigned int block_size = 0; 9.199 + ext2_filsys efs; 9.200 + 9.201 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, 9.202 + &name, &flags, &superblock, &block_size)) 9.203 + return NULL; 9.204 + 9.205 + if (fs->fs != NULL) { 9.206 + PyErr_SetString(PyExc_ValueError, "already have an fs object"); 9.207 + return NULL; 9.208 + } 9.209 + 9.210 + err = ext2fs_open(name, flags, superblock, block_size, 9.211 + unix_io_manager, &efs); 9.212 + if (err) { 9.213 + PyErr_SetString(PyExc_ValueError, "unable to open file"); 9.214 + return NULL; 9.215 + } 9.216 + 9.217 + fs->fs = efs; 9.218 + 9.219 + Py_INCREF(Py_None); 9.220 + return Py_None; 9.221 +} 9.222 + 9.223 +static PyObject * 9.224 +ext2_fs_open_file (Ext2Fs *fs, PyObject *args, PyObject *kwargs) 9.225 +{ 9.226 + static char *kwlist[] = { "name", "flags", NULL }; 9.227 + char * name; 9.228 + int flags = 0; 9.229 + 9.230 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", kwlist, 9.231 + &name, &flags)) 9.232 + return NULL; 9.233 + 9.234 + return ext2_file_open(fs, name, flags); 9.235 +} 9.236 + 9.237 +static void 9.238 +ext2_fs_dealloc (Ext2Fs * fs) 9.239 +{ 9.240 + if (fs->fs != NULL) 9.241 + ext2fs_close(fs->fs); 9.242 + PyMem_DEL(fs); 9.243 +} 9.244 + 9.245 +static struct PyMethodDef Ext2FsMethods[] = { 9.246 + { "close", 9.247 + (PyCFunction) ext2_fs_close, 9.248 + METH_VARARGS, NULL }, 9.249 + { "open", 9.250 + (PyCFunction) ext2_fs_open, 9.251 + METH_VARARGS|METH_KEYWORDS, NULL }, 9.252 + { "open_file", 9.253 + (PyCFunction) ext2_fs_open_file, 9.254 + METH_VARARGS|METH_KEYWORDS, NULL }, 9.255 + { NULL, NULL, 0, NULL } 9.256 +}; 9.257 + 9.258 +static PyObject * 9.259 +ext2_fs_getattr (Ext2Fs * fs, char * name) 9.260 +{ 9.261 + return Py_FindMethod (Ext2FsMethods, (PyObject *) fs, name); 9.262 +} 9.263 + 9.264 +static char Ext2FsType__doc__[] = "This is the ext2 filesystem object"; 9.265 +PyTypeObject Ext2FsType = { 9.266 + PyObject_HEAD_INIT(&PyType_Type) 9.267 + 0, /* ob_size */ 9.268 + "Ext2Fs", /* tp_name */ 9.269 + sizeof(Ext2Fs), /* tp_size */ 9.270 + 0, /* tp_itemsize */ 9.271 + (destructor) ext2_fs_dealloc, /* tp_dealloc */ 9.272 + 0, /* tp_print */ 9.273 + (getattrfunc) ext2_fs_getattr, /* tp_getattr */ 9.274 + 0, /* tp_setattr */ 9.275 + 0, /* tp_compare */ 9.276 + 0, /* tp_repr */ 9.277 + 0, /* tp_as_number */ 9.278 + 0, /* tp_as_sequence */ 9.279 + 0, /* tp_as_mapping */ 9.280 + 0, /* tp_hash */ 9.281 + 0, /* tp_call */ 9.282 + 0, /* tp_str */ 9.283 + 0, /* tp_getattro */ 9.284 + 0, /* tp_setattro */ 9.285 + 0, /* tp_as_buffer */ 9.286 + 0L, /* tp_flags */ 9.287 + Ext2FsType__doc__, 9.288 + PY_PAD 9.289 +}; 9.290 + 9.291 +static PyObject * 9.292 +ext2_fs_new(PyObject *o, PyObject *args, PyObject *kwargs) 9.293 +{ 9.294 + static char *kwlist[] = { "name", "flags", "superblock", 9.295 + "block_size", NULL }; 9.296 + char * name; 9.297 + int flags = 0, superblock = 0; 9.298 + unsigned int block_size = 0; 9.299 + Ext2Fs *pfs; 9.300 + 9.301 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iii", kwlist, 9.302 + &name, &flags, &superblock, &block_size)) 9.303 + return NULL; 9.304 + 9.305 + pfs = (Ext2Fs *) PyObject_NEW(Ext2Fs, &Ext2FsType); 9.306 + if (pfs == NULL) 9.307 + return NULL; 9.308 + pfs->fs = NULL; 9.309 + 9.310 + if (!ext2_fs_open(pfs, 9.311 + Py_BuildValue("siii", name, flags, superblock, block_size), 9.312 + NULL)) 9.313 + return NULL; 9.314 + 9.315 + return (PyObject *)pfs; 9.316 +} 9.317 + 9.318 + 9.319 +static struct PyMethodDef Ext2ModuleMethods[] = { 9.320 + { "Ext2Fs", (PyCFunction) ext2_fs_new, METH_VARARGS|METH_KEYWORDS, NULL }, 9.321 + { NULL, NULL, 0, NULL } 9.322 +}; 9.323 + 9.324 + 9.325 +void init_pyext2(void) { 9.326 + PyObject *m, *d; 9.327 + 9.328 + m = Py_InitModule("_pyext2", Ext2ModuleMethods); 9.329 + d = PyModule_GetDict(m); 9.330 + 9.331 + /* o = PyObject_NEW(PyObject, yExt2FsConstructorType); 9.332 + PyDict_SetItemString(d, "PyExt2Fs", o); 9.333 + Py_DECREF(o);*/ 9.334 + 9.335 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/pygrub/src/fsys/ext2/test.py Thu Apr 28 12:27:47 2005 +0000 10.3 @@ -0,0 +1,15 @@ 10.4 +#!/usr/bin/python 10.5 + 10.6 + 10.7 +import _pyext2 10.8 +import struct, os, sys 10.9 + 10.10 +fs = _pyext2.Ext2Fs("test.img") 10.11 + 10.12 +f = fs.open_file("/boot/vmlinuz-2.6.11-1.1177_FC4") 10.13 +buf = f.read() 10.14 +o = open("vmlinuz", "wb+") 10.15 +o.write(buf) 10.16 +o.close() 10.17 + 10.18 +f.close()
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/tools/pygrub/src/pygrub Thu Apr 28 12:27:47 2005 +0000 11.3 @@ -0,0 +1,270 @@ 11.4 +#!/usr/bin/python 11.5 +# 11.6 +# pygrub - simple python-based bootloader for Xen 11.7 +# 11.8 +# Copyright 2005 Red Hat, Inc. 11.9 +# Jeremy Katz <katzj@redhat.com> 11.10 +# 11.11 +# This software may be freely redistributed under the terms of the GNU 11.12 +# general public license. 11.13 +# 11.14 +# You should have received a copy of the GNU General Public License 11.15 +# along with this program; if not, write to the Free Software 11.16 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 11.17 +# 11.18 + 11.19 +import os, sys, string, struct, tempfile 11.20 +import logging 11.21 + 11.22 +import curses, _curses, curses.wrapper 11.23 +import getopt 11.24 + 11.25 +import grub.GrubConf 11.26 +import grub.fsys 11.27 + 11.28 +PYGRUB_VER = 0.02 11.29 + 11.30 + 11.31 +def draw_window(): 11.32 + stdscr = curses.initscr() 11.33 + curses.use_default_colors() 11.34 + try: 11.35 + curses.curs_set(0) 11.36 + except _curses.error: 11.37 + pass 11.38 + 11.39 + stdscr.addstr(1, 4, "pyGRUB version %s" %(PYGRUB_VER,)) 11.40 + 11.41 + win = curses.newwin(10, 74, 2, 1) 11.42 + win.box() 11.43 + win.refresh() 11.44 + 11.45 + stdscr.addstr(12, 5, "Use the U and D keys to select which entry is highlighted.") 11.46 + stdscr.addstr(13, 5, "Press enter to boot the selected OS. 'e' to edit the") 11.47 + stdscr.addstr(14, 5, "commands before booting, 'a' to modify the kernel arguments ") 11.48 + stdscr.addstr(15, 5, "before booting, or 'c' for a command line.") 11.49 + stdscr.addch(12, 13, curses.ACS_UARROW) 11.50 + stdscr.addch(12, 19, curses.ACS_DARROW) 11.51 + (y, x) = stdscr.getmaxyx() 11.52 + stdscr.move(y - 1, x - 1) 11.53 + 11.54 + stdscr.refresh() 11.55 + return (stdscr, win) 11.56 + 11.57 +def fill_entries(win, cfg, selected): 11.58 + y = 0 11.59 + 11.60 + for i in cfg.images: 11.61 + if (0, y) > win.getmaxyx(): 11.62 + break 11.63 + if y == selected: 11.64 + attr = curses.A_REVERSE 11.65 + else: 11.66 + attr = 0 11.67 + win.addstr(y + 1, 2, i.title.ljust(70), attr) 11.68 + y += 1 11.69 + win.refresh() 11.70 + 11.71 +def select(win, line): 11.72 + win.attron(curses.A_REVERSE) 11.73 + win.redrawln(line + 1, 1) 11.74 + win.refresh() 11.75 + 11.76 +def is_disk_image(file): 11.77 + fd = os.open(file, os.O_RDONLY) 11.78 + buf = os.read(fd, 512) 11.79 + os.close(fd) 11.80 + 11.81 + if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaaff): 11.82 + return True 11.83 + return False 11.84 + 11.85 + 11.86 +def get_config(fn): 11.87 + if not os.access(fn, os.R_OK): 11.88 + raise RuntimeError, "Unable to access %s" %(fn,) 11.89 + 11.90 + cf = grub.GrubConf.GrubConfigFile() 11.91 + 11.92 + if is_disk_image(fn): 11.93 + raise RuntimeError, "appears to be a full disk image... unable to handle this yet" 11.94 + 11.95 + # open the image and read the grub config 11.96 + fs = None 11.97 + for fstype in grub.fsys.fstypes.values(): 11.98 + if fstype.sniff_magic(fn): 11.99 + fs = fstype.open_fs(fn) 11.100 + break 11.101 + 11.102 + if fs is not None: 11.103 + f = fs.open_file("/boot/grub/grub.conf") 11.104 + buf = f.read() 11.105 + f.close() 11.106 + fs.close() 11.107 + # then parse the grub config 11.108 + cf.parse(buf) 11.109 + else: 11.110 + # set the config file and parse it 11.111 + cf.filename = fn 11.112 + cf.parse() 11.113 + 11.114 + return cf 11.115 + 11.116 +def get_entry_idx(cf, entry): 11.117 + # first, see if the given entry is numeric 11.118 + try: 11.119 + idx = string.atoi(entry) 11.120 + return idx 11.121 + except ValueError: 11.122 + pass 11.123 + 11.124 + # it's not, now check the labels for a match 11.125 + for i in range(len(cf.images)): 11.126 + if entry == cf.images[i].title: 11.127 + return i 11.128 + 11.129 + return None 11.130 + 11.131 +def main(cf = None): 11.132 + mytime = 0 11.133 + 11.134 + (stdscr, win) = draw_window() 11.135 + stdscr.timeout(1000) 11.136 + selected = cf.default 11.137 + 11.138 + while (mytime < int(cf.timeout)): 11.139 + if cf.timeout != -1 and mytime != -1: 11.140 + stdscr.addstr(20, 5, "Will boot selected entry in %2d seconds" 11.141 + %(int(cf.timeout) - mytime)) 11.142 + else: 11.143 + stdscr.addstr(20, 5, " " * 80) 11.144 + 11.145 + fill_entries(win, cf, selected) 11.146 + c = stdscr.getch() 11.147 + if mytime != -1: 11.148 + mytime += 1 11.149 +# if c == ord('q'): 11.150 +# selected = -1 11.151 +# break 11.152 + elif c == ord('c'): 11.153 + # FIXME: needs to go to command line mode 11.154 + continue 11.155 + elif c == ord('a'): 11.156 + # FIXME: needs to go to append mode 11.157 + continue 11.158 + elif c == ord('e'): 11.159 + # FIXME: needs to go to edit mode 11.160 + continue 11.161 + elif c in (curses.KEY_ENTER, ord('\n'), ord('\r')): 11.162 + break 11.163 + elif c == curses.KEY_UP: 11.164 + mytime = -1 11.165 + selected -= 1 11.166 + elif c == curses.KEY_DOWN: 11.167 + mytime = -1 11.168 + selected += 1 11.169 + else: 11.170 + pass 11.171 + 11.172 + # bound at the top and bottom 11.173 + if selected < 0: 11.174 + selected = 0 11.175 + elif selected >= len(cf.images): 11.176 + selected = len(cf.images) - 1 11.177 + 11.178 + if selected >= 0: 11.179 + return selected 11.180 + 11.181 +if __name__ == "__main__": 11.182 + sel = None 11.183 + 11.184 + def run_main(scr, *args): 11.185 + global sel 11.186 + sel = main(cf) 11.187 + 11.188 + def usage(): 11.189 + print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] <image>" %(sys.argv[0],) 11.190 + 11.191 + try: 11.192 + opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::', 11.193 + ["quiet", "help", "output=", "entry="]) 11.194 + except getopt.GetoptError: 11.195 + usage() 11.196 + sys.exit(1) 11.197 + 11.198 + if len(args) < 1: 11.199 + usage() 11.200 + sys.exit(1) 11.201 + file = args[0] 11.202 + 11.203 + output = None 11.204 + entry = None 11.205 + interactive = True 11.206 + for o, a in opts: 11.207 + if o in ("-q", "--quiet"): 11.208 + interactive = False 11.209 + elif o in ("-h", "--help"): 11.210 + usage() 11.211 + sys.exit() 11.212 + elif o in ("--output",): 11.213 + output = a 11.214 + elif o in ("--entry",): 11.215 + entry = a 11.216 + # specifying the entry to boot implies non-interactive 11.217 + interactive = False 11.218 + 11.219 + if output is None or output == "-": 11.220 + fd = sys.stdout.fileno() 11.221 + else: 11.222 + fd = os.open(output, os.O_WRONLY) 11.223 + 11.224 + cf = get_config(file) 11.225 + if interactive: 11.226 + curses.wrapper(run_main) 11.227 + else: 11.228 + sel = cf.default 11.229 + 11.230 + # set the entry to boot as requested 11.231 + if entry is not None: 11.232 + idx = get_entry_idx(cf, entry) 11.233 + if idx is not None and idx > 0 and idx < len(cf.images): 11.234 + sel = idx 11.235 + 11.236 + img = cf.images[sel] 11.237 + print "Going to boot %s" %(img.title) 11.238 + print " kernel: %s" %(img.kernel[1],) 11.239 + if img.initrd: 11.240 + print " initrd: %s" %(img.initrd[1],) 11.241 + 11.242 + if is_disk_image(file): 11.243 + raise RuntimeError, "unable to handle full disk images yet" 11.244 + 11.245 + # read the kernel and initrd onto the hostfs 11.246 + fs = None 11.247 + for fstype in grub.fsys.fstypes.values(): 11.248 + if fstype.sniff_magic(file): 11.249 + fs = fstype.open_fs(file) 11.250 + break 11.251 + 11.252 + if fs is None: 11.253 + raise RuntimeError, "Unable to open filesystem" 11.254 + 11.255 + kernel = fs.open_file(img.kernel[1],).read() 11.256 + (tfd, fn) = tempfile.mkstemp(prefix="vmlinuz.") 11.257 + os.write(tfd, kernel) 11.258 + os.close(tfd) 11.259 + sxp = "linux (kernel %s)" %(fn,) 11.260 + 11.261 + if img.initrd: 11.262 + initrd = fs.open_file(img.initrd[1],).read() 11.263 + (tfd, fn) = tempfile.mkstemp(prefix="initrd.") 11.264 + os.write(tfd, initrd) 11.265 + os.close(tfd) 11.266 + sxp += "(ramdisk %s)" %(fn,) 11.267 + else: 11.268 + initrd = None 11.269 + sxp += "(args '%s')" %(img.args,) 11.270 + 11.271 + sys.stdout.flush() 11.272 + os.write(fd, sxp) 11.273 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/tools/python/xen/xend/XendBootloader.py Thu Apr 28 12:27:47 2005 +0000 12.3 @@ -0,0 +1,94 @@ 12.4 +# 12.5 +# XendBootloader.py - Framework to run a boot loader for picking the kernel 12.6 +# 12.7 +# Copyright 2005 Red Hat, Inc. 12.8 +# Jeremy Katz <katzj@xxxxxxxxxx> 12.9 +# 12.10 +# This software may be freely redistributed under the terms of the GNU 12.11 +# general public license. 12.12 +# 12.13 +# You should have received a copy of the GNU General Public License 12.14 +# along with this program; if not, write to the Free Software 12.15 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 12.16 +# 12.17 + 12.18 +import os, sys, select 12.19 +import sxp 12.20 + 12.21 +from XendLogging import log 12.22 +from XendError import VmError 12.23 + 12.24 +BL_FIFO = "/var/lib/xen/xenbl" 12.25 + 12.26 +def bootloader(blexec, disk, quiet = 0, vcpus = None, entry = None): 12.27 + """Run the boot loader executable on the given disk and return a 12.28 + config image. 12.29 + @param blexec Binary to use as the boot loader 12.30 + @param disk Disk to run the boot loader on. 12.31 + @param quiet Run in non-interactive mode, just booting the default. 12.32 + @param vcpus Number of vcpus for the domain. 12.33 + @param entry Default entry to boot.""" 12.34 + 12.35 + if not os.access(blexec, os.X_OK): 12.36 + msg = "Bootloader isn't executable" 12.37 + log.error(msg) 12.38 + raise VmError(msg) 12.39 + if not os.access(disk, os.R_OK): 12.40 + msg = "Disk isn't accessible" 12.41 + log.error(msg) 12.42 + raise VmError(msg) 12.43 + 12.44 + os.mkfifo(BL_FIFO, 0600) 12.45 + 12.46 + child = os.fork() 12.47 + if (not child): 12.48 + args = [ blexec ] 12.49 + if quiet: 12.50 + args.append("-q") 12.51 + args.append("--output=%s" %(BL_FIFO,)) 12.52 + if entry is not None: 12.53 + args.append("--entry=%s" %(entry,)) 12.54 + args.append(disk) 12.55 + 12.56 + try: 12.57 + os.execvp(args[0], args) 12.58 + except OSError, e: 12.59 + print e 12.60 + pass 12.61 + os._exit(1) 12.62 + 12.63 + while 1: 12.64 + try: 12.65 + r = os.open(BL_FIFO, os.O_RDONLY) 12.66 + except OSError, e: 12.67 + if e.errno == 4: 12.68 + continue 12.69 + break 12.70 + ret = "" 12.71 + while 1: 12.72 + select.select([r], [], []) 12.73 + s = os.read(r, 1024) 12.74 + ret = ret + s 12.75 + if len(s) == 0: 12.76 + break 12.77 + 12.78 + (pid, status) = os.waitpid(child, 0) 12.79 + os.close(r) 12.80 + os.unlink(BL_FIFO) 12.81 + 12.82 + if len(ret) == 0: 12.83 + msg = "Boot loader didn't return any data!" 12.84 + log.error(msg) 12.85 + raise VmError, msg 12.86 + 12.87 + pin = sxp.Parser() 12.88 + pin.input(ret) 12.89 + pin.input_eof() 12.90 + 12.91 + config_image = pin.val 12.92 + if vcpus and sxp.child_value(config_image, "vcpus") is None: 12.93 + config_image.append(['vcpus', vcpus]) 12.94 + 12.95 + config = ['image', config_image] 12.96 + return config 12.97 +
13.1 --- a/tools/python/xen/xend/XendDomainInfo.py Thu Apr 28 08:59:31 2005 +0000 13.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Apr 28 12:27:47 2005 +0000 13.3 @@ -16,11 +16,13 @@ import xen.lowlevel.xc; xc = xen.lowleve 13.4 import xen.util.ip 13.5 from xen.util.ip import _readline, _readlines 13.6 from xen.xend.server import channel, controller 13.7 +from xen.xend.server.blkif import blkdev_uname_to_file 13.8 13.9 from server.channel import channelFactory 13.10 import server.SrvDaemon; xend = server.SrvDaemon.instance() 13.11 from server import messages 13.12 13.13 +from xen.xend.XendBootloader import bootloader 13.14 import sxp 13.15 from XendLogging import log 13.16 from XendError import VmError 13.17 @@ -294,6 +296,7 @@ class XendDomainInfo: 13.18 self.image_handler = None 13.19 self.is_vmx = False 13.20 self.vcpus = 1 13.21 + self.bootloader = None 13.22 13.23 def setdom(self, dom): 13.24 """Set the domain id. 13.25 @@ -496,6 +499,7 @@ class XendDomainInfo: 13.26 self.find_image_handler() 13.27 self.init_domain() 13.28 self.register_domain() 13.29 + self.configure_bootloader() 13.30 13.31 # Create domain devices. 13.32 self.configure_backends() 13.33 @@ -674,6 +678,13 @@ class XendDomainInfo: 13.34 memory = memory * 1024 + self.pgtable_size(memory) 13.35 dom = xc.domain_create(dom= dom, mem_kb= memory, 13.36 cpu= cpu, cpu_weight= cpu_weight) 13.37 + if self.bootloader: 13.38 + try: 13.39 + if kernel: os.unlink(kernel) 13.40 + if ramdisk: os.unlink(ramdisk) 13.41 + except OSError, e: 13.42 + log.warning('unable to unlink kernel/ramdisk: %s' %(e,)) 13.43 + 13.44 if dom <= 0: 13.45 raise VmError('Creating domain failed: name=%s memory=%d' 13.46 % (self.name, memory)) 13.47 @@ -854,6 +865,13 @@ class XendDomainInfo: 13.48 self.config.remove(['device', dev_config]) 13.49 self.deleteDevice(type, dev.getId()) 13.50 13.51 + def configure_bootloader(self): 13.52 + """Configure boot loader. 13.53 + """ 13.54 + bl = sxp.child_value(self.config, "bootloader") 13.55 + if bl is not None: 13.56 + self.bootloader = bl 13.57 + 13.58 def configure_console(self): 13.59 """Configure the vm console port. 13.60 """ 13.61 @@ -931,10 +949,30 @@ class XendDomainInfo: 13.62 self.state = STATE_VM_OK 13.63 self.restart_check() 13.64 self.restart_state = STATE_RESTART_BOOTING 13.65 + if self.bootloader: 13.66 + self.config = self.bootloader_config() 13.67 self.construct(self.config) 13.68 finally: 13.69 self.restart_state = None 13.70 13.71 + def bootloader_config(self): 13.72 + # if we're restarting with a bootloader, we need to run it 13.73 + # FIXME: this assumes the disk is the first device and 13.74 + # that we're booting from the first disk 13.75 + blcfg = None 13.76 + # FIXME: this assumes that we want to use the first disk 13.77 + dev = sxp.child_value(self.config, "device") 13.78 + if dev: 13.79 + disk = sxp.child_value(dev, "uname") 13.80 + fn = blkdev_uname_to_file(disk) 13.81 + blcfg = bootloader(self.bootloader, fn, 1, self.vcpus) 13.82 + if blcfg is None: 13.83 + msg = "Had a bootloader specified, but can't find disk" 13.84 + log.error(msg) 13.85 + raise VmError(msg) 13.86 + config = sxp.merge(['vm', blconfig ], self.config) 13.87 + return config 13.88 + 13.89 def configure_backends(self): 13.90 """Set configuration flags if the vm is a backend for netif or blkif. 13.91 Configure the backends to use for vbd and vif if specified. 13.92 @@ -1071,6 +1109,7 @@ def vm_image_linux(vm, image): 13.93 if args: 13.94 cmdline += " " + args 13.95 ramdisk = sxp.child_value(image, "ramdisk", '') 13.96 + log.debug("creating linux domain with cmdline: %s" %(cmdline,)) 13.97 vm.create_domain("linux", kernel, ramdisk, cmdline) 13.98 return vm 13.99 13.100 @@ -1169,6 +1208,7 @@ add_config_handler('image', vm_fiel 13.101 add_config_handler('device', vm_field_ignore) 13.102 add_config_handler('backend', vm_field_ignore) 13.103 add_config_handler('vcpus', vm_field_ignore) 13.104 +add_config_handler('bootloader', vm_field_ignore) 13.105 13.106 # Register other config handlers. 13.107 add_config_handler('maxmem', vm_field_maxmem)
14.1 --- a/tools/python/xen/xend/server/blkif.py Thu Apr 28 08:59:31 2005 +0000 14.2 +++ b/tools/python/xen/xend/server/blkif.py Thu Apr 28 12:27:47 2005 +0000 14.3 @@ -71,6 +71,15 @@ def blkdev_segment(name): 14.4 'type' : 'Disk' } 14.5 return val 14.6 14.7 +def blkdev_uname_to_file(uname): 14.8 + """Take a blkdev uname and return the corresponding filename.""" 14.9 + fn = None 14.10 + if uname.find(":") != -1: 14.11 + (typ, fn) = uname.split(":") 14.12 + if typ == "phy" and not fn.startswith("/dev/"): 14.13 + fn = "/dev/%s" %(fn,) 14.14 + return fn 14.15 + 14.16 def mount_mode(name): 14.17 mode = None 14.18 name = expand_dev_name(name)
15.1 --- a/tools/python/xen/xm/create.py Thu Apr 28 08:59:31 2005 +0000 15.2 +++ b/tools/python/xen/xm/create.py Thu Apr 28 12:27:47 2005 +0000 15.3 @@ -10,6 +10,8 @@ import socket 15.4 from xen.xend import sxp 15.5 from xen.xend import PrettyPrint 15.6 from xen.xend.XendClient import server, XendError 15.7 +from xen.xend.XendBootloader import bootloader 15.8 +from xen.xend.server import blkif 15.9 15.10 from xen.util import console_client 15.11 15.12 @@ -94,6 +96,14 @@ gopts.var('name', val='NAME', 15.13 fn=set_value, default=None, 15.14 use="Domain name. Must be unique.") 15.15 15.16 +gopts.var('bootloader', val='FILE', 15.17 + fn=set_value, default=None, 15.18 + use="Path to bootloader.") 15.19 + 15.20 +gopts.var('bootentry', val='NAME', 15.21 + fn=set_value, default=None, 15.22 + use="Entry to boot via boot loader") 15.23 + 15.24 gopts.var('kernel', val='FILE', 15.25 fn=set_value, default=None, 15.26 use="Path to kernel image.") 15.27 @@ -252,7 +262,7 @@ def strip(pre, s): 15.28 else: 15.29 return s 15.30 15.31 -def configure_image(config, vals): 15.32 +def configure_image(opts, config, vals): 15.33 """Create the image config. 15.34 """ 15.35 config_image = [ vals.builder ] 15.36 @@ -272,7 +282,7 @@ def configure_image(config, vals): 15.37 config.append(['image', config_image ]) 15.38 15.39 15.40 -def configure_disks(config_devs, vals): 15.41 +def configure_disks(opts, config_devs, vals): 15.42 """Create the config for disks (virtual block devices). 15.43 """ 15.44 for (uname, dev, mode, backend) in vals.disk: 15.45 @@ -284,14 +294,14 @@ def configure_disks(config_devs, vals): 15.46 config_vbd.append(['backend', backend]) 15.47 config_devs.append(['device', config_vbd]) 15.48 15.49 -def configure_pci(config_devs, vals): 15.50 +def configure_pci(opts, config_devs, vals): 15.51 """Create the config for pci devices. 15.52 """ 15.53 for (bus, dev, func) in vals.pci: 15.54 config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]] 15.55 config_devs.append(['device', config_pci]) 15.56 15.57 -def configure_usb(config_devs, vals): 15.58 +def configure_usb(opts, config_devs, vals): 15.59 for path in vals.usb: 15.60 config_usb = ['usb', ['path', path]] 15.61 config_devs.append(['device', config_usb]) 15.62 @@ -315,7 +325,7 @@ def randomMAC(): 15.63 random.randint(0x00, 0xff) ] 15.64 return ':'.join(map(lambda x: "%02x" % x, mac)) 15.65 15.66 -def configure_vifs(config_devs, vals): 15.67 +def configure_vifs(opts, config_devs, vals): 15.68 """Create the config for virtual network interfaces. 15.69 """ 15.70 vifs = vals.vif 15.71 @@ -357,7 +367,7 @@ def configure_vifs(config_devs, vals): 15.72 config_vif.append(['ip', ip]) 15.73 config_devs.append(['device', config_vif]) 15.74 15.75 -def configure_vfr(config, vals): 15.76 +def configure_vfr(opts, config, vals): 15.77 if not vals.ipaddr: return 15.78 config_vfr = ['vfr'] 15.79 idx = 0 # No way of saying which IP is for which vif? 15.80 @@ -365,7 +375,7 @@ def configure_vfr(config, vals): 15.81 config_vfr.append(['vif', ['id', idx], ['ip', ip]]) 15.82 config.append(config_vfr) 15.83 15.84 -def configure_vmx(config_devs, vals): 15.85 +def configure_vmx(opts, config_devs, vals): 15.86 """Create the config for VMX devices. 15.87 """ 15.88 memmap = vals.memmap 15.89 @@ -375,7 +385,21 @@ def configure_vmx(config_devs, vals): 15.90 config_devs.append(['device_model', device_model]) 15.91 config_devs.append(['device_config', device_config]) 15.92 15.93 -def make_config(vals): 15.94 +def run_bootloader(opts, config, vals): 15.95 + if not os.access(vals.bootloader, os.X_OK): 15.96 + opts.err("Bootloader isn't executable") 15.97 + if len(vals.disk) < 1: 15.98 + opts.err("No disks configured and boot loader requested") 15.99 + (uname, dev, mode, backend) = vals.disk[0] 15.100 + file = blkif.blkdev_uname_to_file(uname) 15.101 + 15.102 + blcfg = bootloader(vals.bootloader, file, not vals.console_autoconnect, 15.103 + vals.vcpus, vals.blentry) 15.104 + 15.105 + config.append(['bootloader', vals.bootloader]) 15.106 + config.append(blcfg) 15.107 + 15.108 +def make_config(opts, vals): 15.109 """Create the domain configuration. 15.110 """ 15.111 15.112 @@ -396,15 +420,19 @@ def make_config(vals): 15.113 config.append(['restart', vals.restart]) 15.114 if vals.console: 15.115 config.append(['console', vals.console]) 15.116 - 15.117 - configure_image(config, vals) 15.118 + 15.119 + if vals.bootloader: 15.120 + run_bootloader(opts, config, vals) 15.121 + else: 15.122 + configure_image(opts, config, vals) 15.123 config_devs = [] 15.124 - configure_disks(config_devs, vals) 15.125 - configure_pci(config_devs, vals) 15.126 - configure_vifs(config_devs, vals) 15.127 - configure_usb(config_devs, vals) 15.128 - configure_vmx(config_devs, vals) 15.129 + configure_disks(opts, config_devs, vals) 15.130 + configure_pci(opts, config_devs, vals) 15.131 + configure_vifs(opts, config_devs, vals) 15.132 + configure_usb(opts, config_devs, vals) 15.133 + configure_vmx(opts, config_devs, vals) 15.134 config += config_devs 15.135 + 15.136 return config 15.137 15.138 def preprocess_disk(opts, vals): 15.139 @@ -587,7 +615,8 @@ def main(argv): 15.140 preprocess(opts, opts.vals) 15.141 if not opts.getopt('name') and opts.getopt('defconfig'): 15.142 opts.setopt('name', os.path.basename(opts.getopt('defconfig'))) 15.143 - config = make_config(opts.vals) 15.144 + config = make_config(opts, opts.vals) 15.145 + 15.146 if opts.vals.dryrun: 15.147 PrettyPrint.prettyprint(config) 15.148 else:
16.1 --- a/tools/xfrd/xfrd.c Thu Apr 28 08:59:31 2005 +0000 16.2 +++ b/tools/xfrd/xfrd.c Thu Apr 28 12:27:47 2005 +0000 16.3 @@ -49,7 +49,7 @@ 16.4 #include "select.h" 16.5 16.6 #define MODULE_NAME "XFRD" 16.7 - 16.8 +#define DEBUG 1 16.9 #include "debug.h" 16.10 16.11 /* 16.12 @@ -1226,7 +1226,9 @@ int main(int argc, char *argv[]){ 16.13 int err = 0; 16.14 int key = 0; 16.15 int long_index = 0; 16.16 +#ifndef DEBUG 16.17 static const char * LOGFILE = "/var/log/xfrd.log"; 16.18 +#endif 16.19 16.20 #ifndef DEBUG 16.21 freopen(LOGFILE, "w+", stdout);