[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] merge
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 5e5ae834095691ec677fcaaf11e9b16fcaeb76ed # Parent 4e1031ce3bc203badf97c75fa124178e485ca028 # Parent 081b326162bcabd1c1245e16c14c8427f33b1b5e merge diff -r 4e1031ce3bc2 -r 5e5ae8340956 .hgignore --- a/.hgignore Mon Sep 26 17:15:55 2005 +++ b/.hgignore Wed Sep 28 20:06:49 2005 @@ -158,6 +158,7 @@ ^tools/xenstore/xs_dom0_test$ ^tools/xenstore/xs_random$ ^tools/xenstore/xs_stress$ +^tools/xenstore/xs_tdb_dump$ ^tools/xenstore/xs_test$ ^tools/xenstore/xs_watch_stress$ ^tools/xentrace/xenctx$ diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Wed Sep 28 20:06:49 2005 @@ -2684,7 +2684,7 @@ # # File systems # -CONFIG_EXT2_FS=m +CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y @@ -2913,7 +2913,7 @@ # CONFIG_KEYS_DEBUG_PROC_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_CAPABILITIES=y CONFIG_SECURITY_ROOTPLUG=m CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Wed Sep 28 20:06:49 2005 @@ -112,6 +112,10 @@ #ifdef CONFIG_HOTPLUG_CPU #include <asm/nmi.h> +#ifdef CONFIG_SMP +extern void smp_suspend(void); +extern void smp_resume(void); +#endif /* We don't actually take CPU down, just spin without interrupts. */ static inline void play_dead(void) { @@ -120,6 +124,13 @@ HYPERVISOR_yield(); __flush_tlb_all(); + /* + * Restore IPI/IRQ mappings before marking online to prevent + * race between pending interrupts and restoration of handler. + */ +#ifdef CONFIG_SMP + smp_resume(); +#endif cpu_set(smp_processor_id(), cpu_online_map); } #else @@ -135,10 +146,6 @@ * low exit latency (ie sit in a loop waiting for * somebody to say that they'd like to reschedule) */ -#ifdef CONFIG_SMP -extern void smp_suspend(void); -extern void smp_resume(void); -#endif void cpu_idle (void) { int cpu = _smp_processor_id(); @@ -166,9 +173,6 @@ HYPERVISOR_vcpu_down(cpu); #endif play_dead(); -#ifdef CONFIG_SMP - smp_resume(); -#endif local_irq_enable(); } diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Wed Sep 28 20:06:49 2005 @@ -209,7 +209,10 @@ { unsigned long *p, page; - page = __pa(per_cpu(cur_pgd, smp_processor_id())); + preempt_disable(); + page = __pa(per_cpu(cur_pgd, smp_processor_id())); + preempt_enable(); + p = (unsigned long *)__va(page); p += (address >> 30) * 2; printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]); @@ -237,7 +240,12 @@ { unsigned long page; + preempt_disable(); page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id())) + [address >> 22]; + preempt_enable(); + + page = ((unsigned long *) per_cpu(cur_pgd, get_cpu())) [address >> 22]; printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page, machine_to_phys(page)); @@ -567,7 +575,9 @@ pmd_t *pmd, *pmd_k; pte_t *pte_k; + preempt_disable(); pgd = index + per_cpu(cur_pgd, smp_processor_id()); + preempt_enable(); pgd_k = init_mm.pgd + index; if (!pgd_present(*pgd_k)) diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Wed Sep 28 20:06:49 2005 @@ -1,13 +1,10 @@ /****************************************************************************** * gnttab.c * - * Two sets of functionality: - * 1. Granting foreign access to our memory reservation. - * 2. Accessing others' memory reservations via grant references. - * (i.e., mechanisms for both sender and recipient of grant references) + * Granting foreign access to our memory reservation. * * Copyright (c) 2005, Christopher Clark - * Copyright (c) 2004, K A Fraser + * Copyright (c) 2004-2005, K A Fraser */ #include <linux/config.h> @@ -23,15 +20,15 @@ #include <asm/synch_bitops.h> #if 1 -#define ASSERT(_p) \ - if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \ - #_p , __LINE__, __FILE__); *(int*)0=0; } +#define ASSERT(_p) \ + if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \ + #_p , __LINE__, __FILE__); *(int*)0=0; } #else #define ASSERT(_p) ((void)0) #endif -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_grant: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_grant: " fmt, ##args) EXPORT_SYMBOL(gnttab_grant_foreign_access); @@ -49,11 +46,14 @@ EXPORT_SYMBOL(gnttab_grant_foreign_access_ref); EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref); +/* External tools reserve first few grant table entries. */ +#define NR_RESERVED_ENTRIES 8 + #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1) static grant_ref_t gnttab_list[NR_GRANT_ENTRIES]; -static int gnttab_free_count = NR_GRANT_ENTRIES; +static int gnttab_free_count; static grant_ref_t gnttab_free_head; static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED; @@ -64,22 +64,22 @@ static int get_free_entries(int count) { - unsigned long flags; - int ref; - grant_ref_t head; - spin_lock_irqsave(&gnttab_list_lock, flags); - if (gnttab_free_count < count) { + unsigned long flags; + int ref; + grant_ref_t head; + spin_lock_irqsave(&gnttab_list_lock, flags); + if (gnttab_free_count < count) { + spin_unlock_irqrestore(&gnttab_list_lock, flags); + return -1; + } + ref = head = gnttab_free_head; + gnttab_free_count -= count; + while (count-- > 1) + head = gnttab_list[head]; + gnttab_free_head = gnttab_list[head]; + gnttab_list[head] = GNTTAB_LIST_END; spin_unlock_irqrestore(&gnttab_list_lock, flags); - return -1; - } - ref = head = gnttab_free_head; - gnttab_free_count -= count; - while (count-- > 1) - head = gnttab_list[head]; - gnttab_free_head = gnttab_list[head]; - gnttab_list[head] = GNTTAB_LIST_END; - spin_unlock_irqrestore(&gnttab_list_lock, flags); - return ref; + return ref; } #define get_free_entry() get_free_entries(1) @@ -87,38 +87,41 @@ static void do_free_callbacks(void) { - struct gnttab_free_callback *callback = gnttab_free_callback_list, *next; - gnttab_free_callback_list = NULL; - while (callback) { - next = callback->next; - if (gnttab_free_count >= callback->count) { - callback->next = NULL; - callback->fn(callback->arg); - } else { - callback->next = gnttab_free_callback_list; - gnttab_free_callback_list = callback; - } - callback = next; - } + struct gnttab_free_callback *callback, *next; + + callback = gnttab_free_callback_list; + gnttab_free_callback_list = NULL; + + while (callback != NULL) { + next = callback->next; + if (gnttab_free_count >= callback->count) { + callback->next = NULL; + callback->fn(callback->arg); + } else { + callback->next = gnttab_free_callback_list; + gnttab_free_callback_list = callback; + } + callback = next; + } } static inline void check_free_callbacks(void) { - if (unlikely(gnttab_free_callback_list)) - do_free_callbacks(); + if (unlikely(gnttab_free_callback_list)) + do_free_callbacks(); } static void put_free_entry(grant_ref_t ref) { - unsigned long flags; - spin_lock_irqsave(&gnttab_list_lock, flags); - gnttab_list[ref] = gnttab_free_head; - gnttab_free_head = ref; - gnttab_free_count++; - check_free_callbacks(); - spin_unlock_irqrestore(&gnttab_list_lock, flags); + unsigned long flags; + spin_lock_irqsave(&gnttab_list_lock, flags); + gnttab_list[ref] = gnttab_free_head; + gnttab_free_head = ref; + gnttab_free_count++; + check_free_callbacks(); + spin_unlock_irqrestore(&gnttab_list_lock, flags); } /* @@ -128,187 +131,189 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly) { - int ref; + int ref; - if ( unlikely((ref = get_free_entry()) == -1) ) - return -ENOSPC; - - shared[ref].frame = frame; - shared[ref].domid = domid; - wmb(); - shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); - - return ref; + if (unlikely((ref = get_free_entry()) == -1)) + return -ENOSPC; + + shared[ref].frame = frame; + shared[ref].domid = domid; + wmb(); + shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); + + return ref; } void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, unsigned long frame, int readonly) { - shared[ref].frame = frame; - shared[ref].domid = domid; - wmb(); - shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); + shared[ref].frame = frame; + shared[ref].domid = domid; + wmb(); + shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); } int gnttab_query_foreign_access(grant_ref_t ref) { - u16 nflags; - - nflags = shared[ref].flags; - - return ( nflags & (GTF_reading|GTF_writing) ); + u16 nflags; + + nflags = shared[ref].flags; + + return (nflags & (GTF_reading|GTF_writing)); } void gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) { - u16 flags, nflags; - - nflags = shared[ref].flags; - do { - if ( (flags = nflags) & (GTF_reading|GTF_writing) ) - printk(KERN_ALERT "WARNING: g.e. still in use!\n"); - } - while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags ); + u16 flags, nflags; + + nflags = shared[ref].flags; + do { + if ( (flags = nflags) & (GTF_reading|GTF_writing) ) + printk(KERN_ALERT "WARNING: g.e. still in use!\n"); + } + while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != + flags); } void gnttab_end_foreign_access(grant_ref_t ref, int readonly) { - gnttab_end_foreign_access_ref(ref, readonly); - put_free_entry(ref); + gnttab_end_foreign_access_ref(ref, readonly); + put_free_entry(ref); } int gnttab_grant_foreign_transfer(domid_t domid) { - int ref; - - if ( unlikely((ref = get_free_entry()) == -1) ) - return -ENOSPC; - - shared[ref].frame = 0; - shared[ref].domid = domid; - wmb(); - shared[ref].flags = GTF_accept_transfer; - - return ref; + int ref; + + if (unlikely((ref = get_free_entry()) == -1)) + return -ENOSPC; + + shared[ref].frame = 0; + shared[ref].domid = domid; + wmb(); + shared[ref].flags = GTF_accept_transfer; + + return ref; } void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid) { - shared[ref].frame = 0; - shared[ref].domid = domid; - wmb(); - shared[ref].flags = GTF_accept_transfer; + shared[ref].frame = 0; + shared[ref].domid = domid; + wmb(); + shared[ref].flags = GTF_accept_transfer; } unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) { - unsigned long frame = 0; - u16 flags; - - flags = shared[ref].flags; - - /* - * If a transfer is committed then wait for the frame address to appear. - * Otherwise invalidate the grant entry against future use. - */ - if ( likely(flags != GTF_accept_transfer) || - (synch_cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) ) - while ( unlikely((frame = shared[ref].frame) == 0) ) - cpu_relax(); - - return frame; + unsigned long frame = 0; + u16 flags; + + flags = shared[ref].flags; + + /* + * If a transfer is committed then wait for the frame address to + * appear. Otherwise invalidate the grant entry against future use. + */ + if (likely(flags != GTF_accept_transfer) || + (synch_cmpxchg(&shared[ref].flags, flags, 0) != + GTF_accept_transfer)) + while (unlikely((frame = shared[ref].frame) == 0)) + cpu_relax(); + + return frame; } unsigned long gnttab_end_foreign_transfer(grant_ref_t ref) { - unsigned long frame = gnttab_end_foreign_transfer_ref(ref); - put_free_entry(ref); - return frame; + unsigned long frame = gnttab_end_foreign_transfer_ref(ref); + put_free_entry(ref); + return frame; } void gnttab_free_grant_reference(grant_ref_t ref) { - put_free_entry(ref); + put_free_entry(ref); } void gnttab_free_grant_references(grant_ref_t head) { - grant_ref_t ref; - unsigned long flags; - int count = 1; - if (head == GNTTAB_LIST_END) - return; - spin_lock_irqsave(&gnttab_list_lock, flags); - ref = head; - while (gnttab_list[ref] != GNTTAB_LIST_END) { - ref = gnttab_list[ref]; - count++; - } - gnttab_list[ref] = gnttab_free_head; - gnttab_free_head = head; - gnttab_free_count += count; - check_free_callbacks(); - spin_unlock_irqrestore(&gnttab_list_lock, flags); + grant_ref_t ref; + unsigned long flags; + int count = 1; + if (head == GNTTAB_LIST_END) + return; + spin_lock_irqsave(&gnttab_list_lock, flags); + ref = head; + while (gnttab_list[ref] != GNTTAB_LIST_END) { + ref = gnttab_list[ref]; + count++; + } + gnttab_list[ref] = gnttab_free_head; + gnttab_free_head = head; + gnttab_free_count += count; + check_free_callbacks(); + spin_unlock_irqrestore(&gnttab_list_lock, flags); } int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) { - int h = get_free_entries(count); - - if (h == -1) - return -ENOSPC; - - *head = h; - - return 0; + int h = get_free_entries(count); + + if (h == -1) + return -ENOSPC; + + *head = h; + + return 0; } int gnttab_claim_grant_reference(grant_ref_t *private_head) { - grant_ref_t g = *private_head; - if (unlikely(g == GNTTAB_LIST_END)) - return -ENOSPC; - *private_head = gnttab_list[g]; - return g; + grant_ref_t g = *private_head; + if (unlikely(g == GNTTAB_LIST_END)) + return -ENOSPC; + *private_head = gnttab_list[g]; + return g; } void gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release) { - gnttab_list[release] = *private_head; - *private_head = release; + gnttab_list[release] = *private_head; + *private_head = release; } void gnttab_request_free_callback(struct gnttab_free_callback *callback, void (*fn)(void *), void *arg, u16 count) { - unsigned long flags; - spin_lock_irqsave(&gnttab_list_lock, flags); - if (callback->next) - goto out; - callback->fn = fn; - callback->arg = arg; - callback->count = count; - callback->next = gnttab_free_callback_list; - gnttab_free_callback_list = callback; - check_free_callbacks(); + unsigned long flags; + spin_lock_irqsave(&gnttab_list_lock, flags); + if (callback->next) + goto out; + callback->fn = fn; + callback->arg = arg; + callback->count = count; + callback->next = gnttab_free_callback_list; + gnttab_free_callback_list = callback; + check_free_callbacks(); out: - spin_unlock_irqrestore(&gnttab_list_lock, flags); + spin_unlock_irqrestore(&gnttab_list_lock, flags); } /* @@ -323,79 +328,83 @@ grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) { - int ret; - privcmd_hypercall_t hypercall; - - /* XXX Need safety checks here if using for anything other - * than debugging */ - return -ENOSYS; - - if ( cmd != IOCTL_PRIVCMD_HYPERCALL ) - return -ENOSYS; - - if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) ) - return -EFAULT; - - if ( hypercall.op != __HYPERVISOR_grant_table_op ) - return -ENOSYS; - - /* hypercall-invoking asm taken from privcmd.c */ - __asm__ __volatile__ ( - "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; " - "movl 4(%%eax),%%ebx ;" - "movl 8(%%eax),%%ecx ;" - "movl 12(%%eax),%%edx ;" - "movl 16(%%eax),%%esi ;" - "movl 20(%%eax),%%edi ;" - "movl (%%eax),%%eax ;" - TRAP_INSTR "; " - "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx" - : "=a" (ret) : "0" (&hypercall) : "memory" ); - - return ret; + int ret; + privcmd_hypercall_t hypercall; + + /* + * XXX Need safety checks here if using for anything other + * than debugging. + */ + return -ENOSYS; + + if ( cmd != IOCTL_PRIVCMD_HYPERCALL ) + return -ENOSYS; + + if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) ) + return -EFAULT; + + if ( hypercall.op != __HYPERVISOR_grant_table_op ) + return -ENOSYS; + + /* hypercall-invoking asm taken from privcmd.c */ + __asm__ __volatile__ ( + "pushl %%ebx; pushl %%ecx; pushl %%edx; " + "pushl %%esi; pushl %%edi; " + "movl 4(%%eax),%%ebx ;" + "movl 8(%%eax),%%ecx ;" + "movl 12(%%eax),%%edx ;" + "movl 16(%%eax),%%esi ;" + "movl 20(%%eax),%%edi ;" + "movl (%%eax),%%eax ;" + TRAP_INSTR "; " + "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx" + : "=a" (ret) : "0" (&hypercall) : "memory" ); + + return ret; } static struct file_operations grant_file_ops = { - ioctl: grant_ioctl, + ioctl: grant_ioctl, }; static int grant_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; - unsigned int i; - grant_entry_t *gt; - - gt = (grant_entry_t *)shared; - len = 0; - - for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) - /* TODO: safety catch here until this can handle >PAGE_SIZE output */ - if (len > (PAGE_SIZE - 200)) - { - len += sprintf( page + len, "Truncated.\n"); - break; - } - - if ( gt[i].flags ) - len += sprintf( page + len, - "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", - i, - gt[i].flags, - gt[i].domid, - gt[i].frame ); - - *eof = 1; - return len; + int len; + unsigned int i; + grant_entry_t *gt; + + gt = (grant_entry_t *)shared; + len = 0; + + for (i = 0; i < NR_GRANT_ENTRIES; i++) { + if (len > (PAGE_SIZE - 200)) { + len += sprintf( page + len, "Truncated.\n"); + break; + } + } + + if (gt[i].flags) { + len += sprintf(page + len, + "Grant: ref (0x%x) flags (0x%hx) " + "dom (0x%hx) frame (0x%x)\n", + i, + gt[i].flags, + gt[i].domid, + gt[i].frame ); + } + + *eof = 1; + return len; } static int grant_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { - /* TODO: implement this */ - return -ENOSYS; + /* TODO: implement this */ + return -ENOSYS; } #endif /* CONFIG_PROC_FS */ @@ -403,70 +412,81 @@ int gnttab_resume(void) { - gnttab_setup_table_t setup; - unsigned long frames[NR_GRANT_FRAMES]; - int i; - - setup.dom = DOMID_SELF; - setup.nr_frames = NR_GRANT_FRAMES; - setup.frame_list = frames; - - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0); - BUG_ON(setup.status != 0); - - for ( i = 0; i < NR_GRANT_FRAMES; i++ ) - set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); - - return 0; + gnttab_setup_table_t setup; + unsigned long frames[NR_GRANT_FRAMES]; + int i; + + setup.dom = DOMID_SELF; + setup.nr_frames = NR_GRANT_FRAMES; + setup.frame_list = frames; + + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1)); + BUG_ON(setup.status != 0); + + for (i = 0; i < NR_GRANT_FRAMES; i++) + set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); + + return 0; } int gnttab_suspend(void) { - int i; - - for ( i = 0; i < NR_GRANT_FRAMES; i++ ) - clear_fixmap(FIX_GNTTAB_END - i); - - return 0; + int i; + + for (i = 0; i < NR_GRANT_FRAMES; i++) + clear_fixmap(FIX_GNTTAB_END - i); + + return 0; } static int __init gnttab_init(void) { - int i; - - if (xen_init() < 0) - return -ENODEV; - - BUG_ON(gnttab_resume()); - - shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END); - - for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) - gnttab_list[i] = i + 1; - + int i; + + if (xen_init() < 0) + return -ENODEV; + + BUG_ON(gnttab_resume()); + + shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END); + + for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++) + gnttab_list[i] = i + 1; + gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; + gnttab_free_head = NR_RESERVED_ENTRIES; + #ifdef CONFIG_PROC_FS - /* - * /proc/xen/grant : used by libxc to access grant tables - */ - if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL ) - { - WPRINTK("Unable to create grant xen proc entry\n"); - return -1; - } - - grant_file_ops.read = grant_pde->proc_fops->read; - grant_file_ops.write = grant_pde->proc_fops->write; - - grant_pde->proc_fops = &grant_file_ops; - - grant_pde->read_proc = &grant_read; - grant_pde->write_proc = &grant_write; + /* + * /proc/xen/grant : used by libxc to access grant tables + */ + if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) { + WPRINTK("Unable to create grant xen proc entry\n"); + return -1; + } + + grant_file_ops.read = grant_pde->proc_fops->read; + grant_file_ops.write = grant_pde->proc_fops->write; + + grant_pde->proc_fops = &grant_file_ops; + + grant_pde->read_proc = &grant_read; + grant_pde->write_proc = &grant_write; #endif - printk("Grant table initialized\n"); - return 0; + printk("Grant table initialized\n"); + return 0; } __initcall(gnttab_init); + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Wed Sep 28 20:06:49 2005 @@ -149,7 +149,9 @@ pmd_t *pmd; pte_t *pte; + preempt_disable(); pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id()); + preempt_enable(); pgd += pgd_index(address); printk("PGD %lx ", pgd_val(*pgd)); @@ -252,7 +254,9 @@ /* On Xen the line below does not always work. Needs investigating! */ /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/ + preempt_disable(); pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id()); + preempt_enable(); pgd += pgd_index(address); pgd_ref = pgd_offset_k(address); diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Sep 28 20:06:49 2005 @@ -80,6 +80,15 @@ return; } + /* Map the shared frame, irq etc. */ + err = blkif_map(be->blkif, ring_ref, evtchn); + if (err) { + xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u", + ring_ref, evtchn); + return; + } + /* XXX From here on should 'blkif_unmap' on error. */ + again: /* Supply the information about the device the frontend needs */ err = xenbus_transaction_start(); @@ -109,14 +118,6 @@ if (err) { xenbus_dev_error(be->dev, err, "writing %s/sector-size", be->dev->nodename); - goto abort; - } - - /* Map the shared frame, irq etc. */ - err = blkif_map(be->blkif, ring_ref, evtchn); - if (err) { - xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u", - ring_ref, evtchn); goto abort; } diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Sep 28 20:06:49 2005 @@ -57,10 +57,7 @@ #define MAXIMUM_OUTSTANDING_BLOCK_REQS \ (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE) -#define GRANTREF_INVALID (1<<15) -#define GRANT_INVALID_REF (0xFFFF) - -static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */ +#define GRANT_INVALID_REF 0 static void kick_pending_request_queues(struct blkfront_info *info); @@ -82,18 +79,6 @@ info->shadow[id].req.id = info->shadow_free; info->shadow[id].request = 0; info->shadow_free = id; -} - -static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r) -{ - - s->req = *r; -} - -static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s) -{ - - *r = s->req; } static inline void flush_requests(struct blkfront_info *info) @@ -235,7 +220,7 @@ rq_data_dir(req) ); info->shadow[id].frame[ring_req->nr_segments] = - buffer_mfn; + mfn_to_pfn(buffer_mfn); ring_req->frame_and_sects[ring_req->nr_segments] = blkif_fas_from_gref(ref, fsect, lsect); @@ -247,7 +232,7 @@ info->ring.req_prod_pvt++; /* Keep a private copy so we can reissue requests when recovering. */ - pickle_request(&info->shadow[id], ring_req); + info->shadow[id].req = *ring_req; gnttab_free_grant_references(gref_head); @@ -312,7 +297,7 @@ spin_lock_irqsave(&blkif_io_lock, flags); - if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) { + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } @@ -401,36 +386,30 @@ if (copy[i].request == 0) continue; - /* Grab a request slot and unpickle shadow state into it. */ + /* Grab a request slot and copy shadow state into it. */ req = RING_GET_REQUEST( &info->ring, info->ring.req_prod_pvt); - unpickle_request(req, ©[i]); + *req = copy[i].req; /* We get a new request id, and must reset the shadow state. */ req->id = GET_ID_FROM_FREELIST(info); memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i])); /* Rewrite any grant references invalidated by susp/resume. */ - for (j = 0; j < req->nr_segments; j++) { - if ( req->frame_and_sects[j] & GRANTREF_INVALID ) - gnttab_grant_foreign_access_ref( - blkif_gref_from_fas( - req->frame_and_sects[j]), - info->backend_id, - info->shadow[req->id].frame[j], - rq_data_dir( - (struct request *) - info->shadow[req->id].request)); - req->frame_and_sects[j] &= ~GRANTREF_INVALID; - } + for (j = 0; j < req->nr_segments; j++) + gnttab_grant_foreign_access_ref( + blkif_gref_from_fas(req->frame_and_sects[j]), + info->backend_id, + pfn_to_mfn(info->shadow[req->id].frame[j]), + rq_data_dir( + (struct request *) + info->shadow[req->id].request)); info->shadow[req->id].req = *req; info->ring.req_prod_pvt++; } kfree(copy); - - recovery = 0; /* info->ring->req_prod will be set when we flush_requests().*/ wmb(); @@ -438,7 +417,7 @@ /* Kicks things back into life. */ flush_requests(info); - /* Now safe to left other people use the interface. */ + /* Now safe to let other people use the interface. */ info->connected = BLKIF_STATE_CONNECTED; } @@ -591,17 +570,6 @@ goto abort_transaction; } - info->backend = backend; - backend = NULL; - - info->watch.node = info->backend; - info->watch.callback = watch_for_status; - err = register_xenbus_watch(&info->watch); - if (err) { - message = "registering watch on backend"; - goto abort_transaction; - } - err = xenbus_transaction_end(0); if (err) { if (err == -EAGAIN) @@ -610,10 +578,17 @@ goto destroy_blkring; } - out: - if (backend) - kfree(backend); - return err; + info->watch.node = backend; + info->watch.callback = watch_for_status; + err = register_xenbus_watch(&info->watch); + if (err) { + message = "registering watch on backend"; + goto destroy_blkring; + } + + info->backend = backend; + + return 0; abort_transaction: xenbus_transaction_end(1); @@ -621,7 +596,10 @@ xenbus_dev_error(dev, err, "%s", message); destroy_blkring: blkif_free(info); - goto out; + out: + if (backend) + kfree(backend); + return err; } /* Setup supplies the backend dir, virtual device. @@ -702,7 +680,6 @@ kfree(info->backend); info->backend = NULL; - recovery = 1; blkif_free(info); return 0; diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Sep 28 20:06:49 2005 @@ -21,8 +21,6 @@ #include <asm-xen/xen-public/grant_table.h> #include <asm-xen/gnttab.h> #include <asm-xen/driver_util.h> - -#define GRANT_INVALID_REF (0xFFFF) #if 0 #define ASSERT(_p) \ diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Sep 28 20:06:49 2005 @@ -434,7 +434,6 @@ gop->host_addr = MMAP_VADDR(pending_idx); gop->dev_bus_addr = 0; gop->handle = grant_tx_ref[pending_idx]; - grant_tx_ref[pending_idx] = GRANT_INVALID_REF; gop++; } BUG_ON(HYPERVISOR_grant_table_op( diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Sep 28 20:06:49 2005 @@ -1,7 +1,7 @@ /****************************************************************************** * Virtual network driver for conversing with remote driver backends. * - * Copyright (c) 2002-2004, K A Fraser + * Copyright (c) 2002-2005, K A Fraser * * This file may be distributed separately from the Linux kernel, or * incorporated into other software packages, subject to the following license: @@ -57,7 +57,7 @@ #include <asm-xen/xen-public/grant_table.h> #include <asm-xen/gnttab.h> -#define GRANT_INVALID_REF (0xFFFF) +#define GRANT_INVALID_REF 0 #ifndef __GFP_NOWARN #define __GFP_NOWARN 0 @@ -700,6 +700,7 @@ struct net_private *np; int i, requeue_idx; netif_tx_request_t *tx; + struct sk_buff *skb; np = netdev_priv(dev); spin_lock_irq(&np->tx_lock); @@ -711,7 +712,8 @@ np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0; np->rx->event = np->tx->event = 1; - /* Step 2: Rebuild the RX and TX ring contents. + /* + * Step 2: Rebuild the RX and TX ring contents. * NB. We could just free the queued TX packets now but we hope * that sending them out might do some good. We have to rebuild * the RX ring because some of our pages are currently flipped out @@ -722,49 +724,52 @@ * them. */ - /* Rebuild the TX buffer freelist and the TX ring itself. + /* + * Rebuild the TX buffer freelist and the TX ring itself. * NB. This reorders packets. We could keep more private state * to avoid this but maybe it doesn't matter so much given the * interface has been down. */ for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) { - if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) { - struct sk_buff *skb = np->tx_skbs[i]; - - tx = &np->tx->ring[requeue_idx++].req; - - tx->id = i; - gnttab_grant_foreign_access_ref( - np->grant_tx_ref[i], np->backend_id, - virt_to_mfn(np->tx_skbs[i]->data), - GNTMAP_readonly); - tx->gref = np->grant_tx_ref[i]; - tx->offset = (unsigned long)skb->data & ~PAGE_MASK; - tx->size = skb->len; - - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; - } + if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET) + continue; + + skb = np->tx_skbs[i]; + + tx = &np->tx->ring[requeue_idx++].req; + + tx->id = i; + gnttab_grant_foreign_access_ref( + np->grant_tx_ref[i], np->backend_id, + virt_to_mfn(np->tx_skbs[i]->data), + GNTMAP_readonly); + tx->gref = np->grant_tx_ref[i]; + tx->offset = (unsigned long)skb->data & ~PAGE_MASK; + tx->size = skb->len; + tx->csum_blank = (skb->ip_summed == CHECKSUM_HW); + + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; } wmb(); np->tx->req_prod = requeue_idx; /* Rebuild the RX buffer freelist and the RX ring itself. */ for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { - if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) { - gnttab_grant_foreign_transfer_ref( - np->grant_rx_ref[i], np->backend_id); - np->rx->ring[requeue_idx].req.gref = - np->grant_rx_ref[i]; - np->rx->ring[requeue_idx].req.id = i; - requeue_idx++; - } - } - + if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET) + continue; + gnttab_grant_foreign_transfer_ref( + np->grant_rx_ref[i], np->backend_id); + np->rx->ring[requeue_idx].req.gref = + np->grant_rx_ref[i]; + np->rx->ring[requeue_idx].req.id = i; + requeue_idx++; + } wmb(); np->rx->req_prod = requeue_idx; - /* Step 3: All public and private state should now be sane. Get + /* + * Step 3: All public and private state should now be sane. Get * ready to start sending and receiving packets and give the driver * domain a kick because we've probably just requeued some * packets. @@ -798,7 +803,8 @@ #endif } -/* Move the vif into connected state. +/* + * Move the vif into connected state. * Sets the mac and event channel from the message. * Binds the irq to the event channel. */ @@ -1053,8 +1059,7 @@ info->evtchn = 0; } -/* Stop network device and free tx/rx queues and irq. - */ +/* Stop network device and free tx/rx queues and irq. */ static void shutdown_device(struct net_private *np) { /* Stop old i/f to prevent errors whilst we rebuild the state. */ @@ -1148,17 +1153,6 @@ goto abort_transaction; } - info->backend = backend; - backend = NULL; - - info->watch.node = info->backend; - info->watch.callback = watch_for_status; - err = register_xenbus_watch(&info->watch); - if (err) { - message = "registering watch on backend"; - goto abort_transaction; - } - err = xenbus_transaction_end(0); if (err) { if (err == -EAGAIN) @@ -1167,12 +1161,19 @@ goto destroy_ring; } + info->watch.node = backend; + info->watch.callback = watch_for_status; + err = register_xenbus_watch(&info->watch); + if (err) { + message = "registering watch on backend"; + goto destroy_ring; + } + + info->backend = backend; + netif_state = NETIF_STATE_CONNECTED; - out: - if (backend) - kfree(backend); - return err; + return 0; abort_transaction: xenbus_transaction_end(1); @@ -1180,13 +1181,17 @@ xenbus_dev_error(dev, err, "%s", message); destroy_ring: shutdown_device(info); - goto out; -} - -/* Setup supplies the backend dir, virtual device. - - We place an event channel and shared frame entries. - We watch backend to wait if it's ok. */ + out: + if (backend) + kfree(backend); + return err; +} + +/* + * Setup supplies the backend dir, virtual device. + * We place an event channel and shared frame entries. + * We watch backend to wait if it's ok. + */ static int netfront_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Sep 28 20:06:49 2005 @@ -88,6 +88,26 @@ return; } + err = tpmif_map(be->tpmif, ringref, evtchn); + if (err) { + xenbus_dev_error(be->dev, err, + "mapping shared-frame %lu port %u", + ringref, evtchn); + return; + } + + err = tpmif_vtpm_open(be->tpmif, + be->frontend_id, + be->instance); + if (err) { + xenbus_dev_error(be->dev, err, + "queueing vtpm open packet"); + /* + * Should close down this device and notify FE + * about closure. + */ + return; + } /* * Tell the front-end that we are ready to go - @@ -104,27 +124,6 @@ "ready", "%lu", ready); if (err) { xenbus_dev_error(be->dev, err, "writing 'ready'"); - goto abort; - } - - err = tpmif_map(be->tpmif, ringref, evtchn); - if (err) { - xenbus_dev_error(be->dev, err, - "mapping shared-frame %lu port %u", - ringref, evtchn); - goto abort; - } - - err = tpmif_vtpm_open(be->tpmif, - be->frontend_id, - be->instance); - if (err) { - xenbus_dev_error(be->dev, err, - "queueing vtpm open packet"); - /* - * Should close down this device and notify FE - * about closure. - */ goto abort; } diff -r 4e1031ce3bc2 -r 5e5ae8340956 linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Mon Sep 26 17:15:55 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Wed Sep 28 20:06:49 2005 @@ -352,17 +352,6 @@ goto abort_transaction; } - info->backend = backend; - backend = NULL; - - info->watch.node = info->backend; - info->watch.callback = watch_for_status; - err = register_xenbus_watch(&info->watch); - if (err) { - message = "registering watch on backend"; - goto abort_transaction; - } - err = xenbus_transaction_end(0); if (err == -EAGAIN) goto again; @@ -371,10 +360,17 @@ goto destroy_tpmring; } -out: - if (backend) - kfree(backend); - return err; + info->watch.node = backend; + info->watch.callback = watch_for_status; + err = register_xenbus_watch(&info->watch); + if (err) { + message = "registering watch on backend"; + goto destroy_tpmring; + } + + info->backend = backend; + + return 0; abort_transaction: xenbus_transaction_end(1); @@ -382,7 +378,10 @@ xenbus_dev_error(dev, err, "%s", message); destroy_tpmring: destroy_tpmring(info, &my_private); - goto out; +out: + if (backend) + kfree(backend); + return err; } diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Sep 26 17:15:55 2005 +++ b/tools/console/daemon/io.c Wed Sep 28 20:06:49 2005 @@ -399,7 +399,7 @@ while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { dom = lookup_domain(dominfo.domid); - if (dominfo.dying || dominfo.crashed || dominfo.shutdown) { + if (dominfo.dying) { if (dom) shutdown_domain(dom); } else { diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/gen.c --- a/tools/firmware/vmxassist/gen.c Mon Sep 26 17:15:55 2005 +++ b/tools/firmware/vmxassist/gen.c Wed Sep 28 20:06:49 2005 @@ -23,7 +23,7 @@ #include <vm86.h> int -main() +main(void) { printf("/* MACHINE GENERATED; DO NOT EDIT */\n"); printf("#define VMX_ASSIST_CTX_GS_SEL 0x%x\n", diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/head.S --- a/tools/firmware/vmxassist/head.S Mon Sep 26 17:15:55 2005 +++ b/tools/firmware/vmxassist/head.S Wed Sep 28 20:06:49 2005 @@ -110,6 +110,10 @@ _start: cli + /* save register parameters to C land */ + movl %edx, booting_cpu + movl %ebx, booting_vector + /* clear bss */ cld xorb %al, %al @@ -128,7 +132,6 @@ /* go ... */ call main jmp halt - /* * Something bad happened, print invoking %eip and loop forever diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/setup.c --- a/tools/firmware/vmxassist/setup.c Mon Sep 26 17:15:55 2005 +++ b/tools/firmware/vmxassist/setup.c Wed Sep 28 20:06:49 2005 @@ -29,6 +29,9 @@ #define min(a, b) ((a) > (b) ? (b) : (a)) +/* Which CPU are we booting, and what is the initial CS segment? */ +int booting_cpu, booting_vector; + unsigned long long gdt[] __attribute__ ((aligned(32))) = { 0x0000000000000000ULL, /* 0x00: reserved */ 0x0000890000000000ULL, /* 0x08: 32-bit TSS */ @@ -201,12 +204,17 @@ initialize_real_mode = 0; regs->eflags |= EFLAGS_VM | 0x02; regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000; - regs->cs = 0xF000; /* ROM BIOS POST entry point */ -#ifdef TEST - regs->eip = 0xFFE0; + if (booting_cpu == 0) { + regs->cs = 0xF000; /* ROM BIOS POST entry point */ +#ifdef TEST + regs->eip = 0xFFE0; #else - regs->eip = 0xFFF0; -#endif + regs->eip = 0xFFF0; +#endif + } else { + regs->cs = booting_vector << 8; /* AP entry point */ + regs->eip = 0; + } regs->uesp = 0; regs->uss = 0; printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n", @@ -215,8 +223,8 @@ mode = VM86_REAL; /* becomes previous mode */ set_mode(regs, VM86_REAL); - /* this should get us into 16-bit mode */ - return; + /* this should get us into 16-bit mode */ + return; } else { /* go from protected to real mode */ regs->eflags |= EFLAGS_VM; @@ -334,7 +342,12 @@ { unsigned long cr0; - printf("Start BIOS ...\n"); + if (booting_cpu == 0) + printf("Start BIOS ...\n"); + else + printf("Start AP %d from %08x ...\n", + booting_cpu, booting_vector << 12); + initialize_real_mode = 1; cr0 = get_cr0(); #ifndef TEST @@ -345,20 +358,28 @@ } int -main() -{ - banner(); +main(void) +{ + if (booting_cpu == 0) + banner(); + #ifdef TEST setup_paging(); #endif + setup_gdt(); setup_idt(); + #ifndef TEST - set_cr4(get_cr4() | CR4_VME); -#endif + set_cr4(get_cr4() | CR4_VME); +#endif + setup_ctx(); - setup_pic(); + + if (booting_cpu == 0) + setup_pic(); + start_bios(); + return 0; } - diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Mon Sep 26 17:15:55 2005 +++ b/tools/firmware/vmxassist/vm86.c Wed Sep 28 20:06:49 2005 @@ -752,6 +752,9 @@ goto invalid; } break; + case 0x09: /* wbinvd */ + asm volatile ( "wbinvd" ); + return OPC_EMULATED; case 0x20: /* mov Rd, Cd (1h) */ case 0x22: if (!movcr(regs, prefix, opc)) diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/firmware/vmxassist/vmxloader.c --- a/tools/firmware/vmxassist/vmxloader.c Mon Sep 26 17:15:55 2005 +++ b/tools/firmware/vmxassist/vmxloader.c Wed Sep 28 20:06:49 2005 @@ -132,11 +132,12 @@ memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi)); } #endif - + puts("Loading VMXAssist ...\n"); memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist)); + puts("Go ...\n"); - ((void (*)())TEXTADDR)(); + asm volatile ( "jmp *%%eax" : : "a" (TEXTADDR), "d" (0) ); + return 0; } - diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon Sep 26 17:15:55 2005 +++ b/tools/ioemu/vl.c Wed Sep 28 20:06:49 2005 @@ -2385,7 +2385,8 @@ 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) { l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; - l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL; + l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL}; + l2_pgentry_t *vl2e=NULL, *vl2_table = NULL; unsigned long l1tab; unsigned long ppt_alloc = 0; unsigned long count; diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/web/SrvBase.py --- a/tools/python/xen/web/SrvBase.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/web/SrvBase.py Wed Sep 28 20:06:49 2005 @@ -81,7 +81,14 @@ req.write("Operation not implemented: " + op) return '' else: - return op_method(op, req) + try: + return op_method(op, req) + except Exception, exn: + log.exception("Request %s failed.", op) + if req.useSxp(): + return ['xend.err', "Exception: " + str(exn)] + else: + return "<p>%s</p>" % str(exn) def print_path(self, req): """Print the path with hyperlinks. diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/web/http.py --- a/tools/python/xen/web/http.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/web/http.py Wed Sep 28 20:06:49 2005 @@ -22,6 +22,7 @@ from mimetools import Message from cStringIO import StringIO import math +import socket import time import cgi diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/PrettyPrint.py --- a/tools/python/xen/xend/PrettyPrint.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/PrettyPrint.py Wed Sep 28 20:06:49 2005 @@ -39,9 +39,9 @@ print '***PrettyItem>output>', self pass - def prettyprint(self, _, width): + def prettyprint(self, _): print '***PrettyItem>prettyprint>', self - return width + return self.width class PrettyString(PrettyItem): @@ -52,7 +52,7 @@ def output(self, out): out.write(self.value) - def prettyprint(self, line, _): + def prettyprint(self, line): line.output(self) def show(self, out): @@ -63,7 +63,7 @@ def output(self, out): out.write(' ' * self.width) - def prettyprint(self, line, _): + def prettyprint(self, line): line.output(self) def show(self, out): @@ -80,7 +80,7 @@ def output(self, out): out.write(' ' * self.width) - def prettyprint(self, line, _): + def prettyprint(self, line): if line.breaks(self.space): self.active = 1 line.newline(self.indent) @@ -97,7 +97,7 @@ block.newline() block.addtoline(self) - def prettyprint(self, line, _): + def prettyprint(self, line): line.newline(0) line.output(self) @@ -127,7 +127,7 @@ lastbreak.space = (width - lastwidth) self.width = width - def prettyprint(self, line, _): + def prettyprint(self, line): for x in self.content: x.prettyprint(line) @@ -168,7 +168,7 @@ def addtoline(self, x): self.lines[-1].write(x) - def prettyprint(self, line, _): + def prettyprint(self, line): self.indent = line.used line.block = self if not line.fits(self.width): @@ -252,7 +252,7 @@ self.block = self.block.parent def prettyprint(self, out=sys.stdout): - self.top.prettyprint(Line(out, self.width), self.width) + self.top.prettyprint(Line(out, self.width)) class SXPPrettyPrinter(PrettyPrinter): """An SXP prettyprinter. diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Sep 28 20:06:49 2005 @@ -10,8 +10,12 @@ import sxp from string import join from struct import pack, unpack, calcsize + from xen.util.xpopen import xPopen3 + import xen.lowlevel.xc + +import XendDomainInfo from xen.xend.xenstore.xsutil import IntroduceDomain from XendError import XendError @@ -74,7 +78,7 @@ if l.rstrip() == "suspend": log.info("suspending %d" % dominfo.domid) xd.domain_shutdown(dominfo.domid, reason='suspend') - dominfo.state_wait("suspended") + dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED) log.info("suspend %d done" % dominfo.domid) child.tochild.write("done\n") child.tochild.flush() diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendClient.py --- a/tools/python/xen/xend/XendClient.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/XendClient.py Wed Sep 28 20:06:49 2005 @@ -302,12 +302,6 @@ {'op' : 'devices', 'type' : type }) - def xend_domain_device(self, id, type, idx): - return self.xendPost(self.domainurl(id), - {'op' : 'device', - 'type' : type, - 'idx' : idx }) - def xend_domain_device_create(self, id, config): return self.xendPost(self.domainurl(id), {'op' : 'device_create', diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/XendDomain.py Wed Sep 28 20:06:49 2005 @@ -28,16 +28,11 @@ from xen.xend import sxp from xen.xend import XendRoot from xen.xend import XendCheckpoint -from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason +from xen.xend.XendDomainInfo import XendDomainInfo from xen.xend import EventServer from xen.xend.XendError import XendError from xen.xend.XendLogging import log -from xen.xend import scheduler from xen.xend.server import relocate -from xen.xend.uuid import getUuid -from xen.xend.xenstore import XenNode, DBMap -from xen.xend.xenstore.xstransact import xstransact -from xen.xend.xenstore.xsutil import GetDomainPath xc = xen.lowlevel.xc.new() @@ -47,14 +42,7 @@ __all__ = [ "XendDomain" ] -SHUTDOWN_TIMEOUT = 30 -PRIV_DOMAIN = 0 - -def is_dead(dom): - return dom['crashed'] or dom['shutdown'] or ( - dom['dying'] and not(dom['running'] or dom['paused'] or - dom['blocked'])) - +PRIV_DOMAIN = 0 class XendDomainDict(dict): def get_by_name(self, name): @@ -77,11 +65,8 @@ # So we stuff the XendDomain instance (self) into xroot's components. xroot.add_component("xen.xend.XendDomain", self) self.domains = XendDomainDict() - self.domroot = "/domain" - self.vmroot = "/domain" - self.dbmap = DBMap(db=XenNode(self.vmroot)) self.watchReleaseDomain() - self.initial_refresh() + self.refresh() self.dom0_setup() def list(self): @@ -110,9 +95,7 @@ return map(lambda x: x.getName(), doms) def onReleaseDomain(self): - self.reap() self.refresh() - self.domain_restarts() def watchReleaseDomain(self): from xen.xend.xenstore.xswatch import xswatch @@ -141,43 +124,22 @@ dominfo = dominfo[0] return dominfo - def initial_refresh(self): - """Refresh initial domain info from db. - """ - doms = self.xen_domains() - self.dbmap.readDB() # XXX only needed for "xend" - for dom in doms.values(): - domid = dom['dom'] - dompath = GetDomainPath(domid) - if not dompath: - continue - vmpath = xstransact.Read(dompath, "vm") - if not vmpath: - continue - uuid = xstransact.Read(vmpath, "uuid") - if not uuid: - continue - log.info("recreating domain %d, uuid %s" % (domid, uuid)) - dompath = "/".join(dompath.split("/")[0:-1]) - try: - dominfo = XendDomainInfo.recreate(uuid, dompath, domid, dom) - except Exception, ex: - log.exception("Error recreating domain info: id=%d", domid) - continue - self._add_domain(dominfo) - self.reap() - self.refresh() - self.domain_restarts() + + def recreate_domain(self, xeninfo): + """Refresh initial domain info from db.""" + + dominfo = XendDomainInfo.recreate(xeninfo) + self._add_domain(dominfo) + return dominfo + def dom0_setup(self): dom0 = self.domain_lookup(PRIV_DOMAIN) if not dom0: - dom0 = self.dom0_unknown() - dom0.dom0_init_store() + dom0 = self.recreate_domain(self.xen_domain(PRIV_DOMAIN)) + dom0.dom0_init_store() dom0.dom0_enforce_vcpus() - def close(self): - pass def _add_domain(self, info, notify=True): """Add a domain entry to the tables. @@ -193,70 +155,45 @@ eserver.inject('xend.domain.create', [info.getName(), info.getDomid()]) - def _delete_domain(self, id, notify=True): + def _delete_domain(self, domid, notify=True): """Remove a domain from the tables. @param id: domain id @param notify: send a domain died event if true """ - info = self.domains.get(id) + info = self.domains.get(domid) if info: - del self.domains[id] + del self.domains[domid] info.cleanup() info.delete() if notify: eserver.inject('xend.domain.died', [info.getName(), info.getDomid()]) - # XXX this should not be needed - for domdb in self.dbmap.values(): - if not domdb.has_key("xend"): - continue - db = domdb.addChild("xend") - try: - domid = int(domdb["domid"].getData()) - except: - domid = None - if (domid is None) or (domid == id): - domdb.delete() - - def reap(self): - """Look for domains that have crashed or stopped. - Tidy them up. - """ - doms = self.xen_domains() - for d in doms.values(): - if not is_dead(d): - continue - domid = d['dom'] - dominfo = self.domains.get(domid) - if not dominfo or dominfo.is_terminated(): - continue - log.debug('domain died name=%s domid=%d', dominfo.getName(), domid) - if d['crashed'] and xroot.get_enable_dump(): - self.domain_dumpcore(domid) - if d['shutdown']: - reason = shutdown_reason(d['shutdown_reason']) - log.debug('shutdown name=%s id=%d reason=%s', - dominfo.getName(), domid, reason) - if reason == 'suspend': - dominfo.state_set("suspended") - continue - if reason in ['poweroff', 'reboot']: - self.domain_restart_schedule(domid, reason) - dominfo.destroy() + def refresh(self): """Refresh domain list from Xen. """ doms = self.xen_domains() - # Remove entries for domains that no longer exist. - # Update entries for existing domains. for d in self.domains.values(): info = doms.get(d.getDomid()) if info: d.update(info) - elif not d.restart_pending(): + else: self._delete_domain(d.getDomid()) + for d in doms: + if d not in self.domains: + try: + self.recreate_domain(doms[d]) + except: + log.exception( + "Failed to recreate information for domain %d. " + "Destroying it in the hope of recovery.", d) + try: + xc.domain_destroy(dom = d) + except: + log.exception('Destruction of %d failed.', d) + def update_domain(self, id): """Update information for a single domain. @@ -277,32 +214,8 @@ @param config: configuration @return: domain """ - dominfo = XendDomainInfo.create(self.dbmap.getPath(), config) + dominfo = XendDomainInfo.create(config) self._add_domain(dominfo) - return dominfo - - def domain_restart(self, dominfo): - """Restart a domain. - - @param dominfo: domain object - """ - log.info("Restarting domain: name=%s id=%s", dominfo.getName(), - dominfo.getDomid()) - eserver.inject("xend.domain.restart", - [dominfo.getName(), dominfo.getDomid(), "begin"]) - try: - dominfo.restart() - log.info('Restarted domain name=%s id=%s', dominfo.getName(), - dominfo.getDomid()) - eserver.inject("xend.domain.restart", - [dominfo.getName(), dominfo.getDomid(), - "success"]) - self.domain_unpause(dominfo.getDomid()) - except Exception, ex: - log.exception("Exception restarting domain: name=%s id=%s", - dominfo.getName(), dominfo.getDomid()) - eserver.inject("xend.domain.restart", - [dominfo.getName(), dominfo.getDomid(), "fail"]) return dominfo def domain_configure(self, config): @@ -318,13 +231,12 @@ nested = sxp.child_value(config, 'config') if nested: config = nested - return XendDomainInfo.restore(self.dbmap.getPath(), config) - - def domain_restore(self, src, progress=False): + return XendDomainInfo.restore(config) + + def domain_restore(self, src): """Restore a domain from file. @param src: source file - @param progress: output progress if true """ try: @@ -345,33 +257,7 @@ self.update_domain(id) return self.domains.get(id) - def dom0_unknown(self): - dom0 = PRIV_DOMAIN - uuid = None - info = self.xen_domain(dom0) - dompath = GetDomainPath(dom0) - if dompath: - vmpath = xstransact.Read(dompath, "vm") - if vmpath: - uuid = xstransact.Read(vmpath, "uuid") - if not uuid: - uuid = dompath.split("/")[-1] - dompath = "/".join(dompath.split("/")[0:-1]) - if not uuid: - uuid = getUuid() - dompath = self.domroot - log.info("Creating entry for unknown xend domain: id=%d uuid=%s", - dom0, uuid) - try: - dominfo = XendDomainInfo.recreate(uuid, dompath, dom0, info) - self._add_domain(dominfo) - return dominfo - except Exception, exn: - log.exception(exn) - raise XendError("Error recreating xend domain info: id=%d: %s" % - (dom0, str(exn))) - - + def domain_lookup(self, id): return self.domains.get(id) @@ -410,8 +296,9 @@ return xc.domain_pause(dom=dominfo.getDomid()) except Exception, ex: raise XendError(str(ex)) - - def domain_shutdown(self, id, reason='poweroff'): + + + def domain_shutdown(self, domid, reason='poweroff'): """Shutdown domain (nicely). - poweroff: restart according to exit code and restart mode - reboot: restart on exit @@ -422,89 +309,13 @@ @param id: domain id @param reason: shutdown type: poweroff, reboot, suspend, halt """ - dominfo = self.domain_lookup(id) - self.domain_restart_schedule(dominfo.getDomid(), reason, force=True) - eserver.inject('xend.domain.shutdown', [dominfo.getName(), - dominfo.getDomid(), reason]) - if reason == 'halt': - reason = 'poweroff' - val = dominfo.shutdown(reason) - if not reason in ['suspend']: - self.domain_shutdowns() - return val - - - def domain_sysrq(self, id, key): + self.callInfo(domid, XendDomainInfo.shutdown, reason) + + + def domain_sysrq(self, domid, key): """Send a SysRq to the specified domain.""" - return self.callInfo(id, XendDomainInfo.send_sysrq, key) - - - def domain_shutdowns(self): - """Process pending domain shutdowns. - Destroys domains whose shutdowns have timed out. - """ - timeout = SHUTDOWN_TIMEOUT + 1 - for dominfo in self.domains.values(): - if not dominfo.shutdown_pending: - # domain doesn't need shutdown - continue - id = dominfo.getDomid() - left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT) - if left <= 0: - # Shutdown expired - destroy domain. - try: - log.info("Domain shutdown timeout expired: name=%s id=%s", - dominfo.getName(), id) - self.domain_destroy(id, reason= - dominfo.shutdown_pending['reason']) - except Exception: - pass - else: - # Shutdown still pending. - timeout = min(timeout, left) - if timeout <= SHUTDOWN_TIMEOUT: - # Pending shutdowns remain - reschedule. - scheduler.later(timeout, self.domain_shutdowns) - - def domain_restart_schedule(self, id, reason, force=False): - """Schedule a restart for a domain if it needs one. - - @param id: domain id - @param reason: shutdown reason - """ - log.debug('domain_restart_schedule> %d %s %d', id, reason, force) - dominfo = self.domain_lookup(id) - if not dominfo: - return - restart = (force and reason == 'reboot') or dominfo.restart_needed(reason) - if restart: - log.info('Scheduling restart for domain: name=%s id=%s', - dominfo.getName(), dominfo.getDomid()) - eserver.inject("xend.domain.restart", - [dominfo.getName(), dominfo.getDomid(), - "schedule"]) - dominfo.restarting() - else: - log.info('Cancelling restart for domain: name=%s id=%s', - dominfo.getName(), dominfo.getDomid()) - eserver.inject("xend.domain.restart", - [dominfo.getName(), dominfo.getDomid(), "cancel"]) - dominfo.restart_cancel() - - def domain_restarts(self): - """Execute any scheduled domain restarts for domains that have gone. - """ - doms = self.xen_domains() - for dominfo in self.domains.values(): - if not dominfo.restart_pending(): - continue - info = doms.get(dominfo.getDomid()) - if info: - # Don't execute restart for domains still running. - continue - # Remove it from the restarts. - log.info('restarting: %s' % dominfo.getName()) - self.domain_restart(dominfo) + return self.callInfo(domid, XendDomainInfo.send_sysrq, key) + def domain_destroy(self, domid, reason='halt'): """Terminate domain immediately. @@ -517,7 +328,6 @@ if domid == PRIV_DOMAIN: raise XendError("Cannot destroy privileged domain %i" % domid) - self.domain_restart_schedule(domid, reason, force=True) dominfo = self.domain_lookup(domid) if dominfo: val = dominfo.destroy() @@ -554,12 +364,11 @@ return None - def domain_save(self, id, dst, progress=False): + def domain_save(self, id, dst): """Start saving a domain to file. @param id: domain id @param dst: destination file - @param progress: output progress if true """ try: @@ -659,14 +468,6 @@ def domain_devtype_ls(self, domid, devtype): """Get list of device sxprs for the specified domain.""" return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype) - - - def domain_devtype_get(self, domid, devtype, devid): - """Get a device from a domain. - - @return: device object (or None) - """ - return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid) def domain_vif_limit_set(self, id, vif, credit, period): @@ -730,10 +531,16 @@ ## private: def callInfo(self, domid, fn, *args, **kwargs): - self.refresh() - dominfo = self.domains.get(domid) - if dominfo: - return fn(dominfo, *args, **kwargs) + try: + self.refresh() + dominfo = self.domains.get(domid) + if dominfo: + return fn(dominfo, *args, **kwargs) + except XendError: + raise + except Exception, exn: + log.exception("") + raise XendError(str(exn)) def instance(): diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Sep 28 20:06:49 2005 @@ -35,7 +35,9 @@ from xen.xend.server.channel import EventChannel from xen.xend import image +from xen.xend import scheduler from xen.xend import sxp +from xen.xend import XendRoot from xen.xend.XendBootloader import bootloader from xen.xend.XendLogging import log from xen.xend.XendError import XendError, VmError @@ -43,7 +45,7 @@ from xen.xend.uuid import getUuid from xen.xend.xenstore.xstransact import xstransact -from xen.xend.xenstore.xsutil import IntroduceDomain +from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain """Shutdown code for poweroff.""" DOMAIN_POWEROFF = 0 @@ -75,9 +77,6 @@ RESTART_NEVER, ] -STATE_RESTART_PENDING = 'pending' -STATE_RESTART_BOOTING = 'booting' - STATE_VM_OK = "ok" STATE_VM_TERMINATED = "terminated" STATE_VM_SUSPENDED = "suspended" @@ -92,7 +91,29 @@ SIF_TPM_BE_DOMAIN = (1<<7) +SHUTDOWN_TIMEOUT = 30 + + +DOMROOT = '/domain' +VMROOT = '/domain' + + xc = xen.lowlevel.xc.new() +xroot = XendRoot.instance() + + +## Configuration entries that we expect to round-trip -- be read from the +# config file or xc, written to save-files (i.e. through sxpr), and reused as +# config on restart or restore, all without munging. Some configuration +# entries are munged for backwards compatibility reasons, or because they +# don't come out of xc in the same form as they are specified in the config +# file, so those are handled separately. +ROUNDTRIPPING_CONFIG_ENTRIES = [ + ('name', str), + ('ssidref', int), + ('cpu_weight', float), + ('bootloader', str) + ] def domain_exists(name): @@ -133,47 +154,64 @@ MINIMUM_RESTART_TIME = 20 - def create(cls, dompath, config): + def create(cls, config): """Create a VM from a configuration. - @param dompath: The path to all domain information @param config configuration @raise: VmError for invalid configuration """ - log.debug("XendDomainInfo.create(%s, ...)", dompath) + log.debug("XendDomainInfo.create(...)") - vm = cls(getUuid(), dompath, cls.parseConfig(config)) + vm = cls(getUuid(), cls.parseConfig(config)) vm.construct() + vm.refreshShutdown() return vm create = classmethod(create) - def recreate(cls, uuid, dompath, domid, info): - """Create the VM object for an existing domain. - - @param dompath: The path to all domain information - @param info: domain info from xc - """ - - log.debug("XendDomainInfo.recreate(%s, %s, %s, %s)", uuid, dompath, - domid, info) - - return cls(uuid, dompath, info, domid, True) + def recreate(cls, xeninfo): + """Create the VM object for an existing domain.""" + + log.debug("XendDomainInfo.recreate(%s)", xeninfo) + + domid = xeninfo['dom'] + try: + dompath = GetDomainPath(domid) + if not dompath: + raise XendError( + 'No domain path in store for existing domain %d' % domid) + vmpath = xstransact.Read(dompath, "vm") + if not vmpath: + raise XendError( + 'No vm path in store for existing domain %d' % domid) + uuid = xstransact.Read(vmpath, "uuid") + if not uuid: + raise XendError( + 'No vm/uuid path in store for existing domain %d' % domid) + + except Exception, exn: + log.warn(str(exn)) + uuid = getUuid() + + log.info("Recreating domain %d, uuid %s", domid, uuid) + + vm = cls(uuid, xeninfo, domid, True) + vm.refreshShutdown(xeninfo) + return vm recreate = classmethod(recreate) - def restore(cls, dompath, config, uuid = None): + def restore(cls, config, uuid = None): """Create a domain and a VM object to do a restore. - @param dompath: The path to all domain information @param config: domain configuration @param uuid: uuid to use """ - log.debug("XendDomainInfo.restore(%s, %s, %s)", dompath, config, uuid) + log.debug("XendDomainInfo.restore(%s, %s)", config, uuid) if not uuid: uuid = getUuid() @@ -183,14 +221,12 @@ except TypeError, exn: raise VmError('Invalid ssidref in config: %s' % exn) - log.debug('restoring with ssidref = %d' % ssidref) - - vm = cls(uuid, dompath, cls.parseConfig(config), + vm = cls(uuid, cls.parseConfig(config), xc.domain_create(ssidref = ssidref)) - vm.clear_shutdown() vm.create_channel() vm.configure() vm.exportToDB() + vm.refreshShutdown() return vm restore = classmethod(restore) @@ -214,33 +250,28 @@ log.debug("parseConfig: config is %s" % str(config)) result = {} - imagecfg = "()" - - result['name'] = get_cfg('name') - result['ssidref'] = get_cfg('ssidref', int) + + for e in ROUNDTRIPPING_CONFIG_ENTRIES: + result[e[0]] = get_cfg(e[0], e[1]) + result['memory'] = get_cfg('memory', int) result['mem_kb'] = get_cfg('mem_kb', int) result['maxmem'] = get_cfg('maxmem', int) result['maxmem_kb'] = get_cfg('maxmem_kb', int) result['cpu'] = get_cfg('cpu', int) - result['cpu_weight'] = get_cfg('cpu_weight', float) - result['bootloader'] = get_cfg('bootloader') result['restart_mode'] = get_cfg('restart') + result['image'] = get_cfg('image') try: - imagecfg = get_cfg('image') - - if imagecfg: - result['image'] = imagecfg - result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus', - 1)) + if result['image']: + result['vcpus'] = int(sxp.child_value(result['image'], + 'vcpus', 1)) else: result['vcpus'] = 1 except TypeError, exn: raise VmError( 'Invalid configuration setting: vcpus = %s: %s' % - (sxp.child_value(imagecfg, 'vcpus', 1), - str(exn))) + (sxp.child_value(result['image'], 'vcpus', 1), str(exn))) result['backend'] = [] for c in sxp.children(config, 'backend'): @@ -258,12 +289,12 @@ parseConfig = classmethod(parseConfig) - def __init__(self, uuid, parentpath, info, domid = None, augment = False): + def __init__(self, uuid, info, domid = None, augment = False): self.uuid = uuid self.info = info - self.path = parentpath + "/" + uuid + self.path = DOMROOT + "/" + uuid if domid: self.domid = domid @@ -283,26 +314,26 @@ self.store_mfn = None self.console_channel = None self.console_mfn = None - - #todo: state: running, suspended + self.state = STATE_VM_OK self.state_updated = threading.Condition() - self.shutdown_pending = None - - self.restart_state = None - self.restart_time = None - self.restart_count = 0 - + self.writeVm("uuid", self.uuid) self.storeDom("vm", self.path) def augmentInfo(self): + """Augment self.info, as given to us through {@link #recreate}, with + values taken from the store. This recovers those values known to xend + but not to the hypervisor. + """ def useIfNeeded(name, val): if not self.infoIsSet(name) and val is not None: self.info[name] = val params = (("name", str), + ("restart-mode", str), + ("image", str), ("start-time", float)) from_store = self.gatherVm(*params) @@ -322,12 +353,17 @@ defaultInfo('name', lambda: "Domain-%d" % self.domid) defaultInfo('ssidref', lambda: 0) defaultInfo('restart_mode', lambda: RESTART_ONREBOOT) + defaultInfo('cpu', lambda: None) defaultInfo('cpu_weight', lambda: 1.0) defaultInfo('bootloader', lambda: None) defaultInfo('backend', lambda: []) defaultInfo('device', lambda: []) + defaultInfo('image', lambda: None) self.check_name(self.info['name']) + + if isinstance(self.info['image'], str): + self.info['image'] = sxp.from_string(self.info['image']) # Internally, we keep only maxmem_KiB, and not maxmem or maxmem_kb # (which come from outside, and are in MiB and KiB respectively). @@ -451,17 +487,16 @@ 'domid': str(self.domid), 'uuid': self.uuid, - 'restart_time': str(self.restart_time), - - 'xend/state': self.state, - 'xend/restart_count': str(self.restart_count), 'xend/restart_mode': str(self.info['restart_mode']), 'memory/target': str(self.info['memory_KiB']) } for (k, v) in self.info.items(): - to_store[k] = str(v) + if v: + to_store[k] = str(v) + + to_store['image'] = sxp.to_string(self.info['image']) log.debug("Storing %s" % str(to_store)) @@ -511,6 +546,88 @@ def getBackendFlags(self): return reduce(lambda x, y: x | backendFlags[y], self.info['backend'], 0) + + + def refreshShutdown(self, xeninfo = None): + if xeninfo is None: + xeninfo = dom_get(self.domid) + if xeninfo is None: + # The domain no longer exists. This will occur if we have + # scheduled a timer to check for shutdown timeouts and the + # shutdown succeeded. + return + + if xeninfo['dying']: + # Dying means that a domain has been destroyed, but has not yet + # been cleaned up by Xen. This could persist indefinitely if, + # for example, another domain has some of its pages mapped. + # We might like to diagnose this problem in the future, but for + # now all we can sensibly do is ignore it. + pass + + elif xeninfo['crashed']: + log.warn('Domain has crashed: name=%s id=%d.', + self.info['name'], self.domid) + + if xroot.get_enable_dump(): + self.dumpCore() + + self.maybeRestart('crashed') + + elif xeninfo['shutdown']: + reason = shutdown_reason(xeninfo['shutdown_reason']) + + log.info('Domain has shutdown: name=%s id=%d reason=%s.', + self.info['name'], self.domid, reason) + + self.clearRestart() + + if reason == 'suspend': + self.state_set(STATE_VM_SUSPENDED) + # Don't destroy the domain. XendCheckpoint will do this once + # it has finished. + elif reason in ['poweroff', 'reboot']: + self.maybeRestart(reason) + else: + self.destroy() + + else: + # Domain is alive. If we are shutting it down, then check + # the timeout on that, and destroy it if necessary. + + sst = self.readVm('xend/shutdown_start_time') + if sst: + sst = float(sst) + timeout = SHUTDOWN_TIMEOUT - time.time() + sst + if timeout < 0: + log.info( + "Domain shutdown timeout expired: name=%s id=%s", + self.info['name'], self.domid) + self.destroy() + else: + log.debug( + "Scheduling refreshShutdown on domain %d in %ds.", + self.domid, timeout) + scheduler.later(timeout, self.refreshShutdown) + + + def shutdown(self, reason): + if not reason in shutdown_reasons.values(): + raise XendError('invalid reason:' + reason) + self.storeVm("control/shutdown", reason) + if not reason == 'suspend': + self.storeVm('xend/shutdown_start_time', time.time()) + + + def clearRestart(self): + self.removeVm("xend/shutdown_start_time") + + + def maybeRestart(self, reason): + if self.restart_needed(reason): + self.restart() + else: + self.destroy() def dumpCore(self): @@ -526,18 +643,32 @@ self.domid, self.info['name'], str(exn)) + def closeChannel(self, channel, entry): + """Close the given channel, if set, and remove the given entry in the + store. Nothrow guarantee.""" + + try: + try: + if channel: + channel.close() + finally: + self.removeDom(entry) + except Exception, exn: + log.exception(exn) + + def closeStoreChannel(self): """Close the store channel, if any. Nothrow guarantee.""" - - try: - if self.store_channel: - try: - self.store_channel.close() - self.removeDom("store/port") - finally: - self.store_channel = None - except Exception, exn: - log.exception(exn) + + self.closeChannel(self.store_channel, "store/port") + self.store_channel = None + + + def closeConsoleChannel(self): + """Close the console channel, if any. Nothrow guarantee.""" + + self.closeChannel(self.console_channel, "console/port") + self.console_channel = None def setConsoleRef(self, ref): @@ -566,10 +697,13 @@ self.info.update(info) self.validateInfo() + self.refreshShutdown(info) log.debug("XendDomainInfo.update done on domain %d: %s", self.domid, self.info) + + ## private: def state_set(self, state): self.state_updated.acquire() @@ -577,13 +711,16 @@ self.state = state self.state_updated.notifyAll() self.state_updated.release() - self.exportToDB() + + + ## public: def state_wait(self, state): self.state_updated.acquire() while self.state != state: self.state_updated.wait() self.state_updated.release() + def __str__(self): s = "<domain" @@ -597,6 +734,25 @@ __repr__ = __str__ + def createDevice(self, deviceClass, devconfig): + return self.getDeviceController(deviceClass).createDevice(devconfig) + + + def configureDevice(self, deviceClass, devid, devconfig): + return self.getDeviceController(deviceClass).configureDevice( + devid, devconfig) + + + def destroyDevice(self, deviceClass, devid): + return self.getDeviceController(deviceClass).destroyDevice(devid) + + + def getDeviceSxprs(self, deviceClass): + return self.getDeviceController(deviceClass).sxprs() + + + ## private: + def getDeviceController(self, name): if name not in controllerClasses: raise XendError("unknown device type: " + str(name)) @@ -604,62 +760,53 @@ return controllerClasses[name](self) - def createDevice(self, deviceClass, devconfig): - return self.getDeviceController(deviceClass).createDevice(devconfig) - - - def configureDevice(self, deviceClass, devid, devconfig): - return self.getDeviceController(deviceClass).configureDevice( - devid, devconfig) - - - def destroyDevice(self, deviceClass, devid): - return self.getDeviceController(deviceClass).destroyDevice(devid) - + ## public: def sxpr(self): sxpr = ['domain', - ['domid', self.domid], - ['name', self.info['name']], - ['memory', self.info['memory_KiB'] / 1024], - ['ssidref', self.info['ssidref']]] - if self.uuid: - sxpr.append(['uuid', self.uuid]) - if self.info: - sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024]) - - if self.infoIsSet('device'): - for (_, c) in self.info['device']: - sxpr.append(['device', c]) - - def stateChar(name): - if name in self.info: - if self.info[name]: - return name[0] - else: - return '-' + ['domid', self.domid], + ['uuid', self.uuid], + ['memory', self.info['memory_KiB'] / 1024]] + + for e in ROUNDTRIPPING_CONFIG_ENTRIES: + if self.infoIsSet(e[0]): + sxpr.append([e[0], self.info[e[0]]]) + + sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024]) + + if self.infoIsSet('image'): + sxpr.append(['image', self.info['image']]) + + if self.infoIsSet('device'): + for (_, c) in self.info['device']: + sxpr.append(['device', c]) + + def stateChar(name): + if name in self.info: + if self.info[name]: + return name[0] else: - return '?' - - state = reduce( - lambda x, y: x + y, - map(stateChar, - ['running', 'blocked', 'paused', 'shutdown', 'crashed'])) - - sxpr.append(['state', state]) - if self.infoIsSet('shutdown'): - reason = shutdown_reason(self.info['shutdown_reason']) - sxpr.append(['shutdown_reason', reason]) - if self.infoIsSet('cpu_time'): - sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) - sxpr.append(['vcpus', self.info['vcpus']]) - sxpr.append(['cpumap', self.info['cpumap']]) - if self.infoIsSet('vcpu_to_cpu'): - sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) - # build a string, using '|' to separate items, show only up - # to number of vcpus in domain, and trim the trailing '|' - sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|', - self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]]) + return '-' + else: + return '?' + + state = reduce( + lambda x, y: x + y, + map(stateChar, + ['running', 'blocked', 'paused', 'shutdown', 'crashed', + 'dying'])) + + sxpr.append(['state', state]) + if self.infoIsSet('shutdown'): + reason = shutdown_reason(self.info['shutdown_reason']) + sxpr.append(['shutdown_reason', reason]) + if self.infoIsSet('cpu_time'): + sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) + sxpr.append(['vcpus', self.info['vcpus']]) + sxpr.append(['cpumap', self.info['cpumap']]) + if self.infoIsSet('vcpu_to_cpu'): + sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) + sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()]) if self.infoIsSet('start_time'): up_time = time.time() - self.info['start_time'] @@ -674,13 +821,16 @@ sxpr.append(['console_channel', self.console_channel.sxpr()]) if self.console_mfn: sxpr.append(['console_mfn', self.console_mfn]) - if self.restart_count: - sxpr.append(['restart_count', self.restart_count]) - if self.restart_state: - sxpr.append(['restart_state', self.restart_state]) - if self.restart_time: - sxpr.append(['restart_time', str(self.restart_time)]) + return sxpr + + + ## private: + + def prettyVCpuMap(self): + return '|'.join(map(str, + self.info['vcpu_to_cpu'][0:self.info['vcpus']])) + def check_name(self, name): """Check if a vm name is valid. Valid names contain alphabetic characters, @@ -719,11 +869,19 @@ @param config: configuration @raise: VmError on error """ - # todo - add support for scheduling params? + + log.debug('XendDomainInfo.construct: %s %s', + str(self.domid), + str(self.info['ssidref'])) + + self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref']) + + if self.domid <= 0: + raise VmError('Creating domain failed: name=%s' % + self.info['name']) + try: self.initDomain() - - # Create domain devices. self.construct_image() self.configure() self.exportToDB() @@ -737,30 +895,23 @@ def initDomain(self): - log.debug('XendDomainInfo.initDomain: %s %s %s %s)', + log.debug('XendDomainInfo.initDomain: %s %s %s', str(self.domid), str(self.info['memory_KiB']), - str(self.info['ssidref']), str(self.info['cpu_weight'])) - self.domid = xc.domain_create(dom = self.domid or 0, - ssidref = self.info['ssidref']) - - if 'image' not in self.info: + if not self.infoIsSet('image'): raise VmError('Missing image in configuration') self.image = image.create(self, self.info['image'], self.info['device']) - if self.domid <= 0: - raise VmError('Creating domain failed: name=%s' % - self.info['name']) - if self.info['bootloader']: self.image.handleBootloading() xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) + # XXX Merge with configure_maxmem? m = self.image.getDomainMemory(self.info['memory_KiB']) xc.domain_setmaxmem(self.domid, m) xc.domain_memory_increase_reservation(self.domid, m, 0, 0) @@ -794,6 +945,8 @@ self.configure_vcpus(self.info['vcpus']) + ## public: + def delete(self): """Delete the vm's db. """ @@ -803,48 +956,46 @@ log.warning("error in domain db delete: %s", ex) - def destroy_domain(self): - """Destroy the vm's domain. - The domain will not finally go away unless all vm - devices have been released. - """ - if self.domid is None: - return - try: - xc.domain_destroy(dom=self.domid) - except Exception, err: - log.exception("Domain destroy failed: %s", self.info['name']) - def cleanup(self): - """Cleanup vm resources: release devices. - """ - self.state = STATE_VM_TERMINATED + """Cleanup vm resources: release devices. Nothrow guarantee.""" + + self.state_set(STATE_VM_TERMINATED) self.release_devices() self.closeStoreChannel() - if self.console_channel: - # notify processes using this console? - try: - self.console_channel.close() - self.console_channel = None - except: - pass + self.closeConsoleChannel() + if self.image: try: self.image.destroy() - self.image = None except: - pass + log.exception( + "XendDomainInfo.cleanup: image.destroy() failed.") + self.image = None + def destroy(self): - """Cleanup vm and destroy domain. - """ - - log.debug("XendDomainInfo.destroy") - - self.destroy_domain() + """Cleanup vm and destroy domain. Nothrow guarantee.""" + + log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid)) + self.cleanup() - self.exportToDB() - return 0 + + try: + self.removeVm() + except Exception: + log.exception("Removing VM path failed.") + + try: + self.removeDom() + except Exception: + log.exception("Removing domain path failed.") + + try: + if self.domid is not None: + xc.domain_destroy(dom=self.domid) + except Exception: + log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.") + def is_terminated(self): """Check if a domain has been terminated. @@ -852,8 +1003,7 @@ return self.state == STATE_VM_TERMINATED def release_devices(self): - """Release all vm devices. - """ + """Release all vm devices. Nothrow guarantee.""" while True: t = xstransact("%s/device" % self.path) @@ -865,8 +1015,8 @@ # Log and swallow any exceptions in removal -- # there's nothing more we can do. log.exception( - "Device release failed: %s; %s; %s; %s" % - (self.info['name'], n, d, str(ex))) + "Device release failed: %s; %s; %s", + self.info['name'], n, d) if t.commit(): break @@ -902,8 +1052,7 @@ @raise: VmError for invalid devices """ - if not self.rebooting(): - self.create_configured_devices() + self.create_configured_devices() if self.image: self.image.createDeviceModel() @@ -942,23 +1091,6 @@ return reason == 'reboot' return False - def restart_cancel(self): - """Cancel a vm restart. - """ - self.restart_state = None - - def restarting(self): - """Put the vm into restart mode. - """ - self.restart_state = STATE_RESTART_PENDING - - def restart_pending(self): - """Test if the vm has a pending restart. - """ - return self.restart_state == STATE_RESTART_PENDING - - def rebooting(self): - return self.restart_state == STATE_RESTART_BOOTING def restart_check(self): """Check if domain restart is OK. @@ -976,23 +1108,37 @@ self.restart_time = tnow self.restart_count += 1 + def restart(self): - """Restart the domain after it has exited. - Reuses the domain id - - """ + """Restart the domain after it has exited. """ + + # self.restart_check() + self.cleanup() + + config = self.sxpr() + + if self.readVm('xend/restart_in_progress'): + log.error('Xend failed during restart of domain %d. ' + 'Refusing to restart to avoid loops.', + self.domid) + self.destroy() + return + + self.writeVm('xend/restart_in_progress', 'True') + try: - self.clear_shutdown() - self.state = STATE_VM_OK - self.shutdown_pending = None - self.restart_check() - self.exportToDB() - self.restart_state = STATE_RESTART_BOOTING - self.configure_bootloader() - self.construct() - self.exportToDB() + self.destroy() + try: + xd = get_component('xen.xend.XendDomain') + xd.domain_unpause(xd.domain_create(config).getDomid()) + except Exception, exn: + log.exception('Failed to restart domain %d.', self.domid) finally: - self.restart_state = None + self.removeVm('xend/restart_in_progress') + + # self.configure_bootloader() + # self.exportToDB() + def configure_bootloader(self): if not self.info['bootloader']: @@ -1006,7 +1152,8 @@ if dev: disk = sxp.child_value(dev, "uname") fn = blkdev_uname_to_file(disk) - blcfg = bootloader(self.info['bootloader'], fn, 1, self.info['vcpus']) + blcfg = bootloader(self.info['bootloader'], fn, 1, + self.info['vcpus']) if blcfg is None: msg = "Had a bootloader specified, but can't find disk" log.error(msg) @@ -1023,7 +1170,9 @@ def configure_maxmem(self): - xc.domain_setmaxmem(self.domid, maxmem_kb = self.info['maxmem_KiB']) + if self.image: + m = self.image.getDomainMemory(self.info['memory_KiB']) + xc.domain_setmaxmem(self.domid, maxmem_kb = m) def vcpu_hotplug(self, vcpu, state): @@ -1038,23 +1187,8 @@ availability = "online" self.storeVm("cpu/%d/availability" % vcpu, availability) - def shutdown(self, reason): - if not reason in shutdown_reasons.values(): - raise XendError('invalid reason:' + reason) - self.storeVm("control/shutdown", reason) - if not reason in ['suspend']: - self.shutdown_pending = {'start':time.time(), 'reason':reason} - - def clear_shutdown(self): - self.removeVm("control/shutdown") - def send_sysrq(self, key=0): self.storeVm("control/sysrq", '%c' % key) - - def shutdown_time_left(self, timeout): - if not self.shutdown_pending: - return 0 - return timeout - (time.time() - self.shutdown_pending['start']) def dom0_init_store(self): if not self.store_channel: @@ -1078,8 +1212,6 @@ def dom0_enforce_vcpus(self): dom = 0 # get max number of vcpus to use for dom0 from config - from xen.xend import XendRoot - xroot = XendRoot.instance() target = int(xroot.get_dom0_vcpus()) log.debug("number of vcpus to use is %d" % (target)) diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/DevController.py Wed Sep 28 20:06:49 2005 @@ -81,6 +81,13 @@ xstransact.Remove(backpath) + def sxprs(self): + """@return an s-expression describing all the devices of this + controller's device-class. + """ + return xstransact.ListRecursive(self.frontendRoot()) + + def sxpr(self, devid): """@return an s-expression describing the specified device. """ @@ -126,8 +133,8 @@ compulsory to use it; subclasses may prefer to allocate IDs based upon the device configuration instead. """ + path = self.frontendMiscPath() while True: - path = self.frontendMiscPath() t = xstransact(path) try: result = t.read("nextDeviceID") @@ -196,8 +203,11 @@ def frontendPath(self, devid): - return "%s/device/%s/%d" % (self.vm.getPath(), self.deviceClass, - devid) + return "%s/%d" % (self.frontendRoot(), devid) + + + def frontendRoot(self): + return "%s/device/%s" % (self.vm.getPath(), self.deviceClass) def frontendMiscPath(self): diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDaemon.py --- a/tools/python/xen/xend/server/SrvDaemon.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/SrvDaemon.py Wed Sep 28 20:06:49 2005 @@ -9,25 +9,23 @@ import sys import threading import linecache -import socket import pwd import re -import StringIO import traceback -import time -import glob - -from xen.xend import sxp -from xen.xend import PrettyPrint -from xen.xend import EventServer; eserver = EventServer.instance() -from xen.xend.XendError import XendError + +from xen.xend import EventServer from xen.xend.server import SrvServer from xen.xend.XendLogging import log -from xen.xend import XendRoot; xroot = XendRoot.instance() +from xen.xend import XendRoot import event import relocate from params import * + + +eserver = EventServer.instance() +xroot = XendRoot.instance() + class Daemon: """The xend daemon. @@ -233,7 +231,7 @@ except: pass - def print_trace(self, str): + def print_trace(self, string): for i in range(self.traceindent): ch = " " if (i % 5): @@ -241,7 +239,7 @@ else: ch = '|' self.tracefile.write(ch) - self.tracefile.write(str) + self.tracefile.write(string) def trace(self, frame, event, arg): if not self.traceon: @@ -289,7 +287,7 @@ try: os.setuid(pwd.getpwnam(XEND_USER)[2]) return 0 - except KeyError, error: + except KeyError: print >>sys.stderr, "Error: no such user '%s'" % XEND_USER return 1 diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDmesg.py --- a/tools/python/xen/xend/server/SrvDmesg.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/SrvDmesg.py Wed Sep 28 20:06:49 2005 @@ -13,14 +13,14 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> +# Copyright (C) 2005 XenSource Ltd #============================================================================ -import os -from xen.xend import sxp from xen.xend import XendDmesg from xen.web.SrvDir import SrvDir + class SrvDmesg(SrvDir): """Xen Dmesg output. @@ -47,6 +47,6 @@ def info(self): return self.xd.info() - def op_clear(self, op, req): + def op_clear(self, _1, _2): self.xd.clear() return 0 diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDomain.py --- a/tools/python/xen/xend/server/SrvDomain.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/SrvDomain.py Wed Sep 28 20:06:49 2005 @@ -150,17 +150,6 @@ val = fn(req.args, {'dom': self.dom.domid}) return val - def op_device(self, op, req): - fn = FormFn(self.xd.domain_devtype_get, - [['dom', 'int'], - ['type', 'str'], - ['idx', 'int']]) - val = fn(req.args, {'dom': self.dom.domid}) - if val: - return val.sxpr() - else: - raise XendError("invalid device") - def op_device_create(self, op, req): fn = FormFn(self.xd.domain_device_create, [['dom', 'int'], @@ -172,7 +161,7 @@ fn = FormFn(self.xd.domain_device_refresh, [['dom', 'int'], ['type', 'str'], - ['idx', 'str']]) + ['idx', 'int']]) val = fn(req.args, {'dom': self.dom.domid}) return val @@ -180,7 +169,7 @@ fn = FormFn(self.xd.domain_device_destroy, [['dom', 'int'], ['type', 'str'], - ['idx', 'str']]) + ['idx', 'int']]) val = fn(req.args, {'dom': self.dom.domid}) return val @@ -188,7 +177,7 @@ fn = FormFn(self.xd.domain_device_configure, [['dom', 'int'], ['config', 'sxpr'], - ['idx', 'str']]) + ['idx', 'int']]) val = fn(req.args, {'dom': self.dom.domid}) return val @@ -230,10 +219,6 @@ self.print_path(req) #self.ls() req.write('<p>%s</p>' % self.dom) - if self.dom.config: - req.write("<code><pre>") - PrettyPrint.prettyprint(self.dom.config, out=req) - req.write("</pre></code>") self.form(req) req.write('</body></html>') return '' diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvDomainDir.py --- a/tools/python/xen/xend/server/SrvDomainDir.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/SrvDomainDir.py Wed Sep 28 20:06:49 2005 @@ -38,19 +38,17 @@ self.xd = XendDomain.instance() def domain(self, x): - val = None dom = self.xd.domain_lookup_by_name(x) if not dom: raise XendError('No such domain ' + str(x)) - val = SrvDomain(dom) - return val + return SrvDomain(dom) def get(self, x): v = SrvDir.get(self, x) if v is not None: return v - v = self.domain(x) - return v + else: + return self.domain(x) def op_create(self, op, req): """Create a domain. @@ -152,11 +150,11 @@ domains = self.xd.list_sorted() req.write('<ul>') for d in domains: - req.write('<li><a href="%s%s"> Domain %s</a>' - % (url, d.getName(), d.getName())) - req.write('id=%s' % d.getDomain()) - req.write('memory=%d'% d.getMemoryTarget()) - req.write('ssidref=%d'% d.getSsidref()) + req.write( + '<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d, ' + 'ssidref = %d.' + % (url, d.getName(), d.getName(), d.getDomid(), + d.getMemoryTarget(), d.getSsidref())) req.write('</li>') req.write('</ul>') diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/server/SrvNode.py --- a/tools/python/xen/xend/server/SrvNode.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/server/SrvNode.py Wed Sep 28 20:06:49 2005 @@ -62,7 +62,7 @@ for d in self.info(): req.write('<li> %10s: %s' % (d[0], str(d[1]))) req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url) - req.write('<li><a href="%slog>Xend log</a>' % url) + req.write('<li><a href="%slog">Xend log</a>' % url) req.write('</ul>') req.write('</body></html>') diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xend/xenstore/xstransact.py --- a/tools/python/xen/xend/xenstore/xstransact.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xend/xenstore/xstransact.py Wed Sep 28 20:06:49 2005 @@ -1,4 +1,5 @@ # Copyright (C) 2005 Christian Limpach <Christian.Limpach@xxxxxxxxxxxx> +# Copyright (C) 2005 XenSource Ltd # This file is subject to the terms and conditions of the GNU General # Public License. See the file "COPYING" in the main directory of @@ -8,6 +9,7 @@ import threading from xen.lowlevel import xs from xen.xend.xenstore.xsutil import xshandle + class xstransact: @@ -40,8 +42,15 @@ '%s, while reading %s' % (ex.args[1], path)) def read(self, *args): - if len(args) == 0: - raise TypeError + """If no arguments are given, return the value at this transaction's + path. If one argument is given, treat that argument as a subpath to + this transaction's path, and return the value at that path. + Otherwise, treat each argument as a subpath to this transaction's + path, and return a list composed of the values at each of those + instead. + """ + if len(args) == 0: + return xshandle().read(self.path) if len(args) == 1: return self._read(args[0]) ret = [] @@ -105,12 +114,49 @@ return [] def list(self, *args): - if len(args) == 0: - raise TypeError + """If no arguments are given, list this transaction's path, returning + the entries therein, or the empty list if no entries are found. + Otherwise, treat each argument as a subpath to this transaction's + path, and return the cumulative listing of each of those instead. + """ + if len(args) == 0: + ret = xshandle().ls(self.path) + if ret is None: + return [] + else: + return ret + else: + ret = [] + for key in args: + ret.extend(self._list(key)) + return ret + + + def list_recursive_(self, subdir, keys): ret = [] - for key in args: - ret.extend(self._list(key)) + for key in keys: + new_subdir = subdir + "/" + key + l = xshandle().ls(new_subdir) + if l: + ret.append([key, self.list_recursive_(new_subdir, l)]) + else: + ret.append([key, xshandle().read(new_subdir)]) return ret + + + def list_recursive(self, *args): + """If no arguments are given, list this transaction's path, returning + the entries therein, or the empty list if no entries are found. + Otherwise, treat each argument as a subpath to this transaction's + path, and return the cumulative listing of each of those instead. + """ + if len(args) == 0: + args = self.list() + if args is None or len(args) == 0: + return [] + + return self.list_recursive_(self.path, args) + def gather(self, *args): if len(args) and type(args[0]) != tuple: @@ -163,6 +209,13 @@ def Read(cls, path, *args): + """If only one argument is given (path), return the value stored at + that path. If two arguments are given, treat the second argument as a + subpath within the first, and return the value at the composed path. + Otherwise, treat each argument after the first as a subpath to the + given path, and return a list composed of the values at each of those + instead. This operation is performed inside a transaction. + """ while True: t = cls(path) try: @@ -206,6 +259,12 @@ Remove = classmethod(Remove) def List(cls, path, *args): + """If only one argument is given (path), list its contents, returning + the entries therein, or the empty list if no entries are found. + Otherwise, treat each further argument as a subpath to the given path, + and return the cumulative listing of each of those instead. This + operation is performed inside a transaction. + """ while True: t = cls(path) try: @@ -218,6 +277,25 @@ List = classmethod(List) + def ListRecursive(cls, path, *args): + """If only one argument is given (path), list its contents + recursively, returning the entries therein, or the empty list if no + entries are found. Otherwise, treat each further argument as a + subpath to the given path, and return the cumulative listing of each + of those instead. This operation is performed inside a transaction. + """ + while True: + t = cls(path) + try: + v = t.list_recursive(*args) + if t.commit(): + return v + except: + t.abort() + raise + + ListRecursive = classmethod(ListRecursive) + def Gather(cls, path, *args): while True: t = cls(path) diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Mon Sep 26 17:15:55 2005 +++ b/tools/python/xen/xm/main.py Wed Sep 28 20:06:49 2005 @@ -175,6 +175,10 @@ dom = args[0] # TODO: should check if this exists savefile = os.path.abspath(args[1]) + + if not os.access(os.path.dirname(savefile), os.W_OK): + err("xm save: Unable to create file %s" % savefile) + sys.exit(1) from xen.xend.XendClient import server server.xend_domain_save(dom, savefile) @@ -183,6 +187,10 @@ arg_check(args,1,"restore") savefile = os.path.abspath(args[0]) + + if not os.access(savefile, os.R_OK): + err("xm restore: Unable to read file %s" % savefile) + sys.exit(1) from xen.xend.XendClient import server info = server.xend_domain_restore(savefile) diff -r 4e1031ce3bc2 -r 5e5ae8340956 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Mon Sep 26 17:15:55 2005 +++ b/tools/xenstore/xenstored_domain.c Wed Sep 28 20:06:49 2005 @@ -63,6 +63,8 @@ /* The connection associated with this. */ struct connection *conn; + /* Have we noticed that this domain is shutdown? */ + int shutdown; }; static LIST_HEAD(domains); @@ -222,19 +224,25 @@ { xc_dominfo_t dominfo; struct domain *domain, *tmp; - int released = 0; + int notify = 0; list_for_each_entry_safe(domain, tmp, &domains, list) { if (xc_domain_getinfo(*xc_handle, domain->domid, 1, &dominfo) == 1 && - dominfo.domid == domain->domid && - !dominfo.dying && !dominfo.crashed && !dominfo.shutdown) - continue; + dominfo.domid == domain->domid) { + if ((dominfo.crashed || dominfo.shutdown) + && !domain->shutdown) { + domain->shutdown = 1; + notify = 1; + } + if (!dominfo.dying) + continue; + } talloc_free(domain->conn); - released++; - } - - if (released) + notify = 1; + } + + if (notify) fire_watches(NULL, "@releaseDomain", false); } @@ -272,6 +280,7 @@ struct domain *domain; domain = talloc(context, struct domain); domain->port = 0; + domain->shutdown = 0; domain->domid = domid; domain->path = talloc_strdup(domain, path); domain->page = xc_map_foreign_range(*xc_handle, domain->domid, diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/shadow32.c --- a/xen/arch/x86/shadow32.c Mon Sep 26 17:15:55 2005 +++ b/xen/arch/x86/shadow32.c Wed Sep 28 20:06:49 2005 @@ -755,9 +755,13 @@ /* * Then free monitor_table. + * Note: for VMX guest, only BSP need do this free. */ - mfn = pagetable_get_pfn(v->arch.monitor_table); - free_domheap_page(&frame_table[mfn]); + if (!(VMX_DOMAIN(v) && v->vcpu_id)) { + mfn = pagetable_get_pfn(v->arch.monitor_table); + unmap_domain_page(v->arch.monitor_vtable); + free_domheap_page(&frame_table[mfn]); + } v->arch.monitor_table = mk_pagetable(0); v->arch.monitor_vtable = 0; diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/shadow_public.c --- a/xen/arch/x86/shadow_public.c Mon Sep 26 17:15:55 2005 +++ b/xen/arch/x86/shadow_public.c Wed Sep 28 20:06:49 2005 @@ -256,14 +256,15 @@ { unsigned long mfn; -// ASSERT( pagetable_val(v->arch.monitor_table) ); /* * free monitor_table. + * Note: for VMX guest, only BSP need do this free. */ - //mfn = (pagetable_val(v->arch.monitor_table)) >> PAGE_SHIFT; - mfn = pagetable_get_pfn(v->arch.monitor_table); - unmap_domain_page(v->arch.monitor_vtable); - free_domheap_page(&frame_table[mfn]); + if (!(VMX_DOMAIN(v) && v->vcpu_id)) { + mfn = pagetable_get_pfn(v->arch.monitor_table); + unmap_domain_page(v->arch.monitor_vtable); + free_domheap_page(&frame_table[mfn]); + } v->arch.monitor_table = mk_pagetable(0); v->arch.monitor_vtable = 0; } @@ -358,9 +359,13 @@ /* * Then free monitor_table. + * Note: for VMX guest, only BSP need do this free. */ - mfn = pagetable_get_pfn(v->arch.monitor_table); - free_domheap_page(&frame_table[mfn]); + if (!(VMX_DOMAIN(v) && v->vcpu_id)) { + mfn = pagetable_get_pfn(v->arch.monitor_table); + unmap_domain_page(v->arch.monitor_vtable); + free_domheap_page(&frame_table[mfn]); + } v->arch.monitor_table = mk_pagetable(0); v->arch.monitor_vtable = 0; diff -r 4e1031ce3bc2 -r 5e5ae8340956 xen/arch/x86/vmx_platform.c --- a/xen/arch/x86/vmx_platform.c Mon Sep 26 17:15:55 2005 +++ b/xen/arch/x86/vmx_platform.c Wed Sep 28 20:06:49 2005 @@ -667,6 +667,7 @@ mpcip->instr = inst->instr; mpcip->operand[0] = inst->operand[0]; /* source */ mpcip->operand[1] = inst->operand[1]; /* destination */ + mpcip->immediate = inst->immediate; if (inst->operand[0] & REGISTER) { /* dest is memory */ index = operand_index(inst->operand[0]); @@ -833,12 +834,16 @@ mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs); break; - case INSTR_CMP: - mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs); - break; - + case INSTR_CMP: /* Pass through */ case INSTR_TEST: - mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs); + mpcip->flags = mmio_inst.flags; + mpcip->instr = mmio_inst.instr; + mpcip->operand[0] = mmio_inst.operand[0]; /* source */ + mpcip->operand[1] = mmio_inst.operand[1]; /* destination */ + mpcip->immediate = mmio_inst.immediate; + + /* send the request and wait for the value */ + send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, IOREQ_READ, 0); break; default: _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |