Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-changelog

[Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.0.5-testing] Merge with xen-unstable for 3.0.5-rc4.
From: "Xen patchbot-3.0.5-testing" <patchbot-3.0.5-testing@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 28 Apr 2007 10:51:01 -0700
Delivery-date: Sat, 28 Apr 2007 11:50:51 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1177752539 -3600
# Node ID 1668299c0ea4bbd530cdf67e71c64ff8baa10efb
# Parent  ee16cdeddade3ba0e826c85e84d10431edccdb15
# Parent  0f9b97523450aae06d42852bdac9bbca3d6033d1
Merge with xen-unstable for 3.0.5-rc4.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/firmware/hvmloader/smbios.h                                           |  
 38 -
 tools/xm-test/tests/network-attach/network_utils.py                         |  
 56 -
 xen/common/compat/acm_ops.c                                                 |  
 47 -
 docs/man/xm.pod.1                                                           |  
 18 
 docs/xen-api/xenapi-coversheet.tex                                          |  
  6 
 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c                        |  
  1 
 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c                         |  
  1 
 tools/blktap/drivers/block-qcow.c                                           |  
 67 +
 tools/examples/init.d/xend                                                  |  
 12 
 tools/firmware/hvmloader/acpi/acpi2_0.h                                     |  
  2 
 tools/firmware/hvmloader/config.h                                           |  
  9 
 tools/firmware/hvmloader/hvmloader.c                                        |  
 58 +
 tools/firmware/hvmloader/hypercall.h                                        |  
 11 
 tools/firmware/hvmloader/smbios.c                                           |  
 14 
 tools/firmware/hvmloader/util.c                                             |  
  1 
 tools/firmware/hvmloader/util.h                                             |  
  1 
 tools/firmware/rombios/rombios.c                                            |  
 12 
 tools/ioemu/hw/pc.c                                                         |  
 11 
 tools/libxc/xc_core_x86.c                                                   |  
  8 
 tools/libxc/xc_dom_core.c                                                   |  
  4 
 tools/libxc/xc_domain_save.c                                                |  
  2 
 tools/libxc/xc_hvm_build.c                                                  |  
 15 
 tools/libxen/Makefile                                                       |  
  4 
 tools/libxen/Makefile.dist                                                  |  
  4 
 tools/python/xen/xend/XendAPI.py                                            |  
347 ++-------
 tools/python/xen/xend/XendAPIStore.py                                       |  
 59 +
 tools/python/xen/xend/XendAPIVersion.py                                     |  
  4 
 tools/python/xen/xend/XendBase.py                                           |  
126 +++
 tools/python/xen/xend/XendConfig.py                                         |  
 10 
 tools/python/xen/xend/XendDomain.py                                         |  
  6 
 tools/python/xen/xend/XendDomainInfo.py                                     |  
 41 -
 tools/python/xen/xend/XendError.py                                          |  
120 +++
 tools/python/xen/xend/XendNetwork.py                                        |  
175 ++++
 tools/python/xen/xend/XendNode.py                                           |  
269 +++----
 tools/python/xen/xend/XendPBD.py                                            |  
108 +-
 tools/python/xen/xend/XendPIF.py                                            |  
372 +++++++---
 tools/python/xen/xend/XendPIFMetrics.py                                     |  
 40 -
 tools/python/xen/xend/XendQCoWStorageRepo.py                                |  
  2 
 tools/python/xen/xend/XendStateStore.py                                     |  
 65 -
 tools/python/xen/xend/XendStorageRepository.py                              |  
  2 
 tools/python/xen/xend/XendVMMetrics.py                                      |  
 55 -
 tools/python/xen/xend/server/SrvServer.py                                   |  
  2 
 tools/python/xen/xm/create.dtd                                              |  
  9 
 tools/python/xen/xm/create.py                                               |  
  7 
 tools/python/xen/xm/main.py                                                 |  
130 +++
 tools/python/xen/xm/messages/en/xen-xm.po                                   |  
 24 
 tools/python/xen/xm/xenapi_create.py                                        |  
 69 +
 tools/vnet/vnet-module/00README                                             |  
  4 
 tools/vnet/vnet-module/Makefile.ver                                         |  
 14 
 tools/vnet/vnet-module/varp.c                                               |  
  5 
 tools/vnet/vnet-module/vnet.c                                               |  
  9 
 tools/vnet/vnetd/Makefile                                                   |  
  4 
 tools/vnet/vnetd/sys_kernel.h                                               |  
  1 
 tools/xenstore/xenstored_core.c                                             |  
  2 
 tools/xm-test/lib/XmTestLib/network_utils.py                                |  
 60 +
 tools/xm-test/tests/network-attach/01_network_attach_pos.py                 |  
  2 
 tools/xm-test/tests/network-attach/02_network_attach_detach_pos.py          |  
  2 
 tools/xm-test/tests/network-attach/03_network_attach_detach_multiple_pos.py |  
  2 
 tools/xm-test/tests/xapi/03_xapi-network_pos.py                             |  
 71 +
 tools/xm-test/tests/xapi/Makefile.am                                        |  
  3 
 xen/Makefile                                                                |  
  2 
 xen/acm/acm_policy.c                                                        |  
  8 
 xen/arch/x86/domain.c                                                       |  
 87 +-
 xen/arch/x86/domain_build.c                                                 |  
 53 -
 xen/arch/x86/domctl.c                                                       |  
  8 
 xen/arch/x86/hvm/hvm.c                                                      |  
  4 
 xen/arch/x86/hvm/save.c                                                     |  
  2 
 xen/arch/x86/hvm/vmx/intr.c                                                 |  
  3 
 xen/arch/x86/hvm/vmx/vmcs.c                                                 |  
 86 +-
 xen/arch/x86/machine_kexec.c                                                |  
  5 
 xen/arch/x86/mm.c                                                           |  
 67 -
 xen/arch/x86/mm/shadow/common.c                                             |  
 14 
 xen/arch/x86/mm/shadow/multi.c                                              |  
 35 
 xen/arch/x86/traps.c                                                        |  
 18 
 xen/arch/x86/x86_32/entry.S                                                 |  
 11 
 xen/arch/x86/x86_64/asm-offsets.c                                           |  
  2 
 xen/arch/x86/x86_64/compat/entry.S                                          |  
 26 
 xen/arch/x86/x86_64/entry.S                                                 |  
 30 
 xen/arch/x86/x86_64/mm.c                                                    |  
  6 
 xen/arch/x86/x86_64/traps.c                                                 |  
  7 
 xen/common/Makefile                                                         |  
  1 
 xen/common/acm_ops.c                                                        |  
 49 -
 xen/common/compat/grant_table.c                                             |  
  4 
 xen/common/sched_credit.c                                                   |  
  4 
 xen/include/Makefile                                                        |  
  2 
 xen/include/acm/acm_core.h                                                  |  
  8 
 xen/include/asm-x86/desc.h                                                  |  
  4 
 xen/include/asm-x86/domain.h                                                |  
 24 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                          |  
  2 
 xen/include/asm-x86/ldt.h                                                   |  
  2 
 xen/include/asm-x86/shadow.h                                                |  
 10 
 xen/include/asm-x86/shared.h                                                |  
 94 +-
 xen/include/asm-x86/x86_64/page.h                                           |  
  4 
 xen/include/asm-x86/x86_64/regs.h                                           |  
 10 
 xen/include/public/domctl.h                                                 |  
  6 
 xen/include/public/hvm/save.h                                               |  
  7 
 xen/include/xen/sched.h                                                     |  
  8 
 xen/include/xen/shared.h                                                    |  
 20 
 xen/include/xlat.lst                                                        |  
  1 
 99 files changed, 2010 insertions(+), 1347 deletions(-)

diff -r ee16cdeddade -r 1668299c0ea4 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Wed Apr 25 10:39:08 2007 +0100
+++ b/docs/man/xm.pod.1 Sat Apr 28 10:28:59 2007 +0100
@@ -555,29 +555,29 @@ I<normal EDF (20ms/5ms):>
 I<normal EDF (20ms/5ms):>
 
     xm sched-sedf <dom-id> 20000000 5000000 0 0 0
-  
+
 I<best-effort domains (i.e. non-realtime):>
 
     xm sched-sedf <dom-id> 20000000 0 0 1 0
- 
+
 I<normal EDF (20ms/5ms) + share of extra-time:>
-  
+
     xm sched-sedf <dom-id> 20000000 5000000 0 1 0
 
 I<4 domains with weights 2:3:4:2>
 
     xm sched-sedf <d1> 0 0 0 0 2
-    xm sched-sedf <d2> 0 0 0 0 3
-    xm sched-sedf <d3> 0 0 0 0 4
-    xm sched-sedf <d4> 0 0 0 0 2
+    xm sched-sedf <d2> 0 0 0 0 3
+    xm sched-sedf <d3> 0 0 0 0 4
+    xm sched-sedf <d4> 0 0 0 0 2
   
 I<1 fully-specified (10ms/3ms) domain, 3 other domains share available
 rest in 2:7:3 ratio:>
 
-    xm sched-sedf <d1> 10000000 3000000 0 0 0   
-    xm sched-sedf <d2> 0 0 0 0 2   
+    xm sched-sedf <d1> 10000000 3000000 0 0 0
+    xm sched-sedf <d2> 0 0 0 0 2
     xm sched-sedf <d3> 0 0 0 0 7
-    xm sched-sedf <d4> 0 0 0 0 3
+    xm sched-sedf <d4> 0 0 0 0 3
 
 =back
 
diff -r ee16cdeddade -r 1668299c0ea4 docs/xen-api/xenapi-coversheet.tex
--- a/docs/xen-api/xenapi-coversheet.tex        Wed Apr 25 10:39:08 2007 +0100
+++ b/docs/xen-api/xenapi-coversheet.tex        Sat Apr 28 10:28:59 2007 +0100
@@ -17,12 +17,12 @@
 \newcommand{\coversheetlogo}{xen.eps}
 
 %% Document date
-\newcommand{\datestring}{21st April 2007}
+\newcommand{\datestring}{27th April 2007}
 
-\newcommand{\releasestatement}{Candidate for Release\\Comments are welcome!}
+\newcommand{\releasestatement}{Stable Release}
 
 %% Document revision
