aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortlh20@elite.cl.cam.ac.uk <tlh20@elite.cl.cam.ac.uk>2003-05-06 09:36:15 +0000
committertlh20@elite.cl.cam.ac.uk <tlh20@elite.cl.cam.ac.uk>2003-05-06 09:36:15 +0000
commitfd347f1b55d1a77969f2624f0063152568dabab0 (patch)
treee90591937b99940e1237421f9a6e047d5dbca521
parent5379a4b2d0213f3a323dc6c0340845b6353cd273 (diff)
downloadxen-fd347f1b55d1a77969f2624f0063152568dabab0.tar.gz
bitkeeper revision 1.206 (3eb7820fjxOimwW6NMSeo6KyAdqZUQ)
Many files: new file domctl, xi_ tools, updated domain builder, /proc/xeno/domains
-rwxr-xr-x.bk-to-hg2
-rwxr-xr-x.hg-to-bk2
-rw-r--r--.rootkeys26
-rw-r--r--BitKeeper/etc/logging_ok1
-rw-r--r--tools/domain_builder/dom_builder.c11
-rw-r--r--tools/domain_builder/dom_kill.c2
-rw-r--r--tools/domctl/Makefile5
-rw-r--r--tools/domctl/build.xml45
-rwxr-xr-xtools/domctl/domctl31
-rw-r--r--tools/domctl/domctl.xml15
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java74
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java69
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java58
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java203
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java63
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java64
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java153
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java60
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java39
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java38
-rw-r--r--tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java59
-rw-r--r--tools/internal/Makefile32
-rw-r--r--tools/internal/dom0_defs.h9
-rw-r--r--tools/internal/hypervisor_defs.h36
-rw-r--r--tools/internal/mem_defs.h45
-rw-r--r--tools/internal/xi_build.c524
-rw-r--r--tools/internal/xi_create.c98
-rw-r--r--tools/internal/xi_destroy.c81
-rw-r--r--tools/internal/xi_start.c80
-rw-r--r--tools/internal/xi_stop.c80
-rwxr-xr-xtools/internal/xi_vifinit25
-rw-r--r--xen/common/dom0_ops.c57
-rw-r--r--xen/common/domain.c23
-rw-r--r--xen/common/schedule.c1
-rw-r--r--xen/include/xeno/dom0_ops.h34
-rw-r--r--xen/include/xeno/sched.h7
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c105
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h39
38 files changed, 2271 insertions, 25 deletions
diff --git a/.bk-to-hg b/.bk-to-hg
index 1d83a2cea7..ee55de0843 100755
--- a/.bk-to-hg
+++ b/.bk-to-hg
@@ -2,5 +2,7 @@
set -e
test -L tools/domain_builder/dom0_ops.h
rm tools/domain_builder/dom0_ops.h
+test -L tools/internal/dom0_ops.h
+rm tools/internal/dom0_ops.h
(find -depth -type d -print | xargs -r rmdir 2>/dev/null) || true
exit 0
diff --git a/.hg-to-bk b/.hg-to-bk
index 9c6992a320..2bde703139 100755
--- a/.hg-to-bk
+++ b/.hg-to-bk
@@ -3,5 +3,7 @@ set -e
mkdir -p tools
mkdir -p tools/domain_builder
ln -s ../../xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h tools/domain_builder/dom0_ops.h
+mkdir -p tools/internal
+ln -s ../../xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h tools/internal/dom0_ops.h
(find -depth -type d -print | xargs -r rmdir 2>/dev/null) || true
exit 0
diff --git a/.rootkeys b/.rootkeys
index efe0d08fe2..92bdbddc82 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -15,6 +15,32 @@
3e71afadoAI0VvAGKebLpToVQxUKfQ tools/domain_builder/mynewdom
3e4d0046VHhXwFuG5FK34AVxqd5A_A tools/domain_builder/newdom
3e4d0046IBzDIeaMbQB-e2QB2ahbig tools/domain_builder/vifinit
+3eb781edFwm_pW9FwnQACIe68viLOw tools/domctl/Makefile
+3eb781fcTp_LPQwaot3SSSehkaf4eg tools/domctl/build.xml
+3eb781fcXf-WczEdAhnTpWfbR55jqA tools/domctl/domctl
+3eb781fcabCKRogwxJA3-jJKstw9Vg tools/domctl/domctl.xml
+3eb781fcffCXkrcWLBxUTOfQFa3Saw tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java
+3eb781fcOLcVAcqnZOAikur6sAP0rA tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
+3eb781fcQuQVSKxKtp4fBgPOwx7DDw tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
+3eb781fcRYdxK1HbjBX7r7VlO5PS0w tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
+3eb781fcbp9IAHTl40CoMavY1FNd_g tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
+3eb781fdRXSsyEre7LxCmPJMpB5BaQ tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
+3eb781fdX_thm9iHSxQ8vqQ0fL7Ncg tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
+3eb781fdTWJr8RPdfuG20IC0CzYL2A tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
+3eb781fdA8LFQEYE2fXg1JDB9OceYA tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java
+3eb781fd_CgRvlaIBkJjxUSnuvCuHQ tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java
+3eb781fdFDS4lap1-3ZVDtbKZfpVZA tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
+3eb781fdl4lXWYZzmqDDUAYhAThRqQ tools/internal/Makefile
+3eb781fdc539MQQm47rYRCCR3N5i-Q tools/internal/dom0_defs.h
+3eb781fdEYILyFg60YVBsWNqxWFf1g tools/internal/dom0_ops.h
+3eb781fddjylXbsepjppUyIXa5lcaQ tools/internal/hypervisor_defs.h
+3eb781fdKiQbgozBsgs_zzJQ9ubehw tools/internal/mem_defs.h
+3eb781fdgbSkh2O6JQS-65Dz4n0ItQ tools/internal/xi_build.c
+3eb781fdW1SAyiaC4mTsXq_9fRHh-A tools/internal/xi_create.c
+3eb781fdcJ0fF7rWfzAOArW-x4-gwA tools/internal/xi_destroy.c
+3eb781fd8oRfPgH7qTh7xvgmwD6NgA tools/internal/xi_start.c
+3eb781fd0Eo9K1jEFCSAVzO51i_ngg tools/internal/xi_stop.c
+3eb781fd7211MZsLxJSiuy7W4KnJXg tools/internal/xi_vifinit
3ea53c6dz47kAOwpk54f8_zOAQ5ngw tools/vdmanager/build.xml
3eaff785PwN0C3-xhCf_zMCL27JIgQ tools/vdmanager/notes.xml
3ea53c6dE-azH1i1VJmJMp9SHnETkQ tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Extent.java
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 9ec62d9ca9..9cc9e724e8 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -18,3 +18,4 @@ rn@wyvis.camb.intel-research.net
rn@wyvis.research.intel-research.net
smh22@boulderdash.cl.cam.ac.uk
smh22@uridium.cl.cam.ac.uk
+tlh20@elite.cl.cam.ac.uk
diff --git a/tools/domain_builder/dom_builder.c b/tools/domain_builder/dom_builder.c
index 13ee8d8735..d1cc68d704 100644
--- a/tools/domain_builder/dom_builder.c
+++ b/tools/domain_builder/dom_builder.c
@@ -49,7 +49,7 @@ static int do_kill_domain(int dom_id, int force)
dom0_op_t dop;
int cmd_fd;
- dop.cmd = DOM0_KILLDOMAIN;
+ dop.cmd = DOM0_DESTROYDOMAIN;
dop.u.killdomain.domain = dom_id;
dop.u.killdomain.force = force;
@@ -178,8 +178,9 @@ static dom0_newdomain_t * create_new_domain(long req_mem)
return 0;
}
- dop.cmd = DOM0_NEWDOMAIN;
+ dop.cmd = DOM0_CREATEDOMAIN;
dop.u.newdomain.memory_kb = req_mem;
+ dop.u.newdomain.name[0] = 0;
write(cmd_fd, &dop, sizeof(dom0_op_t));
close(cmd_fd);
@@ -435,7 +436,11 @@ static int launch_domain(dom_meminfo_t * meminfo)
return -1;
}
- dop.cmd = DOM0_STARTDOM;
+ dop.cmd = DOM0_BUILDDOMAIN;
+ memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+
+ dop.cmd = DOM0_STARTDOMAIN;
memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
write(cmd_fd, &dop, sizeof(dom0_op_t));
diff --git a/tools/domain_builder/dom_kill.c b/tools/domain_builder/dom_kill.c
index ddc0f8a4fd..b27fca9a58 100644
--- a/tools/domain_builder/dom_kill.c
+++ b/tools/domain_builder/dom_kill.c
@@ -21,7 +21,7 @@ static int do_kill_domain(int dom_id, int force)
dom0_op_t dop;
int cmd_fd;
- dop.cmd = DOM0_KILLDOMAIN;
+ dop.cmd = DOM0_DESTROYDOMAIN;
dop.u.killdomain.domain = dom_id;
dop.u.killdomain.force = force;
diff --git a/tools/domctl/Makefile b/tools/domctl/Makefile
new file mode 100644
index 0000000000..054fb95791
--- /dev/null
+++ b/tools/domctl/Makefile
@@ -0,0 +1,5 @@
+default:
+ ant dist
+
+clean:
+ ant clean
diff --git a/tools/domctl/build.xml b/tools/domctl/build.xml
new file mode 100644
index 0000000000..88d5ffb5b5
--- /dev/null
+++ b/tools/domctl/build.xml
@@ -0,0 +1,45 @@
+<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"/>
+
+ <target name="init">
+ <tstamp/>
+ <mkdir dir="${build}"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <javac srcdir="${src}" destdir="${build}" debug="on"/>
+ </target>
+
+ <target name="dist" depends="compile">
+ <jar jarfile="domctl.jar"
+ excludes="*~"
+ basedir="${build}">
+ <fileset dir="${src}" />
+ <fileset dir=".">
+ <include name="build.xml"/>
+ <include name="domctl"/>
+ </fileset>
+ <manifest>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Main-Class" value="uk.ac.cam.cl.xeno.domctl.Main"/>
+ <attribute name="Sealed" value="true"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test" depends="compile">
+ <java fork="true" classname="uk.ac.cam.cl.xeno.domctl.Main">
+ <classpath>
+ <pathelement path="${build}"/>
+ </classpath>
+ </java>
+ </target>
+
+ <target name="clean">
+ <delete dir="${build}"/>
+ <delete dir="${lib}"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/tools/domctl/domctl b/tools/domctl/domctl
new file mode 100755
index 0000000000..3f80d21176
--- /dev/null
+++ b/tools/domctl/domctl
@@ -0,0 +1,31 @@
+#!/bin/bash -x
+
+if [ -z "$DEFAULTS_FILE" ] ; then DEFAULTS_FILE=domctl.xml ; fi
+if [ -z "$DEFAULTS_PATH" ] ; then DEFAULTS_PATH=.:/etc ; 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
+if [ -z "$JAVA" ] ; then JAVA=java ; fi
+
+if [ ! -x "$IFCONFIG" ]; then
+ echo Could not find executable $IFCONFIG
+ exit 1
+fi
+
+if [ ! -x "$ROUTE" ]; then
+ echo Could not find executable $ROUTE
+ exit 1
+fi
+
+# Try to determine dom0 network settings to avoid hard-coding
+# particular machines in the defaults file
+LOCAL_IP=$(/sbin/ifconfig $QUERY_DEV | grep 'inet addr' | tr ':' '\t' | awk '{print $3}')
+LOCAL_MASK=$(/sbin/ifconfig $QUERY_DEV | grep 'Mask' | tr ':' '\t' | awk '{print $7}')
+LOCAL_ROUTE=$(/sbin/route -n | grep $QUERY_DEV | grep 'G' | awk '{print $2}')
+
+
+#ARGS="-DTEST -DDEFAULTS_FILE=$DEFAULTS_FILE -DDEFAULTS_PATH=$DEFAULTS_PATH -DLOCAL_IP=$LOCAL_IP -DLOCAL_MASK=$LOCAL_MASK -DLOCAL_ROUTE=$LOCAL_ROUTE"
+ARGS="-DDEFAULTS_FILE=$DEFAULTS_FILE -DDEFAULTS_PATH=$DEFAULTS_PATH -DLOCAL_IP=$LOCAL_IP -DLOCAL_MASK=$LOCAL_MASK -DLOCAL_ROUTE=$LOCAL_ROUTE"
+
+
+$JAVA $ARGS -jar domctl.jar $*
diff --git a/tools/domctl/domctl.xml b/tools/domctl/domctl.xml
new file mode 100644
index 0000000000..168b8da2fa
--- /dev/null
+++ b/tools/domctl/domctl.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<domctl_defaults>
+<domain_name>XenoLinux</domain_name>
+<domain_size_kb>16000</domain_size_kb>
+<domain_image>./image</domain_image>
+<domain_vifs>1</domain_vifs>
+<root_device>/dev/nfs</root_device>
+<nw_ip>=+</nw_ip>
+<nw_gw>=</nw_gw>
+<nw_mask>=</nw_mask>
+<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>2</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/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java
new file mode 100644
index 0000000000..b667e3f274
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Command.java
@@ -0,0 +1,74 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+public abstract class Command
+{
+ public abstract int doCommand(Defaults d, String args[]);
+ public abstract String getName();
+ public abstract String getUsage();
+ public abstract String getHelpText();
+
+ public String getStringParameter(String args[], char key, String def)
+ {
+ String r = getParameter (args, key);
+ return (r == null) ? def : r;
+ }
+
+ public int getIntParameter(String args[], char key, int def)
+ {
+ String r = getParameter (args, key);
+ return (r == null) ? def : (Integer.parseInt (r));
+ }
+
+ public boolean getFlagParameter(String args[], char key)
+ {
+ String r = getParameter (args, key);
+ return (r == null) ? false : true;
+ }
+
+ public String getParameter (String args[], char key)
+ {
+ int i;
+ String result = null;
+ for (i = 0; i < args.length; i ++)
+ {
+ if (args[i].startsWith("-" + key))
+ {
+ if (args[i].length() > 2)
+ {
+ result = args[i].substring(2, args[i].length());
+ }
+ else
+ {
+ result = "";
+ }
+ }
+ }
+ return result;
+ }
+
+ public int reportXIError (String message, String cmd_array[])
+ {
+ int i;
+ System.err.print (message + " using: ");
+ for (i = 0; i < cmd_array.length; i ++) {
+ System.err.print (cmd_array[i] + " ");
+ }
+ System.err.println();
+ return -1;
+ }
+
+ public int reportError (String message)
+ {
+ System.err.println (message);
+ return -1;
+ }
+
+ public void reportCommand (String cmd_array[])
+ {
+ int i;
+ for (i = 0; i < cmd_array.length; i ++) {
+ System.out.print (cmd_array[i] + " ");
+ }
+ System.out.println();
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
new file mode 100644
index 0000000000..025f373c50
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandDestroy.java
@@ -0,0 +1,69 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.io.*;
+import java.net.*;
+
+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;
+
+ if (domain_id == 0) {
+ System.err.println ("Expected -n<domain_id>");
+ rc = -1;
+ return rc;
+ }
+
+ try
+ {
+ Process destroy_p;
+ String destroy_cmdarray[] = force ? new String[3] : new String[2];
+ int destroy_rc;
+ int idx = 0;
+ destroy_cmdarray[idx++] = d.XIToolsDir + "xi_destroy";
+ if (force) {
+ destroy_cmdarray[idx++] = "-f";
+ }
+ destroy_cmdarray[idx++] = "" + domain_id;
+
+ if (Settings.TEST) {
+ reportCommand (destroy_cmdarray);
+ } else {
+ destroy_p = r.exec (destroy_cmdarray);
+ destroy_rc = destroy_p.waitFor ();
+
+ if (destroy_rc != 0) {
+ return reportXIError ("Could not destroy domain", destroy_cmdarray);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not destroy domain (" + e + ")");
+ e.printStackTrace ();
+ rc = -1;
+ }
+
+ return rc;
+ }
+
+ public String getName()
+ {
+ return "destroy";
+ }
+
+ public String getUsage()
+ {
+ return "[-f] [-n<domain_id>]";
+ }
+
+ public String getHelpText()
+ {
+ return
+ "Destory the specified domain. -f forcibly destroys it.";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
new file mode 100644
index 0000000000..aef1ee9473
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandHelp.java
@@ -0,0 +1,58 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+public class CommandHelp extends Command
+{
+ public int doCommand(Defaults d, String args[])
+ {
+ if (args.length <= 1)
+ {
+ System.out.println ("Usage:");
+ for (int i = 0; i < Main.commands.length; i ++)
+ {
+ String name = Main.commands[i].getName ();
+ String usage = Main.commands[i].getUsage ();
+ while (name.length() < 12) name = name + " ";
+ System.out.println (" " + name + usage);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < Main.commands.length; i ++)
+ {
+ String name = Main.commands[i].getName ();
+ String usage = Main.commands[i].getUsage ();
+ if (name.equals (args[1]))
+ {
+ doHelpFor (Main.commands[i]);
+ break;
+ }
+ }
+ }
+
+ System.out.println ("");
+ return 0;
+ }
+
+ public int doHelpFor (Command c)
+ {
+ System.out.println ("domctl " + c.getName() + " " + c.getUsage());
+ System.out.println ();
+ System.out.println (c.getHelpText ());
+ return 0;
+ }
+
+ public String getName()
+ {
+ return "help";
+ }
+
+ public String getUsage()
+ {
+ return "";
+ }
+
+ public String getHelpText()
+ {
+ return "This message";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
new file mode 100644
index 0000000000..1dd915686e
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandNew.java
@@ -0,0 +1,203 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.io.*;
+import java.net.*;
+
+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);
+ String initrd = getStringParameter (args, 'r', d.domainInitRD);
+ int vifs = getIntParameter(args, 'v', d.domainVIFs);
+ String bargs = getStringParameter (args, 'a', "");
+ String root_dev = getStringParameter (args, 'd', d.rootDevice);
+ String nfs_root_path = getStringParameter (args, 'f', d.NWNFSRoot);
+ String nw_ip = getStringParameter (args, '4', d.NWIP);
+ String nw_gw = getStringParameter (args, 'g', d.NWGW);
+ 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;
+ int domain_id;
+ DataInputStream dis;
+ int idx;
+ int i;
+
+
+ try
+ {
+ /* Some initial sanity checks */
+ if (root_dev.equals ("/dev/nfs") && (vifs == 0)) {
+ return reportError ("Cannot use NFS root without VIFs configured");
+ }
+
+ /* 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;
+ create_cmdarray[2] = name;
+ if (Settings.TEST) {
+ reportCommand (create_cmdarray);
+ domain_id=1;
+ create_rc=0;
+ } else {
+ create_p = r.exec (create_cmdarray);
+ dis = new DataInputStream (new BufferedInputStream (create_p.getInputStream ()));
+ domain_id = Integer.parseInt (dis.readLine ());
+ create_rc = create_p.waitFor ();
+ }
+
+ if (create_rc != 0) {
+ return reportXIError ("Failed to create domain", create_cmdarray);
+ } else if (domain_id > d.MaxDomainNumber) {
+ return reportError ("Cannot configure more than " +
+ d.MaxDomainNumber + " domains");
+ }
+
+ /* Set up boot parameters to pass to xi_build. */
+ bargs = "";
+
+ if (root_dev.equals ("/dev/nfs")) {
+ if (vifs == 0) {
+ return reportError ("Cannot use NFS root without VIFs configured");
+ }
+ bargs = (bargs +
+ "root=/dev/nfs " +
+ "nfsroot=" + StringPattern.parse(nfs_root_path).resolve(domain_id) +
+ " ");
+ } else {
+ bargs = ("root=" + StringPattern.parse(root_dev).resolve(domain_id) +
+ " ");
+
+ }
+
+ if (vifs > 0) {
+ domain_ip = InetAddressPattern.parse(nw_ip).resolve(domain_id);
+ if (nw_host == null) {
+ try {
+ nw_host = InetAddress.getByName(domain_ip).getHostName();
+ } catch (UnknownHostException uhe) {
+ nw_host = "" + nw_ip;
+ }
+
+ }
+ bargs = ("ip=" + domain_ip +
+ ":" + InetAddressPattern.parse(nw_nfs_server).resolve(domain_id) +
+ ":" + InetAddressPattern.parse(nw_gw).resolve(domain_id) +
+ ":" + InetAddressPattern.parse(nw_mask).resolve(domain_id) +
+ ":" + nw_host +
+ ":eth0:off " + bargs);
+ }
+
+ /* 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 ++)
+ build_cmdarray[i] = "";
+ build_cmdarray[idx ++] = d.XIToolsDir + "xi_build";
+ build_cmdarray[idx ++] = "" + domain_id;
+ build_cmdarray[idx ++] = "" + image;
+ build_cmdarray[idx ++] = "" + vifs;
+ if (initrd != null) build_cmdarray[idx ++] = "initrd=" + initrd;
+ build_cmdarray[idx ++] = "" + bargs;
+ System.out.println ("Build args: " + bargs);
+ if (Settings.TEST) {
+ reportCommand (build_cmdarray);
+ build_rc = 0;
+ } else {
+ build_p = r.exec (build_cmdarray);
+ build_rc = build_p.waitFor ();
+ }
+
+ if (build_rc != 0) {
+ return reportXIError ("Failed to build domain", build_cmdarray);
+ }
+
+
+ /* 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;
+ vifinit_cmdarray[2] = "0";
+ vifinit_cmdarray[3] = domain_ip;
+ if (Settings.TEST) {
+ reportCommand (vifinit_cmdarray);
+ vifinit_rc = 0;
+ } else {
+ vifinit_p = r.exec (vifinit_cmdarray);
+ vifinit_rc = vifinit_p.waitFor ();
+ }
+
+ if (vifinit_rc != 0) {
+ return reportXIError ("Failed to initialise VIF 0", vifinit_cmdarray);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not create new domain (" + e + ")");
+ e.printStackTrace ();
+ rc = -1;
+ }
+
+ return rc;
+ }
+
+ public String getName()
+ {
+ return "new";
+ }
+
+ public String getUsage()
+ {
+ return "[-n<domain_name>] [-k<size>] [-i<image>] [-v<num_vifs>] [-r<initrd>] [-d<root_device>] [-f<nfs_root>] [-s<nfs_boot_server>] [-4<ipv4_boot_address>] [-g<ipv4_boot_gateway>] [-m<ipv4_boot_netmask>] [-h<hostname>] [-a<args>]";
+ }
+
+ public String getHelpText()
+ {
+ return
+ "Create a new domain. Note that most of the parameters will assume\n" +
+ "default values: it should not be necessary to specify them all. See\n" +
+ "domctl.xml for the current default settings.\n" +
+ "\n" +
+ "General command line options:\n" +
+ " -n Domain name domain_name\n" +
+ " -k Domain size (kb) domain_size_kb\n" +
+ " -i Domain image name domain_image\n" +
+ " -v Number of VIFs domain_vifs\n" +
+ " -r InitRD (if required) domain_init_rd\n" +
+ " -d Root device (e.g /dev/nfs, /dev/hda3) root_device\n" +
+ " -a Additional boot parameters\n" +
+ "\n" +
+ "Networking options:\n" +
+ " -f NFS root (if /dev/nfs specified) nw_nfs_root\n" +
+ " -s NFS server nw_nfs_server\n" +
+ " -4 Domain IPv4 address nw_ip\n" +
+ " -g Domain gateway nw_gw\n" +
+ " -m Domain net mask nw_mask\n" +
+ " -h Domain hostname nw_host\n" +
+ "\n" +
+ "Parameters to -d, -f, -4, -g, -h can be specified as patterns into\n" +
+ "which the allocated domain ID will be incorporated. e.g. for\n" +
+ "domain 1 patterns would expand as follows:\n" +
+ "\n" +
+ " /dev/hda+ /dev/hda1\n" +
+ " /dev/hda7+ /dev/hda8\n" +
+ " 128.232.8.50+ 128.232.8.51\n" +
+ "\n" +
+ "Additionally, patterns for -4 -g -m can include an = which is\n" +
+ "expanded to the corresponding setting from the calling domain.\n";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
new file mode 100644
index 0000000000..b84b66d306
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStart.java
@@ -0,0 +1,63 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.io.*;
+import java.net.*;
+
+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;
+
+ if (domain_id == 0) {
+ System.err.println ("Expected -n<domain_id>");
+ rc = -1;
+ return rc;
+ }
+
+ try
+ {
+ Process start_p;
+ String start_cmdarray[] = new String[2];
+ int start_rc;
+ start_cmdarray[0] = d.XIToolsDir + "xi_start";
+ start_cmdarray[1] = "" + domain_id;
+
+ if (Settings.TEST) {
+ reportCommand (start_cmdarray);
+ } else {
+ start_p = r.exec (start_cmdarray);
+ start_rc = start_p.waitFor ();
+ if (start_rc != 0) {
+ return reportXIError ("Could not start domain", start_cmdarray);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not start new domain (" + e + ")");
+ e.printStackTrace ();
+ rc = -1;
+ }
+
+ return rc;
+ }
+
+ public String getName()
+ {
+ return "start";
+ }
+
+ public String getUsage()
+ {
+ return "[-n<domain_id>]";
+ }
+
+ public String getHelpText()
+ {
+ return
+ "Start the specified domain.";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
new file mode 100644
index 0000000000..c6b4cadd6c
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/CommandStop.java
@@ -0,0 +1,64 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.io.*;
+import java.net.*;
+
+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;
+
+ if (domain_id == 0) {
+ System.err.println ("Expected -n<domain_id>");
+ rc = -1;
+ return rc;
+ }
+
+ try
+ {
+ Process stop_p;
+ String stop_cmdarray[] = new String[2];
+ int stop_rc;
+ stop_cmdarray[0] = d.XIToolsDir + "xi_stop";
+ stop_cmdarray[1] = "" + domain_id;
+
+ if (Settings.TEST) {
+ reportCommand (stop_cmdarray);
+ } else {
+ stop_p = r.exec (stop_cmdarray);
+ stop_rc = stop_p.waitFor ();
+
+ if (stop_rc != 0) {
+ return reportXIError ("Could not stop domain", stop_cmdarray);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not stop new domain (" + e + ")");
+ e.printStackTrace ();
+ rc = -1;
+ }
+
+ return rc;
+ }
+
+ public String getName()
+ {
+ return "stop";
+ }
+
+ public String getUsage()
+ {
+ return "[-n<domain_id>]";
+ }
+
+ public String getHelpText()
+ {
+ return
+ "Stop the specified domain.";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
new file mode 100644
index 0000000000..bacce11a95
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Defaults.java
@@ -0,0 +1,153 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.net.InetAddress;
+import java.io.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+public class Defaults
+{
+ String domainName;
+
+ int domainSizeKB;
+ String domainImage;
+ String domainInitRD;
+ int domainVIFs;
+
+ String rootDevice;
+
+ String NWIP;
+ String NWGW;
+ String NWMask;
+ String NWHost;
+
+ String NWNFSServer;
+ String NWNFSRoot;
+
+ int MaxDomainNumber;
+
+ String XIToolsDir;
+
+ /***********************************************************************/
+
+ public Defaults ()
+ {
+ File f = Settings.getDefaultsFile ();
+ System.out.println ("f=" + f);
+
+ try
+ {
+ XMLReader xr = new org.apache.crimson.parser.XMLReaderImpl();
+ Handler handler = new Handler ();
+ xr.setContentHandler (handler);
+ xr.setErrorHandler (handler);
+ xr.parse (new InputSource(new FileReader (f)));
+ }
+ catch (Exception e)
+ {
+ System.err.println ("Could not read defaults file " + f +
+ "\nException: " + e);
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ System.out.println ("Domain defaults:");
+ System.out.println (" name " + domainName);
+ System.out.println (" size " + domainSizeKB);
+ System.out.println (" vifs " + domainVIFs);
+ System.out.println (" domainImage " + domainImage);
+ System.out.println (" domainInitRD " + domainInitRD);
+ System.out.println (" rootDevice " + rootDevice);
+ System.out.println (" NWIP " + NWIP);
+ System.out.println (" NWGW " + NWGW);
+ System.out.println (" NWMask " + NWMask);
+ System.out.println (" MaxDomainNumber " + MaxDomainNumber);
+ System.out.println (" NWNFSServer " + NWNFSServer);
+ System.out.println (" NWNFSRoot " + NWNFSRoot);
+ System.out.println (" XIToolsDir " + XIToolsDir);
+ }
+
+ /***********************************************************************/
+
+ class Handler extends DefaultHandler
+ {
+ boolean inDomctlDefaults;
+ String lastName;
+
+ public void startDocument ()
+ {
+ }
+
+ public void endDocument ()
+ {
+ }
+
+ public void startElement (String uri, String name,
+ String qname, Attributes atts)
+ {
+ if (qname.equals ("domctl_defaults")) {
+ inDomctlDefaults = true;
+ } else {
+ lastName = qname;
+ }
+ }
+
+ public void endElement (String uri, String name, String qname)
+ {
+ lastName = "";
+ if (qname.equals ("domctl_defaults")) {
+ inDomctlDefaults = false;
+ }
+ }
+
+ public void characters (char ch[], int start, int length)
+ {
+ String s = new String (ch, start, length);
+ if (lastName != null)
+ {
+ if (lastName.equals ("domain_size_kb")) {
+ domainSizeKB = Integer.parseInt (s);
+ } else if (lastName.equals ("domain_image")) {
+ domainImage = s;
+ } else if (lastName.equals ("domain_name")) {
+ domainName = s;
+ } else if (lastName.equals ("domain_init_rd")) {
+ domainInitRD = s;
+ } else if (lastName.equals ("domain_vifs")) {
+ domainVIFs = Integer.parseInt (s);
+ } else if (lastName.equals ("root_device")) {
+ rootDevice = s;
+ } else if (lastName.equals ("nw_ip")) {
+ NWIP = expandDefault (s, Settings.LOCAL_IP);
+ } else if (lastName.equals ("nw_gw")) {
+ NWGW = expandDefault (s, Settings.LOCAL_GW);
+ } else if (lastName.equals ("nw_mask")) {
+ NWMask = expandDefault (s, Settings.LOCAL_MASK);
+ } else if (lastName.equals ("nw_host")) {
+ NWHost = s;
+ } else if (lastName.equals ("nw_nfs_server")) {
+ NWNFSServer = s;
+ } else if (lastName.equals ("nw_nfs_root")) {
+ NWNFSRoot = s;
+ } else if (lastName.equals ("max_domain_number")) {
+ MaxDomainNumber = Integer.parseInt(s);
+ } else if (lastName.equals ("xi_tools_dir")) {
+ XIToolsDir = s;
+ }
+ }
+ }
+ }
+
+ public String expandDefault (String supplied, String self)
+ {
+ if (supplied.startsWith ("=")) {
+ if (supplied.length() > 1) {
+ return self + supplied.substring (1, supplied.length());
+ } else {
+ return self;
+ }
+ } else {
+ return supplied;
+ }
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
new file mode 100644
index 0000000000..5786edde71
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/InetAddressPattern.java
@@ -0,0 +1,60 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.net.*;
+
+public class InetAddressPattern
+{
+ InetAddress base;
+ boolean addDom;
+
+ static InetAddressPattern parse (String t)
+ {
+ InetAddressPattern result = new InetAddressPattern ();
+ char[] ca = t.toCharArray ();
+ int idx = 0;
+ int len = ca.length;
+
+ try {
+ if (len == 0) {
+ result.base = null;
+ result.addDom = false;
+ } else if (ca[len - 1] == '+') {
+ result.base = InetAddress.getByName(t.substring(0, len - 1));
+ result.addDom = true;
+ } else {
+ result.base = InetAddress.getByName(t);
+ result.addDom = false;
+ }
+ } catch (UnknownHostException uhe) {
+ result.base = null;
+ result.addDom = false;
+ }
+
+ return result;
+ }
+
+ public String resolve (int domain_id) {
+ byte b[] = base.getAddress ();
+ if (addDom) {
+ if (((int)b[3]) + domain_id > 255) {
+ if (((int)b[2]) + domain_id > 255) {
+ if (((int)b[1]) + domain_id > 255) {
+ b[0] ++;
+ }
+ b[1] ++;
+ }
+ b[2] ++;
+ }
+ b[3] += domain_id;
+ }
+ return "" +
+ (b[0] + (b[0] < 0 ? 256 : 0)) + "." +
+ (b[1] + (b[1] < 0 ? 256 : 0)) + "." +
+ (b[2] + (b[2] < 0 ? 256 : 0)) + "." +
+ (b[3] + (b[3] < 0 ? 256 : 0));
+ }
+
+ public String toString () {
+ return "[" + base + (addDom ? "+dom_id" : "") + "]";
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java
new file mode 100644
index 0000000000..49b4fb3c54
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Main.java
@@ -0,0 +1,39 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+public class Main
+{
+ static CommandHelp help = new CommandHelp ();
+ static CommandNew newdom = new CommandNew ();
+ static CommandStart start = new CommandStart ();
+ static CommandStop stop = new CommandStop ();
+ static CommandDestroy destroy = new CommandDestroy ();
+ static Command commands[] = { help, newdom, start, stop, destroy };
+
+ public static void main (String[] args)
+ {
+ Defaults d = new Defaults ();
+ int ec = -1;
+
+ if (args.length == 0) {
+ ec = help.doCommand (d, args);
+ } else {
+ String c = args[0];
+ int i;
+ for (i = 0; i < commands.length; i ++) {
+ if (commands[i].getName().equals(c)) {
+ if (commands[i].getFlagParameter (args, '?')) {
+ ec = help.doHelpFor (commands[i]);
+ } else {
+ ec = commands[i].doCommand (d, args);
+ }
+ break;
+ }
+ }
+ if (i == commands.length) {
+ System.out.println ("Unknown command " + c);
+ }
+ }
+
+ System.exit (ec);
+ }
+}
diff --git a/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java
new file mode 100644
index 0000000000..13d1a2d1df
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/Settings.java
@@ -0,0 +1,38 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+import java.util.*;
+import java.io.*;
+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 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 File getDefaultsFile() {
+ StringTokenizer tok = new StringTokenizer (DEFAULTS_PATH, ":");
+ File result = null;
+ File probe;
+
+ while (tok.hasMoreTokens ()) {
+ String probe_dir = tok.nextToken ();
+ probe = new File (probe_dir, DEFAULTS_FILE);
+ if (probe.exists ()) {
+ result = probe;
+ break;
+ }
+ }
+
+ 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/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
new file mode 100644
index 0000000000..a0486ba2be
--- /dev/null
+++ b/tools/domctl/src/uk/ac/cam/cl/xeno/domctl/StringPattern.java
@@ -0,0 +1,59 @@
+package uk.ac.cam.cl.xeno.domctl;
+
+public class StringPattern
+{
+ String base;
+ int bn;
+ boolean addDom;
+ boolean appendDom;
+
+ static StringPattern parse (String t)
+ {
+ StringPattern result = new StringPattern ();
+ char[] ca = t.toCharArray ();
+ int idx = 0;
+ int len = ca.length;
+
+ if (len == 0) {
+ result.base = "";
+ result.bn = 0;
+ result.addDom = false;
+ } else if (ca[len - 1] == '+') {
+ idx = len - 2;
+ if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+ while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+ idx --;
+ }
+ result.base = t.substring(0, idx + 1);
+ result.bn = Integer.parseInt (t.substring (idx + 1, len - 1));
+ result.addDom = true;
+ } else {
+ result.base = t.substring(0, len - 1);
+ result.appendDom = true;
+ }
+ } else {
+ result.base = t;
+ }
+
+ return result;
+ }
+
+ public String resolve (int domain_id) {
+ if (addDom) {
+ return base + (bn + domain_id);
+ } else if (appendDom) {
+ return base + domain_id;
+ } else {
+ return base;
+ }
+ }
+
+ public String toString () {
+ return ("[" +
+ base +
+ (addDom ? "+" + bn : "") +
+ ((addDom || appendDom) ? "+ID" : "") +
+ "]");
+ }
+
+}
diff --git a/tools/internal/Makefile b/tools/internal/Makefile
new file mode 100644
index 0000000000..d2e19221d1
--- /dev/null
+++ b/tools/internal/Makefile
@@ -0,0 +1,32 @@
+CC = gcc
+XI_CREATE = xi_create
+XI_START = xi_start
+XI_STOP = xi_stop
+XI_DESTROY = xi_destroy
+XI_BUILD = xi_build
+
+all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o
+ $(CC) -o $(XI_CREATE) $(XI_CREATE).o
+ $(CC) -o $(XI_BUILD) $(XI_BUILD).o
+ $(CC) -o $(XI_START) $(XI_START).o
+ $(CC) -o $(XI_STOP) $(XI_STOP).o
+ $(CC) -o $(XI_DESTROY) $(XI_DESTROY).o
+
+$(XI_CREATE).o: $(XI_CREATE).c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
+ $(CC) -c $(XI_CREATE).c
+
+internal_domain_build.o: internal_domain_build.c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
+ $(CC) -c internal_domain_build.c
+
+$(XI_START).o: $(XI_START).c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
+ $(CC) -c $(XI_START).c
+
+$(XI_STOP).o: $(XI_STOP).c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
+ $(CC) -c $(XI_STOP).c
+
+$(XI_DESTROY).o: $(XI_DESTROY).c dom0_ops.h dom0_defs.h
+ $(CC) -c $(XI_DESTROY).c
+
+clean:
+ $(RM) *.o $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD)
+
diff --git a/tools/internal/dom0_defs.h b/tools/internal/dom0_defs.h
new file mode 100644
index 0000000000..e79d85d417
--- /dev/null
+++ b/tools/internal/dom0_defs.h
@@ -0,0 +1,9 @@
+#define PROC_XENO_ROOT "xeno"
+#define PROC_CMD "dom0_cmd"
+#define PROC_DOM_PREFIX "dom"
+#define PROC_DOM_MEM "mem"
+#define PROC_DOM_DATA "new_dom_data"
+#define PROC_DOMAINS "domains"
+
+#define MAX_PATH 256
+
diff --git a/tools/internal/hypervisor_defs.h b/tools/internal/hypervisor_defs.h
new file mode 100644
index 0000000000..7d0aba03d7
--- /dev/null
+++ b/tools/internal/hypervisor_defs.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * hypervisor_defs.h
+ *
+ * This needs to be kept in sync with Xen's pagetable update interface!
+ *
+ * Copyright (c) 2002-2003, Keir Fraser & Boris Dragovic
+ */
+
+/* taken from include/hypervisor-ifs/hypervisor-if.h */
+typedef struct
+{
+/*
+ * PGREQ_XXX: specified in least-significant bits of 'ptr' field. All requests
+ * specify relevent PTE or PT address in 'ptr'. Normal requests specify update
+ * value in 'value'. Extended requests specify command in least 8 bits of
+ * 'value'.
+ */
+ unsigned long ptr, val; /* *ptr = val */
+} page_update_request_t;
+
+/* A normal page-table update request. */
+#define PGREQ_NORMAL 0
+#define PGREQ_MPT_UPDATE 1
+/* An extended command. */
+#define PGREQ_EXTENDED_COMMAND 2
+/* Announce a new top-level page table. */
+#define PGEXT_PIN_L1_TABLE 0
+#define PGEXT_PIN_L2_TABLE 1
+#define PGEXT_PIN_L3_TABLE 2
+#define PGEXT_PIN_L4_TABLE 3
+#define PGEXT_UNPIN_TABLE 4
+#define PGEXT_NEW_BASEPTR 5
+#define PGEXT_TLB_FLUSH 6
+#define PGEXT_INVLPG 7
+#define PGEXT_CMD_MASK 255
+#define PGEXT_CMD_SHIFT 8
diff --git a/tools/internal/mem_defs.h b/tools/internal/mem_defs.h
new file mode 100644
index 0000000000..a9a1441d61
--- /dev/null
+++ b/tools/internal/mem_defs.h
@@ -0,0 +1,45 @@
+/*
+ * memory related definitions needed for userspace domain builder dom0 application. these _need_ to
+ * be kept in sync with the kernel .h files they were copied over from or something horrible will
+ * happen. remmember: god kills a kitten every time you forget to keep these in sync.
+ *
+ * KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-)
+ *
+ * Copyright 2002 by B Dragovic
+ */
+
+/* copied over from hypervisor: include/asm-i386/page.h */
+
+#define _PAGE_PRESENT 0x001
+#define _PAGE_RW 0x002
+#define _PAGE_USER 0x004
+#define _PAGE_PWT 0x008
+#define _PAGE_PCD 0x010
+#define _PAGE_ACCESSED 0x020
+#define _PAGE_DIRTY 0x040
+#define _PAGE_PAT 0x080
+#define _PAGE_PSE 0x080
+#define _PAGE_GLOBAL 0x100
+
+
+#define L1_PAGETABLE_SHIFT 12
+#define L2_PAGETABLE_SHIFT 22
+
+#define ENTRIES_PER_L1_PAGETABLE 1024
+#define ENTRIES_PER_L2_PAGETABLE 1024
+
+#define PAGE_SHIFT L1_PAGETABLE_SHIFT
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+typedef struct { unsigned long l1_lo; } l1_pgentry_t;
+typedef struct { unsigned long l2_lo; } l2_pgentry_t;
+
+#define l1_table_offset(_a) \
+ (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
+#define l2_table_offset(_a) \
+ ((_a) >> L2_PAGETABLE_SHIFT)
+
+/* local definitions */
+
+#define nr_2_page(x) (x << PAGE_SHIFT)
diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c
new file mode 100644
index 0000000000..2df44f6532
--- /dev/null
+++ b/tools/internal/xi_build.c
@@ -0,0 +1,524 @@
+/*
+ * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
+ * This code is released under terms and conditions of GNU GPL :).
+ * Usage: <executable> <mem_kb> <os image> <num_vifs>
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "hypervisor_defs.h"
+#include "dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+#define PERR_STRING "Xeno Domain Builder"
+
+#define GUEST_SIG "XenoGues"
+#define SIG_LEN 8
+
+/*
+ * NB. No ring-3 access in initial guestOS pagetables. Note that we allow
+ * ring-3 privileges in the page directories, so that the guestOS may later
+ * decide to share a 4MB region with applications.
+ */
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+
+/* standardized error reporting function */
+static void dberr(char *msg)
+{
+ printf("%s: %s\n", PERR_STRING, msg);
+}
+
+/* status reporting function */
+static void dbstatus(char * msg)
+{
+ printf("Domain Builder: %s\n", msg);
+}
+
+
+/* clean up domain's memory allocations */
+static void dom_mem_cleanup(dom_mem_t * dom_mem)
+{
+ char mem_path[MAX_PATH];
+ int mem_fd;
+
+ /* open the domain's /proc mem interface */
+ sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/",
+ PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM);
+
+ mem_fd = open(mem_path, O_WRONLY);
+ if(mem_fd < 0){
+ perror(PERR_STRING);
+ }
+
+ if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){
+ dbstatus("Error unmapping domain's memory.\n");
+ }
+
+ close(mem_fd);
+}
+
+/* ask dom0 to export domains memory through /proc */
+static int setup_dom_memmap(unsigned long pfn, int pages, int dom)
+{
+ char cmd_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+
+ dop.cmd = MAP_DOM_MEM;
+ dop.u.dommem.start_pfn = pfn;
+ dop.u.dommem.tot_pages = pages;
+ dop.u.dommem.domain = dom;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ perror(PERR_STRING);
+ return -1;
+ }
+
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
+/* request the actual mapping from dom0 */
+static unsigned long get_vaddr(unsigned int dom)
+{
+ char mem_path[MAX_PATH];
+ unsigned long addr;
+ int mem_fd;
+
+ /* open the domain's /proc mem interface */
+ sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/",
+ PROC_DOM_PREFIX, dom, "/", PROC_DOM_MEM);
+
+ mem_fd = open(mem_path, O_RDONLY);
+ if(mem_fd < 0){
+ perror(PERR_STRING);
+ return 0;
+ }
+
+ /* get virtual address of mapped region */
+ read(mem_fd, &addr, sizeof(addr));
+
+ close(mem_fd);
+
+ return addr;
+}
+
+static int map_dom_mem(unsigned long pfn, int pages, int dom,
+ dom_mem_t * dom_mem)
+{
+
+ if(setup_dom_memmap(pfn, pages, dom)){
+ perror(PERR_STRING);
+ return -1;
+ }
+
+ dom_mem->domain = dom;
+ dom_mem->start_pfn = pfn;
+ dom_mem->tot_pages = pages;
+ if((dom_mem->vaddr = get_vaddr(dom)) == 0){
+ dberr("Error mapping dom memory.");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* open kernel image and do some sanity checks */
+static int do_kernel_chcks(char *image, long dom_size,
+ unsigned long * load_addr, size_t * ksize)
+{
+ char signature[8];
+ char status[MAX_PATH];
+ struct stat stat;
+ int fd;
+ int ret;
+
+ fd = open(image, O_RDONLY);
+ if(fd < 0){
+ perror(PERR_STRING);
+ ret = -1;
+ goto out;
+ }
+
+ if(fstat(fd, &stat) < 0){
+ perror(PERR_STRING);
+ ret = -1;
+ close(fd);
+ goto out;
+ }
+
+ if(stat.st_size > (dom_size << 10)){
+ sprintf(status, "Kernel image size %ld larger than requested "
+ "domain size %ld\n Terminated.\n", stat.st_size, dom_size);
+ dberr(status);
+ ret = -1;
+ close(fd);
+ goto out;
+ }
+
+ read(fd, signature, SIG_LEN);
+ if(strncmp(signature, GUEST_SIG, SIG_LEN)){
+ dberr("Kernel image does not contain required signature. "
+ "Terminating.\n");
+ ret = -1;
+ close(fd);
+ goto out;
+ }
+
+ read(fd, load_addr, sizeof(unsigned long));
+
+ *ksize = stat.st_size - SIG_LEN - sizeof(unsigned long);
+
+ ret = fd;
+
+out:
+ return ret;
+}
+
+/* this is the main guestos setup function,
+ * returnes domain descriptor structure to be used when launching
+ * the domain by hypervisor to do some last minute initialization.
+ * page table initialization is done by making a list of page table
+ * requests that are handeled by the hypervisor in the ordinary
+ * manner. this way, many potentially messy things are avoided...
+ */
+#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE)))
+static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
+ unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
+{
+ dom_meminfo_t *meminfo;
+ unsigned long *page_array;
+ page_update_request_t *pgt_updates;
+ dom_mem_t mem_map;
+ dom_meminfo_t *ret = NULL;
+ int alloc_index, num_pt_pages;
+ unsigned long l2tab;
+ unsigned long l1tab = 0;
+ unsigned long num_pgt_updates = 0;
+ unsigned long count, pt_start;
+ dom0_op_t pgupdate_req;
+ char cmd_path[MAX_PATH];
+ int cmd_fd;
+
+ meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
+ page_array = malloc(dom_mem->tot_pages * 4);
+ pgt_updates = (page_update_request_t *)dom_mem->vaddr;
+ alloc_index = dom_mem->tot_pages - 1;
+
+ memset(meminfo, 0, sizeof(meminfo));
+
+ memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
+
+ /* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
+ num_pt_pages =
+ (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024;
+
+ /* We must also count the page directory. */
+ num_pt_pages++;
+
+ /* Index of first PT page. */
+ pt_start = dom_mem->tot_pages - num_pt_pages;
+
+ /* first allocate page for page dir. allocation goes backwards from the
+ * end of the allocated physical address space.
+ */
+ l2tab = *(page_array + alloc_index) << PAGE_SHIFT;
+ memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
+ alloc_index--;
+ meminfo->l2_pgt_addr = l2tab;
+ meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages);
+
+ /* pin down l2tab addr as page dir page - causes hypervisor to provide
+ * correct protection for the page
+ */
+ pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND;
+ pgt_updates->val = PGEXT_PIN_L2_TABLE;
+ pgt_updates++;
+ num_pgt_updates++;
+
+ /*
+ * Initialise the page tables. The final iteration is for the shared_info
+ * PTE -- we break out before filling in the entry, as that is done by
+ * Xen during final setup.
+ */
+ l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
+ for ( count = 0; count < (dom_mem->tot_pages + 1); count++ )
+ {
+ if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
+ {
+ l1tab = *(page_array + alloc_index) << PAGE_SHIFT;
+ memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
+ alloc_index--;
+
+ l1tab += l1_table_offset(virt_load_addr + nr_2_page(count))
+ * sizeof(l1_pgentry_t);
+
+ /* make apropriate entry in the page directory */
+ pgt_updates->ptr = l2tab;
+ pgt_updates->val = l1tab | L2_PROT;
+ pgt_updates++;
+ num_pgt_updates++;
+ l2tab += sizeof(l2_pgentry_t);
+ }
+
+ /* The last PTE we consider is filled in later by Xen. */
+ if ( count == dom_mem->tot_pages ) break;
+
+ if ( count < pt_start )
+ {
+ pgt_updates->ptr = l1tab;
+ pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT;
+ pgt_updates++;
+ num_pgt_updates++;
+ l1tab += sizeof(l1_pgentry_t);
+ }
+ else
+ {
+ pgt_updates->ptr = l1tab;
+ pgt_updates->val =
+ ((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
+ pgt_updates++;
+ num_pgt_updates++;
+ l1tab += sizeof(l1_pgentry_t);
+ }
+
+ pgt_updates->ptr =
+ (*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
+ pgt_updates->val = count;
+ pgt_updates++;
+ num_pgt_updates++;
+ }
+
+ meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
+ meminfo->domain = dom;
+
+ /*
+ * Send the page update requests down to the hypervisor.
+ * NB. We must do this before loading the guest OS image!
+ */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out;
+ pgupdate_req.cmd = DO_PGUPDATES;
+ pgupdate_req.u.pgupdate.pgt_update_arr = (unsigned long)dom_mem->vaddr;
+ pgupdate_req.u.pgupdate.num_pgt_updates = num_pgt_updates;
+ write(cmd_fd, &pgupdate_req, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ /* Load the guest OS image. */
+ if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
+ {
+ dberr("Error reading kernel image, could not"
+ " read the whole image. Terminating.\n");
+ goto out;
+ }
+
+ if( initrd_fd )
+ {
+ struct stat stat;
+ unsigned long isize;
+
+ if(fstat(initrd_fd, &stat) < 0){
+ perror(PERR_STRING);
+ close(initrd_fd);
+ goto out;
+ }
+ isize = stat.st_size;
+
+ if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize )
+ {
+ dberr("Error reading initrd image, could not"
+ " read the whole image. Terminating.\n");
+ goto out;
+ }
+
+ meminfo->virt_mod_addr = virt_load_addr + ksize;
+ meminfo->virt_mod_len = isize;
+
+ }
+
+
+ ret = meminfo;
+out:
+
+ return ret;
+}
+
+static int launch_domain(dom_meminfo_t * meminfo)
+{
+ char cmd_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ perror(PERR_STRING);
+ return -1;
+ }
+
+ dop.cmd = DOM0_BUILDDOMAIN;
+ memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
+static int get_domain_info (int domain_id,
+ int *pg_head,
+ int *tot_pages)
+{
+ FILE *f;
+ char domains_path[MAX_PATH];
+ char domains_line[256];
+ int rc = -1;
+ int read_id;
+
+ sprintf (domains_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_DOMAINS
+);
+
+ f = fopen (domains_path, "r");
+ if (f == NULL) goto out;
+
+ read_id = -1;
+ while (fgets (domains_line, 256, f) != 0)
+ {
+ int trans;
+ trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id
+, pg_head, tot_pages);
+ if (trans == 3) {
+ if (read_id == domain_id) {
+ rc = 0;
+ break;
+ }
+ }
+ }
+
+ if (read_id == -1) {
+ errno = ESRCH;
+ }
+
+ fclose (f);
+
+ out:
+ return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+
+ dom_mem_t dom_os_image;
+ dom_mem_t dom_pgt;
+ dom_meminfo_t * meminfo;
+ size_t ksize;
+ unsigned long load_addr;
+ char status[1024];
+ int kernel_fd, initrd_fd = 0;
+ int count;
+ int cmd_len;
+ int rc = -1;
+ int args_start = 4;
+ char initrd_name[1024];
+ int domain_id;
+ int pg_head;
+ int tot_pages;
+
+ unsigned long addr;
+
+ /**** this argument parsing code is really _gross_. rewrite me! ****/
+
+ if(argc < 4) {
+ dberr("Usage: dom_builder <domain_id> <image> <num_vifs> "
+ "[<initrd=initrd_name>] <boot_params>\n");
+ return -1;
+ }
+
+ /* Look up information about the domain */
+ domain_id = atol(argv[1]);
+ if (get_domain_info (domain_id, &pg_head, &tot_pages) != 0) {
+ perror ("Could not find domain information");
+ rc = -1;
+ goto out;
+ }
+
+ kernel_fd = do_kernel_chcks(argv[2], tot_pages << (PAGE_SHIFT - 10), &load_addr, &ksize);
+ if(kernel_fd < 0)
+ return -1;
+
+
+ /* map domain's memory */
+ if(map_dom_mem(pg_head, tot_pages,
+ domain_id, &dom_os_image))
+ goto out;
+
+ if( strncmp("initrd=", argv[args_start], 7) == 0 )
+ {
+ strncpy( initrd_name, argv[args_start]+7, sizeof(initrd_name) );
+ initrd_name[sizeof(initrd_name)-1] = 0;
+ printf("initrd present, name = %s\n", initrd_name );
+ args_start++;
+
+ initrd_fd = open(initrd_name, O_RDONLY);
+ if(initrd_fd < 0){
+ perror(PERR_STRING);
+ goto out;
+ }
+ }
+
+ /* the following code does the actual domain building */
+ meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr,
+ ksize, &dom_os_image);
+
+ /* and unmap the new domain's memory image since we no longer need it */
+ dom_mem_cleanup(&dom_os_image);
+
+ if(!meminfo) {
+ printf("Domain Builder: debug: meminfo NULL\n");
+ goto out;
+ }
+
+ meminfo->virt_load_addr = load_addr;
+ meminfo->num_vifs = atoi(argv[3]);
+ meminfo->cmd_line[0] = '\0';
+ cmd_len = 0;
+ for(count = args_start; count < argc; count++){
+ if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){
+ dberr("Size of image boot params too big!\n");
+ break;
+ }
+ strcat(meminfo->cmd_line, argv[count]);
+ strcat(meminfo->cmd_line, " ");
+ cmd_len += strlen(argv[count] + 1);
+ }
+
+ /* sprintf(status,
+ "About to launch new domain %d with folowing parameters:\n"
+ " * page table base: %lx \n * load address: %lx \n"
+ " * shared info address: %lx \n * start info address: %lx \n"
+ " * number of vifs: %d \n * cmd line: %s \n", meminfo->domain,
+ meminfo->l2_pgt_addr, meminfo->virt_load_addr,
+ meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr,
+ meminfo->num_vifs, meminfo->cmd_line);
+ dbstatus(status);*/
+
+ /* and launch the domain */
+ rc = launch_domain(meminfo);
+
+out:
+ return rc;
+}
diff --git a/tools/internal/xi_create.c b/tools/internal/xi_create.c
new file mode 100644
index 0000000000..5162e27bba
--- /dev/null
+++ b/tools/internal/xi_create.c
@@ -0,0 +1,98 @@
+/*
+ * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
+ * This code is released under terms and conditions of GNU GPL :).
+ * Usage: <executable> <mem_kb> <os image> <num_vifs>
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "hypervisor_defs.h"
+#include "dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+/***********************************************************************/
+
+static char *argv0 = "internal_domain_create";
+
+static void ERROR (char *message)
+{
+ fprintf (stderr, "%s: %s\n", argv0, message);
+ exit (-1);
+}
+
+static void PERROR (char *message)
+{
+ fprintf (stderr, "%s: %s (%s)\n", argv0, message, sys_errlist[errno]);
+ exit (-1);
+}
+
+/***********************************************************************/
+
+static dom0_newdomain_t * create_new_domain(long req_mem, char *name)
+{
+ dom0_newdomain_t * dom_data;
+ char cmd_path[MAX_PATH];
+ char dom_id_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+ int id_fd;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ PERROR ("Could not open PROC_CMD interface");
+ return 0;
+ }
+
+ dop.cmd = DOM0_CREATEDOMAIN;
+ dop.u.newdomain.memory_kb = req_mem;
+ strncpy (dop.u.newdomain.name, name, MAX_DOMAIN_NAME - 1);
+ dop.u.newdomain.name[MAX_DOMAIN_NAME - 1] = 0;
+
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/",
+ PROC_DOM_DATA);
+ while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
+ dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
+ read(id_fd, dom_data, sizeof(dom0_newdomain_t));
+ close(id_fd);
+
+ return dom_data;
+}
+
+/***********************************************************************/
+
+int main(int argc, char **argv)
+{
+ dom0_newdomain_t * dom_data;
+
+ if (argv[0] != NULL)
+ {
+ argv0 = argv[0];
+ }
+
+ if(argc != 3)
+ {
+ fprintf (stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0);
+ return -1;
+ }
+
+ if(!(dom_data = create_new_domain(atol(argv[1]), argv[2])))
+ {
+ return -1;
+ }
+
+ fprintf (stdout, "%d\n", dom_data -> domain);
+ return 0;
+}
diff --git a/tools/internal/xi_destroy.c b/tools/internal/xi_destroy.c
new file mode 100644
index 0000000000..b262609165
--- /dev/null
+++ b/tools/internal/xi_destroy.c
@@ -0,0 +1,81 @@
+/*
+ * A very(!) simple program to kill a domain. (c) Boris Dragovic
+ * Usage: <executable> <mem_kb> <os image> <num_vifs>
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "dom0_ops.h"
+#include "dom0_defs.h"
+
+/***********************************************************************/
+
+static char *argv0 = "internal_domain_stop";
+
+static void ERROR (char *message)
+{
+ fprintf (stderr, "%s: %s\n", argv0, message);
+ exit (-1);
+}
+
+static void PERROR (char *message)
+{
+ fprintf (stderr, "%s: %s (%s)\n", argv0, message, sys_errlist[errno]);
+ exit (-1);
+}
+
+/***********************************************************************/
+
+static int do_kill_domain(int dom_id, int force)
+{
+ char cmd_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+
+ dop.cmd = DOM0_DESTROYDOMAIN;
+ dop.u.killdomain.domain = dom_id;
+ dop.u.killdomain.force = force;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ PERROR ("Count not open PROC_CMD interface");
+ }
+
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ if (argv[0] != NULL)
+ {
+ argv0 = argv[0];
+ }
+
+ if ( (argc < 2) || (argc > 3) )
+ {
+ usage:
+ fprintf(stderr, "Usage: %s [-f] <domain_id>\n", argv0);
+ fprintf(stderr, " -f: Forces immediate destruction of specified domain\n");
+ ret = -1;
+ goto out;
+ }
+
+ if ( (argc == 3) && strcmp("-f", argv[1]) ) goto usage;
+
+ ret = do_kill_domain(atoi(argv[argc-1]), argc == 3);
+
+out:
+ return ret;
+}
diff --git a/tools/internal/xi_start.c b/tools/internal/xi_start.c
new file mode 100644
index 0000000000..7c03180dcc
--- /dev/null
+++ b/tools/internal/xi_start.c
@@ -0,0 +1,80 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "hypervisor_defs.h"
+#include "dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+/***********************************************************************/
+
+static char *argv0 = "internal_domain_start";
+
+static void ERROR (char *message)
+{
+ fprintf (stderr, "%s: %s\n", argv0, message);
+ exit (-1);
+}
+
+static void PERROR (char *message)
+{
+ fprintf (stderr, "%s: %s (%s)\n", argv0, message, sys_errlist[errno]);
+ exit (-1);
+}
+
+/***********************************************************************/
+
+static int start_domain(int id)
+{
+ dom0_newdomain_t * dom_data;
+ char cmd_path[MAX_PATH];
+ char dom_id_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+ int id_fd;
+
+ /* Set up the DOM0_STARTDOMAIN command */
+ dop.cmd = DOM0_STARTDOMAIN;
+ dop.u.meminfo.domain = id;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ PERROR ("Count not open PROC_CMD interface");
+ }
+
+ /* Issue the command */
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
+/***********************************************************************/
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ if (argv[0] != NULL)
+ {
+ argv0 = argv[0];
+ }
+
+ if(argc != 2)
+ {
+ fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
+ return -1;
+ }
+
+ rc = start_domain(atol(argv[1]));
+
+ return rc;
+}
diff --git a/tools/internal/xi_stop.c b/tools/internal/xi_stop.c
new file mode 100644
index 0000000000..cbed24d867
--- /dev/null
+++ b/tools/internal/xi_stop.c
@@ -0,0 +1,80 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "hypervisor_defs.h"
+#include "dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+/***********************************************************************/
+
+static char *argv0 = "internal_domain_stop";
+
+static void ERROR (char *message)
+{
+ fprintf (stderr, "%s: %s\n", argv0, message);
+ exit (-1);
+}
+
+static void PERROR (char *message)
+{
+ fprintf (stderr, "%s: %s (%s)\n", argv0, message, sys_errlist[errno]);
+ exit (-1);
+}
+
+/***********************************************************************/
+
+static int stop_domain(int id)
+{
+ dom0_newdomain_t * dom_data;
+ char cmd_path[MAX_PATH];
+ char dom_id_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+ int id_fd;
+
+ /* Set up the DOM0_STOPDOMAIN command */
+ dop.cmd = DOM0_STOPDOMAIN;
+ dop.u.meminfo.domain = id;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ PERROR ("Count not open PROC_CMD interface");
+ }
+
+ /* Issue the command */
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
+/***********************************************************************/
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ if (argv[0] != NULL)
+ {
+ argv0 = argv[0];
+ }
+
+ if(argc != 2)
+ {
+ fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
+ return -1;
+ }
+
+ rc = stop_domain(atol(argv[1]));
+
+ return rc;
+}
diff --git a/tools/internal/xi_vifinit b/tools/internal/xi_vifinit
new file mode 100755
index 0000000000..feac666bb6
--- /dev/null
+++ b/tools/internal/xi_vifinit
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# vifinit
+#
+# This is a silly little script to dump a couple of simple rules down to
+# the hypervisor to assign a full static IP to a given virtual interface.
+#
+# Usage is:
+#
+# vifinit [vif dom] [vif idx] [dotted decimal ip address]
+#
+if [ $# -ne 3 ] ;
+then
+ echo "usage: $0 <domain_id> <vid_ifx> <dotted_decimal_ip_address>"
+ exit
+fi
+
+#outbound rule:
+echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/vfr
+
+#inbound rule:
+echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/vfr
+
+#----] done.
+
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
index 3ac6e72c0f..fb8d44429e 100644
--- a/xen/common/dom0_ops.c
+++ b/xen/common/dom0_ops.c
@@ -62,11 +62,19 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
switch ( op.cmd )
{
- case DOM0_STARTDOM:
+ case DOM0_BUILDDOMAIN:
{
struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
if ( (ret = final_setup_guestos(p, &op.u.meminfo)) != 0 )
break;
+ ret = p->domain;
+ free_task_struct(p);
+ }
+ break;
+
+ case DOM0_STARTDOMAIN:
+ {
+ struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
wake_up(p);
reschedule(p);
ret = p->domain;
@@ -74,7 +82,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
- case DOM0_NEWDOMAIN:
+ case DOM0_STOPDOMAIN:
+ {
+ ret = stop_other_domain (op.u.meminfo.domain);
+ }
+ break;
+
+ case DOM0_CREATEDOMAIN:
{
struct task_struct *p;
static unsigned int pro = 0;
@@ -89,6 +103,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
if ( p == NULL )
break;
+ if (op.u.newdomain.name[0]) {
+ strncpy (p -> name, op.u.newdomain.name, MAX_DOMAIN_NAME);
+ p -> name[MAX_DOMAIN_NAME - 1] = 0;
+ }
+
ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
if ( ret != 0 )
{
@@ -108,7 +127,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
- case DOM0_KILLDOMAIN:
+ case DOM0_DESTROYDOMAIN:
{
unsigned int dom = op.u.killdomain.domain;
int force = op.u.killdomain.force;
@@ -168,6 +187,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
+ case DOM0_GETDOMAININFO:
+ {
+ struct task_struct *p;
+ u_long flags;
+
+ p = idle0_task.next_task;
+ read_lock_irqsave (&tasklist_lock, flags);
+ do {
+ if ((!is_idle_task (p)) && (p -> domain >= op.u.getdominfo.domain)) {
+ break;
+ }
+ } while ((p = p -> next_task) != &idle0_task);
+
+ if (p == &idle0_task) {
+ ret = -ESRCH;
+ } else {
+ op.u.getdominfo.domain = p -> domain;
+ strcpy (op.u.getdominfo.name, p -> name);
+ op.u.getdominfo.processor = p -> processor;
+ op.u.getdominfo.has_cpu = p -> has_cpu;
+ op.u.getdominfo.state = p -> state;
+ op.u.getdominfo.hyp_events = p -> hyp_events;
+ op.u.getdominfo.mcu_advance = p -> mcu_advance;
+ op.u.getdominfo.pg_head = list_entry(p->pg_head.next,
+ struct pfn_info, list) - frame_table;
+ op.u.getdominfo.tot_pages = p -> tot_pages;
+ }
+ read_unlock_irqrestore (&tasklist_lock, flags);
+ copy_to_user(u_dom0_op, &op, sizeof(op));
+ break;
+ }
+
default:
ret = -ENOSYS;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f54e7c9d67..35154baf37 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -175,6 +175,29 @@ long kill_other_domain(unsigned int dom, int force)
return 0;
}
+void stop_domain(void)
+{
+ current -> state = TASK_SUSPENDED;
+ clear_bit(_HYP_EVENT_STOP, &(current->hyp_events));
+ schedule ();
+}
+
+long stop_other_domain(unsigned int dom)
+{
+ unsigned long cpu_mask;
+ struct task_struct *p;
+
+ p = find_domain_by_id (dom);
+ if ( p == NULL) return -ESRCH;
+
+ if ( p -> state != TASK_SUSPENDED )
+ {
+ cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP);
+ hyp_event_notify(cpu_mask);
+ }
+
+ return 0;
+}
unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes)
{
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 5749d27d4a..6536bf1ba5 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -349,6 +349,7 @@ asmlinkage void schedule(void)
case TASK_UNINTERRUPTIBLE:
case TASK_WAIT:
case TASK_DYING:
+ case TASK_SUSPENDED:
default:
/* done if not running. Else, continue */
goto deschedule_done;
diff --git a/xen/include/xeno/dom0_ops.h b/xen/include/xeno/dom0_ops.h
index ea3f829d73..8737e192aa 100644
--- a/xen/include/xeno/dom0_ops.h
+++ b/xen/include/xeno/dom0_ops.h
@@ -12,14 +12,18 @@
#ifndef __DOM0_OPS_H__
#define __DOM0_OPS_H__
-#define DOM0_NEWDOMAIN 0
-#define DOM0_KILLDOMAIN 1
-#define DOM0_GETMEMLIST 2
-#define DOM0_STARTDOM 4
-#define DOM0_BVTCTL 6
-#define DOM0_ADJUSTDOM 7
+#define DOM0_GETMEMLIST 2
+#define DOM0_BVTCTL 6
+#define DOM0_ADJUSTDOM 7
+#define DOM0_CREATEDOMAIN 8
+#define DOM0_DESTROYDOMAIN 9
+#define DOM0_STARTDOMAIN 10
+#define DOM0_STOPDOMAIN 11
+#define DOM0_GETDOMAININFO 12
+#define DOM0_BUILDDOMAIN 13
#define MAX_CMD_LEN 256
+#define MAX_DOMAIN_NAME 16
typedef struct dom0_newdomain_st
{
@@ -27,6 +31,7 @@ typedef struct dom0_newdomain_st
unsigned int memory_kb;
unsigned int num_vifs; // temporary
unsigned long pg_head; // return parameter
+ char name[MAX_DOMAIN_NAME];
} dom0_newdomain_t;
typedef struct dom0_killdomain_st
@@ -69,6 +74,20 @@ typedef struct dom0_adjustdom_st
unsigned long warpu; /* unwarp time requirement */
} dom0_adjustdom_t;
+typedef struct dom0_getdominfo_st
+{
+ unsigned int domain; /* All returns except domain */
+ char name[MAX_DOMAIN_NAME];
+ int processor;
+ int has_cpu;
+ int state;
+ int hyp_events;
+ unsigned long mcu_advance;
+ unsigned long pg_head;
+ unsigned int tot_pages;
+} dom0_getdominfo_t;
+
+
typedef struct dom0_op_st
{
unsigned long cmd;
@@ -80,7 +99,8 @@ typedef struct dom0_op_st
dom0_bvtctl_t bvtctl;
dom0_adjustdom_t adjustdom;
dom_meminfo_t meminfo;
- }
+ dom0_getdominfo_t getdominfo;
+ }
u;
} dom0_op_t;
diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h
index d29c7f9e49..fe4c49736e 100644
--- a/xen/include/xeno/sched.h
+++ b/xen/include/xeno/sched.h
@@ -16,6 +16,8 @@
#include <xeno/time.h>
#include <xeno/ac_timer.h>
+#define MAX_DOMAIN_NAME 16
+
extern unsigned long volatile jiffies;
extern rwlock_t tasklist_lock;
@@ -51,6 +53,7 @@ extern struct mm_struct init_mm;
#define _HYP_EVENT_NEED_RESCHED 0
#define _HYP_EVENT_DIE 1
+#define _HYP_EVENT_STOP 2
#define PF_DONEFPUINIT 0x1 /* Has the FPU been initialised for this task? */
#define PF_USEDFPU 0x2 /* Has this task used the FPU since last save? */
@@ -141,6 +144,8 @@ struct task_struct
0-0xFFFFFFFF for kernel-thread
*/
+ char name[MAX_DOMAIN_NAME];
+
/*
* active_mm stays for now. It's entangled in the tricky TLB flushing
* stuff which I haven't addressed yet. It stays until I'm man enough
@@ -223,6 +228,8 @@ extern void __kill_domain(struct task_struct *p);
extern void kill_domain(void);
extern void kill_domain_with_errmsg(const char *err);
extern long kill_other_domain(unsigned int dom, int force);
+extern void stop_domain(void);
+extern long stop_other_domain(unsigned int dom);
/* arch/process.c */
void new_thread(struct task_struct *p,
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
index d3e4752eb3..4f03fda0e2 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
@@ -23,6 +23,7 @@
#include <linux/iobuf.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
+#include <linux/seq_file.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
@@ -31,6 +32,9 @@
#include "dom0_ops.h"
+#define TRUE 1
+#define FALSE 0
+
/* Private proc-file data structures. */
typedef struct proc_data {
unsigned int domain;
@@ -45,6 +49,7 @@ typedef struct proc_mem_data {
#define XENO_BASE "xeno"
#define DOM0_CMD_INTF "dom0_cmd"
#define DOM0_NEWDOM "new_dom_data"
+#define DOM_LIST_INTF "domains"
#define MAX_LEN 16
#define DOM_DIR "dom"
@@ -56,6 +61,7 @@ typedef struct proc_mem_data {
struct proc_dir_entry *xeno_base;
static struct proc_dir_entry *dom0_cmd_intf;
static struct proc_dir_entry *proc_ft;
+static struct proc_dir_entry *dom_list_intf;
unsigned long direct_mmap(unsigned long, unsigned long, pgprot_t, int, int);
int direct_unmap(unsigned long, unsigned long);
@@ -266,7 +272,7 @@ static int cmd_write_proc(struct file *file, const char *buffer,
ret = HYPERVISOR_dom0_op(&op);
/* if new domain created, create proc entries */
- if(op.cmd == DOM0_NEWDOMAIN){
+ if(op.cmd == DOM0_CREATEDOMAIN) {
create_proc_dom_entries(ret);
params = (dom0_newdomain_t *)kmalloc(sizeof(dom0_newdomain_t),
@@ -295,6 +301,94 @@ out:
}
+/***********************************************************************
+ *
+ * Implementation of /proc/xeno/domains
+ */
+
+static dom0_op_t proc_domains_op;
+static int proc_domains_finished;
+static rwlock_t proc_xeno_domains_lock = RW_LOCK_UNLOCKED;
+
+static void *xeno_domains_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ int ret;
+
+ if (pos != NULL) { ++ (*pos); }
+ if (!proc_domains_finished) {
+ proc_domains_op.u.getdominfo.domain ++;
+ ret = HYPERVISOR_dom0_op(&proc_domains_op);
+ if (ret < 0) proc_domains_finished = TRUE;
+ }
+
+ return (proc_domains_finished) ? NULL : &proc_domains_op;
+}
+
+static void *xeno_domains_start(struct seq_file *s, loff_t *ppos)
+{
+ loff_t pos = *ppos;
+
+ write_lock (&proc_xeno_domains_lock);
+ proc_domains_op.cmd = DOM0_GETDOMAININFO;
+ proc_domains_op.u.getdominfo.domain = 0;
+ (void)HYPERVISOR_dom0_op(&proc_domains_op);
+ proc_domains_finished = FALSE;
+
+ while (pos > 0) {
+ pos --;
+ xeno_domains_next (s, NULL, NULL);
+ }
+
+ return (proc_domains_finished) ? NULL : &proc_domains_op;
+}
+
+static void xeno_domains_stop(struct seq_file *s, void *v)
+{
+ write_unlock (&proc_xeno_domains_lock);
+}
+
+static int xeno_domains_show(struct seq_file *s, void *v)
+{
+ dom0_op_t *di = v;
+
+ seq_printf (s,
+ "%8d %2d %1d %2d %8d %8ld %p %8d %s\n",
+ di -> u.getdominfo.domain,
+ di -> u.getdominfo.processor,
+ di -> u.getdominfo.has_cpu,
+ di -> u.getdominfo.state,
+ di -> u.getdominfo.hyp_events,
+ di -> u.getdominfo.mcu_advance,
+ di -> u.getdominfo.pg_head,
+ di -> u.getdominfo.tot_pages,
+ di -> u.getdominfo.name);
+
+ return 0;
+}
+
+struct seq_operations xeno_domains_op = {
+ .start = xeno_domains_start,
+ .next = xeno_domains_next,
+ .stop = xeno_domains_stop,
+ .show = xeno_domains_show,
+};
+
+static int xeno_domains_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &xeno_domains_op);
+}
+
+static struct file_operations proc_xeno_domains_operations = {
+ open: xeno_domains_open,
+ read: seq_read,
+ llseek: seq_lseek,
+ release: seq_release,
+};
+
+/***********************************************************************/
+
+
+
static int __init init_module(void)
{
/* xeno proc root setup */
@@ -311,6 +405,15 @@ static int __init init_module(void)
dom0_cmd_intf->write_proc = cmd_write_proc;
}
+ /* domain list interface */
+ dom_list_intf = create_proc_entry (DOM_LIST_INTF, 0400, xeno_base);
+ if ( dom_list_intf != NULL )
+ {
+ dom_list_intf -> owner = THIS_MODULE;
+ dom_list_intf -> nlink = 1;
+ dom_list_intf -> proc_fops = &proc_xeno_domains_operations;
+ }
+
/* set up /proc entries for dom 0 */
create_proc_dom_entries(0);
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h
index 74c9b24de7..1a5b63dad2 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_ops.h
@@ -9,17 +9,21 @@
* MUST BE KEPT IN SYNC WITH tools/domain_builder/dom0_ops.h
*/
-#define DOM0_NEWDOMAIN 0
-#define DOM0_KILLDOMAIN 1
-#define DOM0_GETMEMLIST 2
-#define DOM0_STARTDOM 4
-#define DOM0_BVTCTL 6
-#define DOM0_ADJUSTDOM 7
-#define MAP_DOM_MEM 8 /* Not passed down to Xen */
-#define DO_PGUPDATES 9 /* Not passed down to Xen */
-#define MAX_CMD 10
+#define DOM0_GETMEMLIST 2
+#define DOM0_BVTCTL 6
+#define DOM0_ADJUSTDOM 7
+#define DOM0_CREATEDOMAIN 8
+#define DOM0_DESTROYDOMAIN 9
+#define DOM0_STARTDOMAIN 10
+#define DOM0_STOPDOMAIN 11
+#define DOM0_GETDOMAININFO 12
+#define DOM0_BUILDDOMAIN 13
+#define MAP_DOM_MEM 14 /* Not passed down to Xen */
+#define DO_PGUPDATES 15 /* Not passed down to Xen */
+#define MAX_CMD 16
#define MAX_CMD_LEN 256
+#define MAX_DOMAIN_NAME 16
typedef struct dom0_newdomain_st
{
@@ -27,6 +31,7 @@ typedef struct dom0_newdomain_st
unsigned int memory_kb;
unsigned int num_vifs; /* temporary */
unsigned long pg_head; /* return parameter */
+ char name[MAX_DOMAIN_NAME];
} dom0_newdomain_t;
typedef struct dom0_killdomain_st
@@ -86,6 +91,19 @@ typedef struct domain_launch
} dom_meminfo_t;
+typedef struct dom0_getdominfo_st
+{
+ unsigned int domain; /* All returns except domain */
+ char name[MAX_DOMAIN_NAME];
+ int processor;
+ int has_cpu;
+ int state;
+ int hyp_events;
+ unsigned long mcu_advance;
+ unsigned long pg_head;
+ unsigned int tot_pages;
+} dom0_getdominfo_t;
+
typedef struct dom0_op_st
{
@@ -100,7 +118,8 @@ typedef struct dom0_op_st
dom_mem_t dommem;
dom_pgupdate_t pgupdate;
dom_meminfo_t meminfo;
- }
+ dom0_getdominfo_t getdominfo;
+ }
u;
} dom0_op_t;