From 61a664017f391947bda0466cfd1ef03959661e20 Mon Sep 17 00:00:00 2001 From: "ach61@labyrinth.cl.cam.ac.uk" Date: Tue, 22 Apr 2003 12:58:25 +0000 Subject: bitkeeper revision 1.160.3.1 (3ea53c71xG2JEZ0LCbFRAxt9kayWBw) fix earlier merge problems user space virtual disk manager --- tools/vdmanager/build.xml | 45 +++ .../src/uk/ac/cam/cl/xeno/vdmanager/Extent.java | 14 + .../src/uk/ac/cam/cl/xeno/vdmanager/Library.java | 114 ++++++ .../src/uk/ac/cam/cl/xeno/vdmanager/Main.java | 35 ++ .../src/uk/ac/cam/cl/xeno/vdmanager/Mode.java | 20 + .../src/uk/ac/cam/cl/xeno/vdmanager/Parser.java | 406 +++++++++++++++++++++ .../src/uk/ac/cam/cl/xeno/vdmanager/Partition.java | 80 ++++ .../ac/cam/cl/xeno/vdmanager/PartitionManager.java | 149 ++++++++ .../cam/cl/xeno/vdmanager/VirtualBlockDevice.java | 51 +++ .../uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.java | 211 +++++++++++ .../cam/cl/xeno/vdmanager/VirtualDiskManager.java | 289 +++++++++++++++ .../src/uk/ac/cam/cl/xeno/vdmanager/XML.java | 126 +++++++ .../src/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.java | 205 +++++++++++ tools/vdmanager/vdmanager | 16 + 14 files changed, 1761 insertions(+) create mode 100755 tools/vdmanager/build.xml create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Extent.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Library.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Main.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Mode.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Parser.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Partition.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/PartitionManager.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualBlockDevice.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDiskManager.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XML.java create mode 100755 tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.java create mode 100755 tools/vdmanager/vdmanager (limited to 'tools') diff --git a/tools/vdmanager/build.xml b/tools/vdmanager/build.xml new file mode 100755 index 0000000000..5a76a48eee --- /dev/null +++ b/tools/vdmanager/build.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Extent.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Extent.java new file mode 100755 index 0000000000..048a38156c --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Extent.java @@ -0,0 +1,14 @@ +/* + * Extent.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +public class +Extent +{ + int disk; + long offset; /* offset into disk */ + long size; /* size of this extent in 512 byte sectors */ +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Library.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Library.java new file mode 100755 index 0000000000..0709376294 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Library.java @@ -0,0 +1,114 @@ +/* + * Library.java + * 03.03.28 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +public class +Library +{ + /* + * convert a number to a fixed width string + */ + static String + format (long input, int width, int prefix) + { + String sss = Long.toString(input); + String space = " "; + + if (width < sss.length()) + { + width = sss.length(); + } + + if (prefix == 0) + { + return space.substring(0, width - sss.length()) + sss; + } + else + { + return sss + space.substring(0, width - sss.length()); + } + } + + /* + * convert a string to a fixed width string + */ + static String + format (String input, int width, int prefix) + { + String space = " "; + + if (width < input.length()) + { + width = input.length(); + } + + if (prefix == 0) + { + return space.substring(0, width - input.length()) + input; + } + else + { + return input + space.substring(0, width - input.length()); + } + } + + /* + * convert a number (string format) into + * the corresponding integer value. + */ + static int + parse_size(String size) + { + String substring = size; + int suffix = 1; + + if ((substring = check(size, 'm')) != null) + { + suffix = 1024 * 1024; + } + else if ((substring = check(size, 'M')) != null) + { + suffix = 1024 * 1024; + } + else if ((substring = check(size, 'k')) != null) + { + suffix = 1024; + } + else if ((substring = check(size, 'K')) != null) + { + suffix = 1024; + } + else if ((substring = check(size, 'g')) != null) + { + suffix = 1024 * 1024 * 1024; + } + else if ((substring = check(size, 'G')) != null) + { + suffix = 1024 * 1024 * 1024; + } + else + { + substring = size; + } + + return Integer.decode(substring).intValue() * suffix; + } + + static String + check(String size, char suffix) + { + int index = size.indexOf(suffix); + + if (index != -1) + { + return size.substring(0, index); + } + else + { + return null; + } + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Main.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Main.java new file mode 100755 index 0000000000..2a036bbe9c --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Main.java @@ -0,0 +1,35 @@ +/* + * Main.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.util.Date; + +public class +Main +{ + static String state_filename_in = "/var/run/vdmanager.xml"; + static String state_filename_out = "/var/run/vdmanager.xml"; + static String partition_filename = "/proc/partitions"; + + void + go (String[] argv) + { + PartitionManager pm = new PartitionManager(partition_filename); + VirtualDiskManager vdm = new VirtualDiskManager();; + Parser parser = new Parser(pm, vdm); + + XML.load_state(pm, vdm, state_filename_in); + parser.parse_main(argv); + XML.dump_state(pm, vdm, state_filename_out); + } + + public static void + main (String[] argv) + { + Main foo = new Main(); + foo.go(argv); + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Mode.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Mode.java new file mode 100755 index 0000000000..70e66f6542 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Mode.java @@ -0,0 +1,20 @@ +/* + * Mode.java + * 03.03.27 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +public class +Mode +{ + private final String name; + + private Mode(String name) { this.name = name; } + + public String toString() { return name; } + + public static final Mode READ_ONLY = new Mode("ro"); + public static final Mode READ_WRITE = new Mode("rw"); +} + diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Parser.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Parser.java new file mode 100755 index 0000000000..0ce703a2cb --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Parser.java @@ -0,0 +1,406 @@ +/* + * Parser.java + * 03.03.27 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.Date; + +public class +Parser +{ + static String prompt = "vdmanager> "; + static String default_addpartition_chunksize = "104857600"; /* 100M */ + static int default_sector_size = 512; + + PartitionManager pm; + VirtualDiskManager vdm; + + Parser (PartitionManager pm, VirtualDiskManager vdm) + { + this.pm = pm; + this.vdm = vdm; + } + + void + parse_main (String[] argv) + { + if (argv.length == 0) + { + parse_input(null); + } + else + { + parse_commandline(argv); + } + } + + void + parse_input (String filename) + { + String line; + BufferedReader in; + + if (filename != null) + { + try + { + in = new BufferedReader(new FileReader(filename)); + } + catch (FileNotFoundException fnfe) + { + System.err.println (fnfe); + return; + } + } + else + { + in = new BufferedReader(new InputStreamReader(System.in)); + } + + try + { + if (filename == null) + { + System.out.print (prompt); + } + line = in.readLine(); + while (line != null) + { + StringTokenizer st = new StringTokenizer(line); + Vector v = new Vector(); + + while (st.hasMoreTokens()) + { + v.add(st.nextToken()); + } + + if (parse_commandline((String[]) v.toArray(new String[v.size()]))) + { + return; + } + + if (filename == null) + { + System.out.print (prompt); + } + line = in.readLine(); + } + } + catch (IOException ioe) + { + System.err.println(ioe); + } + + if (filename == null) + { + System.out.println (""); + } + return; + } + + boolean + parse_commandline (String[] commands) + { + if (commands.length == 0) + { + return false; + } + + String keyword = commands[0].toLowerCase(); + if (keyword.equals("file")) + { + if (commands.length < 2) + { + System.out.println ("file [filename]"); + return false; + } + for (int i = 1; i < commands.length; i++) + { + System.out.println ("file " + commands[i]); + parse_input(commands[i]); + } + } + else if (keyword.equals("show")) + { + parse_show(commands); + } + else if (keyword.equals("addpartition")) + { + parse_addpartition(commands); + } + else if (keyword.equals("vdcreate")) + { + parse_vdcreate(commands); + } + else if (keyword.equals("vddelete")) + { + parse_vddelete(commands); + } + else if (keyword.equals("vdrefresh")) + { + parse_vdrefresh(commands); + } + else if (keyword.equals("vbdcreate")) + { + parse_vbdcreate(commands); + } + else if (keyword.equals("vbddelete")) + { + parse_vbddelete(commands); + } + else if (keyword.equals("vbdflush")) + { + vdm.flush_virtual_block_devices(); + } + else if (keyword.equals("load")) + { + if (commands.length < 2) + { + System.out.println ("load "); + return false; + } + XML.load_state (pm, vdm, commands[1]); + } + else if (keyword.equals("save")) + { + if (commands.length < 2) + { + System.out.println ("save "); + return false; + } + XML.dump_state (pm, vdm, commands[1]); + } + else if (keyword.equals("help") || + keyword.equals("?")) + { + parse_help(); + } + else if (keyword.equals("exit") || + keyword.equals("quit")) + { + return true; + } + else + { + System.out.println ("unknown command [" + commands[0] + "]. " + + "try \"help\""); + } + return false; + } + + void + parse_vdcreate (String[] commands) + { + VirtualDisk vd; + + if (commands.length < 4) + { + System.out.println ("vdcreate name size expiry"); + return; + } + + vd = vdm.create_virtual_disk(commands[1], + Library.parse_size(commands[2]) / default_sector_size, + new Date()); + + System.out.println ("Virtual Disk created with key: " + vd.get_key()); + } + + void + parse_vddelete (String[] commands) + { + if (commands.length < 2) + { + System.out.println ("vddelete key"); + return; + } + + vdm.delete_virtual_disk(commands[1]); + } + + void + parse_vdrefresh (String[] commands) + { + if (commands.length < 3) + { + System.out.println ("vdrefresh key expiry"); + return; + } + + vdm.refresh_virtual_disk(commands[1], + new Date()); + } + + void + parse_vbdcreate (String[] commands) + { + VirtualDisk vd; + VirtualBlockDevice vbd; + + if (commands.length < 4) + { + System.out.println ("vbdcreate "); + return; + } + + if (commands.length == 4) + { + vbd = + vdm.create_virtual_block_device(commands[1], + Integer.decode(commands[2]).intValue(), + Integer.decode(commands[3]).intValue(), + "rw"); + } + else + { + vbd = + vdm.create_virtual_block_device(commands[1], + Integer.decode(commands[2]).intValue(), + Integer.decode(commands[3]).intValue(), + commands[4]); + } + + { + vd = vdm.get_virtual_disk_key(commands[1]); + System.out.println ("\n" + vd.dump_xen(vbd) + "\n"); + } + } + + void + parse_vbddelete (String[] commands) + { + if (commands.length < 3) + { + System.out.println ("vbdcreate "); + return; + } + + vdm.delete_virtual_block_device(Integer.decode(commands[1]).intValue(), + Integer.decode(commands[2]).intValue()); + } + + static String show_helptxt = "show "; + void + parse_show (String[] commands) + { + String subword; + + if (commands.length < 2) + { + System.out.println (show_helptxt); + return; + } + + subword = commands[1].toLowerCase(); + if (subword.equals("partition") || + subword.equals("partitions")) + { + System.out.println(pm.dump(true)); + } + else if (subword.equals("vd")) + { + String text; + + if (commands.length < 3) + { + System.out.println(vdm.dump_virtualdisks()); + return; + } + text = vdm.dump_virtualdisk(Integer.decode(commands[2]).intValue()); + if (text == null) + { + System.out.println("show vd error: invalid virtual disk number"); + } + else + { + System.out.println(text); + } + } + else if (subword.equals("vbd")) + { + System.out.println(vdm.dump_virtualblockdevices()); + } + else if (subword.equals("free")) + { + System.out.println(vdm.dump_free()); + } + else + { + System.out.println (show_helptxt); + return; + } + } + + void + parse_addpartition(String[] commands) + { + String chunksize = default_addpartition_chunksize; + + if (commands.length > 3 || commands.length < 2) + { + System.out.println ("addpartition [chunksize]"); + return; + } + if (commands.length == 3) + { + chunksize = commands[2]; + } + + System.out.println ("add partition " + commands[1] + " " + chunksize); + + vdm.add_xeno_partition(pm.get_partition(Integer.parseInt(commands[1])), + Library.parse_size(chunksize)/default_sector_size); + pm.add_xeno_partition(pm.get_partition(Integer.parseInt(commands[1]))); + } + + void + parse_help() + { + System.out.println ("file " + + "read the contents of a file as input to vdmanager"); + System.out.println ("addpartition [chunksize]"); + System.out.println (" " + + "add a partition as a xeno partition"); + System.out.println ("vdcreate "); + System.out.println (" " + + "create a new virtual disk"); + System.out.println ("vddelete " + + "delete a virtual disk"); + System.out.println ("vdrefresh "); + System.out.println (" " + + "reset virtual disk expiry"); + System.out.println ("vbdcreate [rw|ro]"); + System.out.println (" " + + "create a new virtual block device"); + System.out.println ("vbddelete "); + System.out.println (" " + + "delete a new virtual block device"); + System.out.println ("vbdflush " + + "remove all virtual block devices"); + System.out.println ("show partitions " + + "display a complete list of disk partitions"); + System.out.println ("show vd " + + "display virtual disk information"); + System.out.println ("show vbd " + + "display virtual virtual block device list"); + System.out.println ("show free " + + "display details about unallocated space"); + System.out.println ("load " + + "load new state from file"); + System.out.println ("save " + + "save state to file"); + System.out.println ("help " + + "display this help message"); + System.out.println ("quit " + + "exit"); + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Partition.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Partition.java new file mode 100755 index 0000000000..eacb5b652c --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/Partition.java @@ -0,0 +1,80 @@ +/* + * PartitionManager.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.io.*; + +public class +Partition +{ + int major; + int minor; + long blocks; + long start_sect; + long nr_sects; + String name; + + boolean + identical (Partition p) + { + return (major == p.major && + minor == p.minor && + blocks == p.blocks && + start_sect == p.start_sect && + nr_sects == p.nr_sects && + name.equals(p.name)); + } + + Partition + duplicate () + { + Partition p = new Partition(); + + p.major = major; + p.minor = minor; + p.blocks = blocks; + p.start_sect = start_sect; + p.nr_sects = nr_sects; + p.name = name; + + return p; + } + + String + dump (boolean title) + { + if (title) + { + return ("maj:min " + + " blocks " + + "start sect " + + " num sects " + + "name"); + } + else + { + return (Library.format(major,3,0) + ":" + + Library.format(minor,3,1) + " " + + Library.format(blocks,10,0) + " " + + Library.format(start_sect,10,0) + " " + + Library.format(nr_sects,10,0) + " " + + Library.format(name,7,1)); + } + } + + void + dump_xml(PrintWriter out) + { + out.println (" \n" + + " " + major + "\n" + + " " + minor + "\n" + + " " + blocks + "\n" + + " " + start_sect + "\n" + + " " + nr_sects + "\n" + + " " + name + "\n" + + " "); + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/PartitionManager.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/PartitionManager.java new file mode 100755 index 0000000000..72f5982aff --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/PartitionManager.java @@ -0,0 +1,149 @@ +/* + * PartitionManager.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.io.*; +import java.util.Vector; + +public class +PartitionManager +{ + Vector partition_map; + Vector xeno_partition_list; + + /* + * Initialize partition manager with source file. + * Normally we read from /proc/partitions, but we can + * specify an alternative file for debugging + */ + PartitionManager (String filename) + { + String str; + BufferedReader in; + + partition_map = new Vector(100,10); + xeno_partition_list = new Vector(10,5); + + try + { + in = new BufferedReader(new FileReader(filename)); + + str = in.readLine(); /* skip headings */ + str = in.readLine(); /* skip blank line */ + + str = in.readLine(); + while (str != null) + { + Partition partition = new Partition(); + + partition.major = Integer.parseInt(str.substring(0,5).trim()); + partition.minor = Integer.parseInt(str.substring(5,10).trim()); + partition.blocks = Integer.parseInt(str.substring(10,21).trim()); + partition.start_sect = Integer.parseInt(str.substring(21,32).trim()); + partition.nr_sects = Integer.parseInt(str.substring(32,43).trim()); + partition.name = str.substring(43).trim(); + + partition_map.add(partition); + str = in.readLine(); + } + } + catch (IOException io) + { + System.err.println ("PartitionManager: error reading partition file [" + + filename + "]"); + System.err.println (io); + } + } + + Partition + get_partition (int index) + { + return (Partition) partition_map.get(index); + } + + void + add_xeno_partition (Partition partition) + { + Partition xeno_partition = (Partition) partition.duplicate(); + + xeno_partition_list.add(xeno_partition); + } + + /* + * dump the xeno partition list as xml + */ + void + dump_xml (PrintWriter out) + { + int loop; + + out.println(""); + for (loop = 0; loop < xeno_partition_list.size(); loop++) + { + Partition partition = (Partition) xeno_partition_list.get(loop); + partition.dump_xml(out); + } + out.println(""); + + return; + } + + /* + * dump the partition map as a string + * mark: mark the current xeno partitions in the partition map + */ + String + dump (boolean mark) + { + int loop, idx; + StringBuffer sb = new StringBuffer(); + Partition partition; + + for (idx = 0; idx < partition_map.size(); idx++) + { + boolean xeno_partition = false; + + partition = (Partition) partition_map.get(idx); + + /* is this a xeno partition */ + if (mark) + { + for (loop = 0; loop < xeno_partition_list.size(); loop++) + { + if (partition.identical((Partition)xeno_partition_list.get(loop))) + { + xeno_partition = true; + break; + } + } + } + + if (idx == 0) + { + sb.append(" idx " + partition.dump(true) + "\n"); + } + if (xeno_partition) + { + sb.append("[ "); + } + else + { + sb.append(" "); + } + sb.append(Library.format(idx,2,0) + " " + partition.dump(false)); + if (xeno_partition) + { + sb.append("]\n"); + } + else + { + sb.append("\n"); + } + } + + return sb.toString(); + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualBlockDevice.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualBlockDevice.java new file mode 100755 index 0000000000..a841ca73fe --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualBlockDevice.java @@ -0,0 +1,51 @@ +/* + * VirtualBlockDevice.java + * 03.03.27 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.io.PrintWriter; + +public class +VirtualBlockDevice +{ + String key; + int domain; + int vbdnum; + Mode mode; /* rw or ro */ + + String + dump (boolean title) + { + StringBuffer sb = new StringBuffer(); + int loop; + + if (title) + { + sb.append(" key dom vbd mode\n"); + } + else + { + sb.append(" " + key + " " + + Library.format(domain,3,0) + " " + + Library.format(vbdnum,3,0) + " " + + mode.toString() + "\n"); + } + + return sb.toString(); + } + + void + dump_xml (PrintWriter out) + { + out.println(" "); + out.println(" " + key + ""); + out.println(" " + domain + ""); + out.println(" " + vbdnum + ""); + out.println(" " + mode + ""); + out.println(" "); + + return; + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.java new file mode 100755 index 0000000000..72d5bb9441 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDisk.java @@ -0,0 +1,211 @@ +/* + * VirtualDisk.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.util.Date; +import java.util.Vector; +import java.lang.Math; +import java.io.PrintWriter; + +public class +VirtualDisk +{ + String name; + String key; + Date expiry; + Vector extents; + + VirtualDisk (String name, Date expiry, String key) + { + this.name = name; + this.key = key; + this.expiry = expiry; + extents = new Vector(); + } + + VirtualDisk (String name) + { + this (name, null, null); + this.key = generate_key(); + extents = new Vector(); + + return; + } + + VirtualDisk (String name, Date expiry) + { + this(name, expiry, null); + this.key = generate_key(); + } + + /* + * generate a unique key for this virtual disk. + * for now, just generate a 10 digit number + */ + String + generate_key () + { + return Long.toString(1000000000l + (long)(Math.random() * 8999999999l)); + } + + String + get_key () + { + return key; + } + + Date + get_expiry () + { + return expiry; + } + + void + set_expiry (Date expiry) + { + this.expiry = expiry; + } + + public void + add_extent (Extent extent) + { + extents.add(extent); + } + + public Extent + remove_extent () + { + Extent e; + + if (extents.size() > 0) + { + e = (Extent) extents.remove(0); + } + else + { + e = null; + } + + return e; + } + + String + dump (boolean details, boolean title) + { + StringBuffer sb = new StringBuffer(); + int loop; + + if (details) + { + if (title) + { + sb.append(" name: " + name + "\n"); + sb.append(" key: " + key + "\n"); + sb.append("expiry: " + expiry + "\n"); + sb.append("\n"); + } + sb.append(" idx disk offset size \n"); + for (loop = 0; loop < extents.size(); loop++) + { + Extent e = (Extent) extents.get(loop); + sb.append(" " + + Library.format(loop,3,0) + " " + + Library.format(e.disk,6,0) + + Library.format(e.offset,10,0) + + Library.format(e.size,10,0) + "\n"); + } + } + else + { + if (title) + { + sb.append(" key expiry name\n"); + } + else + { + sb.append(" " + key + " " + expiry.toString() + " " + name + "\n"); + } + } + + return sb.toString(); + } + + String + dump_xen (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(" "); + out.println(" " + name + ""); + out.println(" " + key + ""); + if (expiry == null) + { + out.println(" 0"); + } + else + { + out.println(" " + expiry.getTime() + ""); + } + out.println(" "); + for (int loop = 0; loop < extents.size(); loop++) + { + Extent e = (Extent) extents.get(loop); + out.println(" "); + out.println(" " + e.disk + ""); + out.println(" " + e.size + ""); + out.println(" " + e.offset + ""); + out.println(" "); + } + out.println(" "); + out.println(" "); + + 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, int 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; + } + +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDiskManager.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDiskManager.java new file mode 100755 index 0000000000..eeaa156414 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/VirtualDiskManager.java @@ -0,0 +1,289 @@ +/* + * VirtualDiskManager.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.util.Enumeration; +import java.util.Vector; +import java.util.Hashtable; +import java.util.Date; +import java.io.PrintWriter; + +public class +VirtualDiskManager +{ + VirtualDisk free; + Vector virtual_disks; + Hashtable virtual_block_devices; + Hashtable key_hash; + + VirtualDiskManager () + { + free = 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, int size) + { + free.add_new_partition (partition, size); + return; + } + + /* + * create a new virtual disk + */ + + public VirtualDisk + create_virtual_disk(String name, int size, Date expiry) + { + VirtualDisk vd = new VirtualDisk (name, expiry); + + while (size > 0) + { + Extent e; + + e = free.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.add_extent(e); + e = vd.remove_extent(); + } + } + return; + } + + /* + * reset the expiry time for a virtual disk + */ + + public void + refresh_virtual_disk (String key, Date expiry) + { + VirtualDisk vd = (VirtualDisk) key_hash.get(key); + if (vd != null) + { + vd.set_expiry(expiry); + } + } + + /* + * create a new virtual block device + */ + public VirtualBlockDevice + create_virtual_block_device (String key, int domain, int vbd_num, + String mode) + { + VirtualBlockDevice vbd = new VirtualBlockDevice(); + VirtualDisk vd = get_virtual_disk_key(key); + + if (vd == null) + { + System.err.println("create virtual block device error: unknown key " + + "[" + key + "]"); + return null; + } + + vbd.key = key; + vbd.domain = domain; + vbd.vbdnum = vbd_num; + + if (mode.equals(Mode.READ_ONLY.toString()) || + mode.equals("RO") || + mode.equals("ro")) + { + vbd.mode = Mode.READ_ONLY; + } + else if (mode.equals(Mode.READ_WRITE.toString()) || + mode.equals("RW") || + mode.equals("rw")) + { + vbd.mode = Mode.READ_WRITE; + } + else + { + System.err.println("create virtual block device error: unknown mode " + + "[" + mode + "]"); + return null; + } + + add_virtual_block_device(vbd); + + return vbd; + } + + /* + * delete a virtual block device + */ + public void + delete_virtual_block_device (int domain, int vbd_num) + { + Object hash = get_vbd_hash(domain, vbd_num); + VirtualBlockDevice vbd = (VirtualBlockDevice)virtual_block_devices.remove(hash); + return; + } + + /* + * flush all virtual block devices + */ + public void + flush_virtual_block_devices () + { + /* isn't automatic garbage collection wonderful? */ + virtual_block_devices = new Hashtable(100); + } + + public void + add_virtual_disk (VirtualDisk vd) + { + virtual_disks.add(vd); + key_hash.put(vd.get_key(), vd); + } + + public void + add_virtual_block_device (VirtualBlockDevice vbd) + { + Object hash = get_vbd_hash(vbd.domain, vbd.vbdnum); + virtual_block_devices.put(hash, vbd); + } + + Object + get_vbd_hash (int domain, int vbd_num) + { + return new Integer(domain * 16 + vbd_num); + } + + public void + add_free (VirtualDisk vd) + { + free = vd; + } + + public String + dump_virtualdisk (int segment) + { + if (segment < 0 || segment >= virtual_disks.size()) + { + return null; + } + else + { + VirtualDisk vd = (VirtualDisk) virtual_disks.get(segment); + return (vd.dump(true, true)); + } + } + + public String + dump_free() + { + return(free.dump(true, false)); + } + + public String + dump_virtualdisks() + { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < virtual_disks.size(); i++) + { + VirtualDisk vd = (VirtualDisk) virtual_disks.get(i); + if (i == 0) + { + sb.append(vd.dump(false, true)); + } + sb.append(vd.dump(false, false)); + } + + return sb.toString(); + } + + public String + dump_virtualblockdevices() + { + StringBuffer sb = new StringBuffer(); + boolean first = true; + + for (Enumeration enumeration = virtual_block_devices.elements() ; + enumeration.hasMoreElements() ;) + { + VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement(); + if (first) + { + sb.append(vbd.dump(true)); + first = false; + } + + sb.append(vbd.dump(false)); + } + + return sb.toString(); + } + + public void + dump_xml(PrintWriter out) + { + out.println(""); + free.dump_xml(out); + out.println(""); + out.println(""); + for (int i = 0; i < virtual_disks.size(); i++) + { + VirtualDisk vd = (VirtualDisk) virtual_disks.get(i); + vd.dump_xml(out); + } + out.println(""); + out.println(""); + for (Enumeration enumeration = virtual_block_devices.elements() ; + enumeration.hasMoreElements() ;) + { + VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement(); + vbd.dump_xml(out); + } + + out.println(""); + + return; + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XML.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XML.java new file mode 100755 index 0000000000..fa117802b8 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XML.java @@ -0,0 +1,126 @@ +/* + * XML.java + * 03.03.26 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; +import org.w3c.dom.Document; +import org.w3c.dom.DOMException; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class +XML +{ + static Document document = null; + + /* + * dump partition manager and virtual disk manager state to filename + */ + + static void + dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename) + { + PrintWriter out; + + try + { + out = new PrintWriter(new BufferedWriter(new FileWriter(filename))); + } + catch (IOException e) + { + System.err.println ("XML.dump_state error [" + filename + "]"); + System.err.println (e); + return; + } + + out.println(""); + out.println(""); + pm.dump_xml(out); + vdm.dump_xml(out); + out.println(""); + + out.close(); + return; + } + + /* + * load partition manager and virtual disk manager state from filename + */ + static void + load_state (PartitionManager pm, VirtualDiskManager vdm, String filename) + { + if (document == null) + { + load_file (filename); + } + + XMLHelper.parse(pm, vdm, document); + } + + /* + * load XML from disk + */ + static void + load_file (String filename) + { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // factory.setNamespaceAware(true); + // factory.setValidating(true); + + try + { + File file = new File(filename); + + DocumentBuilder builder = factory.newDocumentBuilder(); + document = builder.parse(file); + } + catch (SAXParseException spe) /* error generated by parser */ + { + System.err.println ("xml parser exception on line " + + spe.getLineNumber() + + " for uri " + spe.getSystemId()); + System.err.println (spe.getMessage()); + + Exception x = spe; + if (spe.getException() != null) + x = spe.getException(); + x.printStackTrace(); + System.exit(1); + } + catch (SAXException sxe) + { + Exception e = sxe; + if (sxe.getException() != null) + e = sxe.getException(); + e.printStackTrace(); + System.exit(1); + } + catch (ParserConfigurationException pce) + { + pce.printStackTrace(); + } + catch (FileNotFoundException fnfe) + { + System.err.println ("warning: state file not found [" + + filename + "]"); + } + catch (IOException ioe) + { + ioe.printStackTrace(); + } + return; + } +} diff --git a/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.java b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.java new file mode 100755 index 0000000000..29ef786661 --- /dev/null +++ b/tools/vdmanager/src/uk/ac/cam/cl/xeno/vdmanager/XMLHelper.java @@ -0,0 +1,205 @@ +/* + * XMLHelper.java + * 03.03.27 aho creation + */ + +package uk.ac.cam.cl.xeno.vdmanager; + +import java.util.Date; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class +XMLHelper +{ + static void + dump_document (Document document) + { + dump_element(document.getDocumentElement(), 0); + } + + static void + dump_element (Element element, int indent) + { + NodeList nl = element.getChildNodes(); + + System.out.println ("<" + element.getTagName() + ">"); + dump_nodelist(nl, indent + 1); + System.out.println(""); + } + + static void + dump_nodelist (NodeList nl, int indent) + { + for (int loop = 0; loop < nl.getLength(); loop++) + { + Node node = nl.item(loop); + switch (node.getNodeType()) + { + case Node.ELEMENT_NODE : + { + dump_element((Element)node, indent); + break; + } + case Node.TEXT_NODE : + { + System.out.println("TEXT: " + node.getNodeValue()); + break; + } + default : + { + System.out.println("NODE: " + node.getNodeType()); + } + } + } + } + + static Node + get_subnode (String name, Node node) + { + if (node.getNodeType() != Node.ELEMENT_NODE) + { + System.err.println("Error: Search node not of element type"); + return null; + } + + if (!node.hasChildNodes()) return null; + + NodeList list = node.getChildNodes(); + for (int i=0; i < list.getLength(); i++) + { + Node subnode = list.item(i); + if (subnode.getNodeType() == Node.ELEMENT_NODE) + { + if (subnode.getNodeName() == name) return subnode; + } + } + return null; + } + + static String + get_text (Node node) + { + StringBuffer result = new StringBuffer(); + if (node==null || !node.hasChildNodes()) return ""; + + NodeList list = node.getChildNodes(); + for (int i=0; i < list.getLength(); i++) + { + Node subnode = list.item(i); + if (subnode.getNodeType() == Node.TEXT_NODE) + { + result.append(subnode.getNodeValue()); + } + } + return result.toString(); + } + + static void + parse (PartitionManager pm, VirtualDiskManager vdm, Document document) + { + if (document == null) return; + + /* parse partitions */ + parse_partitions(pm, document.getElementsByTagName("partition")); + + /* parse virtual disks */ + NodeList list = document.getElementsByTagName("virtual_disk"); + for (int i = 0; i < list.getLength(); i++) + { + Node subnode = list.item(i); + String parent = subnode.getParentNode().getNodeName(); + VirtualDisk vd = parse_virtual_disk(subnode); + + if (parent.equals("free")) + { + vdm.add_free(vd); + } + else if (parent.equals("virtual_disks")) + { + vdm.add_virtual_disk(vd); + } + else + { + System.out.println ("XML parse error: unknown parent for virtual_disk " + + "[" + parent + "]"); + } + } + + /* parse virtual block devices */ + parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device")); + + return; + } + + static VirtualDisk + parse_virtual_disk(Node node) + { + VirtualDisk vd; + Date date = new Date(); + NodeList list; + + date.setTime(Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node)))); + vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)), + date, + XMLHelper.get_text(XMLHelper.get_subnode("key", node))); + + list = XMLHelper.get_subnode("extents", node).getChildNodes(); + for (int i = 0; i < list.getLength(); i++) + { + Node enode = list.item(i); + + if (enode.getNodeType() == Node.ELEMENT_NODE && + enode.getNodeName().equals("extent")) + { + Extent extent = new Extent(); + + extent.disk = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("disk", enode))); + extent.size = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("size", enode))); + extent.offset = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("offset", enode))); + vd.add_extent(extent); + } + } + + return vd; + } + + static void + parse_partitions (PartitionManager pm, NodeList nl) + { + Partition partition; + + for (int loop = 0; loop < nl.getLength(); loop++) + { + Node node = nl.item(loop); + + partition = new Partition(); + partition.major = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("major", node))); + partition.minor = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("minor", node))); + partition.blocks = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("blocks", node))); + partition.start_sect = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("start_sect", node))); + partition.nr_sects = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("nr_sects", node))); + partition.name = XMLHelper.get_text(XMLHelper.get_subnode("name", node)); + + pm.add_xeno_partition(partition); + } + } + + static void + parse_virtual_block_devices (VirtualDiskManager vdm, NodeList nl) + { + VirtualBlockDevice vbd; + + for (int loop = 0; loop < nl.getLength(); loop++) + { + Node node = nl.item(loop); + + vdm.create_virtual_block_device(XMLHelper.get_text(XMLHelper.get_subnode("key", node)), + Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("domain", node))), + Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))), + XMLHelper.get_text(XMLHelper.get_subnode("mode", node))); + } + } +} diff --git a/tools/vdmanager/vdmanager b/tools/vdmanager/vdmanager new file mode 100755 index 0000000000..e58562496b --- /dev/null +++ b/tools/vdmanager/vdmanager @@ -0,0 +1,16 @@ +#!/bin/sh + +# development only +export ANT_HOME=/anfs/scratch/boulderdash/ach61/jakarta-ant-1.5.1 +export JAVA_HOME=/anfs/scratch/labyrinth/ach61/java-1.4.1 +export PATH=${ANT_HOME}/bin:${JAVA_HOME}/bin:${PATH} + +# runtime +export JAVA_HOME=../jre-1.4.1 +export PATH=${JAVA_HOME}/bin:${PATH} +if [ -f /var/run/vdmanager.xml ] +then + cp /var/run/vdmanager.xml /var/run/vdmanager.old.xml +fi + +java -jar vdmanager.jar $* -- cgit v1.2.3