-\newcommand{\revstring}{API Revision 0.9.1}
+\newcommand{\revstring}{API Revision 1.0.0}
 
 %% Document authors
 \newcommand{\docauthors}{
diff -r ee16cdeddade -r 1668299c0ea4 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Wed Apr 25 
10:39:08 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Sat Apr 28 
10:28:59 2007 +0100
@@ -136,6 +136,7 @@ int blkif_map(blkif_t *blkif, unsigned l
        {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
+               blkif->blk_rings.common.sring = NULL;
                return err;
        }
        blkif->irq = err;
diff -r ee16cdeddade -r 1668299c0ea4 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Wed Apr 25 
10:39:08 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Sat Apr 28 
10:28:59 2007 +0100
@@ -137,6 +137,7 @@ int tap_blkif_map(blkif_t *blkif, unsign
        if (err < 0) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
+               blkif->blk_rings.common.sring = NULL;
                return err;
        }
        blkif->irq = err;
diff -r ee16cdeddade -r 1668299c0ea4 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/blktap/drivers/block-qcow.c Sat Apr 28 10:28:59 2007 +0100
@@ -55,7 +55,6 @@
 
 /******AIO DEFINES******/
 #define REQUEST_ASYNC_FD 1
-#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
 
 struct pending_aio {
         td_callback_t cb;
@@ -146,18 +145,37 @@ struct tdqcow_state {
        AES_KEY aes_encrypt_key;       /*AES key*/
        AES_KEY aes_decrypt_key;       /*AES key*/
         /* libaio state */
-        io_context_t       aio_ctx;
-        struct iocb        iocb_list  [MAX_AIO_REQS];
-        struct iocb       *iocb_free  [MAX_AIO_REQS];
-        struct pending_aio pending_aio[MAX_AIO_REQS];
-        int                iocb_free_count;
-        struct iocb       *iocb_queue[MAX_AIO_REQS];
-        int                iocb_queued;
-        int                poll_fd;      /* NB: we require aio_poll support */
-        struct io_event    aio_events[MAX_AIO_REQS];
+        io_context_t        aio_ctx;
+        int                 max_aio_reqs;
+        struct iocb        *iocb_list;
+        struct iocb       **iocb_free;
+        struct pending_aio *pending_aio;
+        int                 iocb_free_count;
+        struct iocb       **iocb_queue;
+        int                 iocb_queued;
+        int                 poll_fd;      /* NB: we require aio_poll support */
+        struct io_event    *aio_events;
 };
 
 static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
+
+static void free_aio_state(struct disk_driver *dd)
+{
+        struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+
+        if (s->sector_lock)
+                free(s->sector_lock);
+        if (s->iocb_list)
+                free(s->iocb_list);
+        if (s->pending_aio)
+                free(s->pending_aio);
+        if (s->aio_events)
+                free(s->aio_events);
+        if (s->iocb_free)
+                free(s->iocb_free);
+        if (s->iocb_queue)
+                free(s->iocb_queue);
+}
 
 static int init_aio_state(struct disk_driver *dd)
 {
@@ -166,6 +184,12 @@ static int init_aio_state(struct disk_dr
        struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
         long     ioidx;
 
+        s->iocb_list = NULL;
+        s->pending_aio = NULL;
+        s->aio_events = NULL;
+        s->iocb_free = NULL;
+        s->iocb_queue = NULL;
+
         /*Initialize Locking bitmap*/
        s->sector_lock = calloc(1, bs->size);
        
@@ -174,13 +198,26 @@ static int init_aio_state(struct disk_dr
                goto fail;
        }
 
+        /* A segment (i.e. a page) can span multiple clusters */
+        s->max_aio_reqs = (getpagesize() / s->cluster_size) + 1;
+
         /* Initialize AIO */
-        s->iocb_free_count = MAX_AIO_REQS;
+        s->iocb_free_count = s->max_aio_reqs;
         s->iocb_queued     = 0;
+
+        if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) ||
+            !(s->pending_aio = malloc(sizeof(struct pending_aio) * 
s->max_aio_reqs)) ||
+            !(s->aio_events = malloc(sizeof(struct io_event) * 
s->max_aio_reqs)) ||
+            !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) 
||
+            !(s->iocb_queue = malloc(sizeof(struct iocb *) * 
s->max_aio_reqs))) {
+                DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
+                        s->max_aio_reqs);
+                goto fail;
+        }
 
         /*Signal kernel to create Poll FD for Asyc completion events*/
         s->aio_ctx = (io_context_t) REQUEST_ASYNC_FD;   
-        s->poll_fd = io_setup(MAX_AIO_REQS, &s->aio_ctx);
+        s->poll_fd = io_setup(s->max_aio_reqs, &s->aio_ctx);
 
        if (s->poll_fd < 0) {
                 if (s->poll_fd == -EAGAIN) {
@@ -198,7 +235,7 @@ static int init_aio_state(struct disk_dr
                goto fail;
        }
 
-        for (i=0;i<MAX_AIO_REQS;i++)
+        for (i=0;i<s->max_aio_reqs;i++)
                 s->iocb_free[i] = &s->iocb_list[i];
 
         DPRINTF("AIO state initialised\n");
@@ -946,6 +983,7 @@ int tdqcow_open (struct disk_driver *dd,
  end_xenhdr:
        if (init_aio_state(dd)!=0) {
                DPRINTF("Unable to initialise AIO state\n");
+                free_aio_state(dd);
                goto fail;
        }
        init_fds(dd);
@@ -962,6 +1000,7 @@ int tdqcow_open (struct disk_driver *dd,
        
 fail:
        DPRINTF("QCOW Open failed\n");
+       free_aio_state(dd);
        free(s->l1_table);
        free(s->l2_cache);
        free(s->cluster_cache);
@@ -1145,7 +1184,7 @@ int tdqcow_do_callbacks(struct disk_driv
         if (sid > MAX_IOFD) return 1;
        
        /* Non-blocking test for completed io. */
-        ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
+        ret = io_getevents(prv->aio_ctx, 0, prv->max_aio_reqs, prv->aio_events,
                            NULL);
 
         for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
diff -r ee16cdeddade -r 1668299c0ea4 tools/examples/init.d/xend
--- a/tools/examples/init.d/xend        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/examples/init.d/xend        Sat Apr 28 10:28:59 2007 +0100
@@ -6,6 +6,18 @@
 #
 # chkconfig: 2345 98 01
 # description: Starts and stops the Xen control daemon.
+### BEGIN INIT INFO
+# Provides:          xend
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop xend
+# Description:       Starts and stops the Xen control daemon.
+### END INIT INFO
 
 if ! grep -q "control_d" /proc/xen/capabilities ; then
        exit 0
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Sat Apr 28 10:28:59 2007 +0100
@@ -394,8 +394,6 @@ struct acpi_20_madt_intsrcovr {
 
 #pragma pack ()
 
-#define ACPI_PHYSICAL_ADDRESS 0xEA000
-
 int acpi_build_tables(uint8_t *);
 
 #endif /* _ACPI_2_0_H_ */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/config.h Sat Apr 28 10:28:59 2007 +0100
@@ -17,5 +17,14 @@
 #define ROMBIOS_MAXOFFSET      0x0000FFFF
 #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
 
+/* Memory map. */
+#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
+#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
+#define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
+#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
+#define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
+#define SMBIOS_MAXIMUM_SIZE           0x00001000
+#define ACPI_PHYSICAL_ADDRESS         0x000EA000
+#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
 
 #endif /* __HVMLOADER_CONFIG_H__ */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Sat Apr 28 10:28:59 2007 +0100
@@ -19,23 +19,16 @@
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
+
 #include "roms.h"
-#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "acpi/acpi2_0.h"
 #include "hypercall.h"
 #include "util.h"
-#include "smbios.h"
 #include "config.h"
 #include "apic_regs.h"
 #include "pci_regs.h"
 #include <xen/version.h>
 #include <xen/hvm/params.h>
-
-/* memory map */
-#define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
-#define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
-#define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
-#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
-#define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
 
 asm(
     "    .text                       \n"
@@ -103,7 +96,8 @@ asm(
     "stack_top:                      \n"
     );
 
-extern void create_mp_tables(void);
+void create_mp_tables(void);
+int hvm_write_smbios_tables(void);
 
 static int
 cirrus_check(void)
@@ -351,17 +345,20 @@ static void cmos_write_memory_size(void)
 
 int main(void)
 {
-    int acpi_sz;
+    int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
 
     printf("HVM Loader\n");
 
     init_hypercalls();
 
     printf("Writing SMBIOS tables ...\n");
-    hvm_write_smbios_tables();
+    smbios_sz = hvm_write_smbios_tables();
 
     printf("Loading ROMBIOS ...\n");
-    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+    rombios_sz = sizeof(rombios);
+    if ( rombios_sz > 0x10000 )
+        rombios_sz = 0x10000;
+    memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz);
     highbios_setup();
 
     apic_setup();
@@ -375,12 +372,14 @@ int main(void)
         printf("Loading Cirrus VGABIOS ...\n");
         memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
                vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
+        vgabios_sz = sizeof(vgabios_cirrusvga);
     }
     else
     {
         printf("Loading Standard VGABIOS ...\n");
         memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
                vgabios_stdvga, sizeof(vgabios_stdvga));
+        vgabios_sz = sizeof(vgabios_stdvga);
     }
 
     if ( must_load_nic() )
@@ -388,9 +387,10 @@ int main(void)
         printf("Loading ETHERBOOT ...\n");
         memcpy((void *)ETHERBOOT_PHYSICAL_ADDRESS,
                etherboot, sizeof(etherboot));
-    }
-
-    if ( get_acpi_enabled() != 0 )
+        etherboot_sz = sizeof(etherboot);
+    }
+
+    if ( get_acpi_enabled() )
     {
         printf("Loading ACPI ...\n");
         acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
@@ -398,6 +398,32 @@ int main(void)
     }
 
     cmos_write_memory_size();
+
+    printf("BIOS map:\n");
+    if ( vgabios_sz )
+        printf(" %05x-%05x: VGA BIOS\n",
+               VGABIOS_PHYSICAL_ADDRESS,
+               VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1);
+    if ( etherboot_sz )
+        printf(" %05x-%05x: Etherboot ROM\n",
+               ETHERBOOT_PHYSICAL_ADDRESS,
+               ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
+    if ( !check_amd() )
+        printf(" %05x-%05x: VMXAssist\n",
+               VMXASSIST_PHYSICAL_ADDRESS,
+               VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
+    if ( smbios_sz )
+        printf(" %05x-%05x: SMBIOS tables\n",
+               SMBIOS_PHYSICAL_ADDRESS,
+               SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
+    if ( acpi_sz )
+        printf(" %05x-%05x: ACPI tables\n",
+               ACPI_PHYSICAL_ADDRESS,
+               ACPI_PHYSICAL_ADDRESS + acpi_sz - 1);
+    if ( rombios_sz )
+        printf(" %05x-%05x: Main BIOS\n",
+               ROMBIOS_PHYSICAL_ADDRESS,
+               ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
 
     if ( !check_amd() )
     {
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/hypercall.h
--- a/tools/firmware/hvmloader/hypercall.h      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/hypercall.h      Sat Apr 28 10:28:59 2007 +0100
@@ -31,17 +31,18 @@
 #ifndef __HVMLOADER_HYPERCALL_H__
 #define __HVMLOADER_HYPERCALL_H__
 
+#include <stdint.h>
 #include <xen/xen.h>
+#include "config.h"
+
+#define __STR(...) #__VA_ARGS__
+#define STR(...) __STR(__VA_ARGS__)
 
 /*
  * NB. Hypercall address needs to be relative to a linkage symbol for
  * some version of ld to relocate the relative calls properly.
- * Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c!
  */
-#define hypercall_pa "_start - 0x80000"
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
+#define hypercall_pa "_start - " STR(HYPERCALL_PHYSICAL_ADDRESS)
 
 #define _hypercall0(type, name)                                                
\
 ({                                                                     \
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/smbios.c Sat Apr 28 10:28:59 2007 +0100
@@ -22,12 +22,11 @@
 
 #include <stdint.h>
 #include <xen/version.h>
-#include "smbios.h"
 #include "smbios_types.h"
 #include "util.h"
 #include "hypercall.h"
 
-static size_t
+static int
 write_smbios_tables(void *start,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
@@ -82,7 +81,7 @@ get_cpu_manufacturer(char *buf, int len)
         strncpy(buf, "unknown", len);
 }
 
-static size_t
+static int
 write_smbios_tables(void *start,
                     uint32_t vcpus, uint64_t memsize,
                     uint8_t uuid[16], char *xen_version,
@@ -125,7 +124,7 @@ write_smbios_tables(void *start,
         SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
         nr_structs);
 
-    return (size_t)((char *)p - (char *)start);
+    return ((char *)p - (char *)start);
 }
 
 /* Calculate how much pseudo-physical memory (in MB) is allocated to us. */
@@ -156,7 +155,7 @@ get_memsize(void)
     return (memsize + (1 << 20) - 1) >> 20;
 }
 
-void
+int
 hvm_write_smbios_tables(void)
 {
     uint8_t uuid[16]; /* ** This will break if xen_domain_handle_t is
@@ -221,16 +220,17 @@ hvm_write_smbios_tables(void)
                               get_vcpu_nr(), get_memsize(),
                               uuid, xen_version_str,
                               xen_major_version, xen_minor_version);
-    if ( len > SMBIOS_SIZE_LIMIT )
+    if ( len > SMBIOS_MAXIMUM_SIZE )
         goto error_out;
     /* Okay, not too large: copy out of scratch to final location. */
     memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
 
-    return;
+    return len;
 
  error_out:
     printf("Could not write SMBIOS tables, error in hvmloader.c:"
            "hvm_write_smbios_tables()\n");
+    return 0;
 }
 
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/smbios.h
--- a/tools/firmware/hvmloader/smbios.h Wed Apr 25 10:39:08 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * smbios.h - interface for Xen HVM SMBIOS generation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2006
- *
- * Authors: Andrew D. Ball <aball@xxxxxxxxxx>
- */
-
-#ifndef SMBIOS_H
-#define SMBIOS_H
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/* These constants must agree with the ACPI e820 memory map as defined
-   in tools/libxc/xc_hvm_build.c and the address the ROMBIOS pulls the
-   SMBIOS entry point from in the smbios_init subroutine.
- */
-#define SMBIOS_PHYSICAL_ADDRESS 0x9f000
-#define SMBIOS_SIZE_LIMIT 0x800
-
-void hvm_write_smbios_tables(void);
-
-#endif /* SMBIOS_H */
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/util.c   Sat Apr 28 10:28:59 2007 +0100
@@ -18,7 +18,6 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
-#include "acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
 #include "util.h"
 #include "config.h"
 #include <stdint.h>
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/hvmloader/util.h   Sat Apr 28 10:28:59 2007 +0100
@@ -2,6 +2,7 @@
 #define __HVMLOADER_UTIL_H__
 
 #include <stdarg.h>
+#include <stdint.h>
 
 #undef offsetof
 #define offsetof(t, m) ((unsigned long)&((t *)0)->m)
diff -r ee16cdeddade -r 1668299c0ea4 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/firmware/rombios/rombios.c  Sat Apr 28 10:28:59 2007 +0100
@@ -25,6 +25,8 @@
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 // ROM BIOS for use with Bochs/Plex x86 emulation environment
+
+#include "../hvmloader/config.h"
 
 #define HVMASSIST
 #undef HVMTEST
@@ -9409,9 +9411,9 @@ rom_scan_increment:
 
 #ifdef HVMASSIST
 
-; Copy the SMBIOS entry point over from 0x9f000, where hvmloader left it.
+; Copy the SMBIOS entry point from where hvmloader left it.
 ; The entry point must be somewhere in 0xf0000-0xfffff on a 16-byte boundary,
-; but the tables themeselves can be elsewhere.
+; but the tables themselves can be elsewhere.
 smbios_init:
   push ax
   push cx
@@ -9424,9 +9426,9 @@ smbios_init:
   mov ax, #0xf000
   mov es, ax      ; destination segment is 0xf0000
   mov di, #smbios_entry_point ; destination offset
-  mov ax, #0x9f00
-  mov ds, ax      ; source segment is 0x9f000
-  mov si, #0x0000 ; source offset is 0
+  mov ax, #(SMBIOS_PHYSICAL_ADDRESS>>4)
+  mov ds, ax
+  mov si, #(SMBIOS_PHYSICAL_ADDRESS&15)
   cld
   rep
     movsb
diff -r ee16cdeddade -r 1668299c0ea4 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/ioemu/hw/pc.c       Sat Apr 28 10:28:59 2007 +0100
@@ -922,12 +922,13 @@ static void pc_init1(uint64_t ram_size, 
 #endif
 #else
     if (pci_enabled) {
-        void *scsi;
-
-        scsi = lsi_scsi_init(pci_bus, -1);
+        void *scsi = NULL;
         for (i = 0; i < MAX_SCSI_DISKS ; i++) {
-            if (bs_table[i + MAX_DISKS]) 
-                lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
+            if (!bs_table[i + MAX_DISKS])
+                continue;
+            if (!scsi)
+                scsi = lsi_scsi_init(pci_bus, -1);
+            lsi_scsi_attach(scsi, bs_table[i + MAX_DISKS], -1);
         }
     }
 #endif /* !CONFIG_DM */
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_core_x86.c
--- a/tools/libxc/xc_core_x86.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_core_x86.c Sat Apr 28 10:28:59 2007 +0100
@@ -21,9 +21,9 @@
 #include "xg_private.h"
 #include "xc_core.h"
 
-static int max_gpfn(int xc_handle, domid_t domid)
+static int nr_gpfns(int xc_handle, domid_t domid)
 {
-    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
+    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid) + 1;
 }
 
 int
@@ -38,7 +38,7 @@ xc_core_arch_memory_map_get(int xc_handl
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
-    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
+    unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
     xc_core_memory_map_t *map;
 
     map = malloc(sizeof(*map));
@@ -65,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
     xen_pfn_t *live_p2m_frame_list_list = NULL;
     xen_pfn_t *live_p2m_frame_list = NULL;
     uint32_t dom = info->domid;
-    unsigned long p2m_size = max_gpfn(xc_handle, info->domid);
+    unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
     int ret = -1;
     int err;
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_dom_core.c Sat Apr 28 10:28:59 2007 +0100
@@ -209,13 +209,13 @@ size_t xc_dom_check_gzip(void *blob, siz
     unsigned char *gzlen;
     size_t unziplen;
 
-    if (strncmp(blob, "\037\213", 2))
+    if ( strncmp(blob, "\037\213", 2) )
         /* not gzipped */
         return 0;
 
     gzlen = blob + ziplen - 4;
     unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0];
-    if ( (unziplen < ziplen) || (unziplen > (ziplen * 8)) )
+    if ( (unziplen < 0) || (unziplen > (1024*1024*1024)) ) /* 1GB limit */
     {
         xc_dom_printf
             ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n",
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_domain_save.c      Sat Apr 28 10:28:59 2007 +0100
@@ -870,7 +870,7 @@ int xc_domain_save(int xc_handle, int io
     }
 
     /* Get the size of the P2M table */
-    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
+    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;
 
     /* Domain is still running at this point */
     if ( live )
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxc/xc_hvm_build.c        Sat Apr 28 10:28:59 2007 +0100
@@ -47,20 +47,15 @@ static void build_e820map(void *e820_pag
         mem_size = HVM_BELOW_4G_RAM_END;
     }
 
-    /* 0x0-0x9F000: Ordinary RAM. */
+    /* 0x0-0x9FC00: Ordinary RAM. */
     e820entry[nr_map].addr = 0x0;
-    e820entry[nr_map].size = 0x9F000;
+    e820entry[nr_map].size = 0x9FC00;
     e820entry[nr_map].type = E820_RAM;
     nr_map++;
 
-    /*
-     * 0x9F000-0x9F800: SMBIOS tables.
-     * 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA).
-     * TODO: SMBIOS tables should be moved higher (>=0xE0000).
-     *       They are unusually low in our memory map: could cause problems?
-     */
-    e820entry[nr_map].addr = 0x9F000;
-    e820entry[nr_map].size = 0x1000;
+    /* 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). */
+    e820entry[nr_map].addr = 0x9FC00;
+    e820entry[nr_map].size = 0x400;
     e820entry[nr_map].type = E820_RESERVED;
     nr_map++;
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile
--- a/tools/libxen/Makefile     Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxen/Makefile     Sat Apr 28 10:28:59 2007 +0100
@@ -18,8 +18,8 @@ XEN_ROOT=../..
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-MAJOR = 0.9
-MINOR = 1
+MAJOR = 1.0
+MINOR = 0
 
 CFLAGS = -Iinclude                     \
          $(shell xml2-config --cflags) \
diff -r ee16cdeddade -r 1668299c0ea4 tools/libxen/Makefile.dist
--- a/tools/libxen/Makefile.dist        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/libxen/Makefile.dist        Sat Apr 28 10:28:59 2007 +0100
@@ -16,8 +16,8 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 #
 
-MAJOR = 0.9
-MINOR = 1
+MAJOR = 1.0
+MINOR = 0
 
 CFLAGS = -Iinclude                     \
          $(shell xml2-config --cflags) \
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendAPI.py  Sat Apr 28 10:28:59 2007 +0100
@@ -27,7 +27,7 @@ import xmlrpclib
 import xmlrpclib
 
 import XendDomain, XendDomainInfo, XendNode, XendDmesg
-import XendLogging, XendTaskManager
+import XendLogging, XendTaskManager, XendAPIStore
 
 from XendAPIVersion import *
 from XendAuthSessions import instance as auth_manager
@@ -38,8 +38,8 @@ from XendTask import XendTask
 from XendTask import XendTask
 from XendPIFMetrics import XendPIFMetrics
 from XendVMMetrics import XendVMMetrics
-
-import XendPBD
+from XendPIF import XendPIF
+from XendPBD import XendPBD
 
 from XendAPIConstants import *
 from xen.util.xmlrpclib2 import stringify
@@ -237,6 +237,8 @@ def catch_typeerror(func):
                     finally:
                         del tb
             raise
+        except XendAPIError, exn:
+            return xen_api_error(exn.get_api_error())
 
     return f
 
@@ -307,26 +309,6 @@ def valid_vm(func):
            _check_ref(XendDomain.instance().is_valid_vm,
                       'VM', func, *args, **kwargs)
 
-def valid_vm_metrics(func):
-    """Decorator to verify if vm_metrics_ref is valid before calling method.
-
-    @param func: function with params: (self, session, vm_metrics_ref, ...)
-    @rtype: callable object
-    """    
-    return lambda *args, **kwargs: \
-           _check_ref(XendVMMetrics.is_valid_vm_metrics,
-                      'VM_metrics', func, *args, **kwargs)
-
-def valid_network(func):
-    """Decorator to verify if network_ref is valid before calling method.
-
-    @param func: function with params: (self, session, network_ref, ...)
-    @rtype: callable object
-    """    
-    return lambda *args, **kwargs: \
-           _check_ref(XendNode.instance().is_valid_network,
-                      'network', func, *args, **kwargs)
-
 def valid_vbd(func):
     """Decorator to verify if vbd_ref is valid before calling method.
 
@@ -409,39 +391,6 @@ def valid_sr(func):
            _check_ref(lambda r: XendNode.instance().is_valid_sr,
                       'SR', func, *args, **kwargs)
 
-def valid_pbd(func):
-    """Decorator to verify if pbd_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pbd_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendPBD.get_all_refs(),
-                      'PBD', func, *args, **kwargs)
-
-def valid_pif(func):
-    """Decorator to verify if pif_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pif_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendNode.instance().pifs,
-                      'PIF', func, *args, **kwargs)
-
-def valid_pif_metrics(func):
-    """Decorator to verify if pif_metrics_ref is valid before calling
-    method.
-
-    @param func: function with params: (self, session, pif_metrics_ref)
-    @rtype: callable object
-    """
-    return lambda *args, **kwargs: \
-           _check_ref(lambda r: r in XendNode.instance().pif_metrics,
-                      'PIF_metrics', func, *args, **kwargs)
-
 def valid_task(func):
     """Decorator to verify if task_ref is valid before calling
     method.
@@ -463,6 +412,20 @@ def valid_debug(func):
     return lambda *args, **kwargs: \
            _check_ref(lambda r: r in XendAPI._debug,
                       'debug', func, *args, **kwargs)
+
+
+def valid_object(class_name):
+    """Decorator to verify if object is valid before calling
+    method.
+
+    @param func: function with params: (self, session, pif_ref)
+    @rtype: callable object
+    """
+    return lambda func: \
+           lambda *args, **kwargs: \
+           _check_ref(lambda r: \
+                          XendAPIStore.get(r, class_name) is not None,
+                      'PIF', func, *args, **kwargs)
 
 # -----------------------------
 # Bridge to Legacy XM API calls
@@ -494,9 +457,7 @@ classes = {
     'host'         : valid_host,
     'host_cpu'     : valid_host_cpu,
     'host_metrics' : valid_host_metrics,
-    'network'      : valid_network,
     'VM'           : valid_vm,
-    'VM_metrics'   : valid_vm_metrics,
     'VBD'          : valid_vbd,
     'VBD_metrics'  : valid_vbd_metrics,
     'VIF'          : valid_vif,
@@ -505,20 +466,22 @@ classes = {
     'VTPM'         : valid_vtpm,
     'console'      : valid_console,
     'SR'           : valid_sr,
-    'PBD'          : valid_pbd,
-    'PIF'          : valid_pif,
-    'PIF_metrics'  : valid_pif_metrics,
     'task'         : valid_task,
     'debug'        : valid_debug,
+    'network'      : valid_object("network"),
+    'PIF'          : valid_object("PIF"),
+    'VM_metrics'   : valid_object("VM_metrics"),
+    'PBD'          : valid_object("PBD"),
+    'PIF_metrics'  : valid_object("PIF_metrics")
 }
 
 autoplug_classes = {
     'network'     : XendNetwork,
+    'PIF'         : XendPIF,
     'VM_metrics'  : XendVMMetrics,
-    'PBD'         : XendPBD.XendPBD,
+    'PBD'         : XendPBD,
     'PIF_metrics' : XendPIFMetrics,
 }
-
 
 class XendAPI(object):
     """Implementation of the Xen-API in Xend. Expects to be
@@ -570,7 +533,9 @@ class XendAPI(object):
         #    all get_by_uuid() methods.
         
         for api_cls in classes.keys():
-            if api_cls == 'session':
+            # We'll let the autoplug classes implement these functions
+            # themselves - its much cleaner to do it in the base class
+            if api_cls == 'session' or api_cls in autoplug_classes.keys():
                 continue
             
             get_by_uuid = '%s_get_by_uuid' % api_cls
@@ -588,8 +553,8 @@ class XendAPI(object):
 
             def _get_all_records(_api_cls):
                 return lambda s, session: \
-                    xen_api_success([unpack(getattr(cls, '%s_get_record' % 
_api_cls)(s, session, ref))\
-                                     for ref in unpack(getattr(cls, 
'%s_get_all' % _api_cls)(s, session))])
+                    xen_api_success(dict([(ref, unpack(getattr(cls, 
'%s_get_record' % _api_cls)(s, session, ref)))\
+                                          for ref in unpack(getattr(cls, 
'%s_get_all' % _api_cls)(s, session))]))
 
             setattr(cls, get_by_uuid, _get_by_uuid)
             setattr(cls, get_uuid,    _get_uuid)
@@ -599,34 +564,48 @@ class XendAPI(object):
         # --------------------
         # These have all of their methods grabbed out from the implementation
         # class, and wrapped up to be compatible with the Xen-API.
+
+        def getter(ref, type):
+            return XendAPIStore.get(ref, type)
         
         for api_cls, impl_cls in autoplug_classes.items():
-            def doit(n):
-                getter = getattr(cls, '_%s_get' % api_cls)
+            def doit(n):           
                 dot_n = '%s.%s' % (api_cls, n)
                 full_n = '%s_%s' % (api_cls, n)
                 if not hasattr(cls, full_n):
                     f = getattr(impl_cls, n)
                     argcounts[dot_n] = f.func_code.co_argcount + 1
-                    setattr(cls, full_n,
+                    g = lambda api_cls: \
+                    setattr(cls, full_n, \
                             lambda s, session, ref, *args: \
                                xen_api_success( \
-                                   f(getter(s, session, ref), *args)))
-
-            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
-            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
-            methods  = getattr(cls, '%s_methods' % api_cls, [])
-            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+                                   f(getter(ref, api_cls), *args)))
+                    g(api_cls) # Force api_cls to be captured
+                    
+            def doit_func(n):           
+                dot_n = '%s.%s' % (api_cls, n)
+                full_n = '%s_%s' % (api_cls, n)
+                if not hasattr(cls, full_n):
+                    f = getattr(impl_cls, n)
+                    argcounts[dot_n] = f.func_code.co_argcount
+                    setattr(cls, full_n, \
+                            lambda s, session, *args: \
+                               xen_api_success( \
+                                   f(*args)))
+
+            ro_attrs = impl_cls.getAttrRO()
+            rw_attrs = impl_cls.getAttrRW()
+            methods  = impl_cls.getMethods()
+            funcs    = impl_cls.getFuncs()
             
             for attr_name in ro_attrs + rw_attrs:
                 doit('get_%s' % attr_name)
-            for attr_name in rw_attrs + cls.Base_attr_rw:
+            for attr_name in rw_attrs:
                 doit('set_%s' % attr_name)
-            for method_name, return_type in methods + cls.Base_methods:
-                doit('%s' % method_name)
-            for func_name, return_type in funcs + cls.Base_funcs:
-                doit('%s' % func_name)
-
+            for method in methods:
+                doit('%s' % method)
+            for func in funcs:
+                doit_func('%s' % func)
 
         def wrap_method(name, new_f):
             try:
@@ -692,31 +671,42 @@ class XendAPI(object):
                 except AttributeError:
                     log.warn("API call: %s not found" % n)
 
-
-            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
-            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
-            methods  = getattr(cls, '%s_methods' % api_cls, [])
-            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+            if api_cls in autoplug_classes.keys():
+                impl_cls = autoplug_classes[api_cls]
+                ro_attrs = impl_cls.getAttrRO()
+                rw_attrs = impl_cls.getAttrRW()
+                methods  = map(lambda x: (x, ""), impl_cls.getMethods())
+                funcs    = map(lambda x: (x, ""), impl_cls.getFuncs())
+            else:
+                ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) \
+                           + cls.Base_attr_ro
+                rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) \
+                           + cls.Base_attr_rw
+                methods  = getattr(cls, '%s_methods' % api_cls, []) \
+                           + cls.Base_methods
+                funcs    = getattr(cls, '%s_funcs'   % api_cls, []) \
+                           + cls.Base_funcs
 
             # wrap validators around readable class attributes
-            for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro:
+            for attr_name in ro_attrs + rw_attrs:
                 doit('%s.get_%s' % (api_cls, attr_name), True,
                      async_support = False)
 
             # wrap validators around writable class attrributes
-            for attr_name in rw_attrs + cls.Base_attr_rw:
+            for attr_name in rw_attrs:
                 doit('%s.set_%s' % (api_cls, attr_name), True,
                      async_support = False)
                 setter_event_wrapper(api_cls, attr_name)
 
             # wrap validators around methods
-            for method_name, return_type in methods + cls.Base_methods:
+            for method_name, return_type in methods:
                 doit('%s.%s' % (api_cls, method_name), True,
                      async_support = True)
 
             # wrap validators around class functions
-            for func_name, return_type in funcs + cls.Base_funcs:
-                doit('%s.%s' % (api_cls, func_name), False, async_support = 
True,
+            for func_name, return_type in funcs:
+                doit('%s.%s' % (api_cls, func_name), False,
+                     async_support = True,
                      return_type = return_type)
 
             ctor_event_wrapper(api_cls)
@@ -952,7 +942,7 @@ class XendAPI(object):
     def host_get_resident_VMs(self, session, host_ref):
         return xen_api_success(XendDomain.instance().get_domain_refs())
     def host_get_PBDs(self, _, ref):
-        return xen_api_success(XendPBD.get_all_refs())
+        return xen_api_success(XendPBD.get_all())
     def host_get_PIFs(self, session, ref):
         return xen_api_success(XendNode.instance().get_PIF_refs())
     def host_get_host_CPUs(self, session, host_ref):
@@ -1130,130 +1120,6 @@ class XendAPI(object):
     def _host_metrics_get_memory_free(self):
         node = XendNode.instance()
         return node.xc.physinfo()['free_memory'] * 1024
-
-
-    # Xen API: Class network
-    # ----------------------------------------------------------------
-
-    network_attr_ro = ['VIFs', 'PIFs']
-    network_attr_rw = ['name_label',
-                       'name_description',
-                       'other_config']
-    network_methods = [('add_to_other_config', None),
-                       ('remove_from_other_config', None),
-                       ('destroy', None)]
-    network_funcs = [('create', None)]
-    
-    def _network_get(self, _, ref):
-        return XendNode.instance().get_network(ref)
-
-    def network_get_all(self, _):
-        return xen_api_success(XendNode.instance().get_network_refs())
-
-    def network_create(self, _, record):
-        return xen_api_success(XendNode.instance().network_create(record))
-
-    def network_destroy(self, _, ref):
-        return xen_api_success(XendNode.instance().network_destroy(ref))
-
-
-    # Xen API: Class PIF
-    # ----------------------------------------------------------------
-
-    PIF_attr_ro = ['network',
-                   'host',
-                   'metrics']
-    PIF_attr_rw = ['device',
-                   'MAC',
-                   'MTU',
-                   'VLAN']
-
-    PIF_attr_inst = PIF_attr_rw
-
-    PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
-
-    def _get_PIF(self, ref):
-        return XendNode.instance().pifs[ref]
-
-    def PIF_destroy(self, _, ref):
-        try:
-            return xen_api_success(XendNode.instance().PIF_destroy(ref))
-        except PIFIsPhysical, exn:
-            return xen_api_error(['PIF_IS_PHYSICAL', ref])
-
-    # object methods
-    def PIF_get_record(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).get_record())
-
-    def PIF_get_all(self, _):
-        return xen_api_success(XendNode.instance().pifs.keys())
-
-    def PIF_get_metrics(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).metrics.uuid)
-
-    def PIF_get_device(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).device)
-
-    def PIF_get_network(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).network.uuid)
-
-    def PIF_get_host(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).host.uuid)
-
-    def PIF_get_MAC(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).mac)
-
-    def PIF_get_MTU(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).mtu)
-
-    def PIF_get_VLAN(self, _, ref):
-        return xen_api_success(self._get_PIF(ref).vlan)
-
-    def PIF_set_device(self, _, ref, device):
-        return xen_api_success(self._get_PIF(ref).set_device(device))
-
-    def PIF_set_MAC(self, _, ref, mac):
-        return xen_api_success(self._get_PIF(ref).set_mac(mac))
-
-    def PIF_set_MTU(self, _, ref, mtu):
-        return xen_api_success(self._get_PIF(ref).set_mtu(mtu))
-
-    def PIF_create_VLAN(self, _, ref, network, vlan):
-        try:
-            vlan = int(vlan)
-        except:
-            return xen_api_error(['VLAN_TAG_INVALID', vlan])
-
-        try:
-            node = XendNode.instance()
-            
-            if _is_valid_ref(network, node.is_valid_network):
-                return xen_api_success(
-                    node.PIF_create_VLAN(ref, network, vlan))
-            else:
-                return xen_api_error(['HANDLE_INVALID', 'network', network])
-        except NetworkAlreadyConnected, exn:
-            return xen_api_error(['NETWORK_ALREADY_CONNECTED',
-                                  network, exn.pif_uuid])
-        except VLANTagInvalid:
-            return xen_api_error(['VLAN_TAG_INVALID', vlan])
-
-
-    # Xen API: Class PIF_metrics
-    # ----------------------------------------------------------------
-
-    PIF_metrics_attr_ro = ['io_read_kbs',
-                           'io_write_kbs',
-                           'last_updated']
-    PIF_metrics_attr_rw = []
-    PIF_metrics_methods = []
-
-    def PIF_metrics_get_all(self, _):
-        return xen_api_success(XendNode.instance().pif_metrics.keys())
-
-    def _PIF_metrics_get(self, _, ref):
-        return XendNode.instance().pif_metrics[ref]
-
 
     # Xen API: Class VM
     # ----------------------------------------------------------------        
@@ -1865,28 +1731,6 @@ class XendAPI(object):
         return xen_api_success_void()
 
 
-    # Xen API: Class VM_metrics
-    # ----------------------------------------------------------------
-
-    VM_metrics_attr_ro = ['memory_actual',
-                          'VCPUs_number',
-                          'VCPUs_utilisation',
-                          'VCPUs_CPU',
-                          'VCPUs_flags',
-                          'VCPUs_params',
-                          'state',
-                          'start_time',
-                          'last_updated']
-    VM_metrics_attr_rw = []
-    VM_metrics_methods = []
-
-    def _VM_metrics_get(self, _, ref):
-        return XendVMMetrics.get_by_uuid(ref)
-
-    def VM_metrics_get_all(self, _):
-        return xen_api_success(XendVMMetrics.get_all())
-
-
     # Xen API: Class VBD
     # ----------------------------------------------------------------
 
@@ -2570,33 +2414,6 @@ class XendAPI(object):
         return xen_api_success_void()
 
 
-    # Xen API: Class PBD
-    # ----------------------------------------------------------------
-
-    PBD_attr_ro = ['host',
-                   'SR',
-                   'device_config',
-                   'currently_attached']
-    PBD_attr_rw = []
-    PBD_methods = [('destroy', None)]
-    PBD_funcs   = [('create', None)]
-
-    def PBD_get_all(self, _):
-        return xen_api_success(XendPBD.get_all_refs())
-
-    def _PBD_get(self, _, ref):
-        return XendPBD.get(ref)
-
-    def PBD_create(self, _, record):
-        if 'uuid' in record:
-            return xen_api_error(['VALUE_NOT_SUPPORTED',
-                                  'uuid', record['uuid'],
-                                  'You may not specify a UUID on creation'])
-        new_uuid = XendPBD.XendPBD(record).get_uuid()
-        XendNode.instance().save()
-        return xen_api_success(new_uuid)
-
-
     # Xen API: Class event
     # ----------------------------------------------------------------
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIStore.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendAPIStore.py     Sat Apr 28 10:28:59 2007 +0100
@@ -0,0 +1,59 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx>
+#============================================================================
+"""
+This is a place to put instances of XenAPI objects,
+instead of just holding them in arbitrary places.
+
+All objects which subclass XendBase should use this
+mechanism.
+
+You must register both the uuid and type, and get objects
+by type, to ensure safety
+"""
+
+__classes = {}
+
+def register(uuid, type, inst):
+    __classes[(uuid, type)] = inst
+    return inst
+
+def deregister(uuid, type):
+    old = get(uuid, type)
+    del __classes[(uuid, type)]
+    return old
+
+def get(uuid, type):
+    """
+    Get the instances by uuid and type
+    """
+    return __classes.get((uuid, type), None)
+
+def get_all(all_type):
+    """
+    Get all instances by type
+    """
+    return [inst
+            for ((uuid, t), inst) in __classes.items()
+            if t == all_type]        
+
+def get_all_uuid(all_type):
+    """
+    Get all uuids by type
+    """
+    return [uuid
+            for (uuid, t) in __classes.keys()
+            if t == all_type]
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendAPIVersion.py
--- a/tools/python/xen/xend/XendAPIVersion.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendAPIVersion.py   Sat Apr 28 10:28:59 2007 +0100
@@ -16,7 +16,7 @@
 #============================================================================
 
 
-XEN_API_VERSION_MAJOR = 0
-XEN_API_VERSION_MINOR = 5
+XEN_API_VERSION_MAJOR = 1
+XEN_API_VERSION_MINOR = 0
 XEN_API_VERSION_VENDOR = 'xenbits'
 XEN_API_VERSION_VENDOR_IMPLEMENTATION = {}
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendBase.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendBase.py Sat Apr 28 10:28:59 2007 +0100
@@ -0,0 +1,126 @@
+#!/usr/bin/python
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx>
+#============================================================================
+"""
+Base class for all XenAPI classes
+"""
+
+from xen.xend.XendError import *
+from xen.xend import XendAPIStore
+
+class XendBase:
+    #
+    # These functions describe the object, and what is exposed via the API
+    #
+    def getClass(self):
+        return "Base"
+    
+    def getAttrRO(self):
+        return ['uuid']
+
+    def getAttrRW(self):
+        return []
+
+    def getAttrInst(self):
+        return []
+
+    def getMethods(self):
+        return ["get_record"]
+
+    def getFuncs(self):
+        return ["get_all", "get_by_uuid", "get_all_records"]
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+    
+    def __init__(self, uuid, record):
+        self.__uuid = uuid
+        
+        # First check this class implements all the correct methods:
+        for attr_ro in self.getAttrRO() + self.getAttrRW():
+            if not hasattr(self, "get_%s" % attr_ro):
+                raise ImplementationError(self.getClass(),
+                                          "get_%s" % attr_ro)
+
+        for attr_rw in self.getAttrRW():
+            if not hasattr(self, "set_%s" % attr_rw):
+                raise ImplementationError(self.getClass(),
+                                          "set_%s" % attr_rw)
+
+        for method in self.getMethods():
+            if not hasattr(self, method):
+                raise ImplementationError(self.getClass(),
+                                          method)
+
+        for func in self.getFuncs():
+            if not hasattr(self.__class__, func):
+                raise ImplementationError(self.getClass(),
+                                          func)
+
+        # Next check that the class is being created with the correct
+        # parameters
+        if not isinstance(record, dict):
+            raise CreateUnspecifiedAttributeError(
+                    "record" , self.getClass())
+        
+        for attr_inst in self.getAttrInst():
+            if attr_inst not in record:
+                raise CreateUnspecifiedAttributeError(
+                    attr_inst, self.getClass())
+            setattr(self, attr_inst, record[attr_inst])
+
+        # Finally register it
+        XendAPIStore.register(uuid, self.getClass(), self)
+
+    def destroy(self):
+        XendAPIStore.deregister(self.get_uuid(), self.getClass())
+
+    def get_uuid(self):
+        return self.__uuid
+
+    def get_record(self):
+        keys = self.getAttrRO() + self.getAttrRW()
+        return dict([(key, getattr(self, "get_%s" % key)())
+                     for key in keys])
+
+    #
+    # Class methods
+    #
+
+    def get_all(cls):
+        return XendAPIStore.get_all_uuid(cls.getClass())
+
+    def get_by_uuid(cls, uuid):
+        # Sanity check the uuid is one of us
+        me = XendAPIStore.get(uuid, cls.getClass())
+        if me is not None and me.getClass() == cls.getClass():
+            # In OSS, ref == uuid
+            return uuid
+        else:
+            raise "Big Error.. TODO!"
+
+    def get_all_records(cls):
+        return dict([(inst.get_uuid(), inst.get_record())
+                     for inst in XendAPIStore.get_all(cls.getClass())])
+
+    get_all = classmethod(get_all)
+    get_by_uuid = classmethod(get_by_uuid)
+    get_all_records = classmethod(get_all_records)
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Sat Apr 28 10:28:59 2007 +0100
@@ -22,6 +22,7 @@ import types
 
 from xen.xend import sxp
 from xen.xend import uuid
+from xen.xend import XendAPIStore
 from xen.xend.XendError import VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
@@ -341,7 +342,7 @@ class XendConfig(dict):
     # try and 'fix it up' but acutually fix the cause ;-)
     #
     def _memory_sanity_check(self):
-        log.debug("_memory_sanity_check memory_static_min: %s, "
+        log.trace("_memory_sanity_check memory_static_min: %s, "
                       "memory_static_max: %i, "
                       "memory_dynamic_min: %i, " 
                       "memory_dynamic_max: %i",
@@ -353,9 +354,6 @@ class XendConfig(dict):
         if not self["memory_static_min"] <= self["memory_static_max"]:
             raise XendConfigError("memory_static_min must be less " \
                                   "than or equal to memory_static_max") 
-        if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]:
-            raise XendConfigError("memory_dynamic_min must be less " \
-                                  "than or equal to memory_dynamic_max")
         if not self["memory_static_min"] <= self["memory_dynamic_min"]:
             raise XendConfigError("memory_static_min must be less " \
                                   "than or equal to memory_dynamic_min")
@@ -1049,6 +1047,10 @@ class XendConfig(dict):
                     dev_info['type'] = cfg_xenapi.get('type')
                 if cfg_xenapi.get('name'):
                     dev_info['name'] = cfg_xenapi.get('name')
+                if cfg_xenapi.get('network'):
+                    network = XendAPIStore.get(
+                        cfg_xenapi.get('network'), 'network')
+                    dev_info['bridge'] = network.get_name_label()
                 
                 dev_uuid = cfg_xenapi.get('uuid', None)
                 if not dev_uuid:
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Sat Apr 28 10:28:59 2007 +0100
@@ -293,10 +293,12 @@ class XendDomain:
                                 width = 78)
                 finally:
                     f.close()
+                    
                 try:
-                    os.rename(fn, self._managed_config_path(dom_uuid))
+                    shutil.move(fn, self._managed_config_path(dom_uuid))
                 except:
-                    log.exception("Renaming %s" % fn)
+                    log.exception("Renaming %s to %s", fn,
+                                  self._managed_config_path(dom_uuid))
                     os.remove(fn)
             except:
                 log.exception("Error occurred saving configuration file " +
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sat Apr 28 10:28:59 2007 +0100
@@ -580,12 +580,9 @@ class XendDomainInfo:
         log.debug("Setting memory target of domain %s (%s) to %d MiB.",
                   self.info['name_label'], str(self.domid), target)
         
-        if target <= 0:
-            raise XendError('Invalid memory size')
-        
         MiB = 1024 * 1024
-        self.info['memory_dynamic_min'] = target * MiB
-        self.info['memory_dynamic_max'] = target * MiB
+        self._safe_set_memory('memory_dynamic_min', target * MiB)
+        self._safe_set_memory('memory_dynamic_max', target * MiB)
 
         if self.domid >= 0:
             self.storeVm("memory", target)
@@ -1422,6 +1419,9 @@ class XendDomainInfo:
                 raise VmError("HVM guest support is unavailable: is VT/AMD-V "
                               "supported by your CPU and enabled in your "
                               "BIOS?")
+            # Hack to pre-reserve some memory for HVM setup.
+            # Needed because Xen allocates 1MB by default immediately.
+            balloon.free(2*1024) # 2MB should be plenty
 
         self.domid = xc.domain_create(
             domid = 0,
@@ -1820,7 +1820,7 @@ class XendDomainInfo:
                     log.info("Unmounting %s from %s." %
                              (fn, BOOTLOADER_LOOPBACK_DEVICE))
 
-                    dom0.destroyDevice('tap', '/dev/xvdp')
+                    dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE)
 
             if blcfg is None:
                 msg = "Had a bootloader specified, but can't find disk"
@@ -2134,14 +2134,24 @@ class XendDomainInfo:
     def get_memory_dynamic_min(self):
         return self.info.get('memory_dynamic_min', 0)
 
+    # only update memory-related config values if they maintain sanity 
+    def _safe_set_memory(self, key, newval):
+        oldval = self.info.get(key, 0)
+        try:
+            self.info[key] = newval
+            self.info._memory_sanity_check()
+        except Exception, ex:
+            self.info[key] = oldval
+            raise 
+    
     def set_memory_static_max(self, val):
-        self.info['memory_static_max'] = val
+        self._safe_set_memory('memory_static_max', val)
     def set_memory_static_min(self, val):
-        self.info['memory_static_min'] = val
+        self._safe_set_memory('memory_static_min', val)
     def set_memory_dynamic_max(self, val):
-        self.info['memory_dynamic_max'] = val
+        self._safe_set_memory('memory_dynamic_max', val)
     def set_memory_dynamic_min(self, val):
-        self.info['memory_dynamic_min'] = val
+        self._safe_set_memory('memory_dynamic_min', val)
     
     def get_vcpus_params(self):
         if self.getDomid() is None:
@@ -2246,9 +2256,18 @@ class XendDomainInfo:
 
             if not config.has_key('network'):
                 try:
+                    bridge = config.get('bridge', None)
+                    if bridge is None:
+                        from xen.util import Brctl
+                        if_to_br = dict([(i,b)
+                            for (b,ifs) in Brctl.get_state().items()
+                                for i in ifs])
+                        vifname = "vif%s.%s" % (self.getDomid(),
+                                                config.get('id'))
+                        bridge = if_to_br.get(vifname, None)
                     config['network'] = \
                         XendNode.instance().bridge_to_network(
-                        config.get('bridge')).uuid
+                        config.get('bridge')).get_uuid()
                 except Exception:
                     log.exception('bridge_to_network')
                     # Ignore this for now -- it may happen if the device
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendError.py        Sat Apr 28 10:28:59 2007 +0100
@@ -48,10 +48,6 @@ class PIFIsPhysical(XendError):
     def __init__(self):
         XendError.__init__(self, 'PIF is physical')
 
-class VLANTagInvalid(XendError):
-    def __init__(self):
-        XendError.__init__(self, 'VLAN tag invalid')
-
 class VmError(XendError):
     """Vm construction error."""
     pass
@@ -62,7 +58,123 @@ class HVMRequired(VmError):
                            'HVM guest support is unavailable: is VT/AMD-V '
                            'supported by your CPU and enabled in your BIOS?')
 
+class XendAPIError(XendError):
+    """Extend this class for all error thrown by
+    autoplugged classes"""
+    def __init__(self):
+        XendError.__init__(self, 'XendAPI Error: You should never see this'
+                           ' message; this class need to be overidden')
 
+    def get_api_error(self):
+        return ['INTERNAL_ERROR', 'You should never see this message; '
+                'this method needs to be overidden']
+
+class CreateUnspecifiedAttributeError(XendAPIError):
+    def __init__(self, attr_name, class_name):
+        XendAPIError.__init__(self)
+        self.attr_name = attr_name
+        self.class_name = class_name
+
+    def get_api_error(self):
+        return ['CREATE_UNSPECIFIED_ATTRIBUTE', self.attr_name,
+                self.class_name]
+
+    def __str__(self):
+        return "CREATE_UNSPECIFIED_ATTRIBUTE: %s, %s" % (self.attr_name,
+                 self.class_name)
+
+class UnmanagedNetworkError(XendAPIError):
+    def __init__(self, attr_name):
+        XendAPIError.__init__(self)
+        self.attr_name = attr_name
+
+    def get_api_error(self):
+        return ['UNMANAGED_NETWORK_ERROR', self.attr_name]
+
+    def __str__(self):
+        return "UNMANAGED_NETWORK_ERROR: %s" % self.attr_name
+
+class UniqueNameError(XendAPIError):
+    def __init__(self, name, class_name):
+        XendAPIError.__init__(self)
+        self.name = name
+        self.class_name = class_name
+        
+    def get_api_error(self):
+        return ['UNIQUE_NAME_ERROR', self.name, self.class_name]        
+
+    def __str__(self):
+        return 'UNIQUE_NAME_ERROR: %s, %s' % (self.name, self.class_name)
+
+class InvalidDeviceError(XendAPIError):
+    def __init__(self, dev):
+        XendAPIError.__init__(self)
+        self.dev = dev
+        
+    def get_api_error(self):
+        return ['INVALID_DEVICE_ERROR', self.dev]        
+
+    def __str__(self):
+        return 'INVALID_DEVICE_ERROR: %s' % self.dev
+    
+class DeviceExistsError(XendAPIError):
+    def __init__(self, dev):
+        XendAPIError.__init__(self)
+        self.dev = dev
+        
+    def get_api_error(self):
+        return ['DEVICE_EXISTS_ERROR', self.dev]        
+
+    def __str__(self):
+        return 'DEVICE_EXISTS_ERROR: %s' % self.dev
+
+class InvalidHandleError(XendAPIError):
+    def __init__(self, klass, handle):
+        XendAPIError.__init__(self)
+        self.klass = klass
+        self.handle = handle
+        
+    def get_api_error(self):
+        return ['HANDLE_INVALID', self.klass, self.handle]        
+
+    def __str__(self):
+        return 'HANDLE_INVALID: %s %s' % (self.klass, self.handle)
+
+class ImplementationError(XendAPIError):
+    def __init__(self, klass, func):
+        XendAPIError.__init__(self)
+        self.klass = klass
+        self.func = func
+
+    def get_api_error(self):
+        return ['IMPLEMENTATION_ERROR', self.klass, self.func]        
+
+    def __str__(self):
+        return 'IMPLEMENTATION_ERROR: %s %s' % (self.klass, self.func)
+
+class VLANTagInvalid(XendAPIError):
+    def __init__(self, vlan):
+        XendAPIError.__init__(self)
+        self.vlan = vlan
+
+    def get_api_error(self):
+        return ['VLAN_TAG_INVALID', self.vlan]
+
+    def __str__(self):
+        return 'VLAN_TAG_INVALID: %s' % self.vlan
+
+class NetworkError(XendAPIError):
+    def __init__(self, error, network):
+        XendAPIError.__init__(self)
+        self.network = network
+        self.error = error
+
+    def get_api_error(self):
+        return ['NETWORK_ERROR', self.error, self.network]
+
+    def __str__(self):
+        return 'NETWORK_ERROR: %s %s' % (self.error, self.network)
+    
 XEND_ERROR_AUTHENTICATION_FAILED = ('ELUSER', 'Authentication Failed')
 XEND_ERROR_SESSION_INVALID       = ('EPERMDENIED', 'Session Invalid')
 XEND_ERROR_DOMAIN_INVALID        = ('EINVALIDDOMAIN', 'Domain Invalid')
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendNetwork.py      Sat Apr 28 10:28:59 2007 +0100
@@ -24,15 +24,139 @@ import XendDomain
 import XendDomain
 import XendNode
 from XendLogging import log
+from xen.xend import uuid as genuuid
+from xen.xend.XendBase import XendBase
+from xen.xend.XendError import *
+from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
 
-class XendNetwork:
-    def __init__(self, uuid, record):
-        self.uuid = uuid
-        self.name_label = record.get('name_label', '')
-        self.name_description = record.get('name_description', '')
-        self.other_config = record.get('other_config', {})
+def bridge_exists(name):
+    return name in Brctl.get_state().keys()
+
+class XendNetwork(XendBase):
+    """We're going to assert that the name_label of this
+    network is just the name of the bridge"""
+
+    def getClass(self):
+        return "network"
+
+    def getAttrRW(self):
+        attrRW = ['name_label',
+                  'name_description',
+                  'other_config',
+                  'default_gateway',
+                  'default_netmask']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrRO(self):
+        attrRO =  ['VIFs',
+                   'PIFs']
+        return XendBase.getAttrRO() + attrRO
+
+    def getAttrInst(self):
+        return XendBase.getAttrInst() + self.getAttrRW()
+
+    def getMethods(self):
+        methods = ['add_to_other_config',
+                   'remove_from_other_config',
+                   'destroy']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+
+    def create_phy(self, name):
+        """
+        Called when a new bridge is found on xend start
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance
+        record = {
+                'name_label':       name,
+                'name_description': '',
+                'other_config':     {},
+                'default_gateway':  '',
+                'default_netmask':  ''
+            }
+        network = XendNetwork(record, uuid)
+
+        return uuid
+        
+    def recreate(self, record, uuid):
+        """
+        Called on xend start / restart, or machine
+        restart, when read from saved config.
+        Needs to check network exists, create it otherwise
+        """
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Create network if it doesn't already exist
+        if not bridge_exists(network.name_label):
+            Brctl.bridge_create(network.name_label)
+
+        return uuid
+
+    def create(self, record):
+        """
+        Called from API, to create a new network
+        """
+        # Create new uuids
+        uuid = genuuid.createString()
+
+        # Create instance (do this first, to check record)
+        network = XendNetwork(record, uuid)
+
+        # Check network doesn't already exist
+        name_label = network.name_label
+        if bridge_exists(name_label):
+            del network
+            raise UniqueNameError(name_label, "network")
+
+        # Create the bridge
+        Brctl.bridge_create(network.name_label)
+
+        XendNode.instance().save_networks()
+
+        return uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create      = classmethod(create)
+        
+    def __init__(self, record, uuid):       
+        XendBase.__init__(self, uuid, record)
+        
+    #
+    # XenAPI Mehtods
+    #
+
+    def destroy(self):
+        # check no VIFs or PIFs attached
+        if len(self.get_VIFs()) > 0:
+            raise NetworkError("Cannot destroy network with VIFs attached",
+                               self.get_name_label())
+
+        if len(self.get_PIFs()) > 0:
+            raise NetworkError("Cannot destroy network with PIFs attached",
+                               self.get_name_label())        
+        
+        XendBase.destroy(self)
+        Brctl.bridge_del(self.get_name_label())
+        XendNode.instance().save_networks()
 
     def get_name_label(self):
         return self.name_label
@@ -41,9 +165,8 @@ class XendNetwork:
         return self.name_description
 
     def set_name_label(self, new_name):
-        self.name_label = new_name
-        XendNode.instance().save_networks()
-
+        pass
+        
     def set_name_description(self, new_desc):
         self.name_description = new_desc
         XendNode.instance().save_networks()
@@ -55,13 +178,14 @@ class XendNetwork:
             vifs = vm.get_vifs()
             for vif in vifs:
                 vif_cfg = vm.get_dev_xenapi_config('vif', vif)
-                if vif_cfg.get('network') == self.uuid:
+                if vif_cfg.get('network') == self.get_uuid():
                     result.append(vif)
         return result
 
     def get_PIFs(self):
-        return [x.uuid for x in XendNode.instance().pifs.values()
-                if x.network == self]
+        pifs = XendAPIStore.get_all("PIF")
+        return [pif.get_uuid() for pif in pifs
+                if pif.get_network() == self.get_uuid()]
 
     def get_other_config(self):
         return self.other_config
@@ -79,17 +203,16 @@ class XendNetwork:
             del self.other_config[key]
         XendNode.instance().save_networks()
 
-    def get_record(self):
-        return self.get_record_internal(True)
-
-    def get_record_internal(self, transient):
-        result = {
-            'uuid': self.uuid,
-            'name_label': self.name_label,
-            'name_description': self.name_description,
-            'other_config' : self.other_config,
-        }
-        if transient:
-            result['VIFs'] = self.get_VIFs()
-            result['PIFs'] = self.get_PIFs()
-        return result
+    def get_default_gateway(self):
+        return self.default_gateway
+
+    def set_default_gateway(self, gateway):
+        self.default_gateway = gateway
+        XendNode.instance().save_networks()
+
+    def get_default_netmask(self):
+        return self.default_netmask
+
+    def set_default_netmask(self, netmask):
+        self.default_netmask = netmask
+        XendNode.instance().save_networks()
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendNode.py Sat Apr 28 10:28:59 2007 +0100
@@ -21,9 +21,10 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 
 from xen.util import Brctl
+from xen.xend import XendAPIStore
 
 import uuid, arch
-import XendPBD
+from XendPBD import XendPBD
 from XendError import *
 from XendOptions import instance as xendoptions
 from XendQCoWStorageRepo import XendQCoWStorageRepo
@@ -34,7 +35,7 @@ from XendNetwork import *
 from XendNetwork import *
 from XendStateStore import XendStateStore
 from XendMonitor import XendMonitor
-
+     
 class XendNode:
     """XendNode - Represents a Domain 0 Host."""
     
@@ -133,70 +134,78 @@ class XendNode:
                       'features' : cpu_features,
                     })
 
-        self.pifs = {}
-        self.pif_metrics = {}
-        self.networks = {}
         self.srs = {}
-        
-        # initialise networks
+
+        # Initialise networks
+        # First configure ones off disk
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.network_create(network, False, net_uuid)
-        else:
-            bridges = Brctl.get_state().keys()
-            for bridge in bridges:
-                self.network_create({'name_label' : bridge }, False)
+                try:
+                    XendNetwork.recreate(network, net_uuid)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating network %s", net_uuid)
                 
-        # Get a mapping from interface to bridge
-
-        if_to_br = dict([(i,b)
-                         for (b,ifs) in Brctl.get_state().items()
-                         for i in ifs])
-
-        # initialise PIFs
+        # Next discover any existing bridges and check
+        # they are not already configured
+        bridges = Brctl.get_state().keys()
+        configured_bridges = [XendAPIStore.get(
+                                  network_uuid, "network")
+                                      .get_name_label()
+                              for network_uuid in XendNetwork.get_all()]
+        unconfigured_bridges = [bridge
+                                for bridge in bridges
+                                if bridge not in configured_bridges]
+        for unconfigured_bridge in unconfigured_bridges:
+            XendNetwork.create_phy(unconfigured_bridge)
+
+        # Initialise PIFs
+        # First configure ones off disk
         saved_pifs = self.state_store.load_state('pif')
         if saved_pifs:
             for pif_uuid, pif in saved_pifs.items():
-                if pif.get('network') in self.networks:
-                    network = self.networks[pif['network']]
-                    try:
-                        if 'device' not in pif and 'name' in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['device'] = pif['name']
-                        if 'metrics' not in pif:
-                            # Compatibility hack, can go pretty soon.
-                            pif['metrics'] = uuid.createString()
-
-                        try:
-                            pif['VLAN'] = int(pif.get('VLAN', -1))
-                        except (ValueError, TypeError):
-                            pif['VLAN'] = -1
-
-                        self._PIF_create(pif['device'], pif['MTU'],
-                                         pif['VLAN'],
-                                         pif['MAC'], network, False, pif_uuid,
-                                         pif['metrics'])
-                    except NetworkAlreadyConnected, exn:
-                        log.error('Cannot load saved PIF %s, as network %s ' +
-                                  'is already connected to PIF %s',
-                                  pif_uuid, pif['network'], exn.pif_uuid)
-        else:
-            for name, mtu, mac in linux_get_phy_ifaces():
-                bridge_name = if_to_br.get(name, None)
-                if bridge_name is not None:
-                    networks = [network for
-                                network in self.networks.values()
-                                if network.get_name_label() == bridge_name]
-                    if len(networks) > 0:
-                        network = networks[0]
-                        self._PIF_create(name, mtu, -1, mac, network, False)
-
+                try:
+                    XendPIF.recreate(pif, pif_uuid)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating PIF %s", pif_uuid)
+        
+        # Next discover any existing PIFs and check
+        # they are not already configured
+        configured_pifs = [XendAPIStore.get(
+                               pif_uuid, "PIF")
+                                   .get_interface_name()
+                           for pif_uuid in XendPIF.get_all()]
+        unconfigured_pifs = [(name, mtu, mac)
+                             for name, mtu, mac in linux_get_phy_ifaces()
+                             if name not in configured_pifs]
+
+        # Get a mapping from interface to bridge          
+        if_to_br = dict([(i,b)
+                         for (b,ifs) in Brctl.get_state().items()
+                             for i in ifs])
+
+        for name, mtu, mac in unconfigured_pifs:
+            # Check PIF is on bridge
+            # if not, ignore
+            bridge_name = if_to_br.get(name, None)
+            if bridge_name is not None:
+                # Translate bridge name to network uuid
+                for network_uuid in XendNetwork.get_all():
+                    network = XendAPIStore.get(
+                        network_uuid, 'network')
+                    if network.get_name_label() == bridge_name:
+                        XendPIF.create_phy(network_uuid, name,
+                                           mtu, mac)
+                        break
+                else:
+                    log.debug("Cannot find network for bridge %s "
+                              "when configuring PIF %s",
+                              (bridge_name, name))     
+        
         # initialise storage
         saved_srs = self.state_store.load_state('sr')
         if saved_srs:
             for sr_uuid, sr_cfg in saved_srs.items():
-                log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type'])
                 if sr_cfg['type'] == 'qcow_file':
                     self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid)
                 elif sr_cfg['type'] == 'local':
@@ -214,69 +223,50 @@ class XendNode:
         saved_pbds = self.state_store.load_state('pbd')
         if saved_pbds:
             for pbd_uuid, pbd_cfg in saved_pbds.items():
-                pbd_cfg['uuid'] = pbd_uuid
-                XendPBD.XendPBD(pbd_cfg)
-
-
-    def network_create(self, record, persist = True, net_uuid = None):
-        if net_uuid is None:
-            net_uuid = uuid.createString()
-        self.networks[net_uuid] = XendNetwork(net_uuid, record)
-        if persist:
-            self.save_networks()
-        return net_uuid
-
-
-    def network_destroy(self, net_uuid):
-        del self.networks[net_uuid]
-        self.save_networks()
-
-
-    def get_PIF_refs(self):
-        return self.pifs.keys()
-
-
-    def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
-                    pif_uuid = None, metrics_uuid = None):
-        for pif in self.pifs.values():
-            if pif.network == network:
-                raise NetworkAlreadyConnected(pif.uuid)
-
-        if pif_uuid is None:
-            pif_uuid = uuid.createString()
-        if metrics_uuid is None:
-            metrics_uuid = uuid.createString()
-
-        metrics = XendPIFMetrics(metrics_uuid)
-        pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self)
-        metrics.set_PIF(pif)
-
-        self.pif_metrics[metrics_uuid] = metrics
-        self.pifs[pif_uuid] = pif
-
-        if persist:
-            self.save_PIFs()
-            self.refreshBridges()
-        return pif_uuid
-
-
-    def PIF_create_VLAN(self, pif_uuid, network_uuid, vlan):
-        if vlan < 0 or vlan >= 4096:
-            raise VLANTagInvalid()
-            
-        pif = self.pifs[pif_uuid]
-        network = self.networks[network_uuid]
-        return self._PIF_create(pif.device, pif.mtu, vlan, pif.mac, network)
-
-
-    def PIF_destroy(self, pif_uuid):
-        pif = self.pifs[pif_uuid]
-
-        if pif.vlan == -1:
-            raise PIFIsPhysical()
-
-        del self.pifs[pif_uuid]
-        self.save_PIFs()
+                try:
+                    XendPBD.recreate(pbd_uuid, pbd_cfg)
+                except CreateUnspecifiedAttributeError:
+                    log.warn("Error recreating PBD %s", pbd_uuid) 
+
+##    def network_destroy(self, net_uuid):
+ ##       del self.networks[net_uuid]
+  ##      self.save_networks()
+
+
+##    def get_PIF_refs(self):
+##       return self.pifs[:]
+
+##   def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
+##                     pif_uuid = None, metrics_uuid = None):
+##         for pif in self.pifs.values():
+##             if pif.network == network:
+##                 raise NetworkAlreadyConnected(pif.uuid)
+
+##         if pif_uuid is None:
+##             pif_uuid = uuid.createString()
+##         if metrics_uuid is None:
+##             metrics_uuid = uuid.createString()
+
+##         metrics = XendPIFMetrics(metrics_uuid)
+##         pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, 
self)
+##         metrics.set_PIF(pif)
+
+##         self.pif_metrics[metrics_uuid] = metrics
+##         self.pifs[pif_uuid] = pif
+
+##         if persist:
+##             self.save_PIFs()
+##             self.refreshBridges()
+##         return pif_uuid
+
+##     def PIF_destroy(self, pif_uuid):
+##         pif = self.pifs[pif_uuid]
+
+##         if pif.vlan == -1:
+##             raise PIFIsPhysical()
+
+##         del self.pifs[pif_uuid]
+##         self.save_PIFs()
 
 
     def save(self):
@@ -284,7 +274,7 @@ class XendNode:
         host_record = {self.uuid: {'name_label':self.name,
                                    'name_description':self.desc,
                                    'metrics_uuid': self.host_metrics_uuid,
-                                   'other_config': repr(self.other_config)}}
+                                   'other_config': self.other_config}}
         self.state_store.save_state('host',host_record)
         self.state_store.save_state('cpu', self.cpus)
         self.save_PIFs()
@@ -293,18 +283,21 @@ class XendNode:
         self.save_SRs()
 
     def save_PIFs(self):
-        pif_records = dict([(k, v.get_record())
-                            for k, v in self.pifs.items()])
+        pif_records = dict([(pif_uuid, XendAPIStore.get(
+                                 pif_uuid, "PIF").get_record())
+                            for pif_uuid in XendPIF.get_all()])
         self.state_store.save_state('pif', pif_records)
 
     def save_networks(self):
-        net_records = dict([(k, v.get_record_internal(False))
-                            for k, v in self.networks.items()])
+        net_records = dict([(network_uuid, XendAPIStore.get(
+                                 network_uuid, "network").get_record())
+                            for network_uuid in XendNetwork.get_all()])
         self.state_store.save_state('network', net_records)
 
     def save_PBDs(self):
-        pbd_records = dict([(v.get_uuid(), v.get_record())
-                            for v in XendPBD.get_all()])
+        pbd_records = dict([(pbd_uuid, XendAPIStore.get(
+                                 pbd_uuid, "PBD").get_record())
+                            for pbd_uuid in XendPBD.get_all()])
         self.state_store.save_state('pbd', pbd_records)
 
     def save_SRs(self):
@@ -330,9 +323,6 @@ class XendNode:
 
     def is_valid_cpu(self, cpu_ref):
         return (cpu_ref in self.cpus)
-
-    def is_valid_network(self, network_ref):
-        return (network_ref in self.networks)
 
     def is_valid_sr(self, sr_ref):
         return (sr_ref in self.srs)
@@ -495,12 +485,6 @@ class XendNode:
     # Network Functions
     #
     
-    def get_network_refs(self):
-        return self.networks.keys()
-
-    def get_network(self, network_ref):
-        return self.networks[network_ref]
-
     def bridge_to_network(self, bridge):
         """
         Determine which network a particular bridge is attached to.
@@ -518,13 +502,12 @@ class XendNode:
                 raise Exception(
                     'Could not find default bridge, and none was specified')
 
-        bridges = Brctl.get_state()
-        if bridge not in bridges:
-            raise Exception('Bridge %s is not up' % bridge)
-        for pif in self.pifs.values():
-            if pif.interface_name() in bridges[bridge]:
-                return pif.network
-        raise Exception('Bridge %s is not connected to a network' % bridge)
+        for network_uuid in XendNetwork.get_all():
+            network = XendAPIStore.get(network_uuid, "network")
+            if network.get_name_label() == bridge:
+                return network
+        else:
+            raise Exception('Cannot find network for bridge %s' % bridge)
 
     #
     # Debug keys.
@@ -641,12 +624,6 @@ class XendNode:
         return dict(self.physinfo())
     def info_dict(self):
         return dict(self.info())
-
-
-    def refreshBridges(self):
-        for pif in self.pifs.values():
-            pif.refresh(Brctl.get_state())
-
 
 def parse_proc_cpuinfo():
     cpuinfo = {}
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPBD.py
--- a/tools/python/xen/xend/XendPBD.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPBD.py  Sat Apr 28 10:28:59 2007 +0100
@@ -18,62 +18,82 @@
 
 import uuid
 from XendLogging import log
+from xen.xend.XendBase import XendBase
+from xen.xend import XendAPIStore
 
+class XendPBD(XendBase):
+    """Physical block devices."""
 
-attr_inst = ['uuid',
-             'host',
-             'SR',
-             'device_config']
-attr_ro = attr_inst + ['currently_attached']
+    def getClass(self):
+        return "PBD"
+    
+    def getAttrRO(self):
+        attrRO = ['host',
+                  'SR',
+                  'device_config',
+                  'currently_attached']
+        return XendBase.getAttrRO() + attrRO
 
+    def getAttrRW(self):
+        attrRW = []
+        return XendBase.getAttrRW() + attrRW
 
-_all = {}
+    def getAttrInst(self):
+        return ['uuid',
+                'host',
+                'SR',
+                'device_config']
 
+    def getMethods(self):
+        methods = ['destroy']
+        return XendBase.getMethods() + methods
 
-def get(ref):
-    return _all[ref]
+    def getFuncs(self):
+        funcs = ['create',
+                 'get_by_SR']
+        return XendBase.getFuncs() + funcs
 
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
 
-def get_all():
-    return _all.values()
+    def recreate(uuid, record):
+        pbd = XendPBD(uuid, record)
+        return uuid
+    
+    def create(cls, record):
+        uuid = genuuid.createString()
+        pbd = XendPBD(uuid, record)
+        return uuid       
 
+    create = classmethod(create)
+    
+    def __init__(self, uuid, record):
+        XendBase.__init__(self, uuid, record)
+        this.currently_attached = True
 
-def get_all_refs():
-    return _all.keys()
+    def get_host(self):
+        return this.host
+    
+    def get_SR(self):
+        return this.SR
 
+    def get_device_config(self):
+        return this.device_config
 
-def get_by_SR(sr_ref):
-    return [k for (k, v) in _all.items() if v.get_SR() == sr_ref]
-
-
-class XendPBD:
-    """Physical block devices."""
-    
-    def __init__(self, record):
-        if 'uuid' not in record:
-            record['uuid'] = uuid.createString()
-
-        import XendAPI
-        for v in attr_inst:
-            setattr(self, v, record[v])
-        self.currently_attached = True
-        _all[record['uuid']] = self
-
+    def get_currently_attached(self):
+        return this.currently_attached
 
     def destroy(self):
-        if self.uuid in _all:
-            del _all[self.uuid]
+        pass
+    
+    def get_by_SR(cls, sr_ref):
+        pbds = XendAPIStore.get_all("PBD")
+        return [pbd.get_uuid()
+                for pbd in pbds
+                if pbd.get_SR() == sr_ref]
 
-
-    def get_record(self):
-        import XendAPI
-        result = {}
-        for v in attr_ro:
-            result[v] = getattr(self, v)
-        return result
-
-
-for v in attr_ro:
-    def f(v_):
-        setattr(XendPBD, 'get_' + v_, lambda s: getattr(s, v_))
-    f(v)
+    get_by_SR = classmethod(get_by_SR)
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPIF.py  Sat Apr 28 10:28:59 2007 +0100
@@ -19,11 +19,14 @@ import logging
 import logging
 import os
 import re
-
+from xen.xend import uuid as genuuid
+from xen.xend import XendAPIStore
+from xen.xend.XendBase import XendBase
+from xen.xend.XendPIFMetrics import XendPIFMetrics
+from xen.xend.XendError import *
 
 log = logging.getLogger("xend.XendPIF")
 log.setLevel(logging.TRACE)
-
 
 MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))
 IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')
@@ -87,106 +90,279 @@ def linux_set_mtu(iface, mtu):
     except ValueError:
         return False
 
-class XendPIF:
+def _create_VLAN(dev, vlan):
+    rc, _ = commands.getstatusoutput('vconfig add %s %d' %
+                                     (dev, vlan))
+    if rc != 0:
+        return False
+
+    rc, _ = commands.getstatusoutput('ifconfig %s.%d up' %
+                                     (dev, vlan))
+    return rc == 0
+
+def _destroy_VLAN(dev, vlan):
+    rc, _ = commands.getstatusoutput('ifconfig %s.%d down' %
+                                     (dev, vlan))
+    if rc != 0:
+        return False
+                                     
+    rc, _ = commands.getstatusoutput('vconfig rem %s.%d' %
+                                     (dev, vlan))
+    return rc == 0
+
+class XendPIF(XendBase):
     """Representation of a Physical Network Interface."""
-    
-    def __init__(self, uuid, metrics, device, mtu, vlan, mac, network,
-                 host):
-        self.uuid = uuid
-        self.metrics = metrics
-        self.device = device
-        self.mac = mac
-        self.mtu = mtu
-        self.vlan = vlan
-        self.network = network
-        self.host = host
-
-    def set_device(self, new_device):
-        self.device = new_device
-
-    def set_mac(self, new_mac):
-        success = linux_set_mac(new_mac)
+
+    def getClass(self):
+        return "PIF"
+
+    def getAttrRO(self):
+        attrRO = ['network',
+                  'host',
+                  'metrics',
+                  'device',
+                  'VLAN']
+        return XendBase.getAttrRO() + attrRO
+    
+    def getAttrRW(self):
+        attrRW = ['MAC',
+                  'MTU']
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrInst(self):
+        attrInst = ['network',
+                    'device',
+                    'MAC',
+                    'MTU',
+                    'VLAN']
+        return attrInst
+
+    def getMethods(self):
+        methods = ['plug',
+                   'unplug',
+                   'destroy']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create_VLAN']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+    
+    def create_phy(self, network_uuid, device,
+                   MAC, MTU):
+        """
+        Called when a new physical PIF is found
+        Could be a VLAN...
+        """
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+
+        # Is this a VLAN?
+        VLANdot = device.split(".")
+        VLANcolon = device.split(":")
+
+        if len(VLANdot) > 1:
+            VLAN = VLANdot[1]
+            device = VLANdot[0]
+        elif len(VLANcolon) > 1:
+            VLAN = VLANcolon[1]
+            device = VLANcolon[0] 
+        else:
+            VLAN = -1
+            
+        record = {
+            'network': network_uuid,
+            'device':  device,
+            'MAC':     MAC,
+            'MTU':     MTU,
+            'VLAN':    VLAN
+            }
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        return pif_uuid
+
+    def recreate(self, record, uuid):
+        """Called on xend start / restart"""        
+        pif_uuid = uuid
+        metrics_uuid = record['metrics']
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        # If physical PIF, check exists
+        # If VLAN, create if not exist
+        ifs = [dev for dev, _1, _2 in linux_get_phy_ifaces()]
+        if pif.get_VLAN() == -1:
+            if pif.get_device() not in ifs:
+                pif.destroy()
+                metrics.destroy()
+                return None
+        else:
+            if pif.get_interface_name() not in ifs:
+                _create_VLAN(pif.get_device(), pif.get_VLAN())
+                pif.plug()
+
+        return pif_uuid
+
+    def create_VLAN(self, device, network_uuid, host_ref, vlan):
+        """Exposed via API - create a new VLAN from existing VIF"""
+        
+        ifs = [name for name, _, _ in linux_get_phy_ifaces()]
+
+        vlan = int(vlan)
+
+        # Check VLAN tag is valid
+        if vlan < 0 or vlan >= 4096:
+            raise VLANTagInvalid(vlan)
+        
+        # Check device exists
+        if device not in ifs:
+            raise InvalidDeviceError(device)
+
+        # Check VLAN doesn't already exist
+        if "%s.%d" % (device, vlan) in ifs:
+            raise DeviceExistsError("%s.%d" % (device, vlan))
+
+        # Check network ref is valid
+        from XendNetwork import XendNetwork
+        if network_uuid not in XendNetwork.get_all():
+            raise InvalidHandleError("Network", network_uuid)
+
+        # Check host_ref is this host
+        import XendNode
+        if host_ref != XendNode.instance().get_uuid():
+            raise InvalidHandleError("Host", host_ref)
+
+        # Create the VLAN
+        _create_VLAN(device, vlan)
+
+        # Create new uuids
+        pif_uuid = genuuid.createString()
+        metrics_uuid = genuuid.createString()
+
+        # Create the record
+        record = {
+            "device":  device,
+            "MAC":     '',
+            "MTU":     '',
+            "network": network_uuid,
+            "VLAN":    vlan
+            }
+
+        # Create instances
+        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)
+        pif = XendPIF(record, pif_uuid, metrics_uuid)
+
+        # Not sure if they should be created plugged or not...
+        pif.plug()
+
+        XendNode.instance().save_PIFs()
+        return pif_uuid
+
+    create_phy  = classmethod(create_phy)
+    recreate    = classmethod(recreate)
+    create_VLAN = classmethod(create_VLAN)
+    
+    def __init__(self, record, uuid, metrics_uuid):
+        XendBase.__init__(self, uuid, record)
+        self.metrics = metrics_uuid
+
+    def plug(self):
+        """Plug the PIF into the network"""
+        network = XendAPIStore.get(self.network,
+                                   "network")
+        bridge_name = network.get_name_label()
+
+        from xen.util import Brctl
+        Brctl.vif_bridge_add({
+            "bridge": bridge_name,
+            "vif":    self.get_interface_name()
+            })
+
+    def unplug(self):
+        """Unplug the PIF from the network"""
+        network = XendAPIStore.get(self.network,
+                                   "network")
+        bridge_name = network.get_name_label()
+
+        from xen.util import Brctl
+        Brctl.vif_bridge_rem({
+            "bridge": bridge_name,
+            "vif":    self.get_interface_name()
+            })
+
+    def destroy(self):
+        # Figure out if this is a physical device
+        if self.get_interface_name() == \
+           self.get_device():
+            raise PIFIsPhysical(self.get_uuid())
+
+        self.unplug()
+
+        if _destroy_VLAN(self.get_device(), self.get_VLAN()):
+            XendBase.destroy(self)
+            import XendNode
+            XendNode.instance().save_PIFs()
+        else:
+            raise NetworkError("Unable to delete VLAN", self.get_uuid())
+
+    def get_interface_name(self):
+        if self.get_VLAN() == -1:
+            return self.get_device()
+        else:
+            return "%s.%d" % (self.get_device(), self.get_VLAN())
+        
+    def get_device(self):
+        """
+        This is the base interface.
+        For phy if (VLAN == -1) this is same as
+        if name.
+        For VLANs, this it the bit before the period
+        """
+        return self.device
+
+    def get_network(self):
+        return self.network
+
+    def get_host(self):
+        from xen.xend import XendNode
+        return XendNode.instance().get_uuid()
+
+    def get_metrics(self):
+        return self.metrics
+
+    def get_MAC(self):
+        return self.MAC
+
+    def set_MAC(self, new_mac):
+        success = linux_set_mac(self.device, new_mac)
         if success:
-            self.mac = new_mac
+            self.MAC = new_mac
+            import XendNode
+            XendNode.instance().save_PIFs()
         return success
 
-    def set_mtu(self, new_mtu):
-        success = linux_set_mtu(new_mtu)
+    def get_MTU(self):
+        return self.MTU
+
+    def set_MTU(self, new_mtu):
+        success = linux_set_mtu(self.device, new_mtu)
         if success:
-            self.mtu = new_mtu
+            self.MTU = new_mtu
+            import XendNode
+            XendNode.instance().save_PIFs()
         return success
 
-    def get_record(self):
-        return {'uuid': self.uuid,
-                'device': self.device,
-                'MAC': self.mac,
-                'MTU': self.mtu,
-                'VLAN': self.vlan,
-                'host': self.host.uuid,
-                'network': self.network.uuid,
-                'metrics': self.metrics.uuid}
-
-    def refresh(self, bridges):
-        ifname = self.interface_name()
-        rc, _ = _cmd('ip link show %s', ifname)
-        if rc != 0:
-            # Interface does not exist.  If it's a physical interface, then
-            # there's nothing we can do -- this should have been set up with
-            # the network script.  Otherwise, we can use vconfig to derive
-            # a subinterface.
-            if self.vlan == -1:
-                return
-            
-            rc, _ = _cmd('vconfig add %s %d', self.device, self.vlan)
-            if rc != 0:
-                log.error('Could not refresh VLAN for interface %s', ifname)
-                return
-            
-            log.info('Created network interface %s', ifname)
-
-        for brname, nics in bridges.items():
-            if ifname in nics:
-                log.debug('%s is already attached to %s', ifname, brname)
-                return
-
-        # The interface is not attached to a bridge.  Create one, and attach
-        # the interface to it.
-        brname = _new_bridge_name(bridges)
-        rc, _ = _cmd('brctl addbr %s', brname)
-        if rc != 0:
-            log.error('Could not create bridge %s for interface %s', brname,
-                      ifname)
-            return
-        log.info('Created network bridge %s', brname)
-        
-        rc, _ = _cmd('brctl addif %s %s', brname, ifname)
-        if rc != 0:
-            log.error('Could not add %s to %s', ifname, brname)
-            return
-        log.info('Added network interface %s to bridge %s', ifname, brname)
-
-
-    def interface_name(self):
-        if self.vlan != -1:
-            return '%s.%d' % (self.device, self.vlan)
-        else:
-            return self.device
-
-
-def _cmd(cmd, *args):
-    if len(args) > 0:
-        cmd = cmd % args
-    rc, output = commands.getstatusoutput(cmd)
-    if rc != 0:
-        log.debug('%s failed with code %d' % (cmd, rc))
-    log.trace('%s: %s' % (cmd, output))
-    return rc, output
-
-
-def _new_bridge_name(bridges):
-    n = 0
-    while True:
-        brname = 'xenbr%d' % n
-        if brname not in bridges:
-            return brname
-        n += 1
+    def get_VLAN(self):
+        return self.VLAN
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendPIFMetrics.py   Sat Apr 28 10:28:59 2007 +0100
@@ -15,15 +15,30 @@
 # Copyright (c) 2006-2007 Xensource Inc.
 #============================================================================
 
+from XendBase import XendBase
 
-class XendPIFMetrics:
+class XendPIFMetrics(XendBase):
     """PIF Metrics."""
+
+    def getClass(self):
+        return "PIF_metrics"
     
-    def __init__(self, uuid):
-        self.uuid = uuid
+    def getAttrRO(self):
+        attrRO =  ['io_read_kbs',
+                   'io_write_kbs',
+                   'last_updated',
+                   'pif']
+        return XendBase.getAttrRO() + attrRO
 
-    def set_PIF(self, pif):
-        self.pif = pif
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+
+    def __init__(self, uuid, pif_uuid):
+        XendBase.__init__(self, uuid, {})
+        self.pif_uuid = pif_uuid
+
+    def get_pif(self):
+        return self.pif_uuid
 
     def get_io_read_kbs(self):
         return self._get_stat(0)
@@ -33,19 +48,12 @@ class XendPIFMetrics:
 
     def _get_stat(self, n):
         from xen.xend.XendNode import instance as xennode
-        pifname = self.pif.device
-        pifs_util = xennode().monitor.get_pifs_util()
-        if pifname in pifs_util:
-            return pifs_util[pifname][n]
+        #pifname = self.pif.device
+        #pifs_util = xennode().monitor.get_pifs_util()
+        #if pifname in pifs_util:
+        #    return pifs_util[pifname][n]
         return 0.0
 
     def get_last_updated(self):
         import xen.xend.XendAPI as XendAPI
         return XendAPI.now()
-
-    def get_record(self):
-        return {'uuid'         : self.uuid,
-                'io_read_kbs'  : self.get_io_read_kbs(),
-                'io_write_kbs' : self.get_io_write_kbs(),
-                'last_updated' : self.get_last_updated(),
-                }
diff -r ee16cdeddade -r 1668299c0ea4 
tools/python/xen/xend/XendQCoWStorageRepo.py
--- a/tools/python/xen/xend/XendQCoWStorageRepo.py      Wed Apr 25 10:39:08 
2007 +0100
+++ b/tools/python/xen/xend/XendQCoWStorageRepo.py      Sat Apr 28 10:28:59 
2007 +0100
@@ -30,7 +30,7 @@ import struct
 
 from xen.util import mkdir
 import uuid
-import XendPBD
+from XendPBD import XendPBD
 from XendError import XendError
 from XendVDI import *
 from XendTask import XendTask
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py   Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendStateStore.py   Sat Apr 28 10:28:59 2007 +0100
@@ -57,10 +57,12 @@ class XendStateStore:
 
     <hosts>
        <host uuid='49c01812-3c28-1ad4-a59d-2a3f81b13ec2'>
-           <name type='string'>norwich</name>
-           <description type='string'>Test Xen Host</description>
-           <cpu uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' />
-           <cpu uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' />
+          <name type='string'>norwich</name>
+          <description type='string'>Test Xen Host</description>
+          <cpu type='dict'>
+             <item uuid='6fc2d1ed-7eb0-4c9d-8006-3657d5483ae0' />
+             <item uuid='669df3b8-62be-4e61-800b-bbe8ee63a760' />
+          </cpu>
        </host>
     </hosts>
 
@@ -121,18 +123,20 @@ class XendStateStore:
                 if val_elem.firstChild:
                     val_text = val_elem.firstChild.nodeValue.strip()
                 
-                if val_type == '' and val_uuid != '':
-                    # this is a reference
-                    if val_name not in cls_dict:
-                        cls_dict[val_name] = {}
-                    cls_dict[val_name][val_uuid] = None
-                elif val_type == '':
-                    # dictionary
-                    k = val_elem.getAttribute('key').encode('utf8')
-                    v = val_elem.getAttribute('value').encode('utf8')
-                    if val_name not in cls_dict:
-                        cls_dict[val_name] = {}
-                    cls_dict[val_name][k] = v
+                if val_type == 'list':
+                    cls_dict[val_name] = []
+                    for item in val_elem.childNodes:
+                        if item.nodeType != Node.ELEMENT_NODE:
+                            continue # skip non element nodes
+                        cls_dict[val_name].append(item.getAttribute('uuid'))
+                elif val_type == 'dict':
+                    cls_dict[val_name] = {}
+                    for item in val_elem.childNodes:
+                        if item.nodeType != Node.ELEMENT_NODE:
+                            continue # skip non element nodes
+                        k = item.getAttribute('key').encode('utf8')
+                        v = item.getAttribute('value').encode('utf8')
+                        cls_dict[val_name][k] = v
                 elif val_type == 'string':
                     cls_dict[val_name] = val_text.encode('utf8')
                 elif val_type == 'float':
@@ -158,8 +162,7 @@ class XendStateStore:
         @param state: a Xen API struct of the state of the class.
         @type  state: dict
         @rtype: None
-        """
-        
+        """        
         xml_path = self._xml_file(cls)
 
         doc = minidom.getDOMImplementation().createDocument(None,
@@ -191,7 +194,7 @@ class XendStateStore:
                     store_val = str(int(val))
                     store_type = 'bool'
 
-                if store_type != None:
+                if store_type is not None:
                     val_node = doc.createElement(key)
                     val_node.setAttribute('type', store_type)
                     node.appendChild(val_node)
@@ -202,19 +205,25 @@ class XendStateStore:
 
                 # deal with dicts and lists
                 if type(val) == dict:
-                    for val_uuid in val.keys():
-                        val_node = doc.createElement(key)
+                    val_node = doc.createElement(key)
+                    val_node.setAttribute('type', 'dict')
+                    for val_item in val.keys():
+                        tmp = doc.createElement("item")
                         if key in ['other_config', 'device_config']:
-                            val_node.setAttribute('key', str(val_uuid))
-                            val_node.setAttribute('value', str(val[val_uuid]))
+                            tmp.setAttribute('key', str(val_item))
+                            tmp.setAttribute('value', str(val[val_item]))
                         else:
-                            val_node.setAttribute('uuid', val_uuid)
-                        node.appendChild(val_node)
+                            tmp.setAttribute('uuid', val_uuid)
+                        val_node.appendChild(tmp)
+                    node.appendChild(val_node)
                 elif type(val) in (list, tuple):
+                    val_node = doc.createElement(key)
+                    val_node.setAttribute('type', 'list')
                     for val_uuid in val:
-                        val_node = doc.createElement(key)
-                        val_node.setAttribute('uuid', val_uuid)
-                        node.appendChild(val_node)
+                        tmp = doc.createElement("item")
+                        tmp.setAttribute('uuid', val_uuid)
+                        val_node.appendChild(tmp)
+                    node.appendChild(val_node)
 
         open(xml_path, 'w').write(doc.toprettyxml())
         
diff -r ee16cdeddade -r 1668299c0ea4 
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py    Wed Apr 25 10:39:08 
2007 +0100
+++ b/tools/python/xen/xend/XendStorageRepository.py    Sat Apr 28 10:28:59 
2007 +0100
@@ -24,7 +24,7 @@ import sys
 
 from XendError import XendError
 from XendVDI import *
-import XendPBD
+from XendPBD import XendPBD
 
 XEND_STORAGE_NO_MAXIMUM = sys.maxint
 
diff -r ee16cdeddade -r 1668299c0ea4 tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py    Wed Apr 25 10:39:08 2007 +0100
+++ b/tools/python/xen/xend/XendVMMetrics.py    Sat Apr 28 10:28:59 2007 +0100
@@ -17,38 +17,36 @@
 #============================================================================
 
 from xen.xend.XendLogging import log
+from xen.xend.XendBase import XendBase
 import xen.lowlevel.xc
 
 xc = xen.lowlevel.xc.xc()
 
-instances = {}
-
-class XendVMMetrics:
+class XendVMMetrics(XendBase):
     """VM Metrics."""
 
-    def get_by_uuid(_, uuid):
-        return instances[uuid]
+    def getClass(self):
+        return "VM_metrics"
+    
+    def getAttrRO(self):
+        attrRO = ['memory_actual',
+                  'VCPUs_number'