[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.0.4-testing] merge with xen-unstable.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |