WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 Dec 2006 04:30:17 -0800
Delivery-date: Tue, 19 Dec 2006 04:31:06 -0800
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 awilliam@xxxxxxxxxxxx
# Date 1166464594 25200
# Node ID 6e68e8a8cc99717b372c482efa0e153e868ae6f4
# Parent  ea2dc4a3c8eb5ee780dbbc6d12447b6bda2ee2b4
# Parent  469478194aef6e987f9281efbc0756749be6eb80
merge with xen-unstable.hg
---
 .hgignore                                        |    1 
 config/x86_32.mk                                 |    1 
 config/x86_64.mk                                 |    1 
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c |  102 +++++++++++++++++++---
 tools/ioemu/target-i386-dm/exec-dm.c             |   35 ++++++-
 tools/python/xen/xend/XendAPI.py                 |    5 -
 tools/python/xen/xend/XendCheckpoint.py          |    9 -
 tools/python/xen/xend/XendConfig.py              |   84 ++++++++++++------
 tools/python/xen/xend/XendDomain.py              |   20 ++--
 tools/python/xen/xend/XendDomainInfo.py          |    5 -
 tools/python/xen/xend/server/netif.py            |    2 
 tools/python/xen/xend/server/vfbif.py            |   40 ++++++--
 tools/python/xen/xm/XenAPI.py                    |   14 +--
 tools/python/xen/xm/create.py                    |    4 
 tools/python/xen/xm/main.py                      |   10 +-
 tools/xenfb/vncfb.c                              |  106 ++++++++++++++++++++---
 tools/xm-test/lib/XmTestLib/acm.py               |    2 
 17 files changed, 344 insertions(+), 97 deletions(-)

diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 .hgignore
--- a/.hgignore Mon Dec 18 10:20:34 2006 -0700
+++ b/.hgignore Mon Dec 18 10:56:34 2006 -0700
@@ -229,3 +229,4 @@
 ^unmodified_drivers/linux-2.6/.*\.cmd$
 ^unmodified_drivers/linux-2.6/.*\.ko$
 ^unmodified_drivers/linux-2.6/.*\.mod\.c$
+^LibVNCServer.*
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 config/x86_32.mk
--- a/config/x86_32.mk  Mon Dec 18 10:20:34 2006 -0700
+++ b/config/x86_32.mk  Mon Dec 18 10:56:34 2006 -0700
@@ -1,4 +1,5 @@ CONFIG_X86 := y
 CONFIG_X86 := y
+CONFIG_X86_32 := y
 CONFIG_X86_$(XEN_OS) := y
 
 CONFIG_HVM := y
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 config/x86_64.mk
--- a/config/x86_64.mk  Mon Dec 18 10:20:34 2006 -0700
+++ b/config/x86_64.mk  Mon Dec 18 10:56:34 2006 -0700
@@ -1,4 +1,5 @@ CONFIG_X86 := y
 CONFIG_X86 := y
+CONFIG_X86_64 := y
 CONFIG_X86_$(XEN_OS) := y
 
 CONFIG_HVM := y
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c  Mon Dec 18 10:20:34 
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c  Mon Dec 18 10:56:34 
2006 -0700
@@ -49,8 +49,9 @@ struct xenfb_info
        struct timer_list       refresh;
        int                     dirty;
        int                     x1, y1, x2, y2; /* dirty rectangle,
-                                                  protected by mm_lock */
-       spinlock_t              mm_lock;
+                                                  protected by dirty_lock */
+       spinlock_t              dirty_lock;
+       struct mutex            mm_lock;
        int                     nr_pages;
        struct page             **pages;
        struct list_head        mappings; /* protected by mm_lock */
@@ -63,6 +64,70 @@ struct xenfb_info
 
        struct xenbus_device    *xbdev;
 };
