aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rootkeys8
-rw-r--r--README52
-rw-r--r--README.CD358
-rw-r--r--tools/Makefile4
-rw-r--r--tools/examples/Makefile34
-rw-r--r--tools/examples/README109
-rw-r--r--tools/examples/defaults89
-rw-r--r--tools/examples/democd126
-rwxr-xr-xtools/examples/xc_dom_control.py219
-rwxr-xr-xtools/examples/xc_dom_create.py296
-rwxr-xr-xtools/examples/xc_vd_tool.py155
-rw-r--r--tools/misc/Makefile6
-rwxr-xr-xtools/misc/xen_dmesg.py26
-rwxr-xr-xtools/misc/xen_nat_enable2
-rw-r--r--tools/xc/py/Makefile3
-rw-r--r--tools/xc/py/XenoUtil.py60
16 files changed, 1418 insertions, 129 deletions
diff --git a/.rootkeys b/.rootkeys
index 312d4df82a..6870410f6d 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -40,8 +40,12 @@
3e6377b24eQqYMsDi9XrFkIgTzZ47A tools/balloon/Makefile
3e6377d6eiFjF1hHIS6JEIOFk62xSA tools/balloon/README
3e6377dbGcgnisKw16DPCaND7oGO3Q tools/balloon/balloon.c
+401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/examples/Makefile
+401d7e16UgeqroJQTIhwkrDVkoWgZQ tools/examples/README
40083bb4_j61quzxosgZ19LUgLlgYw tools/examples/add_vbd_to_dom.py
3fbe2f12OPAkzIUtumU3wRAihnhocQ tools/examples/createlinuxdom.py
+401d7e16GS8YesM1zateRbaOoI6YLQ tools/examples/defaults
+401d7e16NoWaBGC1RXbBcqAOr5Uaag tools/examples/democd
3fbe2f12dZbmXLlgQdMgkmnSUj23AQ tools/examples/destroydom.py
40083bb4lxCIf5HRu6fwWUyHCYOHKA tools/examples/list_vbds.py
3fbe2f12ltvweb13kBSsxqzZDAq4sg tools/examples/listdoms.py
@@ -59,6 +63,9 @@
40083bb4NhDpKiYTrebI3ZjX__oI_w tools/examples/vd_refresh.py
400c774eXs8hWKK70ZYzi1ScKiSjPQ tools/examples/vd_to_file.py
400c33001-uDKTfHBchTKUwuMFcqTA tools/examples/vd_undelete.py
+401d7e16NpnVrFSsR7lKKKfTwCYvWA tools/examples/xc_dom_control.py
+401d7e16RJj-lbtsVEjua6HYAIiKiA tools/examples/xc_dom_create.py
+401d7e16X4iojyKopo_j63AyzYZd2A tools/examples/xc_vd_tool.py
3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
3f6dc140C8tAeBfroAF24VrmCS4v_w tools/misc/miniterm/README
@@ -68,6 +75,7 @@
3f5ef5a2dTZP0nnsFoeq2jRf3mWDDg tools/misc/xen-clone.README
3f1668d4-FUY6Enc7MB3GcwUtfJ5HA tools/misc/xen-mkdevnodes
3f870808zS6T6iFhqYPGelroZlVfGQ tools/misc/xen_cpuperf.c
+401d7e16hWEsgEnMwbPM9sKyInomWw tools/misc/xen_dmesg.py
3f8bcf29ulZIC9rC4wM70H_q4s6VPg tools/misc/xen_log.c
3f13d81eQ9Vz-h-6RDGFkNR9CRP95g tools/misc/xen_nat_enable
3f13d81e6Z6806ihYYUw8GVKNkYnuw tools/misc/xen_nat_enable.README
diff --git a/README b/README
index ca90e0864f..1ff127dd59 100644
--- a/README
+++ b/README
@@ -1,23 +1,23 @@
#############################
- __ __ _ ___
- \ \/ /___ _ __ / | / _ \
- \ // _ \ '_ \ | || | | |
- / \ __/ | | | | || |_| |
- /_/\_\___|_| |_| |_(_)___/
-
+ __ __ _ ____
+ \ \/ /___ _ __ / | |___ \
+ \ // _ \ '_ \ | | __) |
+ / \ __/ | | | | |_ / __/
+ /_/\_\___|_| |_| |_(_)_____|
+
#############################
University of Cambridge Computer Laboratory
-31 Aug 2003
+30 Jan 2004
http://www.cl.cam.ac.uk/netos/xen
About the Xen Virtual Machine Monitor
=====================================
-"Xen" is a Virtual Machine Monitor (VMM) developed by the Systems
-Research Group of the University of Cambridge Computer Laboratory, as
-part of the UK-EPSRC funded XenoServers project.
+"Xen" is a Virtual Machine Monitor (VMM) originally developed by the
+Systems Research Group of the University of Cambridge Computer
+Laboratory, as part of the UK-EPSRC funded XenoServers project.
The XenoServers project aims to provide a "public infrastructure for
global distributed computing", and Xen plays a key part in that,
@@ -54,7 +54,7 @@ tricky to handle. A good description of Xen's design, implementation
and performance is contained in our October 2003 SOSP paper, available
at http://www.cl.cam.ac.uk/netos/papers/2003-xensosp.pdf
-We have been working on porting 3 different operating systems to run
+We have worked on porting 3 different operating systems to run
on Xen: Linux 2.4, Windows XP, and NetBSD.
The Linux 2.4 port (currently Linux 2.4.22) works very well -- we
@@ -65,10 +65,10 @@ tried. We refer to our version of Linux ported to run on Xen as
virtual CPU architecture that we call xeno-x86 (abbreviated to just
"xeno").
-Unfortunately, the NetBSD port has stalled due to lack of man
-power. We believe most of the hard stuff has already been done, and
-are hoping to get the ball rolling again soon. In hindsight, a FreeBSD
-4 port might have been more useful to the community. Any volunteers? :-)
+NetBSD has been ported to Xen by Christian Limpach, and will hopefully
+soon become part of the standard release. Work on a FreeBSD port has
+been started by Kip Macy, and we hope to see this complete for the 1.3
+release.
The Windows XP port is nearly finished. It's running user space
applications and is generally in pretty good shape thanks to some hard
@@ -134,26 +134,32 @@ recommended since they require extra packet copies.
Building Xen and XenoLinux
==========================
-The public master BK repository for the 1.0 release lives at:
-bk://xen.bkbits.net/xeno-1.0.bk
+The public master BK repository for the 1.2 release lives at:
+bk://xen.bkbits.net/xeno-1.2.bk
To fetch a local copy, install the BitKeeper tools, then run:
-'bk clone bk://xen.bkbits.net/xeno-1.0.bk'
+'bk clone bk://xen.bkbits.net/xeno-1.2.bk'
To see how to build Xen, Xenolinux, and all the control tools, inspect
-the tools/misc/xen-clone script in the BK repository. This script can
-be used to clone the repostitory and perform a full build.
+the tools/misc/xen-clone script in the BK repository (also available
+via http://www.cl.cam.ac.uk/netos/xen/readmes/xen-clone). This script
+can be used to clone the repository and perform a full build.
The build procedure for xenolinux is slightly complicated as its done
by running the 'mkbuildtree' script over a pristine Linux tree to turn
it into a xenolinux tree by adding the 'xeno' architecture.
-There's also a pre-built source tree on the project downloads page.
+There's also a recent pre-built source tree on the project downloads
+page: http://www.cl.cam.ac.uk/netos/xen/downloads/xeno-1.2.tar.gz
Using the domain control tools
==============================
-See example Python scripts in tools/examples/
+README.CD contains some example invocations.
+
+See example Python scripts in tools/examples/ and the associated README.
+
+Further documentation is in docs/ (e.g., docs/Xeno-HOWTO), and also in
+
-Further documentation is in docs/ (e.g., docs/Xeno-HOWTO).
diff --git a/README.CD b/README.CD
index a69b165ea3..155795a069 100644
--- a/README.CD
+++ b/README.CD
@@ -1,15 +1,15 @@
#############################
- __ __ _ ___
- \ \/ /___ _ __ / | / _ \
- \ // _ \ '_ \ | || | | |
- / \ __/ | | | | || |_| |
- /_/\_\___|_| |_| |_(_)___/
-
+ __ __ _ ____
+ \ \/ /___ _ __ / | |___ \
+ \ // _ \ '_ \ | | __) |
+ / \ __/ | | | | |_ / __/
+ /_/\_\___|_| |_| |_(_)_____|
+
#############################
- XenDemoCD 1.0
+ XenDemoCD 1.2
University of Cambridge Computer Laboratory
- 29 Sep 2003
+ 24 Jan 2004
http://www.cl.cam.ac.uk/netos/xen
@@ -36,7 +36,7 @@ hardware:
CPU: Pentium Pro/II/III/IV/Xeon, Athlon (i.e. P6 or newer) SMP supported
IDE: Intel PIIX chipset, others will be PIO only (slow)
-SCSI: Adaptec / Dell PERC Raid (aacraid), megaraid, Adaptec aic7xxx
+SCSI: Adaptec / Dell PERC Raid (aacraid), fusion MPT, megaraid, Adaptec aic7xxx
Net: Recommended: Intel e1000, Broadcom BCM57xx (tg3), 3c905 (3c59x)
Working, but require extra copies : pcnet32, Intel e100, tulip
@@ -47,9 +47,9 @@ To try out the Demo, boot from CD (you may need to change your BIOS
configuration to do this), then select one of the four boot options
from the Grub menu:
- Xen / linux-2.4.22
- Xen / linux-2.4.22 using cmdline IP configuration
- Xen / linux-2.4.22 in "safe mode"
+ Xen / linux-2.4.24
+ Xen / linux-2.4.24 using cmdline IP configuration
+ Xen / linux-2.4.24 in "safe mode"
linux-2.4.22
The last option is a plain linux kernel that runs on the bare machine,
@@ -91,13 +91,13 @@ via ssh::
Once logged in, it should look just like any regular linux box. All
the usual tools and commands should work as per usual. However,
because of the poor random access performance of CD drives, the
-machine will feel rather slugish, and you may run out of memory if you
+machine will feel very slugish, and you may run out of memory if you
make significant modifications to the ramfs filesystem -- for the full
experience, install a Xen and XenoLinux image on you hard drive :-)
You can configure networking, either with 'dhclient' or manually via
'ifconfig' and 'route', remembering to edit /etc/resolv.conf if you
-want DNS.
+want DNS to work.
You can start an X server with 'startx'. It defaults to a conservative
1024x768, but you can edit the script for higher resoloutions. The CD
@@ -115,100 +115,189 @@ work with Xen, and you'll only be able to configure a VGA X
server. We're working on a fix for this for the next release.
If you want to browse the Xen / XenoLinux source, it's all located
-under /usr/local/src, complete with BitKeeper repository. We've also
-included source code and configuration information for the various
-benchmarks we used in the SOSP paper.
+under /usr/local/src/xeno-1.2, complete with BitKeeper
+repository. We've also included source code and configuration
+information for the various benchmarks we used in the SOSP paper.
Starting other domains
======================
-Xen's privileged control interfaces can be accessed using a handy C
-library (libxc.so) or an even easier-to-use Python wrapper module
-(Xc). Example script templates are provided in tools/examples/.
+Xen's privileged control interfaces can be accessed using a C library
+(libxc.so) or an easier-to-use Python wrapper module (Xc). Example
+script templates are provided in tools/examples/.
Abyway, the first thing to do is to set up a window in which you will
receive console output from other domains. Console output will arrive
-as UDP packets destined for 169.254.1.0, so its necessary to setup an
-alias on eth0. The easiest way to do this is to run:
-
- xen_nat_enable
-
-This also inserts a few NAT rules into "domain0", in case you'll be
-starting other domains without their own IP addresses. Alternatively,
-just do "ifconfig eth0:0 169.254.1.0 up". NB: The intention is that in
-future Xen will do NAT itsel (actually RSIP), but this is part of a
-larger work package that isn't stable enough to release.
-
-Next, run a the xen UDP console displayer:
-
- xen_read_console &
-
-
-As mentioned above, a template Python script is provided:
-tools/examples/craetelinuxdom.py. This can be modified to set up a
-virtual Ethernet interface, access to local discs, and various other
-parameters.
-
-When you execute your modified screipt, you should see the domain
-booting on your xen_read_console window.
-
-The new domain may be started with a '4' on the kernel command line to
-tell 'init' to go to runlevel 4 rather than the default of 3. This is
-done simply to suppress a bunch of harmless error messages that would
-otherwise occur when the new (unprivileged) domain tried to access
-physical hardware resources to try setting the hwclock, system font,
-run gpm etc.
-
-After it's booted, you should be able to ssh into your new domain. If
-you went for a NATed address, from domain 0 you should be able to ssh
-into '169.254.1.X' where X is the domain number. If you ran the
-xen_enable_nat script, a bunch of port redirects have been installed
-to enable you to ssh in to other domains remotely. To access the new
-virtual machine remotely, use:
+as UDP packets destined for 169.254.1.0. The DemoCD's startup scripts
+automatically bring up 169.254.1.0 as an alias called eth0:xen (see
+/etc/sysconfig/network-scripts/ifcfg-eth0 )
+
+If you're not intending to configure the new domain with an IP address
+on your LAN, then you'll probably want to use NAT. The
+'xen_nat_enable' installs a few useful iptables rules into domain0 to
+enable NAT. [ NB: The intention is that in future Xen will do NAT
+itsel (actually RSIP), but this is part of a larger work package that
+isn't ready to release.]
+
+Next, run the xen UDP console displayer:
+
+ xen_read_console
+
+[This is currently output only, but infuture we will have
+bidirectional domain console]
+
+Xen has a management interface that can be manipulated from domain0 to
+create new domains, control their CPU, network and memory resource
+allocations, allocate IP addresses, grant access to disk partitions,
+and suspend/resume domains to files, etc. The management interface is
+implemented as a set of library functions (implemented in C) for which
+there are Python language bindings.
+
+We have developed a simple set of example python tools for
+manipulating the interface, with the intention that more sophisticated
+high-level management tools will be developed in due course. Within
+the source repository the tools live in tools/examples/ but are
+installed in /usr/local/bin/ on the CD.
+
+Starting a new domain is achieved using xc_dom_create.py which
+allocates resources to a new domain, populates it with a kernel image
+(and optionally a ramdisk) and then starts it.
+
+It parses a configuration file written in the Python language, the
+default location of which is "/etc/xc/defaults", but this may be
+overridden with the "-f" option. For the Demo CD, the defaults file
+will cause domains to be created with ram-based root file systems, and
+mount their /usr partition from the CD, just like domain0. (If you are
+writing your own config file, the "example" script may be a better
+starting point)
+
+Variables can be initialised and passed into configuration files. Some
+of these may be compulsory, others optional.
+
+The 'defaults' file on the CD requires the 'ip' variable to be set to
+tell Xen what IP address(es) should be routed to this domain. Xen
+will route packets to the domain if they bear one of these addresses
+as a destination address, and will also ensure that packets sent from
+the domain contain one of the addresses as a source address (to
+prevent spoofing). If multiple IP addresses are to be assigned to a
+domain they can be listed in a comma separated list (with no
+whitespace).
+
+The 'mem' variable can be used to change the default memory allocation
+of 64MB. For example to start a domain with two IP addresses and
+72MB:
+
+ xc_dom_create.py -Dip=128.23.45.34,169.254.1.1 -Dmem=72
+
+[multiple variables may also be set with a single '-D' flag by
+separating them with ':'. Also, it's possible to use DNS hostnames
+rather than IP addresses.]
+
+When invoked with the '-n' option xc_dom_create.py will do a dry run
+and just print out what resources and configuration the domain will
+have e.g.:
+
+ [root@xendemo]# xc_dom_create.py -D ip=commando-1.xeno,169.254.2.3 -Dmem=100
+ Parsing config file 'defaults'
+
+ VM image : "/boot/xenolinux.gz"
+ VM ramdisk : "/boot/initrd.gz"
+ VM memory (MB) : "100"
+ VM IP address(es) : "128.232.38.51:169.254.2.3"
+ VM block device(s) : "phy:cdrom,hdd,r"
+ VM cmdline : "ip=128.232.38.51:169.254.1.0:128.232.32.1:255.255.240.0::eth0:off root=/dev/ram0 rw init=/linuxrc 4 LOCALIP=169.254.2.3"
+
+If you invoke xc_dom_create.py without the '-n' option you should see
+the domain booting on your xen_read_console window.
+
+The 169.254.x.x network is special in that it is the 'link local'
+subnet, and is isolated from the external network and hence can only
+be used for communication between virtual machines. By convention, we
+usually give each domain a link local address. The startup scripts on
+the CD have been modified to accept a LINKLOCAL= parameter on the
+kernel command line and initialise an IP alias accordingly (see
+/etc/sysinit/network-scripts/ifcfg-eth0).
+
+Linux only allows one IP address to be specified on the kernel command
+line, so if you specify multiple IP addresses you'll need to configure
+the new Linux VM with the other addresses manually (using ifconfig)
+having logged in.
+
+If you inspect the 'defaults' config script you'll see that the new
+domain was started with a '4' on the kernel command line to tell
+'init' to go to runlevel 4 rather than the default of 3 used by
+domain0. This is done simply to suppress a bunch of harmless error
+messages that would otherwise occur when the new (unprivileged) domain
+tried to access physical hardware resources to try setting the
+hwclock, system font, run gpm etc.
+
+[root@commando-0 examples]# ./xc_dom_create.py -?
+Usage: ./xc_dom_create.py <args>
+
+This tool is used to create and start new domains. It reads defaults
+from a file written in Python, having allowed variables to be set and
+passed into the file. Further command line arguments allow the
+defaults to be overridden. The defaults for each parameter are listed
+in [] brackets. Arguments are as follows:
+
+Arguments to control the parsing of the defaults file:
+ -f config_file -- Use the specified defaults script.
+ Default: ['/etc/xc/defaults']
+ -D foo=bar -- Set variable foo=bar before parsing config
+ E.g. '-D vmid=3:ip=1.2.3.4'
+ -h -- Print extended help message, including all arguments
+ -n -- Dry run only, don't actually create domain
+
+The config file /etc/xc/defaults requires the following vars to be defined:
+ ip -- List of IP addr(s) for Xen to route to domain
+ e.g. -Dip='1.2.3.4,5.6.7.8'
+The following variables may be optionally defined:
+ mem -- Adjust initial memory allocation (default 64MB)
+ netmask -- Override gateway for kernel ip= command line
+ gateway -- Override network for kernel ip= command line
+
+
+After it's booted, you should be able to ssh into your new domain from
+domain0 using the link local 19.254.x.x address you assigned. If you
+assigned a further IP address you should be able to ssh in using that
+address too. If you ran the xen_enable_nat script, a bunch of port
+redirects have been installed to enable you to ssh in to other domains
+remotely even if you didn't assign an externally routeable address.
+To access the new virtual machine remotely, use:
ssh -p2201 root@IP.address.Of.Domain0 # use 2202 for domain 2 etc.
-If you configured the new domain with its own IP address, you should
-be able to ssh into it directly.
-
-Script 'tools/examples/listdoms.py' demonstrates how to generate a
-list of all extant domains. Prettier printing is an exercise for the
-reader!
-
-createlinuxdom.py can be used to set the new kernel's command line,
-and hence determine what it uses as a root file system, etc. Although
-the default is to boot in the same manner that domain0 did (using the
-RAM-based file system for root and the CD for /usr) it's possible to
-configure any of the following possibilities, for example:
-
- * initrd=/boot/initrd init=/linuxrc
- boot using an initial ram disk, executing /linuxrc (as per this CD)
-
- * root=/dev/hda3 ro
- boot using a standard hard disk partition as root
- !!! remember to grant access in createlinuxdom.py.
-
- * root=/dev/xvda1 ro
- boot using a pre-configured 'virtual block device' that will be
- attached to a virtual disk that previously has had a file system
- installed on it.
-
- * root=/dev/nfs nfsroot=/path/on/server ip=<blah_including server_IP>
- Boot using an NFS mounted root file system. This could be from a
- remote NFS server, or from an NFS server running in another
- domain. The latter is rather a useful option.
-
-A typical setup might be to allocate a standard disk partition for
-each domain and populate it with files. To save space, having a shared
-read-only usr partition might make sense.
-
-Block devices should only be shared between domains in a read-only
-fashion otherwise the linux kernels will obviously get very confused
-as the file system structure may change underneath them (having the
-same partition mounted rw twice is a sure fire way to cause
-irreparable damage)! If you want read-write sharing, export the
-directory to other domains via NFS from domain0.
+You can manipulate running domains using the xc_dom_control.py tool.
+Invoking it without arguments prints some usage information.
+
+To see what domains are running, run 'xc_dom_control list'. Using the
+tool you can change scheduling parameters, pause a domain, send it a
+shutdown request, or blow it away with the 'destroy' command. You can
+even suspend it to disk (but you probably won't have enough memory to
+do the latter if you're running off the demo CD).
+
+Usage: xc_dom_control [command] <params>
+
+ stop [dom] -- pause a domain
+ start [dom] -- un-pause a domain
+ shutdown [dom] -- request a domain to shutdown
+ destroy [dom] -- immediately terminate a domain
+ pincpu [dom] [cpu] -- pin a domain to the specified CPU
+ save [dom] [file] -- suspend a domain's memory to file
+ restore [file] -- resume a domain from a file
+ list -- print info about all domains
+ listvbds -- print info about all virtual block devs
+ cpu_bvtset [dom] [mcuadv] [warp] [warpl] [warpu]
+ -- set scheduling parameters for domain
+ cpu_bvtslice [slice] -- default scheduler slice
+ vif_stats [dom] [vif] -- get stats for a given network vif
+ vif_addip [dom] [vif] [ip] -- add an IP address to a given vif
+ vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth
+ vif_getsched [dom] [vif] -- print vif's scheduling parameters
+ vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to
+ domain as dev e.g. 'vbd_add phy:sda3 hda1 rw'
+ vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev'
Troubleshooting Problems
@@ -324,18 +413,85 @@ unsupported, use ifname=dummy
The second line specifies which xenolinux image to use, and the
standard linux command line arguments to pass to the kernel. In this
case, we're configuring the root partition and stating that it should
-be mounted read-only (normal practice).
+initially be mounted read-only (normal practice).
If we were booting with an initial ram disk (initrd), then this would
require a second "module" line.
+Installing the Xen tools and source
+===================================
+
+The tools and source live in the /usr/local/src/xen-1.2 directory on
+the CD (and may also be downloaded from the project downloads
+page). You'll need to copy them to some mutable storage before using
+them.
+
+If you have the BitKeeper BK tools installed you can check the
+repository is up to date by cd'ing into the xeno-1.2.bk directory and
+typing 'bk pull' (assuming you have an Internet connection).
+
+You can rebuild Xen and the tools by typing 'make'. You can install
+them to the standard directories with 'make install', or into the
+../install subtree with 'make dist'.
+
+/usr/local/bin/xc_* the domain control tools
+/lib/libxc.so the xc library
+/usr/lib/python2.2/site-packages/XenoUtil.py python util library
+/usr/lib/python2.2/site-packages/Xc.c python xc bindings
+
+If you're using the virtual disk control tools (xc_vd_tool) you'll
+need the SQLite library and python binding pysqlite. There's a tar
+ball containing the necessary binaries on the project downloads page.
+
+
+Modifying xc_mycreatelinuxdom1.py
+=================================
+
+xc_mycreatelinuxdom1.py.py can be used to set the new kernel's command line,
+and hence determine what it uses as a root file system, etc. Although
+the default is to boot in the same manner that domain0 did (using the
+RAM-based file system for root and the CD for /usr) it's possible to
+configure any of the following possibilities, for example:
+
+ * initrd=/boot/initrd init=/linuxrc
+ boot using an initial ram disk, executing /linuxrc (as per this CD)
+
+ * root=/dev/hda3 ro
+ boot using a standard hard disk partition as root
+ !!! remember to grant access in createlinuxdom.py.
+
+ * root=/dev/xvda1 ro
+ boot using a pre-configured 'virtual block device' that will be
+ attached to a virtual disk that previously has had a file system
+ installed on it.
+
+ * root=/dev/nfs nfsroot=/path/on/server ip=<blah_including server_IP>
+ Boot using an NFS mounted root file system. This could be from a
+ remote NFS server, or from an NFS server running in another
+ domain. The latter is rather a useful option.
+
+A typical setup might be to allocate a standard disk partition for
+each domain and populate it with files. To save space, having a shared
+read-only usr partition might make sense.
+
+Block devices should only be shared between domains in a read-only
+fashion otherwise the linux kernels will obviously get very confused
+as the file system structure may change underneath them (having the
+same partition mounted rw twice is a sure fire way to cause
+irreparable damage)! If you want read-write sharing, export the
+directory to other domains via NFS from domain0.
+
+
+
Installing the file systems from the CD
=======================================
-If you haven't an existing Linux installation onto which you can just
-drop down the Xen and XenoLinux images, then the file systems on the
-CD provide a quick way of doing an install.
+If you haven't got an existing Linux installation onto which you can
+just drop down the Xen and XenoLinux images, then the file systems on
+the CD provide a quick way of doing an install. However, you're
+probably better off in the long run doing a proper Redhat, Fedora,
+Debian etc install rather than just doing the hack described below:
Choose one or two partitions, depending on whether you want a separate
/usr or not. Make file systems on it/them e.g.:
diff --git a/tools/Makefile b/tools/Makefile
index 96913d7424..a2bf548d9f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -21,19 +21,23 @@ all:
$(MAKE) -C balloon
$(MAKE) -C xc
$(MAKE) -C misc
+ $(MAKE) -C examples
install: all
$(MAKE) -C balloon install
$(MAKE) -C xc install
$(MAKE) -C misc install
+ $(MAKE) -C examples install
dist: all
$(MAKE) -C balloon dist
$(MAKE) -C xc dist
$(MAKE) -C misc dist
+ $(MAKE) -C examples dist
clean:
$(MAKE) -C balloon clean
$(MAKE) -C xc clean
$(MAKE) -C misc clean
+ $(MAKE) -C examples clean
diff --git a/tools/examples/Makefile b/tools/examples/Makefile
new file mode 100644
index 0000000000..7a8089f74e
--- /dev/null
+++ b/tools/examples/Makefile
@@ -0,0 +1,34 @@
+
+CC = gcc
+CFLAGS = -Wall -O3
+EXTRA_INC = -I../../xen/include -I../../xenolinux-sparse/include -I../xc/lib
+
+HDRS = $(wildcard *.h)
+SRCS = $(wildcard *.c)
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+
+INSTALL = $(wildcard *.py)
+ETC = defaults democd
+
+all:
+
+install: all
+ mkdir -p /usr/bin
+ cp -a $(INSTALL) /usr/bin
+ #chmod 755 $(INSTALL)
+ mkdir -p /etc/xc
+ for i in $(ETC) ; do [ ! -e /etc/xc/$$i ] && echo Install $$i && cp $$i /etc/xc/ ; done || true
+
+dist: all
+ mkdir -p ../../../install/bin
+ mkdir -p ../../../install/etc
+ cp -a $(INSTALL) ../../../install/bin
+ cp -a $(ETC) ../../../install/etc
+ #chmod 755 $(INSTALL)
+
+clean:
+
+
+%: %.c $(HDRS) Makefile
+ $(CC) $(CFLAGS) $(EXTRA_INC) -o $@ $<
+
diff --git a/tools/examples/README b/tools/examples/README
new file mode 100644
index 0000000000..13379bb5c4
--- /dev/null
+++ b/tools/examples/README
@@ -0,0 +1,109 @@
+Xen Control Tools - Example Scripts
+===================================
+
+This directory contains a set of example scripts for common Xen operations.
+For many operations you will either be able to use these scripts directly, or
+incorporate code from them into your own scripts.
+
+The Xc and XenoUtil Python modules provide an API for accessing all this
+functionality - and more - from your own Python programs. These libraries may
+contain features for which there aren't yet example scripts written for...
+
+If you write a useful script and would like to share it, please do
+send it (preferably with a little summary to go in this file) to
+<xen-devel@lists.sourceforge.net> so we can add it to this directory.
+
+xc_dom_control.py
+ - general tool for controling running domains
+ Usage: xc_dom_control.py [command] <params>
+ stop [dom] -- pause a domain
+ start [dom] -- un-pause a domain
+ shutdown [dom] -- request a domain to shutdown
+ destroy [dom] -- immediately terminate a domain
+ pincpu [dom] [cpu] -- pin a domain to the specified CPU
+ save [dom] [file] -- suspend a domain's memory to file
+ restore [file] -- resume a domain from a file
+ list -- print info about all domains
+ listvbds -- print info about all virtual block devs
+ cpu_bvtset [dom] [mcuadv] [warp] [warpl] [warpu]
+ -- set scheduling parameters for domain
+ cpu_bvtslice [slice] -- default scheduler slice
+ vif_stats [dom] [vif] -- get stats for a given network vif
+ vif_addip [dom] [vif] [ip] -- add an IP address to a given vif
+ vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth
+ vif_getsched [dom] [vif] -- print vif's scheduling parameters
+ vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to
+ domain as dev e.g. 'vbd_add phy:sda3 hda1 rw'
+ vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev'
+
+
+xc_dom_create.py
+ - This tool is used to create and start new domains. It reads defaults
+from a file written in Python, having allowed variables to be set and
+passed into the file. Further command line arguments allow the
+defaults to be overridden. The defaults for each parameter are listed
+in [] brackets. Arguments are as follows:
+
+Arguments to control the parsing of the defaults file:
+ -f config_file -- Use the specified defaults script.
+ Default: ['/etc/xc/defaults']
+ -D foo=bar -- Set variable foo=bar before parsing config
+ E.g. '-D vmid=3:ip=1.2.3.4'
+ -h -- Print extended help message, including all arguments
+ -n -- Dry run only, don't actually create domain
+
+
+The config file 'defaults' requires the following variable to be defined:
+ vmid -- Numeric identifier for the new domain, used to calculate
+ the VM's IP address and root partition. E.g. -Dvmid=1
+
+
+Arguments to override current config read from 'defaults':
+ -k image -- Path to kernel image ['']
+ -r ramdisk -- Path to ramdisk (or empty) ['']
+ -b builder_fn -- Function to use to build domain ['']
+ -m mem_size -- Initial memory allocation in MB [0MB]
+ -N domain_name -- Set textual name of domain ['']
+ -a auto_restart -- Restart domain on exit, yes/no ['0']
+ -e vbd_expert -- Saftey catch to avoid some disk accidents ['0']
+ -d udisk,dev,rw -- Add disk, partition, or virtual disk to domain. E.g. to
+ make partion sda4 available to the domain as hda1 with
+ read-write access: '-b phy:sda4,hda1,rw' To add
+ multiple disks use multiple -d flags or seperate with ':'
+ Default: ['']
+ -i vfr_ipaddr -- Add IP address to the list which Xen will route to
+ the domain. Use multiple times to add more IP addrs.
+ Default: ['']
+
+Args to override the kernel command line, which is concatenated from these:
+ -I cmdline_ip -- Override 'ip=ipaddr:nfsserv:gateway:netmask::eth0:off'
+ Default: ['']
+ -R cmdline_root -- Override root device parameters.
+ Default: ['']
+ -E cmdline_extra -- Override extra kernel args and rc script env vars.
+ Default: ['']
+
+
+
+xc_vd_tool
+ - tool for manipulating virtual disks
+ Usage: xc_vd_tool command <params>
+
+ initalise [dev] [[ext_size]] - init. a physcial partition to store vd's
+ create [size] [[expiry]] - allocate a vd of specified size (and expiry)
+ delete [vdid] - delete a vd
+ import [filename] [[expiry]] - create a vd and populate w/ image from file
+ export [vdid] [filename] - copy vd's contents to a file
+ setexpiry [vdid] [[expiry]] - update the expiry time for a vd
+ list - list all the unexpired virtual disks
+ undelete [vdid] [[expiry]] - attempts to recover an expired vd
+ freespace - print out the amount of space in free pool
+
+ notes:
+ vdid - the virtual disk's identity string
+ size - measured in MB
+ expiry - is the expiry time of the virtual disk in seconds from now
+ (0 = don't expire)
+ device - physical partition to 'format' to hold vd's. e.g. hda4
+ ext_size - extent size (default 64MB)
+
diff --git a/tools/examples/defaults b/tools/examples/defaults
new file mode 100644
index 0000000000..0afdebb7af
--- /dev/null
+++ b/tools/examples/defaults
@@ -0,0 +1,89 @@
+
+##### Edit this python file to reflect the configuration of your system
+
+##### This example script expects a variable called 'vmid' to be set.
+
+def config_usage ():
+ print >>sys.stderr,"""
+The config file '%s' requires the following variable to be defined:
+ vmid -- Numeric identifier for the new domain, used to calculate
+ the VM's IP address and root partition. E.g. -Dvmid=1
+""" % config_file
+
+
+try:
+ vmid=int(vmid) # convert to integer
+except:
+ print >>sys.stderr,"%s: This script expects 'vmid' to be set using -D vmid=X" % config_file
+ assert()
+
+if vmid == 0:
+ print >>sys.stderr,"%s: 'vmid' must be greater than 0" % config_file
+ assert()
+
+
+# STEP 1. Specify kernel image file and otional ramdisk. Can be gzip'ed.
+image = "../../../install/boot/xenolinux.gz"
+ramdisk = ""
+#ramdisk = "/boot/initrd.gz"
+builder_fn='xc.linux_build' # this is a linux domain
+
+# STEP 2. The initial memory allocation (in megabytes) for the new domain.
+mem_size = 64
+
+
+# STEP 3. A handy name for your new domain.
+domain_name = "This is VM %d" % vmid
+
+
+# STEP 4. Specify IP address(es), for the new domain. You need to
+# configure IP addrs within the domain just as you do normally. This
+# is just to let Xen know about them so it can route packets
+# appropriately.
+
+#vfr_ipaddr = ["111.222.333.444","222.333.444.555"]
+vfr_ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),vmid),
+ XenoUtil.add_offset_to_ip('169.254.1.0',vmid),]
+
+
+# STEP 5a. Identify any physcial partitions or virtual disks you want the
+# domain to have access to, and what you want them accessible as
+# e.g. vbd_list = [ ('phy:sda1','sda1', 'w'),
+# ('phy:sda%d' % (3+vmid), 'hda2', 'r'),
+# ('vd:as73gd784dh','hda1','w'),
+# ('phy:cdrom','hdd','r')
+
+vbd_list = [ ('phy:sda%d'%(7+vmid),'sda1','w' ),
+ ('phy:sda6','sda6','r') ]
+
+
+
+# STEP 5b. Set the VBD expertise level. Most people should leave this
+# on 0, at least to begin with - this script can detect most dangerous
+# disk sharing between domains and with this set to zero it will only
+# allow read only sharing.
+
+vbd_expert = 0
+
+
+# STEP 6. Build the command line for the new domain. Edit as req'd.
+# You only need the ip= line if you're NFS booting or the root file system
+# doesn't set it later e.g. in ifcfg-eth0 or via DHCP
+# You can use 'extrabit' to set the runlevel and custom environment
+# variables used by custom rc scripts (e.g. VMID=, usr= )
+
+netmask = XenoUtil.get_current_ipmask()
+gateway = XenoUtil.get_current_ipgw()
+nfsserv = '169.254.1.0'
+
+cmdline_ip = "ip="+vfr_ipaddr[0]+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off"
+cmdline_root = "root=/dev/sda1 ro"
+#cmdline_root = "root=/dev/nfs nfsroot=/full/path/to/root/directory"
+cmdline_extra = "4 VMID=%d usr=/dev/sda6" % vmid
+
+
+# STEP 7. Set according to whether you want the script to watch the domain
+# and auto-restart it should it die or exit.
+
+auto_restart = False
+#auto_restart = True
diff --git a/tools/examples/democd b/tools/examples/democd
new file mode 100644
index 0000000000..da266f35ea
--- /dev/null
+++ b/tools/examples/democd
@@ -0,0 +1,126 @@
+
+##### Edit this python file to reflect the configuration of your system
+
+##### This example script requires variable 'ip' to be set, and optionally
+##### netmask and gatewaty for the kernel command line
+
+def config_usage ():
+ print >>sys.stderr, """
+The config file %s requires the following vars to be defined:
+ ip -- List of IP addr(s) for Xen to route to domain
+ e.g. -Dip='1.2.3.4,5.6.7.8'
+The following variables may be optionally defined:
+ mem -- Adjust initial memory allocation (default 64MB)
+ netmask -- Override gateway for kernel ip= command line
+ gateway -- Override network for kernel ip= command line
+""" % config_file
+
+try:
+ ip
+except:
+ print "Set variable 'ip' using -Dip='1.2.3.4,5.6.7.8'"
+ assert()
+
+# STEP 1. Specify kernel image file and otional ramdisk. Can be gzip'ed.
+image = "/boot/xenolinux.gz"
+ramdisk = "/boot/initrd.gz"
+builder_fn='xc.linux_build' # this is a linux domain
+
+# STEP 2. The initial memory allocation (in megabytes) for the new domain.
+try:
+ mem_size = int(mem)
+except NameError:
+ mem_size = 64
+
+
+# STEP 3. A handy name for your new domain.
+domain_name = "Demo CD VM %s" % ip
+
+
+# STEP 4. Specify IP address(es), for the new domain. You need to
+# configure IP addrs within the domain just as you do normally. This
+# is just to let Xen know about them so it can route packets
+# appropriately.
+
+#vfr_ipaddr = ["111.222.333.444","222.333.444.555"]
+#vfr_ipaddr = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),vmid)]
+vfr_ipaddr = map(socket.gethostbyname,string.split(ip,','))
+
+
+# STEP 5a. Identify any physcial partitions or virtual disks you want the
+# domain to have access to, and what you want them accessible as
+# e.g. vbd_list = [ ('phy:sda1','sda1', 'w'),
+# ('phy:sda%d' % (3+vmid), 'hda2', 'r'),
+# ('vd:as73gd784dh','hda1','w'),
+# ('phy:cdrom','hdd','r')
+
+vbd_list = [ ('phy:cdrom','hdd','r' ) ]
+
+
+
+# STEP 5b. Set the VBD expertise level. Most people should leave this
+# on 0, at least to begin with - this script can detect most dangerous
+# disk sharing between domains and with this set to zero it will only
+# allow read only sharing.
+
+vbd_expert = 0
+
+
+# STEP 6. Build the command line for the new domain. Edit as req'd.
+# You only need the ip= line if you're NFS booting or the root file system
+# doesn't set it later e.g. in ifcfg-eth0 or via DHCP
+# You can use 'extrabit' to set the runlevel and custom environment
+# variables used by custom rc scripts (e.g. VMID=, usr= )
+
+try:
+ netmask = socket.gethostbyname( netmask )
+except NameError:
+ netmask = XenoUtil.get_current_ipmask()
+
+try:
+ gateway = socket.gethostbyname( gateway )
+except NameError:
+ gateway = XenoUtil.get_current_ipgw()
+
+localip=''
+for i in vfr_ipaddr:
+ if XenoUtil.check_subnet(i,'169.254.0.0','255.255.0.0'): localip=i
+
+# Try to guess the machine's LAN settings
+
+lanip=''
+if netmask and gateway:
+ for i in vfr_ipaddr:
+ if XenoUtil.check_subnet(i,gateway,netmask):
+ lanip=i
+ break
+
+# Have a fall back plan...
+
+if not netmask:
+ netmask = '255.255.0.0'
+
+if not gateway:
+ gateway = '169.254.1.0'
+
+if not lanip:
+ lanip = vfr_ipaddr[0]
+
+
+# Calculate the components with which we will build the command line
+
+nfsserv = '169.254.1.0'
+
+cmdline_ip="ip="+lanip+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off"
+cmdline_root = "root=/dev/ram0 rw init=/linuxrc"
+
+if localip:
+ cmdline_extra = "4 LOCALIP=%s" % localip
+else:
+ cmdline_extra = "4"
+
+# STEP 7. Set according to whether you want the script to watch the domain
+# and auto-restart it should it die or exit.
+
+auto_restart = False
+#auto_restart = True
diff --git a/tools/examples/xc_dom_control.py b/tools/examples/xc_dom_control.py
new file mode 100755
index 0000000000..540d9d3c1c
--- /dev/null
+++ b/tools/examples/xc_dom_control.py
@@ -0,0 +1,219 @@
+#!/usr/bin/env python
+
+# usage: xc_dom_control [command] <params>
+#
+# this script isn't very smart, but it'll do for now.
+#
+
+def usage ():
+ print >>sys.stderr, """
+Usage: %s [command] <params>
+
+ stop [dom] -- pause a domain
+ start [dom] -- un-pause a domain
+ shutdown [dom] -- request a domain to shutdown
+ destroy [dom] -- immediately terminate a domain
+ pincpu [dom] [cpu] -- pin a domain to the specified CPU
+ save [dom] [file] -- suspend a domain's memory to file
+ restore [file] -- resume a domain from a file
+ list -- print info about all domains
+ listvbds -- print info about all virtual block devs
+ cpu_bvtset [dom] [mcuadv] [warp] [warpl] [warpu]
+ -- set scheduling parameters for domain
+ cpu_bvtslice [slice] -- default scheduler slice
+ vif_stats [dom] [vif] -- get stats for a given network vif
+ vif_addip [dom] [vif] [ip] -- add an IP address to a given vif
+ vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth
+ vif_getsched [dom] [vif] -- print vif's scheduling parameters
+ vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to
+ domain as dev e.g. 'vbd_add phy:sda3 hda1 rw'
+ vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev'
+""" % sys.argv[0]
+
+import Xc, sys, re, string
+
+if len(sys.argv) < 2:
+ usage()
+ sys.exit(-1)
+
+cmd = sys.argv[1]
+
+
+xc = Xc.new()
+rc = ''
+
+if len( sys.argv ) > 2 and re.match('\d+$', sys.argv[2]):
+ dom = string.atoi(sys.argv[2])
+
+if cmd == 'stop':
+ rc = xc.domain_stop( dom=dom )
+
+elif cmd == 'start':
+ rc = xc.domain_start( dom=dom )
+
+elif cmd == 'shutdown':
+ rc = xc.domain_destroy( dom=dom, force=0 )
+
+elif cmd == 'destroy':
+ rc = xc.domain_destroy( dom=dom, force=1 )
+
+elif cmd == 'pincpu':
+
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(-1)
+
+ cpu = int(sys.argv[3])
+ orig_state = xc.domain_getinfo(first_dom=dom, max_doms=1)[0]['stopped']
+
+ while xc.domain_getinfo(first_dom=dom, max_doms=1)[0]['stopped'] != 1:
+ xc.domain_stop( dom=dom )
+ time.sleep(0.1)
+
+ rc = xc.domain_pincpu( dom, cpu )
+
+ if orig_state == 0:
+ xc.domain_start( dom=dom )
+
+elif cmd == 'list':
+ for i in xc.domain_getinfo(): print i
+
+elif cmd == 'listvbds':
+ for i in xc.vbd_probe(): print i
+
+elif cmd == 'save':
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(-1)
+
+ file = sys.argv[3]
+
+ rc = xc.linux_save( dom=dom, state_file=file, progress=1)
+
+elif cmd == 'restore':
+ if len(sys.argv) < 3:
+ usage()
+ sys.exit(-1)
+
+ file = sys.argv[2]
+ rc = xc.linux_restore( state_file=file, progress=1 )
+
+elif cmd == 'cpu_bvtslice':
+ if len(sys.argv) < 3:
+ usage()
+ sys.exit(-1)
+
+ slice = dom # first int argument is in "dom" (!)
+
+ rc = xc.bvtsched_global_set(ctx_allow=slice)
+
+elif cmd == 'cpu_bvtset':
+ if len(sys.argv) < 7:
+ usage()
+ sys.exit(-1)
+
+ mcuadv = int(sys.argv[3])
+ warp = int(sys.argv[4])
+ warpl = int(sys.argv[5])
+ warpu = int(sys.argv[6])
+
+ rc = xc.bvtsched_domain_set(dom=dom, mcuadv=mcuadv, warp=warp,
+ warpl=warpl, warpu=warpu)
+elif cmd == 'vif_stats':
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(-1)
+
+ vif = int(sys.argv[3])
+
+ print xc.vif_stats_get(dom=dom, vif=vif)
+
+elif cmd == 'vif_addip':
+ if len(sys.argv) < 5:
+ usage()
+ sys.exit(-1)
+
+ vif = int(sys.argv[3])
+ ip = sys.argv[4]
+
+ # XXX This function should be moved to Xc once we sort out the VFR
+ import XenoUtil
+ XenoUtil.setup_vfr_rules_for_vif( dom, vif, ip )
+
+elif cmd == 'vif_setsched':
+ if len(sys.argv) < 6:
+ usage()
+ sys.exit(-1)
+
+ vif = int(sys.argv[3])
+ credit_bytes = int(sys.argv[4])
+ credit_usecs = int(sys.argv[5])
+
+ rc = xc.xc_vif_scheduler_set(dom=dom, vif=vif,
+ credit_bytes=credit_bytes,
+ credit_usecs=credit_usecs)
+
+elif cmd == 'vif_getsched':
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(-1)
+
+ vif = int(sys.argv[3])
+
+ print xc.vif_scheduler_get(dom=dom, vif=vif)
+
+
+elif cmd == 'vbd_add':
+
+ XenoUtil.VBD_EXPERT_LEVEL = 0 # sets the allowed level of potentially unsafe mappings
+
+ if len(sys.argv) < 6:
+ usage()
+ sys.exit(1)
+
+ uname = sys.argv[3]
+ dev = sys.argv[4]
+ mode = sys.argv[5]
+
+ writeable = 0
+ if mode == 'rw' or mode == 'w':
+ writeable = 1;
+
+ segments = XenoUtil.lookup_disk_uname(uname)
+
+ if XenoUtil.vd_extents_validate(segments,writeable) < 0:
+ print "That mapping is too unsafe for the current VBD expertise level"
+ sys.exit(1)
+
+ virt_dev = XenoUtil.blkdev_name_to_number(dev)
+
+ xc.vbd_create(dom,virt_dev,writeable)
+
+ if xc.vbd_setextents( dom, virt_dev, segments ):
+ print "Error populating VBD vbd=%d\n" % virt_dev
+ sys.exit(1)
+
+ print "Added disk/partition %s to domain %d as device %s (%x)" % (uname, dom, dev, virt_dev)
+
+elif cmd == 'vbd_remove':
+
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(1)
+
+ dev = sys.argv[3]
+ virt_dev = XenoUtil.blkdev_name_to_number(dev)
+
+ if not xc.vbd_destroy(dom,virt_dev):
+ print "Removed disk/partition attached as device %s (%x) in domain %d" % (dev, virt_dev, dom)
+ else:
+ print "Failed"
+ sys.exit(1)
+
+
+else:
+ usage()
+ sys.exit(-1)
+
+if rc != '':
+ print "return code %d" % rc
diff --git a/tools/examples/xc_dom_create.py b/tools/examples/xc_dom_create.py
new file mode 100755
index 0000000000..6eaeb34715
--- /dev/null
+++ b/tools/examples/xc_dom_create.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python
+
+import Xc, XenoUtil, string, sys, os, time, socket, getopt
+
+config_dir = '/etc/xc/'
+config_file = xc_config_file = config_dir + 'defaults'
+
+def main_usage ():
+ print >>sys.stderr,"""
+Usage: %s <args>
+
+This tool is used to create and start new domains. It reads defaults
+from a file written in Python, having allowed variables to be set and
+passed into the file. Further command line arguments allow the
+defaults to be overridden. The defaults for each parameter are listed
+in [] brackets. Arguments are as follows:
+
+Arguments to control the parsing of the defaults file:
+ -f config_file -- Use the specified defaults script.
+ Default: ['%s']
+ -D foo=bar -- Set variable foo=bar before parsing config
+ E.g. '-D vmid=3:ip=1.2.3.4'
+ -h -- Print extended help message, including all arguments
+ -n -- Dry run only, don't actually create domain
+""" % (sys.argv[0], xc_config_file)
+
+def extra_usage ():
+ print >>sys.stderr,"""
+Arguments to override current config read from '%s':
+ -k image -- Path to kernel image ['%s']
+ -r ramdisk -- Path to ramdisk (or empty) ['%s']
+ -b builder_fn -- Function to use to build domain ['%s']
+ -m mem_size -- Initial memory allocation in MB [%dMB]
+ -N domain_name -- Set textual name of domain ['%s']
+ -a auto_restart -- Restart domain on exit, yes/no ['%d']
+ -e vbd_expert -- Saftey catch to avoid some disk accidents ['%d']
+ -d udisk,dev,rw -- Add disk, partition, or virtual disk to domain. E.g. to
+ make partion sda4 available to the domain as hda1 with
+ read-write access: '-b phy:sda4,hda1,rw' To add
+ multiple disks use multiple -d flags or seperate with ':'
+ Default: ['%s']
+ -i vfr_ipaddr -- Add IP address to the list which Xen will route to
+ the domain. Use multiple times to add more IP addrs.
+ Default: ['%s']
+
+Args to override the kernel command line, which is concatenated from these:
+ -I cmdline_ip -- Override 'ip=ipaddr:nfsserv:gateway:netmask::eth0:off'
+ Default: ['%s']
+ -R cmdline_root -- Override root device parameters.
+ Default: ['%s']
+ -E cmdline_extra -- Override extra kernel args and rc script env vars.
+ Default: ['%s']
+
+""" % (config_file,
+ image, ramdisk, builder_fn, mem_size, domain_name, auto_restart,
+ vbd_expert,
+ printvbds( vbd_list ),
+ reduce ( (lambda a,b: a+':'+b), vfr_ipaddr,'' )[1:],
+ cmdline_ip, cmdline_root, cmdline_extra)
+
+def config_usage (): pass
+
+def answer ( s ):
+ s = string.lower(s)
+ if s == 'yes' or s == 'true' or s == '1': return 1
+ return 0
+
+def printvbds ( v ):
+ s=''
+ for (a,b,c) in v:
+ s = s + ':%s,%s,%s' % (a,b,c)
+ return s[1:]
+
+
+bail=False; dryrun=False; extrahelp=False
+image=''; ramdisk=''; builder_fn='';
+mem_size=0; domain_name=''; vfr_ipaddr=[];
+vbd_expert=0; auto_restart=0;
+vbd_list = []; cmdline_ip = ''; cmdline_root=''; cmdline_extra=''
+
+##### Determine location of defautls file
+#####
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "h?nf:D:k:r:b:m:N:a:e:d:i:I:R:E:" )
+
+ for opt in opts:
+ if opt[0] == '-f': config_file= opt[1]
+ if opt[0] == '-h' or opt[0] == '-?' : bail=True; extrahelp=True
+ if opt[0] == '-n': dryrun=True
+ if opt[0] == '-D':
+ for o in string.split( opt[1], ':' ):
+ (l,r) = string.split( o, '=' )
+ exec "%s='%s'" % (l,r)
+
+
+except getopt.GetoptError:
+ bail=True
+
+
+try:
+ os.stat( config_file )
+except:
+ try:
+ d = config_dir + config_file
+ os.stat( d )
+ config_file = d
+ except:
+ print >> sys.stderr, "Unable to open config file '%s'" % config_file
+ bail = True
+
+
+##### Parse the config file
+#####
+
+print "Parsing config file '%s'" % config_file
+
+try:
+ execfile ( config_file )
+except (AssertionError,IOError):
+ print >>sys.stderr,"Exiting %s" % sys.argv[0]
+ bail = True
+
+##### Print out config if necessary
+#####
+
+if bail:
+ main_usage()
+ config_usage()
+ if extrahelp: extra_usage()
+ sys.exit(1)
+
+##### Parse any command line overrides
+#####
+
+x_vbd_list = []
+x_vfr_ipaddr = []
+
+for opt in opts:
+ if opt[0] == '-k': image = opt[1]
+ if opt[0] == '-r': ramdisk = opt[1]
+ if opt[0] == '-b': builder_fn = opt[1] #XXXX
+ if opt[0] == '-m': mem_size = int(opt[1])
+ if opt[0] == '-N': domain_name = opt[1]
+ if opt[0] == '-a': auto_restart = answer(opt[1])
+ if opt[0] == '-e': vbd_expert = answer(opt[1])
+ if opt[0] == '-I': cmdline_ip = opt[1]
+ if opt[0] == '-R': cmdline_root = opt[1]
+ if opt[0] == '-E': cmdline_extra = opt[1]
+ if opt[0] == '-i': x_vfr_ipaddr.append(opt[1])
+ if opt[0] == '-d':
+ try:
+ vv = string.split(opt[1],':')
+ for v in vv:
+ (udisk,dev,mode) = string.split(v,',')
+ x_vbd_list.append( (udisk,dev,mode) )
+ except:
+ print >>sys.stderr, "Invalid block device specification : %s" % opt[1]
+ sys.exit(1)
+
+if x_vbd_list: vbd_list = x_vbd_list
+if x_vfr_ipaddr: vfr_ipaddr = x_vfr_ipaddr
+
+cmdline = cmdline_ip +' '+ cmdline_root +' '+ cmdline_extra
+
+##### Print some debug info just incase things don't work out...
+#####
+
+print
+print 'VM image : "%s"' % image
+print 'VM ramdisk : "%s"' % ramdisk
+print 'VM memory (MB) : "%d"' % mem_size
+print 'VM IP address(es) : "%s"' % reduce((lambda a,b: a+':'+b),vfr_ipaddr,'' )[1:]
+print 'VM block device(s) : "%s"' % printvbds( vbd_list )
+print 'VM cmdline : "%s"' % cmdline
+print
+
+if dryrun:
+ sys.exit(1)
+
+##### Code beyond this point is actually used to manage the mechanics of
+##### starting (and watching if necessary) guest virtual machines.
+
+# Obtain an instance of the Xen control interface
+xc = Xc.new()
+
+# This function creates, builds and starts a domain, using the values
+# in the global variables, set above. It is used in the subsequent
+# code for starting the new domain and rebooting it if appropriate.
+def make_domain():
+ """Create, build and start a domain.
+ Returns: [int] the ID of the new domain.
+ """
+
+ # set up access to the global variables declared above
+ global image, ramdisk, mem_size, domain_name, vfr_ipaddr, netmask
+ global vbd_list, cmdline, xc, vbd_expert
+
+ if not os.path.isfile( image ):
+ print "Image file '" + image + "' does not exist"
+ sys.exit()
+
+ if ramdisk and not os.path.isfile( ramdisk ):
+ print "Ramdisk file '" + ramdisk + "' does not exist"
+ sys.exit()
+
+ id = xc.domain_create( mem_kb=mem_size*1024, name=domain_name )
+ if id <= 0:
+ print "Error creating domain"
+ sys.exit()
+
+ ret = xc.linux_build( dom=id, image=image, ramdisk=ramdisk,
+ cmdline=cmdline )
+ if ret < 0:
+ print "Error building Linux guest OS: "
+ print "Return code from linux_build = " + str(ret)
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+
+ # setup the virtual block devices
+
+ # set the expertise level appropriately
+ XenoUtil.VBD_EXPERT_MODE = vbd_expert
+
+ for ( uname, virt_name, rw ) in vbd_list:
+ virt_dev = XenoUtil.blkdev_name_to_number( virt_name )
+
+ segments = XenoUtil.lookup_disk_uname( uname )
+ if not segments:
+ print "Error looking up %s\n" % uname
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+
+ # check that setting up this VBD won't violate the sharing
+ # allowed by the current VBD expertise level
+ if XenoUtil.vd_extents_validate(segments, rw=='w' or rw=='rw') < 0:
+ xc.domain_destroy( dom = id )
+ sys.exit()
+
+ if xc.vbd_create( dom=id, vbd=virt_dev, writeable= rw=='w' or rw=='rw' ):
+ print "Error creating VBD vbd=%d writeable=%d\n" % (virt_dev,rw)
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+
+ if xc.vbd_setextents( dom=id,
+ vbd=virt_dev,
+ extents=segments):
+ print "Error populating VBD vbd=%d\n" % virt_dev
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+
+ # setup virtual firewall rules for all aliases
+ for ip in vfr_ipaddr:
+ XenoUtil.setup_vfr_rules_for_vif( id, 0, ip )
+
+ if xc.domain_start( dom=id ) < 0:
+ print "Error starting domain"
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+
+ return id
+# end of make_domain()
+
+
+
+# The starting / monitoring of the domain actually happens here...
+
+# start the domain and record its ID number
+current_id = make_domain()
+print "VM started in domain %d" % current_id
+
+# if the auto_restart flag is set then keep polling to see if the domain is
+# alive - restart if it is not by calling make_domain() again (it's necessary
+# to update the id variable, since the new domain may have a new ID)
+
+if auto_restart:
+ # turn ourselves into a background daemon
+ try:
+ pid = os.fork()
+ if pid > 0:
+ sys.exit(0)
+ os.setsid()
+ pid = os.fork()
+ if pid > 0:
+ print >> sys.stderr, 'Auto-restart daemon PID = %d' % pid
+ sys.exit(0)
+ except:
+ print >> sys.stderr, 'Problem starting daemon'
+ sys.exit(1)
+
+ while auto_restart:
+ time.sleep(1)
+ if not xc.domain_getinfo(current_id):
+ print "Domain %d has terminated, restarting VM in new domain" % current_id
+ current_id = make_domain()
+ print "VM started in domain %d" % current_id
diff --git a/tools/examples/xc_vd_tool.py b/tools/examples/xc_vd_tool.py
new file mode 100755
index 0000000000..787bcff0fa
--- /dev/null
+++ b/tools/examples/xc_vd_tool.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+
+import XenoUtil, sys, re, string
+
+def usage():
+
+ print >>sys.stderr,"""
+Usage: %s command <params>
+
+ initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
+ create [size] [[expiry]] - allocate a vd of specified size (and expiry)
+ enlarge [vdid] [extra_size] - enlarge a specified vd by some amount
+ delete [vdid] - delete a vd
+ import [filename] [[expiry]] - create a vd and populate w/ image from file
+ export [vdid] [filename] - copy vd's contents to a file
+ setexpiry [vdid] [[expiry]] - update the expiry time for a vd
+ list - list all the unexpired virtual disks
+ undelete [vdid] [[expiry]] - attempts to recover an expired vd
+ freespace - print out the amount of space in free pool
+
+notes:
+ vdid - the virtual disk's identity string
+ size - measured in MB
+ expiry - is the expiry time of the virtual disk in seconds from now
+ (0 = don't expire)
+ device - physical partition to 'format' to hold vd's. e.g. hda4
+ ext_size - extent size (default 64MB)
+""" % sys.argv[0]
+
+if len(sys.argv) < 2:
+ usage()
+ sys.exit(-1)
+
+rc=''
+src=''
+expiry_time = 0
+cmd = sys.argv[1]
+
+if cmd == 'initialise':
+
+ dev = sys.argv[2]
+
+ if len(sys.argv) > 3:
+ extent_size = int(sys.argv[3])
+ else:
+ print """No extent size specified - using default size of 64MB"""
+ extent_size = 64
+
+ print "Formatting for virtual disks"
+ print "Device: " + dev
+ print "Extent size: " + str(extent_size) + "MB"
+
+ rc = XenoUtil.vd_format(dev, extent_size)
+
+elif cmd == 'create':
+
+ size = int(sys.argv[2])
+
+ if len(sys.argv) > 3:
+ expiry_time = int(sys.argv[3])
+
+ print "Creating a virtual disk"
+ print "Size: %d" % size
+ print "Expiry time (seconds from now): %d" % expiry_time
+
+ src = XenoUtil.vd_create(size, expiry_time)
+
+elif cmd == 'enlarge':
+
+ id = sys.argv[2]
+
+ extra_size = int(sys.argv[3])
+
+ rc = XenoUtil.vd_enlarge(id, extra_size)
+
+elif cmd == 'delete':
+
+ id = sys.argv[2]
+
+ print "Deleting a virtual disk with ID: " + id
+
+ rc = XenoUtil.vd_delete(id)
+
+elif cmd == 'import':
+
+ file = sys.argv[2]
+
+ if len(sys.argv) > 3:
+ expiry_time = int(sys.argv[3])
+
+ print "Allocate new virtual disk and populate from file : %s" % file
+
+ print XenoUtil.vd_read_from_file(file, expiry_time)
+
+elif cmd == 'export':
+
+ id = sys.argv[2]
+ file = sys.argv[3]
+
+ print "Dump contents of virtual disk to file : %s" % file
+
+ rc = XenoUtil.vd_cp_to_file(id, file )
+
+elif cmd == 'setexpiry':
+
+ id = sys.argv[2]
+
+ if len(sys.argv) > 3:
+ expiry_time = int(sys.argv[3])
+
+ print "Refreshing a virtual disk"
+ print "Id: " + id
+ print "Expiry time (seconds from now [or 0]): " + expiry_time
+
+ rc = XenoUtil.vd_refresh(id, expiry_time)
+
+elif cmd == 'list':
+
+ for vbd in XenoUtil.vd_list():
+ print """ID: %s
+Expires: %s
+Expiry time: %s
+Size (MB): %d
+""" % (vbd['vdisk_id'], vbd['expires'],
+ str(vbd['expiry_time']), vbd['size'] / 2048)
+
+elif cmd == 'freespace':
+
+ print XenoUtil.vd_freespace()
+
+elif cmd == 'undelete':
+
+ id = sys.argv[2]
+
+ if len(sys.argv) > 3:
+ expiry_time = int(sys.argv[3])
+
+ if XenoUtil.vd_undelete(id, expiry_time):
+ print "Undelete operation failed for virtual disk: " + id
+ else:
+ print "Undelete operation succeeded for virtual disk: " + id
+
+else:
+ usage()
+ sys.exit(-1)
+
+
+if src != '':
+ print "Returned virtual disk id is : %s" % src
+
+if rc != '':
+ print "return code %d" % rc
+
+
+
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 597e68da17..67a1ed9e47 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -7,7 +7,7 @@ HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
-TARGETS = xen_read_console xen_refresh_dev xen_cpuperf
+TARGETS = xen_read_console xen_cpuperf
INSTALL = $(TARGETS) xen-mkdevnodes xen_nat_enable xen-clone
@@ -16,7 +16,7 @@ all: $(TARGETS)
install: all
mkdir -p /usr/bin
- cp $(INSTALL) /usr/bin
+ cp -a $(INSTALL) /usr/bin
chmod 755 /usr/bin/xen-mkdevnodes
chmod 755 /usr/bin/xen_nat_enable
chmod 755 /usr/bin/xen-clone
@@ -24,7 +24,7 @@ install: all
dist: all
mkdir -p ../../../install/bin
- cp $(INSTALL) ../../../install/bin
+ cp -a $(INSTALL) ../../../install/bin
chmod 755 ../../../install/bin/xen-mkdevnodes
chmod 755 ../../../install/bin/xen_nat_enable
chmod 755 ../../../install/bin/xen-clone
diff --git a/tools/misc/xen_dmesg.py b/tools/misc/xen_dmesg.py
new file mode 100755
index 0000000000..402d80d60e
--- /dev/null
+++ b/tools/misc/xen_dmesg.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+"""Reads out the contents of the console ring
+
+Usage: readconsolering.py [-c]
+The -c option causes the contents to be cleared.
+"""
+
+import sys, Xc # import the Xc Xen Control module
+
+xc = Xc.new() # get a new instance of the control interface
+
+clear_buffer = False
+
+if sys.argv[1:] != []:
+ if sys.argv[1] == "-c":
+ clear_buffer = True
+ else:
+ print >> sys.stderr, "Usage: " + sys.argv[0] + """ [-c]
+ Reads the contents of the console buffer.
+ (specifying -c will also clear current contents)"""
+
+# Get the console ring's contents as a string and print it out.
+# If argument to readconsolering is true then the buffer is cleared as well as
+# fetching the (pre-clearing) contents.
+print xc.readconsolering(clear_buffer)
diff --git a/tools/misc/xen_nat_enable b/tools/misc/xen_nat_enable
index b2522b97b4..ea6b107fc3 100755
--- a/tools/misc/xen_nat_enable
+++ b/tools/misc/xen_nat_enable
@@ -7,7 +7,7 @@ run_iptables() {
}
ifconfig eth0 up
-ifconfig eth0:0 169.254.1.0 up
+ifconfig eth0:xen 169.254.1.0 up
run_iptables -t filter -F
run_iptables -t nat -F
diff --git a/tools/xc/py/Makefile b/tools/xc/py/Makefile
index 7a7d86b854..66fe33df4a 100644
--- a/tools/xc/py/Makefile
+++ b/tools/xc/py/Makefile
@@ -10,6 +10,7 @@ dist: all
for i in `find . -name 'Xc.so'` ; do \
cp $$i ../../../../install/lib/python/`basename $$i` ; \
done
-
+ python -c 'import py_compile, sys; py_compile.compile("XenoUtil.py")'
+ cp XenoUtil.py* ../../../../install/lib/python
clean:
rm -rf build *.pyc *.pyo *.o *.a *~
diff --git a/tools/xc/py/XenoUtil.py b/tools/xc/py/XenoUtil.py
index 5b0464f961..043d7782d1 100644
--- a/tools/xc/py/XenoUtil.py
+++ b/tools/xc/py/XenoUtil.py
@@ -99,6 +99,22 @@ def add_offset_to_ip( ip, off ):
return '%d.%d.%d.%d' % ( ((a>>24)&0xff), ((a>>16)&0xff),
((a>>8)&0xff), (a&0xff) )
+def check_subnet( ip, network, netmask ):
+ l = string.split(ip,'.')
+ n_ip = ( (string.atoi(l[0])<<24) | (string.atoi(l[1])<<16) |
+ (string.atoi(l[2])<<8) | string.atoi(l[3]) )
+
+ l = string.split(network,'.')
+ n_net = ( (string.atoi(l[0])<<24) | (string.atoi(l[1])<<16) |
+ (string.atoi(l[2])<<8) | string.atoi(l[3]) )
+
+ l = string.split(netmask,'.')
+ n_mask = ( (string.atoi(l[0])<<24) | (string.atoi(l[1])<<16) |
+ (string.atoi(l[2])<<8) | string.atoi(l[3]) )
+
+ return (n_ip&n_mask)==(n_net&n_mask)
+
+
##### VBD-related Functions
def blkdev_name_to_number(name):
@@ -171,6 +187,46 @@ def lookup_disk_uname( uname ):
##### VD Management-related functions
+##### By Mark Williamson, <mark.a.williamson@intel.com>
+##### (C) Intel Research Cambridge
+
+# TODO:
+#
+# Plenty of room for enhancement to this functionality (contributions
+# welcome - and then you get to have your name in the source ;-)...
+#
+# vd_unformat() : want facilities to unallocate virtual disk
+# partitions, possibly migrating virtual disks of them, with checks to see if
+# it's safe and options to force it anyway
+#
+# vd_create() : should have an optional argument specifying a physical
+# disk preference - useful to allocate for guest doms to do RAID
+#
+# vd_undelete() : add ability to "best effort" undelete as much of a
+# vdisk as is left in the case that some of it has already been
+# reallocated. Some people might still be able to recover some of
+# their data this way, even if some of the disk has disappeared.
+#
+# It'd be nice if we could wipe virtual disks for security purposes -
+# should be easy to do this using dev if=/dev/{zero,random} on each
+# extent in turn. There could be another optional flag to vd_create
+# in order to allow this.
+#
+# Error codes could be more expressive - i.e. actually tell why the
+# error occurred rather than "it broke". Currently the code avoids
+# using exceptions to make control scripting simpler and more
+# accessible to beginners - therefore probably should just use more
+# return codes.
+#
+# Enhancements / additions to the example scripts are also welcome:
+# some people will interact with this code mostly through those
+# scripts.
+#
+# More documentation of how this stuff should be used is always nice -
+# if you have a novel configuration that you feel isn't discussed
+# enough in the HOWTO (which is currently a work in progress), feel
+# free to contribute a walkthrough, or something more substantial.
+#
def __vd_no_database():
@@ -179,6 +235,7 @@ def __vd_no_database():
print >> sys.stderr, "ERROR: Could not locate the database file at " + VD_DB_FILE
sys.exit(1)
+
def vd_format(partition, extent_size_mb):
"""Format a partition or drive for use a virtual disk storage.
partition [string]: device file representing the partition
@@ -496,6 +553,9 @@ def vd_undelete(vdisk_id, expiry_time):
if not os.path.isfile(VD_DB_FILE):
__vd_no_database()
+ if vdisk_id == '0': # undeleting vdisk 0 isn't sane!
+ return -1
+
cx = sqlite.connect(VD_DB_FILE)
cu = cx.cursor()