# 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
|