+
+/*
+ * How the locks work together
+ *
+ * There are two locks: spinlock dirty_lock protecting the dirty
+ * rectangle, and mutex mm_lock protecting mappings.
+ *
+ * The problem is that dirty rectangle and mappings aren't
+ * independent: the dirty rectangle must cover all faulted pages in
+ * mappings.  We need to prove that our locking maintains this
+ * invariant.
+ *
+ * There are several kinds of critical regions:
+ *
+ * 1. Holding only dirty_lock: xenfb_refresh().  May run in
+ *    interrupts.  Extends the dirty rectangle.  Trivially preserves
+ *    invariant.
+ *
+ * 2. Holding only mm_lock: xenfb_mmap() and xenfb_vm_close().  Touch
+ *    only mappings.  The former creates unfaulted pages.  Preserves
+ *    invariant.  The latter removes pages.  Preserves invariant.
+ *
+ * 3. Holding both locks: xenfb_vm_nopage().  Extends the dirty
+ *    rectangle and updates mappings consistently.  Preserves
+ *    invariant.
+ *
+ * 4. The ugliest one: xenfb_update_screen().  Clear the dirty
+ *    rectangle and update mappings consistently.
+ *
+ *    We can't simply hold both locks, because zap_page_range() cannot
+ *    be called with a spinlock held.
+ *
+ *    Therefore, we first clear the dirty rectangle with both locks
+ *    held.  Then we unlock dirty_lock and update the mappings.
+ *    Critical regions that hold only dirty_lock may interfere with
+ *    that.  This can only be region 1: xenfb_refresh().  But that
+ *    just extends the dirty rectangle, which can't harm the
+ *    invariant.
+ *
+ * But FIXME: the invariant is too weak.  It misses that the fault
+ * record in mappings must be consistent with the mapping of pages in
+ * the associated address space!  do_no_page() updates the PTE after
+ * xenfb_vm_nopage() returns, i.e. outside the critical region.  This
+ * allows the following race:
+ *
+ * X writes to some address in the Xen frame buffer
+ * Fault - call do_no_page()
+ *     call xenfb_vm_nopage()
+ *         grab mm_lock
+ *         map->faults++;
+ *         release mm_lock
+ *     return back to do_no_page()
+ * (preempted, or SMP)
+ * Xen worker thread runs.
+ *      grab mm_lock
+ *      look at mappings
+ *          find this mapping, zaps its pages (but page not in pte yet)
+ *          clear map->faults
+ *      releases mm_lock
+ * (back to X process)
+ *     put page in X's pte
+ *
+ * Oh well, we wont be updating the writes to this page anytime soon.
+ */
 
 static int xenfb_fps = 20;
 static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH 
