ia64/xen-unstable
changeset 1013:59994ddfbb7e
bitkeeper revision 1.652.2.1 (3fe4dd99t24zD9Wu1VbWDg5fOnRCgQ)
Cleanup and documentation improvement to createlinuxdom.py/XenoUtil.py
along with addition of VM auto restart facility (latter curtesy of
Mark Williamson).
Cleanup and documentation improvement to createlinuxdom.py/XenoUtil.py
along with addition of VM auto restart facility (latter curtesy of
Mark Williamson).
author | iap10@nidd.cl.cam.ac.uk |
---|---|
date | Sat Dec 20 23:39:05 2003 +0000 (2003-12-20) |
parents | 60a3a567a347 |
children | 4bfd14bb15cd |
files | .rootkeys BitKeeper/etc/logging_ok tools/examples/createlinuxdom.py tools/examples/mynewdom.py tools/xc/lib/Makefile tools/xc/py/XenoUtil.py |
line diff
1.1 --- a/.rootkeys Fri Dec 19 14:43:39 2003 +0000 1.2 +++ b/.rootkeys Sat Dec 20 23:39:05 2003 +0000 1.3 @@ -42,7 +42,6 @@ 3e6377dbGcgnisKw16DPCaND7oGO3Q tools/bal 1.4 3fbe2f12OPAkzIUtumU3wRAihnhocQ tools/examples/createlinuxdom.py 1.5 3fbe2f12dZbmXLlgQdMgkmnSUj23AQ tools/examples/destroydom.py 1.6 3fbe2f12ltvweb13kBSsxqzZDAq4sg tools/examples/listdoms.py 1.7 -3fca7788tBihusQSq3HJI-YKQTN2iQ tools/examples/mynewdom.py 1.8 3fca7700PVj36cZObaFZlQicRiw1pQ tools/examples/pincpu.py 1.9 3fd8bc48ww3aOqPhYjCr8KGulG0NQQ tools/examples/readxenconsolering.py 1.10 3fccbe068ov0YCxnk-2m4law19QMmA tools/examples/startdom.py
2.1 --- a/BitKeeper/etc/logging_ok Fri Dec 19 14:43:39 2003 +0000 2.2 +++ b/BitKeeper/etc/logging_ok Sat Dec 20 23:39:05 2003 +0000 2.3 @@ -10,6 +10,7 @@ br260@labyrinth.cl.cam.ac.uk 2.4 br260@laudney.cl.cam.ac.uk 2.5 iap10@freefall.cl.cam.ac.uk 2.6 iap10@labyrinth.cl.cam.ac.uk 2.7 +iap10@nidd.cl.cam.ac.uk 2.8 iap10@striker.cl.cam.ac.uk 2.9 jws22@gauntlet.cl.cam.ac.uk 2.10 jws@cairnwell.research
3.1 --- a/tools/examples/createlinuxdom.py Fri Dec 19 14:43:39 2003 +0000 3.2 +++ b/tools/examples/createlinuxdom.py Sat Dec 20 23:39:05 2003 +0000 3.3 @@ -2,107 +2,169 @@ 3.4 3.5 # 3.6 # Example script for creating and building a new Linux guest OS for Xen. 3.7 +# It takes an optional parameter that specifies offsets to be added to the 3.8 +# ip address and root partition numbers, enabling multiple domains to be 3.9 +# started from the one script. 3.10 +# 3.11 +# Edit as required... 3.12 # 3.13 3.14 -import Xc, XenoUtil, sys, os 3.15 +import Xc, XenoUtil, string, sys, os, time, socket 3.16 3.17 -# Variable declaration. Set these up properly later on, as needed. 3.18 -nfsserv = nfspath = root_partn = usr_partn = "" 3.19 +# initialize a few variables that might come in handy 3.20 +thishostname = socket.gethostname() 3.21 +guestid = 0 3.22 +if sys.argv >= 2: 3.23 + guestid = string.atoi(sys.argv[1]) 3.24 + print "Offset to add to guest's IP etc : %d\n" % guestid 3.25 + 3.26 +##### This section of the code establishes various settings to be used 3.27 +##### for this guest virtual machine 3.28 3.29 -# STEP 1. Specify kernel image file. 3.30 -image = "FULL_PATH_TO_IMAGE" 3.31 +# STEP 1. Specify kernel image file. Can be gzip'ed. 3.32 +image = "../../../install/boot/xenolinux.gz" 3.33 3.34 # STEP 2. How many megabytes of memory for the new domain? 3.35 memory_megabytes = 64 3.36 3.37 # STEP 3. A handy name for your new domain. 3.38 -domain_name = "My new domain" 3.39 +domain_name = "This is VM %d" % guestid 3.40 3.41 -# STEP 4. Specify IP address, netmask and gateway for the new domain. 3.42 -ipaddr = "ADDRESS" 3.43 +# STEP 4. Specify IP address(es), netmask and gateway for the new 3.44 +# domain. You need to configure IP addrs within the domain just as 3.45 +# you do normally. This is just to let Xen know about them so it can 3.46 +# route packets appropriately. 3.47 + 3.48 +#ipaddr = ["111.222.333.444","222.333.444.555"] 3.49 +ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),guestid)] 3.50 netmask = XenoUtil.get_current_ipmask() 3.51 gateway = XenoUtil.get_current_ipgw() 3.52 +nfsserv = '169.254.1.0' # You need to set this if you're using NFS root 3.53 3.54 -# STEP 5a. Specify NFS server and path to rootfs (only needed for network boot) 3.55 -nfsserv = "ADDRESS" 3.56 -nfspath = "FULL_PATH_TO_ROOT_DIR" 3.57 +# STEP 5. Identify any physcial partitions or virtual disks you want the 3.58 +# domain to have access to, and what you want them accessible as 3.59 +# e.g. vbds = [ ('phy:sda1','sda1', 'w'), 3.60 +# ('phy:sda4','sda%d' % (3+guestid), 'r'), 3.61 +# ('vd:as73gd784dh','hda1','w') ] 3.62 + 3.63 +vbds = [ ('phy:sda%d'%(7+guestid),'sda1','w' ), 3.64 + ('phy:sda6','sda6','r'), 3.65 + ('phy:cdrom','hdd','r') ] 3.66 3.67 -# STEP 5b. Specify root partition on local disc (if not NFS booting) 3.68 -#root_partn = "/dev/sda2" 3.69 -# (NB. The following is only needed for a separate shared read-only /usr) 3.70 -# (usr_partn = "/dev/sda6") 3.71 +# STEP 6. Build the command line for the new domain. Edit as req'd. 3.72 +# You only need the ip= line if you're NFS booting or the root file system 3.73 +# doesn't set it later e.g. in ifcfg-eth0 or via DHCP 3.74 +# You can use 'extrabit' to set the runlevel and custom environment 3.75 +# variables used by custom rc scripts (e.g. DOMID=, usr= ) 3.76 + 3.77 +ipbit = "ip="+ipaddr[0]+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off" 3.78 +rootbit = "root=/dev/sda1 ro" 3.79 +#rootbit = "root=/dev/nfs nfsroot=/full/path/to/root/directory" 3.80 +extrabit = "4 DOMID=%d usr=/dev/sda6" % guestid 3.81 +cmdline = ipbit +" "+ rootbit +" "+ extrabit 3.82 + 3.83 +# STEP 7. Set according to whether you want the script to watch the domain 3.84 +# and auto-restart it should it die or exit. 3.85 + 3.86 +auto_restart = False 3.87 +#auto_restart = True 3.88 + 3.89 3.90 -# STEP 6. Check that the following cmdline setup is to your taste. 3.91 -cmdline = "ip="+ipaddr+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off" 3.92 -if root_partn: 3.93 - # Boot from local disc. May specify a separate /usr. 3.94 - cmdline = cmdline + " root="+root_partn+" ro" 3.95 - if usr_partn: 3.96 - " usr="+usr_partn 3.97 -elif nfsserv: 3.98 - # NFS boot 3.99 - cmdline = cmdline + " root=/dev/nfs" 3.100 - cmdline = cmdline + " nfsroot="+nfspath 3.101 +##### Print some debug info just incase things don't work out... 3.102 +##### 3.103 + 3.104 +print "Domain image : ", image 3.105 +print "Domain memory : ", memory_megabytes 3.106 +print "Domain IP address(es) : ", ipaddr 3.107 +print "Domain block devices : ", vbds 3.108 +print 'Domain cmdline : "%s"' % cmdline 3.109 + 3.110 + 3.111 +##### Code beyond this point is actually used to manage the mechanics of 3.112 +##### starting (and watching if necessary) guest virtual machines. 3.113 3.114 -if root_partn: 3.115 - root_info = XenoUtil.lookup_blkdev_partn_info(root_partn) 3.116 - if not root_info: 3.117 - print "Could not obtain info on partition '" + root_partn + "'" 3.118 +# Obtain an instance of the Xen control interface 3.119 +xc = Xc.new() 3.120 + 3.121 +# This function creates, builds and starts a domain, using the values 3.122 +# in the global variables, set above. It is used in the subsequent 3.123 +# code for starting the new domain and rebooting it if appropriate. 3.124 +def make_domain(): 3.125 + """Create, build and start a domain. 3.126 + Returns: [int] the ID of the new domain. 3.127 + """ 3.128 + 3.129 + # set up access to the global variables declared above 3.130 + global image, memory_megabytes, domain_name, ipaddr, netmask 3.131 + global vbds, cmdline, xc 3.132 + 3.133 + if not os.path.isfile( image ): 3.134 + print "Image file '" + image + "' does not exist" 3.135 sys.exit() 3.136 3.137 -if usr_partn: 3.138 - usr_info = XenoUtil.lookup_blkdev_partn_info(usr_partn) 3.139 - if not usr_info: 3.140 - print "Could not obtain info on partition '" + usr_partn + "'" 3.141 + id = xc.domain_create( mem_kb=memory_megabytes*1024, name=domain_name ) 3.142 + print "Created new domain with id = " + str(id) 3.143 + if id <= 0: 3.144 + print "Error creating domain" 3.145 sys.exit() 3.146 3.147 -if not os.path.isfile( image ): 3.148 - print "Image file '" + image + "' does not exist" 3.149 - sys.exit() 3.150 - 3.151 -xc = Xc.new() 3.152 - 3.153 -id = xc.domain_create( mem_kb=memory_megabytes*1024, name=domain_name ) 3.154 -if id <= 0: 3.155 - print "Error creating domain" 3.156 - sys.exit() 3.157 - 3.158 -if xc.linux_build( dom=id, image=image, cmdline=cmdline ): 3.159 - print "Error building Linux guest OS" 3.160 - xc.domain_destroy ( dom=id ) 3.161 - sys.exit() 3.162 - 3.163 -if root_partn: 3.164 - if xc.vbd_create( dom=id, vbd=root_info[0], writeable=1 ): 3.165 - print "Error creating root VBD" 3.166 - xc.domain_destroy ( dom=id ) 3.167 - sys.exit() 3.168 - if xc.vbd_grow( dom=id, 3.169 - vbd=root_info[0], 3.170 - device=root_info[1], 3.171 - start_sector=root_info[2], 3.172 - nr_sectors=root_info[3] ): 3.173 - print "Error populating root VBD" 3.174 + ret = xc.linux_build( dom=id, image=image, cmdline=cmdline ) 3.175 + if ret < 0: 3.176 + print "Error building Linux guest OS: " 3.177 + print "Return code from linux_build = " + str(ret) 3.178 xc.domain_destroy ( dom=id ) 3.179 sys.exit() 3.180 3.181 -if usr_partn: 3.182 - if xc.vbd_create( dom=id, vbd=usr_info[0], writeable=0 ): 3.183 - print "Error creating usr VBD" 3.184 - xc.domain_destroy ( dom=id ) 3.185 - sys.exit() 3.186 - if xc.vbd_grow( dom=id, 3.187 - vbd=usr_info[0], 3.188 - device=usr_info[1], 3.189 - start_sector=usr_info[2], 3.190 - nr_sectors=usr_info[3] ): 3.191 - print "Error populating usr VBD" 3.192 + # setup the virtual block devices 3.193 + for ( uname, virt_name, rw ) in vbds: 3.194 + virt_dev = XenoUtil.blkdev_name_to_number( virt_name ) 3.195 + 3.196 + segments = XenoUtil.lookup_disk_uname( uname ) 3.197 + if not segments: 3.198 + print "Error looking up %s\n" % uname 3.199 + xc.domain_destroy ( dom=id ) 3.200 + sys.exit() 3.201 + 3.202 + if xc.vbd_create( dom=id, vbd=virt_dev, writeable= rw=='w' ): 3.203 + print "Error creating VBD vbd=%d writeable=%d\n" % (virt_dev,rw) 3.204 + xc.domain_destroy ( dom=id ) 3.205 + sys.exit() 3.206 + 3.207 + for (s_dev,s_start,s_len,s_type) in segments: 3.208 + if xc.vbd_grow( dom=id, 3.209 + vbd=virt_dev, 3.210 + device=s_dev, 3.211 + start_sector=s_start, 3.212 + nr_sectors=s_len ): 3.213 + print "Error populating VBD vbd=%d\n" % virt_dev 3.214 + xc.domain_destroy ( dom=id ) 3.215 + sys.exit() 3.216 + 3.217 + # setup virtual firewall rules for all aliases 3.218 + for ip in ipaddr: 3.219 + XenoUtil.setup_vfr_rules_for_vif( id, 0, ip ) 3.220 + 3.221 + if xc.domain_start( dom=id ) < 0: 3.222 + print "Error starting domain" 3.223 xc.domain_destroy ( dom=id ) 3.224 sys.exit() 3.225 3.226 -XenoUtil.setup_vfr_rules_for_vif( id, 0, ipaddr ) 3.227 + return id 3.228 +# end of make_domain() 3.229 + 3.230 + 3.231 + 3.232 +# The starting / monitoring of the domain actually happens here... 3.233 + 3.234 +# start the domain and record its ID number 3.235 +current_id = make_domain() 3.236 3.237 -if xc.domain_start( dom=id ): 3.238 - print "Error starting domain" 3.239 - xc.domain_destroy ( dom=id ) 3.240 - sys.exit() 3.241 +# if the auto_restart flag is set then keep polling to see if the domain is 3.242 +# alive - restart if it is not by calling make_domain() again (it's necessary 3.243 +# to update the id variable, since the new domain may have a new ID) 3.244 + 3.245 +while auto_restart: 3.246 + time.sleep(1) 3.247 + if not xc.domain_getinfo(current_id): 3.248 + print "The virtual machine has terminated, restarting in a new domain" 3.249 + current_id = make_domain()
4.1 --- a/tools/examples/mynewdom.py Fri Dec 19 14:43:39 2003 +0000 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,114 +0,0 @@ 4.4 -#!/usr/bin/env python 4.5 - 4.6 -# Example script for creating and building a new Linux guest OS for 4.7 -# Xen. THIS IS VERY SITE SPECIFIC, but shows an example configuration 4.8 -# using multiple root partitions with a common /usr. e.g. Domain1 4.9 -# uses root /dev/sda8, usr /dev/sda6, and the next sequential IP address. 4.10 - 4.11 -import Xc, XenoUtil, sys, os, socket, re 4.12 - 4.13 -# Variable declaration. Set these up properly later on, as needed. 4.14 -nfsserv = nfspath = root_partn = usr_partn = "" 4.15 -shost = re.search( '([a-zA-Z]+)[-.]', socket.gethostname() ).group(1) 4.16 - 4.17 -# STEP 1. Specify kernel image file. 4.18 -image = "/usr/groups/srgboot/%s/xenolinux.gz" % shost 4.19 - 4.20 -# STEP 2. How many megabytes of memory for the new domain? 4.21 -memory_megabytes = 64 4.22 - 4.23 -# STEP 3. A handy name for your new domain. 4.24 -domain_name = "My new domain" 4.25 - 4.26 -# Allocate new domain ad get its domain id 4.27 -xc = Xc.new() 4.28 -id = xc.domain_create( mem_kb=memory_megabytes*1024, name=domain_name ) 4.29 -if id <= 0: 4.30 - print "Error creating domain" 4.31 - sys.exit() 4.32 - 4.33 -# Set the CPU, or leave to round robin allocation 4.34 -#xc.domain_pincpu( dom=id, cpu=1 ) 4.35 - 4.36 -# STEP 4. Specify IP address, netmask and gateway for the new domain. 4.37 -ipaddr = XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),id) 4.38 -netmask = XenoUtil.get_current_ipmask() 4.39 -gateway = XenoUtil.get_current_ipgw() 4.40 - 4.41 -# STEP 5a. Specify NFS server and path to rootfs (only needed for network boot) 4.42 -#nfsserv = "ADDRESS" 4.43 -#nfspath = "FULL_PATH_TO_ROOT_DIR" 4.44 - 4.45 -# STEP 5b. Specify root partition on local disc (if not NFS booting) 4.46 -root_partn = "/dev/sda%d" % (7+id) 4.47 -# (NB. The following is only needed for a separate shared read-only /usr) 4.48 -usr_partn = "/dev/sda6" 4.49 - 4.50 -# STEP 6. Check that the following cmdline setup is to your taste. 4.51 -cmdline = "ip="+ipaddr+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off" 4.52 -if root_partn: 4.53 - # Boot from local disc. May specify a separate /usr. 4.54 - cmdline = cmdline + " root="+root_partn+" ro" 4.55 - if usr_partn: 4.56 - " usr="+usr_partn 4.57 -elif nfsserv: 4.58 - # NFS boot 4.59 - cmdline = cmdline + " root=/dev/nfs" 4.60 - cmdline = cmdline + " nfsroot="+nfspath 4.61 - 4.62 -if root_partn: 4.63 - root_info = XenoUtil.lookup_blkdev_partn_info(root_partn) 4.64 - if not root_info: 4.65 - print "Could not obtain info on partition '" + root_partn + "'" 4.66 - sys.exit() 4.67 - 4.68 -if usr_partn: 4.69 - usr_info = XenoUtil.lookup_blkdev_partn_info(usr_partn) 4.70 - if not usr_info: 4.71 - print "Could not obtain info on partition '" + usr_partn + "'" 4.72 - sys.exit() 4.73 - 4.74 -if not os.path.isfile( image ): 4.75 - print "Image file '" + image + "' does not exist" 4.76 - sys.exit() 4.77 - 4.78 - 4.79 -if xc.linux_build( dom=id, image=image, cmdline=cmdline ): 4.80 - print "Error building Linux guest OS" 4.81 - xc.domain_destroy ( dom=id ) 4.82 - sys.exit() 4.83 - 4.84 -if root_partn: 4.85 - if xc.vbd_create( dom=id, vbd=root_info[0], writeable=1 ): 4.86 - print "Error creating root VBD" 4.87 - xc.domain_destroy ( dom=id ) 4.88 - sys.exit() 4.89 - if xc.vbd_grow( dom=id, 4.90 - vbd=root_info[0], 4.91 - device=root_info[1], 4.92 - start_sector=root_info[2], 4.93 - nr_sectors=root_info[3] ): 4.94 - print "Error populating root VBD" 4.95 - xc.domain_destroy ( dom=id ) 4.96 - sys.exit() 4.97 - 4.98 -if usr_partn: 4.99 - if xc.vbd_create( dom=id, vbd=usr_info[0], writeable=0 ): 4.100 - print "Error creating usr VBD" 4.101 - xc.domain_destroy ( dom=id ) 4.102 - sys.exit() 4.103 - if xc.vbd_grow( dom=id, 4.104 - vbd=usr_info[0], 4.105 - device=usr_info[1], 4.106 - start_sector=usr_info[2], 4.107 - nr_sectors=usr_info[3] ): 4.108 - print "Error populating usr VBD" 4.109 - xc.domain_destroy ( dom=id ) 4.110 - sys.exit() 4.111 - 4.112 -XenoUtil.setup_vfr_rules_for_vif( id, 0, ipaddr ) 4.113 - 4.114 -if xc.domain_start( dom=id ): 4.115 - print "Error starting domain" 4.116 - xc.domain_destroy ( dom=id ) 4.117 - sys.exit()
5.1 --- a/tools/xc/lib/Makefile Fri Dec 19 14:43:39 2003 +0000 5.2 +++ b/tools/xc/lib/Makefile Sat Dec 20 23:39:05 2003 +0000 5.3 @@ -22,7 +22,7 @@ install: all 5.4 mkdir -p /usr/lib 5.5 mkdir -p /usr/include 5.6 cp -a $(LIB) /usr/lib 5.7 - chmod 755 /usr/bin/$(LIB) 5.8 + chmod 755 /usr/lib/$(LIB) 5.9 cp -a xc.h /usr/include 5.10 chmod 644 /usr/include/xc.h 5.11 5.12 @@ -30,7 +30,7 @@ dist: all 5.13 mkdir -p ../../../../install/lib 5.14 mkdir -p ../../../../install/include 5.15 cp -a $(LIB) ../../../../install/lib 5.16 - chmod 755 ../../../../install/bin/$(LIB) 5.17 + chmod 755 ../../../../install/lib/$(LIB) 5.18 cp -a xc.h ../../../../install/include 5.19 chmod 644 ../../../../install/include/xc.h 5.20
6.1 --- a/tools/xc/py/XenoUtil.py Fri Dec 19 14:43:39 2003 +0000 6.2 +++ b/tools/xc/py/XenoUtil.py Sat Dec 20 23:39:05 2003 +0000 6.3 @@ -12,7 +12,7 @@ def blkdev_name_to_number(name): 6.4 6.5 6.6 # lookup_blkdev_partn_info( '/dev/sda3' ) 6.7 -def lookup_blkdev_partn_info(partition): 6.8 +def lookup_raw_partn(partition): 6.9 """Take the given block-device name (e.g., '/dev/sda1', 'hda') 6.10 and return a information tuple ( partn-dev, disc-dev, start-sect, 6.11 nr-sects, type ) 6.12 @@ -32,11 +32,10 @@ def lookup_blkdev_partn_info(partition): 6.13 fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' ) 6.14 line = fd.readline() 6.15 if line: 6.16 - return ( blkdev_name_to_number(drive), 6.17 - blkdev_name_to_number(drive), 6.18 + return [( blkdev_name_to_number(drive), 6.19 0, 6.20 string.atol(line) * 2, 6.21 - 'Disk' ) 6.22 + 'Disk' )] 6.23 return None 6.24 6.25 # determine position on disk 6.26 @@ -48,13 +47,21 @@ def lookup_blkdev_partn_info(partition): 6.27 m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' + 6.28 'size=\s*([0-9]+), Id=\s*(\S+).*$', line) 6.29 if m: 6.30 - return ( blkdev_name_to_number(partition), 6.31 - blkdev_name_to_number(drive), 6.32 + return [( blkdev_name_to_number(drive), 6.33 string.atol(m.group(1)), 6.34 string.atol(m.group(2)), 6.35 - m.group(3) ) 6.36 + m.group(3) )] 6.37 return None 6.38 6.39 +def lookup_disk_uname( uname ): 6.40 + ( type, d_name ) = string.split( uname, ':' ) 6.41 + 6.42 + if type == "phy": 6.43 + segments = lookup_raw_partn( d_name ) 6.44 + elif type == "vd": 6.45 + segments = lookup_vd( d_name ) 6.46 + 6.47 + return segments 6.48 6.49 def get_current_ipaddr(dev='eth0'): 6.50 """Return a string containing the primary IP address for the given