aboutsummaryrefslogtreecommitdiffstats
path: root/tools/control
diff options
context:
space:
mode:
authorrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>2003-07-07 14:44:50 +0000
committerrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>2003-07-07 14:44:50 +0000
commit93c6f36102ca2579a58b99e7ab9095b525336795 (patch)
tree285e697ee33d7bad7a4db0d4fd1d07da4a8ad667 /tools/control
parent928d168337ac6e13d43b67e95160a90af91c3d64 (diff)
downloadxen-93c6f36102ca2579a58b99e7ab9095b525336795.tar.gz
xen-93c6f36102ca2579a58b99e7ab9095b525336795.tar.bz2
xen-93c6f36102ca2579a58b99e7ab9095b525336795.zip
bitkeeper revision 1.288 (3f098762sqCvcfeLanWC1bkr_aEKGA)
Add virtual disk manager to xenctl Implement partial virtual disk functionality Code cleanups
Diffstat (limited to 'tools/control')
-rw-r--r--tools/control/src/org/xenoserver/cmdline/Main.java14
-rw-r--r--tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java56
-rw-r--r--tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java5
-rw-r--r--tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java49
-rw-r--r--tools/control/src/org/xenoserver/cmdline/ParseVdFree.java45
-rw-r--r--tools/control/src/org/xenoserver/cmdline/ParseVdShow.java66
-rw-r--r--tools/control/src/org/xenoserver/control/CommandPartitionAdd.java22
-rw-r--r--tools/control/src/org/xenoserver/control/CommandVdCreate.java28
-rw-r--r--tools/control/src/org/xenoserver/control/VirtualBlockDevice.java61
-rw-r--r--tools/control/src/org/xenoserver/control/VirtualDisk.java181
-rw-r--r--tools/control/src/org/xenoserver/control/VirtualDiskManager.java236
-rw-r--r--tools/control/src/org/xenoserver/control/XML.java8
-rw-r--r--tools/control/src/org/xenoserver/control/XMLHelper.java27
13 files changed, 773 insertions, 25 deletions
diff --git a/tools/control/src/org/xenoserver/cmdline/Main.java b/tools/control/src/org/xenoserver/cmdline/Main.java
index 624a07c951..ad58cadb7e 100644
--- a/tools/control/src/org/xenoserver/cmdline/Main.java
+++ b/tools/control/src/org/xenoserver/cmdline/Main.java
@@ -1,9 +1,6 @@
package org.xenoserver.cmdline;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.LinkedList;
-import java.util.List;
import org.xenoserver.control.CommandFailedException;
import org.xenoserver.control.Defaults;
@@ -18,18 +15,25 @@ public class Main {
new ParseDomainList()
};
static final CommandParser partitioncommands[] =
- { new ParsePartitionsList()
+ { new ParsePartitionsAdd(),
+ new ParsePartitionsList()
};
static final CommandParser physicalcommands[] =
{ new ParsePhysicalGrant(),
new ParsePhysicalRevoke(),
new ParsePhysicalList()
};
+ static final CommandParser vdcommands[] =
+ { new ParseVdCreate(),
+ new ParseVdShow(),
+ new ParseVdFree()
+ };
static final CommandParser commands[] =
{ help,
new ParseGroup( "domain", domaincommands ),
new ParseGroup( "partitions", partitioncommands ),
- new ParseGroup( "physical", physicalcommands )
+ new ParseGroup( "physical", physicalcommands ),
+ new ParseGroup( "vd", vdcommands )
};
static final CommandParser parser = new ParseGroup( null, commands );
diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java
new file mode 100644
index 0000000000..63f6dce36e
--- /dev/null
+++ b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java
@@ -0,0 +1,56 @@
+package org.xenoserver.cmdline;
+
+import java.util.LinkedList;
+
+import org.xenoserver.control.CommandFailedException;
+import org.xenoserver.control.CommandPartitionAdd;
+import org.xenoserver.control.Defaults;
+import org.xenoserver.control.Library;
+import org.xenoserver.control.Partition;
+import org.xenoserver.control.PartitionManager;
+import org.xenoserver.control.Settings;
+
+public class ParsePartitionsAdd extends CommandParser {
+ public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
+ boolean force = getFlagParameter(args, 'f');
+ String partition_name = getStringParameter(args, 'p', "");
+ String size = getStringParameter(args, 'c', "100M");
+
+ if (partition_name.equals(""))
+ throw new ParseFailedException("Expected -p<partition_name>");
+
+ long chunksize = Library.parse_size( size ) / Settings.SECTOR_SIZE;
+ if ( chunksize <= 0 )
+ throw new CommandFailedException("Chunk size " + size + " is smaller than sector size.");
+
+ // Initialise the partition manager and look up the partition
+ loadState();
+ Partition p = PartitionManager.it.get_partition(partition_name);
+
+ if ( p == null )
+ throw new CommandFailedException("Partition " + partition_name + " does not exist.");
+
+ // Check if this partition belongs to the VDM
+ if (p.getIsXeno() && !force)
+ throw new CommandFailedException("Refusing to add partition as it is already allocated to the virtual disk manager. Use -f if you are sure.");
+
+ String output = new CommandPartitionAdd( p, chunksize ).execute();
+ if ( output != null )
+ System.out.println( output );
+
+ saveState();
+ }
+
+ public String getName() {
+ return "add";
+ }
+
+ public String getUsage() {
+ return "[-f] [-p<partition_name>] [-c<chunk_size>]";
+ }
+
+ public String getHelpText() {
+ return "Add the specified partition to the virtual disk manager's free\n" +
+ "space. -c changes the default chunk size. -f forces add.";
+ }
+}
diff --git a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java
index 02a754f23f..7853461463 100644
--- a/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java
+++ b/tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java
@@ -8,13 +8,10 @@ import org.xenoserver.control.Defaults;
import org.xenoserver.control.Library;
import org.xenoserver.control.Partition;
import org.xenoserver.control.PartitionManager;
-import org.xenoserver.control.Settings;
-import org.xenoserver.control.XML;
public class ParsePartitionsList extends CommandParser {
-
public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
- XML.load_state( PartitionManager.it, Settings.STATE_INPUT_FILE );
+ loadState();
Iterator i = PartitionManager.it.iterator();
int idx = 1;
System.out.println( " maj:min " + " blocks " + "start sect " +
diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java b/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java
new file mode 100644
index 0000000000..9075039a29
--- /dev/null
+++ b/tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java
@@ -0,0 +1,49 @@
+package org.xenoserver.cmdline;
+
+import java.util.Date;
+import java.util.LinkedList;
+
+import org.xenoserver.control.CommandFailedException;
+import org.xenoserver.control.CommandVdCreate;
+import org.xenoserver.control.Defaults;
+import org.xenoserver.control.Library;
+import org.xenoserver.control.Settings;
+
+public class ParseVdCreate extends CommandParser {
+ public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
+ String name = getStringParameter(args,'n',"");
+ String size_s = getStringParameter(args,'s',"");
+ String expiry_s = getStringParameter(args,'e',"");
+ Date expiry;
+
+ if ( name.equals("") )
+ throw new ParseFailedException("Expected -n<name>");
+ if ( size_s.equals("") )
+ throw new ParseFailedException("Expected -s<size>");
+ if ( expiry_s.equals("") )
+ expiry = null;
+ else
+ expiry = new Date(Date.parse(expiry_s));
+
+ long size = Library.parse_size(size_s);
+
+ loadState();
+ String output = new CommandVdCreate(name,size/Settings.SECTOR_SIZE,expiry).execute();
+ if ( output != null )
+ System.out.println( output );
+ saveState();
+ }
+
+ public String getName() {
+ return "create";
+ }
+
+ public String getUsage() {
+ return "[-n<name>] [-s<size>] [-e<expiry>]";
+ }
+
+ public String getHelpText() {
+ return "Create a new virtual disk with the specified parameters";
+ }
+
+}
diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java b/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java
new file mode 100644
index 0000000000..7bd3e8a804
--- /dev/null
+++ b/tools/control/src/org/xenoserver/cmdline/ParseVdFree.java
@@ -0,0 +1,45 @@
+package org.xenoserver.cmdline;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.xenoserver.control.CommandFailedException;
+import org.xenoserver.control.Defaults;
+import org.xenoserver.control.Extent;
+import org.xenoserver.control.Library;
+import org.xenoserver.control.Settings;
+import org.xenoserver.control.VirtualDisk;
+import org.xenoserver.control.VirtualDiskManager;
+
+public class ParseVdFree extends CommandParser {
+ public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
+ boolean verbose = getFlagParameter(args, 'v');
+
+ loadState();
+ VirtualDisk free = VirtualDiskManager.it.getFreeVirtualDisk();
+ System.out.println( "Free disk has " + free.getExtentCount() + " extents totalling "
+ + Library.format_size(free.getSize()*Settings.SECTOR_SIZE,8,1) );
+ if ( verbose ) {
+ Iterator i = free.iterator();
+ System.out.println(" disk offset size");
+ while (i.hasNext()) {
+ Extent e = (Extent) i.next();
+ System.out.println( Library.format(e.getDisk(), 6, 0) + " "
+ + Library.format(e.getOffset(), 12, 0) + " "
+ + Library.format(e.getSize(), 12, 0) );
+ }
+ }
+ }
+
+ public String getName() {
+ return "free";
+ }
+
+ public String getUsage() {
+ return "[-v]";
+ }
+
+ public String getHelpText() {
+ return "Show free space allocated to virtual disk manager. -v enables verbose output.";
+ }
+}
diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java b/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java
new file mode 100644
index 0000000000..287a24621a
--- /dev/null
+++ b/tools/control/src/org/xenoserver/cmdline/ParseVdShow.java
@@ -0,0 +1,66 @@
+package org.xenoserver.cmdline;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.xenoserver.control.CommandFailedException;
+import org.xenoserver.control.Defaults;
+import org.xenoserver.control.Extent;
+import org.xenoserver.control.Library;
+import org.xenoserver.control.Settings;
+import org.xenoserver.control.VirtualDisk;
+import org.xenoserver.control.VirtualDiskManager;
+
+public class ParseVdShow extends CommandParser {
+ public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
+ int vd_num = getIntParameter(args,'n',-1);
+
+ loadState();
+
+ if ( vd_num < 0 ) {
+ System.out.println("num key expiry name size");
+ for (int i=0;i<VirtualDiskManager.it.getVirtualDiskCount();i++) {
+ VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(i);
+ System.out.print( Library.format(i,3,0) + " " + vd.getKey() + " " );
+ if ( vd.getExpiry() != null )
+ System.out.print( vd.getExpiry().toString() );
+ else
+ System.out.print( " " );
+ System.out.println( " " + Library.format(vd.getName(),16,1) + " "
+ + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,0) );
+ }
+ } else {
+ VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(vd_num);
+ if ( vd == null )
+ throw new CommandFailedException("There is no virtual disk " + vd_num );
+
+ System.out.println(" name: " + vd.getName());
+ System.out.println(" key: " + vd.getKey());
+ System.out.println(" size: " + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,1));
+ if ( vd.getExpiry() != null )
+ System.out.println("expiry: " + vd.getExpiry());
+ System.out.println();
+
+ Iterator i = vd.iterator();
+ System.out.println(" disk offset size");
+ while (i.hasNext()) {
+ Extent e = (Extent) i.next();
+ System.out.println( Library.format(e.getDisk(), 6, 0) + " "
+ + Library.format(e.getOffset(), 12, 0) + " "
+ + Library.format(e.getSize(), 12, 0) );
+ }
+ }
+ }
+
+ public String getName() {
+ return "show";
+ }
+
+ public String getUsage() {
+ return "[-n<diskno>]";
+ }
+
+ public String getHelpText() {
+ return "Show a summary of all virtual disks, or details of one disk if -n is given";
+ }
+}
diff --git a/tools/control/src/org/xenoserver/control/CommandPartitionAdd.java b/tools/control/src/org/xenoserver/control/CommandPartitionAdd.java
new file mode 100644
index 0000000000..4a2a9c811c
--- /dev/null
+++ b/tools/control/src/org/xenoserver/control/CommandPartitionAdd.java
@@ -0,0 +1,22 @@
+package org.xenoserver.control;
+
+public class CommandPartitionAdd extends Command {
+ private Partition partition;
+ private long chunksize;
+
+ /**
+ * Constructor for CommandPartitionAdd.
+ * @param partition Partition to add.
+ * @param chunksize Chunk size to split partition into (in sectors).
+ */
+ public CommandPartitionAdd(Partition partition, long chunksize) {
+ this.partition = partition;
+ this.chunksize = chunksize;
+ }
+
+ public String execute() throws CommandFailedException {
+ VirtualDiskManager.it.add_xeno_partition(partition,chunksize);
+ PartitionManager.it.add_xeno_partition(partition);
+ return "Added partition " + partition.getName();
+ }
+}
diff --git a/tools/control/src/org/xenoserver/control/CommandVdCreate.java b/tools/control/src/org/xenoserver/control/CommandVdCreate.java
new file mode 100644
index 0000000000..f9b46cfd32
--- /dev/null
+++ b/tools/control/src/org/xenoserver/control/CommandVdCreate.java
@@ -0,0 +1,28 @@
+package org.xenoserver.control;
+
+import java.util.Date;
+
+public class CommandVdCreate extends Command {
+ private String name;
+ private long size;
+ private Date expiry;
+
+ /**
+ * Constructor for CommandVdCreate.
+ * @param name Name of new virtual disk.
+ * @param size Size in sectors.
+ * @param expiry Expiry time, or null for never.
+ */
+ public CommandVdCreate(String name, long size, Date expiry) {
+ this.name = name;
+ this.size = size;
+ this.expiry = expiry;
+ }
+
+ public String execute() throws CommandFailedException {
+ VirtualDisk vd = VirtualDiskManager.it.create_virtual_disk(name,size,expiry);
+ if ( vd == null )
+ throw new CommandFailedException( "Not enough free space to create disk" );
+ return "Virtual Disk created with key: " + vd.getKey();
+ }
+}
diff --git a/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java b/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java
new file mode 100644
index 0000000000..c2e800789f
--- /dev/null
+++ b/tools/control/src/org/xenoserver/control/VirtualBlockDevice.java
@@ -0,0 +1,61 @@
+/*
+ * VirtualBlockDevice.java
+ * 03.03.27 aho creation
+ */
+
+package org.xenoserver.control;
+
+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();
+
+ 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>");
+ }
+
+ 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/org/xenoserver/control/VirtualDisk.java b/tools/control/src/org/xenoserver/control/VirtualDisk.java
new file mode 100644
index 0000000000..460570f2d3
--- /dev/null
+++ b/tools/control/src/org/xenoserver/control/VirtualDisk.java
@@ -0,0 +1,181 @@
+/*
+ * VirtualDisk.java
+ * 03.03.26 aho creation
+ */
+
+package org.xenoserver.control;
+
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class VirtualDisk {
+ String name;
+ String key;
+ Date expiry;
+ Vector extents;
+
+ VirtualDisk(String name, Date expiry, String key) {
+ this.name = name;
+ if ( key == null )
+ this.key = generate_key();
+ else
+ this.key = key;
+ this.expiry = expiry;
+ extents = new Vector();
+ }
+
+ VirtualDisk(String name) {
+ this(name, null, null);
+ }
+
+ VirtualDisk(String name, Date expiry) {
+ this(name, expiry, null);
+ }
+
+ /*
+ * 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));
+ }
+
+ 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_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 Date getExpiry() {
+ return expiry;
+ }
+
+ public int getExtentCount() {
+ return extents.size();
+ }
+
+ public Extent getExtent(int index) {
+ return (Extent) extents.get(index);
+ }
+
+ /**
+ * @return Total size of this virtual disk in sectors.
+ */
+ public long getSize() {
+ long size = 0;
+ Iterator i = extents.iterator();
+ while ( i.hasNext() ) {
+ size += ((Extent) i.next()).getSize();
+ }
+ return size;
+ }
+
+ /**
+ * @return An iterator over all extents in the disk.
+ */
+ public Iterator iterator() {
+ return extents.iterator();
+ }
+}
diff --git a/tools/control/src/org/xenoserver/control/VirtualDiskManager.java b/tools/control/src/org/xenoserver/control/VirtualDiskManager.java
new file mode 100644
index 0000000000..e2d1e6d6cc
--- /dev/null
+++ b/tools/control/src/org/xenoserver/control/VirtualDiskManager.java
@@ -0,0 +1,236 @@
+/*
+ * VirtualDiskManager.java
+ * 03.03.26 aho creation
+ */
+
+package org.xenoserver.control;
+
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * VirtualDiskManager manages the list of virtual disks on the machine. It is
+ * a Singleton which automatically initialises itself on first class reference.
+ */
+public class VirtualDiskManager {
+ public static final VirtualDiskManager it = new VirtualDiskManager();
+ VirtualDisk free_disk;
+ Vector virtual_disks;
+ Hashtable virtual_block_devices;
+ Hashtable key_hash;
+
+ private 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);
+
+ if ( free_disk.getSize() < size )
+ return null;
+
+ 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);
+ virtual_block_devices.remove(hash);
+ }
+
+ /*
+ * 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.getKey(), 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_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/org/xenoserver/control/XML.java b/tools/control/src/org/xenoserver/control/XML.java
index d8331b9c2b..55bc3a9c12 100644
--- a/tools/control/src/org/xenoserver/control/XML.java
+++ b/tools/control/src/org/xenoserver/control/XML.java
@@ -30,7 +30,7 @@ XML
*/
public static void
- dump_state (PartitionManager pm,/* VirtualDiskManager vdm,*/ String filename)
+ dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
{
PrintWriter out;
@@ -48,7 +48,7 @@ XML
out.println("<?xml version=\"1.0\"?>");
out.println("<vdmanager>");
pm.dump_xml(out);
- //vdm.dump_xml(out);
+ vdm.dump_xml(out);
out.println("</vdmanager>");
out.close();
@@ -59,14 +59,14 @@ XML
* load partition manager and virtual disk manager state from filename
*/
public static void
- load_state (PartitionManager pm, /*VirtualDiskManager vdm,*/ String filename)
+ load_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
{
if (document == null)
{
load_file (filename);
}
- XMLHelper.parse(pm, /*vdm,*/ document);
+ XMLHelper.parse(pm, vdm, document);
}
/*
diff --git a/tools/control/src/org/xenoserver/control/XMLHelper.java b/tools/control/src/org/xenoserver/control/XMLHelper.java
index 5646e5ce21..ad1c3f50e1 100644
--- a/tools/control/src/org/xenoserver/control/XMLHelper.java
+++ b/tools/control/src/org/xenoserver/control/XMLHelper.java
@@ -6,6 +6,7 @@
package org.xenoserver.control;
import java.util.Date;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -98,14 +99,14 @@ XMLHelper
}
static void
- parse (PartitionManager pm, /*VirtualDiskManager vdm,*/ Document document)
+ parse (PartitionManager pm, VirtualDiskManager vdm, Document document)
{
if (document == null) return;
/* parse partitions */
parse_partitions(pm, document.getElementsByTagName("partition"));
-/*
- / parse virtual disks /
+
+ /* parse virtual disks */
NodeList list = document.getElementsByTagName("virtual_disk");
for (int i = 0; i < list.getLength(); i++)
{
@@ -128,20 +129,24 @@ XMLHelper
}
}
- / parse virtual block devices /
+ /* parse virtual block devices */
parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device"));
-*/
+
return;
}
- /* static VirtualDisk
+ 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))));
+ long timestamp = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node)));
+ if ( timestamp == 0 )
+ date = null;
+ else
+ date.setTime( timestamp );
vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)),
date,
XMLHelper.get_text(XMLHelper.get_subnode("key", node)));
@@ -164,7 +169,7 @@ XMLHelper
}
return vd;
- }*/
+ }
static void
parse_partitions (PartitionManager pm, NodeList nl)
@@ -186,12 +191,10 @@ XMLHelper
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);
@@ -201,5 +204,5 @@ XMLHelper
Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))),
XMLHelper.get_text(XMLHelper.get_subnode("mode", node)));
}
- }*/
+ }
}