/ 8;
@@ -105,6 +170,7 @@ static int xenfb_queue_full(struct xenfb
 
 static void xenfb_update_screen(struct xenfb_info *info)
 {
+       unsigned long flags;
        int y1, y2, x1, x2;
        struct xenfb_mapping *map;
 
@@ -113,14 +179,16 @@ static void xenfb_update_screen(struct x
        if (xenfb_queue_full(info))
                return;
 
-       spin_lock(&info->mm_lock);
-
+       mutex_lock(&info->mm_lock);
+
+       spin_lock_irqsave(&info->dirty_lock, flags);
        y1 = info->y1;
        y2 = info->y2;
        x1 = info->x1;
        x2 = info->x2;
        info->x1 = info->y1 = INT_MAX;
        info->x2 = info->y2 = 0;
+       spin_unlock_irqrestore(&info->dirty_lock, flags);
 
        list_for_each_entry(map, &info->mappings, link) {
                if (!map->faults)
@@ -130,7 +198,7 @@ static void xenfb_update_screen(struct x
                map->faults = 0;
        }
 
-       spin_unlock(&info->mm_lock);
+       mutex_unlock(&info->mm_lock);
 
        xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
 }
@@ -213,9 +281,11 @@ static void xenfb_refresh(struct xenfb_i
 static void xenfb_refresh(struct xenfb_info *info,
                          int x1, int y1, int w, int h)
 {
-       spin_lock(&info->mm_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&info->dirty_lock, flags);
        __xenfb_refresh(info, x1, y1, w, h);
-       spin_unlock(&info->mm_lock);
+       spin_unlock_irqrestore(&info->dirty_lock, flags);
 }
 
 static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
@@ -253,12 +323,12 @@ static void xenfb_vm_close(struct vm_are
        struct xenfb_mapping *map = vma->vm_private_data;
        struct xenfb_info *info = map->info;
 
-       spin_lock(&info->mm_lock);
+       mutex_lock(&info->mm_lock);
        if (atomic_dec_and_test(&map->map_refs)) {
                list_del(&map->link);
                kfree(map);
        }
-       spin_unlock(&info->mm_lock);
+       mutex_unlock(&info->mm_lock);
 }
 
 static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
@@ -267,13 +337,15 @@ static struct page *xenfb_vm_nopage(stru
        struct xenfb_mapping *map = vma->vm_private_data;
        struct xenfb_info *info = map->info;
        int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
+       unsigned long flags;
        struct page *page;
        int y1, y2;
 
        if (pgnr >= info->nr_pages)
                return NOPAGE_SIGBUS;
 
-       spin_lock(&info->mm_lock);
+       mutex_lock(&info->mm_lock);
+       spin_lock_irqsave(&info->dirty_lock, flags);
        page = info->pages[pgnr];
        get_page(page);
        map->faults++;
@@ -283,7 +355,8 @@ static struct page *xenfb_vm_nopage(stru
        if (y2 > info->fb_info->var.yres)
                y2 = info->fb_info->var.yres;
        __xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
-       spin_unlock(&info->mm_lock);
+       spin_unlock_irqrestore(&info->dirty_lock, flags);
+       mutex_unlock(&info->mm_lock);
 
        if (type)
                *type = VM_FAULT_MINOR;
@@ -323,9 +396,9 @@ static int xenfb_mmap(struct fb_info *fb
        map->info = info;
        atomic_set(&map->map_refs, 1);
 
-       spin_lock(&info->mm_lock);
+       mutex_lock(&info->mm_lock);
        list_add(&map->link, &info->mappings);
-       spin_unlock(&info->mm_lock);
+       mutex_unlock(&info->mm_lock);
 
        vma->vm_ops = &xenfb_vm_ops;
        vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
@@ -382,7 +455,8 @@ static int __devinit xenfb_probe(struct 
        info->xbdev = dev;
        info->irq = -1;
        info->x1 = info->y1 = INT_MAX;
-       spin_lock_init(&info->mm_lock);
+       spin_lock_init(&info->dirty_lock);
+       mutex_init(&info->mm_lock);
        init_waitqueue_head(&info->wq);
        init_timer(&info->refresh);
        info->refresh.function = xenfb_timer;
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Mon Dec 18 10:56:34 2006 -0700
@@ -128,10 +128,28 @@ FILE *logfile;
 FILE *logfile;
 int loglevel;
 
+
+#if defined(__i386__) || defined(__x86_64__)
+#define MAPCACHE
+#endif
+
+#ifdef MAPCACHE
+static pthread_mutex_t mapcache_mutex;
+#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
+#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
+#else 
+#define mapcache_lock() ( (void)0 )
+#define mapcache_unlock() ( (void)0 )
+#endif
+
+
 void cpu_exec_init(CPUState *env)
 {
     CPUState **penv;
     int cpu_index;
+#ifdef MAPCACHE
+    pthread_mutexattr_t mxattr; 
+#endif
 
     env->next_cpu = NULL;
     penv = &first_cpu;
@@ -145,6 +163,14 @@ void cpu_exec_init(CPUState *env)
 
     /* alloc dirty bits array */
     phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
+
+#ifdef MAPCACHE
+    /* setup memory access mutex to protect mapcache */
+    pthread_mutexattr_init(&mxattr); 
+    pthread_mutexattr_settype(&mxattr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&mapcache_mutex, &mxattr); 
+    pthread_mutexattr_destroy(&mxattr); 
+#endif
 }
 
 /* enable or disable low levels log */
@@ -440,10 +466,7 @@ void cpu_physical_memory_rw(target_phys_
     uint8_t *ptr;
     uint32_t val;
 
-#if defined(__i386__) || defined(__x86_64__)
-    static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-    pthread_mutex_lock(&mutex);
-#endif
+    mapcache_lock();
 
     while (len > 0) {
         /* How much can we copy before the next page boundary? */
@@ -510,9 +533,7 @@ void cpu_physical_memory_rw(target_phys_
         addr += l;
     }
 
-#if defined(__i386__) || defined(__x86_64__)
-    pthread_mutex_unlock(&mutex);
-#endif
+    mapcache_unlock();
 }
 #endif
 
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/XendAPI.py  Mon Dec 18 10:56:34 2006 -0700
@@ -663,7 +663,10 @@ class XendAPI:
             XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
 
     def VM_set(self, name, session, vm_ref, value):
-        XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
+        xd = XendDomain.instance()
+        dominfo = xd.get_vm_by_uuid(vm_ref)
+        dominfo.info[name] = value
+        xd.managed_config_save(dominfo)
         return xen_api_success_void()
 
     # attributes (ro)
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py   Mon Dec 18 10:56:34 2006 -0700
@@ -218,18 +218,17 @@ def forkHelper(cmd, fd, inputHandler, cl
                     log.debug('%s', line)
                     inputHandler(line, child.tochild)
 
-            thread.join()
-
         except IOError, exn:
             raise XendError('Error reading from child process for %s: %s' %
                             (cmd, exn))
     finally:
         child.fromchild.close()
-        child.childerr.close()
         if not closeToChild:
             child.tochild.close()
-
-    status = child.wait()
+        thread.join()
+        child.childerr.close()
+        status = child.wait()
+
     if status >> 8 == 127:
         raise XendError("%s failed: popen failed" % string.join(cmd))
     elif status != 0:
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py       Mon Dec 18 10:56:34 2006 -0700
@@ -15,6 +15,7 @@
 # Copyright (C) 2006 XenSource Ltd
 #============================================================================
 
+import logging
 import re
 import time
 import types
@@ -23,9 +24,12 @@ from xen.xend import uuid
 from xen.xend import uuid
 from xen.xend.XendError import VmError
 from xen.xend.XendDevices import XendDevices
-from xen.xend.XendLogging import log
 from xen.xend.PrettyPrint import prettyprintstring
 from xen.xend.XendConstants import DOM_STATE_HALTED
+
+log = logging.getLogger("xend.XendConfig")
+log.setLevel(logging.WARN)
+
 
 """
 XendConfig API
@@ -182,18 +186,18 @@ LEGACY_CFG_TYPES = {
     'shadow_memory': int,
     'maxmem':        int,
     'start_time':    float,
-    'cpu_cap':         int,
-    'cpu_weight':      int,
+    'cpu_cap':       int,
+    'cpu_weight':    int,
     'cpu_time':      float,
-    'features':        str,
-    'localtime':       int,
-    'name':        str,
-    'on_poweroff': str,
-    'on_reboot':   str,
-    'on_crash':    str,
-    'on_xend_stop': str,
+    'features':      str,
+    'localtime':     int,
+    'name':          str,
+    'on_poweroff':   str,
+    'on_reboot':     str,
+    'on_crash':      str,
+    'on_xend_stop':  str,
     'on_xend_start': str,
-    'online_vcpus': int,
+    'online_vcpus':  int,
 }
 
 # Values that should be stored in xenstore's /vm/<uuid> that is used
@@ -430,8 +434,12 @@ class XendConfig(dict):
         """
         cfg = {}
 
-        # First step is to convert deprecated options to
-        # current equivalents.
+        for key, typ in XENAPI_CFG_TYPES.items():
+            val = sxp.child_value(sxp_cfg, key)
+            if val is not None:
+                cfg[key] = typ(val)
+
+        # Convert deprecated options to current equivalents.
         
         restart = sxp.child_value(sxp_cfg, 'restart')
         if restart:
@@ -574,7 +582,14 @@ class XendConfig(dict):
         """Read in an SXP Configuration object and
         populate at much of the Xen API with valid values.
         """
+        log.debug('_sxp_to_xapi(%s)' % scrub_password(sxp_cfg))
+
         cfg = self._parse_sxp(sxp_cfg)
+
+        for key, typ in XENAPI_CFG_TYPES.items():
+            val = cfg.get(key)
+            if val is not None:
+                self[key] = typ(val)
 
         # Convert parameters that can be directly mapped from
         # the Legacy Config to Xen API Config
@@ -590,9 +605,13 @@ class XendConfig(dict):
             except KeyError:
                 pass
 
-        self['PV_bootloader']      = cfg.get('bootloader',      '')
-        self['PV_bootloader_args'] = cfg.get('bootloader_args', '')
-        
+        def update_with(n, o):
+            if not self.get(n):
+                self[n] = cfg.get(o, '')
+
+        update_with('PV_bootloader',      'bootloader')
+        update_with('PV_bootloader_args', 'bootloader_args')
+
         image_sxp = sxp.child_value(sxp_cfg, 'image', [])
         if image_sxp:
             self.update_with_image_sxp(image_sxp)
@@ -634,6 +653,8 @@ class XendConfig(dict):
         values are that not related directly supported in
         the Xen API.
         """
+
+        log.debug('_sxp_to_xapi_unsupported(%s)' % scrub_password(sxp_cfg))
 
         # Parse and convert parameters used to configure
         # the image (as well as HVM images)
@@ -748,6 +769,9 @@ class XendConfig(dict):
         @param xapi: Xen API VM Struct
         @type xapi: dict
         """
+
+        log.debug('update_with_xenapi_config: %s' % scrub_password(xapi))
+
         for key, val in xapi.items():
             type_conv = XENAPI_CFG_TYPES.get(key)
             if type_conv is None:
@@ -760,11 +784,8 @@ class XendConfig(dict):
 
         self.validate()
 
-    def to_xml(self):
-        """Return an XML string representing the configuration."""
-        pass
-
-    def to_sxp(self, domain = None, ignore_devices = False, ignore = []):
+    def to_sxp(self, domain = None, ignore_devices = False, ignore = [],
+               legacy_only = True):
         """ Get SXP representation of this config object.
 
         Incompat: removed store_mfn, console_mfn
@@ -784,6 +805,11 @@ class XendConfig(dict):
 
         if domain.getDomid() is not None:
             sxpr.append(['domid', domain.getDomid()])
+
+        if not legacy_only:
+            for name in XENAPI_CFG_TYPES.keys():
+                if name in self and self[name] not in (None, []):
+                    sxpr.append([name, str(self[name])])
 
         for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
             if self.has_key(xenapi) and self[xenapi] not in (None, []):
@@ -1044,12 +1070,12 @@ class XendConfig(dict):
         """Returns a backwards compatible image SXP expression that is
         used in xenstore's /vm/<uuid>/image value and xm list."""
         image = [self['image'].get('type', 'linux')]
-        if self.has_key('kernel_kernel'):
-            image.append(['kernel', self['kernel_kernel']])
-        if self.has_key('kernel_initrd') and self['kernel_initrd']:
-            image.append(['ramdisk', self['kernel_initrd']])
-        if self.has_key('kernel_args') and self['kernel_args']:
-            image.append(['args', self['kernel_args']])
+        if self.has_key('PV_kernel'):
+            image.append(['kernel', self['PV_kernel']])
+        if self.has_key('PV_ramdisk') and self['PV_ramdisk']:
+            image.append(['ramdisk', self['PV_ramdisk']])
+        if self.has_key('PV_args') and self['PV_args']:
+            image.append(['args', self['PV_args']])
 
         for arg, conv in LEGACY_IMAGE_CFG:
             if self['image'].has_key(arg):
@@ -1069,8 +1095,10 @@ class XendConfig(dict):
         return image
 
     def update_with_image_sxp(self, image_sxp):
-        # Convert Legacy "image" config to Xen API kernel_*
+        # Convert Legacy "image" config to Xen API PV_*
         # configuration
+        log.debug("update_with_image_sxp(%s)" % scrub_password(image_sxp))
+
         self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
         self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
         kernel_args = sxp.child_value(image_sxp, 'args', '')
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Mon Dec 18 10:56:34 2006 -0700
@@ -26,6 +26,7 @@ import stat
 import stat
 import shutil
 import socket
+import tempfile
 import threading
 
 import xen.lowlevel.xc
@@ -280,16 +281,21 @@ class XendDomain:
             make_or_raise(domain_config_dir)
 
             try:
-                sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
-                prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
-                sxp_cache_file.close()
+                fd, fn = tempfile.mkstemp()
+                f = os.fdopen(fd, 'w+b')
+                try:
+                    prettyprint(dominfo.sxpr(legacy_only = False), f,
+                                width = 78)
+                finally:
+                    f.close()
+                try:
+                    os.rename(fn, self._managed_config_path(dom_uuid))
+                except:
+                    log.exception("Renaming %s" % fn)
+                    os.remove(fn)
             except:
                 log.exception("Error occurred saving configuration file " +
                               "to %s" % domain_config_dir)
-                try:
-                    self._managed_domain_remove(dom_uuid)
-                except:
-                    pass
                 raise XendError("Failed to save configuration file to: %s" %
                                 domain_config_dir)
         else:
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Dec 18 10:56:34 2006 -0700
@@ -1800,9 +1800,10 @@ class XendDomainInfo:
         log.trace("XendDomainInfo.update done on domain %s: %s",
                   str(self.domid), self.info)
 
-    def sxpr(self, ignore_store = False):
+    def sxpr(self, ignore_store = False, legacy_only = True):
         result = self.info.to_sxp(domain = self,
-                                   ignore_devices = ignore_store)
+                                  ignore_devices = ignore_store,
+                                  legacy_only = legacy_only)
 
         if not ignore_store and self.dompath:
             vnc_port = self.readDom('console/vnc-port')
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py     Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/server/netif.py     Mon Dec 18 10:56:34 2006 -0700
@@ -140,7 +140,7 @@ class NetifController(DevController):
 
         script = os.path.join(xroot.network_script_dir,
                               config.get('script', xroot.get_vif_script()))
-        typ = config.get('type')
+        typ     = config.get('type')
         bridge  = config.get('bridge')
         mac     = config.get('mac')
         vifname = config.get('vifname')
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xend/server/vfbif.py     Mon Dec 18 10:56:34 2006 -0700
@@ -1,4 +1,5 @@ from xen.xend.server.DevController impor
 from xen.xend.server.DevController import DevController
+from xen.xend.XendLogging import log
 
 from xen.xend.XendError import VmError
 import xen.xend
@@ -12,6 +13,9 @@ def spawn_detached(path, args, env):
     else:
         os.waitpid(p, 0)
         
+CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
+                  'display', 'xauthority']
+
 class VfbifController(DevController):
     """Virtual frame buffer controller. Handles all vfb devices for a domain.
     Note that we only support a single vfb per domain at the moment.
@@ -19,28 +23,42 @@ class VfbifController(DevController):
 
     def __init__(self, vm):
         DevController.__init__(self, vm)
-        self.config = {}
         
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
-        devid = 0
-        back = {}
-        front = {}
-        return (devid, back, front)
+
+        back = dict([(k, config[k]) for k in CONFIG_ENTRIES
+                     if config.has_key(k)])
+
+        return (0, back, {})
+
 
     def getDeviceConfiguration(self, devid):
-        r = DevController.getDeviceConfiguration(self, devid)
-        for (k,v) in self.config.iteritems():
-            r[k] = v
-        return r
-    
+        result = DevController.getDeviceConfiguration(self, devid)
+
+        devinfo = self.readBackend(devid, *CONFIG_ENTRIES)
+        return dict([(CONFIG_ENTRIES[i], devinfo[i])
+                     for i in range(len(CONFIG_ENTRIES))
+                     if devinfo[i] is not None])
+
+
     def createDevice(self, config):
         DevController.createDevice(self, config)
-        self.config = config
         std_args = [ "--domid", "%d" % self.vm.getDomid(),
                      "--title", self.vm.getName() ]
         t = config.get("type", None)
         if t == "vnc":
+            passwd = None
+            if config.has_key("vncpasswd"):
+                passwd = config["vncpasswd"]
+            else:
+                passwd = xen.xend.XendRoot.instance().get_vncpasswd_default()
+            if passwd:
+                self.vm.storeVm("vncpasswd", passwd)
+                log.debug("Stored a VNC password for vfb access")
+            else:
+                log.debug("No VNC passwd configured for vfb access")
+
             # Try to start the vnc backend
             args = [xen.util.auxbin.pathTo("xen-vncfb")]
             if config.has_key("vncunused"):
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py     Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xm/XenAPI.py     Mon Dec 18 10:56:34 2006 -0700
@@ -83,20 +83,24 @@ class Session(xen.util.xmlrpclib2.Server
 
 
     def xenapi_request(self, methodname, params):
-        full_params = (self._session,) + params
-        return _parse_result(getattr(self, methodname)(*full_params))
+        if methodname.startswith('login'):
+            self._login(methodname, params)
+            return None
+        else:
+            full_params = (self._session,) + params
+            return _parse_result(getattr(self, methodname)(*full_params))
 
 
-    def _login(self, method, username, password):
+    def _login(self, method, params):
         self._session = _parse_result(
-            getattr(self, 'session.%s' % method)(username, password))
+            getattr(self, 'session.%s' % method)(*params))
 
 
     def __getattr__(self, name):
         if name == 'xenapi':
             return _Dispatcher(self.xenapi_request, None)
         elif name.startswith('login'):
-            return lambda u, p: self._login(name, u, p)
+            return lambda *params: self._login(name, params)
         else:
             return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
 
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xm/create.py     Mon Dec 18 10:56:34 2006 -0700
@@ -284,7 +284,7 @@ gopts.var('usbport', val='PATH',
           use="""Add a physical USB port to a domain, as specified by the path
           to that port.  This option may be repeated to add more than one 
port.""")
 
-gopts.var('vfb', 
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY",
+gopts.var('vfb', 
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY,vncpasswd=PASSWORD",
           fn=append_value, default=[],
           use="""Make the domain a framebuffer backend.
           The backend type should be either sdl or vnc.
@@ -584,7 +584,7 @@ def configure_vfbs(config_devs, vals):
             d['type'] = 'sdl'
         for (k,v) in d.iteritems():
             if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
-                          'xauthority', 'type' ]:
+                          'xauthority', 'type', 'vncpasswd' ]:
                 err("configuration option %s unknown to vfbs" % k)
             config.append([k,v])
         if not d.has_key("display") and os.environ.has_key("DISPLAY"):
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/python/xen/xm/main.py       Mon Dec 18 10:56:34 2006 -0700
@@ -558,7 +558,7 @@ class Shell(cmd.Cmd):
                 ok, res = _run_cmd(lambda x: server.xenapi_request(words[0],
                                                                    tuple(x)),
                                    words[0], words[1:])
-                if ok and res != '':
+                if ok and res is not None and res != '':
                     pprint.pprint(res)
             else:
                 print '*** Unknown command: %s' % words[0]
@@ -1556,7 +1556,11 @@ def detach(args, command, deviceClass):
 
 
 def xm_block_detach(args):
-    detach(args, 'block-detach', 'vbd')
+    try:
+        detach(args, 'block-detach', 'vbd')
+        return
+    except:
+        pass
     detach(args, 'block-detach', 'tap')
 
 
@@ -1798,7 +1802,7 @@ def _run_cmd(cmd, cmd_name, args):
     except OptionError, e:
         err(str(e))
         _usage(cmd_name)
-        print e.usage()
+        print e.usage
     except security.ACMError, e:
         err(str(e))
     except:
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/xenfb/vncfb.c
--- a/tools/xenfb/vncfb.c       Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/xenfb/vncfb.c       Mon Dec 18 10:56:34 2006 -0700
@@ -148,6 +148,10 @@ static int xk2linux[0x10000] = {
        [XK_plus] = KEY_EQUAL,
 };
 
+static int btnmap[] = {
+       BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_FORWARD, BTN_BACK
+};
+
 static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
 {
        /*
@@ -184,8 +188,11 @@ static void on_ptr_event(int buttonMask,
                down = buttonMask & (1 << i);
                if (down == last_down)
                        continue;
-               /* FIXME this assumes buttons are numbered the same; verify 
they are */
-               if (xenfb_send_key(xenfb, down != 0, BTN_MOUSE + i) < 0)
+               if (i >= sizeof(btnmap) / sizeof(*btnmap))
+                       break;
+               if (btnmap[i] == 0)
+                       break;
+               if (xenfb_send_key(xenfb, down != 0, btnmap[i]) < 0)
                        fprintf(stderr, "Button %d %s lost (%s)\n",
                                i, down ? "down" : "up", strerror(errno));
        }
@@ -205,15 +212,10 @@ static void on_ptr_event(int buttonMask,
        last_y = y;
 }
 
-static void xenstore_write_vncport(int port, int domid)
-{
-       char *buf = NULL, *path;
+static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid)
+{
+       char *buf, *path;
        char portstr[10];
-       struct xs_handle *xsh = NULL;
-
-       xsh = xs_daemon_open();
-       if (xsh == NULL)
-               return;
 
        path = xs_get_domain_path(xsh, domid);
        if (path == NULL) {
@@ -240,6 +242,56 @@ static void xenstore_write_vncport(int p
        free(buf);
 }
 
+
+static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char 
*pwbuf, int pwbuflen)
+{
+       char buf[256], *path, *uuid = NULL, *passwd = NULL;
+       unsigned int len, rc = 0;
+
+       if (xsh == NULL) {
+               return -1;
+       }
+
+       path = xs_get_domain_path(xsh, domid);
+       if (path == NULL) {
+               fprintf(stderr, "xs_get_domain_path() error\n");
+               return -1;
+       }
+
+       snprintf(buf, 256, "%s/vm", path);
+       uuid = xs_read(xsh, XBT_NULL, buf, &len);
+       if (uuid == NULL) {
+               fprintf(stderr, "xs_read(): uuid get error\n");
+               free(path);
+               return -1;
+       }
+
+       snprintf(buf, 256, "%s/vncpasswd", uuid);
+       passwd = xs_read(xsh, XBT_NULL, buf, &len);
+       if (passwd == NULL) {
+               free(uuid);
+               free(path);
+               return rc;
+       }
+
+       strncpy(pwbuf, passwd, pwbuflen-1);
+       pwbuf[pwbuflen-1] = '\0';
+
+       fprintf(stderr, "Got a VNC password read from XenStore\n");
+
+       passwd[0] = '\0';
+       snprintf(buf, 256, "%s/vncpasswd", uuid);
+       if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
+               fprintf(stderr, "xs_write() vncpasswd failed\n");
+               rc = -1;
+       }
+
+       free(passwd);
+       free(uuid);
+       free(path);
+
+       return rc;
+}
 
 static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h)
 {
@@ -274,6 +326,10 @@ int main(int argc, char **argv)
        char portstr[10];
        char *endp;
        int r;
+       struct xs_handle *xsh;
+       char vncpasswd[1024];
+
+       vncpasswd[0] = '\0';
 
        while ((opt = getopt_long(argc, argv, "d:p:t:u", options,
                                  NULL)) != -1) {
@@ -346,6 +402,19 @@ int main(int argc, char **argv)
                exit(1);
        }
 
+       xsh = xs_daemon_open();
+       if (xsh == NULL) {
+               fprintf(stderr, "cannot open connection to xenstore\n");
+               exit(1);
+       }
+
+
+       if (xenstore_read_vncpasswd(xsh, domid, vncpasswd, 
sizeof(vncpasswd)/sizeof(char)) < 0) {
+               fprintf(stderr, "cannot read VNC password from xenstore\n");
+               exit(1);
+       }
+         
+
        server = rfbGetScreen(&fake_argc, fake_argv, 
                              xenfb->width, xenfb->height,
                              8, 3, xenfb->depth / 8);
@@ -360,6 +429,21 @@ int main(int argc, char **argv)
         if (unused)
                server->autoPort = true;
 
+       if (vncpasswd[0]) {
+               char **passwds = malloc(sizeof(char**)*2);
+               if (!passwds) {
+                       fprintf(stderr, "cannot allocate memory (%s)\n", 
strerror(errno));
+                       exit(1);
+               }
+               fprintf(stderr, "Registered password\n");
+               passwds[0] = vncpasswd;
+               passwds[1] = NULL;
+
+               server->authPasswdData = passwds;
+               server->passwordCheck = rfbCheckPasswordByList;
+       } else {
+               fprintf(stderr, "Running with no password\n");
+       }
        server->serverFormat.redShift = 16;
        server->serverFormat.greenShift = 8;
        server->serverFormat.blueShift = 0;
@@ -372,7 +456,7 @@ int main(int argc, char **argv)
 
        rfbRunEventLoop(server, -1, true);
 
-        xenstore_write_vncport(server->port, domid);
+        xenstore_write_vncport(xsh, server->port, domid);
 
        for (;;) {
                FD_ZERO(&readfds);
diff -r ea2dc4a3c8eb -r 6e68e8a8cc99 tools/xm-test/lib/XmTestLib/acm.py
--- a/tools/xm-test/lib/XmTestLib/acm.py        Mon Dec 18 10:20:34 2006 -0700
+++ b/tools/xm-test/lib/XmTestLib/acm.py        Mon Dec 18 10:56:34 2006 -0700
@@ -57,6 +57,8 @@ def ACMLabelResources(resources):
 
 # Applications may label resources explicitly by calling this function
 def ACMLabelResource(resource, label='red'):
+    if not isACMEnabled():
+        return
     if acm_verbose:
         print "labeling resource %s with label %s" % (resource, label)
     if not ACM_LABEL_RESOURCES:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog