aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-05-16 09:35:50 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-05-16 09:35:50 +0000
commitb6d05a08922675e9eb6f3a7e6192893069dde633 (patch)
tree850f28210efaa187f1ab6e651246182719ed6af9 /tools
parentfe9ba7bea609a559544a6488f095c184792562ec (diff)
downloadxen-b6d05a08922675e9eb6f3a7e6192893069dde633.tar.gz
xen-b6d05a08922675e9eb6f3a7e6192893069dde633.tar.bz2
xen-b6d05a08922675e9eb6f3a7e6192893069dde633.zip
bitkeeper revision 1.233 (3ec4b0f6Cj_75HMxVrjHKR0QUy_kNA)
Many files: new file xenohead.def: change bean persistence from session to application Makefile: clean web/tmpl too xi_list: add raw integer state to output Many files: split for dual use: original command line invocation from domctl and new xenctl gui domctl: look for domctl.xml in /var/lib/xen domctl.xml: xi_tools_dir should come at the top build-dom.xml: remove silliness Makefile: add support for xenctl build-dom.xml: Rename: tools/control/build-domctl.xml -> tools/control/build-dom.xml build-domctl.xml: Rename: tools/control/build.xml -> tools/control/build-domctl.xml Many files: mvdir
Diffstat (limited to 'tools')
-rw-r--r--tools/control/Makefile35
-rw-r--r--tools/control/build-dom.xml (renamed from tools/domctl/build.xml)17
-rw-r--r--tools/control/build-xen.xml506
-rw-r--r--tools/control/build.properties8
-rwxr-xr-xtools/control/domctl (renamed from tools/domctl/domctl)2
-rw-r--r--tools/control/domctl.xml (renamed from tools/domctl/domctl.xml)2
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/Command.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java)24
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java)27
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java)0
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandList.java139
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java)76
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java)31
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java)30
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/Defaults.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java)72
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/Domain.java27
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java)0
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/Main.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java)3
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/Settings.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java)6
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java (renamed from tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java)0
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Extent.java32
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Library.java114
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Main.java.orig35
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Mode.java22
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Parser.java446
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/Partition.java125
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/PartitionManager.java191
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/RootBean.java223
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.java30
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.java76
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.java257
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.java315
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/XML.java126
-rw-r--r--tools/control/src/uk/ac/cam/cl/xeno/xenctl/XMLHelper.java205
-rw-r--r--tools/control/web/WEB-INF/web.xml20
-rw-r--r--tools/control/web/img/cambridge.gifbin0 -> 1733 bytes
-rw-r--r--tools/control/web/img/help.gifbin0 -> 243 bytes
-rw-r--r--tools/control/web/img/home.gifbin0 -> 244 bytes
-rw-r--r--tools/control/web/img/pixel.gifbin0 -> 43 bytes
-rw-r--r--tools/control/web/img/search.gifbin0 -> 272 bytes
-rw-r--r--tools/control/web/img/xeno.gifbin0 -> 3600 bytes
-rw-r--r--tools/control/web/tmpl/about.tmpl71
-rw-r--r--tools/control/web/tmpl/dom-del.tmpl86
-rw-r--r--tools/control/web/tmpl/dom-delr.tmpl42
-rw-r--r--tools/control/web/tmpl/dom-lis.tmpl50
-rw-r--r--tools/control/web/tmpl/dom-new.tmpl197
-rw-r--r--tools/control/web/tmpl/dom-newr.tmpl100
-rw-r--r--tools/control/web/tmpl/dom-sta.tmpl64
-rw-r--r--tools/control/web/tmpl/dom-star.tmpl40
-rw-r--r--tools/control/web/tmpl/dom-stp.tmpl64
-rw-r--r--tools/control/web/tmpl/dom-stpr.tmpl40
-rw-r--r--tools/control/web/tmpl/dom.tmpl30
-rw-r--r--tools/control/web/tmpl/dommenu.tmpl33
-rw-r--r--tools/control/web/tmpl/help.tmpl61
-rw-r--r--tools/control/web/tmpl/index.tmpl66
-rwxr-xr-xtools/control/web/tmpl/install.pl236
-rw-r--r--tools/control/web/tmpl/makefile35
-rw-r--r--tools/control/web/tmpl/newdom.tmpl172
-rw-r--r--tools/control/web/tmpl/vd-fv.tmpl60
-rw-r--r--tools/control/web/tmpl/vd-pa.tmpl97
-rw-r--r--tools/control/web/tmpl/vd-par.tmpl49
-rw-r--r--tools/control/web/tmpl/vd-pv.tmpl54
-rw-r--r--tools/control/web/tmpl/vd-vbdc.tmpl94
-rw-r--r--tools/control/web/tmpl/vd-vbdcr.tmpl44
-rw-r--r--tools/control/web/tmpl/vd-vbdd.tmpl29
-rw-r--r--tools/control/web/tmpl/vd-vbdf.tmpl59
-rw-r--r--tools/control/web/tmpl/vd-vbdfr.tmpl32
-rw-r--r--tools/control/web/tmpl/vd-vbdv.tmpl44
-rw-r--r--tools/control/web/tmpl/vd-vdc.tmpl67
-rw-r--r--tools/control/web/tmpl/vd-vdcr.tmpl64
-rw-r--r--tools/control/web/tmpl/vd-vdd.tmpl58
-rw-r--r--tools/control/web/tmpl/vd-vddr.tmpl34
-rw-r--r--tools/control/web/tmpl/vd-vdr.tmpl83
-rw-r--r--tools/control/web/tmpl/vd-vdrr.tmpl72
-rw-r--r--tools/control/web/tmpl/vd-vdv.tmpl43
-rw-r--r--tools/control/web/tmpl/vd.tmpl24
-rw-r--r--tools/control/web/tmpl/vdmenu.tmpl63
-rw-r--r--tools/control/web/tmpl/xenofoot.def28
-rw-r--r--tools/control/web/tmpl/xenohead.def82
-rw-r--r--tools/control/web/tmpl/xenostyle.css91
-rw-r--r--tools/domctl/Makefile9
-rwxr-xr-xtools/internal/xi_helper15
-rwxr-xr-xtools/internal/xi_list11
82 files changed, 5816 insertions, 99 deletions
diff --git a/tools/control/Makefile b/tools/control/Makefile
new file mode 100644
index 0000000000..f78d796d65
--- /dev/null
+++ b/tools/control/Makefile
@@ -0,0 +1,35 @@
+default: domctl xenctl
+
+install: install-domctl install-xenctl
+
+clean: clean-domctl clean-xenctl
+
+
+
+domctl: FORCE
+ ant -buildfile build-dom.xml dist
+
+install-domctl: domctl
+ cp domctl.jar domctl ../../../install/bin
+ chmod 755 ../../../install/bin/domctl
+
+clean-domctl:
+ ant -buildfile build-dom.xml clean
+ rm -f domctl.jar
+
+
+
+xenctl: FORCE
+ (cd web/tmpl; make)
+ ant -buildfile build-xen.xml dist
+
+install-xenctl: xenctl
+ -ant -buildfile build-xen.xml remove
+ ant -buildfile build-xen.xml install
+
+clean-xenctl:
+ (cd web/tmpl; make clean)
+ ant -buildfile build-xen.xml clean
+ rm -f xenctl.jar
+
+FORCE:
diff --git a/tools/domctl/build.xml b/tools/control/build-dom.xml
index 88d5ffb5b5..eaf7380f0c 100644
--- a/tools/domctl/build.xml
+++ b/tools/control/build-dom.xml
@@ -1,8 +1,6 @@
<project name="domctl project" default="compile">
<property name="src" location="src"/>
- <property name="build" location="build"/>
- <property name="dist" location="dist"/>
- <property name="lib" location="lib"/>
+ <property name="build" location="build-dom"/>
<target name="init">
<tstamp/>
@@ -10,17 +8,23 @@
</target>
<target name="compile" depends="init">
- <javac srcdir="${src}" destdir="${build}" debug="on"/>
+ <javac srcdir="${src}" destdir="${build}" debug="on">
+ <include name="uk/ac/cam/cl/xeno/domctl/**"/>
+ </javac>
</target>
<target name="dist" depends="compile">
<jar jarfile="domctl.jar"
excludes="*~"
basedir="${build}">
- <fileset dir="${src}" />
+ <fileset dir="${src}">
+ <include name="uk/ac/cam/cl/xeno/domctl/**"/>
+ </fileset>
<fileset dir=".">
- <include name="build.xml"/>
+ <include name="build-domctl.xml"/>
<include name="domctl"/>
+ <include name="domctl.xml"/>
+ <include name="Makefile"/>
</fileset>
<manifest>
<attribute name="Built-By" value="${user.name}"/>
@@ -40,6 +44,5 @@
<target name="clean">
<delete dir="${build}"/>
- <delete dir="${lib}"/>
</target>
</project> \ No newline at end of file
diff --git a/tools/control/build-xen.xml b/tools/control/build-xen.xml
new file mode 100644
index 0000000000..7f7a9b3dfb
--- /dev/null
+++ b/tools/control/build-xen.xml
@@ -0,0 +1,506 @@
+<!--
+ General purpose build script for web applications and web services,
+ including enhanced support for deploying directly to a Tomcat 4
+ based server.
+
+ This build script assumes that the source code of your web application
+ is organized into the following subdirectories underneath the source
+ code directory from which you execute the build script:
+
+ docs Static documentation files to be copied to
+ the "docs" subdirectory of your distribution.
+
+ src Java source code (and associated resource files)
+ to be compiled to the "WEB-INF/classes"
+ subdirectory of your web applicaiton.
+
+ web Static HTML, JSP, and other content (such as
+ image files), including the WEB-INF subdirectory
+ and its configuration file contents.
+
+ $Id: build.xml.txt,v 1.7 2002/12/28 09:08:58 jfclere Exp $
+-->
+
+
+<!-- A "project" describes a set of targets that may be requested
+ when Ant is executed. The "default" attribute defines the
+ target which is executed if no specific target is requested,
+ and the "basedir" attribute defines the current working directory
+ from which Ant executes the requested task. This is normally
+ set to the current working directory.
+-->
+
+<project name="My Project" default="compile" basedir=".">
+
+
+
+<!-- ===================== Property Definitions =========================== -->
+
+
+<!--
+
+ Each of the following properties are used in the build script.
+ Values for these properties are set by the first place they are
+ defined, from the following list:
+
+ * Definitions on the "ant" command line (ant -Dfoo=bar compile).
+
+ * Definitions from a "build.properties" file in the top level
+ source directory of this application.
+
+ * Definitions from a "build.properties" file in the developer's
+ home directory.
+
+ * Default definitions in this build.xml file.
+
+ You will note below that property values can be composed based on the
+ contents of previously defined properties. This is a powerful technique
+ that helps you minimize the number of changes required when your development
+ environment is modified. Note that property composition is allowed within
+ "build.properties" files as well as in the "build.xml" script.
+
+-->
+
+ <property file="build.properties"/>
+ <property file="${user.home}/build.properties"/>
+
+
+<!-- ==================== File and Directory Names ======================== -->
+
+
+<!--
+
+ These properties generally define file and directory names (or paths) that
+ affect where the build process stores its outputs.
+
+ app.name Base name of this application, used to
+ construct filenames and directories.
+ Defaults to "myapp".
+
+ app.path Context path to which this application should be
+ deployed (defaults to "/" plus the value of the
+ "app.name" property).
+
+ app.version Version number of this iteration of the application.
+
+ build.home The directory into which the "prepare" and
+ "compile" targets will generate their output.
+ Defaults to "build".
+
+ catalina.home The directory in which you have installed
+ a binary distribution of Tomcat 4. This will
+ be used by the "deploy" target.
+
+ dist.home The name of the base directory in which
+ distribution files are created.
+ Defaults to "dist".
+
+ manager.password The login password of a user that is assigned the
+ "manager" role (so that he or she can execute
+ commands via the "/manager" web application)
+
+ manager.url The URL of the "/manager" web application on the
+ Tomcat installation to which we will deploy web
+ applications and web services.
+
+ manager.username The login username of a user that is assigned the
+ "manager" role (so that he or she can execute
+ commands via the "/manager" web application)
+
+-->
+
+ <property name="app.name" value="myapp"/>
+ <property name="app.path" value="/${app.name}"/>
+ <property name="app.version" value="0.1-dev"/>
+ <property name="build.home" value="${basedir}/build"/>
+ <property name="catalina.home" value="../../../.."/> <!-- UPDATE THIS! -->
+ <property name="dist.home" value="${basedir}/dist"/>
+ <property name="docs.home" value="${basedir}/docs"/>
+<!-- <property name="manager.url" value="http://localhost:8080/manager"/> -->
+ <property name="src.home" value="${basedir}/src"/>
+ <property name="web.home" value="${basedir}/web"/>
+
+
+<!-- ================== Custom Ant Task Definitions ======================= -->
+
+
+<!--
+
+ These properties define custom tasks for the Ant build tool that interact
+ with the "/manager" web application installed with Tomcat 4. Before they
+ can be successfully utilized, you must perform the following steps:
+
+ - Copy the file "server/lib/catalina-ant.jar" from your Tomcat 4
+ installation into the "lib" directory of your Ant installation.
+
+ - Create a "build.properties" file in your application's top-level
+ source directory (or your user login home directory) that defines
+ appropriate values for the "manager.password", "manager.url", and
+ "manager.username" properties described above.
+
+ For more information about the Manager web application, and the functionality
+ of these tasks, see <http://localhost:8080/tomcat-docs/manager-howto.html>.
+
+-->
+
+ <taskdef name="install" classname="org.apache.catalina.ant.InstallTask"/>
+ <taskdef name="list" classname="org.apache.catalina.ant.ListTask"/>
+ <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"/>
+ <taskdef name="remove" classname="org.apache.catalina.ant.RemoveTask"/>
+
+
+<!-- ==================== Compilation Control Options ==================== -->
+
+<!--
+
+ These properties control option settings on the Javac compiler when it
+ is invoked using the <javac> task.
+
+ compile.debug Should compilation include the debug option?
+
+ compile.deprecation Should compilation include the deprecation option?
+
+ compile.optimize Should compilation include the optimize option?
+
+-->
+
+ <property name="compile.debug" value="true"/>
+ <property name="compile.deprecation" value="false"/>
+ <property name="compile.optimize" value="true"/>
+
+
+
+<!-- ==================== External Dependencies =========================== -->
+
+
+<!--
+
+ Use property values to define the locations of external JAR files on which
+ your application will depend. In general, these values will be used for
+ two purposes:
+ * Inclusion on the classpath that is passed to the Javac compiler
+ * Being copied into the "/WEB-INF/lib" directory during execution
+ of the "deploy" target.
+
+ Because we will automatically include all of the Java classes that Tomcat 4
+ exposes to web applications, we will not need to explicitly list any of those
+ dependencies. You only need to worry about external dependencies for JAR
+ files that you are going to include inside your "/WEB-INF/lib" directory.
+
+-->
+
+<!-- Dummy external dependency -->
+<!--
+ <property name="foo.jar"
+ value="/path/to/foo.jar"/>
+-->
+
+
+<!-- ==================== Compilation Classpath =========================== -->
+
+<!--
+
+ Rather than relying on the CLASSPATH environment variable, Ant includes
+ features that makes it easy to dynamically construct the classpath you
+ need for each compilation. The example below constructs the compile
+ classpath to include the servlet.jar file, as well as the other components
+ that Tomcat makes available to web applications automatically, plus anything
+ that you explicitly added.
+
+-->
+
+ <path id="compile.classpath">
+
+ <!-- Include all JAR files that will be included in /WEB-INF/lib -->
+ <!-- *** CUSTOMIZE HERE AS REQUIRED BY YOUR APPLICATION *** -->
+<!--
+ <pathelement location="${foo.jar}"/>
+-->
+
+ <!-- Include all elements that Tomcat exposes to applications -->
+ <pathelement location="${catalina.home}/common/classes"/>
+ <fileset dir="${catalina.home}/common/endorsed">
+ <include name="*.jar"/>
+ </fileset>
+ <fileset dir="${catalina.home}/common/lib">
+ <include name="*.jar"/>
+ </fileset>
+ <pathelement location="${catalina.home}/shared/classes"/>
+ <fileset dir="${catalina.home}/shared/lib">
+ <include name="*.jar"/>
+ </fileset>
+
+ </path>
+
+
+
+<!-- ==================== All Target ====================================== -->
+
+<!--
+
+ The "all" target is a shortcut for running the "clean" target followed
+ by the "compile" target, to force a complete recompile.
+
+-->
+
+ <target name="all" depends="clean,compile"
+ description="Clean build and dist directories, then compile"/>
+
+
+
+<!-- ==================== Clean Target ==================================== -->
+
+<!--
+
+ The "clean" target deletes any previous "build" and "dist" directory,
+ so that you can be ensured the application can be built from scratch.
+
+-->
+
+ <target name="clean"
+ description="Delete old build and dist directories">
+ <delete dir="${build.home}"/>
+ <delete dir="${dist.home}"/>
+ </target>
+
+
+
+<!-- ==================== Compile Target ================================== -->
+
+<!--
+
+ The "compile" target transforms source files (from your "src" directory)
+ into object files in the appropriate location in the build directory.
+ This example assumes that you will be including your classes in an
+ unpacked directory hierarchy under "/WEB-INF/classes".
+
+-->
+
+ <target name="compile" depends="prepare"
+ description="Compile Java sources">
+
+ <!-- Compile Java classes as necessary -->
+ <mkdir dir="${build.home}/WEB-INF/classes"/>
+ <javac srcdir="${src.home}"
+ destdir="${build.home}/WEB-INF/classes"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="compile.classpath"/>
+ </javac>
+
+ <!-- Copy application resources -->
+ <copy todir="${build.home}/WEB-INF/classes">
+ <fileset dir="${src.home}" excludes="**/*.java"/>
+ </copy>
+
+ </target>
+
+
+
+<!-- ==================== Dist Target ===================================== -->
+
+
+<!--
+
+ The "dist" target creates a binary distribution of your application
+ in a directory structure ready to be archived in a tar.gz or zip file.
+ Note that this target depends on two others:
+
+ * "compile" so that the entire web application (including external
+ dependencies) will have been assembled
+
+ * "javadoc" so that the application Javadocs will have been created
+
+-->
+
+ <target name="dist" depends="compile,javadoc"
+ description="Create binary distribution">
+
+ <!-- Copy documentation subdirectories -->
+ <mkdir dir="${dist.home}/docs"/>
+ <copy todir="${dist.home}/docs">
+ <fileset dir="${docs.home}"/>
+ </copy>
+
+ <!-- Create application JAR file -->
+ <jar jarfile="${dist.home}/${app.name}-${app.version}.war"
+ basedir="${build.home}"/>
+
+ <!-- Copy additional files to ${dist.home} as necessary -->
+
+ </target>
+
+
+
+<!-- ==================== Install Target ================================== -->
+
+<!--
+
+ The "install" target tells the specified Tomcat 4 installation to dynamically
+ install this web application and make it available for execution. It does
+ *not* cause the existence of this web application to be remembered across
+ Tomcat restarts; if you restart the server, you will need to re-install all
+ this web application.
+
+ If you have already installed this application, and simply want Tomcat to
+ recognize that you have updated Java classes (or the web.xml file), use the
+ "reload" target instead.
+
+ NOTE: This target will only succeed if it is run from the same server that
+ Tomcat is running on.
+
+ NOTE: This is the logical opposite of the "remove" target.
+
+-->
+
+ <target name="install" depends="compile"
+ description="Install application to servlet container">
+
+ <install url="${manager.url}"
+ username="${manager.username}"
+ password="${manager.password}"
+ path="${app.path}"
+ war="file://${build.home}"/>
+
+ </target>
+
+
+<!-- ==================== Javadoc Target ================================== -->
+
+<!--
+
+ The "javadoc" target creates Javadoc API documentation for the Java
+ classes included in your application. Normally, this is only required
+ when preparing a distribution release, but is available as a separate
+ target in case the developer wants to create Javadocs independently.
+
+-->
+
+ <target name="javadoc" depends="compile"
+ description="Create Javadoc API documentation">
+
+ <mkdir dir="${dist.home}/docs/api"/>
+ <javadoc sourcepath="${src.home}"
+ destdir="${dist.home}/docs/api"
+ packagenames="*">
+ <classpath refid="compile.classpath"/>
+ </javadoc>
+
+ </target>
+
+
+
+<!-- ====================== List Target =================================== -->
+
+<!--
+
+ The "list" target asks the specified Tomcat 4 installation to list the
+ currently running web applications, either loaded at startup time or
+ installed dynamically. It is useful to determine whether or not the
+ application you are currently developing has been installed.
+
+-->
+
+ <target name="list"
+ description="List installed applications on servlet container">
+
+ <list url="${manager.url}"
+ username="${manager.username}"
+ password="${manager.password}"/>
+
+ </target>
+
+
+<!-- ==================== Prepare Target ================================== -->
+
+<!--
+
+ The "prepare" target is used to create the "build" destination directory,
+ and copy the static contents of your web application to it. If you need
+ to copy static files from external dependencies, you can customize the
+ contents of this task.
+
+ Normally, this task is executed indirectly when needed.
+
+-->
+
+ <target name="prepare">
+
+ <!-- Create build directories as needed -->
+ <mkdir dir="${build.home}"/>
+ <mkdir dir="${build.home}/WEB-INF"/>
+ <mkdir dir="${build.home}/WEB-INF/classes"/>
+
+
+ <!-- Copy static content of this web application -->
+ <copy todir="${build.home}">
+ <fileset dir="${web.home}"/>
+ </copy>
+
+ <!-- Copy external dependencies as required -->
+ <!-- *** CUSTOMIZE HERE AS REQUIRED BY YOUR APPLICATION *** -->
+ <mkdir dir="${build.home}/WEB-INF/lib"/>
+<!--
+ <copy todir="${build.home}/WEB-INF/lib" file="${foo.jar}"/>
+-->
+
+ <!-- Copy static files from external dependencies as needed -->
+ <!-- *** CUSTOMIZE HERE AS REQUIRED BY YOUR APPLICATION *** -->
+
+ </target>
+
+
+<!-- ==================== Reload Target =================================== -->
+
+<!--
+
+ The "reload" target tells the specified Tomcat 4 installation to dynamically
+ reload this web application, to reflect changes in the underlying classes or
+ the "web.xml" deployment descriptor.
+
+-->
+
+ <target name="reload" depends="compile"
+ description="Reload application on servlet container">
+
+ <reload url="${manager.url}"
+ username="${manager.username}"
+ password="${manager.password}"
+ path="${app.path}"/>
+
+ </target>
+
+
+<!-- ==================== Remove Target =================================== -->
+
+<!--
+
+ The "remove" target tells the specified Tomcat 4 installation to dynamically
+ remove this web application from service.
+
+ NOTE: This is the logical opposite of the "install" target.
+
+-->
+
+ <target name="remove"
+ description="Remove application on servlet container">
+
+ <remove url="${manager.url}"
+ username="${manager.username}"
+ password="${manager.password}"
+ path="${app.path}"/>
+
+ </target>
+
+
+ <target name="help">
+ <echo>all clean, them compile</echo>
+ <echo>dist create war file</echo>
+ <echo>install install application in servlet container</echo>
+ <echo>list list applications installed in servelet container</echo>
+ <echo>reload reload application in servlet container</echo>
+ <echo>remove dynamically remove web application</echo>
+ </target>
+
+</project>
diff --git a/tools/control/build.properties b/tools/control/build.properties
new file mode 100644
index 0000000000..9e375cbfdc
--- /dev/null
+++ b/tools/control/build.properties
@@ -0,0 +1,8 @@
+catalina.home=/anfs/scratch/labyrinth/ach61/jakarta-tomcat-4.1.24
+manager.url=http://mousetrap-0.xeno.cl.cam.ac.uk:80/manager
+manager.username=hobbes
+manager.password=tiger
+compile.optimize=false
+build.home=/anfs/scratch/labyrinth/ach61/xeno-clone/xeno.bk/tools/control/build-xen
+app.name=xenctl
+
diff --git a/tools/domctl/domctl b/tools/control/domctl
index 9383512f2d..959f0cee75 100755
--- a/tools/domctl/domctl
+++ b/tools/control/domctl
@@ -1,7 +1,7 @@
#!/bin/bash
if [ -z "$DEFAULTS_FILE" ] ; then DEFAULTS_FILE=domctl.xml ; fi
-if [ -z "$DEFAULTS_PATH" ] ; then DEFAULTS_PATH=.:/etc ; fi
+if [ -z "$DEFAULTS_PATH" ] ; then DEFAULTS_PATH=.:/etc:/var/lib/xen ; fi
if [ -z "$QUERY_DEV" ] ; then QUERY_DEV=eth0 ; fi
if [ -z "$IFCONFIG" ] ; then IFCONFIG=/sbin/ifconfig ; fi
if [ -z "$ROUTE" ] ; then ROUTE=/sbin/route ; fi
diff --git a/tools/domctl/domctl.xml b/tools/control/domctl.xml
index bfca3cf549..77bd5dcc7e 100644
--- a/tools/domctl/domctl.xml
+++ b/tools/control/domctl.xml
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
<domctl_defaults>
+<xi_tools_dir>/usr/local/bin/</xi_tools_dir>
<domain_name>XenoLinux</domain_name>
<domain_size_kb>16000</domain_size_kb>
<domain_image>./image</domain_image>
@@ -11,5 +12,4 @@
<nw_nfs_server>128.232.32.20</nw_nfs_server>
<nw_nfs_root>/usr/groups/srgboot/moonraider/roots/root+</nw_nfs_root>
<max_domain_number>10</max_domain_number>
-<xi_tools_dir>/tools/internal/</xi_tools_dir>
</domctl_defaults>
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Command.java
index b667e3f274..29113b534a 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Command.java
@@ -46,29 +46,31 @@ public abstract class Command
return result;
}
- public int reportXIError (String message, String cmd_array[])
+ public String reportXIError (String message, String cmd_array[])
{
+ StringBuffer sb = new StringBuffer();
int i;
- System.err.print (message + " using: ");
+ sb.append (message + " using: ");
for (i = 0; i < cmd_array.length; i ++) {
- System.err.print (cmd_array[i] + " ");
+ sb.append (cmd_array[i] + " ");
}
- System.err.println();
- return -1;
+ sb.append (System.getProperty("line.separator"));
+ return sb.toString();
}
- public int reportError (String message)
+ public String reportError (String message)
{
- System.err.println (message);
- return -1;
+ return (message);
}
- public void reportCommand (String cmd_array[])
+ public String reportCommand (String cmd_array[])
{
+ StringBuffer sb = new StringBuffer();
int i;
for (i = 0; i < cmd_array.length; i ++) {
- System.out.print (cmd_array[i] + " ");
+ sb.append (cmd_array[i] + " ");
}
- System.out.println();
+ sb.append (System.getProperty("line.separator"));
+ return sb.toString();
}
}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
index 025f373c50..68ea270a5d 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
@@ -7,10 +7,10 @@ public class CommandDestroy extends Command
{
public int doCommand(Defaults d, String args[])
{
- Runtime r = Runtime.getRuntime ();
int domain_id = getIntParameter(args, 'n', 0);
boolean force = getFlagParameter(args, 'f');
int rc = 0;
+ String output;
if (domain_id == 0) {
System.err.println ("Expected -n<domain_id>");
@@ -18,6 +18,23 @@ public class CommandDestroy extends Command
return rc;
}
+ output = executeCommand(d, domain_id, force);
+ if (output != null)
+ {
+ System.err.println(output);
+ return -1;
+ }
+ return 0;
+ }
+
+ public String
+ executeCommand(Defaults d,
+ int domain_id,
+ boolean force)
+ {
+ Runtime r = Runtime.getRuntime ();
+ String output = null;
+
try
{
Process destroy_p;
@@ -31,7 +48,7 @@ public class CommandDestroy extends Command
destroy_cmdarray[idx++] = "" + domain_id;
if (Settings.TEST) {
- reportCommand (destroy_cmdarray);
+ output += reportCommand (destroy_cmdarray);
} else {
destroy_p = r.exec (destroy_cmdarray);
destroy_rc = destroy_p.waitFor ();
@@ -43,12 +60,10 @@ public class CommandDestroy extends Command
}
catch (Exception e)
{
- System.err.println ("Could not destroy domain (" + e + ")");
- e.printStackTrace ();
- rc = -1;
+ return ("Could not destroy domain (" + e + ")");
}
- return rc;
+ return output;
}
public String getName()
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
index aef1ee9473..aef1ee9473 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandList.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandList.java
new file mode 100644
index 0000000000..522effa3a6
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandList.java
@@ -0,0 +1,139 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.io.*;
+import java.net.*;
+import java.util.Vector;
+import java.util.StringTokenizer;
+
+public class CommandList extends Command
+{
+ public int doCommand(Defaults d, String args[])
+ {
+ Domain [] domains = executeCommand(d);
+
+ for (int loop = 0; loop < domains.length; loop++)
+ {
+ System.out.println ("id: " + domains[loop].id +
+ " (" + domains[loop].name+ ")");
+ System.out.println (" processor: " + domains[loop].processor);
+ System.out.println (" has cpu: " + domains[loop].cpu);
+ System.out.println (" state: " + domains[loop].nstate + " " +
+ domains[loop].state);
+ System.out.println (" mcu advance: " + domains[loop].mcu);
+ System.out.println (" total pages: " + domains[loop].pages);
+ }
+
+ return 0;
+ }
+
+ public Domain[]
+ executeCommand(Defaults d)
+ {
+ Runtime r = Runtime.getRuntime ();
+ int rc = 0;
+ Vector v = new Vector();
+ String outline;
+ BufferedReader in;
+ Domain[] array;
+ String output = null;
+
+ try
+ {
+ Process start_p;
+ String start_cmdarray[] = new String[1];
+ int start_rc;
+ start_cmdarray[0] = d.XIToolsDir + "xi_list";
+
+ if (Settings.TEST) {
+ output += reportCommand (start_cmdarray);
+ } else {
+ start_p = r.exec (start_cmdarray);
+ start_rc = start_p.waitFor ();
+ if (start_rc != 0) {
+ return null;
+ }
+
+ in = new BufferedReader(
+ new InputStreamReader(start_p.getInputStream()));
+
+ outline = in.readLine();
+ while (outline != null)
+ {
+ Domain domain = new Domain();
+
+ StringTokenizer st = new StringTokenizer(outline);
+ if (st.hasMoreTokens())
+ {
+ domain.id = Integer.parseInt(st.nextToken());
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.processor = Integer.parseInt(st.nextToken());
+ }
+ if (st.hasMoreTokens())
+ {
+ if (st.nextToken().equals("1"))
+ {
+ domain.cpu = true;
+ }
+ else
+ {
+ domain.cpu = false;
+ }
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.nstate = Integer.parseInt(st.nextToken());
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.state = st.nextToken().toLowerCase();
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.mcu = Integer.parseInt(st.nextToken());
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.pages = Integer.parseInt(st.nextToken());
+ }
+ if (st.hasMoreTokens())
+ {
+ domain.name = st.nextToken();
+ }
+
+ v.add(domain);
+
+ outline = in.readLine();
+ }
+
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not get domain list(" + e + ")");
+ e.printStackTrace ();
+ return null;
+ }
+
+ array = new Domain[v.size()];
+ v.toArray(array);
+ return array;
+ }
+
+ public String getName()
+ {
+ return "list";
+ }
+
+ public String getUsage()
+ {
+ return "";
+ }
+
+ public String getHelpText()
+ {
+ return
+ "List domain information";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
index cc5e782196..e52f4584f0 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
@@ -8,7 +8,6 @@ public class CommandNew extends Command
{
public int doCommand(Defaults d, String args[])
{
- Runtime r = Runtime.getRuntime ();
String name = getStringParameter(args, 'n', d.domainName);
int size = getIntParameter(args, 'k', d.domainSizeKB);
String image = getStringParameter(args, 'i', d.domainImage);
@@ -22,16 +21,50 @@ public class CommandNew extends Command
String nw_mask = getStringParameter (args, 'm', d.NWMask);
String nw_nfs_server = getStringParameter (args, 's', d.NWNFSServer);
String nw_host = getStringParameter (args, 'h', d.NWHost);
- String domain_ip = "";
- int rc = 0;
+ String output;
+
+ d.describe ();
+
+ output = executeCommand(d, name, size, image, initrd, vifs,
+ bargs, root_dev, nfs_root_path,
+ nw_ip, nw_gw, nw_mask, nw_nfs_server, nw_host);
+ if (output != null)
+ {
+ System.err.println(output);
+ return -1;
+ }
+ return 0;
+ }
+
+ public String
+ executeCommand(Defaults d,
+ String name,
+ int size,
+ String image,
+ String initrd,
+ int vifs,
+ String bargs,
+ String root_dev,
+ String nfs_root_path,
+ String nw_ip,
+ String nw_gw,
+ String nw_mask,
+ String nw_nfs_server,
+ String nw_host)
+ {
+ Runtime r = Runtime.getRuntime ();
int domain_id = -1;
- DataInputStream dis;
+ BufferedReader br;
int idx;
int i;
File image_tmp = null;
File initrd_tmp = null;
+ String domain_ip = "";
+ String output = "";
- d.describe ();
+ String create_cmdarray[] = new String[3];
+ String build_cmdarray[] = new String[6];
+ String vifinit_cmdarray[] = new String[4];
try
{
@@ -55,7 +88,6 @@ public class CommandNew extends Command
/* Create a new empty domain */
Process create_p;
- String create_cmdarray[] = new String[3];
int create_rc;
create_cmdarray[0] = d.XIToolsDir + "xi_create";
create_cmdarray[1] = "" + size;
@@ -66,13 +98,14 @@ public class CommandNew extends Command
create_rc=0;
} else {
create_p = r.exec (create_cmdarray);
- dis = new DataInputStream (new BufferedInputStream (create_p.getInputStream ()));
- domain_id = Integer.parseInt (dis.readLine ());
+ br = new BufferedReader (
+ new InputStreamReader (create_p.getInputStream ()));
+ domain_id = Integer.parseInt (br.readLine ());
create_rc = create_p.waitFor ();
}
if (create_rc != 0) {
- return reportXIError ("Failed to create domain", create_cmdarray);
+ return reportXIError("Failed to create domain", create_cmdarray);
} else if (domain_id > d.MaxDomainNumber) {
return reportError ("Cannot configure more than " +
d.MaxDomainNumber + " domains");
@@ -90,12 +123,12 @@ public class CommandNew extends Command
return reportError ("No NFS server specified");
}
bargs = (bargs +
- "root=/dev/nfs " +
+ " root=/dev/nfs " +
"nfsroot=" + StringPattern.parse(nfs_root_path).resolve(domain_id) +
" ");
} else {
bargs = (bargs +
- "root=" + StringPattern.parse(root_dev).resolve(domain_id) +
+ " root=" + StringPattern.parse(root_dev).resolve(domain_id) +
" ");
}
@@ -120,7 +153,6 @@ public class CommandNew extends Command
/* Build the domain */
Process build_p;
- String build_cmdarray[] = new String[6];
int build_rc;
idx = 0;
for (i = 0; i < build_cmdarray.length; i ++)
@@ -147,7 +179,6 @@ public class CommandNew extends Command
/* Set up the first VIF if necessary */
if (vifs > 0) {
Process vifinit_p;
- String vifinit_cmdarray[] = new String[4];
int vifinit_rc;
vifinit_cmdarray[0] = d.XIToolsDir + "xi_vifinit";
vifinit_cmdarray[1] = "" + domain_id;
@@ -172,16 +203,21 @@ public class CommandNew extends Command
}
catch (Exception e)
{
- System.err.println ("Could not create new domain (" + e + ")");
- e.printStackTrace ();
- rc = -1;
+ e.printStackTrace();
+ return ("Could not create new domain (" + e + ")");
}
- if (rc == 0) {
- System.out.println ("Created domain " + domain_id);
- }
+ output += "\n<b>domain created</b> with arguments:<br>\n";
+ for (i = 0; i < create_cmdarray.length; i ++)
+ output += create_cmdarray[i] + "<br>";
+ output += "\n<b>domain built</b> with arguments:<br>\n";
+ for (i = 0; i < build_cmdarray.length; i ++)
+ output += build_cmdarray[i] + "<br>";
+ output += "\n<b>VIF 0 initialized</b> with arguments:<br>\n";
+ for (i = 0; i < vifinit_cmdarray.length; i ++)
+ output += vifinit_cmdarray[i] + "<br>";
- return rc;
+ return output;
}
File getUncompressed (String prefix, String original) throws IOException {
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
index b84b66d306..0a5141efe9 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
@@ -7,16 +7,31 @@ public class CommandStart extends Command
{
public int doCommand(Defaults d, String args[])
{
- Runtime r = Runtime.getRuntime ();
int domain_id = getIntParameter(args, 'n', 0);
- int rc = 0;
+ String output;
if (domain_id == 0) {
System.err.println ("Expected -n<domain_id>");
- rc = -1;
- return rc;
+ return -1;
+ }
+
+ output = executeCommand(d, domain_id);
+ if (output != null)
+ {
+ System.err.println(output);
+ return -1;
}
+ return 0;
+ }
+
+
+ public String
+ executeCommand(Defaults d, int domain_id)
+ {
+ Runtime r = Runtime.getRuntime ();
+ String output = null;
+
try
{
Process start_p;
@@ -26,7 +41,7 @@ public class CommandStart extends Command
start_cmdarray[1] = "" + domain_id;
if (Settings.TEST) {
- reportCommand (start_cmdarray);
+ output += reportCommand (start_cmdarray);
} else {
start_p = r.exec (start_cmdarray);
start_rc = start_p.waitFor ();
@@ -37,12 +52,10 @@ public class CommandStart extends Command
}
catch (Exception e)
{
- System.err.println ("Could not start new domain (" + e + ")");
- e.printStackTrace ();
- rc = -1;
+ return ("Could not start new domain (" + e + ")");
}
- return rc;
+ return output;
}
public String getName()
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
index c6b4cadd6c..ffee1efd2d 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
@@ -7,15 +7,29 @@ public class CommandStop extends Command
{
public int doCommand(Defaults d, String args[])
{
- Runtime r = Runtime.getRuntime ();
int domain_id = getIntParameter(args, 'n', 0);
- int rc = 0;
+ String output;
if (domain_id == 0) {
System.err.println ("Expected -n<domain_id>");
- rc = -1;
- return rc;
+ return -1;
+ }
+
+ output = executeCommand(d, domain_id);
+ if (output != null)
+ {
+ System.err.println(output);
+ return -1;
}
+ return 0;
+ }
+
+ public String
+ executeCommand(Defaults d,
+ int domain_id)
+ {
+ Runtime r = Runtime.getRuntime ();
+ String output = null;
try
{
@@ -26,7 +40,7 @@ public class CommandStop extends Command
stop_cmdarray[1] = "" + domain_id;
if (Settings.TEST) {
- reportCommand (stop_cmdarray);
+ output += reportCommand (stop_cmdarray);
} else {
stop_p = r.exec (stop_cmdarray);
stop_rc = stop_p.waitFor ();
@@ -38,12 +52,10 @@ public class CommandStop extends Command
}
catch (Exception e)
{
- System.err.println ("Could not stop new domain (" + e + ")");
- e.printStackTrace ();
- rc = -1;
+ return ("Could not stop new domain (" + e + ")");
}
- return rc;
+ return output;
}
public String getName()
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
index 5ce360a5ad..9a2dc706ac 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
@@ -5,29 +5,31 @@ import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
+/* these values are used in xenctl & domctl, so they need to be public */
+
public class Defaults
{
- String domainName;
+ public String domainName;
- int domainSizeKB;
- String domainImage;
- String domainInitRD;
- int domainVIFs;
+ public int domainSizeKB;
+ public String domainImage;
+ public String domainInitRD;
+ public int domainVIFs;
- String rootDevice;
+ public String rootDevice;
- String NWIP;
- String NWGW;
- String NWMask;
- String NWHost;
+ public String NWIP;
+ public String NWGW;
+ public String NWMask;
+ public String NWHost;
- String NWNFSServer;
- String NWNFSRoot;
+ public String NWNFSServer;
+ public String NWNFSRoot;
int MaxDomainNumber = Integer.MAX_VALUE;
String args = "";
- String XIToolsDir;
+ public String XIToolsDir = "";
/***********************************************************************/
@@ -35,6 +37,11 @@ public class Defaults
{
File f = Settings.getDefaultsFile ();
+ if (f == null)
+ {
+ return;
+ }
+
try
{
XMLReader xr = new org.apache.crimson.parser.XMLReaderImpl();
@@ -48,7 +55,7 @@ public class Defaults
System.err.println ("Could not read defaults file " + f +
"\nException: " + e);
e.printStackTrace();
- System.exit(1);
+ return;
}
}
@@ -121,11 +128,11 @@ public class Defaults
} else if (lastName.equals ("root_device")) {
rootDevice = s;
} else if (lastName.equals ("nw_ip")) {
- NWIP = expandDefault (s, Settings.LOCAL_IP);
+ NWIP = expandDefault (s, runCommand(XIToolsDir+Settings.XI_HELPER+" ip").trim());
} else if (lastName.equals ("nw_gw")) {
- NWGW = expandDefault (s, Settings.LOCAL_GW);
+ NWGW = expandDefault (s, runCommand(XIToolsDir+Settings.XI_HELPER+" route").trim());
} else if (lastName.equals ("nw_mask")) {
- NWMask = expandDefault (s, Settings.LOCAL_MASK);
+ NWMask = expandDefault (s, runCommand(XIToolsDir+Settings.XI_HELPER+" mask").trim());
} else if (lastName.equals ("nw_host")) {
NWHost = s;
} else if (lastName.equals ("nw_nfs_server")) {
@@ -155,4 +162,35 @@ public class Defaults
return supplied;
}
}
+
+
+ public String
+ runCommand (String command)
+ {
+ Runtime runtime = Runtime.getRuntime();
+ String outline;
+ StringBuffer output = new StringBuffer();
+
+ try
+ {
+ Process process = runtime.exec(command);
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+
+ outline = in.readLine();
+ while (outline != null)
+ {
+ output.append("\n" + outline);
+ outline = in.readLine();
+ }
+ }
+ catch (IOException e)
+ {
+ return e.toString();
+ }
+
+ return output.toString();
+ }
+
+
}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/domctl/Domain.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Domain.java
new file mode 100644
index 0000000000..d84d9eaf7e
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Domain.java
@@ -0,0 +1,27 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+public class
+Domain
+{
+ public int id; /* domain id */
+ public int processor; /* processor */
+ public boolean cpu; /* has cpu */
+ public int nstate; /* state */
+ public String state; /* running, interruptable, uninterruptable,
+ wait, suspended, dying */
+ public int mcu; /* mcu advances */
+ public int pages; /* total pages */
+ public String name; /* name */
+
+ Domain()
+ {
+ id = 0;
+ processor = 0;
+ cpu = false;
+ nstate = 0;
+ state = "";
+ mcu = 0;
+ pages = 0;
+ name = "none";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
index 5786edde71..5786edde71 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Main.java
index 49b4fb3c54..a4f74de535 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Main.java
@@ -7,7 +7,8 @@ public class Main
static CommandStart start = new CommandStart ();
static CommandStop stop = new CommandStop ();
static CommandDestroy destroy = new CommandDestroy ();
- static Command commands[] = { help, newdom, start, stop, destroy };
+ static CommandList list = new CommandList ();
+ static Command commands[] = { help, newdom, start, stop, destroy, list };
public static void main (String[] args)
{
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Settings.java
index 13d1a2d1df..bdef1c41de 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/Settings.java
@@ -6,12 +6,13 @@ import org.xml.sax.*;
public final class Settings
{
- public static final String DEFAULTS_FILE = System.getProperty ("DEFAULTS_FILE");
- public static final String DEFAULTS_PATH = System.getProperty ("DEFAULTS_PATH");
+ public static final String DEFAULTS_FILE = System.getProperty ("DEFAULTS_FILE", "domctl.xml");
+ public static final String DEFAULTS_PATH = System.getProperty ("DEFAULTS_PATH", ".:/etc:/var/lib/xen");
public static final String LOCAL_IP = System.getProperty ("LOCAL_IP");
public static final String LOCAL_MASK = System.getProperty ("LOCAL_MASK");
public static final String LOCAL_GW = System.getProperty ("LOCAL_ROUTE");
public static final boolean TEST = (System.getProperty ("TEST") != null);
+ public static final String XI_HELPER = System.getProperty ("XI_HELPER", "xi_helper");
public static File getDefaultsFile() {
@@ -30,7 +31,6 @@ public final class Settings
if (result == null) {
System.err.println ("Could not find " + DEFAULTS_FILE + " in path " + DEFAULTS_PATH);
- System.exit (1);
}
return result;
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java b/tools/control/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
index a0486ba2be..a0486ba2be 100644
--- a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
+++ b/tools/control/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Extent.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Extent.java
new file mode 100644
index 0000000000..6bbb2325aa
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Extent.java
@@ -0,0 +1,32 @@
+/*
+ * Extent.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+public class
+Extent
+{
+ int disk;
+ long offset; /* offset into disk */
+ long size; /* size of this extent in 512 byte sectors */
+
+ public int
+ getDisk()
+ {
+ return disk;
+ }
+
+ public long
+ getOffset()
+ {
+ return offset;
+ }
+
+ public long
+ getSize()
+ {
+ return size;
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Library.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Library.java
new file mode 100644
index 0000000000..0679ccaedd
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Library.java
@@ -0,0 +1,114 @@
+/*
+ * Library.java
+ * 03.03.28 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+public class
+Library
+{
+ /*
+ * convert a number to a fixed width string
+ */
+ static String
+ format (long input, int width, int prefix)
+ {
+ String sss = Long.toString(input);
+ String space = " ";
+
+ if (width < sss.length())
+ {
+ width = sss.length();
+ }
+
+ if (prefix == 0)
+ {
+ return space.substring(0, width - sss.length()) + sss;
+ }
+ else
+ {
+ return sss + space.substring(0, width - sss.length());
+ }
+ }
+
+ /*
+ * convert a string to a fixed width string
+ */
+ static String
+ format (String input, int width, int prefix)
+ {
+ String space = " ";
+
+ if (width < input.length())
+ {
+ width = input.length();
+ }
+
+ if (prefix == 0)
+ {
+ return space.substring(0, width - input.length()) + input;
+ }
+ else
+ {
+ return input + space.substring(0, width - input.length());
+ }
+ }
+
+ /*
+ * convert a number (string format) into
+ * the corresponding integer value.
+ */
+ static long
+ parse_size(String size)
+ {
+ String substring = size;
+ int suffix = 1;
+
+ if ((substring = check(size, 'm')) != null)
+ {
+ suffix = 1024 * 1024;
+ }
+ else if ((substring = check(size, 'M')) != null)
+ {
+ suffix = 1024 * 1024;
+ }
+ else if ((substring = check(size, 'k')) != null)
+ {
+ suffix = 1024;
+ }
+ else if ((substring = check(size, 'K')) != null)
+ {
+ suffix = 1024;
+ }
+ else if ((substring = check(size, 'g')) != null)
+ {
+ suffix = 1024 * 1024 * 1024;
+ }
+ else if ((substring = check(size, 'G')) != null)
+ {
+ suffix = 1024 * 1024 * 1024;
+ }
+ else
+ {
+ substring = size;
+ }
+
+ return Long.decode(substring).longValue() * suffix;
+ }
+
+ static String
+ check(String size, char suffix)
+ {
+ int index = size.indexOf(suffix);
+
+ if (index != -1)
+ {
+ return size.substring(0, index);
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Main.java.orig b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Main.java.orig
new file mode 100644
index 0000000000..2110521bcb
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Main.java.orig
@@ -0,0 +1,35 @@
+/*
+ * Main.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.vdmanager;
+
+import java.util.Date;
+
+public class
+Main
+{
+ static String state_filename_in = "/var/lib/xen/vdstate.xml";
+ static String state_filename_out = "/var/lib/xen/vdstate.xml";
+ static String partition_filename = "/proc/partitions";
+
+ void
+ go (String[] argv)
+ {
+ PartitionManager pm = new PartitionManager(partition_filename);
+ VirtualDiskManager vdm = new VirtualDiskManager();;
+ Parser parser = new Parser(pm, vdm);
+
+ XML.load_state(pm, vdm, state_filename_in);
+ parser.parse_main(argv);
+ XML.dump_state(pm, vdm, state_filename_out);
+ }
+
+ public static void
+ main (String[] argv)
+ {
+ Main foo = new Main();
+ foo.go(argv);
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Mode.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Mode.java
new file mode 100644
index 0000000000..ade6126663
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Mode.java
@@ -0,0 +1,22 @@
+/*
+ * Mode.java
+ * 03.03.27 aho creation
+ *
+ * until we have jdk1.5, we're left with this mess...
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+public class
+Mode
+{
+ private final String name;
+
+ private Mode(String name) { this.name = name; }
+
+ public String toString() { return name; }
+
+ public static final Mode READ_ONLY = new Mode("ro");
+ public static final Mode READ_WRITE = new Mode("rw");
+}
+
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Parser.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Parser.java
new file mode 100644
index 0000000000..a1459a1ba1
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Parser.java
@@ -0,0 +1,446 @@
+/*
+ * Parser.java
+ * 03.03.27 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Date;
+
+public class
+Parser
+{
+ static String prompt = "vdmanager> ";
+ static String default_addpartition_chunksize = "104857600"; /* 100M */
+ static int default_sector_size = 512;
+
+ PartitionManager pm;
+ VirtualDiskManager vdm;
+
+ Parser (PartitionManager pm, VirtualDiskManager vdm)
+ {
+ this.pm = pm;
+ this.vdm = vdm;
+ }
+
+ void
+ parse_main (String[] argv)
+ {
+ if (argv.length == 0)
+ {
+ parse_input(null);
+ }
+ else
+ {
+ parse_commandline(argv);
+ }
+ }
+
+ void
+ parse_input (String filename)
+ {
+ String line;
+ BufferedReader in;
+
+ if (filename != null)
+ {
+ try
+ {
+ in = new BufferedReader(new FileReader(filename));
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ System.err.println (fnfe);
+ return;
+ }
+ }
+ else
+ {
+ in = new BufferedReader(new InputStreamReader(System.in));
+ }
+
+ try
+ {
+ if (filename == null)
+ {
+ System.out.print (prompt);
+ }
+ line = in.readLine();
+ while (line != null)
+ {
+ StringTokenizer st = new StringTokenizer(line);
+ Vector v = new Vector();
+
+ while (st.hasMoreTokens())
+ {
+ v.add(st.nextToken());
+ }
+
+ if (parse_commandline((String[]) v.toArray(new String[v.size()])))
+ {
+ return;
+ }
+
+ if (filename == null)
+ {
+ System.out.print (prompt);
+ }
+ line = in.readLine();
+ }
+ }
+ catch (IOException ioe)
+ {
+ System.err.println(ioe);
+ }
+
+ if (filename == null)
+ {
+ System.out.println ("");
+ }
+ return;
+ }
+
+ boolean
+ parse_commandline (String[] commands)
+ {
+ if (commands.length == 0)
+ {
+ return false;
+ }
+
+ String keyword = commands[0].toLowerCase();
+ if (keyword.equals("file"))
+ {
+ if (commands.length < 2)
+ {
+ System.out.println ("file [filename]");
+ return false;
+ }
+ for (int i = 1; i < commands.length; i++)
+ {
+ System.out.println ("file " + commands[i]);
+ parse_input(commands[i]);
+ }
+ }
+ else if (keyword.equals("show"))
+ {
+ parse_show(commands);
+ }
+ else if (keyword.equals("addpartition"))
+ {
+ parse_addpartition(commands);
+ }
+ else if (keyword.equals("vdcreate"))
+ {
+ parse_vdcreate(commands);
+ }
+ else if (keyword.equals("vddelete"))
+ {
+ parse_vddelete(commands);
+ }
+ else if (keyword.equals("vdrefresh"))
+ {
+ parse_vdrefresh(commands);
+ }
+ else if (keyword.equals("vbdcreate"))
+ {
+ parse_vbdcreate(commands);
+ }
+ else if (keyword.equals("vbddelete"))
+ {
+ parse_vbddelete(commands);
+ }
+ else if (keyword.equals("vbdflush"))
+ {
+ vdm.flush_virtual_block_devices();
+ }
+ else if (keyword.equals("load"))
+ {
+ if (commands.length < 2)
+ {
+ System.out.println ("load <filename>");
+ return false;
+ }
+ XML.load_state (pm, vdm, commands[1]);
+ }
+ else if (keyword.equals("save"))
+ {
+ if (commands.length < 2)
+ {
+ System.out.println ("save <filename>");
+ return false;
+ }
+ XML.dump_state (pm, vdm, commands[1]);
+ }
+ else if (keyword.equals("help") ||
+ keyword.equals("?"))
+ {
+ parse_help();
+ }
+ else if (keyword.equals("exit") ||
+ keyword.equals("quit"))
+ {
+ return true;
+ }
+ else
+ {
+ System.out.println ("unknown command [" + commands[0] + "]. " +
+ "try \"help\"");
+ }
+ return false;
+ }
+
+ void
+ parse_vdcreate (String[] commands)
+ {
+ VirtualDisk vd;
+
+ if (commands.length < 4)
+ {
+ System.out.println ("vdcreate name size expiry");
+ return;
+ }
+
+ vd = vdm.create_virtual_disk(commands[1],
+ Library.parse_size(commands[2]) / default_sector_size,
+ new Date());
+
+ System.out.println ("Virtual Disk created with key: " + vd.get_key());
+ }
+
+ void
+ parse_vddelete (String[] commands)
+ {
+ if (commands.length < 2)
+ {
+ System.out.println ("vddelete key");
+ return;
+ }
+
+ vdm.delete_virtual_disk(commands[1]);
+ }
+
+ void
+ parse_vdrefresh (String[] commands)
+ {
+ if (commands.length < 3)
+ {
+ System.out.println ("vdrefresh key expiry");
+ return;
+ }
+
+ vdm.refresh_virtual_disk(commands[1],
+ new Date());
+ }
+
+ void
+ parse_vbdcreate (String[] commands)
+ {
+ VirtualDisk vd;
+ VirtualBlockDevice vbd;
+
+ if (commands.length < 4)
+ {
+ System.out.println ("vbdcreate <key> <domain number> <vbd number>");
+ return;
+ }
+
+ if (commands[1].startsWith("sd") ||
+ commands[1].startsWith("hd"))
+ {
+ /*
+ * this is a gross hack to allow you to create a virtual block
+ * device that maps directly to a physical partition
+ */
+
+ /* find the appropriate partition */
+ Partition partition = pm.get_partition(commands[1]);
+ if (partition == null)
+ {
+ System.out.println ("vbdcreate error: couldn't find partition \"" +
+ commands[1] + "\"");
+ return;
+ }
+
+ /* create a virtual disk */
+ vd = new VirtualDisk("vbd:" + commands[1]);
+ vd.add_new_partition(partition, partition.nr_sects);
+
+
+ /* display result */
+ System.out.print("domain:" + commands[2] + " ");
+ if (commands.length == 4)
+ {
+ System.out.print ("rw ");
+ }
+ else
+ {
+ System.out.print(commands[4] + " ");
+ }
+ System.out.print("segment:" + commands[3] + " ");
+ System.out.print(vd.dump_xen());
+ System.out.println("");
+
+ return;
+ }
+
+ if (commands.length == 4)
+ {
+ vbd =
+ vdm.create_virtual_block_device(commands[1],
+ Integer.decode(commands[2]).intValue(),
+ Integer.decode(commands[3]).intValue(),
+ "rw");
+ }
+ else
+ {
+ vbd =
+ vdm.create_virtual_block_device(commands[1],
+ Integer.decode(commands[2]).intValue(),
+ Integer.decode(commands[3]).intValue(),
+ commands[4]);
+ }
+
+ /* display commandline to user */
+ {
+ vd = vdm.get_virtual_disk_key(commands[1]);
+ System.out.println ("\n" + vd.dump_xen(vbd) + "\n");
+ }
+ }
+
+ void
+ parse_vbddelete (String[] commands)
+ {
+ if (commands.length < 3)
+ {
+ System.out.println ("vbddelete <domain number> <vbd number>");
+ return;
+ }
+
+ vdm.delete_virtual_block_device(Integer.decode(commands[1]).intValue(),
+ Integer.decode(commands[2]).intValue());
+ }
+
+ static String show_helptxt = "show <partitions | free | vd [vd number] | vbd>";
+ void
+ parse_show (String[] commands)
+ {
+ String subword;
+
+ if (commands.length < 2)
+ {
+ System.out.println (show_helptxt);
+ return;
+ }
+
+ subword = commands[1].toLowerCase();
+ if (subword.equals("partition") ||
+ subword.equals("partitions"))
+ {
+ System.out.println(pm.dump(true));
+ }
+ else if (subword.equals("vd"))
+ {
+ String text;
+
+ if (commands.length < 3)
+ {
+ System.out.println(vdm.dump_virtualdisks());
+ return;
+ }
+ text = vdm.dump_virtualdisk(Integer.decode(commands[2]).intValue());
+ if (text == null)
+ {
+ System.out.println("show vd error: invalid virtual disk number");
+ }
+ else
+ {
+ System.out.println(text);
+ }
+ }
+ else if (subword.equals("vbd"))
+ {
+ System.out.println(vdm.dump_virtualblockdevices());
+ }
+ else if (subword.equals("free"))
+ {
+ System.out.println(vdm.dump_free());
+ }
+ else
+ {
+ System.out.println (show_helptxt);
+ return;
+ }
+ }
+
+ void
+ parse_addpartition(String[] commands)
+ {
+ String chunksize = default_addpartition_chunksize;
+
+ if (commands.length > 3 || commands.length < 2)
+ {
+ System.out.println ("addpartition <partition number> [chunksize]");
+ return;
+ }
+ if (commands.length == 3)
+ {
+ chunksize = commands[2];
+ }
+
+ System.out.println ("add partition " + commands[1] + " " + chunksize);
+
+ vdm.add_xeno_partition(pm.get_partition(Integer.parseInt(commands[1])),
+ Library.parse_size(chunksize)/default_sector_size);
+ pm.add_xeno_partition(pm.get_partition(Integer.parseInt(commands[1])));
+ }
+
+ void
+ parse_help()
+ {
+ System.out.println ("file <filename> " +
+ "read the contents of a file as input to vdmanager");
+ System.out.println ("addpartition <partition number> [chunksize]");
+ System.out.println (" " +
+ "add a partition as a xeno partition");
+ System.out.println ("vdcreate <name> <size> <expiry>");
+ System.out.println (" " +
+ "create a new virtual disk");
+ System.out.println ("vddelete <key> " +
+ "delete a virtual disk");
+ System.out.println ("vdrefresh <key> <expiry>");
+ System.out.println (" " +
+ "reset virtual disk expiry");
+ System.out.println ("vbdcreate <key> <domain number> <vbd number> [rw|ro]");
+ System.out.println (" " +
+ "create a new virtual block device");
+ System.out.println ("vbddelete <domain number> <vbd number>");
+ System.out.println (" " +
+ "delete a new virtual block device");
+ System.out.println ("vbdflush " +
+ "remove all virtual block devices");
+ System.out.println ("show partitions " +
+ "display a complete list of disk partitions");
+ System.out.println ("show vd <vd number> " +
+ "display virtual disk information");
+ System.out.println ("show vbd " +
+ "display virtual virtual block device list");
+ System.out.println ("show free " +
+ "display details about unallocated space");
+ System.out.println ("load <filename> " +
+ "load new state from file");
+ System.out.println ("save <filename> " +
+ "save state to file");
+ System.out.println ("help " +
+ "display this help message");
+ System.out.println ("quit " +
+ "exit");
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Partition.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Partition.java
new file mode 100644
index 0000000000..75c42e9589
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/Partition.java
@@ -0,0 +1,125 @@
+/*
+ * Partition.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.*;
+
+public class
+Partition
+{
+ int major;
+ int minor;
+ long blocks;
+ long start_sect;
+ long nr_sects;
+ String name;
+ boolean xeno;
+
+ boolean
+ identical (Partition p)
+ {
+ return (major == p.major &&
+ minor == p.minor &&
+ blocks == p.blocks &&
+ start_sect == p.start_sect &&
+ nr_sects == p.nr_sects &&
+ name.equals(p.name));
+ }
+
+ Partition
+ duplicate ()
+ {
+ Partition p = new Partition();
+
+ p.major = major;
+ p.minor = minor;
+ p.blocks = blocks;
+ p.start_sect = start_sect;
+ p.nr_sects = nr_sects;
+ p.name = name;
+ p.xeno = xeno;
+
+ return p;
+ }
+
+ String
+ dump (boolean title)
+ {
+ if (title)
+ {
+ return ("maj:min " +
+ " blocks " +
+ "start sect " +
+ " num sects " +
+ "name");
+ }
+ else
+ {
+ return (Library.format(major,3,0) + ":" +
+ Library.format(minor,3,1) + " " +
+ Library.format(blocks,10,0) + " " +
+ Library.format(start_sect,10,0) + " " +
+ Library.format(nr_sects,10,0) + " " +
+ Library.format(name,7,1));
+ }
+ }
+
+ void
+ dump_xml(PrintWriter out)
+ {
+ out.println (" <partition>\n" +
+ " <major>" + major + "</major>\n" +
+ " <minor>" + minor + "</minor>\n" +
+ " <blocks>" + blocks + "</blocks>\n" +
+ " <start_sect>" + start_sect + "</start_sect>\n" +
+ " <nr_sects>" + nr_sects + "</nr_sects>\n" +
+ " <name>" + name + "</name>\n" +
+ " </partition>");
+ }
+
+ public int
+ getMajor()
+ {
+ return major;
+ }
+
+ public int
+ getMinor()
+ {
+ return minor;
+ }
+
+ public long
+ getBlocks()
+ {
+ return blocks;
+ }
+
+ public long
+ getStartSect()
+ {
+ return start_sect;
+ }
+
+ public long
+ getNumSects()
+ {
+ return nr_sects;
+ }
+
+ public String
+ getName()
+ {
+ return name;
+ }
+
+ public boolean
+ getIsXeno()
+ {
+ return xeno;
+ }
+
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/PartitionManager.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/PartitionManager.java
new file mode 100644
index 0000000000..553f8db880
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/PartitionManager.java
@@ -0,0 +1,191 @@
+/*
+ * PartitionManager.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.*;
+import java.util.Vector;
+import java.util.Enumeration;
+
+public class
+PartitionManager
+{
+ Vector partition_map;
+
+ static String proc_template =
+ "major minor #blocks start_sect nr_sects name";
+
+ /*
+ * Initialize partition manager with source file.
+ * Normally we read from /proc/partitions, but we can
+ * specify an alternative file for debugging
+ */
+ PartitionManager (String filename)
+ {
+ String str;
+ BufferedReader in;
+
+ partition_map = new Vector(100,10);
+
+ try
+ {
+ in = new BufferedReader(new FileReader(filename));
+
+ str = in.readLine(); /* skip headings */
+ if (str.length() < proc_template.length() ||
+ !str.substring(0, proc_template.length()).equals(proc_template))
+ {
+ System.err.println ("Error: Incorrect /proc/partitions.");
+ System.err.println (" Is this Xeno?");
+ System.exit (1);
+ }
+
+ str = in.readLine(); /* skip blank line */
+
+ str = in.readLine();
+ while (str != null)
+ {
+ Partition partition = new Partition();
+
+ partition.major = Integer.parseInt(str.substring(0,5).trim());
+ partition.minor = Integer.parseInt(str.substring(5,10).trim());
+ partition.blocks = Integer.parseInt(str.substring(10,21).trim());
+ partition.start_sect = Integer.parseInt(str.substring(21,32).trim());
+ partition.nr_sects = Integer.parseInt(str.substring(32,43).trim());
+ partition.name = str.substring(43).trim();
+ partition.xeno = false;
+
+ partition_map.add(partition);
+ str = in.readLine();
+ }
+ }
+ catch (IOException io)
+ {
+ System.err.println ("PartitionManager: error reading partition file ["
+ + filename + "]");
+ System.err.println (io);
+ }
+ }
+
+ Partition
+ get_partition (String name)
+ {
+ Partition partition = null;
+ for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
+ {
+ partition = (Partition) e.nextElement();
+ if (partition.name.equals(name))
+ {
+ return partition;
+ }
+ }
+ return null;
+ }
+
+ Partition
+ get_partition (int index)
+ {
+ return (Partition) partition_map.get(index);
+ }
+
+ void
+ add_xeno_partition (Partition p)
+ {
+ for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
+ {
+ Partition partition = (Partition) e.nextElement();
+ if (partition.identical(p))
+ {
+ partition.xeno = true;
+ }
+ }
+ }
+
+ /*
+ * dump the xeno partition list as xml
+ */
+ void
+ dump_xml (PrintWriter out)
+ {
+ int loop;
+
+ out.println("<partitions>");
+ for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
+ {
+ Partition partition = (Partition) e.nextElement();
+ if (partition.xeno == true)
+ {
+ partition.dump_xml(out);
+ }
+ }
+
+ out.println("</partitions>");
+
+ return;
+ }
+
+ /*
+ * dump the partition map as a string
+ * mark: mark the current xeno partitions in the partition map
+ */
+ String
+ dump (boolean mark)
+ {
+ int loop, idx;
+ StringBuffer sb = new StringBuffer();
+ Partition partition;
+
+ for (idx = 0; idx < partition_map.size(); idx++)
+ {
+ partition = (Partition) partition_map.get(idx);
+
+ if (idx == 0)
+ {
+ sb.append(" idx " + partition.dump(true) + "\n");
+ }
+ if (partition.xeno)
+ {
+ sb.append("[ ");
+ }
+ else
+ {
+ sb.append(" ");
+ }
+ sb.append(Library.format(idx,2,0) + " " + partition.dump(false));
+ if (partition.xeno)
+ {
+ sb.append("]\n");
+ }
+ else
+ {
+ sb.append("\n");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * get the number of partitions
+ */
+
+ int
+ getPartitionCount ()
+ {
+ return partition_map.size();
+ }
+
+ /**
+ * get the details about a particular partition
+ *
+ */
+ Partition
+ getPartition (int index)
+ {
+ Partition partition = (Partition) partition_map.get(index);
+ return partition;
+ }
+
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/RootBean.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/RootBean.java
new file mode 100644
index 0000000000..08f388dccb
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/RootBean.java
@@ -0,0 +1,223 @@
+/*
+ * RootBean.java
+ * 03.05.05 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.FileWriter;
+import java.util.Date;
+import java.util.Enumeration;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+public class
+RootBean
+ implements HttpSessionBindingListener
+{
+ static String state_filename_in = "/var/lib/xen/vdstate.xml";
+ static String state_filename_out = "/var/lib/xen/vdstate.xml";
+ static String partition_filename = "/proc/partitions";
+ static int default_sector_size = 512;
+
+ PartitionManager pm;
+ VirtualDiskManager vdm;
+
+ int counter = 0;
+
+ public
+ RootBean ()
+ {
+ valueBound(null);
+ }
+
+ public void
+ valueBound (HttpSessionBindingEvent event)
+ {
+ pm = new PartitionManager(partition_filename);
+ vdm = new VirtualDiskManager();
+ XML.load_state(pm, vdm, state_filename_in);
+ }
+
+ public void
+ valueUnbound (HttpSessionBindingEvent event)
+ {
+ doFlushState();
+ }
+
+ public int
+ getDebugCounter()
+ {
+ return counter++;
+ }
+
+ /*************************************************************************/
+
+ public int
+ getPartitionCount()
+ {
+ return pm.getPartitionCount();
+ }
+
+ public Partition
+ getPartition(int index)
+ {
+ return pm.getPartition(index);
+ }
+
+ public String
+ doAddPartition(String partition, String chunksize )
+ {
+ Partition p = pm.get_partition(partition);
+ String result="done";
+ int loop;
+
+ if (p == null)
+ {
+ return (" eh? what partition: " + partition);
+ }
+
+ vdm.add_xeno_partition(p,
+ Library.parse_size(chunksize)/default_sector_size);
+ pm.add_xeno_partition(p);
+
+ /* return pm.dump(true); */
+ return "done";
+ }
+
+ /*************************************************************************/
+
+ public int
+ getVirtualDiskCount ()
+ {
+ return vdm.getVirtualDiskCount();
+ }
+
+ public VirtualDisk
+ getVirtualDisk (int index)
+ {
+ return vdm.getVirtualDisk(index);
+ }
+
+ public VirtualDisk
+ getVirtualDiskKey (String key)
+ {
+ return vdm.get_virtual_disk_key(key);
+ }
+
+ public String
+ doCreateVirtualDisk (String name, String size, long expiry)
+ {
+ VirtualDisk vd;
+ Date date = new Date();
+
+ vd = vdm.create_virtual_disk(name,
+ Library.parse_size(size)/default_sector_size,
+ new Date(date.getTime() + expiry));
+
+ return ("Virtual Disk created with key: " + vd.get_key());
+
+ }
+
+ public String
+ doDeleteVirtualDisk (String key)
+ {
+ vdm.delete_virtual_disk(key);
+
+ return ("okay");
+ }
+
+ public String
+ doRefreshVirtualDisk (String key, long expiry)
+ {
+ VirtualDisk vd = vdm.get_virtual_disk_key(key);
+ Date date;
+ String s = "";
+
+ if (vd == null)
+ {
+ return ("disk not found: " + key);
+ }
+ s = vd.get_expiry().toString();
+ date = new Date(vd.get_expiry().getTime() + expiry);
+ vd.set_expiry(date);
+
+ return ("okay " + expiry + " " + s + " " + date.toString());
+ }
+
+ /*************************************************************************/
+
+ public int
+ getFreeExtentCount ()
+ {
+ VirtualDisk free = vdm.getFreeVirtualDisk();
+ return free.getExtentCount();
+ }
+
+ public Extent
+ getFreeExtent (int index)
+ {
+ VirtualDisk free = vdm.getFreeVirtualDisk();
+ return free.getExtent(index);
+ }
+
+ /*************************************************************************/
+
+ public Enumeration
+ getVirtualBlockDevices ()
+ {
+ return vdm.getVirtualBlockDevices();
+ }
+
+ public String
+ doCreateVirtualBlockDevice (String vd_key, int domain,
+ int vbd_num, String mode)
+ {
+ VirtualBlockDevice vbd;
+ VirtualDisk vd;
+
+ vbd = vdm.create_virtual_block_device(vd_key, domain, vbd_num, mode);
+ if (vbd != null)
+ {
+ String command;
+ FileWriter fw;
+
+ vd = vdm.get_virtual_disk_key(vd_key);
+ command = vd.dump_xen(vbd);
+
+ try
+ {
+ fw = new FileWriter("/proc/xeno/dom0/vhd");
+ fw.write(command);
+ fw.flush();
+ fw.close();
+ }
+ catch (Exception e)
+ {
+ return (e.toString());
+ }
+ return command;
+ }
+ else
+ {
+ return "Error encountered";
+ }
+ }
+
+ public String
+ doFlushVirtualBlockDevices()
+ {
+ vdm.flush_virtual_block_devices();
+ return "done";
+ }
+
+ /*************************************************************************/
+
+
+ public void
+ doFlushState ()
+ {
+ XML.dump_state(pm, vdm, state_filename_out);
+ }
+
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.java
new file mode 100644
index 0000000000..7c2605d8ce
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/SystemConfigurationBean.java
@@ -0,0 +1,30 @@
+/*
+ * SystemConfigurationBean.java
+ * 03.05.06 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.*;
+import java.lang.Process;
+import java.lang.Runtime;
+import uk.ac.cam.cl.xeno.domctl.Defaults;
+
+public class
+SystemConfigurationBean
+{
+ Defaults defaults;
+
+ public
+ SystemConfigurationBean ()
+ {
+ defaults = new Defaults();
+ }
+
+ public Defaults
+ getDefaults ()
+ {
+ return defaults;
+ }
+
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.java
new file mode 100644
index 0000000000..62640e0edf
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualBlockDevice.java
@@ -0,0 +1,76 @@
+/*
+ * VirtualBlockDevice.java
+ * 03.03.27 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.PrintWriter;
+
+public class
+VirtualBlockDevice
+{
+ String key;
+ int domain;
+ int vbdnum;
+ Mode mode; /* rw or ro */
+
+ String
+ dump (boolean title)
+ {
+ StringBuffer sb = new StringBuffer();
+ int loop;
+
+ if (title)
+ {
+ sb.append(" key dom vbd mode\n");
+ }
+ else
+ {
+ sb.append(" " + key + " " +
+ Library.format(domain,3,0) + " " +
+ Library.format(vbdnum,3,0) + " " +
+ mode.toString() + "\n");
+ }
+
+ return sb.toString();
+ }
+
+ void
+ dump_xml (PrintWriter out)
+ {
+ out.println(" <virtual_block_device>");
+ out.println(" <key>" + key + "</key>");
+ out.println(" <domain>" + domain + "</domain>");
+ out.println(" <vbdnum>" + vbdnum + "</vbdnum>");
+ out.println(" <mode>" + mode + "</mode>");
+ out.println(" </virtual_block_device>");
+
+ return;
+ }
+
+ public String
+ getKey()
+ {
+ return key;
+ }
+
+ public int
+ getDomain()
+ {
+ return domain;
+ }
+
+
+ public int
+ getVBDNum()
+ {
+ return vbdnum;
+ }
+
+ public Mode
+ getMode()
+ {
+ return mode;
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.java
new file mode 100644
index 0000000000..fb751db4e2
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDisk.java
@@ -0,0 +1,257 @@
+/*
+ * VirtualDisk.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.util.Date;
+import java.util.Vector;
+import java.lang.Math;
+import java.io.PrintWriter;
+
+public class
+VirtualDisk
+{
+ String name;
+ String key;
+ Date expiry;
+ Vector extents;
+
+ VirtualDisk (String name, Date expiry, String key)
+ {
+ this.name = name;
+ this.key = key;
+ this.expiry = expiry;
+ extents = new Vector();
+ }
+
+ VirtualDisk (String name)
+ {
+ this (name, null, null);
+ this.key = generate_key();
+ extents = new Vector();
+
+ return;
+ }
+
+ VirtualDisk (String name, Date expiry)
+ {
+ this(name, expiry, null);
+ this.key = generate_key();
+ }
+
+ /*
+ * generate a unique key for this virtual disk.
+ * for now, just generate a 10 digit number
+ */
+ String
+ generate_key ()
+ {
+ return Long.toString(1000000000l + (long)(Math.random() * 8999999999l));
+ }
+
+ String
+ get_key ()
+ {
+ return key;
+ }
+
+ Date
+ get_expiry ()
+ {
+ return expiry;
+ }
+
+ void
+ set_expiry (Date expiry)
+ {
+ this.expiry = expiry;
+ }
+
+ public void
+ add_extent (Extent extent)
+ {
+ extents.add(extent);
+ }
+
+ public Extent
+ remove_extent ()
+ {
+ Extent e;
+
+ if (extents.size() > 0)
+ {
+ e = (Extent) extents.remove(0);
+ }
+ else
+ {
+ e = null;
+ }
+
+ return e;
+ }
+
+ String
+ dump (boolean details, boolean title)
+ {
+ StringBuffer sb = new StringBuffer();
+ int loop;
+
+ if (details)
+ {
+ if (title)
+ {
+ sb.append(" name: " + name + "\n");
+ sb.append(" key: " + key + "\n");
+ sb.append("expiry: " + expiry + "\n");
+ sb.append("\n");
+ }
+ sb.append(" idx disk offset size \n");
+ for (loop = 0; loop < extents.size(); loop++)
+ {
+ Extent e = (Extent) extents.get(loop);
+ sb.append(" " +
+ Library.format(loop,3,0) + " " +
+ Library.format(e.disk,6,0) +
+ Library.format(e.offset,10,0) +
+ Library.format(e.size,10,0) + "\n");
+ }
+ }
+ else
+ {
+ if (title)
+ {
+ sb.append(" key expiry name\n");
+ }
+ else
+ {
+ sb.append(" " + key + " " + expiry.toString() + " " + name + "\n");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ String
+ dump_xen ()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("extents:" + extents.size() + " ");
+ for (int loop = 0; loop < extents.size(); loop++)
+ {
+ Extent e = (Extent) extents.get(loop);
+ sb.append("(disk:" + e.disk + " " +
+ "offset:" + e.offset + " " +
+ "size:" + e.size + ")");
+ }
+ return sb.toString();
+ }
+
+ String
+ dump_xen (VirtualBlockDevice vbd)
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("domain:" + vbd.domain + " " +
+ vbd.mode.toString() + " " +
+ "segment:" + vbd.vbdnum + " " +
+ "extents:" + extents.size() + " ");
+ for (int loop = 0; loop < extents.size(); loop++)
+ {
+ Extent e = (Extent) extents.get(loop);
+ sb.append("(disk:" + e.disk + " " +
+ "offset:" + e.offset + " " +
+ "size:" + e.size + ")");
+ }
+ return sb.toString();
+ }
+
+ void
+ dump_xml (PrintWriter out)
+ {
+ out.println(" <virtual_disk>");
+ out.println(" <name>" + name + "</name>");
+ out.println(" <key>" + key + "</key>");
+ if (expiry == null)
+ {
+ out.println(" <expiry>0</expiry>");
+ }
+ else
+ {
+ out.println(" <expiry>" + expiry.getTime() + "</expiry>");
+ }
+ out.println(" <extents>");
+ for (int loop = 0; loop < extents.size(); loop++)
+ {
+ Extent e = (Extent) extents.get(loop);
+ out.println(" <extent>");
+ out.println(" <disk>" + e.disk + "</disk>");
+ out.println(" <size>" + e.size + "</size>");
+ out.println(" <offset>" + e.offset + "</offset>");
+ out.println(" </extent>");
+ }
+ out.println(" </extents>");
+ out.println(" </virtual_disk>");
+
+ return;
+ }
+
+ /*
+ * Add a partition as a XenoPartition.
+ * Chop the partition in to extents and of size "size" sectors
+ * and add them to the virtual disk.
+ */
+
+ void
+ add_new_partition (Partition partition, long size)
+ {
+ int loop;
+
+ for (loop = 0; loop < partition.nr_sects / size; loop++)
+ {
+ Extent extent = new Extent();
+
+ extent.disk = partition.major << 8;
+ extent.disk = extent.disk | (partition.minor >> 5) << 5;
+ extent.size = size;
+ extent.offset = partition.start_sect + (size * loop);
+
+ add_extent(extent);
+ }
+
+ return;
+ }
+
+ public String
+ getName()
+ {
+ return name;
+ }
+
+ public String
+ getKey()
+ {
+ return key;
+ }
+
+ public String
+ getExpiry()
+ {
+ return expiry.toString();
+ }
+
+ public int
+ getExtentCount()
+ {
+ return extents.size();
+ }
+
+ public Extent
+ getExtent(int index)
+ {
+ return (Extent) extents.get(index);
+ }
+
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.java
new file mode 100644
index 0000000000..a225efde91
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/VirtualDiskManager.java
@@ -0,0 +1,315 @@
+/*
+ * VirtualDiskManager.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Date;
+import java.io.PrintWriter;
+
+public class
+VirtualDiskManager
+{
+ VirtualDisk free_disk;
+ Vector virtual_disks;
+ Hashtable virtual_block_devices;
+ Hashtable key_hash;
+
+ VirtualDiskManager ()
+ {
+ free_disk = new VirtualDisk("free");
+
+ virtual_disks = new Vector(10,5);
+ flush_virtual_block_devices();
+ key_hash = new Hashtable(100);
+ }
+
+ public VirtualDisk
+ get_virtual_disk_key (String key)
+ {
+ return ((VirtualDisk) key_hash.get(key));
+ }
+
+ public void
+ add_xeno_partition (Partition partition, long size)
+ {
+ free_disk.add_new_partition (partition, size);
+ return;
+ }
+
+ /*
+ * create a new virtual disk
+ */
+
+ public VirtualDisk
+ create_virtual_disk(String name, long size, Date expiry)
+ {
+ VirtualDisk vd = new VirtualDisk (name, expiry);
+
+ while (size > 0)
+ {
+ Extent e;
+
+ e = free_disk.remove_extent();
+ if (e == null)
+ {
+ return null;
+ }
+ size -= e.size;
+ vd.add_extent(e);
+ }
+
+ add_virtual_disk(vd);
+
+ return vd;
+ }
+
+ /*
+ * delete a new virtual disk. extents go back into the free pool
+ */
+
+ public void
+ delete_virtual_disk (String key)
+ {
+ VirtualDisk vd;
+
+ vd = (VirtualDisk) key_hash.get(key);
+ if (vd != null)
+ {
+ Extent e;
+
+ key_hash.remove(key);
+ virtual_disks.remove(vd);
+
+ e = vd.remove_extent();
+ while (e != null)
+ {
+ free_disk.add_extent(e);
+ e = vd.remove_extent();
+ }
+ }
+ return;
+ }
+
+ /*
+ * reset the expiry time for a virtual disk
+ */
+
+ public void
+ refresh_virtual_disk (String key, Date expiry)
+ {
+ VirtualDisk vd = (VirtualDisk) key_hash.get(key);
+ if (vd != null)
+ {
+ vd.set_expiry(expiry);
+ }
+ }
+
+ /*
+ * create a new virtual block device
+ */
+ public VirtualBlockDevice
+ create_virtual_block_device (String key, int domain, int vbd_num,
+ String mode)
+ {
+ VirtualBlockDevice vbd = new VirtualBlockDevice();
+ VirtualDisk vd = get_virtual_disk_key(key);
+
+ if (vd == null)
+ {
+ System.err.println("create virtual block device error: unknown key " +
+ "[" + key + "]");
+ return null;
+ }
+
+ vbd.key = key;
+ vbd.domain = domain;
+ vbd.vbdnum = vbd_num;
+
+ if (mode.equals(Mode.READ_ONLY.toString()) ||
+ mode.equals("RO") ||
+ mode.equals("ro"))
+ {
+ vbd.mode = Mode.READ_ONLY;
+ }
+ else if (mode.equals(Mode.READ_WRITE.toString()) ||
+ mode.equals("RW") ||
+ mode.equals("rw"))
+ {
+ vbd.mode = Mode.READ_WRITE;
+ }
+ else
+ {
+ System.err.println("create virtual block device error: unknown mode " +
+ "[" + mode + "]");
+ return null;
+ }
+
+ add_virtual_block_device(vbd);
+
+ return vbd;
+ }
+
+ /*
+ * delete a virtual block device
+ */
+ public void
+ delete_virtual_block_device (int domain, int vbd_num)
+ {
+ Object hash = get_vbd_hash(domain, vbd_num);
+ VirtualBlockDevice vbd = (VirtualBlockDevice)virtual_block_devices.remove(hash);
+ return;
+ }
+
+ /*
+ * flush all virtual block devices
+ */
+ public void
+ flush_virtual_block_devices ()
+ {
+ /* isn't automatic garbage collection wonderful? */
+ virtual_block_devices = new Hashtable(100);
+ }
+
+ public void
+ add_virtual_disk (VirtualDisk vd)
+ {
+ virtual_disks.add(vd);
+ key_hash.put(vd.get_key(), vd);
+ }
+
+ public void
+ add_virtual_block_device (VirtualBlockDevice vbd)
+ {
+ Object hash = get_vbd_hash(vbd.domain, vbd.vbdnum);
+ virtual_block_devices.put(hash, vbd);
+ }
+
+ Object
+ get_vbd_hash (int domain, int vbd_num)
+ {
+ return new Integer(domain * 16 + vbd_num);
+ }
+
+ public void
+ add_free (VirtualDisk vd)
+ {
+ free_disk = vd;
+ }
+
+ public String
+ dump_virtualdisk (int segment)
+ {
+ if (segment < 0 || segment >= virtual_disks.size())
+ {
+ return null;
+ }
+ else
+ {
+ VirtualDisk vd = (VirtualDisk) virtual_disks.get(segment);
+ return (vd.dump(true, true));
+ }
+ }
+
+ public String
+ dump_free()
+ {
+ return(free_disk.dump(true, false));
+ }
+
+ public String
+ dump_virtualdisks()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < virtual_disks.size(); i++)
+ {
+ VirtualDisk vd = (VirtualDisk) virtual_disks.get(i);
+ if (i == 0)
+ {
+ sb.append(vd.dump(false, true));
+ }
+ sb.append(vd.dump(false, false));
+ }
+
+ return sb.toString();
+ }
+
+ public String
+ dump_virtualblockdevices()
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean first = true;
+
+ for (Enumeration enumeration = virtual_block_devices.elements() ;
+ enumeration.hasMoreElements() ;)
+ {
+ VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
+ if (first)
+ {
+ sb.append(vbd.dump(true));
+ first = false;
+ }
+
+ sb.append(vbd.dump(false));
+ }
+
+ return sb.toString();
+ }
+
+ public void
+ dump_xml(PrintWriter out)
+ {
+ out.println("<free>");
+ free_disk.dump_xml(out);
+ out.println("</free>");
+ out.println("<virtual_disks>");
+ for (int i = 0; i < virtual_disks.size(); i++)
+ {
+ VirtualDisk vd = (VirtualDisk) virtual_disks.get(i);
+ vd.dump_xml(out);
+ }
+ out.println("</virtual_disks>");
+ out.println("<virtual_block_devices>");
+ for (Enumeration enumeration = virtual_block_devices.elements() ;
+ enumeration.hasMoreElements() ;)
+ {
+ VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
+ vbd.dump_xml(out);
+ }
+
+ out.println("</virtual_block_devices>");
+
+ return;
+ }
+
+ /*************************************************************************/
+
+ public int
+ getVirtualDiskCount ()
+ {
+ return virtual_disks.size();
+ }
+
+ public VirtualDisk
+ getVirtualDisk (int index)
+ {
+ return (VirtualDisk) virtual_disks.get(index);
+ }
+
+ public VirtualDisk
+ getFreeVirtualDisk ()
+ {
+ return free_disk;
+ }
+
+ public Enumeration
+ getVirtualBlockDevices ()
+ {
+ return virtual_block_devices.elements();
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XML.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XML.java
new file mode 100644
index 0000000000..cf62466ff7
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XML.java
@@ -0,0 +1,126 @@
+/*
+ * XML.java
+ * 03.03.26 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class
+XML
+{
+ static Document document = null;
+
+ /*
+ * dump partition manager and virtual disk manager state to filename
+ */
+
+ static void
+ dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
+ {
+ PrintWriter out;
+
+ try
+ {
+ out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
+ }
+ catch (IOException e)
+ {
+ System.err.println ("XML.dump_state error [" + filename + "]");
+ System.err.println (e);
+ return;
+ }
+
+ out.println("<?xml version=\"1.0\"?>");
+ out.println("<vdmanager>");
+ pm.dump_xml(out);
+ vdm.dump_xml(out);
+ out.println("</vdmanager>");
+
+ out.close();
+ return;
+ }
+
+ /*
+ * load partition manager and virtual disk manager state from filename
+ */
+ static void
+ load_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
+ {
+ if (document == null)
+ {
+ load_file (filename);
+ }
+
+ XMLHelper.parse(pm, vdm, document);
+ }
+
+ /*
+ * load XML from disk
+ */
+ static void
+ load_file (String filename)
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ // factory.setNamespaceAware(true);
+ // factory.setValidating(true);
+
+ try
+ {
+ File file = new File(filename);
+
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ document = builder.parse(file);
+ }
+ catch (SAXParseException spe) /* error generated by parser */
+ {
+ System.err.println ("xml parser exception on line " +
+ spe.getLineNumber() +
+ " for uri " + spe.getSystemId());
+ System.err.println (spe.getMessage());
+
+ Exception x = spe;
+ if (spe.getException() != null)
+ x = spe.getException();
+ x.printStackTrace();
+ System.exit(1);
+ }
+ catch (SAXException sxe)
+ {
+ Exception e = sxe;
+ if (sxe.getException() != null)
+ e = sxe.getException();
+ e.printStackTrace();
+ System.exit(1);
+ }
+ catch (ParserConfigurationException pce)
+ {
+ pce.printStackTrace();
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ System.err.println ("warning: state file not found [" +
+ filename + "]");
+ }
+ catch (IOException ioe)
+ {
+ ioe.printStackTrace();
+ }
+ return;
+ }
+}
diff --git a/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XMLHelper.java b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XMLHelper.java
new file mode 100644
index 0000000000..79fdd63177
--- /dev/null
+++ b/tools/control/src/uk/ac/cam/cl/xeno/xenctl/XMLHelper.java
@@ -0,0 +1,205 @@
+/*
+ * XMLHelper.java
+ * 03.03.27 aho creation
+ */
+
+package uk.ac.cam.cl.xeno.xenctl;
+
+import java.util.Date;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class
+XMLHelper
+{
+ static void
+ dump_document (Document document)
+ {
+ dump_element(document.getDocumentElement(), 0);
+ }
+
+ static void
+ dump_element (Element element, int indent)
+ {
+ NodeList nl = element.getChildNodes();
+
+ System.out.println ("<" + element.getTagName() + ">");
+ dump_nodelist(nl, indent + 1);
+ System.out.println("</" + element.getTagName() + ">");
+ }
+
+ static void
+ dump_nodelist (NodeList nl, int indent)
+ {
+ for (int loop = 0; loop < nl.getLength(); loop++)
+ {
+ Node node = nl.item(loop);
+ switch (node.getNodeType())
+ {
+ case Node.ELEMENT_NODE :
+ {
+ dump_element((Element)node, indent);
+ break;
+ }
+ case Node.TEXT_NODE :
+ {
+ System.out.println("TEXT: " + node.getNodeValue());
+ break;
+ }
+ default :
+ {
+ System.out.println("NODE: " + node.getNodeType());
+ }
+ }
+ }
+ }
+
+ static Node
+ get_subnode (String name, Node node)
+ {
+ if (node.getNodeType() != Node.ELEMENT_NODE)
+ {
+ System.err.println("Error: Search node not of element type");
+ return null;
+ }
+
+ if (!node.hasChildNodes()) return null;
+
+ NodeList list = node.getChildNodes();
+ for (int i=0; i < list.getLength(); i++)
+ {
+ Node subnode = list.item(i);
+ if (subnode.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if (subnode.getNodeName() == name) return subnode;
+ }
+ }
+ return null;
+ }
+
+ static String
+ get_text (Node node)
+ {
+ StringBuffer result = new StringBuffer();
+ if (node==null || !node.hasChildNodes()) return "";
+
+ NodeList list = node.getChildNodes();
+ for (int i=0; i < list.getLength(); i++)
+ {
+ Node subnode = list.item(i);
+ if (subnode.getNodeType() == Node.TEXT_NODE)
+ {
+ result.append(subnode.getNodeValue());
+ }
+ }
+ return result.toString();
+ }
+
+ static void
+ parse (PartitionManager pm, VirtualDiskManager vdm, Document document)
+ {
+ if (document == null) return;
+
+ /* parse partitions */
+ parse_partitions(pm, document.getElementsByTagName("partition"));
+
+ /* parse virtual disks */
+ NodeList list = document.getElementsByTagName("virtual_disk");
+ for (int i = 0; i < list.getLength(); i++)
+ {
+ Node subnode = list.item(i);
+ String parent = subnode.getParentNode().getNodeName();
+ VirtualDisk vd = parse_virtual_disk(subnode);
+
+ if (parent.equals("free"))
+ {
+ vdm.add_free(vd);
+ }
+ else if (parent.equals("virtual_disks"))
+ {
+ vdm.add_virtual_disk(vd);
+ }
+ else
+ {
+ System.out.println ("XML parse error: unknown parent for virtual_disk "
+ + "[" + parent + "]");
+ }
+ }
+
+ /* parse virtual block devices */
+ parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device"));
+
+ return;
+ }
+
+ static VirtualDisk
+ parse_virtual_disk(Node node)
+ {
+ VirtualDisk vd;
+ Date date = new Date();
+ NodeList list;
+
+ date.setTime(Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node))));
+ vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)),
+ date,
+ XMLHelper.get_text(XMLHelper.get_subnode("key", node)));
+
+ list = XMLHelper.get_subnode("extents", node).getChildNodes();
+ for (int i = 0; i < list.getLength(); i++)
+ {
+ Node enode = list.item(i);
+
+ if (enode.getNodeType() == Node.ELEMENT_NODE &&
+ enode.getNodeName().equals("extent"))
+ {
+ Extent extent = new Extent();
+
+ extent.disk = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("disk", enode)));
+ extent.size = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("size", enode)));
+ extent.offset = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("offset", enode)));
+ vd.add_extent(extent);
+ }
+ }
+
+ return vd;
+ }
+
+ static void
+ parse_partitions (PartitionManager pm, NodeList nl)
+ {
+ Partition partition;
+
+ for (int loop = 0; loop < nl.getLength(); loop++)
+ {
+ Node node = nl.item(loop);
+
+ partition = new Partition();
+ partition.major = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("major", node)));
+ partition.minor = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("minor", node)));
+ partition.blocks = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("blocks", node)));
+ partition.start_sect = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("start_sect", node)));
+ partition.nr_sects = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("nr_sects", node)));
+ partition.name = XMLHelper.get_text(XMLHelper.get_subnode("name", node));
+
+ pm.add_xeno_partition(partition);
+ }
+ }
+
+ static void
+ parse_virtual_block_devices (VirtualDiskManager vdm, NodeList nl)
+ {
+ VirtualBlockDevice vbd;
+
+ for (int loop = 0; loop < nl.getLength(); loop++)
+ {
+ Node node = nl.item(loop);
+
+ vdm.create_virtual_block_device(XMLHelper.get_text(XMLHelper.get_subnode("key", node)),
+ Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("domain", node))),
+ Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))),
+ XMLHelper.get_text(XMLHelper.get_subnode("mode", node)));
+ }
+ }
+}
diff --git a/tools/control/web/WEB-INF/web.xml b/tools/control/web/WEB-INF/web.xml
new file mode 100644
index 0000000000..c1e0d41784
--- /dev/null
+++ b/tools/control/web/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+ <display-name>Xen Control</display-name>
+ <description>
+ Copyright 2003, University of Cambridge Computer Laboratory
+ This is version 1.0-beta of the Xen control software.
+ </description>
+ <welcome-file-list>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+</web-app>
diff --git a/tools/control/web/img/cambridge.gif b/tools/control/web/img/cambridge.gif
new file mode 100644
index 0000000000..f30964c143
--- /dev/null
+++ b/tools/control/web/img/cambridge.gif
Binary files differ
diff --git a/tools/control/web/img/help.gif b/tools/control/web/img/help.gif
new file mode 100644
index 0000000000..e7d480939b
--- /dev/null
+++ b/tools/control/web/img/help.gif
Binary files differ
diff --git a/tools/control/web/img/home.gif b/tools/control/web/img/home.gif
new file mode 100644
index 0000000000..9c07803d3b
--- /dev/null
+++ b/tools/control/web/img/home.gif
Binary files differ
diff --git a/tools/control/web/img/pixel.gif b/tools/control/web/img/pixel.gif
new file mode 100644
index 0000000000..a92143a31d
--- /dev/null
+++ b/tools/control/web/img/pixel.gif
Binary files differ
diff --git a/tools/control/web/img/search.gif b/tools/control/web/img/search.gif
new file mode 100644
index 0000000000..d87207210f
--- /dev/null
+++ b/tools/control/web/img/search.gif
Binary files differ
diff --git a/tools/control/web/img/xeno.gif b/tools/control/web/img/xeno.gif
new file mode 100644
index 0000000000..efd7d0ad9f
--- /dev/null
+++ b/tools/control/web/img/xeno.gif
Binary files differ
diff --git a/tools/control/web/tmpl/about.tmpl b/tools/control/web/tmpl/about.tmpl
new file mode 100644
index 0000000000..77e4f90804
--- /dev/null
+++ b/tools/control/web/tmpl/about.tmpl
@@ -0,0 +1,71 @@
+About
+SECTION&XenoServers
+
+<!-- content -->
+<img src="img/pixel.gif" class="block" width="1" height="12" alt="">
+<table cellpadding="0" cellspacing="0" border="0" summary="page content">
+<tbody><tr>
+ <td width="250" valign="top" align="right">
+ <a href="http://www.cl.cam.ac.uk/xeno/"><img width="191" heigth="65" src="img/xeno.gif" border="0"></a>
+
+<table cellpadding="0" cellspacing="0" border="0" align="right">
+<tbody><tr>
+ <td><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+</tr>
+<tr>
+ <td colspan="3"><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+<tr>
+ <td align="right">
+ <table width="180" ><tbody><tr><td><p align="right">
+The XenoServer project aims to build a public infrastructure for wide-area distributed computing.
+</p>
+ </td></tr></tbody></table></td>
+<td><img src="img/pixel.gif" class="block" width="10" height="1" alt=""></td>
+</tr>
+</tbody></table>
+</td>
+<td bgcolor="#666666" width="2"><img src="img/pixel.gif" class="block" width="2" height="50" alt=""></td>
+<td width="20"><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+<td valign="top">
+
+<!-- main navigation -->
+<table cellpadding="0" cellspacing="0" border="0">
+
+<tbody><tr><td><b>Overview</b><td></tr>
+<tr>
+ <td>
+The Xenoserver project is building a public infrastructure for wide-area distributed computing. We envisage a world in which Xenoserver execution platforms will be scattered across the globe and available for any member of the public to submit code for execution. Crucially, the sponsor of the code will be billed for all the resources used or reserved during the course of execution. This will serve to encourage load balancing, limit congestion, and hopefully even make the platform self-financing.
+<p>
+A global infrastructure such as we propose is essential to address the fundamental problem of communication latency. By enabling principles to run programs at points throughout the network they can ensure that their code executes close to the entities with which it needs to interact. As well as reducing latency this can be used to avoid network bottlenecks, to reduce long-haul network charges and to provide a platform over which code provided by transiently-connected mobile devices can maintain a network presence.
+<p>
+Our approach is distinguished from existing work on mobile agents, execution platforms, code hosting and the like by two principles:
+<p>
+<b>Tackling difficult problems at the same time.</b> Acceptable designs for execution environments, resource management, resource discovery, authentication, privacy, charging, billing, payment and auditing are all crucial to the success of our platform as an infrastructure service open to and accepted by the public. Existing work has tackled individual subsets of these problems, but tensions between the issues concerned mean that solutions proficient in some dimension are lacking in another.
+<p>
+<b>No brave new world.</b> Our platform will host applications written in today's programming languages against existing APIs -- and, we believe, those written with tomorrow's languages and libraries. We do not want to mandate a particular code distribution format or a particular middleware toolkit for distributed programming.
+</td>
+</tr>
+
+<tr> <!-- blank white space -->
+ <td><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+
+<tr> <!-- grey line -->
+ <td bgcolor="#cccccc"><img src="img/pixel.gif" class="block" width="1" height="2" alt=""></td>
+</tr>
+
+<tr> <!-- blank white space -->
+ <td><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+
+<tr> <!-- list of menu items -->
+ <td nowrap="nowrap">
+ <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xeno/general-xeno.pdf" class="homemenu">Project Overview Document</a><br>
+ </td>
+</tr>
+</tbody></table>
+</td>
+</tr>
+</tbody></table>
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-del.tmpl b/tools/control/web/tmpl/dom-del.tmpl
new file mode 100644
index 0000000000..1c71fba836
--- /dev/null
+++ b/tools/control/web/tmpl/dom-del.tmpl
@@ -0,0 +1,86 @@
+Delete Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<form method="post" action="dom-delr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<%
+ CommandList command_list = new CommandList();
+ Defaults d = sc.getDefaults();
+ Domain domains[] = command_list.executeCommand(d);
+%>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>domain<br>id</td><td>processor</td><td>has<br>cpu</td><td>state</td><td>mcu<br>advance</td><td>total<br>pages</td><td>name</td></tr>
+ <%
+ for (int loop = 0; loop < domains.length; loop++)
+ {
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="dom" value="<%= domains[loop].id %>"></td>
+ <td align="center"><%= domains[loop].id %></td>
+ <td align="center"><%= domains[loop].processor %></td>
+ <td align="center"><%= domains[loop].cpu %> </td>
+ <td><%= domains[loop].state %> </td>
+ <td align="center"><%= domains[loop].mcu %> </td>
+ <td align="center"><%= domains[loop].pages %> </td>
+ <td><%= domains[loop].name %> </td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr><td>
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr>
+ <td></td>
+ <td class="menuheader">force immediate destruction?</td>
+</tr>
+<tr>
+ <td> <input type="radio" name="force" value="false" checked></td>
+ <td> don't force </td>
+</tr>
+<tr>
+ <td> <input type="radio" name="force" value="true"></td>
+ <td> force </td>
+</tr>
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="delete domain"></td>
+</tr>
+</tbody>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-delr.tmpl b/tools/control/web/tmpl/dom-delr.tmpl
new file mode 100644
index 0000000000..0693570f7a
--- /dev/null
+++ b/tools/control/web/tmpl/dom-delr.tmpl
@@ -0,0 +1,42 @@
+Delete Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+
+<b>Delete Domain Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+ Defaults d = sc.getDefaults();
+ CommandDestroy command_destroy = new CommandDestroy();
+
+ String domains[] = hsrw.getParameterValues("dom");
+ boolean force = hsrw.getParameter("force").equals("true");
+
+ for (int i = 0; i < domains.length; i++)
+ {
+%>
+result <%= domains[i] %> =
+ <%= command_destroy.executeCommand(d, Integer.parseInt(domains[i]),
+ force) %> <br>
+<%
+ }
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-lis.tmpl b/tools/control/web/tmpl/dom-lis.tmpl
new file mode 100644
index 0000000000..7a479a0f87
--- /dev/null
+++ b/tools/control/web/tmpl/dom-lis.tmpl
@@ -0,0 +1,50 @@
+Domain List
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<%
+ CommandList command_list = new CommandList();
+ Defaults d = sc.getDefaults();
+ Domain domains[] = command_list.executeCommand(d);
+%>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>domain<br>id</td><td>processor</td><td>has<br>cpu</td><td>state</td><td>mcu<br>advance</td><td>total<br>pages</td><td>name</td></tr>
+ <%
+ /* assert: domains != null, otherwise, where is the servlet engine? */
+ for (int loop = 0; loop < domains.length; loop++)
+ {
+ %>
+ <tr>
+ <td align="center"><%= domains[loop].id %></td>
+ <td align="center"><%= domains[loop].processor %></td>
+ <td align="center"><%= domains[loop].cpu %> </td>
+ <td><%= domains[loop].state %> </td>
+ <td align="center"><%= domains[loop].mcu %> </td>
+ <td align="center"><%= domains[loop].pages %> </td>
+ <td><%= domains[loop].name %> </td>
+ </tr>
+ <%
+ }
+ %>
+</tbody>
+</table>
+
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-new.tmpl b/tools/control/web/tmpl/dom-new.tmpl
new file mode 100644
index 0000000000..f6af5e570b
--- /dev/null
+++ b/tools/control/web/tmpl/dom-new.tmpl
@@ -0,0 +1,197 @@
+Create New Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<form method="post" action="dom-newr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr>
+ <td width="10"></td>
+ <td></td>
+ <td></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4><b>Create A New Domain</b></td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<%
+ Defaults d = sc.getDefaults();
+
+ if (d == null)
+ {
+%>
+ <b>ACK Defaults IS NULL</b>
+<%
+ }
+%>
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Domain Name</td>
+</tr>
+<tr>
+ <td></td> <td></td> <td></td> <td></td>
+ <td> <input type="text" size="16" name="name" value="<%= d.domainName %>">
+ </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Memory Size</td>
+</tr>
+<tr>
+ <td></td> <td></td> <td></td> <td></td>
+ <td>
+ <input type="text" size="5" name="size" value="<%= d.domainSizeKB %>"> KB
+ </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Kernel Image</td>
+</tr>
+<tr>
+ <td></td>
+ <td colspan=2 align="right">path</td>
+ <td></td>
+ <td>
+ <input type="text" size="40" name="image" value="<%= d.domainImage %>">
+ </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>IP Config</td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">VIFs</td>
+ <td></td>
+ <td>
+ <input type="text" size="4" name="vifs" value="<%= d.domainVIFs %>">
+ </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">IP address</td>
+ <td></td>
+ <td> <input type="text" size="15" name="ip" value="<%= d.NWIP %>"> </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">Gateway</td>
+ <td></td>
+ <td> <input type="text" size="15" name="gw" value="<%= d.NWGW %>"> </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">Netmask</td>
+ <td></td>
+ <td> <input type="text" size="15" name="mask" value="<%= d.NWMask %>"> </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=2>Root File System</td>
+</tr>
+
+##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td align="right">NFS<input type="radio" name="root" value="nfs"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td>
+ <input type="text" size="40" name="nfsroot" value="<%= d.NWNFSRoot %>">
+ </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td align="right">server</td>
+ <td></td>
+ <td>
+ <input type="text" size="15" name="nfsserver" value="<%= d.NWNFSServer%>">
+ </td>
+</tr>
+ ##WHITESPACE##
+<tr>
+ <td></td>
+ <td align="right">ramdisk<input type="radio" name="root" value="ram"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td>
+ <input type="text" size="40" name="rd" value="/usr/isolinux/initrd.gz">
+ </td>
+</tr>
+ ##WHITESPACE##
+<tr>
+ <td></td>
+ <td align="right">physical disk<input type="radio" checked name="root" value="pdisk"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" name="pdisk" value="/dev/sda8"></td>
+</tr>
+<tr>
+ <td></td>
+ <td align="right">virtual disk<input type="radio" checked name="root" value="vdisk"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" name="vdisk" value="/dev/xvda1"></td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Extra Arguments</td>
+</tr>
+<tr>
+ <td></td>
+ <td colspan=2 align="right"></td>
+ <td></td>
+ <td> <input type="text" size="40" name="args" value="ro"> </td>
+</tr>
+
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td><input type="submit" value="create domain"></td>
+</tr>
+
+</tbody>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-newr.tmpl b/tools/control/web/tmpl/dom-newr.tmpl
new file mode 100644
index 0000000000..2800eac702
--- /dev/null
+++ b/tools/control/web/tmpl/dom-newr.tmpl
@@ -0,0 +1,100 @@
+Create New Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<b>Create Domain Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+ Defaults d = sc.getDefaults();
+ CommandNew command_new = new CommandNew();
+ String root_device = hsrw.getParameter("root");
+
+ String nfsroot = null;
+ String nfsserver = null;
+ String rd = null;
+ String disk = null;
+
+ if (root_device.equals("nfs"))
+ {
+ nfsroot = hsrw.getParameter("nfsroot");
+ nfsserver = hsrw.getParameter("nfsserver");
+ disk = "/dev/nfs";
+ }
+ else if (root_device.equals("ram"))
+ {
+ nfsserver = hsrw.getParameter("nfsserver");
+ rd = hsrw.getParameter("rd");
+ }
+ else if (root_device.equals("pdisk"))
+ {
+ nfsserver = hsrw.getParameter("nfsserver");
+ disk = hsrw.getParameter("pdisk");
+ }
+ else if (root_device.equals("vdisk"))
+ {
+ nfsserver = hsrw.getParameter("nfsserver");
+ disk = hsrw.getParameter("vdisk");
+ }
+
+%>
+name = <%= hsrw.getParameter("name") %>
+<br>
+size = <%= hsrw.getParameter("size") %>
+<br>
+image = <%= hsrw.getParameter("image") %>
+<br>
+initrd = <%= rd %>
+<br>
+vifs = <%= hsrw.getParameter("vifs") %>
+<br>
+bargs = <%= hsrw.getParameter("args") %>
+<br>
+nfs_root_path = <%= nfsroot %>
+<br>
+nw_ip = <%= hsrw.getParameter("ip") %>
+<br>
+nw_gw = <%= hsrw.getParameter("gw") %>
+<br>
+nw_mask = <%= hsrw.getParameter("mask") %>
+<br>
+nw_nfs_server = <%= nfsserver %>
+<br>
+nw_host = <%= hsrw.getParameter("hostname") %>
+<br>
+root = <%= disk %>
+<br>
+output = <br><%=
+ command_new.executeCommand(d,
+ hsrw.getParameter("name"),
+ Integer.parseInt(hsrw.getParameter("size")),
+ hsrw.getParameter("image"),
+ rd,
+ Integer.parseInt(hsrw.getParameter("vifs")),
+ hsrw.getParameter("args"),
+ disk,
+ nfsroot,
+ hsrw.getParameter("ip"),
+ hsrw.getParameter("gw"),
+ hsrw.getParameter("mask"),
+ nfsserver,
+ hsrw.getParameter("hostname"))
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-sta.tmpl b/tools/control/web/tmpl/dom-sta.tmpl
new file mode 100644
index 0000000000..06fda1a96a
--- /dev/null
+++ b/tools/control/web/tmpl/dom-sta.tmpl
@@ -0,0 +1,64 @@
+Start Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<form method="post" action="dom-star.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<%
+ CommandList command_list = new CommandList();
+ Defaults d = sc.getDefaults();
+ Domain domains[] = command_list.executeCommand(d);
+%>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>domain<br>id</td><td>processor</td><td>has<br>cpu</td><td>state</td><td>mcu<br>advance</td><td>total<br>pages</td><td>name</td></tr>
+ <%
+ for (int loop = 0; loop < domains.length; loop++)
+ {
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="dom" value="<%= domains[loop].id %>"></td>
+ <td align="center"><%= domains[loop].id %></td>
+ <td align="center"><%= domains[loop].processor %></td>
+ <td align="center"><%= domains[loop].cpu %> </td>
+ <td><%= domains[loop].state %> </td>
+ <td align="center"><%= domains[loop].mcu %> </td>
+ <td align="center"><%= domains[loop].pages %> </td>
+ <td><%= domains[loop].name %> </td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="start domain"></td>
+</tr>
+</tbody>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-star.tmpl b/tools/control/web/tmpl/dom-star.tmpl
new file mode 100644
index 0000000000..cd7e27abd4
--- /dev/null
+++ b/tools/control/web/tmpl/dom-star.tmpl
@@ -0,0 +1,40 @@
+Start Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+
+<b>Start Domain Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+ Defaults d = sc.getDefaults();
+ CommandStart command_start = new CommandStart();
+
+ String domains[] = hsrw.getParameterValues("dom");
+
+ for (int i = 0; i < domains.length; i++)
+ {
+%>
+result <%= domains[i] %> =
+ <%= command_start.executeCommand(d, Integer.parseInt(domains[i])) %> <br>
+<%
+ }
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-stp.tmpl b/tools/control/web/tmpl/dom-stp.tmpl
new file mode 100644
index 0000000000..8587a5a594
--- /dev/null
+++ b/tools/control/web/tmpl/dom-stp.tmpl
@@ -0,0 +1,64 @@
+Stop Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+<form method="post" action="dom-stpr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<%
+ CommandList command_list = new CommandList();
+ Defaults d = sc.getDefaults();
+ Domain domains[] = command_list.executeCommand(d);
+%>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>domain<br>id</td><td>processor</td><td>has<br>cpu</td><td>state</td><td>mcu<br>advance</td><td>total<br>pages</td><td>name</td></tr>
+ <%
+ for (int loop = 0; loop < domains.length; loop++)
+ {
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="dom" value="<%= domains[loop].id %>"></td>
+ <td align="center"><%= domains[loop].id %></td>
+ <td align="center"><%= domains[loop].processor %></td>
+ <td align="center"><%= domains[loop].cpu %> </td>
+ <td><%= domains[loop].state %> </td>
+ <td align="center"><%= domains[loop].mcu %> </td>
+ <td align="center"><%= domains[loop].pages %> </td>
+ <td><%= domains[loop].name %> </td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="stop domain"></td>
+</tr>
+</tbody>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom-stpr.tmpl b/tools/control/web/tmpl/dom-stpr.tmpl
new file mode 100644
index 0000000000..8c0016e89b
--- /dev/null
+++ b/tools/control/web/tmpl/dom-stpr.tmpl
@@ -0,0 +1,40 @@
+Stop Domain
+SECTION&XenoServers
+BREADCRUMB&Domain Manager&dom.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+
+
+<b>Stop Domain Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+ Defaults d = sc.getDefaults();
+ CommandStop command_stop = new CommandStop();
+
+ String domains[] = hsrw.getParameterValues("dom");
+
+ for (int i = 0; i < domains.length; i++)
+ {
+%>
+result <%= domains[i] %> =
+ <%= command_stop.executeCommand(d, Integer.parseInt(domains[i])) %> <br>
+<%
+ }
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dom.tmpl b/tools/control/web/tmpl/dom.tmpl
new file mode 100644
index 0000000000..6e602c979f
--- /dev/null
+++ b/tools/control/web/tmpl/dom.tmpl
@@ -0,0 +1,30 @@
+Domain Manager
+SECTION&XenoServers
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&dommenu.tmpl
+<td valign="top">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<%
+ Defaults d = sc.getDefaults();
+%>
+ <tr><td nowrap="nowrap">Domain Manager</td></tr>
+ <tr><td></td></tr>
+<!--
+ <tr><td><%= d.XIToolsDir %></td></tr>
+-->
+</tbody>
+</table>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/dommenu.tmpl b/tools/control/web/tmpl/dommenu.tmpl
new file mode 100644
index 0000000000..8fc11b2276
--- /dev/null
+++ b/tools/control/web/tmpl/dommenu.tmpl
@@ -0,0 +1,33 @@
+<td width="10" valign="top" align="right"></td>
+
+<td valign="top">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr>
+ <td class="menuheader" width="100">Domains</td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="dom-lis.jsp">List</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="dom-new.jsp">New</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="dom-sta.jsp">Start</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="dom-stp.jsp">Stop</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="dom-del.jsp">Delete</a></td>
+</tr>
+
+</tbody>
+</table>
+</td>
+
+<td width="5" valign="top" align="right"></td>
+
+<td bgcolor="#666666" width="2"><img src="img/pixel.gif" class="block" width="2" height="50"></td>
+
+<td width="15" valign="top" align="right"></td>
diff --git a/tools/control/web/tmpl/help.tmpl b/tools/control/web/tmpl/help.tmpl
new file mode 100644
index 0000000000..9cf6462273
--- /dev/null
+++ b/tools/control/web/tmpl/help.tmpl
@@ -0,0 +1,61 @@
+Help
+SECTION&XenoServers
+
+<!-- content -->
+<img src="img/pixel.gif" class="block" width="1" height="12" alt="">
+<table cellpadding="0" cellspacing="0" border="0" summary="page content">
+<tbody><tr>
+ <td width="250" valign="top" align="right">
+ <a href="http://www.cl.cam.ac.uk/newlabphotos/"><img width="191" heigth="65" src="img/xeno.gif" border="0"></a>
+
+<table cellpadding="0" cellspacing="0" border="0" align="right">
+<tbody><tr>
+ <td><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+</tr>
+<tr>
+ <td colspan="3"><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+<tr>
+ <td align="right">
+ <table width="180" ><tbody><tr><td><p align="right">
+The XenoServer project aims to build a public infrastructure for wide-area distributed computing.
+</p>
+ </td></tr></tbody></table></td>
+<td><img src="img/pixel.gif" class="block" width="10" height="1" alt=""></td>
+</tr>
+</tbody></table>
+</td>
+<td bgcolor="#666666" width="2"><img src="img/pixel.gif" class="block" width="2" height="50" alt=""></td>
+<td width="20"><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+<td valign="top">
+
+<!-- main navigation -->
+<table cellpadding="0" cellspacing="0" border="0">
+
+<tbody><tr> <!-- list of menu items -->
+ <td nowrap="nowrap">
+ <b>Help</b>
+</td>
+</tr>
+
+<tr> <!-- blank white space -->
+ <td><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+
+<tr> <!-- grey line -->
+ <td bgcolor="#cccccc"><img src="img/pixel.gif" class="block" width="1" height="2" alt=""></td>
+</tr>
+
+<tr> <!-- blank white space -->
+ <td><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+
+<tr> <!-- list of menu items -->
+ <td nowrap="nowrap">Some help text will go here.
+ </td>
+</tr>
+</tbody></table>
+</td>
+</tr>
+</tbody></table>
+<!-- end content -->
diff --git a/tools/control/web/tmpl/index.tmpl b/tools/control/web/tmpl/index.tmpl
new file mode 100644
index 0000000000..d1e158ff48
--- /dev/null
+++ b/tools/control/web/tmpl/index.tmpl
@@ -0,0 +1,66 @@
+XenoServers
+COPYRIGHT&Computer Laboratory, University of Cambridge
+
+<!-- content -->
+<img src="img/pixel.gif" class="block" width="1" height="12" alt="">
+<table cellpadding="0" cellspacing="0" border="0" summary="page content">
+<tbody><tr>
+ <td width="250" valign="top" align="right">
+ <a href="http://www.cl.cam.ac.uk/xeno"><img width="191" heigth="65" src="img/xeno.gif" border="0"></a>
+
+<table cellpadding="0" cellspacing="0" border="0" align="right">
+<tbody>
+<tr>
+ <td><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+</tr>
+<tr>
+ <td colspan="2"><img src="img/pixel.gif" class="block" width="1" height="10" alt=""></td>
+</tr>
+<tr>
+ <td align="right">
+ <table width="180" ><tbody><tr><td><p align="right">
+ The XenoServer project aims to build a public infrastructure
+ for wide-area distributed computing.
+ </td></tr></tbody></table></td>
+<td><img src="img/pixel.gif" class="block" width="10" height="1" alt=""></td>
+</tr>
+</tbody></table>
+</td>
+<td bgcolor="#666666" width="2"><img src="img/pixel.gif" class="block" width="2" height="50" alt=""></td>
+<td width="20"><img src="img/pixel.gif" class="block" width="20" height="1" alt=""></td>
+<td valign="top">
+
+<!-- main navigation -->
+<table cellpadding="0" cellspacing="0" border="0">
+
+<tbody><tr> <!-- list of menu items -->
+ <td nowrap="nowrap">
+ <a href="about.jsp" class="homemenu">About the XenoServers Project</a><br>
+</td>
+</tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td nowrap="nowrap">
+ <a href="dom.jsp" class="homemenu">Domain Manager</a><br>
+ <a href="vd.jsp" class="homemenu">Virtual Disk Manager</a><br>
+ </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td nowrap="nowrap">
+ For additional information, click
+ <a href="http://www.xenoserver.org">here</a>
+ </td>
+</tr>
+
+
+##WHITESPACE##
+</tbody></table>
+</td>
+</tr>
+</tbody></table>
+<!-- end content -->
diff --git a/tools/control/web/tmpl/install.pl b/tools/control/web/tmpl/install.pl
new file mode 100755
index 0000000000..1d712a2e39
--- /dev/null
+++ b/tools/control/web/tmpl/install.pl
@@ -0,0 +1,236 @@
+#!/usr/bin/perl5
+if($#ARGV<0) {
+ &usage();
+} else {
+
+ $headerfile = "xenohead.def" ;
+ $footerfile = "xenofoot.def" ;
+
+ $sectionbreak = "-" ;
+ $supress_section = 0 ;
+ $homepage = 0 ;
+ $navigationwidth = 106;
+ $navigationstring = "<td><a href=\"index.jsp\"><img src=\"img/home.gif\" width=\"53\" height=\"18\" border=\"0\" alt=\"XenoServers Home Page\" class=\"block\" /></a></td>";
+ $whitespace = "<tr><td><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"10\"></td></tr>";
+ $greyline1 = "<tr><td bgcolor=\"#cccccc\"><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"2\"></td></tr>";
+ $greyline2 = "<tr><td bgcolor=\"#cccccc\" colspan=\"2\"><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"2\"></td></tr>";
+ $greyline3 = "<tr><td bgcolor=\"#cccccc\" colspan=\"3\"><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"2\"></td></tr>";
+ $greyline4 = "<tr><td bgcolor=\"#cccccc\" colspan=\"4\"><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"2\"></td></tr>";
+ $greyline14 = "<tr><td></td><td bgcolor=\"#cccccc\" colspan=\"4\"><img src=\"img/pixel.gif\" class=\"block\" width=\"1\" height=\"2\"></td></tr>";
+
+
+ $login = getlogin || (getpwuid($<))[0] || "an unidentified user" ;
+
+ $name =`finger $login | sed -n "s/Login.*:.*: //p"` ;
+ if( $name eq "" ) { $name = $login ; }
+
+ $date = `date +"on %-e-%b-%Y at %H:%M"` ;
+
+ $year = `date +"%Y"` ;
+
+ foreach $ag (@ARGV) {
+
+ if( $ag =~ "^-s" ) {
+ $supress_section = 1 ;
+ }
+ elsif( $ag =~ "^-home" ) {
+ $homepage = 1 ;
+ }
+ else {
+
+ $preagtmp = $ag . ".tmpl~$$";
+ $agtmp = $ag . ".jsp~$$";
+
+ open(PRETMPL,">$preagtmp") or die "Unable to write $preagtmp\n";
+ print PRETMPL &doIncludes("$ag.tmpl");
+ close(PRETMPL);
+
+ open(TMPL,"<$preagtmp") or die "Unable to read $preagtmp\n";
+
+ open(HTML,">$agtmp") or die "Unable to open $agtmp\n" ;
+
+ $title=<TMPL> ;
+
+ $sectionhead = "XenoServers" ;
+ $copyright = "Computer Laboratory, University of Cambridge" ;
+ $breadcrumbline = "" ;
+ $commentcontact="<a href=\"mailto:pagemaster\@cl.cam.ac.uk\">pagemaster\@cl.cam.ac.uk</a>" ;
+
+ $process_headings = 1 ;
+ $tmp=<TMPL> ;
+ while( $process_headings ) {
+ $process_headings = 0 ;
+
+ if( $tmp =~ /^SECTION&(.*)$/ ) {
+ $sectionhead=$1 ;
+ $process_headings = 1 ;
+ }
+
+ if( $tmp =~ /^COMMENTS&(.*)$/ ) {
+ $commentcontact=$1 ;
+ $process_headings = 1 ;
+ }
+
+ if( $tmp =~ /^COPYRIGHT&(.*)$/ ) {
+ $copyright=$1 ;
+ $process_headings = 1 ;
+ }
+
+ if( $tmp =~ /^HEADERFILE&(.*)$/ ) {
+ $headerfile=$1 ;
+ $process_headings = 1 ;
+ }
+
+ if( $tmp =~ /^FOOTERFILE&(.*)$/ ) {
+ $footerfile=$1 ;
+ $process_headings = 1 ;
+ }
+
+ if( $tmp =~ /BREADCRUMB&.*/ ) {
+ @bread=split(/&/,$tmp) ;
+ @bwords=split(/ /, @bread[1]) ;
+ $bname=@bwords[0] ;
+ for( $i=1 ; $i <= $#bwords ; $i++ ){
+ $bname = $bname . "&nbsp;" . @bwords[$i] ;
+ }
+ $breadcrumbline = $breadcrumbline . "&nbsp;&gt;&nbsp;<a href=\"" . @bread[2] . "\"class=\"bread\">" . $bname . "</a>" ;
+ $process_headings = 1 ;
+ }
+
+ if( $process_headings ) {
+ $tmp=<TMPL> ;
+ }
+ }
+
+#### generate the final breadcrumb which is the current file itself
+ @path=split(/\//, $ag) ;
+ $localfilename=@path[$#path] . ".jsp" ;
+ @bwords=split(/ /, $title) ;
+ $bname=@bwords[0] ;
+ for( $i=1 ; $i <= $#bwords ; $i++ ){
+ $bname = $bname . "&nbsp;" . @bwords[$i] ;
+ }
+ $breadcrumbline = $breadcrumbline . "&nbsp;&gt;&nbsp;<a href=\"" . $localfilename . "\" class=\"bread\">" . $bname . "</a>" ;
+
+
+#### if suppressing the section header then do so now
+ if( $supress_section ) {
+ $sectionhead = "" ;
+ $sectionbreak = "" ;
+ }
+
+#### if homepage then do so now
+ if( $homepage ) {
+ $breadcrumbline = "" ;
+ $navigationwidth = 53;
+ $navigationstring = "";
+ }
+
+
+ open(HEADER,"<$headerfile") or die "Unable to open $headerfile\n" ;
+ while(<HEADER>) {
+ s/##TITLE##/$title/g ;
+ s/##SECTION##/$sectionhead/g ;
+ s/##SECTIONBREAK##/$sectionbreak/g ;
+ s/##BREADCRUMBS##/$breadcrumbline/g ;
+ s/##FILENAME##/$ag.jsp/g ;
+ s/##DATE##/$date/g ;
+ s/##OWNERNAME##/$name/g ;
+ s/##OWNERUSERID##/$login/g ;
+ s/##OWNEREMAIL##/$login\@cl.cam.ac.uk/g ;
+ s/##COMMENTCONTACT##/$commentcontact/g ;
+ s/##COPYRIGHT##/$copyright/g ;
+ s/##YEAR##/$year/g ;
+ s/##NAVIGATIONWIDTH##/$navigationwidth/g ;
+ s/##NAVIGATIONSTRING##/$navigationstring/g ;
+ print HTML $_ ;
+ }
+ close(HEADER) ;
+
+ $_ = $tmp ;
+ while(defined($_)) {
+ s/##LISTSTART##/<ul>/g ;
+ s/##ITEMHEAD##/<li>/g ;
+ s/##ITEMBODY##/<br \/>/g ;
+ s|##LISTEND##|</ul>|g ;
+ s/##TITLE##/$title/g ;
+ s/##SECTION##/$sectionhead/g ;
+ s/##BREADCRUMBS##/$breadcrumbline/g ;
+ s/##FILENAME##/$ag.jsp/g ;
+ s/##DATE##/$date/g ;
+ s/##OWNERNAME##/$name/g ;
+ s/##OWNERUSERID##/$login/g ;
+ s/##OWNEREMAIL##/$login\@cl.cam.ac.uk/g ;
+ s/##COMMENTCONTACT##/$commentcontact/g ;
+ s/##COPYRIGHT##/$copyright/g ;
+ s/##YEAR##/$year/g ;
+ s/##WHITESPACE##/$whitespace/g ;
+ s/##GREYLINE1##/$greyline1/g ;
+ s/##GREYLINE2##/$greyline2/g ;
+ s/##GREYLINE3##/$greyline3/g ;
+ s/##GREYLINE4##/$greyline4/g ;
+ s/##GREYLINE14##/$greyline14/g ;
+ print HTML $_ ;
+ $_ = <TMPL>
+ }
+ open(FOOTER,"<$footerfile") or die "Unable to open $footerfile\n" ;
+ while(<FOOTER>) {
+ s/##TITLE##/$title/g ;
+ s/##SECTION##/$sectionhead/g ;
+ s/##BREADCRUMBS##/$breadcrumbline/g ;
+ s/##FILENAME##/$ag.jsp/g ;
+ s/##DATE##/$date/g ;
+ s/##OWNERNAME##/$name/g ;
+ s/##OWNERUSERID##/$login/g ;
+ s/##OWNEREMAIL##/$login\@cl.cam.ac.uk/g ;
+ s/##COMMENTCONTACT##/$commentcontact/g ;
+ s/##COPYRIGHT##/$copyright/g ;
+ s/##YEAR##/$year/g ;
+ print HTML $_ ;
+ }
+ close(FOOTER) ;
+ close(HTML);
+ close(TMPL);
+
+ if( system "mv $agtmp $ag.jsp" ) {
+ die "Unable to rename $agtmp to $ag.jsp\n" ; ;
+ }
+ if( system "rm $preagtmp" ) {
+ die "Unable to remove $preagtmp\n" ; ;
+ }
+ }
+ }
+}
+
+sub usage
+{
+ print "Usage: install.pl [-s] <name>\n";
+ print " Installs web page <name>.jsp based on <name>.tmpl\n";
+ print " -s supresses the generation of any section title";
+ print " which says `Computer Laboratory' in the default" ;
+ print " case or is specified by SECTION& in the .tmpl file" ;
+ exit;
+}
+
+sub doIncludes
+{
+ my $infile=$_[0];
+ my $out="";
+ my $tmp;
+ my $incfile;
+ my @lines;
+ my $line;
+
+ open(FIN,"<$infile") or die "doIncludes unable to read from $infile\n";
+ @lines=<FIN>;
+ close(FIN);
+ foreach $line (@lines) {
+ if( $line =~ /^INCLUDE&.*/ ) {
+ ($tmp,$incfile) = split(/&/,$line);
+ $out=$out.&doIncludes($incfile);
+ } else {
+ $out=$out.$line;
+ }
+ }
+ return $out;
+}
diff --git a/tools/control/web/tmpl/makefile b/tools/control/web/tmpl/makefile
new file mode 100644
index 0000000000..aed826114e
--- /dev/null
+++ b/tools/control/web/tmpl/makefile
@@ -0,0 +1,35 @@
+src0 = xenostyle.css
+src1 = index.jsp newdom.jsp about.jsp help.jsp vd.jsp \
+ vd-pv.jsp vd-pa.jsp vd-vdv.jsp vd-vdc.jsp vd-vdd.jsp vd-vdr.jsp \
+ vd-fv.jsp vd-vbdv.jsp vd-vbdc.jsp vd-vbdd.jsp vd-vbdf.jsp \
+ vd-par.jsp vd-vdcr.jsp vd-vddr.jsp vd-vdrr.jsp \
+ vd-vbdcr.jsp vd-vbdfr.jsp \
+ dom.jsp dom-lis.jsp dom-new.jsp dom-newr.jsp dom-sta.jsp dom-star.jsp \
+ dom-stp.jsp dom-stpr.jsp dom-del.jsp dom-delr.jsp
+target = ..
+target1 = $(target)/index.jsp $(target)/newdom.jsp $(target)/vd.jsp \
+ $(target)/vd-pv.jsp $(target)/vd-pa.jsp $(target)/vd-vdv.jsp \
+ $(target)/vd-vdc.jsp $(target)/vd-vdd.jsp $(target)/vd-vdr.jsp \
+ $(target)/vd-fv.jsp $(target)/vd-vbdv.jsp $(target)/vd-vbdc.jsp \
+ $(target)/vd-vbdd.jsp $(target)/vd-vbdf.jsp \
+ $(target)/about.jsp $(target)/help.jsp \
+ $(target)/vd-par.jsp $(target)/vd-vdcr.jsp $(target)/vd-vddr.jsp \
+ $(target)/vd-vdrr.jsp $(target)/vd-vbdcr.jsp $(target)/vd-vbdfr.jsp \
+ $(target)/dom.jsp $(target)/dom-lis.jsp $(target)/dom-new.jsp \
+ $(target)/dom-newr.jsp $(target)/dom-sta.jsp $(target)/dom-star.jsp \
+ $(target)/dom-stp.jsp $(target)/dom-stpr.jsp \
+ $(target)/dom-del.jsp $(target)/dom-delr.jsp
+
+.SUFFIXES: .tmpl .jsp
+
+.tmpl.jsp:
+ ./install.pl $*
+
+all: $(src0) $(src1)
+ ./install.pl -s -home index
+ mv *.jsp $(target)
+ cp $(src0) $(target)
+
+clean:
+ rm -f $(target1)
+ rm -f $(target)/$(src0)
diff --git a/tools/control/web/tmpl/newdom.tmpl b/tools/control/web/tmpl/newdom.tmpl
new file mode 100644
index 0000000000..47af39f4a8
--- /dev/null
+++ b/tools/control/web/tmpl/newdom.tmpl
@@ -0,0 +1,172 @@
+New Domain
+SECTION&XenoServers
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<form>
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr>
+ <td width="50"></td>
+ <td></td>
+ <td></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4><b>Create A New Domain</b></td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Memory Size</td>
+</tr>
+<tr>
+ <td></td> <td></td> <td></td> <td></td>
+ <td> <input type="text" size="5" value="64"> MB </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Kernel Image</td>
+</tr>
+<tr>
+ <td></td>
+ <td colspan=2 align="right">path</td>
+ <td></td>
+ <td> <input type="text" size="40" value="/usr/src/xeno/install/xenolinux.gz"> </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>IP Config</td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">IP address</td>
+ <td></td>
+ <td> <input type="text" size="15" value="128.232.35.202"> </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">Gateway</td>
+ <td></td>
+ <td> <input type="text" size="15" value="128.232.32.1"> </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">Netmask</td>
+ <td></td>
+ <td> <input type="text" size="15" value="255.255.240.0"> </td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td class="block" align="right">New Name</td>
+ <td></td>
+ <td> <input type="text" size="15"> </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=2>Root File System</td>
+</tr>
+
+##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td align="right">NFS<input type="radio" name="root" value="nfs"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" value="/usr/groups/xeno/srgboot/mousetrap/root0"></td>
+</tr>
+<tr>
+ <td></td> <td></td>
+ <td align="right">server</td>
+ <td></td>
+ <td><input type="text" size="15" value="128.232.32.20"></td>
+</tr>
+ ##WHITESPACE##
+<tr>
+ <td></td>
+ <td align="right">ramdisk<input type="radio" name="root" value="ram"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" value="/usr/isolinux/initrd.gz"></td>
+</tr>
+ ##WHITESPACE##
+<tr>
+ <td></td>
+ <td align="right">raw partition<input type="radio" name="root" value="raw"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" value="/dev/xsda8"></td>
+</tr>
+ ##WHITESPACE##
+<tr>
+ <td></td>
+ <td align="right">virtual disk<input type="radio" checked name="root" value="virtual"></td>
+ <td align="right">path</td>
+ <td></td>
+ <td><input type="text" size="40" value="/dev/xvda0"></td>
+</tr>
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td class="block" colspan=4>Extra Arguments</td>
+</tr>
+<tr>
+ <td></td>
+ <td colspan=2 align="right"></td>
+ <td></td>
+ <td> <input type="text" size="40"> </td>
+</tr>
+
+
+##WHITESPACE## ##GREYLINE14## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td><input type="submit" value="refresh"></td>
+</tr>
+
+##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td colspan=4>
+ <textarea cols="60" rows="5" name="commandline">
+When you press refresh, the sample command line shows
+up here. The user has the option of editing it before
+pressing execute below. e.g.
+./newdom 16000 image 128.232.35.202 ip=128.232.35.202:128.232.32.20:128.232.32.1:255.255.240.0::eth0:off root=/dev/xsda9 ro
+</textarea>
+</td></tr>
+
+##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td><input type="submit" value="execute"></td>
+</tr>
+
+</tbody>
+</table>
+</form>
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-fv.tmpl b/tools/control/web/tmpl/vd-fv.tmpl
new file mode 100644
index 0000000000..e8b41a2bb5
--- /dev/null
+++ b/tools/control/web/tmpl/vd-fv.tmpl
@@ -0,0 +1,60 @@
+View Free Space
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr><td>
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>idx</td><td>disk</td><td>offset</td><td>size </td></tr>
+
+ <%
+ long space = 0;
+ int count = root.getFreeExtentCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ Extent e = root.getFreeExtent(loop);
+ space += e.getSize();
+ %>
+ <tr class="vdt">
+ <td ><%= loop %></td>
+ <td ><%= e.getDisk() %></td>
+ <td align="right"><%= e.getOffset() %> </td>
+ <td align="right"><%= e.getSize() %> </td>
+ </tr>
+ <%
+ }
+ %>
+</tbody>
+</table>
+</td></tr>
+
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr><td>
+Total available freespace: <%= space * 512 / (1024 * 1024) %> MB
+</td></tr>
+
+</tbody>
+</table>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-pa.tmpl b/tools/control/web/tmpl/vd-pa.tmpl
new file mode 100644
index 0000000000..e71a6bf195
--- /dev/null
+++ b/tools/control/web/tmpl/vd-pa.tmpl
@@ -0,0 +1,97 @@
+Add Partition
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-par.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr><td>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>maj:min</td><td>blocks</td><td>start sect</td><td>num sects</td><td>name</td></tr>
+ <%
+ int count = root.getPartitionCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ Partition p = root.getPartition(loop);
+ if (p.getIsXeno() == true)
+ {
+ %>
+ <tr class="vds"><td></td>
+ <%
+ }
+ else
+ {
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="p" value="<%= p.getName() %>"></td>
+ <%
+ }
+ %>
+ <td><%= p.getMajor() %>:<%= p.getMinor() %></td>
+ <td align="right"><%= p.getBlocks() %></td>
+ <td align="right"><%= p.getStartSect() %> </td>
+ <td align="right"><%= p.getNumSects() %> </td>
+ <td><%= p.getName() %> </td>
+ </tr>
+ <%
+ }
+ %>
+</tbody>
+</table>
+
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+
+<tr><td>
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr>
+ <td width="50"></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td align="right">chunksize</td>
+ <td></td>
+ <td> <input type="text" size="5" name="chunk" value="256">
+ <input type="radio" name="chunkunits" value="m" checked>MB
+ <input type="radio" name="chunkunits" value="g">GB
+ </td>
+</tr>
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="add partition"></td>
+</tr>
+
+</tbody>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-par.tmpl b/tools/control/web/tmpl/vd-par.tmpl
new file mode 100644
index 0000000000..3a7f5ec3b9
--- /dev/null
+++ b/tools/control/web/tmpl/vd-par.tmpl
@@ -0,0 +1,49 @@
+Add Partition Results
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<b>Add Partition Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+
+ String partitions[] = hsrw.getParameterValues("p");
+ String size = hsrw.getParameter("chunk").trim() +
+ hsrw.getParameter("chunkunits").trim();
+
+ for (int i = 0; i < partitions.length; i++)
+ {
+%>
+p = <%= root.doAddPartition(partitions[i], size) %> <br>
+<%
+ }
+%>
+chunk = <%= hsrw.getParameter("chunk") %>
+<br>
+chunkunits = <%= hsrw.getParameter("chunkunits") %>
+<br>
+size = <%= size %>
+<br>
+
+
+<%
+ root.doFlushState();
+%>
+
+
+</td>
+</tbody>
+</table>
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-pv.tmpl b/tools/control/web/tmpl/vd-pv.tmpl
new file mode 100644
index 0000000000..8195f82964
--- /dev/null
+++ b/tools/control/web/tmpl/vd-pv.tmpl
@@ -0,0 +1,54 @@
+View Partitions
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+note: highlighted entries are currently being used as xeno partitions.
+<br><br>
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>maj:min</td><td>blocks</td><td>start sect</td><td>num sects</td><td>name</td></tr>
+ <%
+ int count = root.getPartitionCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ Partition p = root.getPartition(loop);
+ if (p.getIsXeno() == true)
+ {
+ %>
+ <tr class="vds">
+ <%
+ }
+ else
+ {
+ %>
+ <tr class="vdt">
+ <%
+ }
+ %>
+ <td><%= p.getMajor() %>:<%= p.getMinor() %></td>
+ <td align="right"><%= p.getBlocks() %></td>
+ <td align="right"><%= p.getStartSect() %> </td>
+ <td align="right"><%= p.getNumSects() %> </td>
+ <td><%= p.getName() %> </td>
+ <%
+ }
+ %>
+</tbody>
+</table>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdc.tmpl b/tools/control/web/tmpl/vd-vbdc.tmpl
new file mode 100644
index 0000000000..e6952182b8
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdc.tmpl
@@ -0,0 +1,94 @@
+Create Virtual Block Device
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-vbdcr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>vd key</td><td width="5"></td><td>name</td><td width="5"></td><td>expiry</td></tr>
+
+ <%
+ int count = root.getVirtualDiskCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ VirtualDisk vd = root.getVirtualDisk(loop);
+ %>
+ <tr class="vdt">
+ <td>
+ <input type="radio" name="vd"
+ <% if (loop == 0) { %> checked <% } %>
+ value="<%= vd.getKey() %>">
+ </td>
+ <td><%= vd.getKey() %></td>
+ <td></td>
+ <td><%= vd.getName() %></td>
+ <td></td>
+ <td><%= vd.getExpiry() %></td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr><td>
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr>
+ <td width="100"></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td align="right">domain</td>
+ <td></td>
+ <td> <input type="text" size="3" name="domain"> </td>
+</tr>
+<tr>
+ <td align="right">vbd number</td>
+ <td></td>
+ <td> <input type="text" size="3" name="vbd"> </td>
+</tr>
+<tr>
+ <td align="right"></td>
+ <td></td>
+ <td> <input type="radio" name="mode" value="ro" checked>RO
+ <input type="radio" name="mode" value="rw">RW</td>
+</tr>
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="create virtual block device"></td>
+</tr>
+</table>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdcr.tmpl b/tools/control/web/tmpl/vd-vbdcr.tmpl
new file mode 100644
index 0000000000..78d1d74c6e
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdcr.tmpl
@@ -0,0 +1,44 @@
+Create Virtual Block Device
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<b>Create Virtual Block Device Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+%>
+output = <%= root.doCreateVirtualBlockDevice(hsrw.getParameter("vd"),
+ Integer.decode(hsrw.getParameter("domain")).intValue(),
+ Integer.decode(hsrw.getParameter("vbd")).intValue(),
+ hsrw.getParameter("mode"))
+ %>
+<br>
+vd = <%= hsrw.getParameter("vd") %>
+<br>
+domain = <%= hsrw.getParameter("domain") %>
+<br>
+vbd = <%= hsrw.getParameter("vbd") %>
+<br>
+mode = <%= hsrw.getParameter("mode") %>
+
+<%
+ root.doFlushState();
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdd.tmpl b/tools/control/web/tmpl/vd-vbdd.tmpl
new file mode 100644
index 0000000000..39b6163643
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdd.tmpl
@@ -0,0 +1,29 @@
+Delete Virtual Block Devices
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr><td>
+Not currently implemented.
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdf.tmpl b/tools/control/web/tmpl/vd-vbdf.tmpl
new file mode 100644
index 0000000000..5325fbb9ab
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdf.tmpl
@@ -0,0 +1,59 @@
+Flush Virtual Block Devices
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-vbdfr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr><td>
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>vd key</td><td>dom</td><td>vbd</td><td>mode</td></tr>
+
+ <%
+ for (Enumeration e = root.getVirtualBlockDevices(); e.hasMoreElements();)
+ {
+ VirtualBlockDevice vbd = (VirtualBlockDevice) e.nextElement();
+ %>
+ <tr class="vdt">
+ <td><%= vbd.getKey() %></td>
+ <td><%= vbd.getDomain() %></td>
+ <td><%= vbd.getVBDNum() %></td>
+ <td><%= vbd.getMode().toString() %></td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><font color="red">Warning, this will remove all virtual block devices</font></td>
+</tr>
+
+<tr>
+ <td><input type="submit" value="flush all vbds"></td>
+</tr>
+</form>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdfr.tmpl b/tools/control/web/tmpl/vd-vbdfr.tmpl
new file mode 100644
index 0000000000..566f4cb038
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdfr.tmpl
@@ -0,0 +1,32 @@
+Flush Virtual Block Devices
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<b>Flush Virtual Block Device Results</b>
+<br>
+
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+%>
+output = <%= root.doFlushVirtualBlockDevices() %>
+<%
+ root.doFlushState();
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vbdv.tmpl b/tools/control/web/tmpl/vd-vbdv.tmpl
new file mode 100644
index 0000000000..306372e2bb
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vbdv.tmpl
@@ -0,0 +1,44 @@
+View Virtual Block Devices
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>dom</td><td>vbd</td><td>mode</td><td>vd key</td><td>vd name</td></tr>
+
+
+ <%
+ for (Enumeration e = root.getVirtualBlockDevices(); e.hasMoreElements();)
+ {
+ VirtualBlockDevice vbd = (VirtualBlockDevice) e.nextElement();
+ VirtualDisk vd = root.getVirtualDiskKey(vbd.getKey());
+ %>
+ <tr class="vdt">
+ <td><%= vbd.getDomain() %></td>
+ <td><%= vbd.getVBDNum() %></td>
+ <td><%= vbd.getMode().toString() %></td>
+ <td><%= vbd.getKey() %></td>
+ <td><%= vd.getName() %></td>
+ </tr>
+ <%
+ }
+ %>
+</tbody>
+</table>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdc.tmpl b/tools/control/web/tmpl/vd-vdc.tmpl
new file mode 100644
index 0000000000..97a9276e50
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdc.tmpl
@@ -0,0 +1,67 @@
+Create New Virtual Disk
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-vdcr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr>
+ <td width="50"></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td align="right">name</td>
+ <td></td>
+ <td> <input type="text" size="40" name="name" value="name of disk"> </td>
+</tr>
+
+<tr>
+ <td align="right">size</td>
+ <td></td>
+ <td> <input type="text" size="10" name="size">
+ <input type="radio" name="sizeunits" value="mb" checked>MB
+ <input type="radio" name="sizeunits" value="gb">GB
+ </td>
+</tr>
+
+<tr>
+ <td align="right">expiry</td>
+ <td></td>
+ <td> <input type="text" size="3" name="expiry">
+ <input type="radio" name="expiryunits" value="d" checked>days
+ <input type="radio" name="expiryunits" value="w">weeks
+ <input type="radio" name="expiryunits" value="m">months
+ <input type="radio" name="expiryunits" value="y">years
+ </td>
+</tr>
+
+##WHITESPACE## ##GREYLINE3## ##WHITESPACE##
+
+<tr>
+ <td></td>
+ <td></td>
+ <td><input type="submit" name="action" value="create virtual disk"></td>
+</tr>
+
+</tbody>
+</table>
+</form>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdcr.tmpl b/tools/control/web/tmpl/vd-vdcr.tmpl
new file mode 100644
index 0000000000..85936cdd95
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdcr.tmpl
@@ -0,0 +1,64 @@
+Create New Virtual Disk
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+
+<b>Create Virtual Disk Results</b>
+<br>
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+ String size = hsrw.getParameter("size").trim() +
+ hsrw.getParameter("sizeunits").trim();
+ long expiry = Long.decode(hsrw.getParameter("expiry")).longValue();
+
+ /* not perfect, but good enough for now... */
+ if ( hsrw.getParameter("expiryunits").equals("d"))
+ {
+ expiry *= 24 * 60 * 60 * 1000;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("w"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 7;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("m"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 30;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("y"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 365;
+ }
+
+%>
+output = <%= root.doCreateVirtualDisk( hsrw.getParameter("name"),
+ size, expiry)
+ %>
+<br>
+size = <%= size %>
+<br>
+expiry = <%= hsrw.getParameter("expiry") %>
+<br>
+expiryunits = <%= hsrw.getParameter("expiryunits") %>
+<br>
+
+<%
+ root.doFlushState();
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdd.tmpl b/tools/control/web/tmpl/vd-vdd.tmpl
new file mode 100644
index 0000000000..920899b1b2
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdd.tmpl
@@ -0,0 +1,58 @@
+Delete Virtual Disk
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-vddr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>key</td><td width="5"></td><td>name</td><td width="5"></td><td>expiry</td></tr>
+
+ <%
+ int count = root.getVirtualDiskCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ VirtualDisk vd = root.getVirtualDisk(loop);
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="vd" value="<%= vd.getKey() %>"></td>
+ <td><%= vd.getKey() %></td>
+ <td></td>
+ <td><%= vd.getName() %></td>
+ <td></td>
+ <td><%= vd.getExpiry() %></td>
+ </tr>
+ <%
+ }
+ %>
+
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="delete virtual disk"></td>
+</tr>
+</table>
+</form>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vddr.tmpl b/tools/control/web/tmpl/vd-vddr.tmpl
new file mode 100644
index 0000000000..13925ebb8b
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vddr.tmpl
@@ -0,0 +1,34 @@
+Delete Virtual Disk
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<b>Delete Virtual Disk Results</b>
+<br>
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+%>
+
+vd= <%= hsrw.getParameter("vd") %>
+
+vd= <%= root.doDeleteVirtualDisk(hsrw.getParameter("vd")) %>
+
+<%
+ root.doFlushState();
+%>
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdr.tmpl b/tools/control/web/tmpl/vd-vdr.tmpl
new file mode 100644
index 0000000000..551d230ceb
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdr.tmpl
@@ -0,0 +1,83 @@
+Refresh Virtual Disk
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<form method="post" action="vd-vdrr.jsp">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr><td>
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td></td><td>key</td><td width="5"></td><td>name</td><td width="5"></td><td>expiry</td></tr>
+
+ <%
+ int count = root.getVirtualDiskCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ VirtualDisk vd = root.getVirtualDisk(loop);
+ %>
+ <tr class="vdt">
+ <td><input type="checkbox" name="vd" value="<%= vd.getKey() %>"></td>
+ <td><%= vd.getKey() %></td>
+ <td></td>
+ <td><%= vd.getName() %></td>
+ <td></td>
+ <td><%= vd.getExpiry() %></td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr><td>
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+
+<tr>
+ <td width="50"></td>
+ <td width="7"></td>
+ <td></td>
+</tr>
+
+<tr>
+ <td align="right">new<br>expiry</td>
+ <td></td>
+ <td> <input type="text" size="3" name="expiry">
+ <input type="radio" name="expiryunits" value="d" checked>days
+ <input type="radio" name="expiryunits" value="w">weeks
+ <input type="radio" name="expiryunits" value="m">months
+ <input type="radio" name="expiryunits" value="y">years
+ </td>
+</tr>
+</tbody>
+</table>
+</td></tr>
+
+##WHITESPACE## ##GREYLINE1## ##WHITESPACE##
+
+<tr>
+ <td><input type="submit" name="action" value="refresh expiry time"></td>
+</tr>
+</table>
+</form>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdrr.tmpl b/tools/control/web/tmpl/vd-vdrr.tmpl
new file mode 100644
index 0000000000..bf93429b26
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdrr.tmpl
@@ -0,0 +1,72 @@
+Refresh Virtual Disk Results
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<%
+ HttpServletRequestWrapper hsrw = new HttpServletRequestWrapper(request);
+
+ String vds[] = hsrw.getParameterValues("vd");
+ long expiry = Long.decode(hsrw.getParameter("expiry")).longValue();
+
+ /* not perfect, but good enough for now... */
+ if ( hsrw.getParameter("expiryunits").equals("d"))
+ {
+ expiry *= 24 * 60 * 60 * 1000;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("w"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 7;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("m"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 30;
+ }
+ else if ( hsrw.getParameter("expiryunits").equals("y"))
+ {
+ expiry *= 24 * 60 * 60 * 1000 * 365;
+ }
+
+ if (vds == null)
+ {
+%>
+no virtual disks selected.
+<%
+ }
+ else
+ {
+ for (int i = 0; i < vds.length; i++)
+ {
+%>
+vd = <%= root.doRefreshVirtualDisk(vds[i], expiry) %> <br>
+<%
+ }
+ }
+%>
+
+<br>
+expiry = <%= hsrw.getParameter("expiry") %>
+<br>
+expiryunits = <%= hsrw.getParameter("expiryunits") %>
+<br>
+
+<%
+ root.doFlushState();
+%>
+
+
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd-vdv.tmpl b/tools/control/web/tmpl/vd-vdv.tmpl
new file mode 100644
index 0000000000..e03cd6959f
--- /dev/null
+++ b/tools/control/web/tmpl/vd-vdv.tmpl
@@ -0,0 +1,43 @@
+View Virtual Disks
+SECTION&XenoServers
+BREADCRUMB&Virtual Disk Manager&vd.jsp
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+
+<table cellpadding="2" cellspacing="0" border="0">
+<tbody>
+ <tr class="vdh"><td>key</td><td width="5"></td><td>name</td><td width="5"></td><td>expiry</td></tr>
+
+ <%
+ int count = root.getVirtualDiskCount();
+ for (int loop = 0; loop < count; loop++)
+ {
+ VirtualDisk vd = root.getVirtualDisk(loop);
+ %>
+ <tr class="vdt">
+ <td><%= vd.getKey() %></td>
+ <td></td>
+ <td><%= vd.getName() %></td>
+ <td></td>
+ <td><%= vd.getExpiry() %></td>
+ </tr>
+ <%
+ }
+ %>
+
+</tbody>
+</table>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vd.tmpl b/tools/control/web/tmpl/vd.tmpl
new file mode 100644
index 0000000000..a21189966a
--- /dev/null
+++ b/tools/control/web/tmpl/vd.tmpl
@@ -0,0 +1,24 @@
+Virtual Disk Manager
+SECTION&XenoServers
+
+<!-- content -->
+<img src="pixel.gif" class="block" width="1" height="12">
+
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+INCLUDE&vdmenu.tmpl
+<td valign="top">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+ <tr><td nowrap="nowrap">Virtual Disk Manager</td></tr>
+
+</tbody>
+</table>
+</td>
+</tbody>
+</table>
+
+
+
+
+<!-- end content -->
diff --git a/tools/control/web/tmpl/vdmenu.tmpl b/tools/control/web/tmpl/vdmenu.tmpl
new file mode 100644
index 0000000000..20cb5ecf6f
--- /dev/null
+++ b/tools/control/web/tmpl/vdmenu.tmpl
@@ -0,0 +1,63 @@
+<td width="10" valign="top" align="right"></td>
+
+<td valign="top">
+<table cellpadding="0" cellspacing="0" border="0">
+<tbody>
+<tr>
+ <td class="menuheader" width="100">Partitions</td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-pv.jsp">View</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-pa.jsp">Add</a></td>
+</tr>
+##WHITESPACE##
+<tr>
+ <td class="menuheader" width="100">Virtual Disk</td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vdv.jsp">View</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vdc.jsp">Create</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vdd.jsp">Delete</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vdr.jsp">Refresh</a></td>
+</tr>
+##WHITESPACE##
+<tr>
+ <td class="menuheader" width="100">Free Space</td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-fv.jsp">View</a></td>
+</tr>
+##WHITESPACE##
+<tr>
+ <td class="menuheader" width="100">Virtual Block Device</td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vbdv.jsp">View</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vbdc.jsp">Create</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vbdd.jsp">Delete</a></td>
+</tr>
+<tr>
+ <td class="sidemenu" width="100"><a href="vd-vbdf.jsp">Flush</a></td>
+</tr>
+
+</tbody>
+</table>
+</td>
+
+<td width="5" valign="top" align="right"></td>
+
+<td bgcolor="#666666" width="2"><img src="img/pixel.gif" class="block" width="2" height="50"></td>
+
+<td width="15" valign="top" align="right"></td>
diff --git a/tools/control/web/tmpl/xenofoot.def b/tools/control/web/tmpl/xenofoot.def
new file mode 100644
index 0000000000..4653a78495
--- /dev/null
+++ b/tools/control/web/tmpl/xenofoot.def
@@ -0,0 +1,28 @@
+<!-- START OF STANDARD FOOTER-->
+</td>
+</tr></table>
+<!-- end body text -->
+
+<!-- footer -->
+<br />
+<table cellpadding="0" cellspacing="0" border="0" width="98%" summary="footer">
+<tr><td bgcolor="#0099cc" colspan="2"><img
+src="http://www.cl.cam.ac.uk/UoCCL/images/pixel.gif" class="block" width="1" height="4" border="0" alt="" /></td>
+</tr>
+<tr><td bgcolor="#cccccc" colspan="2"><img
+src="http://www.cl.cam.ac.uk/UoCCL/images/pixel.gif" class="block" width="1" height="2" border="0" alt="" /></td>
+</tr>
+
+<tr><td>
+<div class="footer">
+<!--Add Department name and email contact here-->
+<p>&copy; ##YEAR## ##COPYRIGHT##<br />
+<!-- Page last updated ##DATE## by ##OWNERNAME##</p> -->
+</div>
+</td>
+</tr>
+</table>
+
+<!-- end footer -->
+</body>
+</html>
diff --git a/tools/control/web/tmpl/xenohead.def b/tools/control/web/tmpl/xenohead.def
new file mode 100644
index 0000000000..843244a0ae
--- /dev/null
+++ b/tools/control/web/tmpl/xenohead.def
@@ -0,0 +1,82 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<jsp:useBean id="root" scope="application"
+ class="uk.ac.cam.cl.xeno.xenctl.RootBean" />
+<jsp:useBean id="sc" scope="application"
+ class="uk.ac.cam.cl.xeno.xenctl.SystemConfigurationBean" />
+<%@ page session="false" %>
+<%@ page import="uk.ac.cam.cl.xeno.xenctl.*" %>
+<%@ page import="uk.ac.cam.cl.xeno.domctl.*" %>
+<%@ page import="java.util.Enumeration" %>
+<%@ page import="javax.servlet.http.HttpServletRequestWrapper" %>
+
+<html lang="en">
+
+<!--
+ THIS FILE HAS BEEN AUTOMATICALLY GENERATED BY A PERL SCRIPT
+ THE SOURCE FILE HAS THE EXTENSION .tmpl
+-->
+
+
+<head>
+
+<title>##SECTION## ##SECTIONBREAK## ##TITLE## <%= root.getDebugCounter() %></title>
+
+<link rel="stylesheet" type="text/css" href="xenostyle.css">
+
+</head>
+
+<body bgcolor="#ffffff" text="#000000" link="#003399"
+ alink="#cc0000"vlink="#cc3333">
+
+<!-- header -->
+<table cellpadding="0" cellspacing="0" border="0" width="98%" summary="navigation bar">
+<tr>
+<td bgcolor="#0099cc" width="98%" ><img src="img/pixel.gif" class="block" width="1" height="16" alt="" border="0" /></td>
+<td align="right" width="212" rowspan="2" >
+<table cellpadding="0" cellspacing="0" border="0" width="##NAVIGATIONWIDTH##" summary="navigation bar insert">
+<tr>
+ ##NAVIGATIONSTRING##
+ <td><a href="help.jsp"><img src="img/help.gif" width="53" height="18" border="0" alt="Help" class="block" /></a></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td bgcolor="#cccccc" ><img src="img/pixel.gif" class="block"
+width="1" height="2" alt="" border="0" /></td>
+</tr>
+</table>
+<table cellpadding="0" cellspacing="0" border="0" width="98%" summary="departmental header">
+<tr>
+<td><a href="http://www.cam.ac.uk/"><img src="img/cambridge.gif" width="192"
+height="46" border="0" alt="University of Cambridge Home" /></a></td>
+
+<!--Departmental name in next cell-->
+<td align="right" valign="bottom" class="title">##SECTION##<br />##TITLE##</td>
+</tr>
+
+<tr><td bgcolor="#0099cc" colspan="3"><img
+src="img/pixel.gif" class="block" width="1" height="4" alt="" /></td>
+</tr>
+<tr><td bgcolor="#cccccc" colspan="3"><img
+src="img/pixel.gif" class="block" width="1" height="2" alt="" /></td>
+</tr>
+</table>
+<!-- end header -->
+
+<!-- breadcrumbs start -->
+<table cellpadding="0" cellspacing="0" border="0" width="98%" summary="breadcrumb navigation">
+<tr>
+<td><a href="index.jsp"class="bread">XenoServers</a>##BREADCRUMBS##</td>
+</tr>
+</table>
+<!-- end breadcrumbs -->
+
+<!-- body text -->
+<br />
+<!-- <h1>##TITLE##</h1> -->
+<table cellpadding="0" cellspacing="0" border="0" width="98%" summary="content panel">
+<tr>
+<td valign="top">
+<!-- END OF STANDARD HEADER-->
diff --git a/tools/control/web/tmpl/xenostyle.css b/tools/control/web/tmpl/xenostyle.css
new file mode 100644
index 0000000000..1681a55bb0
--- /dev/null
+++ b/tools/control/web/tmpl/xenostyle.css
@@ -0,0 +1,91 @@
+body {background-color: #ffffff; color: #000000;}
+
+p, ul, ol, li, table, td {font-family: Arial, Helvetica, sans-serif; }
+
+a {text-decoration:none;}
+a:link {color: #003399; font-family: Arial, Helvetica, sans-serif;}
+a:visited {color: #cc3333; font-family: Arial, Helvetica, sans-serif;}
+a:hover {text-decoration: underline; font-family: Arial, Helvetica, sans-serif;}
+a:active {color: #cc0000; font-family: Arial, Helvetica, sans-serif;}
+
+a.bread {font-size: 80%; font-weight: bold;}
+a.univbread {font-size: 90%; font-weight: bold;}
+p.small {font-size: 90%;}
+p.smallc {font-size: 90%; text-align:center; font-weight: bold;}
+p.foot {font-size: 110%; text-align:center;}
+p.nav {font-size: 80%;}
+span.activenav {font-size: 80%; color: #000000}
+
+.bigb {font-size: 110%; font-weight: bold;}
+.small {font-size: 90%;}
+.deptitle {font-size: 140%; color: #000000; font-weight: bold;}
+.deptitle {font-size: 120%; color: #000000; font-weight: bold;}
+.title {font-size: 130%; color: #990000; font-weight: bold;}
+.center {text-align:center;}
+div.footer {font-size: 80%;}
+
+h1 {font-weight: bold; font-size: 120%; color: #990000; font-family: Arial, Helvetica, sans-serif;}
+h2 {font-weight: bold; font-size: 110%; color: #333333; font-family: Arial, Helvetica, sans-serif;}
+h3 {font-weight: bold; font-style: italic; font-size: 100%; color: #333333; font-family: Arial, Helvetica, sans-serif;}
+h4 {font-weight: bold; font-size: 90%; color: #333333; font-family: Arial, Helvetica, sans-serif;}
+h5 {font-weight: bold; font-size: 80%; color: #333333; font-family: Arial, Helvetica, sans-serif;}
+
+
+/* netscape 6 correction */
+.null {font-size: 1px;}
+
+/* linux correction */
+.block {display: block;}
+
+
+/* home page */
+.homeheading {font-weight: bold; font-size: 80%; font-family: arial, helvetica, sans-serif; color: #990000;}
+
+a.homemenu {font-weight: bold; font-family: arial, helvetica, sans-serif;}
+a.homemenu2 {font-size: 80%; font-family: arial, helvetica, sans-serif;}
+
+p.homealert {font-size: 80%; color: #990000; font-family: arial, helvetica, sans-serif;}
+p.homenews {font-size: 80%; font-family: arial, helvetica, sans-serif;}
+
+
+<!--from admin styles-->
+.linkcell { background: #003399; color: #ffffff }
+a.cell { font-family: sans-serif; text-decoration:none }
+a.cell:link { color: #ffffff }
+a.cell:visited { color: #ffffff }
+a.cell:active { color: #ffff33 }
+
+
+.sidemenu {
+ /*font-weight : 400; */
+ /*font-size : 13px; */
+ /*line-height : 12px; */
+ /*font-family : Verdana, Arial, Helvetica, sans-serif, "MS sans serif"; */
+ /*letter-spacing : 0px; */
+ /*text-decoration : none; */
+ text-align : left;
+}
+
+.menuheader {
+ color : #003366;
+ font-weight : bold;
+ /*font-size : 13px; */
+ /*line-height : 15px; */
+ /*font-family : Verdana, Arial, Helvetica, sans-serif, "MS sans serif"; */
+ /*letter-spacing : -1px; */
+ text-decoration : none;
+ text-align : left;
+}
+
+.vdh {
+ background-color: #003366;
+ color : #ffffff;
+ font-weight : bold;
+ text-align : center;
+}
+.vdt {
+ background-color: #f0f0f0;
+}
+.vds {
+ background-color: #aaaaaa;
+}
diff --git a/tools/domctl/Makefile b/tools/domctl/Makefile
deleted file mode 100644
index 3d40b8fc5e..0000000000
--- a/tools/domctl/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-default:
- ant dist
-
-install: default
- cp domctl.jar domctl ../../../install/bin
- chmod 755 ../../../install/bin/domctl
-clean:
- ant clean
- rm -f domctl.jar
diff --git a/tools/internal/xi_helper b/tools/internal/xi_helper
new file mode 100755
index 0000000000..8c1f8e1eb1
--- /dev/null
+++ b/tools/internal/xi_helper
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+if [ -z "$QUERY_DEV" ] ; then QUERY_DEV=eth0 ; fi
+
+if [ "$1" = "ip" ] ; then
+ /sbin/ifconfig $QUERY_DEV | grep 'inet addr' | tr ':' '\t' | awk '{ print $3}';
+fi
+
+if [ "$1" = "mask" ] ; then
+ /sbin/ifconfig $QUERY_DEV | grep 'Mask' | tr ':' '\t' | awk '{print $7}';
+fi
+
+if [ "$1" = "route" ] ; then
+ /sbin/route -n | grep $QUERY_DEV | grep 'G' | awk '{print $2}'
+fi
diff --git a/tools/internal/xi_list b/tools/internal/xi_list
index bff4633f83..e90901818d 100755
--- a/tools/internal/xi_list
+++ b/tools/internal/xi_list
@@ -8,10 +8,11 @@
# 1. Domain id
# 2. Processor
# 3. Has CPU (1 => true, 0 => false)
-# 4. State (RUNNING, INTERRUPTABLE, UNINTERRUPTABLE, WAIT, SUSPENDED, DYING)
-# 5. MCU advance
-# 6. Total pages
-# 7. Name
+# 4. State (integer)
+# 5. State (RUNNING, INTERRUPTABLE, UNINTERRUPTABLE, WAIT, SUSPENDED, DYING)
+# 6. MCU advance
+# 7. Total pages
+# 8. Name
INPUT_FILE=/proc/xeno/domains
@@ -36,7 +37,7 @@ awk -f - $INPUT_FILE <<EOF
tot_pages = \$8;
- printf "%d %d %d %s %d %d %s", dom_id, processor, has_cpu, state, mcu_advance, tot_pages, \$9;
+ printf "%d %d %d %d %s %d %d %s", dom_id, processor, has_cpu, \$4, state, mcu_advance, tot_pages, \$9;
for (i = 10; i < NF; i ++) {
printf " %s", \$i;
}