ia64/xen-unstable

changeset 7123:5e5ae8340956

merge
author kaf24@firebug.cl.cam.ac.uk
date Wed Sep 28 21:06:49 2005 +0100 (2005-09-28)
parents 4e1031ce3bc2 081b326162bc
children f069a06e650f
files linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c tools/firmware/vmxassist/vmxloader.c tools/ioemu/vl.c tools/python/xen/xend/PrettyPrint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/xenstore/xstransact.py tools/python/xen/xm/main.py tools/xenstore/xenstored_domain.c
line diff
     1.1 --- a/.hgignore	Mon Sep 26 11:15:55 2005 -0600
     1.2 +++ b/.hgignore	Wed Sep 28 21:06:49 2005 +0100
     1.3 @@ -158,6 +158,7 @@
     1.4  ^tools/xenstore/xs_dom0_test$
     1.5  ^tools/xenstore/xs_random$
     1.6  ^tools/xenstore/xs_stress$
     1.7 +^tools/xenstore/xs_tdb_dump$
     1.8  ^tools/xenstore/xs_test$
     1.9  ^tools/xenstore/xs_watch_stress$
    1.10  ^tools/xentrace/xenctx$
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Mon Sep 26 11:15:55 2005 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Wed Sep 28 21:06:49 2005 +0100
     2.3 @@ -2684,7 +2684,7 @@ CONFIG_ACPI_SYSTEM=y
     2.4  #
     2.5  # File systems
     2.6  #
     2.7 -CONFIG_EXT2_FS=m
     2.8 +CONFIG_EXT2_FS=y
     2.9  CONFIG_EXT2_FS_XATTR=y
    2.10  CONFIG_EXT2_FS_POSIX_ACL=y
    2.11  CONFIG_EXT2_FS_SECURITY=y
    2.12 @@ -2913,7 +2913,7 @@ CONFIG_KEYS=y
    2.13  # CONFIG_KEYS_DEBUG_PROC_KEYS is not set
    2.14  CONFIG_SECURITY=y
    2.15  # CONFIG_SECURITY_NETWORK is not set
    2.16 -CONFIG_SECURITY_CAPABILITIES=m
    2.17 +CONFIG_SECURITY_CAPABILITIES=y
    2.18  CONFIG_SECURITY_ROOTPLUG=m
    2.19  CONFIG_SECURITY_SECLVL=m
    2.20  CONFIG_SECURITY_SELINUX=y
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Mon Sep 26 11:15:55 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Wed Sep 28 21:06:49 2005 +0100
     3.3 @@ -112,6 +112,10 @@ void xen_idle(void)
     3.4  
     3.5  #ifdef CONFIG_HOTPLUG_CPU
     3.6  #include <asm/nmi.h>
     3.7 +#ifdef CONFIG_SMP
     3.8 +extern void smp_suspend(void);
     3.9 +extern void smp_resume(void);
    3.10 +#endif
    3.11  /* We don't actually take CPU down, just spin without interrupts. */
    3.12  static inline void play_dead(void)
    3.13  {
    3.14 @@ -120,6 +124,13 @@ static inline void play_dead(void)
    3.15  		HYPERVISOR_yield();
    3.16  
    3.17  	__flush_tlb_all();
    3.18 +   /* 
    3.19 +    * Restore IPI/IRQ mappings before marking online to prevent 
    3.20 +    * race between pending interrupts and restoration of handler. 
    3.21 +    */
    3.22 +#ifdef CONFIG_SMP
    3.23 +	smp_resume();
    3.24 +#endif
    3.25  	cpu_set(smp_processor_id(), cpu_online_map);
    3.26  }
    3.27  #else
    3.28 @@ -135,10 +146,6 @@ static inline void play_dead(void)
    3.29   * low exit latency (ie sit in a loop waiting for
    3.30   * somebody to say that they'd like to reschedule)
    3.31   */
    3.32 -#ifdef CONFIG_SMP
    3.33 -extern void smp_suspend(void);
    3.34 -extern void smp_resume(void);
    3.35 -#endif
    3.36  void cpu_idle (void)
    3.37  {
    3.38  	int cpu = _smp_processor_id();
    3.39 @@ -166,9 +173,6 @@ void cpu_idle (void)
    3.40  				HYPERVISOR_vcpu_down(cpu);
    3.41  #endif
    3.42  				play_dead();
    3.43 -#ifdef CONFIG_SMP
    3.44 -				smp_resume();
    3.45 -#endif
    3.46  				local_irq_enable();
    3.47  			}
    3.48  
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Mon Sep 26 11:15:55 2005 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Wed Sep 28 21:06:49 2005 +0100
     4.3 @@ -209,7 +209,10 @@ static void dump_fault_path(unsigned lon
     4.4  {
     4.5  	unsigned long *p, page;
     4.6  
     4.7 -        page = __pa(per_cpu(cur_pgd, smp_processor_id()));
     4.8 +	preempt_disable();
     4.9 +	page = __pa(per_cpu(cur_pgd, smp_processor_id()));
    4.10 +	preempt_enable();
    4.11 +
    4.12  	p  = (unsigned long *)__va(page);
    4.13  	p += (address >> 30) * 2;
    4.14  	printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
    4.15 @@ -237,8 +240,13 @@ static void dump_fault_path(unsigned lon
    4.16  {
    4.17  	unsigned long page;
    4.18  
    4.19 +	preempt_disable();
    4.20  	page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id()))
    4.21  	    [address >> 22];
    4.22 +	preempt_enable();
    4.23 +
    4.24 +	page = ((unsigned long *) per_cpu(cur_pgd, get_cpu()))
    4.25 +	    [address >> 22];
    4.26  	printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
    4.27  	       machine_to_phys(page));
    4.28  	/*
    4.29 @@ -567,7 +575,9 @@ vmalloc_fault:
    4.30  		pmd_t *pmd, *pmd_k;
    4.31  		pte_t *pte_k;
    4.32  
    4.33 +		preempt_disable();
    4.34  		pgd = index + per_cpu(cur_pgd, smp_processor_id());
    4.35 +		preempt_enable();
    4.36  		pgd_k = init_mm.pgd + index;
    4.37  
    4.38  		if (!pgd_present(*pgd_k))
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Mon Sep 26 11:15:55 2005 -0600
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Wed Sep 28 21:06:49 2005 +0100
     5.3 @@ -1,13 +1,10 @@
     5.4  /******************************************************************************
     5.5   * gnttab.c
     5.6   * 
     5.7 - * Two sets of functionality:
     5.8 - * 1. Granting foreign access to our memory reservation.
     5.9 - * 2. Accessing others' memory reservations via grant references.
    5.10 - * (i.e., mechanisms for both sender and recipient of grant references)
    5.11 + * Granting foreign access to our memory reservation.
    5.12   * 
    5.13   * Copyright (c) 2005, Christopher Clark
    5.14 - * Copyright (c) 2004, K A Fraser
    5.15 + * Copyright (c) 2004-2005, K A Fraser
    5.16   */
    5.17  
    5.18  #include <linux/config.h>
    5.19 @@ -23,15 +20,15 @@
    5.20  #include <asm/synch_bitops.h>
    5.21  
    5.22  #if 1
    5.23 -#define ASSERT(_p) \
    5.24 -    if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
    5.25 -    #_p , __LINE__, __FILE__); *(int*)0=0; }
    5.26 +#define ASSERT(_p)							      \
    5.27 +	if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
    5.28 +	#_p , __LINE__, __FILE__); *(int*)0=0; }
    5.29  #else
    5.30  #define ASSERT(_p) ((void)0)
    5.31  #endif
    5.32  
    5.33 -#define WPRINTK(fmt, args...) \
    5.34 -    printk(KERN_WARNING "xen_grant: " fmt, ##args)
    5.35 +#define WPRINTK(fmt, args...)				\
    5.36 +	printk(KERN_WARNING "xen_grant: " fmt, ##args)
    5.37  
    5.38  
    5.39  EXPORT_SYMBOL(gnttab_grant_foreign_access);
    5.40 @@ -49,11 +46,14 @@ EXPORT_SYMBOL(gnttab_release_grant_refer
    5.41  EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
    5.42  EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
    5.43  
    5.44 +/* External tools reserve first few grant table entries. */
    5.45 +#define NR_RESERVED_ENTRIES 8
    5.46 +
    5.47  #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    5.48  #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
    5.49  
    5.50  static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
    5.51 -static int gnttab_free_count = NR_GRANT_ENTRIES;
    5.52 +static int gnttab_free_count;
    5.53  static grant_ref_t gnttab_free_head;
    5.54  static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
    5.55  
    5.56 @@ -64,22 +64,22 @@ static struct gnttab_free_callback *gntt
    5.57  static int
    5.58  get_free_entries(int count)
    5.59  {
    5.60 -    unsigned long flags;
    5.61 -    int ref;
    5.62 -    grant_ref_t head;
    5.63 -    spin_lock_irqsave(&gnttab_list_lock, flags);
    5.64 -    if (gnttab_free_count < count) {
    5.65 +	unsigned long flags;
    5.66 +	int ref;
    5.67 +	grant_ref_t head;
    5.68 +	spin_lock_irqsave(&gnttab_list_lock, flags);
    5.69 +	if (gnttab_free_count < count) {
    5.70 +		spin_unlock_irqrestore(&gnttab_list_lock, flags);
    5.71 +		return -1;
    5.72 +	}
    5.73 +	ref = head = gnttab_free_head;
    5.74 +	gnttab_free_count -= count;
    5.75 +	while (count-- > 1)
    5.76 +		head = gnttab_list[head];
    5.77 +	gnttab_free_head = gnttab_list[head];
    5.78 +	gnttab_list[head] = GNTTAB_LIST_END;
    5.79  	spin_unlock_irqrestore(&gnttab_list_lock, flags);
    5.80 -	return -1;
    5.81 -    }
    5.82 -    ref = head = gnttab_free_head;
    5.83 -    gnttab_free_count -= count;
    5.84 -    while (count-- > 1)
    5.85 -	head = gnttab_list[head];
    5.86 -    gnttab_free_head = gnttab_list[head];
    5.87 -    gnttab_list[head] = GNTTAB_LIST_END;
    5.88 -    spin_unlock_irqrestore(&gnttab_list_lock, flags);
    5.89 -    return ref;
    5.90 +	return ref;
    5.91  }
    5.92  
    5.93  #define get_free_entry() get_free_entries(1)
    5.94 @@ -87,38 +87,41 @@ get_free_entries(int count)
    5.95  static void
    5.96  do_free_callbacks(void)
    5.97  {
    5.98 -    struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
    5.99 -    gnttab_free_callback_list = NULL;
   5.100 -    while (callback) {
   5.101 -	next = callback->next;
   5.102 -	if (gnttab_free_count >= callback->count) {
   5.103 -	    callback->next = NULL;
   5.104 -	    callback->fn(callback->arg);
   5.105 -	} else {
   5.106 -	    callback->next = gnttab_free_callback_list;
   5.107 -	    gnttab_free_callback_list = callback;
   5.108 +	struct gnttab_free_callback *callback, *next;
   5.109 +
   5.110 +	callback = gnttab_free_callback_list;
   5.111 +	gnttab_free_callback_list = NULL;
   5.112 +
   5.113 +	while (callback != NULL) {
   5.114 +		next = callback->next;
   5.115 +		if (gnttab_free_count >= callback->count) {
   5.116 +			callback->next = NULL;
   5.117 +			callback->fn(callback->arg);
   5.118 +		} else {
   5.119 +			callback->next = gnttab_free_callback_list;
   5.120 +			gnttab_free_callback_list = callback;
   5.121 +		}
   5.122 +		callback = next;
   5.123  	}
   5.124 -	callback = next;
   5.125 -    }
   5.126  }
   5.127  
   5.128  static inline void
   5.129  check_free_callbacks(void)
   5.130  {
   5.131 -    if (unlikely(gnttab_free_callback_list))
   5.132 -	do_free_callbacks();
   5.133 +	if (unlikely(gnttab_free_callback_list))
   5.134 +		do_free_callbacks();
   5.135  }
   5.136  
   5.137  static void
   5.138  put_free_entry(grant_ref_t ref)
   5.139  {
   5.140 -    unsigned long flags;
   5.141 -    spin_lock_irqsave(&gnttab_list_lock, flags);
   5.142 -    gnttab_list[ref] = gnttab_free_head;
   5.143 -    gnttab_free_head = ref;
   5.144 -    gnttab_free_count++;
   5.145 -    check_free_callbacks();
   5.146 -    spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.147 +	unsigned long flags;
   5.148 +	spin_lock_irqsave(&gnttab_list_lock, flags);
   5.149 +	gnttab_list[ref] = gnttab_free_head;
   5.150 +	gnttab_free_head = ref;
   5.151 +	gnttab_free_count++;
   5.152 +	check_free_callbacks();
   5.153 +	spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.154  }
   5.155  
   5.156  /*
   5.157 @@ -128,187 +131,189 @@ put_free_entry(grant_ref_t ref)
   5.158  int
   5.159  gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
   5.160  {
   5.161 -    int ref;
   5.162 +	int ref;
   5.163      
   5.164 -    if ( unlikely((ref = get_free_entry()) == -1) )
   5.165 -        return -ENOSPC;
   5.166 +	if (unlikely((ref = get_free_entry()) == -1))
   5.167 +		return -ENOSPC;
   5.168  
   5.169 -    shared[ref].frame = frame;
   5.170 -    shared[ref].domid = domid;
   5.171 -    wmb();
   5.172 -    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   5.173 +	shared[ref].frame = frame;
   5.174 +	shared[ref].domid = domid;
   5.175 +	wmb();
   5.176 +	shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   5.177  
   5.178 -    return ref;
   5.179 +	return ref;
   5.180  }
   5.181  
   5.182  void
   5.183  gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
   5.184  				unsigned long frame, int readonly)
   5.185  {
   5.186 -    shared[ref].frame = frame;
   5.187 -    shared[ref].domid = domid;
   5.188 -    wmb();
   5.189 -    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   5.190 +	shared[ref].frame = frame;
   5.191 +	shared[ref].domid = domid;
   5.192 +	wmb();
   5.193 +	shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   5.194  }
   5.195  
   5.196  
   5.197  int
   5.198  gnttab_query_foreign_access(grant_ref_t ref)
   5.199  {
   5.200 -    u16 nflags;
   5.201 +	u16 nflags;
   5.202  
   5.203 -    nflags = shared[ref].flags;
   5.204 +	nflags = shared[ref].flags;
   5.205  
   5.206 -    return ( nflags & (GTF_reading|GTF_writing) );
   5.207 +	return (nflags & (GTF_reading|GTF_writing));
   5.208  }
   5.209  
   5.210  void
   5.211  gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
   5.212  {
   5.213 -    u16 flags, nflags;
   5.214 +	u16 flags, nflags;
   5.215  
   5.216 -    nflags = shared[ref].flags;
   5.217 -    do {
   5.218 -        if ( (flags = nflags) & (GTF_reading|GTF_writing) )
   5.219 -            printk(KERN_ALERT "WARNING: g.e. still in use!\n");
   5.220 -    }
   5.221 -    while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags );
   5.222 +	nflags = shared[ref].flags;
   5.223 +	do {
   5.224 +		if ( (flags = nflags) & (GTF_reading|GTF_writing) )
   5.225 +			printk(KERN_ALERT "WARNING: g.e. still in use!\n");
   5.226 +	}
   5.227 +	while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
   5.228 +	       flags);
   5.229  }
   5.230  
   5.231  void
   5.232  gnttab_end_foreign_access(grant_ref_t ref, int readonly)
   5.233  {
   5.234 -    gnttab_end_foreign_access_ref(ref, readonly);
   5.235 -    put_free_entry(ref);
   5.236 +	gnttab_end_foreign_access_ref(ref, readonly);
   5.237 +	put_free_entry(ref);
   5.238  }
   5.239  
   5.240  int
   5.241  gnttab_grant_foreign_transfer(domid_t domid)
   5.242  {
   5.243 -    int ref;
   5.244 +	int ref;
   5.245  
   5.246 -    if ( unlikely((ref = get_free_entry()) == -1) )
   5.247 -        return -ENOSPC;
   5.248 +	if (unlikely((ref = get_free_entry()) == -1))
   5.249 +		return -ENOSPC;
   5.250  
   5.251 -    shared[ref].frame = 0;
   5.252 -    shared[ref].domid = domid;
   5.253 -    wmb();
   5.254 -    shared[ref].flags = GTF_accept_transfer;
   5.255 +	shared[ref].frame = 0;
   5.256 +	shared[ref].domid = domid;
   5.257 +	wmb();
   5.258 +	shared[ref].flags = GTF_accept_transfer;
   5.259  
   5.260 -    return ref;
   5.261 +	return ref;
   5.262  }
   5.263  
   5.264  void
   5.265  gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
   5.266  {
   5.267 -    shared[ref].frame = 0;
   5.268 -    shared[ref].domid = domid;
   5.269 -    wmb();
   5.270 -    shared[ref].flags = GTF_accept_transfer;
   5.271 +	shared[ref].frame = 0;
   5.272 +	shared[ref].domid = domid;
   5.273 +	wmb();
   5.274 +	shared[ref].flags = GTF_accept_transfer;
   5.275  }
   5.276  
   5.277  unsigned long
   5.278  gnttab_end_foreign_transfer_ref(grant_ref_t ref)
   5.279  {
   5.280 -    unsigned long frame = 0;
   5.281 -    u16           flags;
   5.282 +	unsigned long frame = 0;
   5.283 +	u16           flags;
   5.284  
   5.285 -    flags = shared[ref].flags;
   5.286 +	flags = shared[ref].flags;
   5.287  
   5.288 -    /*
   5.289 -     * If a transfer is committed then wait for the frame address to appear.
   5.290 -     * Otherwise invalidate the grant entry against future use.
   5.291 -     */
   5.292 -    if ( likely(flags != GTF_accept_transfer) ||
   5.293 -         (synch_cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
   5.294 -        while ( unlikely((frame = shared[ref].frame) == 0) )
   5.295 -            cpu_relax();
   5.296 +	/*
   5.297 +	 * If a transfer is committed then wait for the frame address to
   5.298 +	 * appear. Otherwise invalidate the grant entry against future use.
   5.299 +	 */
   5.300 +	if (likely(flags != GTF_accept_transfer) ||
   5.301 +	    (synch_cmpxchg(&shared[ref].flags, flags, 0) !=
   5.302 +	     GTF_accept_transfer))
   5.303 +		while (unlikely((frame = shared[ref].frame) == 0))
   5.304 +			cpu_relax();
   5.305  
   5.306 -    return frame;
   5.307 +	return frame;
   5.308  }
   5.309  
   5.310  unsigned long
   5.311  gnttab_end_foreign_transfer(grant_ref_t ref)
   5.312  {
   5.313 -    unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
   5.314 -    put_free_entry(ref);
   5.315 -    return frame;
   5.316 +	unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
   5.317 +	put_free_entry(ref);
   5.318 +	return frame;
   5.319  }
   5.320  
   5.321  void
   5.322  gnttab_free_grant_reference(grant_ref_t ref)
   5.323  {
   5.324  
   5.325 -    put_free_entry(ref);
   5.326 +	put_free_entry(ref);
   5.327  }
   5.328  
   5.329  void
   5.330  gnttab_free_grant_references(grant_ref_t head)
   5.331  {
   5.332 -    grant_ref_t ref;
   5.333 -    unsigned long flags;
   5.334 -    int count = 1;
   5.335 -    if (head == GNTTAB_LIST_END)
   5.336 -	return;
   5.337 -    spin_lock_irqsave(&gnttab_list_lock, flags);
   5.338 -    ref = head;
   5.339 -    while (gnttab_list[ref] != GNTTAB_LIST_END) {
   5.340 -	ref = gnttab_list[ref];
   5.341 -	count++;
   5.342 -    }
   5.343 -    gnttab_list[ref] = gnttab_free_head;
   5.344 -    gnttab_free_head = head;
   5.345 -    gnttab_free_count += count;
   5.346 -    check_free_callbacks();
   5.347 -    spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.348 +	grant_ref_t ref;
   5.349 +	unsigned long flags;
   5.350 +	int count = 1;
   5.351 +	if (head == GNTTAB_LIST_END)
   5.352 +		return;
   5.353 +	spin_lock_irqsave(&gnttab_list_lock, flags);
   5.354 +	ref = head;
   5.355 +	while (gnttab_list[ref] != GNTTAB_LIST_END) {
   5.356 +		ref = gnttab_list[ref];
   5.357 +		count++;
   5.358 +	}
   5.359 +	gnttab_list[ref] = gnttab_free_head;
   5.360 +	gnttab_free_head = head;
   5.361 +	gnttab_free_count += count;
   5.362 +	check_free_callbacks();
   5.363 +	spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.364  }
   5.365  
   5.366  int
   5.367  gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
   5.368  {
   5.369 -    int h = get_free_entries(count);
   5.370 +	int h = get_free_entries(count);
   5.371  
   5.372 -    if (h == -1)
   5.373 -	return -ENOSPC;
   5.374 +	if (h == -1)
   5.375 +		return -ENOSPC;
   5.376  
   5.377 -    *head = h;
   5.378 +	*head = h;
   5.379  
   5.380 -    return 0;
   5.381 +	return 0;
   5.382  }
   5.383  
   5.384  int
   5.385  gnttab_claim_grant_reference(grant_ref_t *private_head)
   5.386  {
   5.387 -    grant_ref_t g = *private_head;
   5.388 -    if (unlikely(g == GNTTAB_LIST_END))
   5.389 -        return -ENOSPC;
   5.390 -    *private_head = gnttab_list[g];
   5.391 -    return g;
   5.392 +	grant_ref_t g = *private_head;
   5.393 +	if (unlikely(g == GNTTAB_LIST_END))
   5.394 +		return -ENOSPC;
   5.395 +	*private_head = gnttab_list[g];
   5.396 +	return g;
   5.397  }
   5.398  
   5.399  void
   5.400  gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t  release)
   5.401  {
   5.402 -    gnttab_list[release] = *private_head;
   5.403 -    *private_head = release;
   5.404 +	gnttab_list[release] = *private_head;
   5.405 +	*private_head = release;
   5.406  }
   5.407  
   5.408  void
   5.409  gnttab_request_free_callback(struct gnttab_free_callback *callback,
   5.410  			     void (*fn)(void *), void *arg, u16 count)
   5.411  {
   5.412 -    unsigned long flags;
   5.413 -    spin_lock_irqsave(&gnttab_list_lock, flags);
   5.414 -    if (callback->next)
   5.415 -	goto out;
   5.416 -    callback->fn = fn;
   5.417 -    callback->arg = arg;
   5.418 -    callback->count = count;
   5.419 -    callback->next = gnttab_free_callback_list;
   5.420 -    gnttab_free_callback_list = callback;
   5.421 -    check_free_callbacks();
   5.422 +	unsigned long flags;
   5.423 +	spin_lock_irqsave(&gnttab_list_lock, flags);
   5.424 +	if (callback->next)
   5.425 +		goto out;
   5.426 +	callback->fn = fn;
   5.427 +	callback->arg = arg;
   5.428 +	callback->count = count;
   5.429 +	callback->next = gnttab_free_callback_list;
   5.430 +	gnttab_free_callback_list = callback;
   5.431 +	check_free_callbacks();
   5.432   out:
   5.433 -    spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.434 +	spin_unlock_irqrestore(&gnttab_list_lock, flags);
   5.435  }
   5.436  
   5.437  /*
   5.438 @@ -323,79 +328,83 @@ static int
   5.439  grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
   5.440  	    unsigned long data)
   5.441  {
   5.442 -    int                     ret;
   5.443 -    privcmd_hypercall_t     hypercall;
   5.444 +	int                     ret;
   5.445 +	privcmd_hypercall_t     hypercall;
   5.446  
   5.447 -    /* XXX Need safety checks here if using for anything other
   5.448 -     *     than debugging */
   5.449 -    return -ENOSYS;
   5.450 +	/*
   5.451 +	 * XXX Need safety checks here if using for anything other
   5.452 +	 *     than debugging.
   5.453 +	 */
   5.454 +	return -ENOSYS;
   5.455  
   5.456 -    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
   5.457 -        return -ENOSYS;
   5.458 +	if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
   5.459 +		return -ENOSYS;
   5.460  
   5.461 -    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
   5.462 -        return -EFAULT;
   5.463 +	if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
   5.464 +		return -EFAULT;
   5.465  
   5.466 -    if ( hypercall.op != __HYPERVISOR_grant_table_op )
   5.467 -        return -ENOSYS;
   5.468 +	if ( hypercall.op != __HYPERVISOR_grant_table_op )
   5.469 +		return -ENOSYS;
   5.470  
   5.471 -    /* hypercall-invoking asm taken from privcmd.c */
   5.472 -    __asm__ __volatile__ (
   5.473 -        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
   5.474 -        "movl  4(%%eax),%%ebx ;"
   5.475 -        "movl  8(%%eax),%%ecx ;"
   5.476 -        "movl 12(%%eax),%%edx ;"
   5.477 -        "movl 16(%%eax),%%esi ;"
   5.478 -        "movl 20(%%eax),%%edi ;"
   5.479 -        "movl   (%%eax),%%eax ;"
   5.480 -        TRAP_INSTR "; "
   5.481 -        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
   5.482 -        : "=a" (ret) : "0" (&hypercall) : "memory" );
   5.483 +	/* hypercall-invoking asm taken from privcmd.c */
   5.484 +	__asm__ __volatile__ (
   5.485 +		"pushl %%ebx; pushl %%ecx; pushl %%edx; "
   5.486 +		"pushl %%esi; pushl %%edi; "
   5.487 +		"movl  4(%%eax),%%ebx ;"
   5.488 +		"movl  8(%%eax),%%ecx ;"
   5.489 +		"movl 12(%%eax),%%edx ;"
   5.490 +		"movl 16(%%eax),%%esi ;"
   5.491 +		"movl 20(%%eax),%%edi ;"
   5.492 +		"movl   (%%eax),%%eax ;"
   5.493 +		TRAP_INSTR "; "
   5.494 +		"popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
   5.495 +		: "=a" (ret) : "0" (&hypercall) : "memory" );
   5.496  
   5.497 -    return ret;
   5.498 +	return ret;
   5.499  }
   5.500  
   5.501  static struct file_operations grant_file_ops = {
   5.502 -    ioctl:  grant_ioctl,
   5.503 +	ioctl:  grant_ioctl,
   5.504  };
   5.505  
   5.506  static int
   5.507  grant_read(char *page, char **start, off_t off, int count, int *eof,
   5.508  	   void *data)
   5.509  {
   5.510 -    int             len;
   5.511 -    unsigned int    i;
   5.512 -    grant_entry_t  *gt;
   5.513 +	int             len;
   5.514 +	unsigned int    i;
   5.515 +	grant_entry_t  *gt;
   5.516  
   5.517 -    gt = (grant_entry_t *)shared;
   5.518 -    len = 0;
   5.519 +	gt = (grant_entry_t *)shared;
   5.520 +	len = 0;
   5.521  
   5.522 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   5.523 -        /* TODO: safety catch here until this can handle >PAGE_SIZE output */
   5.524 -        if (len > (PAGE_SIZE - 200))
   5.525 -        {
   5.526 -            len += sprintf( page + len, "Truncated.\n");
   5.527 -            break;
   5.528 -        }
   5.529 +	for (i = 0; i < NR_GRANT_ENTRIES; i++) {
   5.530 +		if (len > (PAGE_SIZE - 200)) {
   5.531 +			len += sprintf( page + len, "Truncated.\n");
   5.532 +			break;
   5.533 +		}
   5.534 +	}
   5.535  
   5.536 -        if ( gt[i].flags )
   5.537 -            len += sprintf( page + len,
   5.538 -                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", 
   5.539 -                    i,
   5.540 -                    gt[i].flags,
   5.541 -                    gt[i].domid,
   5.542 -                    gt[i].frame );
   5.543 +	if (gt[i].flags) {
   5.544 +		len += sprintf(page + len,
   5.545 +			       "Grant: ref (0x%x) flags (0x%hx) "
   5.546 +			       "dom (0x%hx) frame (0x%x)\n", 
   5.547 +			       i,
   5.548 +			       gt[i].flags,
   5.549 +			       gt[i].domid,
   5.550 +			       gt[i].frame );
   5.551 +	}
   5.552  
   5.553 -    *eof = 1;
   5.554 -    return len;
   5.555 +	*eof = 1;
   5.556 +	return len;
   5.557  }
   5.558  
   5.559  static int
   5.560  grant_write(struct file *file, const char __user *buffer, unsigned long count,
   5.561  	    void *data)
   5.562  {
   5.563 -    /* TODO: implement this */
   5.564 -    return -ENOSYS;
   5.565 +	/* TODO: implement this */
   5.566 +	return -ENOSYS;
   5.567  }
   5.568  
   5.569  #endif /* CONFIG_PROC_FS */
   5.570 @@ -403,70 +412,81 @@ grant_write(struct file *file, const cha
   5.571  int
   5.572  gnttab_resume(void)
   5.573  {
   5.574 -    gnttab_setup_table_t setup;
   5.575 -    unsigned long        frames[NR_GRANT_FRAMES];
   5.576 -    int                  i;
   5.577 +	gnttab_setup_table_t setup;
   5.578 +	unsigned long        frames[NR_GRANT_FRAMES];
   5.579 +	int                  i;
   5.580  
   5.581 -    setup.dom        = DOMID_SELF;
   5.582 -    setup.nr_frames  = NR_GRANT_FRAMES;
   5.583 -    setup.frame_list = frames;
   5.584 +	setup.dom        = DOMID_SELF;
   5.585 +	setup.nr_frames  = NR_GRANT_FRAMES;
   5.586 +	setup.frame_list = frames;
   5.587  
   5.588 -    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0);
   5.589 -    BUG_ON(setup.status != 0);
   5.590 +	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
   5.591 +	BUG_ON(setup.status != 0);
   5.592  
   5.593 -    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
   5.594 -        set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
   5.595 +	for (i = 0; i < NR_GRANT_FRAMES; i++)
   5.596 +		set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
   5.597  
   5.598 -    return 0;
   5.599 +	return 0;
   5.600  }
   5.601  
   5.602  int
   5.603  gnttab_suspend(void)
   5.604  {
   5.605 -    int i;
   5.606 +	int i;
   5.607  
   5.608 -    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
   5.609 -	clear_fixmap(FIX_GNTTAB_END - i);
   5.610 +	for (i = 0; i < NR_GRANT_FRAMES; i++)
   5.611 +		clear_fixmap(FIX_GNTTAB_END - i);
   5.612  
   5.613 -    return 0;
   5.614 +	return 0;
   5.615  }
   5.616  
   5.617  static int __init
   5.618  gnttab_init(void)
   5.619  {
   5.620 -    int i;
   5.621 +	int i;
   5.622  
   5.623 -    if (xen_init() < 0)
   5.624 -        return -ENODEV;
   5.625 +	if (xen_init() < 0)
   5.626 +		return -ENODEV;
   5.627 +
   5.628 +	BUG_ON(gnttab_resume());
   5.629  
   5.630 -    BUG_ON(gnttab_resume());
   5.631 -
   5.632 -    shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
   5.633 +	shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
   5.634  
   5.635 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   5.636 -        gnttab_list[i] = i + 1;
   5.637 -    
   5.638 +	for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
   5.639 +		gnttab_list[i] = i + 1;
   5.640 +	gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
   5.641 +	gnttab_free_head  = NR_RESERVED_ENTRIES;
   5.642 +
   5.643  #ifdef CONFIG_PROC_FS
   5.644 -    /*
   5.645 -     *  /proc/xen/grant : used by libxc to access grant tables
   5.646 -     */
   5.647 -    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
   5.648 -    {
   5.649 -        WPRINTK("Unable to create grant xen proc entry\n");
   5.650 -        return -1;
   5.651 -    }
   5.652 +	/*
   5.653 +	 *  /proc/xen/grant : used by libxc to access grant tables
   5.654 +	 */
   5.655 +	if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
   5.656 +		WPRINTK("Unable to create grant xen proc entry\n");
   5.657 +		return -1;
   5.658 +	}
   5.659  
   5.660 -    grant_file_ops.read   = grant_pde->proc_fops->read;
   5.661 -    grant_file_ops.write  = grant_pde->proc_fops->write;
   5.662 +	grant_file_ops.read   = grant_pde->proc_fops->read;
   5.663 +	grant_file_ops.write  = grant_pde->proc_fops->write;
   5.664  
   5.665 -    grant_pde->proc_fops  = &grant_file_ops;
   5.666 +	grant_pde->proc_fops  = &grant_file_ops;
   5.667  
   5.668 -    grant_pde->read_proc  = &grant_read;
   5.669 -    grant_pde->write_proc = &grant_write;
   5.670 +	grant_pde->read_proc  = &grant_read;
   5.671 +	grant_pde->write_proc = &grant_write;
   5.672  #endif
   5.673  
   5.674 -    printk("Grant table initialized\n");
   5.675 -    return 0;
   5.676 +	printk("Grant table initialized\n");
   5.677 +	return 0;
   5.678  }
   5.679  
   5.680  __initcall(gnttab_init);
   5.681 +
   5.682 +/*
   5.683 + * Local variables:
   5.684 + *  c-file-style: "linux"
   5.685 + *  indent-tabs-mode: t
   5.686 + *  c-indent-level: 8
   5.687 + *  c-basic-offset: 8
   5.688 + *  tab-width: 8
   5.689 + * End:
   5.690 + */
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Mon Sep 26 11:15:55 2005 -0600
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Wed Sep 28 21:06:49 2005 +0100
     6.3 @@ -149,7 +149,9 @@ void dump_pagetable(unsigned long addres
     6.4  	pmd_t *pmd;
     6.5  	pte_t *pte;
     6.6  
     6.7 +	preempt_disable();
     6.8  	pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
     6.9 +	preempt_enable();
    6.10  	pgd += pgd_index(address);
    6.11  
    6.12  	printk("PGD %lx ", pgd_val(*pgd));
    6.13 @@ -252,7 +254,9 @@ static int vmalloc_fault(unsigned long a
    6.14  
    6.15  	/* On Xen the line below does not always work. Needs investigating! */
    6.16  	/*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
    6.17 +	preempt_disable();
    6.18  	pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
    6.19 +	preempt_enable();
    6.20  	pgd += pgd_index(address);
    6.21  
    6.22  	pgd_ref = pgd_offset_k(address);
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Mon Sep 26 11:15:55 2005 -0600
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Sep 28 21:06:49 2005 +0100
     7.3 @@ -80,6 +80,15 @@ static void frontend_changed(struct xenb
     7.4  		return;
     7.5  	}
     7.6  
     7.7 +	/* Map the shared frame, irq etc. */
     7.8 +	err = blkif_map(be->blkif, ring_ref, evtchn);
     7.9 +	if (err) {
    7.10 +		xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
    7.11 +				 ring_ref, evtchn);
    7.12 +		return;
    7.13 +	}
    7.14 +	/* XXX From here on should 'blkif_unmap' on error. */
    7.15 +
    7.16  again:
    7.17  	/* Supply the information about the device the frontend needs */
    7.18  	err = xenbus_transaction_start();
    7.19 @@ -112,14 +121,6 @@ again:
    7.20  		goto abort;
    7.21  	}
    7.22  
    7.23 -	/* Map the shared frame, irq etc. */
    7.24 -	err = blkif_map(be->blkif, ring_ref, evtchn);
    7.25 -	if (err) {
    7.26 -		xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
    7.27 -				 ring_ref, evtchn);
    7.28 -		goto abort;
    7.29 -	}
    7.30 -
    7.31  	err = xenbus_transaction_end(0);
    7.32  	if (err == -EAGAIN)
    7.33  		goto again;
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Mon Sep 26 11:15:55 2005 -0600
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Sep 28 21:06:49 2005 +0100
     8.3 @@ -57,10 +57,7 @@ static unsigned int blkif_state = BLKIF_
     8.4  
     8.5  #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
     8.6      (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
     8.7 -#define GRANTREF_INVALID (1<<15)
     8.8 -#define GRANT_INVALID_REF	(0xFFFF)
     8.9 -
    8.10 -static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */
    8.11 +#define GRANT_INVALID_REF	0
    8.12  
    8.13  static void kick_pending_request_queues(struct blkfront_info *info);
    8.14  
    8.15 @@ -84,18 +81,6 @@ static inline void ADD_ID_TO_FREELIST(
    8.16  	info->shadow_free = id;
    8.17  }
    8.18  
    8.19 -static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r)
    8.20 -{
    8.21 -
    8.22 -	s->req = *r;
    8.23 -}
    8.24 -
    8.25 -static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s)
    8.26 -{
    8.27 -
    8.28 -	*r = s->req;
    8.29 -}
    8.30 -
    8.31  static inline void flush_requests(struct blkfront_info *info)
    8.32  {
    8.33  	RING_PUSH_REQUESTS(&info->ring);
    8.34 @@ -235,7 +220,7 @@ static int blkif_queue_request(struct re
    8.35  				rq_data_dir(req) );
    8.36  
    8.37  			info->shadow[id].frame[ring_req->nr_segments] =
    8.38 -				buffer_mfn;
    8.39 +				mfn_to_pfn(buffer_mfn);
    8.40  
    8.41  			ring_req->frame_and_sects[ring_req->nr_segments] =
    8.42  				blkif_fas_from_gref(ref, fsect, lsect);
    8.43 @@ -247,7 +232,7 @@ static int blkif_queue_request(struct re
    8.44  	info->ring.req_prod_pvt++;
    8.45  
    8.46  	/* Keep a private copy so we can reissue requests when recovering. */
    8.47 -	pickle_request(&info->shadow[id], ring_req);
    8.48 +	info->shadow[id].req = *ring_req;
    8.49  
    8.50  	gnttab_free_grant_references(gref_head);
    8.51  
    8.52 @@ -312,7 +297,7 @@ static irqreturn_t blkif_int(int irq, vo
    8.53  
    8.54  	spin_lock_irqsave(&blkif_io_lock, flags);
    8.55  
    8.56 -	if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
    8.57 +	if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
    8.58  		spin_unlock_irqrestore(&blkif_io_lock, flags);
    8.59  		return IRQ_HANDLED;
    8.60  	}
    8.61 @@ -401,28 +386,24 @@ static void blkif_recover(struct blkfron
    8.62  		if (copy[i].request == 0)
    8.63  			continue;
    8.64  
    8.65 -		/* Grab a request slot and unpickle shadow state into it. */
    8.66 +		/* Grab a request slot and copy shadow state into it. */
    8.67  		req = RING_GET_REQUEST(
    8.68  			&info->ring, info->ring.req_prod_pvt);
    8.69 -		unpickle_request(req, &copy[i]);
    8.70 +		*req = copy[i].req;
    8.71  
    8.72  		/* We get a new request id, and must reset the shadow state. */
    8.73  		req->id = GET_ID_FROM_FREELIST(info);
    8.74  		memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
    8.75  
    8.76  		/* Rewrite any grant references invalidated by susp/resume. */
    8.77 -		for (j = 0; j < req->nr_segments; j++) {
    8.78 -			if ( req->frame_and_sects[j] & GRANTREF_INVALID )
    8.79 -				gnttab_grant_foreign_access_ref(
    8.80 -					blkif_gref_from_fas(
    8.81 -						req->frame_and_sects[j]),
    8.82 -					info->backend_id,
    8.83 -					info->shadow[req->id].frame[j],
    8.84 -					rq_data_dir(
    8.85 -						(struct request *)
    8.86 -						info->shadow[req->id].request));
    8.87 -			req->frame_and_sects[j] &= ~GRANTREF_INVALID;
    8.88 -		}
    8.89 +		for (j = 0; j < req->nr_segments; j++)
    8.90 +			gnttab_grant_foreign_access_ref(
    8.91 +				blkif_gref_from_fas(req->frame_and_sects[j]),
    8.92 +				info->backend_id,
    8.93 +				pfn_to_mfn(info->shadow[req->id].frame[j]),
    8.94 +				rq_data_dir(
    8.95 +					(struct request *)
    8.96 +					info->shadow[req->id].request));
    8.97  		info->shadow[req->id].req = *req;
    8.98  
    8.99  		info->ring.req_prod_pvt++;
   8.100 @@ -430,15 +411,13 @@ static void blkif_recover(struct blkfron
   8.101  
   8.102  	kfree(copy);
   8.103  
   8.104 -	recovery = 0;
   8.105 -
   8.106  	/* info->ring->req_prod will be set when we flush_requests().*/
   8.107  	wmb();
   8.108  
   8.109  	/* Kicks things back into life. */
   8.110  	flush_requests(info);
   8.111  
   8.112 -	/* Now safe to left other people use the interface. */
   8.113 +	/* Now safe to let other people use the interface. */
   8.114  	info->connected = BLKIF_STATE_CONNECTED;
   8.115  }
   8.116  
   8.117 @@ -591,17 +570,6 @@ again:
   8.118  		goto abort_transaction;
   8.119  	}
   8.120  
   8.121 -	info->backend = backend;
   8.122 -	backend = NULL;
   8.123 -
   8.124 -	info->watch.node = info->backend;
   8.125 -	info->watch.callback = watch_for_status;
   8.126 -	err = register_xenbus_watch(&info->watch);
   8.127 -	if (err) {
   8.128 -		message = "registering watch on backend";
   8.129 -		goto abort_transaction;
   8.130 -	}
   8.131 -
   8.132  	err = xenbus_transaction_end(0);
   8.133  	if (err) {
   8.134  		if (err == -EAGAIN)
   8.135 @@ -610,10 +578,17 @@ again:
   8.136  		goto destroy_blkring;
   8.137  	}
   8.138  
   8.139 - out:
   8.140 -	if (backend)
   8.141 -		kfree(backend);
   8.142 -	return err;
   8.143 +	info->watch.node = backend;
   8.144 +	info->watch.callback = watch_for_status;
   8.145 +	err = register_xenbus_watch(&info->watch);
   8.146 +	if (err) {
   8.147 +		message = "registering watch on backend";
   8.148 +		goto destroy_blkring;
   8.149 +	}
   8.150 +
   8.151 +	info->backend = backend;
   8.152 +
   8.153 +	return 0;
   8.154  
   8.155   abort_transaction:
   8.156  	xenbus_transaction_end(1);
   8.157 @@ -621,7 +596,10 @@ again:
   8.158  	xenbus_dev_error(dev, err, "%s", message);
   8.159   destroy_blkring:
   8.160  	blkif_free(info);
   8.161 -	goto out;
   8.162 + out:
   8.163 +	if (backend)
   8.164 +		kfree(backend);
   8.165 +	return err;
   8.166  }
   8.167  
   8.168  /* Setup supplies the backend dir, virtual device.
   8.169 @@ -702,7 +680,6 @@ static int blkfront_suspend(struct xenbu
   8.170  	kfree(info->backend);
   8.171  	info->backend = NULL;
   8.172  
   8.173 -	recovery = 1;
   8.174  	blkif_free(info);
   8.175  
   8.176  	return 0;
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Mon Sep 26 11:15:55 2005 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Wed Sep 28 21:06:49 2005 +0100
     9.3 @@ -22,8 +22,6 @@
     9.4  #include <asm-xen/gnttab.h>
     9.5  #include <asm-xen/driver_util.h>
     9.6  
     9.7 -#define GRANT_INVALID_REF (0xFFFF)
     9.8 -
     9.9  #if 0
    9.10  #define ASSERT(_p) \
    9.11      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Mon Sep 26 11:15:55 2005 -0600
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Sep 28 21:06:49 2005 +0100
    10.3 @@ -434,7 +434,6 @@ inline static void net_tx_action_dealloc
    10.4  		gop->host_addr    = MMAP_VADDR(pending_idx);
    10.5  		gop->dev_bus_addr = 0;
    10.6  		gop->handle       = grant_tx_ref[pending_idx];
    10.7 -		grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
    10.8  		gop++;
    10.9  	}
   10.10  	BUG_ON(HYPERVISOR_grant_table_op(
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Mon Sep 26 11:15:55 2005 -0600
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Sep 28 21:06:49 2005 +0100
    11.3 @@ -1,7 +1,7 @@
    11.4  /******************************************************************************
    11.5   * Virtual network driver for conversing with remote driver backends.
    11.6   * 
    11.7 - * Copyright (c) 2002-2004, K A Fraser
    11.8 + * Copyright (c) 2002-2005, K A Fraser
    11.9   * 
   11.10   * This file may be distributed separately from the Linux kernel, or
   11.11   * incorporated into other software packages, subject to the following license:
   11.12 @@ -57,7 +57,7 @@
   11.13  #include <asm-xen/xen-public/grant_table.h>
   11.14  #include <asm-xen/gnttab.h>
   11.15  
   11.16 -#define GRANT_INVALID_REF	(0xFFFF)
   11.17 +#define GRANT_INVALID_REF	0
   11.18  
   11.19  #ifndef __GFP_NOWARN
   11.20  #define __GFP_NOWARN 0
   11.21 @@ -700,6 +700,7 @@ static void network_connect(struct net_d
   11.22  	struct net_private *np;
   11.23  	int i, requeue_idx;
   11.24  	netif_tx_request_t *tx;
   11.25 +	struct sk_buff *skb;
   11.26  
   11.27  	np = netdev_priv(dev);
   11.28  	spin_lock_irq(&np->tx_lock);
   11.29 @@ -711,7 +712,8 @@ static void network_connect(struct net_d
   11.30  	np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
   11.31  	np->rx->event = np->tx->event = 1;
   11.32  
   11.33 -	/* Step 2: Rebuild the RX and TX ring contents.
   11.34 +	/*
   11.35 +	 * Step 2: Rebuild the RX and TX ring contents.
   11.36  	 * NB. We could just free the queued TX packets now but we hope
   11.37  	 * that sending them out might do some good.  We have to rebuild
   11.38  	 * the RX ring because some of our pages are currently flipped out
   11.39 @@ -722,49 +724,52 @@ static void network_connect(struct net_d
   11.40  	 * them.
   11.41  	 */
   11.42  
   11.43 -	/* Rebuild the TX buffer freelist and the TX ring itself.
   11.44 +	/*
   11.45 +	 * Rebuild the TX buffer freelist and the TX ring itself.
   11.46  	 * NB. This reorders packets.  We could keep more private state
   11.47  	 * to avoid this but maybe it doesn't matter so much given the
   11.48  	 * interface has been down.
   11.49  	 */
   11.50  	for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
   11.51 -		if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
   11.52 -			struct sk_buff *skb = np->tx_skbs[i];
   11.53 +		if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET)
   11.54 +			continue;
   11.55  
   11.56 -			tx = &np->tx->ring[requeue_idx++].req;
   11.57 +		skb = np->tx_skbs[i];
   11.58 +
   11.59 +		tx = &np->tx->ring[requeue_idx++].req;
   11.60  
   11.61 -			tx->id   = i;
   11.62 -			gnttab_grant_foreign_access_ref(
   11.63 -				np->grant_tx_ref[i], np->backend_id, 
   11.64 -				virt_to_mfn(np->tx_skbs[i]->data),
   11.65 -				GNTMAP_readonly); 
   11.66 -			tx->gref = np->grant_tx_ref[i];
   11.67 -			tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
   11.68 -			tx->size = skb->len;
   11.69 +		tx->id = i;
   11.70 +		gnttab_grant_foreign_access_ref(
   11.71 +			np->grant_tx_ref[i], np->backend_id, 
   11.72 +			virt_to_mfn(np->tx_skbs[i]->data),
   11.73 +			GNTMAP_readonly); 
   11.74 +		tx->gref = np->grant_tx_ref[i];
   11.75 +		tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
   11.76 +		tx->size = skb->len;
   11.77 +		tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
   11.78  
   11.79 -			np->stats.tx_bytes += skb->len;
   11.80 -			np->stats.tx_packets++;
   11.81 -		}
   11.82 +		np->stats.tx_bytes += skb->len;
   11.83 +		np->stats.tx_packets++;
   11.84  	}
   11.85  	wmb();
   11.86  	np->tx->req_prod = requeue_idx;
   11.87  
   11.88  	/* Rebuild the RX buffer freelist and the RX ring itself. */
   11.89  	for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { 
   11.90 -		if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
   11.91 -			gnttab_grant_foreign_transfer_ref(
   11.92 -				np->grant_rx_ref[i], np->backend_id);
   11.93 -			np->rx->ring[requeue_idx].req.gref =
   11.94 -				np->grant_rx_ref[i];
   11.95 -			np->rx->ring[requeue_idx].req.id = i;
   11.96 -			requeue_idx++; 
   11.97 -		}
   11.98 +		if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
   11.99 +			continue;
  11.100 +		gnttab_grant_foreign_transfer_ref(
  11.101 +			np->grant_rx_ref[i], np->backend_id);
  11.102 +		np->rx->ring[requeue_idx].req.gref =
  11.103 +			np->grant_rx_ref[i];
  11.104 +		np->rx->ring[requeue_idx].req.id = i;
  11.105 +		requeue_idx++; 
  11.106  	}
  11.107 -
  11.108  	wmb();                
  11.109  	np->rx->req_prod = requeue_idx;
  11.110  
  11.111 -	/* Step 3: All public and private state should now be sane.  Get
  11.112 +	/*
  11.113 +	 * Step 3: All public and private state should now be sane.  Get
  11.114  	 * ready to start sending and receiving packets and give the driver
  11.115  	 * domain a kick because we've probably just requeued some
  11.116  	 * packets.
  11.117 @@ -798,7 +803,8 @@ static void show_device(struct net_priva
  11.118  #endif
  11.119  }
  11.120  
  11.121 -/* Move the vif into connected state.
  11.122 +/*
  11.123 + * Move the vif into connected state.
  11.124   * Sets the mac and event channel from the message.
  11.125   * Binds the irq to the event channel.
  11.126   */
  11.127 @@ -1053,8 +1059,7 @@ static void netif_free(struct netfront_i
  11.128  	info->evtchn = 0;
  11.129  }
  11.130  
  11.131 -/* Stop network device and free tx/rx queues and irq.
  11.132 - */
  11.133 +/* Stop network device and free tx/rx queues and irq. */
  11.134  static void shutdown_device(struct net_private *np)
  11.135  {
  11.136  	/* Stop old i/f to prevent errors whilst we rebuild the state. */
  11.137 @@ -1148,17 +1153,6 @@ again:
  11.138  		goto abort_transaction;
  11.139  	}
  11.140  
  11.141 -	info->backend = backend;
  11.142 -	backend = NULL;
  11.143 -
  11.144 -	info->watch.node = info->backend;
  11.145 -	info->watch.callback = watch_for_status;
  11.146 -	err = register_xenbus_watch(&info->watch);
  11.147 -	if (err) {
  11.148 -		message = "registering watch on backend";
  11.149 -		goto abort_transaction;
  11.150 -	}
  11.151 -
  11.152  	err = xenbus_transaction_end(0);
  11.153  	if (err) {
  11.154  		if (err == -EAGAIN)
  11.155 @@ -1167,12 +1161,19 @@ again:
  11.156  		goto destroy_ring;
  11.157  	}
  11.158  
  11.159 +	info->watch.node = backend;
  11.160 +	info->watch.callback = watch_for_status;
  11.161 +	err = register_xenbus_watch(&info->watch);
  11.162 +	if (err) {
  11.163 +		message = "registering watch on backend";
  11.164 +		goto destroy_ring;
  11.165 +	}
  11.166 +
  11.167 +	info->backend = backend;
  11.168 +
  11.169  	netif_state = NETIF_STATE_CONNECTED;
  11.170  
  11.171 - out:
  11.172 -	if (backend)
  11.173 -		kfree(backend);
  11.174 -	return err;
  11.175 +	return 0;
  11.176  
  11.177   abort_transaction:
  11.178  	xenbus_transaction_end(1);
  11.179 @@ -1180,13 +1181,17 @@ again:
  11.180  	xenbus_dev_error(dev, err, "%s", message);
  11.181   destroy_ring:
  11.182  	shutdown_device(info);
  11.183 -	goto out;
  11.184 + out:
  11.185 +	if (backend)
  11.186 +		kfree(backend);
  11.187 +	return err;
  11.188  }
  11.189  
  11.190 -/* Setup supplies the backend dir, virtual device.
  11.191 -
  11.192 -   We place an event channel and shared frame entries.
  11.193 -   We watch backend to wait if it's ok. */
  11.194 +/*
  11.195 + * Setup supplies the backend dir, virtual device.
  11.196 + * We place an event channel and shared frame entries.
  11.197 + * We watch backend to wait if it's ok.
  11.198 + */
  11.199  static int netfront_probe(struct xenbus_device *dev,
  11.200  			  const struct xenbus_device_id *id)
  11.201  {
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Mon Sep 26 11:15:55 2005 -0600
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Wed Sep 28 21:06:49 2005 +0100
    12.3 @@ -88,6 +88,26 @@ static void frontend_changed(struct xenb
    12.4  		return;
    12.5  	}
    12.6  
    12.7 +	err = tpmif_map(be->tpmif, ringref, evtchn);
    12.8 +	if (err) {
    12.9 +		xenbus_dev_error(be->dev, err,
   12.10 +				 "mapping shared-frame %lu port %u",
   12.11 +				 ringref, evtchn);
   12.12 +		return;
   12.13 +	}
   12.14 +
   12.15 +	err = tpmif_vtpm_open(be->tpmif,
   12.16 +	                      be->frontend_id,
   12.17 +	                      be->instance);
   12.18 +	if (err) {
   12.19 +		xenbus_dev_error(be->dev, err,
   12.20 +		                 "queueing vtpm open packet");
   12.21 +		/*
   12.22 +		 * Should close down this device and notify FE
   12.23 +		 * about closure.
   12.24 +		 */
   12.25 +		return;
   12.26 +	}
   12.27  
   12.28  	/*
   12.29  	 * Tell the front-end that we are ready to go -
   12.30 @@ -107,27 +127,6 @@ again:
   12.31  		goto abort;
   12.32  	}
   12.33  
   12.34 -	err = tpmif_map(be->tpmif, ringref, evtchn);
   12.35 -	if (err) {
   12.36 -		xenbus_dev_error(be->dev, err,
   12.37 -				 "mapping shared-frame %lu port %u",
   12.38 -				 ringref, evtchn);
   12.39 -		goto abort;
   12.40 -	}
   12.41 -
   12.42 -	err = tpmif_vtpm_open(be->tpmif,
   12.43 -	                      be->frontend_id,
   12.44 -	                      be->instance);
   12.45 -	if (err) {
   12.46 -		xenbus_dev_error(be->dev, err,
   12.47 -		                 "queueing vtpm open packet");
   12.48 -		/*
   12.49 -		 * Should close down this device and notify FE
   12.50 -		 * about closure.
   12.51 -		 */
   12.52 -		goto abort;
   12.53 -	}
   12.54 -
   12.55  	err = xenbus_transaction_end(0);
   12.56  	if (err == -EAGAIN)
   12.57  		goto again;
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Mon Sep 26 11:15:55 2005 -0600
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Wed Sep 28 21:06:49 2005 +0100
    13.3 @@ -352,17 +352,6 @@ again:
    13.4  		goto abort_transaction;
    13.5  	}
    13.6  
    13.7 -	info->backend = backend;
    13.8 -	backend = NULL;
    13.9 -
   13.10 -	info->watch.node = info->backend;
   13.11 -	info->watch.callback = watch_for_status;
   13.12 -	err = register_xenbus_watch(&info->watch);
   13.13 -	if (err) {
   13.14 -		message = "registering watch on backend";
   13.15 -		goto abort_transaction;
   13.16 -	}
   13.17 -
   13.18  	err = xenbus_transaction_end(0);
   13.19  	if (err == -EAGAIN)
   13.20  		goto again;
   13.21 @@ -371,10 +360,17 @@ again:
   13.22  		goto destroy_tpmring;
   13.23  	}
   13.24  
   13.25 -out:
   13.26 -	if (backend)
   13.27 -		kfree(backend);
   13.28 -	return err;
   13.29 +	info->watch.node = backend;
   13.30 +	info->watch.callback = watch_for_status;
   13.31 +	err = register_xenbus_watch(&info->watch);
   13.32 +	if (err) {
   13.33 +		message = "registering watch on backend";
   13.34 +		goto destroy_tpmring;
   13.35 +	}
   13.36 +
   13.37 +	info->backend = backend;
   13.38 +
   13.39 +	return 0;
   13.40  
   13.41  abort_transaction:
   13.42  	xenbus_transaction_end(1);
   13.43 @@ -382,7 +378,10 @@ abort_transaction:
   13.44  	xenbus_dev_error(dev, err, "%s", message);
   13.45  destroy_tpmring:
   13.46  	destroy_tpmring(info, &my_private);
   13.47 -	goto out;
   13.48 +out:
   13.49 +	if (backend)
   13.50 +		kfree(backend);
   13.51 +	return err;
   13.52  }
   13.53  
   13.54  
    14.1 --- a/tools/console/daemon/io.c	Mon Sep 26 11:15:55 2005 -0600
    14.2 +++ b/tools/console/daemon/io.c	Wed Sep 28 21:06:49 2005 +0100
    14.3 @@ -399,7 +399,7 @@ void enum_domains(void)
    14.4  
    14.5  	while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
    14.6  		dom = lookup_domain(dominfo.domid);
    14.7 -		if (dominfo.dying || dominfo.crashed || dominfo.shutdown) {
    14.8 +		if (dominfo.dying) {
    14.9  			if (dom)
   14.10  				shutdown_domain(dom);
   14.11  		} else {
    15.1 --- a/tools/firmware/vmxassist/gen.c	Mon Sep 26 11:15:55 2005 -0600
    15.2 +++ b/tools/firmware/vmxassist/gen.c	Wed Sep 28 21:06:49 2005 +0100
    15.3 @@ -23,7 +23,7 @@
    15.4  #include <vm86.h>
    15.5  
    15.6  int
    15.7 -main()
    15.8 +main(void)
    15.9  {
   15.10  	printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
   15.11  	printf("#define VMX_ASSIST_CTX_GS_SEL	0x%x\n",
    16.1 --- a/tools/firmware/vmxassist/head.S	Mon Sep 26 11:15:55 2005 -0600
    16.2 +++ b/tools/firmware/vmxassist/head.S	Wed Sep 28 21:06:49 2005 +0100
    16.3 @@ -110,6 +110,10 @@ 1:
    16.4  _start:
    16.5  	cli
    16.6  
    16.7 +	/* save register parameters to C land */
    16.8 +	movl	%edx, booting_cpu
    16.9 +	movl	%ebx, booting_vector
   16.10 +
   16.11  	/* clear bss */
   16.12  	cld
   16.13  	xorb	%al, %al
   16.14 @@ -129,7 +133,6 @@ 1:
   16.15  	call    main
   16.16  	jmp	halt
   16.17  
   16.18 -
   16.19  /*
   16.20   * Something bad happened, print invoking %eip and loop forever
   16.21   */
    17.1 --- a/tools/firmware/vmxassist/setup.c	Mon Sep 26 11:15:55 2005 -0600
    17.2 +++ b/tools/firmware/vmxassist/setup.c	Wed Sep 28 21:06:49 2005 +0100
    17.3 @@ -29,6 +29,9 @@
    17.4  
    17.5  #define	min(a, b)	((a) > (b) ? (b) : (a))
    17.6  
    17.7 +/* Which CPU are we booting, and what is the initial CS segment? */
    17.8 +int booting_cpu, booting_vector;
    17.9 +
   17.10  unsigned long long gdt[] __attribute__ ((aligned(32))) = {
   17.11  	0x0000000000000000ULL,		/* 0x00: reserved */
   17.12  	0x0000890000000000ULL,		/* 0x08: 32-bit TSS */
   17.13 @@ -201,12 +204,17 @@ enter_real_mode(struct regs *regs)
   17.14  		initialize_real_mode = 0;
   17.15  		regs->eflags |= EFLAGS_VM | 0x02;
   17.16  		regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
   17.17 -		regs->cs = 0xF000; /* ROM BIOS POST entry point */
   17.18 +		if (booting_cpu == 0) {
   17.19 +			regs->cs = 0xF000; /* ROM BIOS POST entry point */
   17.20  #ifdef TEST
   17.21 -		regs->eip = 0xFFE0;
   17.22 +			regs->eip = 0xFFE0;
   17.23  #else
   17.24 -		regs->eip = 0xFFF0;
   17.25 +			regs->eip = 0xFFF0;
   17.26  #endif
   17.27 +		} else {
   17.28 +			regs->cs = booting_vector << 8; /* AP entry point */
   17.29 +			regs->eip = 0;
   17.30 +		}
   17.31  		regs->uesp = 0;
   17.32  		regs->uss = 0;
   17.33  		printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
   17.34 @@ -215,8 +223,8 @@ enter_real_mode(struct regs *regs)
   17.35  		mode = VM86_REAL; /* becomes previous mode */
   17.36  		set_mode(regs, VM86_REAL);
   17.37  
   17.38 -                /* this should get us into 16-bit mode */
   17.39 -                return;
   17.40 +		/* this should get us into 16-bit mode */
   17.41 +		return;
   17.42  	} else {
   17.43  		/* go from protected to real mode */
   17.44  		regs->eflags |= EFLAGS_VM;
   17.45 @@ -334,7 +342,12 @@ start_bios(void)
   17.46  {
   17.47  	unsigned long cr0;
   17.48  
   17.49 -	printf("Start BIOS ...\n");
   17.50 +	if (booting_cpu == 0)
   17.51 +		printf("Start BIOS ...\n");
   17.52 +	else
   17.53 +		printf("Start AP %d from %08x ...\n",
   17.54 +		       booting_cpu, booting_vector << 12);
   17.55 +
   17.56  	initialize_real_mode = 1;
   17.57  	cr0 = get_cr0();
   17.58  #ifndef TEST
   17.59 @@ -345,20 +358,28 @@ start_bios(void)
   17.60  }
   17.61  
   17.62  int
   17.63 -main()
   17.64 +main(void)
   17.65  {
   17.66 -	banner();
   17.67 +	if (booting_cpu == 0)
   17.68 +		banner();
   17.69 +
   17.70  #ifdef TEST
   17.71  	setup_paging();
   17.72  #endif
   17.73 +
   17.74  	setup_gdt();
   17.75  	setup_idt();
   17.76 +
   17.77  #ifndef	TEST
   17.78 -	set_cr4(get_cr4() | CR4_VME); 
   17.79 +	set_cr4(get_cr4() | CR4_VME);
   17.80  #endif
   17.81 +
   17.82  	setup_ctx();
   17.83 -	setup_pic();
   17.84 +
   17.85 +	if (booting_cpu == 0)
   17.86 +		setup_pic();
   17.87 +
   17.88  	start_bios();
   17.89 +
   17.90  	return 0;
   17.91  }
   17.92 -
    18.1 --- a/tools/firmware/vmxassist/vm86.c	Mon Sep 26 11:15:55 2005 -0600
    18.2 +++ b/tools/firmware/vmxassist/vm86.c	Wed Sep 28 21:06:49 2005 +0100
    18.3 @@ -752,6 +752,9 @@ opcode(struct regs *regs)
    18.4  					goto invalid;
    18.5  				}
    18.6  				break;
    18.7 +			case 0x09: /* wbinvd */
    18.8 +				asm volatile ( "wbinvd" );
    18.9 +				return OPC_EMULATED;
   18.10  			case 0x20: /* mov Rd, Cd (1h) */
   18.11  			case 0x22:
   18.12  				if (!movcr(regs, prefix, opc))
    19.1 --- a/tools/firmware/vmxassist/vmxloader.c	Mon Sep 26 11:15:55 2005 -0600
    19.2 +++ b/tools/firmware/vmxassist/vmxloader.c	Wed Sep 28 21:06:49 2005 +0100
    19.3 @@ -132,11 +132,12 @@ main(void)
    19.4  		 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
    19.5  	}
    19.6  #endif
    19.7 -			
    19.8 +
    19.9  	puts("Loading VMXAssist ...\n");
   19.10  	memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
   19.11 +
   19.12  	puts("Go ...\n");
   19.13 -	((void (*)())TEXTADDR)();
   19.14 +	asm volatile ( "jmp *%%eax" : : "a" (TEXTADDR), "d" (0) );
   19.15 +
   19.16  	return 0;
   19.17  }
   19.18 -
    20.1 --- a/tools/ioemu/vl.c	Mon Sep 26 11:15:55 2005 -0600
    20.2 +++ b/tools/ioemu/vl.c	Wed Sep 28 21:06:49 2005 +0100
    20.3 @@ -2385,7 +2385,8 @@ int
    20.4  setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long  *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end)
    20.5  {
    20.6      l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    20.7 -    l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
    20.8 +    l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL};
    20.9 +    l2_pgentry_t *vl2e=NULL, *vl2_table = NULL;
   20.10      unsigned long l1tab;
   20.11      unsigned long ppt_alloc = 0;
   20.12      unsigned long count;
    21.1 --- a/tools/python/xen/web/SrvBase.py	Mon Sep 26 11:15:55 2005 -0600
    21.2 +++ b/tools/python/xen/web/SrvBase.py	Wed Sep 28 21:06:49 2005 +0100
    21.3 @@ -81,7 +81,14 @@ class SrvBase(resource.Resource):
    21.4              req.write("Operation not implemented: " + op)
    21.5              return ''
    21.6          else:
    21.7 -            return op_method(op, req)
    21.8 +            try:
    21.9 +                return op_method(op, req)
   21.10 +            except Exception, exn:
   21.11 +                log.exception("Request %s failed.", op)
   21.12 +                if req.useSxp():
   21.13 +                    return ['xend.err', "Exception: " + str(exn)]
   21.14 +                else:
   21.15 +                    return "<p>%s</p>" % str(exn)
   21.16  
   21.17      def print_path(self, req):
   21.18          """Print the path with hyperlinks.
    22.1 --- a/tools/python/xen/web/http.py	Mon Sep 26 11:15:55 2005 -0600
    22.2 +++ b/tools/python/xen/web/http.py	Wed Sep 28 21:06:49 2005 +0100
    22.3 @@ -22,6 +22,7 @@
    22.4  from  mimetools import Message
    22.5  from cStringIO import StringIO
    22.6  import math
    22.7 +import socket
    22.8  import time
    22.9  import cgi
   22.10  
    23.1 --- a/tools/python/xen/xend/PrettyPrint.py	Mon Sep 26 11:15:55 2005 -0600
    23.2 +++ b/tools/python/xen/xend/PrettyPrint.py	Wed Sep 28 21:06:49 2005 +0100
    23.3 @@ -39,9 +39,9 @@ class PrettyItem:
    23.4          print '***PrettyItem>output>', self
    23.5          pass
    23.6  
    23.7 -    def prettyprint(self, _, width):
    23.8 +    def prettyprint(self, _):
    23.9          print '***PrettyItem>prettyprint>', self
   23.10 -        return width
   23.11 +        return self.width
   23.12  
   23.13  class PrettyString(PrettyItem):
   23.14  
   23.15 @@ -52,7 +52,7 @@ class PrettyString(PrettyItem):
   23.16      def output(self, out):
   23.17          out.write(self.value)
   23.18  
   23.19 -    def prettyprint(self, line, _):
   23.20 +    def prettyprint(self, line):
   23.21          line.output(self)
   23.22  
   23.23      def show(self, out):
   23.24 @@ -63,7 +63,7 @@ class PrettySpace(PrettyItem):
   23.25      def output(self, out):
   23.26          out.write(' ' * self.width)
   23.27  
   23.28 -    def prettyprint(self, line, _):
   23.29 +    def prettyprint(self, line):
   23.30          line.output(self)
   23.31  
   23.32      def show(self, out):
   23.33 @@ -80,7 +80,7 @@ class PrettyBreak(PrettyItem):
   23.34      def output(self, out):
   23.35          out.write(' ' * self.width)
   23.36  
   23.37 -    def prettyprint(self, line, _):
   23.38 +    def prettyprint(self, line):
   23.39          if line.breaks(self.space):
   23.40              self.active = 1
   23.41              line.newline(self.indent)
   23.42 @@ -97,7 +97,7 @@ class PrettyNewline(PrettySpace):
   23.43          block.newline()
   23.44          block.addtoline(self)
   23.45  
   23.46 -    def prettyprint(self, line, _):
   23.47 +    def prettyprint(self, line):
   23.48          line.newline(0)
   23.49          line.output(self)
   23.50  
   23.51 @@ -127,7 +127,7 @@ class PrettyLine(PrettyItem):
   23.52              lastbreak.space = (width - lastwidth)
   23.53          self.width = width
   23.54   
   23.55 -    def prettyprint(self, line, _):
   23.56 +    def prettyprint(self, line):
   23.57          for x in self.content:
   23.58              x.prettyprint(line)
   23.59  
   23.60 @@ -168,7 +168,7 @@ class PrettyBlock(PrettyItem):
   23.61      def addtoline(self, x):
   23.62          self.lines[-1].write(x)
   23.63  
   23.64 -    def prettyprint(self, line, _):
   23.65 +    def prettyprint(self, line):
   23.66          self.indent = line.used
   23.67          line.block = self
   23.68          if not line.fits(self.width):
   23.69 @@ -252,7 +252,7 @@ class PrettyPrinter:
   23.70          self.block = self.block.parent
   23.71  
   23.72      def prettyprint(self, out=sys.stdout):
   23.73 -        self.top.prettyprint(Line(out, self.width), self.width)
   23.74 +        self.top.prettyprint(Line(out, self.width))
   23.75  
   23.76  class SXPPrettyPrinter(PrettyPrinter):
   23.77      """An SXP prettyprinter.
    24.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Mon Sep 26 11:15:55 2005 -0600
    24.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Wed Sep 28 21:06:49 2005 +0100
    24.3 @@ -10,8 +10,12 @@ import select
    24.4  import sxp
    24.5  from string import join
    24.6  from struct import pack, unpack, calcsize
    24.7 +
    24.8  from xen.util.xpopen import xPopen3
    24.9 +
   24.10  import xen.lowlevel.xc
   24.11 +
   24.12 +import XendDomainInfo
   24.13  from xen.xend.xenstore.xsutil import IntroduceDomain
   24.14  
   24.15  from XendError import XendError
   24.16 @@ -74,7 +78,7 @@ def save(xd, fd, dominfo, live):
   24.17                  if l.rstrip() == "suspend":
   24.18                      log.info("suspending %d" % dominfo.domid)
   24.19                      xd.domain_shutdown(dominfo.domid, reason='suspend')
   24.20 -                    dominfo.state_wait("suspended")
   24.21 +                    dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
   24.22                      log.info("suspend %d done" % dominfo.domid)
   24.23                      child.tochild.write("done\n")
   24.24                      child.tochild.flush()
    25.1 --- a/tools/python/xen/xend/XendClient.py	Mon Sep 26 11:15:55 2005 -0600
    25.2 +++ b/tools/python/xen/xend/XendClient.py	Wed Sep 28 21:06:49 2005 +0100
    25.3 @@ -302,12 +302,6 @@ class Xend:
    25.4                               {'op'      : 'devices',
    25.5                                'type'    : type })
    25.6  
    25.7 -    def xend_domain_device(self, id, type, idx):
    25.8 -        return self.xendPost(self.domainurl(id),
    25.9 -                             {'op'      : 'device',
   25.10 -                              'type'    : type,
   25.11 -                              'idx'     : idx })
   25.12 -    
   25.13      def xend_domain_device_create(self, id, config):
   25.14          return self.xendPost(self.domainurl(id),
   25.15                               {'op'      : 'device_create',
    26.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Sep 26 11:15:55 2005 -0600
    26.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Sep 28 21:06:49 2005 +0100
    26.3 @@ -28,16 +28,11 @@ import xen.lowlevel.xc
    26.4  from xen.xend import sxp
    26.5  from xen.xend import XendRoot
    26.6  from xen.xend import XendCheckpoint
    26.7 -from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason
    26.8 +from xen.xend.XendDomainInfo import XendDomainInfo
    26.9  from xen.xend import EventServer
   26.10  from xen.xend.XendError import XendError
   26.11  from xen.xend.XendLogging import log
   26.12 -from xen.xend import scheduler
   26.13  from xen.xend.server import relocate
   26.14 -from xen.xend.uuid import getUuid
   26.15 -from xen.xend.xenstore import XenNode, DBMap
   26.16 -from xen.xend.xenstore.xstransact import xstransact
   26.17 -from xen.xend.xenstore.xsutil import GetDomainPath
   26.18  
   26.19  
   26.20  xc = xen.lowlevel.xc.new()
   26.21 @@ -47,14 +42,7 @@ eserver = EventServer.instance()
   26.22  
   26.23  __all__ = [ "XendDomain" ]
   26.24  
   26.25 -SHUTDOWN_TIMEOUT = 30
   26.26 -PRIV_DOMAIN      =  0
   26.27 -
   26.28 -def is_dead(dom):
   26.29 -    return dom['crashed'] or dom['shutdown'] or (
   26.30 -        dom['dying'] and not(dom['running'] or dom['paused'] or
   26.31 -                             dom['blocked']))
   26.32 -
   26.33 +PRIV_DOMAIN = 0
   26.34  
   26.35  class XendDomainDict(dict):
   26.36      def get_by_name(self, name):
   26.37 @@ -77,11 +65,8 @@ class XendDomain:
   26.38          # So we stuff the XendDomain instance (self) into xroot's components.
   26.39          xroot.add_component("xen.xend.XendDomain", self)
   26.40          self.domains = XendDomainDict()
   26.41 -        self.domroot = "/domain"
   26.42 -        self.vmroot = "/domain"
   26.43 -        self.dbmap = DBMap(db=XenNode(self.vmroot))
   26.44          self.watchReleaseDomain()
   26.45 -        self.initial_refresh()
   26.46 +        self.refresh()
   26.47          self.dom0_setup()
   26.48  
   26.49      def list(self):
   26.50 @@ -110,9 +95,7 @@ class XendDomain:
   26.51          return map(lambda x: x.getName(), doms)
   26.52  
   26.53      def onReleaseDomain(self):
   26.54 -        self.reap()
   26.55          self.refresh()
   26.56 -        self.domain_restarts()
   26.57  
   26.58      def watchReleaseDomain(self):
   26.59          from xen.xend.xenstore.xswatch import xswatch
   26.60 @@ -141,43 +124,22 @@ class XendDomain:
   26.61              dominfo = dominfo[0]
   26.62          return dominfo
   26.63  
   26.64 -    def initial_refresh(self):
   26.65 -        """Refresh initial domain info from db.
   26.66 -        """
   26.67 -        doms = self.xen_domains()
   26.68 -        self.dbmap.readDB()             # XXX only needed for "xend"
   26.69 -        for dom in doms.values():
   26.70 -            domid = dom['dom']
   26.71 -            dompath = GetDomainPath(domid)
   26.72 -            if not dompath:
   26.73 -                continue
   26.74 -            vmpath = xstransact.Read(dompath, "vm")
   26.75 -            if not vmpath:
   26.76 -                continue
   26.77 -            uuid = xstransact.Read(vmpath, "uuid")
   26.78 -            if not uuid:
   26.79 -                continue
   26.80 -            log.info("recreating domain %d, uuid %s" % (domid, uuid))
   26.81 -            dompath = "/".join(dompath.split("/")[0:-1])
   26.82 -            try:
   26.83 -                dominfo = XendDomainInfo.recreate(uuid, dompath, domid, dom)
   26.84 -            except Exception, ex:
   26.85 -                log.exception("Error recreating domain info: id=%d", domid)
   26.86 -                continue
   26.87 -            self._add_domain(dominfo)
   26.88 -        self.reap()
   26.89 -        self.refresh()
   26.90 -        self.domain_restarts()
   26.91 +
   26.92 +    def recreate_domain(self, xeninfo):
   26.93 +        """Refresh initial domain info from db."""
   26.94 +
   26.95 +        dominfo = XendDomainInfo.recreate(xeninfo)
   26.96 +        self._add_domain(dominfo)
   26.97 +        return dominfo
   26.98 +
   26.99  
  26.100      def dom0_setup(self):
  26.101          dom0 = self.domain_lookup(PRIV_DOMAIN)
  26.102          if not dom0:
  26.103 -            dom0 = self.dom0_unknown()
  26.104 -        dom0.dom0_init_store()    
  26.105 +            dom0 = self.recreate_domain(self.xen_domain(PRIV_DOMAIN))
  26.106 +        dom0.dom0_init_store()
  26.107          dom0.dom0_enforce_vcpus()
  26.108  
  26.109 -    def close(self):
  26.110 -        pass
  26.111  
  26.112      def _add_domain(self, info, notify=True):
  26.113          """Add a domain entry to the tables.
  26.114 @@ -193,70 +155,45 @@ class XendDomain:
  26.115              eserver.inject('xend.domain.create', [info.getName(),
  26.116                                                    info.getDomid()])
  26.117  
  26.118 -    def _delete_domain(self, id, notify=True):
  26.119 +    def _delete_domain(self, domid, notify=True):
  26.120          """Remove a domain from the tables.
  26.121  
  26.122          @param id:     domain id
  26.123          @param notify: send a domain died event if true
  26.124          """
  26.125 -        info = self.domains.get(id)
  26.126 +        info = self.domains.get(domid)
  26.127          if info:
  26.128 -            del self.domains[id]
  26.129 +            del self.domains[domid]
  26.130              info.cleanup()
  26.131              info.delete()
  26.132              if notify:
  26.133                  eserver.inject('xend.domain.died', [info.getName(),
  26.134                                                      info.getDomid()])
  26.135 -        # XXX this should not be needed
  26.136 -        for domdb in self.dbmap.values():
  26.137 -            if not domdb.has_key("xend"):
  26.138 -                continue
  26.139 -            db = domdb.addChild("xend")
  26.140 -            try:
  26.141 -                domid = int(domdb["domid"].getData())
  26.142 -            except:
  26.143 -                domid = None
  26.144 -            if (domid is None) or (domid == id):
  26.145 -                domdb.delete()
  26.146  
  26.147 -    def reap(self):
  26.148 -        """Look for domains that have crashed or stopped.
  26.149 -        Tidy them up.
  26.150 -        """
  26.151 -        doms = self.xen_domains()
  26.152 -        for d in doms.values():
  26.153 -            if not is_dead(d):
  26.154 -                continue
  26.155 -            domid = d['dom']
  26.156 -            dominfo = self.domains.get(domid)
  26.157 -            if not dominfo or dominfo.is_terminated():
  26.158 -                continue
  26.159 -            log.debug('domain died name=%s domid=%d', dominfo.getName(), domid)
  26.160 -            if d['crashed'] and xroot.get_enable_dump():
  26.161 -                self.domain_dumpcore(domid)
  26.162 -            if d['shutdown']:
  26.163 -                reason = shutdown_reason(d['shutdown_reason'])
  26.164 -                log.debug('shutdown name=%s id=%d reason=%s',
  26.165 -                          dominfo.getName(), domid, reason)
  26.166 -                if reason == 'suspend':
  26.167 -                    dominfo.state_set("suspended")
  26.168 -                    continue
  26.169 -                if reason in ['poweroff', 'reboot']:
  26.170 -                    self.domain_restart_schedule(domid, reason)
  26.171 -            dominfo.destroy()
  26.172  
  26.173      def refresh(self):
  26.174          """Refresh domain list from Xen.
  26.175          """
  26.176          doms = self.xen_domains()
  26.177 -        # Remove entries for domains that no longer exist.
  26.178 -        # Update entries for existing domains.
  26.179          for d in self.domains.values():
  26.180              info = doms.get(d.getDomid())
  26.181              if info:
  26.182                  d.update(info)
  26.183 -            elif not d.restart_pending():
  26.184 +            else:
  26.185                  self._delete_domain(d.getDomid())
  26.186 +        for d in doms:
  26.187 +            if d not in self.domains:
  26.188 +                try:
  26.189 +                    self.recreate_domain(doms[d])
  26.190 +                except:
  26.191 +                    log.exception(
  26.192 +                        "Failed to recreate information for domain %d.  "
  26.193 +                        "Destroying it in the hope of recovery.", d)
  26.194 +                    try:
  26.195 +                        xc.domain_destroy(dom = d)
  26.196 +                    except:
  26.197 +                        log.exception('Destruction of %d failed.', d)
  26.198 +
  26.199  
  26.200      def update_domain(self, id):
  26.201          """Update information for a single domain.
  26.202 @@ -277,34 +214,10 @@ class XendDomain:
  26.203          @param config: configuration
  26.204          @return: domain
  26.205          """
  26.206 -        dominfo = XendDomainInfo.create(self.dbmap.getPath(), config)
  26.207 +        dominfo = XendDomainInfo.create(config)
  26.208          self._add_domain(dominfo)
  26.209          return dominfo
  26.210  
  26.211 -    def domain_restart(self, dominfo):
  26.212 -        """Restart a domain.
  26.213 -
  26.214 -        @param dominfo: domain object
  26.215 -        """
  26.216 -        log.info("Restarting domain: name=%s id=%s", dominfo.getName(),
  26.217 -                 dominfo.getDomid())
  26.218 -        eserver.inject("xend.domain.restart",
  26.219 -                       [dominfo.getName(), dominfo.getDomid(), "begin"])
  26.220 -        try:
  26.221 -            dominfo.restart()
  26.222 -            log.info('Restarted domain name=%s id=%s', dominfo.getName(),
  26.223 -                     dominfo.getDomid())
  26.224 -            eserver.inject("xend.domain.restart",
  26.225 -                           [dominfo.getName(), dominfo.getDomid(),
  26.226 -                            "success"])
  26.227 -            self.domain_unpause(dominfo.getDomid())
  26.228 -        except Exception, ex:
  26.229 -            log.exception("Exception restarting domain: name=%s id=%s",
  26.230 -                          dominfo.getName(), dominfo.getDomid())
  26.231 -            eserver.inject("xend.domain.restart",
  26.232 -                           [dominfo.getName(), dominfo.getDomid(), "fail"])
  26.233 -        return dominfo
  26.234 -
  26.235      def domain_configure(self, config):
  26.236          """Configure an existing domain. This is intended for internal
  26.237          use by domain restore and migrate.
  26.238 @@ -318,13 +231,12 @@ class XendDomain:
  26.239          nested = sxp.child_value(config, 'config')
  26.240          if nested:
  26.241              config = nested
  26.242 -        return XendDomainInfo.restore(self.dbmap.getPath(), config)
  26.243 +        return XendDomainInfo.restore(config)
  26.244  
  26.245 -    def domain_restore(self, src, progress=False):
  26.246 +    def domain_restore(self, src):
  26.247          """Restore a domain from file.
  26.248  
  26.249          @param src:      source file
  26.250 -        @param progress: output progress if true
  26.251          """
  26.252  
  26.253          try:
  26.254 @@ -345,33 +257,7 @@ class XendDomain:
  26.255          self.update_domain(id)
  26.256          return self.domains.get(id)
  26.257  
  26.258 -    def dom0_unknown(self):
  26.259 -        dom0 = PRIV_DOMAIN
  26.260 -        uuid = None
  26.261 -        info = self.xen_domain(dom0)
  26.262 -        dompath = GetDomainPath(dom0)
  26.263 -        if dompath:
  26.264 -            vmpath = xstransact.Read(dompath, "vm")
  26.265 -            if vmpath:
  26.266 -                uuid = xstransact.Read(vmpath, "uuid")
  26.267 -            if not uuid:
  26.268 -                uuid = dompath.split("/")[-1]
  26.269 -            dompath = "/".join(dompath.split("/")[0:-1])
  26.270 -        if not uuid:
  26.271 -            uuid = getUuid()
  26.272 -            dompath = self.domroot
  26.273 -        log.info("Creating entry for unknown xend domain: id=%d uuid=%s",
  26.274 -                 dom0, uuid)
  26.275 -        try:
  26.276 -            dominfo = XendDomainInfo.recreate(uuid, dompath, dom0, info)
  26.277 -            self._add_domain(dominfo)
  26.278 -            return dominfo
  26.279 -        except Exception, exn:
  26.280 -            log.exception(exn)
  26.281 -            raise XendError("Error recreating xend domain info: id=%d: %s" %
  26.282 -                            (dom0, str(exn)))
  26.283  
  26.284 -        
  26.285      def domain_lookup(self, id):
  26.286          return self.domains.get(id)
  26.287  
  26.288 @@ -410,8 +296,9 @@ class XendDomain:
  26.289              return xc.domain_pause(dom=dominfo.getDomid())
  26.290          except Exception, ex:
  26.291              raise XendError(str(ex))
  26.292 -    
  26.293 -    def domain_shutdown(self, id, reason='poweroff'):
  26.294 +
  26.295 +
  26.296 +    def domain_shutdown(self, domid, reason='poweroff'):
  26.297          """Shutdown domain (nicely).
  26.298           - poweroff: restart according to exit code and restart mode
  26.299           - reboot:   restart on exit
  26.300 @@ -422,89 +309,13 @@ class XendDomain:
  26.301          @param id:     domain id
  26.302          @param reason: shutdown type: poweroff, reboot, suspend, halt
  26.303          """
  26.304 -        dominfo = self.domain_lookup(id)
  26.305 -        self.domain_restart_schedule(dominfo.getDomid(), reason, force=True)
  26.306 -        eserver.inject('xend.domain.shutdown', [dominfo.getName(),
  26.307 -                                                dominfo.getDomid(), reason])
  26.308 -        if reason == 'halt':
  26.309 -            reason = 'poweroff'
  26.310 -        val = dominfo.shutdown(reason)
  26.311 -        if not reason in ['suspend']:
  26.312 -            self.domain_shutdowns()
  26.313 -        return val
  26.314 -
  26.315 -
  26.316 -    def domain_sysrq(self, id, key):
  26.317 -        """Send a SysRq to the specified domain."""
  26.318 -        return self.callInfo(id, XendDomainInfo.send_sysrq, key)
  26.319 +        self.callInfo(domid, XendDomainInfo.shutdown, reason)
  26.320  
  26.321  
  26.322 -    def domain_shutdowns(self):
  26.323 -        """Process pending domain shutdowns.
  26.324 -        Destroys domains whose shutdowns have timed out.
  26.325 -        """
  26.326 -        timeout = SHUTDOWN_TIMEOUT + 1
  26.327 -        for dominfo in self.domains.values():
  26.328 -            if not dominfo.shutdown_pending:
  26.329 -                # domain doesn't need shutdown
  26.330 -                continue
  26.331 -            id = dominfo.getDomid()
  26.332 -            left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT)
  26.333 -            if left <= 0:
  26.334 -                # Shutdown expired - destroy domain.
  26.335 -                try:
  26.336 -                    log.info("Domain shutdown timeout expired: name=%s id=%s",
  26.337 -                             dominfo.getName(), id)
  26.338 -                    self.domain_destroy(id, reason=
  26.339 -                                        dominfo.shutdown_pending['reason'])
  26.340 -                except Exception:
  26.341 -                    pass
  26.342 -            else:
  26.343 -                # Shutdown still pending.
  26.344 -                timeout = min(timeout, left)
  26.345 -        if timeout <= SHUTDOWN_TIMEOUT:
  26.346 -            # Pending shutdowns remain - reschedule.
  26.347 -            scheduler.later(timeout, self.domain_shutdowns)
  26.348 -
  26.349 -    def domain_restart_schedule(self, id, reason, force=False):
  26.350 -        """Schedule a restart for a domain if it needs one.
  26.351 +    def domain_sysrq(self, domid, key):
  26.352 +        """Send a SysRq to the specified domain."""
  26.353 +        return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
  26.354  
  26.355 -        @param id:     domain id
  26.356 -        @param reason: shutdown reason
  26.357 -        """
  26.358 -        log.debug('domain_restart_schedule> %d %s %d', id, reason, force)
  26.359 -        dominfo = self.domain_lookup(id)
  26.360 -        if not dominfo:
  26.361 -            return
  26.362 -        restart = (force and reason == 'reboot') or dominfo.restart_needed(reason)
  26.363 -        if restart:
  26.364 -            log.info('Scheduling restart for domain: name=%s id=%s',
  26.365 -                     dominfo.getName(), dominfo.getDomid())
  26.366 -            eserver.inject("xend.domain.restart",
  26.367 -                           [dominfo.getName(), dominfo.getDomid(),
  26.368 -                            "schedule"])
  26.369 -            dominfo.restarting()
  26.370 -        else:
  26.371 -            log.info('Cancelling restart for domain: name=%s id=%s',
  26.372 -                     dominfo.getName(), dominfo.getDomid())
  26.373 -            eserver.inject("xend.domain.restart",
  26.374 -                           [dominfo.getName(), dominfo.getDomid(), "cancel"])
  26.375 -            dominfo.restart_cancel()
  26.376 -
  26.377 -    def domain_restarts(self):
  26.378 -        """Execute any scheduled domain restarts for domains that have gone.
  26.379 -        """
  26.380 -        doms = self.xen_domains()
  26.381 -        for dominfo in self.domains.values():
  26.382 -            if not dominfo.restart_pending():
  26.383 -                continue
  26.384 -            info = doms.get(dominfo.getDomid())
  26.385 -            if info:
  26.386 -                # Don't execute restart for domains still running.
  26.387 -                continue
  26.388 -            # Remove it from the restarts.
  26.389 -            log.info('restarting: %s' % dominfo.getName())
  26.390 -            self.domain_restart(dominfo)
  26.391  
  26.392      def domain_destroy(self, domid, reason='halt'):
  26.393          """Terminate domain immediately.
  26.394 @@ -517,7 +328,6 @@ class XendDomain:
  26.395          if domid == PRIV_DOMAIN:
  26.396              raise XendError("Cannot destroy privileged domain %i" % domid)
  26.397          
  26.398 -        self.domain_restart_schedule(domid, reason, force=True)
  26.399          dominfo = self.domain_lookup(domid)
  26.400          if dominfo:
  26.401              val = dominfo.destroy()
  26.402 @@ -554,12 +364,11 @@ class XendDomain:
  26.403          
  26.404          return None
  26.405  
  26.406 -    def domain_save(self, id, dst, progress=False):
  26.407 +    def domain_save(self, id, dst):
  26.408          """Start saving a domain to file.
  26.409  
  26.410          @param id:       domain id
  26.411          @param dst:      destination file
  26.412 -        @param progress: output progress if true
  26.413          """
  26.414  
  26.415          try:
  26.416 @@ -661,14 +470,6 @@ class XendDomain:
  26.417          return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
  26.418  
  26.419  
  26.420 -    def domain_devtype_get(self, domid, devtype, devid):
  26.421 -        """Get a device from a domain.
  26.422 -        
  26.423 -        @return: device object (or None)
  26.424 -        """
  26.425 -        return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid)
  26.426 -
  26.427 -
  26.428      def domain_vif_limit_set(self, id, vif, credit, period):
  26.429          """Limit the vif's transmission rate
  26.430          """
  26.431 @@ -730,10 +531,16 @@ class XendDomain:
  26.432      ## private:
  26.433  
  26.434      def callInfo(self, domid, fn, *args, **kwargs):
  26.435 -        self.refresh()
  26.436 -        dominfo = self.domains.get(domid)
  26.437 -        if dominfo:
  26.438 -            return fn(dominfo, *args, **kwargs)
  26.439 +        try:
  26.440 +            self.refresh()
  26.441 +            dominfo = self.domains.get(domid)
  26.442 +            if dominfo:
  26.443 +                return fn(dominfo, *args, **kwargs)
  26.444 +        except XendError:
  26.445 +            raise
  26.446 +        except Exception, exn:
  26.447 +            log.exception("")
  26.448 +            raise XendError(str(exn))
  26.449  
  26.450  
  26.451  def instance():
    27.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Sep 26 11:15:55 2005 -0600
    27.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Sep 28 21:06:49 2005 +0100
    27.3 @@ -35,7 +35,9 @@ from xen.util.blkif import blkdev_uname_
    27.4  from xen.xend.server.channel import EventChannel
    27.5  
    27.6  from xen.xend import image
    27.7 +from xen.xend import scheduler
    27.8  from xen.xend import sxp
    27.9 +from xen.xend import XendRoot
   27.10  from xen.xend.XendBootloader import bootloader
   27.11  from xen.xend.XendLogging import log
   27.12  from xen.xend.XendError import XendError, VmError
   27.13 @@ -43,7 +45,7 @@ from xen.xend.XendRoot import get_compon
   27.14  
   27.15  from xen.xend.uuid import getUuid
   27.16  from xen.xend.xenstore.xstransact import xstransact
   27.17 -from xen.xend.xenstore.xsutil import IntroduceDomain
   27.18 +from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
   27.19  
   27.20  """Shutdown code for poweroff."""
   27.21  DOMAIN_POWEROFF = 0
   27.22 @@ -75,9 +77,6 @@ restart_modes = [
   27.23      RESTART_NEVER,
   27.24      ]
   27.25  
   27.26 -STATE_RESTART_PENDING = 'pending'
   27.27 -STATE_RESTART_BOOTING = 'booting'
   27.28 -
   27.29  STATE_VM_OK         = "ok"
   27.30  STATE_VM_TERMINATED = "terminated"
   27.31  STATE_VM_SUSPENDED  = "suspended"
   27.32 @@ -92,7 +91,29 @@ SIF_NET_BE_DOMAIN = (1<<5)
   27.33  SIF_TPM_BE_DOMAIN = (1<<7)
   27.34  
   27.35  
   27.36 +SHUTDOWN_TIMEOUT = 30
   27.37 +
   27.38 +
   27.39 +DOMROOT = '/domain'
   27.40 +VMROOT  = '/domain'
   27.41 +
   27.42 +
   27.43  xc = xen.lowlevel.xc.new()
   27.44 +xroot = XendRoot.instance()
   27.45 +
   27.46 +
   27.47 +## Configuration entries that we expect to round-trip -- be read from the
   27.48 +# config file or xc, written to save-files (i.e. through sxpr), and reused as
   27.49 +# config on restart or restore, all without munging.  Some configuration
   27.50 +# entries are munged for backwards compatibility reasons, or because they
   27.51 +# don't come out of xc in the same form as they are specified in the config
   27.52 +# file, so those are handled separately.
   27.53 +ROUNDTRIPPING_CONFIG_ENTRIES = [
   27.54 +        ('name',         str),
   27.55 +        ('ssidref',      int),
   27.56 +        ('cpu_weight',   float),
   27.57 +        ('bootloader',   str)
   27.58 +    ]
   27.59  
   27.60  
   27.61  def domain_exists(name):
   27.62 @@ -133,47 +154,64 @@ class XendDomainInfo:
   27.63      MINIMUM_RESTART_TIME = 20
   27.64  
   27.65  
   27.66 -    def create(cls, dompath, config):
   27.67 +    def create(cls, config):
   27.68          """Create a VM from a configuration.
   27.69  
   27.70 -        @param dompath:   The path to all domain information
   27.71          @param config    configuration
   27.72          @raise: VmError for invalid configuration
   27.73          """
   27.74  
   27.75 -        log.debug("XendDomainInfo.create(%s, ...)", dompath)
   27.76 +        log.debug("XendDomainInfo.create(...)")
   27.77          
   27.78 -        vm = cls(getUuid(), dompath, cls.parseConfig(config))
   27.79 +        vm = cls(getUuid(), cls.parseConfig(config))
   27.80          vm.construct()
   27.81 +        vm.refreshShutdown()
   27.82          return vm
   27.83  
   27.84      create = classmethod(create)
   27.85  
   27.86  
   27.87 -    def recreate(cls, uuid, dompath, domid, info):
   27.88 -        """Create the VM object for an existing domain.
   27.89 +    def recreate(cls, xeninfo):
   27.90 +        """Create the VM object for an existing domain."""
   27.91 +
   27.92 +        log.debug("XendDomainInfo.recreate(%s)", xeninfo)
   27.93  
   27.94 -        @param dompath:   The path to all domain information
   27.95 -        @param info:      domain info from xc
   27.96 -        """
   27.97 +        domid = xeninfo['dom']
   27.98 +        try:
   27.99 +            dompath = GetDomainPath(domid)
  27.100 +            if not dompath:
  27.101 +                raise XendError(
  27.102 +                    'No domain path in store for existing domain %d' % domid)
  27.103 +            vmpath = xstransact.Read(dompath, "vm")
  27.104 +            if not vmpath:
  27.105 +                raise XendError(
  27.106 +                    'No vm path in store for existing domain %d' % domid)
  27.107 +            uuid = xstransact.Read(vmpath, "uuid")
  27.108 +            if not uuid:
  27.109 +                raise XendError(
  27.110 +                    'No vm/uuid path in store for existing domain %d' % domid)
  27.111  
  27.112 -        log.debug("XendDomainInfo.recreate(%s, %s, %s, %s)", uuid, dompath,
  27.113 -                  domid, info)
  27.114 +        except Exception, exn:
  27.115 +            log.warn(str(exn))
  27.116 +            uuid = getUuid()
  27.117  
  27.118 -        return cls(uuid, dompath, info, domid, True)
  27.119 +        log.info("Recreating domain %d, uuid %s", domid, uuid)
  27.120 +
  27.121 +        vm = cls(uuid, xeninfo, domid, True)
  27.122 +        vm.refreshShutdown(xeninfo)
  27.123 +        return vm
  27.124  
  27.125      recreate = classmethod(recreate)
  27.126  
  27.127  
  27.128 -    def restore(cls, dompath, config, uuid = None):
  27.129 +    def restore(cls, config, uuid = None):
  27.130          """Create a domain and a VM object to do a restore.
  27.131  
  27.132 -        @param dompath:   The path to all domain information
  27.133          @param config:    domain configuration
  27.134          @param uuid:      uuid to use
  27.135          """
  27.136          
  27.137 -        log.debug("XendDomainInfo.restore(%s, %s, %s)", dompath, config, uuid)
  27.138 +        log.debug("XendDomainInfo.restore(%s, %s)", config, uuid)
  27.139  
  27.140          if not uuid:
  27.141              uuid = getUuid()
  27.142 @@ -183,14 +221,12 @@ class XendDomainInfo:
  27.143          except TypeError, exn:
  27.144              raise VmError('Invalid ssidref in config: %s' % exn)
  27.145  
  27.146 -        log.debug('restoring with ssidref = %d' % ssidref)
  27.147 -
  27.148 -        vm = cls(uuid, dompath, cls.parseConfig(config),
  27.149 +        vm = cls(uuid, cls.parseConfig(config),
  27.150                   xc.domain_create(ssidref = ssidref))
  27.151 -        vm.clear_shutdown()
  27.152          vm.create_channel()
  27.153          vm.configure()
  27.154          vm.exportToDB()
  27.155 +        vm.refreshShutdown()
  27.156          return vm
  27.157  
  27.158      restore = classmethod(restore)
  27.159 @@ -214,33 +250,28 @@ class XendDomainInfo:
  27.160          log.debug("parseConfig: config is %s" % str(config))
  27.161  
  27.162          result = {}
  27.163 -        imagecfg = "()"
  27.164  
  27.165 -        result['name']         = get_cfg('name')
  27.166 -        result['ssidref']      = get_cfg('ssidref',    int)
  27.167 +        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
  27.168 +            result[e[0]] = get_cfg(e[0], e[1])
  27.169 +
  27.170          result['memory']       = get_cfg('memory',     int)
  27.171          result['mem_kb']       = get_cfg('mem_kb',     int)
  27.172          result['maxmem']       = get_cfg('maxmem',     int)
  27.173          result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
  27.174          result['cpu']          = get_cfg('cpu',        int)
  27.175 -        result['cpu_weight']   = get_cfg('cpu_weight', float)
  27.176 -        result['bootloader']   = get_cfg('bootloader')
  27.177          result['restart_mode'] = get_cfg('restart')
  27.178 +        result['image']        = get_cfg('image')
  27.179  
  27.180          try:
  27.181 -            imagecfg = get_cfg('image')
  27.182 -
  27.183 -            if imagecfg:
  27.184 -                result['image'] = imagecfg
  27.185 -                result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus',
  27.186 -                                                      1))
  27.187 +            if result['image']:
  27.188 +                result['vcpus'] = int(sxp.child_value(result['image'],
  27.189 +                                                      'vcpus', 1))
  27.190              else:
  27.191                  result['vcpus'] = 1
  27.192          except TypeError, exn:
  27.193              raise VmError(
  27.194                  'Invalid configuration setting: vcpus = %s: %s' %
  27.195 -                (sxp.child_value(imagecfg, 'vcpus', 1),
  27.196 -                 str(exn)))
  27.197 +                (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
  27.198  
  27.199          result['backend'] = []
  27.200          for c in sxp.children(config, 'backend'):
  27.201 @@ -258,12 +289,12 @@ class XendDomainInfo:
  27.202      parseConfig = classmethod(parseConfig)
  27.203  
  27.204      
  27.205 -    def __init__(self, uuid, parentpath, info, domid = None, augment = False):
  27.206 +    def __init__(self, uuid, info, domid = None, augment = False):
  27.207  
  27.208          self.uuid = uuid
  27.209          self.info = info
  27.210  
  27.211 -        self.path = parentpath + "/" + uuid
  27.212 +        self.path = DOMROOT + "/" + uuid
  27.213  
  27.214          if domid:
  27.215              self.domid = domid
  27.216 @@ -283,26 +314,26 @@ class XendDomainInfo:
  27.217          self.store_mfn = None
  27.218          self.console_channel = None
  27.219          self.console_mfn = None
  27.220 -        
  27.221 -        #todo: state: running, suspended
  27.222 +
  27.223          self.state = STATE_VM_OK
  27.224          self.state_updated = threading.Condition()
  27.225 -        self.shutdown_pending = None
  27.226  
  27.227 -        self.restart_state = None
  27.228 -        self.restart_time = None
  27.229 -        self.restart_count = 0
  27.230 -        
  27.231          self.writeVm("uuid", self.uuid)
  27.232          self.storeDom("vm", self.path)
  27.233  
  27.234  
  27.235      def augmentInfo(self):
  27.236 +        """Augment self.info, as given to us through {@link #recreate}, with
  27.237 +        values taken from the store.  This recovers those values known to xend
  27.238 +        but not to the hypervisor.
  27.239 +        """
  27.240          def useIfNeeded(name, val):
  27.241              if not self.infoIsSet(name) and val is not None:
  27.242                  self.info[name] = val
  27.243  
  27.244          params = (("name", str),
  27.245 +                  ("restart-mode", str),
  27.246 +                  ("image",        str),
  27.247                    ("start-time", float))
  27.248  
  27.249          from_store = self.gatherVm(*params)
  27.250 @@ -322,13 +353,18 @@ class XendDomainInfo:
  27.251              defaultInfo('name',         lambda: "Domain-%d" % self.domid)
  27.252              defaultInfo('ssidref',      lambda: 0)
  27.253              defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
  27.254 +            defaultInfo('cpu',          lambda: None)
  27.255              defaultInfo('cpu_weight',   lambda: 1.0)
  27.256              defaultInfo('bootloader',   lambda: None)
  27.257              defaultInfo('backend',      lambda: [])
  27.258              defaultInfo('device',       lambda: [])
  27.259 +            defaultInfo('image',        lambda: None)
  27.260  
  27.261              self.check_name(self.info['name'])
  27.262  
  27.263 +            if isinstance(self.info['image'], str):
  27.264 +                self.info['image'] = sxp.from_string(self.info['image'])
  27.265 +
  27.266              # Internally, we keep only maxmem_KiB, and not maxmem or maxmem_kb
  27.267              # (which come from outside, and are in MiB and KiB respectively).
  27.268              # This means that any maxmem or maxmem_kb settings here have come
  27.269 @@ -451,17 +487,16 @@ class XendDomainInfo:
  27.270              'domid':              str(self.domid),
  27.271              'uuid':               self.uuid,
  27.272  
  27.273 -            'restart_time':       str(self.restart_time),
  27.274 -
  27.275 -            'xend/state':         self.state,
  27.276 -            'xend/restart_count': str(self.restart_count),
  27.277              'xend/restart_mode':  str(self.info['restart_mode']),
  27.278  
  27.279              'memory/target':      str(self.info['memory_KiB'])
  27.280              }
  27.281  
  27.282          for (k, v) in self.info.items():
  27.283 -            to_store[k] = str(v)
  27.284 +            if v:
  27.285 +                to_store[k] = str(v)
  27.286 +
  27.287 +        to_store['image'] = sxp.to_string(self.info['image'])
  27.288  
  27.289          log.debug("Storing %s" % str(to_store))
  27.290  
  27.291 @@ -513,6 +548,88 @@ class XendDomainInfo:
  27.292                        self.info['backend'], 0)
  27.293  
  27.294  
  27.295 +    def refreshShutdown(self, xeninfo = None):
  27.296 +        if xeninfo is None:
  27.297 +            xeninfo = dom_get(self.domid)
  27.298 +            if xeninfo is None:
  27.299 +                # The domain no longer exists.  This will occur if we have
  27.300 +                # scheduled a timer to check for shutdown timeouts and the
  27.301 +                # shutdown succeeded.
  27.302 +                return
  27.303 +
  27.304 +        if xeninfo['dying']:
  27.305 +            # Dying means that a domain has been destroyed, but has not yet
  27.306 +            # been cleaned up by Xen.  This could persist indefinitely if,
  27.307 +            # for example, another domain has some of its pages mapped.
  27.308 +            # We might like to diagnose this problem in the future, but for
  27.309 +            # now all we can sensibly do is ignore it.
  27.310 +            pass
  27.311 +
  27.312 +        elif xeninfo['crashed']:
  27.313 +            log.warn('Domain has crashed: name=%s id=%d.',
  27.314 +                     self.info['name'], self.domid)
  27.315 +
  27.316 +            if xroot.get_enable_dump():
  27.317 +                self.dumpCore()
  27.318 +
  27.319 +            self.maybeRestart('crashed')
  27.320 +
  27.321 +        elif xeninfo['shutdown']:
  27.322 +            reason = shutdown_reason(xeninfo['shutdown_reason'])
  27.323 +
  27.324 +            log.info('Domain has shutdown: name=%s id=%d reason=%s.',
  27.325 +                     self.info['name'], self.domid, reason)
  27.326 +
  27.327 +            self.clearRestart()
  27.328 +
  27.329 +            if reason == 'suspend':
  27.330 +                self.state_set(STATE_VM_SUSPENDED)
  27.331 +                # Don't destroy the domain.  XendCheckpoint will do this once
  27.332 +                # it has finished.
  27.333 +            elif reason in ['poweroff', 'reboot']:
  27.334 +                self.maybeRestart(reason)
  27.335 +            else:
  27.336 +                self.destroy()
  27.337 +
  27.338 +        else:
  27.339 +            # Domain is alive.  If we are shutting it down, then check
  27.340 +            # the timeout on that, and destroy it if necessary.
  27.341 +
  27.342 +            sst = self.readVm('xend/shutdown_start_time')
  27.343 +            if sst:
  27.344 +                sst = float(sst)
  27.345 +                timeout = SHUTDOWN_TIMEOUT - time.time() + sst
  27.346 +                if timeout < 0:
  27.347 +                    log.info(
  27.348 +                        "Domain shutdown timeout expired: name=%s id=%s",
  27.349 +                        self.info['name'], self.domid)
  27.350 +                    self.destroy()
  27.351 +                else:
  27.352 +                    log.debug(
  27.353 +                        "Scheduling refreshShutdown on domain %d in %ds.",
  27.354 +                        self.domid, timeout)
  27.355 +                    scheduler.later(timeout, self.refreshShutdown)
  27.356 +
  27.357 +
  27.358 +    def shutdown(self, reason):
  27.359 +        if not reason in shutdown_reasons.values():
  27.360 +            raise XendError('invalid reason:' + reason)
  27.361 +        self.storeVm("control/shutdown", reason)
  27.362 +        if not reason == 'suspend':
  27.363 +            self.storeVm('xend/shutdown_start_time', time.time())
  27.364 +
  27.365 +
  27.366 +    def clearRestart(self):
  27.367 +        self.removeVm("xend/shutdown_start_time")
  27.368 +
  27.369 +
  27.370 +    def maybeRestart(self, reason):
  27.371 +        if self.restart_needed(reason):
  27.372 +            self.restart()
  27.373 +        else:
  27.374 +            self.destroy()
  27.375 +
  27.376 +
  27.377      def dumpCore(self):
  27.378          """Create a core dump for this domain.  Nothrow guarantee."""
  27.379          
  27.380 @@ -526,18 +643,32 @@ class XendDomainInfo:
  27.381                        self.domid, self.info['name'], str(exn))
  27.382  
  27.383  
  27.384 -    def closeStoreChannel(self):
  27.385 -        """Close the store channel, if any.  Nothrow guarantee."""
  27.386 +    def closeChannel(self, channel, entry):
  27.387 +        """Close the given channel, if set, and remove the given entry in the
  27.388 +        store.  Nothrow guarantee."""
  27.389          
  27.390          try:
  27.391 -            if self.store_channel:
  27.392 -                try:
  27.393 -                    self.store_channel.close()
  27.394 -                    self.removeDom("store/port")
  27.395 -                finally:
  27.396 -                    self.store_channel = None
  27.397 +            try:
  27.398 +                if channel:
  27.399 +                    channel.close()
  27.400 +            finally:
  27.401 +                self.removeDom(entry)
  27.402          except Exception, exn:
  27.403              log.exception(exn)
  27.404 +        
  27.405 +
  27.406 +    def closeStoreChannel(self):
  27.407 +        """Close the store channel, if any.  Nothrow guarantee."""
  27.408 +
  27.409 +        self.closeChannel(self.store_channel, "store/port")
  27.410 +        self.store_channel = None
  27.411 +
  27.412 +
  27.413 +    def closeConsoleChannel(self):
  27.414 +        """Close the console channel, if any.  Nothrow guarantee."""
  27.415 +
  27.416 +        self.closeChannel(self.console_channel, "console/port")
  27.417 +        self.console_channel = None
  27.418  
  27.419  
  27.420      def setConsoleRef(self, ref):
  27.421 @@ -566,18 +697,23 @@ class XendDomainInfo:
  27.422              
  27.423          self.info.update(info)
  27.424          self.validateInfo()
  27.425 +        self.refreshShutdown(info)
  27.426  
  27.427          log.debug("XendDomainInfo.update done on domain %d: %s", self.domid,
  27.428                    self.info)
  27.429  
  27.430  
  27.431 +    ## private:
  27.432 +
  27.433      def state_set(self, state):
  27.434          self.state_updated.acquire()
  27.435          if self.state != state:
  27.436              self.state = state
  27.437              self.state_updated.notifyAll()
  27.438          self.state_updated.release()
  27.439 -        self.exportToDB()
  27.440 +
  27.441 +
  27.442 +    ## public:
  27.443  
  27.444      def state_wait(self, state):
  27.445          self.state_updated.acquire()
  27.446 @@ -585,6 +721,7 @@ class XendDomainInfo:
  27.447              self.state_updated.wait()
  27.448          self.state_updated.release()
  27.449  
  27.450 +
  27.451      def __str__(self):
  27.452          s = "<domain"
  27.453          s += " id=" + str(self.domid)
  27.454 @@ -597,13 +734,6 @@ class XendDomainInfo:
  27.455      __repr__ = __str__
  27.456  
  27.457  
  27.458 -    def getDeviceController(self, name):
  27.459 -        if name not in controllerClasses:
  27.460 -            raise XendError("unknown device type: " + str(name))
  27.461 -
  27.462 -        return controllerClasses[name](self)
  27.463 -
  27.464 -
  27.465      def createDevice(self, deviceClass, devconfig):
  27.466          return self.getDeviceController(deviceClass).createDevice(devconfig)
  27.467  
  27.468 @@ -617,49 +747,66 @@ class XendDomainInfo:
  27.469          return self.getDeviceController(deviceClass).destroyDevice(devid)
  27.470  
  27.471  
  27.472 +    def getDeviceSxprs(self, deviceClass):
  27.473 +        return self.getDeviceController(deviceClass).sxprs()
  27.474 +
  27.475 +
  27.476 +    ## private:
  27.477 +
  27.478 +    def getDeviceController(self, name):
  27.479 +        if name not in controllerClasses:
  27.480 +            raise XendError("unknown device type: " + str(name))
  27.481 +
  27.482 +        return controllerClasses[name](self)
  27.483 +
  27.484 +
  27.485 +    ## public:
  27.486 +
  27.487      def sxpr(self):
  27.488          sxpr = ['domain',
  27.489 -                ['domid', self.domid],
  27.490 -                ['name', self.info['name']],
  27.491 -                ['memory', self.info['memory_KiB'] / 1024],
  27.492 -                ['ssidref', self.info['ssidref']]]
  27.493 -        if self.uuid:
  27.494 -            sxpr.append(['uuid', self.uuid])
  27.495 -        if self.info:
  27.496 -            sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
  27.497 +                ['domid',   self.domid],
  27.498 +                ['uuid',    self.uuid],
  27.499 +                ['memory',  self.info['memory_KiB'] / 1024]]
  27.500 +
  27.501 +        for e in ROUNDTRIPPING_CONFIG_ENTRIES:
  27.502 +            if self.infoIsSet(e[0]):
  27.503 +                sxpr.append([e[0], self.info[e[0]]])
  27.504 +        
  27.505 +        sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
  27.506  
  27.507 -            if self.infoIsSet('device'):
  27.508 -                for (_, c) in self.info['device']:
  27.509 -                    sxpr.append(['device', c])
  27.510 +        if self.infoIsSet('image'):
  27.511 +            sxpr.append(['image', self.info['image']])
  27.512  
  27.513 -            def stateChar(name):
  27.514 -                if name in self.info:
  27.515 -                    if self.info[name]:
  27.516 -                        return name[0]
  27.517 -                    else:
  27.518 -                        return '-'
  27.519 +        if self.infoIsSet('device'):
  27.520 +            for (_, c) in self.info['device']:
  27.521 +                sxpr.append(['device', c])
  27.522 +
  27.523 +        def stateChar(name):
  27.524 +            if name in self.info:
  27.525 +                if self.info[name]:
  27.526 +                    return name[0]
  27.527                  else:
  27.528 -                    return '?'
  27.529 +                    return '-'
  27.530 +            else:
  27.531 +                return '?'
  27.532  
  27.533 -            state = reduce(
  27.534 -                lambda x, y: x + y,
  27.535 -                map(stateChar,
  27.536 -                    ['running', 'blocked', 'paused', 'shutdown', 'crashed']))
  27.537 +        state = reduce(
  27.538 +            lambda x, y: x + y,
  27.539 +            map(stateChar,
  27.540 +                ['running', 'blocked', 'paused', 'shutdown', 'crashed',
  27.541 +                 'dying']))
  27.542  
  27.543 -            sxpr.append(['state', state])
  27.544 -            if self.infoIsSet('shutdown'):
  27.545 -                reason = shutdown_reason(self.info['shutdown_reason'])
  27.546 -                sxpr.append(['shutdown_reason', reason])
  27.547 -            if self.infoIsSet('cpu_time'):
  27.548 -                sxpr.append(['cpu_time', self.info['cpu_time']/1e9])    
  27.549 -            sxpr.append(['vcpus', self.info['vcpus']])
  27.550 -            sxpr.append(['cpumap', self.info['cpumap']])
  27.551 -            if self.infoIsSet('vcpu_to_cpu'):
  27.552 -                sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
  27.553 -                # build a string, using '|' to separate items, show only up
  27.554 -                # to number of vcpus in domain, and trim the trailing '|'
  27.555 -                sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
  27.556 -                            self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
  27.557 +        sxpr.append(['state', state])
  27.558 +        if self.infoIsSet('shutdown'):
  27.559 +            reason = shutdown_reason(self.info['shutdown_reason'])
  27.560 +            sxpr.append(['shutdown_reason', reason])
  27.561 +        if self.infoIsSet('cpu_time'):
  27.562 +            sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
  27.563 +        sxpr.append(['vcpus', self.info['vcpus']])
  27.564 +        sxpr.append(['cpumap', self.info['cpumap']])
  27.565 +        if self.infoIsSet('vcpu_to_cpu'):
  27.566 +            sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
  27.567 +            sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
  27.568              
  27.569          if self.infoIsSet('start_time'):
  27.570              up_time =  time.time() - self.info['start_time']
  27.571 @@ -674,14 +821,17 @@ class XendDomainInfo:
  27.572              sxpr.append(['console_channel', self.console_channel.sxpr()])
  27.573          if self.console_mfn:
  27.574              sxpr.append(['console_mfn', self.console_mfn])
  27.575 -        if self.restart_count:
  27.576 -            sxpr.append(['restart_count', self.restart_count])
  27.577 -        if self.restart_state:
  27.578 -            sxpr.append(['restart_state', self.restart_state])
  27.579 -        if self.restart_time:
  27.580 -            sxpr.append(['restart_time', str(self.restart_time)])
  27.581 +
  27.582          return sxpr
  27.583  
  27.584 +
  27.585 +    ## private:
  27.586 +
  27.587 +    def prettyVCpuMap(self):
  27.588 +        return '|'.join(map(str,
  27.589 +                            self.info['vcpu_to_cpu'][0:self.info['vcpus']]))
  27.590 +
  27.591 +
  27.592      def check_name(self, name):
  27.593          """Check if a vm name is valid. Valid names contain alphabetic characters,
  27.594          digits, or characters in '_-.:/+'.
  27.595 @@ -719,11 +869,19 @@ class XendDomainInfo:
  27.596          @param config: configuration
  27.597          @raise: VmError on error
  27.598          """
  27.599 -        # todo - add support for scheduling params?
  27.600 +
  27.601 +        log.debug('XendDomainInfo.construct: %s %s',
  27.602 +                  str(self.domid),
  27.603 +                  str(self.info['ssidref']))
  27.604 +
  27.605 +        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
  27.606 +
  27.607 +        if self.domid <= 0:
  27.608 +            raise VmError('Creating domain failed: name=%s' %
  27.609 +                          self.info['name'])
  27.610 +
  27.611          try:
  27.612              self.initDomain()
  27.613 -
  27.614 -            # Create domain devices.
  27.615              self.construct_image()
  27.616              self.configure()
  27.617              self.exportToDB()
  27.618 @@ -737,30 +895,23 @@ class XendDomainInfo:
  27.619  
  27.620  
  27.621      def initDomain(self):
  27.622 -        log.debug('XendDomainInfo.initDomain: %s %s %s %s)',
  27.623 +        log.debug('XendDomainInfo.initDomain: %s %s %s',
  27.624                    str(self.domid),
  27.625                    str(self.info['memory_KiB']),
  27.626 -                  str(self.info['ssidref']),
  27.627                    str(self.info['cpu_weight']))
  27.628  
  27.629 -        self.domid = xc.domain_create(dom = self.domid or 0,
  27.630 -                                      ssidref = self.info['ssidref'])
  27.631 -
  27.632 -        if 'image' not in self.info:
  27.633 +        if not self.infoIsSet('image'):
  27.634              raise VmError('Missing image in configuration')
  27.635  
  27.636          self.image = image.create(self,
  27.637                                    self.info['image'],
  27.638                                    self.info['device'])
  27.639  
  27.640 -        if self.domid <= 0:
  27.641 -            raise VmError('Creating domain failed: name=%s' %
  27.642 -                          self.info['name'])
  27.643 -
  27.644          if self.info['bootloader']:
  27.645              self.image.handleBootloading()
  27.646  
  27.647          xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
  27.648 +        # XXX Merge with configure_maxmem?
  27.649          m = self.image.getDomainMemory(self.info['memory_KiB'])
  27.650          xc.domain_setmaxmem(self.domid, m)
  27.651          xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
  27.652 @@ -794,6 +945,8 @@ class XendDomainInfo:
  27.653          self.configure_vcpus(self.info['vcpus'])
  27.654  
  27.655  
  27.656 +    ## public:
  27.657 +
  27.658      def delete(self):
  27.659          """Delete the vm's db.
  27.660          """
  27.661 @@ -803,48 +956,46 @@ class XendDomainInfo:
  27.662              log.warning("error in domain db delete: %s", ex)
  27.663  
  27.664  
  27.665 -    def destroy_domain(self):
  27.666 -        """Destroy the vm's domain.
  27.667 -        The domain will not finally go away unless all vm
  27.668 -        devices have been released.
  27.669 -        """
  27.670 -        if self.domid is None:
  27.671 -            return
  27.672 -        try:
  27.673 -            xc.domain_destroy(dom=self.domid)
  27.674 -        except Exception, err:
  27.675 -            log.exception("Domain destroy failed: %s", self.info['name'])
  27.676 +    def cleanup(self):
  27.677 +        """Cleanup vm resources: release devices.  Nothrow guarantee."""
  27.678  
  27.679 -    def cleanup(self):
  27.680 -        """Cleanup vm resources: release devices.
  27.681 -        """
  27.682 -        self.state = STATE_VM_TERMINATED
  27.683 +        self.state_set(STATE_VM_TERMINATED)
  27.684          self.release_devices()
  27.685          self.closeStoreChannel()
  27.686 -        if self.console_channel:
  27.687 -            # notify processes using this console?
  27.688 -            try:
  27.689 -                self.console_channel.close()
  27.690 -                self.console_channel = None
  27.691 -            except:
  27.692 -                pass
  27.693 +        self.closeConsoleChannel()
  27.694 +
  27.695          if self.image:
  27.696              try:
  27.697                  self.image.destroy()
  27.698 -                self.image = None
  27.699              except:
  27.700 -                pass
  27.701 +                log.exception(
  27.702 +                    "XendDomainInfo.cleanup: image.destroy() failed.")
  27.703 +            self.image = None
  27.704 +
  27.705  
  27.706      def destroy(self):
  27.707 -        """Cleanup vm and destroy domain.
  27.708 -        """
  27.709 +        """Cleanup vm and destroy domain.  Nothrow guarantee."""
  27.710 +
  27.711 +        log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
  27.712  
  27.713 -        log.debug("XendDomainInfo.destroy")
  27.714 +        self.cleanup()
  27.715 +
  27.716 +        try:
  27.717 +            self.removeVm()
  27.718 +        except Exception:
  27.719 +            log.exception("Removing VM path failed.")
  27.720  
  27.721 -        self.destroy_domain()
  27.722 -        self.cleanup()
  27.723 -        self.exportToDB()
  27.724 -        return 0
  27.725 +        try:
  27.726 +            self.removeDom()
  27.727 +        except Exception:
  27.728 +            log.exception("Removing domain path failed.")
  27.729 +
  27.730 +        try:
  27.731 +            if self.domid is not None:
  27.732 +                xc.domain_destroy(dom=self.domid)
  27.733 +        except Exception:
  27.734 +            log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
  27.735 +
  27.736  
  27.737      def is_terminated(self):
  27.738          """Check if a domain has been terminated.
  27.739 @@ -852,8 +1003,7 @@ class XendDomainInfo:
  27.740          return self.state == STATE_VM_TERMINATED
  27.741  
  27.742      def release_devices(self):
  27.743 -        """Release all vm devices.
  27.744 -        """
  27.745 +        """Release all vm devices.  Nothrow guarantee."""
  27.746  
  27.747          while True:
  27.748              t = xstransact("%s/device" % self.path)
  27.749 @@ -865,8 +1015,8 @@ class XendDomainInfo:
  27.750                          # Log and swallow any exceptions in removal --
  27.751                          # there's nothing more we can do.
  27.752                          log.exception(
  27.753 -                           "Device release failed: %s; %s; %s; %s" %
  27.754 -                            (self.info['name'], n, d, str(ex)))
  27.755 +                           "Device release failed: %s; %s; %s",
  27.756 +                           self.info['name'], n, d)
  27.757              if t.commit():
  27.758                  break
  27.759  
  27.760 @@ -902,8 +1052,7 @@ class XendDomainInfo:
  27.761  
  27.762          @raise: VmError for invalid devices
  27.763          """
  27.764 -        if not self.rebooting():
  27.765 -            self.create_configured_devices()
  27.766 +        self.create_configured_devices()
  27.767          if self.image:
  27.768              self.image.createDeviceModel()
  27.769  
  27.770 @@ -942,23 +1091,6 @@ class XendDomainInfo:
  27.771              return reason == 'reboot'
  27.772          return False
  27.773  
  27.774 -    def restart_cancel(self):
  27.775 -        """Cancel a vm restart.
  27.776 -        """
  27.777 -        self.restart_state = None
  27.778 -
  27.779 -    def restarting(self):
  27.780 -        """Put the vm into restart mode.
  27.781 -        """
  27.782 -        self.restart_state = STATE_RESTART_PENDING
  27.783 -
  27.784 -    def restart_pending(self):
  27.785 -        """Test if the vm has a pending restart.
  27.786 -        """
  27.787 -        return self.restart_state == STATE_RESTART_PENDING
  27.788 -
  27.789 -    def rebooting(self):
  27.790 -        return self.restart_state == STATE_RESTART_BOOTING
  27.791  
  27.792      def restart_check(self):
  27.793          """Check if domain restart is OK.
  27.794 @@ -976,23 +1108,37 @@ class XendDomainInfo:
  27.795          self.restart_time = tnow
  27.796          self.restart_count += 1
  27.797  
  27.798 +
  27.799      def restart(self):
  27.800 -        """Restart the domain after it has exited.
  27.801 -        Reuses the domain id
  27.802 +        """Restart the domain after it has exited. """
  27.803 +
  27.804 +        #            self.restart_check()
  27.805 +        self.cleanup()
  27.806 +
  27.807 +        config = self.sxpr()
  27.808  
  27.809 -        """
  27.810 +        if self.readVm('xend/restart_in_progress'):
  27.811 +            log.error('Xend failed during restart of domain %d.  '
  27.812 +                      'Refusing to restart to avoid loops.',
  27.813 +                      self.domid)
  27.814 +            self.destroy()
  27.815 +            return
  27.816 +
  27.817 +        self.writeVm('xend/restart_in_progress', 'True')
  27.818 +
  27.819          try:
  27.820 -            self.clear_shutdown()
  27.821 -            self.state = STATE_VM_OK
  27.822 -            self.shutdown_pending = None
  27.823 -            self.restart_check()
  27.824 -            self.exportToDB()
  27.825 -            self.restart_state = STATE_RESTART_BOOTING
  27.826 -            self.configure_bootloader()
  27.827 -            self.construct()
  27.828 -            self.exportToDB()
  27.829 +            self.destroy()
  27.830 +            try:
  27.831 +                xd = get_component('xen.xend.XendDomain')
  27.832 +                xd.domain_unpause(xd.domain_create(config).getDomid())
  27.833 +            except Exception, exn:
  27.834 +                log.exception('Failed to restart domain %d.', self.domid)
  27.835          finally:
  27.836 -            self.restart_state = None
  27.837 +            self.removeVm('xend/restart_in_progress')
  27.838 +            
  27.839 +        # self.configure_bootloader()
  27.840 +        #        self.exportToDB()
  27.841 +
  27.842  
  27.843      def configure_bootloader(self):
  27.844          if not self.info['bootloader']:
  27.845 @@ -1006,7 +1152,8 @@ class XendDomainInfo:
  27.846          if dev:
  27.847              disk = sxp.child_value(dev, "uname")
  27.848              fn = blkdev_uname_to_file(disk)
  27.849 -            blcfg = bootloader(self.info['bootloader'], fn, 1, self.info['vcpus'])
  27.850 +            blcfg = bootloader(self.info['bootloader'], fn, 1,
  27.851 +                               self.info['vcpus'])
  27.852          if blcfg is None:
  27.853              msg = "Had a bootloader specified, but can't find disk"
  27.854              log.error(msg)
  27.855 @@ -1023,7 +1170,9 @@ class XendDomainInfo:
  27.856  
  27.857  
  27.858      def configure_maxmem(self):
  27.859 -        xc.domain_setmaxmem(self.domid, maxmem_kb = self.info['maxmem_KiB'])
  27.860 +        if self.image:
  27.861 +            m = self.image.getDomainMemory(self.info['memory_KiB'])
  27.862 +            xc.domain_setmaxmem(self.domid, maxmem_kb = m)
  27.863  
  27.864  
  27.865      def vcpu_hotplug(self, vcpu, state):
  27.866 @@ -1038,24 +1187,9 @@ class XendDomainInfo:
  27.867              availability = "online"
  27.868          self.storeVm("cpu/%d/availability" % vcpu, availability)
  27.869  
  27.870 -    def shutdown(self, reason):
  27.871 -        if not reason in shutdown_reasons.values():
  27.872 -            raise XendError('invalid reason:' + reason)
  27.873 -        self.storeVm("control/shutdown", reason)
  27.874 -        if not reason in ['suspend']:
  27.875 -            self.shutdown_pending = {'start':time.time(), 'reason':reason}
  27.876 -
  27.877 -    def clear_shutdown(self):
  27.878 -        self.removeVm("control/shutdown")
  27.879 -
  27.880      def send_sysrq(self, key=0):
  27.881          self.storeVm("control/sysrq", '%c' % key)
  27.882  
  27.883 -    def shutdown_time_left(self, timeout):
  27.884 -        if not self.shutdown_pending:
  27.885 -            return 0
  27.886 -        return timeout - (time.time() - self.shutdown_pending['start'])
  27.887 -
  27.888      def dom0_init_store(self):
  27.889          if not self.store_channel:
  27.890              self.store_channel = self.eventChannel("store/port")
  27.891 @@ -1078,8 +1212,6 @@ class XendDomainInfo:
  27.892      def dom0_enforce_vcpus(self):
  27.893          dom = 0
  27.894          # get max number of vcpus to use for dom0 from config
  27.895 -        from xen.xend import XendRoot
  27.896 -        xroot = XendRoot.instance()
  27.897          target = int(xroot.get_dom0_vcpus())
  27.898          log.debug("number of vcpus to use is %d" % (target))
  27.899     
    28.1 --- a/tools/python/xen/xend/server/DevController.py	Mon Sep 26 11:15:55 2005 -0600
    28.2 +++ b/tools/python/xen/xend/server/DevController.py	Wed Sep 28 21:06:49 2005 +0100
    28.3 @@ -81,6 +81,13 @@ class DevController:
    28.4          xstransact.Remove(backpath)
    28.5  
    28.6  
    28.7 +    def sxprs(self):
    28.8 +        """@return an s-expression describing all the devices of this
    28.9 +        controller's device-class.
   28.10 +        """
   28.11 +        return xstransact.ListRecursive(self.frontendRoot())
   28.12 +
   28.13 +
   28.14      def sxpr(self, devid):
   28.15          """@return an s-expression describing the specified device.
   28.16          """
   28.17 @@ -126,8 +133,8 @@ class DevController:
   28.18          compulsory to use it; subclasses may prefer to allocate IDs based upon
   28.19          the device configuration instead.
   28.20          """
   28.21 +        path = self.frontendMiscPath()
   28.22          while True:
   28.23 -            path = self.frontendMiscPath()
   28.24              t = xstransact(path)
   28.25              try:
   28.26                  result = t.read("nextDeviceID")
   28.27 @@ -196,8 +203,11 @@ class DevController:
   28.28  
   28.29  
   28.30      def frontendPath(self, devid):
   28.31 -        return "%s/device/%s/%d" % (self.vm.getPath(), self.deviceClass,
   28.32 -                                    devid)
   28.33 +        return "%s/%d" % (self.frontendRoot(), devid)
   28.34 +
   28.35 +
   28.36 +    def frontendRoot(self):
   28.37 +        return "%s/device/%s" % (self.vm.getPath(), self.deviceClass)
   28.38  
   28.39  
   28.40      def frontendMiscPath(self):
    29.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Mon Sep 26 11:15:55 2005 -0600
    29.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Sep 28 21:06:49 2005 +0100
    29.3 @@ -9,26 +9,24 @@ import signal
    29.4  import sys
    29.5  import threading
    29.6  import linecache
    29.7 -import socket
    29.8  import pwd
    29.9  import re
   29.10 -import StringIO
   29.11  import traceback
   29.12 -import time
   29.13 -import glob
   29.14  
   29.15 -from xen.xend import sxp
   29.16 -from xen.xend import PrettyPrint
   29.17 -from xen.xend import EventServer; eserver = EventServer.instance()
   29.18 -from xen.xend.XendError import XendError
   29.19 +from xen.xend import EventServer
   29.20  from xen.xend.server import SrvServer
   29.21  from xen.xend.XendLogging import log
   29.22 -from xen.xend import XendRoot; xroot = XendRoot.instance()
   29.23 +from xen.xend import XendRoot
   29.24  
   29.25  import event
   29.26  import relocate
   29.27  from params import *
   29.28  
   29.29 +
   29.30 +eserver = EventServer.instance()
   29.31 +xroot = XendRoot.instance()
   29.32 +
   29.33 +
   29.34  class Daemon:
   29.35      """The xend daemon.
   29.36      """
   29.37 @@ -233,7 +231,7 @@ class Daemon:
   29.38              except:
   29.39                  pass
   29.40  
   29.41 -    def print_trace(self, str):
   29.42 +    def print_trace(self, string):
   29.43          for i in range(self.traceindent):
   29.44              ch = " "
   29.45              if (i % 5):
   29.46 @@ -241,7 +239,7 @@ class Daemon:
   29.47              else:
   29.48                  ch = '|'
   29.49              self.tracefile.write(ch)
   29.50 -        self.tracefile.write(str)
   29.51 +        self.tracefile.write(string)
   29.52              
   29.53      def trace(self, frame, event, arg):
   29.54          if not self.traceon:
   29.55 @@ -289,7 +287,7 @@ class Daemon:
   29.56          try:
   29.57              os.setuid(pwd.getpwnam(XEND_USER)[2])
   29.58              return 0
   29.59 -        except KeyError, error:
   29.60 +        except KeyError:
   29.61              print >>sys.stderr, "Error: no such user '%s'" % XEND_USER
   29.62              return 1
   29.63  
    30.1 --- a/tools/python/xen/xend/server/SrvDmesg.py	Mon Sep 26 11:15:55 2005 -0600
    30.2 +++ b/tools/python/xen/xend/server/SrvDmesg.py	Wed Sep 28 21:06:49 2005 +0100
    30.3 @@ -13,15 +13,15 @@
    30.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    30.5  #============================================================================
    30.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    30.7 +# Copyright (C) 2005 XenSource Ltd
    30.8  #============================================================================
    30.9  
   30.10 -import os
   30.11  
   30.12 -from xen.xend import sxp
   30.13  from xen.xend import XendDmesg
   30.14  
   30.15  from xen.web.SrvDir import SrvDir
   30.16  
   30.17 +
   30.18  class SrvDmesg(SrvDir):
   30.19      """Xen Dmesg output.
   30.20      """
   30.21 @@ -47,6 +47,6 @@ class SrvDmesg(SrvDir):
   30.22      def info(self):
   30.23          return self.xd.info()
   30.24  
   30.25 -    def op_clear(self, op, req):
   30.26 +    def op_clear(self, _1, _2):
   30.27          self.xd.clear()
   30.28          return 0
    31.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Mon Sep 26 11:15:55 2005 -0600
    31.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Wed Sep 28 21:06:49 2005 +0100
    31.3 @@ -150,17 +150,6 @@ class SrvDomain(SrvDir):
    31.4          val = fn(req.args, {'dom': self.dom.domid})
    31.5          return val
    31.6  
    31.7 -    def op_device(self, op, req):
    31.8 -        fn = FormFn(self.xd.domain_devtype_get,
    31.9 -                    [['dom',    'int'],
   31.10 -                     ['type',   'str'],
   31.11 -                     ['idx',    'int']])
   31.12 -        val = fn(req.args, {'dom': self.dom.domid})
   31.13 -        if val:
   31.14 -            return val.sxpr()
   31.15 -        else:
   31.16 -            raise XendError("invalid device")
   31.17 -
   31.18      def op_device_create(self, op, req):
   31.19          fn = FormFn(self.xd.domain_device_create,
   31.20                      [['dom',    'int'],
   31.21 @@ -172,7 +161,7 @@ class SrvDomain(SrvDir):
   31.22          fn = FormFn(self.xd.domain_device_refresh,
   31.23                      [['dom',  'int'],
   31.24                       ['type', 'str'],
   31.25 -                     ['idx',  'str']])
   31.26 +                     ['idx',  'int']])
   31.27          val = fn(req.args, {'dom': self.dom.domid})
   31.28          return val
   31.29  
   31.30 @@ -180,7 +169,7 @@ class SrvDomain(SrvDir):
   31.31          fn = FormFn(self.xd.domain_device_destroy,
   31.32                      [['dom',  'int'],
   31.33                       ['type', 'str'],
   31.34 -                     ['idx',  'str']])
   31.35 +                     ['idx',  'int']])
   31.36          val = fn(req.args, {'dom': self.dom.domid})
   31.37          return val
   31.38                  
   31.39 @@ -188,7 +177,7 @@ class SrvDomain(SrvDir):
   31.40          fn = FormFn(self.xd.domain_device_configure,
   31.41                      [['dom',    'int'],
   31.42                       ['config', 'sxpr'],
   31.43 -                     ['idx',    'str']])
   31.44 +                     ['idx',    'int']])
   31.45          val = fn(req.args, {'dom': self.dom.domid})
   31.46          return val
   31.47  
   31.48 @@ -230,10 +219,6 @@ class SrvDomain(SrvDir):
   31.49              self.print_path(req)
   31.50              #self.ls()
   31.51              req.write('<p>%s</p>' % self.dom)
   31.52 -            if self.dom.config:
   31.53 -                req.write("<code><pre>")
   31.54 -                PrettyPrint.prettyprint(self.dom.config, out=req)
   31.55 -                req.write("</pre></code>")
   31.56              self.form(req)
   31.57              req.write('</body></html>')
   31.58          return ''
    32.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Sep 26 11:15:55 2005 -0600
    32.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Wed Sep 28 21:06:49 2005 +0100
    32.3 @@ -38,19 +38,17 @@ class SrvDomainDir(SrvDir):
    32.4          self.xd = XendDomain.instance()
    32.5  
    32.6      def domain(self, x):
    32.7 -        val = None
    32.8          dom = self.xd.domain_lookup_by_name(x)
    32.9          if not dom:
   32.10              raise XendError('No such domain ' + str(x))
   32.11 -        val = SrvDomain(dom)
   32.12 -        return val
   32.13 +        return SrvDomain(dom)
   32.14  
   32.15      def get(self, x):
   32.16          v = SrvDir.get(self, x)
   32.17          if v is not None:
   32.18              return v
   32.19 -        v = self.domain(x)
   32.20 -        return v
   32.21 +        else:
   32.22 +            return self.domain(x)
   32.23  
   32.24      def op_create(self, op, req):
   32.25          """Create a domain.
   32.26 @@ -152,11 +150,11 @@ class SrvDomainDir(SrvDir):
   32.27              domains = self.xd.list_sorted()
   32.28              req.write('<ul>')
   32.29              for d in domains:
   32.30 -                req.write('<li><a href="%s%s"> Domain %s</a>'
   32.31 -                          % (url, d.getName(), d.getName()))
   32.32 -                req.write('id=%s' % d.getDomain())
   32.33 -                req.write('memory=%d'% d.getMemoryTarget())
   32.34 -                req.write('ssidref=%d'% d.getSsidref())
   32.35 +                req.write(
   32.36 +                    '<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d, '
   32.37 +                    'ssidref = %d.'
   32.38 +                    % (url, d.getName(), d.getName(), d.getDomid(),
   32.39 +                       d.getMemoryTarget(), d.getSsidref()))
   32.40                  req.write('</li>')
   32.41              req.write('</ul>')
   32.42  
    33.1 --- a/tools/python/xen/xend/server/SrvNode.py	Mon Sep 26 11:15:55 2005 -0600
    33.2 +++ b/tools/python/xen/xend/server/SrvNode.py	Wed Sep 28 21:06:49 2005 +0100
    33.3 @@ -62,7 +62,7 @@ class SrvNode(SrvDir):
    33.4              for d in self.info():
    33.5                  req.write('<li> %10s: %s' % (d[0], str(d[1])))
    33.6              req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url)
    33.7 -            req.write('<li><a href="%slog>Xend log</a>' % url)
    33.8 +            req.write('<li><a href="%slog">Xend log</a>' % url)
    33.9              req.write('</ul>')
   33.10              req.write('</body></html>')
   33.11              
    34.1 --- a/tools/python/xen/xend/xenstore/xstransact.py	Mon Sep 26 11:15:55 2005 -0600
    34.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py	Wed Sep 28 21:06:49 2005 +0100
    34.3 @@ -1,4 +1,5 @@
    34.4  # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
    34.5 +# Copyright (C) 2005 XenSource Ltd
    34.6  
    34.7  # This file is subject to the terms and conditions of the GNU General
    34.8  # Public License.  See the file "COPYING" in the main directory of
    34.9 @@ -9,6 +10,7 @@ import threading
   34.10  from xen.lowlevel import xs
   34.11  from xen.xend.xenstore.xsutil import xshandle
   34.12  
   34.13 +
   34.14  class xstransact:
   34.15  
   34.16      def __init__(self, path):
   34.17 @@ -40,8 +42,15 @@ class xstransact:
   34.18                                 '%s, while reading %s' % (ex.args[1], path))
   34.19  
   34.20      def read(self, *args):
   34.21 +        """If no arguments are given, return the value at this transaction's
   34.22 +        path.  If one argument is given, treat that argument as a subpath to
   34.23 +        this transaction's path, and return the value at that path.
   34.24 +        Otherwise, treat each argument as a subpath to this transaction's
   34.25 +        path, and return a list composed of the values at each of those
   34.26 +        instead.
   34.27 +        """
   34.28          if len(args) == 0:
   34.29 -            raise TypeError
   34.30 +            return xshandle().read(self.path)
   34.31          if len(args) == 1:
   34.32              return self._read(args[0])
   34.33          ret = []
   34.34 @@ -105,13 +114,50 @@ class xstransact:
   34.35          return []
   34.36  
   34.37      def list(self, *args):
   34.38 +        """If no arguments are given, list this transaction's path, returning
   34.39 +        the entries therein, or the empty list if no entries are found.
   34.40 +        Otherwise, treat each argument as a subpath to this transaction's
   34.41 +        path, and return the cumulative listing of each of those instead.
   34.42 +        """
   34.43          if len(args) == 0:
   34.44 -            raise TypeError
   34.45 +            ret = xshandle().ls(self.path)
   34.46 +            if ret is None:
   34.47 +                return []
   34.48 +            else:
   34.49 +                return ret
   34.50 +        else:
   34.51 +            ret = []
   34.52 +            for key in args:
   34.53 +                ret.extend(self._list(key))
   34.54 +            return ret
   34.55 +
   34.56 +
   34.57 +    def list_recursive_(self, subdir, keys):
   34.58          ret = []
   34.59 -        for key in args:
   34.60 -            ret.extend(self._list(key))
   34.61 +        for key in keys:
   34.62 +            new_subdir = subdir + "/" + key
   34.63 +            l = xshandle().ls(new_subdir)
   34.64 +            if l:
   34.65 +                ret.append([key, self.list_recursive_(new_subdir, l)])
   34.66 +            else:
   34.67 +                ret.append([key, xshandle().read(new_subdir)])
   34.68          return ret
   34.69  
   34.70 +
   34.71 +    def list_recursive(self, *args):
   34.72 +        """If no arguments are given, list this transaction's path, returning
   34.73 +        the entries therein, or the empty list if no entries are found.
   34.74 +        Otherwise, treat each argument as a subpath to this transaction's
   34.75 +        path, and return the cumulative listing of each of those instead.
   34.76 +        """
   34.77 +        if len(args) == 0:
   34.78 +            args = self.list()
   34.79 +            if args is None or len(args) == 0:
   34.80 +                return []
   34.81 +
   34.82 +        return self.list_recursive_(self.path, args)
   34.83 +
   34.84 +
   34.85      def gather(self, *args):
   34.86          if len(args) and type(args[0]) != tuple:
   34.87              args = args,
   34.88 @@ -163,6 +209,13 @@ class xstransact:
   34.89  
   34.90  
   34.91      def Read(cls, path, *args):
   34.92 +        """If only one argument is given (path), return the value stored at
   34.93 +        that path.  If two arguments are given, treat the second argument as a
   34.94 +        subpath within the first, and return the value at the composed path.
   34.95 +        Otherwise, treat each argument after the first as a subpath to the
   34.96 +        given path, and return a list composed of the values at each of those
   34.97 +        instead.  This operation is performed inside a transaction.
   34.98 +        """
   34.99          while True:
  34.100              t = cls(path)
  34.101              try:
  34.102 @@ -206,6 +259,12 @@ class xstransact:
  34.103      Remove = classmethod(Remove)
  34.104  
  34.105      def List(cls, path, *args):
  34.106 +        """If only one argument is given (path), list its contents, returning
  34.107 +        the entries therein, or the empty list if no entries are found.
  34.108 +        Otherwise, treat each further argument as a subpath to the given path,
  34.109 +        and return the cumulative listing of each of those instead.  This
  34.110 +        operation is performed inside a transaction.
  34.111 +        """
  34.112          while True:
  34.113              t = cls(path)
  34.114              try:
  34.115 @@ -218,6 +277,25 @@ class xstransact:
  34.116  
  34.117      List = classmethod(List)
  34.118  
  34.119 +    def ListRecursive(cls, path, *args):
  34.120 +        """If only one argument is given (path), list its contents
  34.121 +        recursively, returning the entries therein, or the empty list if no
  34.122 +        entries are found.  Otherwise, treat each further argument as a
  34.123 +        subpath to the given path, and return the cumulative listing of each
  34.124 +        of those instead.  This operation is performed inside a transaction.
  34.125 +        """
  34.126 +        while True:
  34.127 +            t = cls(path)
  34.128 +            try:
  34.129 +                v = t.list_recursive(*args)
  34.130 +                if t.commit():
  34.131 +                    return v
  34.132 +            except:
  34.133 +                t.abort()
  34.134 +                raise
  34.135 +
  34.136 +    ListRecursive = classmethod(ListRecursive)
  34.137 +
  34.138      def Gather(cls, path, *args):
  34.139          while True:
  34.140              t = cls(path)
    35.1 --- a/tools/python/xen/xm/main.py	Mon Sep 26 11:15:55 2005 -0600
    35.2 +++ b/tools/python/xen/xm/main.py	Wed Sep 28 21:06:49 2005 +0100
    35.3 @@ -175,6 +175,10 @@ def xm_save(args):
    35.4  
    35.5      dom = args[0] # TODO: should check if this exists
    35.6      savefile = os.path.abspath(args[1])
    35.7 +
    35.8 +    if not os.access(os.path.dirname(savefile), os.W_OK):
    35.9 +        err("xm save: Unable to create file %s" % savefile)
   35.10 +        sys.exit(1)
   35.11      
   35.12      from xen.xend.XendClient import server
   35.13      server.xend_domain_save(dom, savefile)
   35.14 @@ -184,6 +188,10 @@ def xm_restore(args):
   35.15  
   35.16      savefile = os.path.abspath(args[0])
   35.17  
   35.18 +    if not os.access(savefile, os.R_OK):
   35.19 +        err("xm restore: Unable to read file %s" % savefile)
   35.20 +        sys.exit(1)
   35.21 +
   35.22      from xen.xend.XendClient import server
   35.23      info = server.xend_domain_restore(savefile)
   35.24      PrettyPrint.prettyprint(info)
    36.1 --- a/tools/xenstore/xenstored_domain.c	Mon Sep 26 11:15:55 2005 -0600
    36.2 +++ b/tools/xenstore/xenstored_domain.c	Wed Sep 28 21:06:49 2005 +0100
    36.3 @@ -63,6 +63,8 @@ struct domain
    36.4  	/* The connection associated with this. */
    36.5  	struct connection *conn;
    36.6  
    36.7 +	/* Have we noticed that this domain is shutdown? */
    36.8 +	int shutdown;
    36.9  };
   36.10  
   36.11  static LIST_HEAD(domains);
   36.12 @@ -222,19 +224,25 @@ static void domain_cleanup(void)
   36.13  {
   36.14  	xc_dominfo_t dominfo;
   36.15  	struct domain *domain, *tmp;
   36.16 -	int released = 0;
   36.17 +	int notify = 0;
   36.18  
   36.19  	list_for_each_entry_safe(domain, tmp, &domains, list) {
   36.20  		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
   36.21  				      &dominfo) == 1 &&
   36.22 -		    dominfo.domid == domain->domid &&
   36.23 -		    !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
   36.24 -			continue;
   36.25 +		    dominfo.domid == domain->domid) {
   36.26 +			if ((dominfo.crashed || dominfo.shutdown)
   36.27 +			    && !domain->shutdown) {
   36.28 +				domain->shutdown = 1;
   36.29 +				notify = 1;
   36.30 +			}
   36.31 +			if (!dominfo.dying)
   36.32 +				continue;
   36.33 +		}
   36.34  		talloc_free(domain->conn);
   36.35 -		released++;
   36.36 +		notify = 1;
   36.37  	}
   36.38  
   36.39 -	if (released)
   36.40 +	if (notify)
   36.41  		fire_watches(NULL, "@releaseDomain", false);
   36.42  }
   36.43  
   36.44 @@ -272,6 +280,7 @@ static struct domain *new_domain(void *c
   36.45  	struct domain *domain;
   36.46  	domain = talloc(context, struct domain);
   36.47  	domain->port = 0;
   36.48 +	domain->shutdown = 0;
   36.49  	domain->domid = domid;
   36.50  	domain->path = talloc_strdup(domain, path);
   36.51  	domain->page = xc_map_foreign_range(*xc_handle, domain->domid,
    37.1 --- a/xen/arch/x86/shadow32.c	Mon Sep 26 11:15:55 2005 -0600
    37.2 +++ b/xen/arch/x86/shadow32.c	Wed Sep 28 21:06:49 2005 +0100
    37.3 @@ -755,9 +755,13 @@ void free_monitor_pagetable(struct vcpu 
    37.4  
    37.5      /*
    37.6       * Then free monitor_table.
    37.7 +     * Note: for VMX guest, only BSP need do this free.
    37.8       */
    37.9 -    mfn = pagetable_get_pfn(v->arch.monitor_table);
   37.10 -    free_domheap_page(&frame_table[mfn]);
   37.11 +    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   37.12 +        mfn = pagetable_get_pfn(v->arch.monitor_table);
   37.13 +        unmap_domain_page(v->arch.monitor_vtable);
   37.14 +        free_domheap_page(&frame_table[mfn]);
   37.15 +    }
   37.16  
   37.17      v->arch.monitor_table = mk_pagetable(0);
   37.18      v->arch.monitor_vtable = 0;
    38.1 --- a/xen/arch/x86/shadow_public.c	Mon Sep 26 11:15:55 2005 -0600
    38.2 +++ b/xen/arch/x86/shadow_public.c	Wed Sep 28 21:06:49 2005 +0100
    38.3 @@ -256,14 +256,15 @@ void free_monitor_pagetable(struct vcpu 
    38.4  {
    38.5      unsigned long mfn;
    38.6  
    38.7 -//    ASSERT( pagetable_val(v->arch.monitor_table) );
    38.8      /*
    38.9       * free monitor_table.
   38.10 +     * Note: for VMX guest, only BSP need do this free.
   38.11       */
   38.12 -    //mfn = (pagetable_val(v->arch.monitor_table)) >> PAGE_SHIFT;
   38.13 -    mfn = pagetable_get_pfn(v->arch.monitor_table);
   38.14 -    unmap_domain_page(v->arch.monitor_vtable);
   38.15 -    free_domheap_page(&frame_table[mfn]);
   38.16 +    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   38.17 +        mfn = pagetable_get_pfn(v->arch.monitor_table);
   38.18 +        unmap_domain_page(v->arch.monitor_vtable);
   38.19 +        free_domheap_page(&frame_table[mfn]);
   38.20 +    }
   38.21      v->arch.monitor_table = mk_pagetable(0);
   38.22      v->arch.monitor_vtable = 0;
   38.23  }
   38.24 @@ -358,9 +359,13 @@ void free_monitor_pagetable(struct vcpu 
   38.25  
   38.26      /*
   38.27       * Then free monitor_table.
   38.28 +     * Note: for VMX guest, only BSP need do this free.
   38.29       */
   38.30 -    mfn = pagetable_get_pfn(v->arch.monitor_table);
   38.31 -    free_domheap_page(&frame_table[mfn]);
   38.32 +    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   38.33 +        mfn = pagetable_get_pfn(v->arch.monitor_table);
   38.34 +        unmap_domain_page(v->arch.monitor_vtable);
   38.35 +        free_domheap_page(&frame_table[mfn]);
   38.36 +    }
   38.37  
   38.38      v->arch.monitor_table = mk_pagetable(0);
   38.39      v->arch.monitor_vtable = 0;
    39.1 --- a/xen/arch/x86/vmx_platform.c	Mon Sep 26 11:15:55 2005 -0600
    39.2 +++ b/xen/arch/x86/vmx_platform.c	Wed Sep 28 21:06:49 2005 +0100
    39.3 @@ -667,6 +667,7 @@ static void mmio_operands(int type, unsi
    39.4      mpcip->instr = inst->instr;
    39.5      mpcip->operand[0] = inst->operand[0]; /* source */
    39.6      mpcip->operand[1] = inst->operand[1]; /* destination */
    39.7 +    mpcip->immediate = inst->immediate;
    39.8  
    39.9      if (inst->operand[0] & REGISTER) { /* dest is memory */
   39.10          index = operand_index(inst->operand[0]);
   39.11 @@ -833,12 +834,16 @@ void handle_mmio(unsigned long va, unsig
   39.12          mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
   39.13          break;
   39.14  
   39.15 -    case INSTR_CMP:
   39.16 -        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
   39.17 -        break;
   39.18 +    case INSTR_CMP:        /* Pass through */
   39.19 +    case INSTR_TEST:
   39.20 +        mpcip->flags = mmio_inst.flags;
   39.21 +        mpcip->instr = mmio_inst.instr;
   39.22 +        mpcip->operand[0] = mmio_inst.operand[0]; /* source */
   39.23 +        mpcip->operand[1] = mmio_inst.operand[1]; /* destination */
   39.24 +        mpcip->immediate = mmio_inst.immediate;
   39.25  
   39.26 -    case INSTR_TEST:
   39.27 -        mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
   39.28 +        /* send the request and wait for the value */
   39.29 +        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, IOREQ_READ, 0);
   39.30          break;
   39.31  
   39.32      default: