xen-vtx-unstable
changeset 5996:d4fd332df775
Manual merge.
line diff
4.1 --- a/buildconfigs/Rules.mk Tue Aug 02 15:38:45 2005 -0700 4.2 +++ b/buildconfigs/Rules.mk Wed Aug 03 09:22:03 2005 +0000 4.3 @@ -115,7 +115,7 @@ config-update-pae: 4.4 ifeq ($(XEN_TARGET_X86_PAE),y) 4.5 sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) 4.6 else 4.7 - @: # do nothing yet 4.8 + grep '^CONFIG_HIGHMEM64G=y' $(CONFIG_FILE) >/dev/null && ( sed -e 's!^CONFIG_HIGHMEM64G=y$$!\# CONFIG_HIGHMEM64G is not set!;s!^\# CONFIG_HIGHMEM4G is not set$$!CONFIG_HIGHMEM4G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) ) || true 4.9 endif 4.10 4.11 # never delete any intermediate files.
10.1 --- a/linux-2.4-xen-sparse/arch/xen/Makefile Tue Aug 02 15:38:45 2005 -0700 10.2 +++ b/linux-2.4-xen-sparse/arch/xen/Makefile Wed Aug 03 09:22:03 2005 +0000 10.3 @@ -61,7 +61,6 @@ SUBDIRS += arch/xen/drivers/console 10.4 SUBDIRS += arch/xen/drivers/evtchn 10.5 SUBDIRS += arch/xen/drivers/blkif 10.6 SUBDIRS += arch/xen/drivers/netif 10.7 -#SUBDIRS += arch/xen/drivers/usbif 10.8 SUBDIRS += arch/xen/drivers/balloon 10.9 ifdef CONFIG_XEN_PRIVILEGED_GUEST 10.10 SUBDIRS += arch/xen/drivers/dom0 10.11 @@ -72,7 +71,6 @@ CORE_FILES += arch/xen/drivers/evtchn/dr 10.12 CORE_FILES += arch/xen/drivers/console/drv.o 10.13 DRIVERS += arch/xen/drivers/blkif/drv.o 10.14 DRIVERS += arch/xen/drivers/netif/drv.o 10.15 -DRIVERS += arch/xen/drivers/usbif/drv.o 10.16 ifdef CONFIG_XEN_PRIVILEGED_GUEST 10.17 CORE_FILES += arch/xen/drivers/dom0/drv.o 10.18 endif
11.1 --- a/linux-2.4-xen-sparse/arch/xen/config.in Tue Aug 02 15:38:45 2005 -0700 11.2 +++ b/linux-2.4-xen-sparse/arch/xen/config.in Wed Aug 03 09:22:03 2005 +0000 11.3 @@ -16,14 +16,10 @@ mainmenu_option next_comment 11.4 comment 'Xen' 11.5 bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST 11.6 bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS 11.7 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then 11.8 - bool 'USB-device backend driver' CONFIG_XEN_USB_BACKEND 11.9 -fi 11.10 bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES 11.11 bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND 11.12 bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND 11.13 bool 'Block-device uses grant tables' CONFIG_XEN_BLKDEV_GRANT 11.14 -bool 'USB-device frontend driver' CONFIG_XEN_USB_FRONTEND 11.15 endmenu 11.16 # The IBM S/390 patch needs this. 11.17 define_bool CONFIG_NO_IDLE_HZ y 11.18 @@ -267,7 +263,7 @@ fi 11.19 11.20 source drivers/char/Config.in 11.21 11.22 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then 11.23 +if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then 11.24 source drivers/media/Config.in 11.25 fi 11.26 11.27 @@ -302,14 +298,8 @@ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" 11.28 endmenu 11.29 fi 11.30 11.31 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then 11.32 - if [ "$CONFIG_XEN_USB_FRONTEND" = "y" -o "$CONFIG_XEN_USB_BACKEND" = "y" ]; then 11.33 - define_bool CONFIG_USB y 11.34 - fi 11.35 +if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then 11.36 source drivers/usb/Config.in 11.37 -fi 11.38 - 11.39 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then 11.40 source net/bluetooth/Config.in 11.41 fi 11.42
38.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Tue Aug 02 15:38:45 2005 -0700 38.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Wed Aug 03 09:22:03 2005 +0000 38.3 @@ -1,7 +1,7 @@ 38.4 # 38.5 # Automatically generated make config: don't edit 38.6 # Linux kernel version: 2.6.12-xen0 38.7 -# Mon Jul 25 09:48:34 2005 38.8 +# Wed Aug 3 09:54:56 2005 38.9 # 38.10 CONFIG_XEN=y 38.11 CONFIG_ARCH_XEN=y 38.12 @@ -18,8 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y 38.13 CONFIG_XEN_NETDEV_BACKEND=y 38.14 CONFIG_XEN_BLKDEV_FRONTEND=y 38.15 CONFIG_XEN_NETDEV_FRONTEND=y 38.16 -#CONFIG_XEN_NETDEV_GRANT_TX=y 38.17 -#CONFIG_XEN_NETDEV_GRANT_RX=y 38.18 +# CONFIG_XEN_NETDEV_GRANT_TX is not set 38.19 +# CONFIG_XEN_NETDEV_GRANT_RX is not set 38.20 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set 38.21 # CONFIG_XEN_BLKDEV_TAP is not set 38.22 # CONFIG_XEN_SHADOW_MODE is not set 38.23 @@ -93,11 +93,11 @@ CONFIG_GENERIC_IOMAP=y 38.24 # CONFIG_M586 is not set 38.25 # CONFIG_M586TSC is not set 38.26 # CONFIG_M586MMX is not set 38.27 -# CONFIG_M686 is not set 38.28 +CONFIG_M686=y 38.29 # CONFIG_MPENTIUMII is not set 38.30 # CONFIG_MPENTIUMIII is not set 38.31 # CONFIG_MPENTIUMM is not set 38.32 -CONFIG_MPENTIUM4=y 38.33 +# CONFIG_MPENTIUM4 is not set 38.34 # CONFIG_MK6 is not set 38.35 # CONFIG_MK7 is not set 38.36 # CONFIG_MK8 is not set 38.37 @@ -112,15 +112,15 @@ CONFIG_MPENTIUM4=y 38.38 # CONFIG_X86_GENERIC is not set 38.39 CONFIG_X86_CMPXCHG=y 38.40 CONFIG_X86_XADD=y 38.41 -CONFIG_X86_L1_CACHE_SHIFT=7 38.42 +CONFIG_X86_L1_CACHE_SHIFT=5 38.43 CONFIG_RWSEM_XCHGADD_ALGORITHM=y 38.44 CONFIG_GENERIC_CALIBRATE_DELAY=y 38.45 +CONFIG_X86_PPRO_FENCE=y 38.46 CONFIG_X86_WP_WORKS_OK=y 38.47 CONFIG_X86_INVLPG=y 38.48 CONFIG_X86_BSWAP=y 38.49 CONFIG_X86_POPAD_OK=y 38.50 CONFIG_X86_GOOD_APIC=y 38.51 -CONFIG_X86_INTEL_USERCOPY=y 38.52 CONFIG_X86_USE_PPRO_CHECKSUM=y 38.53 # CONFIG_HPET_TIMER is not set 38.54 # CONFIG_HPET_EMULATE_RTC is not set
39.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Tue Aug 02 15:38:45 2005 -0700 39.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Wed Aug 03 09:22:03 2005 +0000 39.3 @@ -1,7 +1,7 @@ 39.4 # 39.5 # Automatically generated make config: don't edit 39.6 # Linux kernel version: 2.6.12-xen0 39.7 -# Wed Jun 29 10:01:20 2005 39.8 +# Tue Aug 2 23:55:35 2005 39.9 # 39.10 CONFIG_XEN=y 39.11 CONFIG_ARCH_XEN=y 39.12 @@ -18,6 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y 39.13 CONFIG_XEN_NETDEV_BACKEND=y 39.14 CONFIG_XEN_BLKDEV_FRONTEND=y 39.15 CONFIG_XEN_NETDEV_FRONTEND=y 39.16 +# CONFIG_XEN_NETDEV_GRANT_TX is not set 39.17 +# CONFIG_XEN_NETDEV_GRANT_RX is not set 39.18 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set 39.19 # CONFIG_XEN_BLKDEV_TAP is not set 39.20 # CONFIG_XEN_SHADOW_MODE is not set
40.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Tue Aug 02 15:38:45 2005 -0700 40.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Wed Aug 03 09:22:03 2005 +0000 40.3 @@ -1,7 +1,7 @@ 40.4 # 40.5 # Automatically generated make config: don't edit 40.6 # Linux kernel version: 2.6.12-xenU 40.7 -# Mon Jul 25 10:06:06 2005 40.8 +# Wed Aug 3 09:57:44 2005 40.9 # 40.10 CONFIG_XEN=y 40.11 CONFIG_ARCH_XEN=y 40.12 @@ -15,8 +15,8 @@ CONFIG_NO_IDLE_HZ=y 40.13 CONFIG_XEN_BLKDEV_GRANT=y 40.14 CONFIG_XEN_BLKDEV_FRONTEND=y 40.15 CONFIG_XEN_NETDEV_FRONTEND=y 40.16 -#CONFIG_XEN_NETDEV_GRANT_TX=y 40.17 -#CONFIG_XEN_NETDEV_GRANT_RX=y 40.18 +# CONFIG_XEN_NETDEV_GRANT_TX is not set 40.19 +# CONFIG_XEN_NETDEV_GRANT_RX is not set 40.20 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set 40.21 # CONFIG_XEN_BLKDEV_TAP is not set 40.22 # CONFIG_XEN_SHADOW_MODE is not set 40.23 @@ -90,11 +90,11 @@ CONFIG_GENERIC_IOMAP=y 40.24 # CONFIG_M586 is not set 40.25 # CONFIG_M586TSC is not set 40.26 # CONFIG_M586MMX is not set 40.27 -# CONFIG_M686 is not set 40.28 +CONFIG_M686=y 40.29 # CONFIG_MPENTIUMII is not set 40.30 # CONFIG_MPENTIUMIII is not set 40.31 # CONFIG_MPENTIUMM is not set 40.32 -CONFIG_MPENTIUM4=y 40.33 +# CONFIG_MPENTIUM4 is not set 40.34 # CONFIG_MK6 is not set 40.35 # CONFIG_MK7 is not set 40.36 # CONFIG_MK8 is not set 40.37 @@ -109,15 +109,15 @@ CONFIG_MPENTIUM4=y 40.38 # CONFIG_X86_GENERIC is not set 40.39 CONFIG_X86_CMPXCHG=y 40.40 CONFIG_X86_XADD=y 40.41 -CONFIG_X86_L1_CACHE_SHIFT=7 40.42 +CONFIG_X86_L1_CACHE_SHIFT=5 40.43 CONFIG_RWSEM_XCHGADD_ALGORITHM=y 40.44 CONFIG_GENERIC_CALIBRATE_DELAY=y 40.45 +CONFIG_X86_PPRO_FENCE=y 40.46 CONFIG_X86_WP_WORKS_OK=y 40.47 CONFIG_X86_INVLPG=y 40.48 CONFIG_X86_BSWAP=y 40.49 CONFIG_X86_POPAD_OK=y 40.50 CONFIG_X86_GOOD_APIC=y 40.51 -CONFIG_X86_INTEL_USERCOPY=y 40.52 CONFIG_X86_USE_PPRO_CHECKSUM=y 40.53 # CONFIG_HPET_TIMER is not set 40.54 # CONFIG_HPET_EMULATE_RTC is not set
41.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Tue Aug 02 15:38:45 2005 -0700 41.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Wed Aug 03 09:22:03 2005 +0000 41.3 @@ -1,7 +1,7 @@ 41.4 # 41.5 # Automatically generated make config: don't edit 41.6 # Linux kernel version: 2.6.12-xenU 41.7 -# Thu Jul 7 11:43:14 2005 41.8 +# Tue Aug 2 23:56:13 2005 41.9 # 41.10 CONFIG_XEN=y 41.11 CONFIG_ARCH_XEN=y 41.12 @@ -15,6 +15,8 @@ CONFIG_NO_IDLE_HZ=y 41.13 CONFIG_XEN_BLKDEV_GRANT=y 41.14 CONFIG_XEN_BLKDEV_FRONTEND=y 41.15 CONFIG_XEN_NETDEV_FRONTEND=y 41.16 +# CONFIG_XEN_NETDEV_GRANT_TX is not set 41.17 +# CONFIG_XEN_NETDEV_GRANT_RX is not set 41.18 # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set 41.19 # CONFIG_XEN_BLKDEV_TAP is not set 41.20 # CONFIG_XEN_SHADOW_MODE is not set
48.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Tue Aug 02 15:38:45 2005 -0700 48.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Wed Aug 03 09:22:03 2005 +0000 48.3 @@ -1529,7 +1529,7 @@ void __init smp_cpus_done(unsigned int m 48.4 extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); 48.5 extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); 48.6 48.7 -void __init smp_intr_init(void) 48.8 +void smp_intr_init(void) 48.9 { 48.10 int cpu = smp_processor_id(); 48.11 48.12 @@ -1546,3 +1546,28 @@ void __init smp_intr_init(void) 48.13 smp_call_function_interrupt, 48.14 SA_INTERRUPT, callfunc_name[cpu], NULL)); 48.15 } 48.16 + 48.17 +static void smp_intr_exit(void) 48.18 +{ 48.19 + int cpu = smp_processor_id(); 48.20 + 48.21 + free_irq(per_cpu(resched_irq, cpu), NULL); 48.22 + unbind_ipi_from_irq(RESCHEDULE_VECTOR); 48.23 + 48.24 + free_irq(per_cpu(callfunc_irq, cpu), NULL); 48.25 + unbind_ipi_from_irq(CALL_FUNCTION_VECTOR); 48.26 +} 48.27 + 48.28 +void smp_suspend(void) 48.29 +{ 48.30 + /* XXX todo: take down time and ipi's on all cpus */ 48.31 + local_teardown_timer_irq(); 48.32 + smp_intr_exit(); 48.33 +} 48.34 + 48.35 +void smp_resume(void) 48.36 +{ 48.37 + /* XXX todo: restore time and ipi's on all cpus */ 48.38 + smp_intr_init(); 48.39 + local_setup_timer_irq(); 48.40 +}
49.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Aug 02 15:38:45 2005 -0700 49.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Wed Aug 03 09:22:03 2005 +0000 49.3 @@ -860,6 +860,8 @@ void start_hz_timer(void) 49.4 void time_suspend(void) 49.5 { 49.6 /* nothing */ 49.7 + teardown_irq(per_cpu(timer_irq, 0), &irq_timer); 49.8 + unbind_virq_from_irq(VIRQ_TIMER); 49.9 } 49.10 49.11 /* No locking required. We are only CPU running, and interrupts are off. */ 49.12 @@ -874,10 +876,25 @@ void time_resume(void) 49.13 processed_system_time = 49.14 per_cpu(shadow_time, smp_processor_id()).system_timestamp; 49.15 per_cpu(processed_system_time, 0) = processed_system_time; 49.16 + 49.17 + per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER); 49.18 + (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer); 49.19 } 49.20 49.21 #ifdef CONFIG_SMP 49.22 static char timer_name[NR_CPUS][15]; 49.23 +void local_setup_timer_irq(void) 49.24 +{ 49.25 + int cpu = smp_processor_id(); 49.26 + 49.27 + if (cpu == 0) 49.28 + return; 49.29 + per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER); 49.30 + sprintf(timer_name[cpu], "timer%d", cpu); 49.31 + BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, 49.32 + SA_INTERRUPT, timer_name[cpu], NULL)); 49.33 +} 49.34 + 49.35 void local_setup_timer(void) 49.36 { 49.37 int seq, cpu = smp_processor_id(); 49.38 @@ -888,10 +905,17 @@ void local_setup_timer(void) 49.39 per_cpu(shadow_time, cpu).system_timestamp; 49.40 } while (read_seqretry(&xtime_lock, seq)); 49.41 49.42 - per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER); 49.43 - sprintf(timer_name[cpu], "timer%d", cpu); 49.44 - BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, 49.45 - SA_INTERRUPT, timer_name[cpu], NULL)); 49.46 + local_setup_timer_irq(); 49.47 +} 49.48 + 49.49 +void local_teardown_timer_irq(void) 49.50 +{ 49.51 + int cpu = smp_processor_id(); 49.52 + 49.53 + if (cpu == 0) 49.54 + return; 49.55 + free_irq(per_cpu(timer_irq, cpu), NULL); 49.56 + unbind_virq_from_irq(VIRQ_TIMER); 49.57 } 49.58 #endif 49.59
53.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Aug 02 15:38:45 2005 -0700 53.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Wed Aug 03 09:22:03 2005 +0000 53.3 @@ -284,7 +284,7 @@ void unbind_ipi_from_irq(int ipi) 53.4 evtchn_op_t op; 53.5 int cpu = smp_processor_id(); 53.6 int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; 53.7 - int irq = irq_to_evtchn[evtchn]; 53.8 + int irq = evtchn_to_irq[evtchn]; 53.9 53.10 spin_lock(&irq_mapping_update_lock); 53.11
55.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Aug 02 15:38:45 2005 -0700 55.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Wed Aug 03 09:22:03 2005 +0000 55.3 @@ -16,6 +16,7 @@ static int errno; 55.4 #include <asm-xen/xen-public/dom0_ops.h> 55.5 #include <asm-xen/linux-public/suspend.h> 55.6 #include <asm-xen/queues.h> 55.7 +#include <asm-xen/xenbus.h> 55.8 55.9 void machine_restart(char * __unused) 55.10 { 55.11 @@ -90,6 +91,10 @@ static void __do_suspend(void) 55.12 #define gnttab_resume() do{}while(0) 55.13 #endif 55.14 55.15 +#ifdef CONFIG_SMP 55.16 + extern void smp_suspend(void); 55.17 + extern void smp_resume(void); 55.18 +#endif 55.19 extern void time_suspend(void); 55.20 extern void time_resume(void); 55.21 extern unsigned long max_pfn; 55.22 @@ -114,6 +119,12 @@ static void __do_suspend(void) 55.23 55.24 time_suspend(); 55.25 55.26 +#ifdef CONFIG_SMP 55.27 + smp_suspend(); 55.28 +#endif 55.29 + 55.30 + xenbus_suspend(); 55.31 + 55.32 ctrl_if_suspend(); 55.33 55.34 irq_suspend(); 55.35 @@ -153,6 +164,12 @@ static void __do_suspend(void) 55.36 55.37 ctrl_if_resume(); 55.38 55.39 + xenbus_resume(); 55.40 + 55.41 +#ifdef CONFIG_SMP 55.42 + smp_resume(); 55.43 +#endif 55.44 + 55.45 time_resume(); 55.46 55.47 blkdev_resume();
58.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 02 15:38:45 2005 -0700 58.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Aug 03 09:22:03 2005 +0000 58.3 @@ -84,9 +84,6 @@ static struct timer_list balloon_timer; 58.4 /* Flag for dom0 xenstore workaround */ 58.5 static int balloon_xenbus_init=0; 58.6 58.7 -/* Init Function */ 58.8 -void balloon_init_watcher(void); 58.9 - 58.10 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 58.11 /* Use the private and mapping fields of struct page as a list. */ 58.12 #define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) 58.13 @@ -354,27 +351,21 @@ static void watch_target(struct xenbus_w 58.14 58.15 } 58.16 58.17 -/* 58.18 - Try to set up our watcher, if not already set 58.19 - 58.20 -*/ 58.21 -void balloon_init_watcher(void) 58.22 +/* Init Function - Try to set up our watcher, if not already set. */ 58.23 +void balloon_init_watcher(void) 58.24 { 58.25 int err; 58.26 58.27 - if(!xen_start_info.store_evtchn) 58.28 - { 58.29 + if (!xen_start_info.store_evtchn) { 58.30 IPRINTK("Delaying watcher init until xenstore is available\n"); 58.31 return; 58.32 } 58.33 58.34 down(&xenbus_lock); 58.35 58.36 - if(! balloon_xenbus_init) 58.37 - { 58.38 + if (!balloon_xenbus_init) { 58.39 err = register_xenbus_watch(&xb_watch); 58.40 - if(err) 58.41 - { 58.42 + if (err) { 58.43 /* BIG FAT FIXME: dom0 sequencing workaround 58.44 * dom0 can't set a watch on memory/target until 58.45 * after the tools create it. So, we have to watch 58.46 @@ -384,16 +375,13 @@ void balloon_init_watcher(void) 58.47 * non-existant keys 58.48 */ 58.49 register_xenbus_watch(&root_watch); 58.50 - } 58.51 - else 58.52 - { 58.53 + } else { 58.54 IPRINTK("Balloon xenbus watcher initialized\n"); 58.55 balloon_xenbus_init = 1; 58.56 } 58.57 } 58.58 58.59 up(&xenbus_lock); 58.60 - 58.61 } 58.62 58.63 EXPORT_SYMBOL(balloon_init_watcher);
67.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Aug 02 15:38:45 2005 -0700 67.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Aug 03 09:22:03 2005 +0000 67.3 @@ -36,6 +36,8 @@ 67.4 #include <linux/err.h> 67.5 #include "xenbus_comms.h" 67.6 67.7 +static unsigned int xb_irq; 67.8 + 67.9 #define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head)) 67.10 struct ringbuf_head 67.11 { 67.12 @@ -202,14 +204,17 @@ int xb_read(void *data, unsigned len) 67.13 return 0; 67.14 } 67.15 67.16 -/* Set up interrpt handler off store event channel. */ 67.17 +/* Set up interrupt handler off store event channel. */ 67.18 int xb_init_comms(void) 67.19 { 67.20 - int err, irq; 67.21 + int err; 67.22 67.23 - irq = bind_evtchn_to_irq(xen_start_info.store_evtchn); 67.24 + if (!xen_start_info.store_evtchn) 67.25 + return 0; 67.26 67.27 - err = request_irq(irq, wake_waiting, SA_SHIRQ, "xenbus", &xb_waitq); 67.28 + xb_irq = bind_evtchn_to_irq(xen_start_info.store_evtchn); 67.29 + 67.30 + err = request_irq(xb_irq, wake_waiting, 0, "xenbus", &xb_waitq); 67.31 if (err) { 67.32 printk(KERN_ERR "XENBUS request irq failed %i\n", err); 67.33 unbind_evtchn_from_irq(xen_start_info.store_evtchn); 67.34 @@ -222,3 +227,13 @@ int xb_init_comms(void) 67.35 67.36 return 0; 67.37 } 67.38 + 67.39 +void xb_suspend_comms(void) 67.40 +{ 67.41 + 67.42 + if (!xen_start_info.store_evtchn) 67.43 + return; 67.44 + 67.45 + free_irq(xb_irq, &xb_waitq); 67.46 + unbind_evtchn_from_irq(xen_start_info.store_evtchn); 67.47 +}
68.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Tue Aug 02 15:38:45 2005 -0700 68.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Wed Aug 03 09:22:03 2005 +0000 68.3 @@ -3,6 +3,7 @@ 68.4 #define _XENBUS_COMMS_H 68.5 int xs_init(void); 68.6 int xb_init_comms(void); 68.7 +void xb_suspend_comms(void); 68.8 68.9 /* Low level routines. */ 68.10 int xb_write(const void *data, unsigned len);
69.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 02 15:38:45 2005 -0700 69.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Aug 03 09:22:03 2005 +0000 69.3 @@ -29,6 +29,7 @@ 69.4 69.5 #include <asm-xen/hypervisor.h> 69.6 #include <asm-xen/xenbus.h> 69.7 +#include <asm-xen/balloon.h> 69.8 #include <linux/kernel.h> 69.9 #include <linux/err.h> 69.10 #include <linux/string.h> 69.11 @@ -295,6 +296,19 @@ static struct xenbus_watch dev_watch = { 69.12 .callback = dev_changed, 69.13 }; 69.14 69.15 +void xenbus_suspend(void) 69.16 +{ 69.17 + /* We keep lock, so no comms can happen as page moves. */ 69.18 + down(&xenbus_lock); 69.19 + xb_suspend_comms(); 69.20 +} 69.21 + 69.22 +void xenbus_resume(void) 69.23 +{ 69.24 + xb_init_comms(); 69.25 + up(&xenbus_lock); 69.26 +} 69.27 + 69.28 /* called from a thread in privcmd/privcmd.c */ 69.29 int do_xenbus_probe(void *unused) 69.30 {
71.1 --- a/linux-2.6-xen-sparse/include/asm-generic/pgtable.h Tue Aug 02 15:38:45 2005 -0700 71.2 +++ b/linux-2.6-xen-sparse/include/asm-generic/pgtable.h Wed Aug 03 09:22:03 2005 +0000 71.3 @@ -37,7 +37,7 @@ do { \ 71.4 */ 71.5 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ 71.6 do { \ 71.7 - set_pte_at((__vma)>vm_mm, (__address), __ptep, __entry); \ 71.8 + set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \ 71.9 flush_tlb_page(__vma, __address); \ 71.10 } while (0) 71.11 #endif
73.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Tue Aug 02 15:38:45 2005 -0700 73.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Wed Aug 03 09:22:03 2005 +0000 73.3 @@ -129,6 +129,7 @@ 73.4 extern int bind_virq_to_irq(int virq); 73.5 extern void unbind_virq_from_irq(int virq); 73.6 extern int bind_ipi_to_irq(int ipi); 73.7 +extern int bind_ipi_on_cpu_to_irq(int ipi); 73.8 extern void unbind_ipi_from_irq(int ipi); 73.9 extern int bind_evtchn_to_irq(int evtchn); 73.10 extern void unbind_evtchn_from_irq(int evtchn);
75.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Tue Aug 02 15:38:45 2005 -0700 75.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h Wed Aug 03 09:22:03 2005 +0000 75.3 @@ -127,6 +127,7 @@ 75.4 extern int bind_virq_to_irq(int virq); 75.5 extern void unbind_virq_from_irq(int virq); 75.6 extern int bind_ipi_to_irq(int ipi); 75.7 +extern int bind_ipi_on_cpu_to_irq(int ipi); 75.8 extern void unbind_ipi_from_irq(int ipi); 75.9 extern int bind_evtchn_to_irq(int evtchn); 75.10 extern void unbind_evtchn_from_irq(int evtchn);
76.1 --- a/linux-2.6-xen-sparse/include/asm-xen/balloon.h Tue Aug 02 15:38:45 2005 -0700 76.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/balloon.h Wed Aug 03 09:22:03 2005 +0000 76.3 @@ -48,4 +48,7 @@ extern spinlock_t balloon_lock; 76.4 #define balloon_lock(__flags) spin_lock_irqsave(&balloon_lock, __flags) 76.5 #define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags) 76.6 76.7 +/* Init Function - Try to set up our watcher, if not already set. */ 76.8 +void balloon_init_watcher(void); 76.9 + 76.10 #endif /* __ASM_BALLOON_H__ */
80.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Aug 02 15:38:45 2005 -0700 80.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Wed Aug 03 09:22:03 2005 +0000 80.3 @@ -115,4 +115,8 @@ struct xenbus_watch 80.4 int register_xenbus_watch(struct xenbus_watch *watch); 80.5 void unregister_xenbus_watch(struct xenbus_watch *watch); 80.6 80.7 +/* Called from xen core code. */ 80.8 +void xenbus_suspend(void); 80.9 +void xenbus_resume(void); 80.10 + 80.11 #endif /* _ASM_XEN_XENBUS_H */
118.1 --- a/tools/libxc/xc.h Tue Aug 02 15:38:45 2005 -0700 118.2 +++ b/tools/libxc/xc.h Wed Aug 03 09:22:03 2005 +0000 118.3 @@ -279,9 +279,12 @@ int xc_linux_save(int xc_handle, int fd, 118.4 * @parm fd the file descriptor to restore a domain from 118.5 * @parm dom the id of the domain 118.6 * @parm nr_pfns the number of pages 118.7 + * @parm store_evtchn the store event channel for this domain to use 118.8 + * @parm store_mfn returned with the mfn of the store page 118.9 * @return 0 on success, -1 on failure 118.10 */ 118.11 -int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns); 118.12 +int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, 118.13 + unsigned int store_evtchn, unsigned long *store_mfn); 118.14 118.15 int xc_linux_build(int xc_handle, 118.16 u32 domid,
121.1 --- a/tools/libxc/xc_linux_restore.c Tue Aug 02 15:38:45 2005 -0700 121.2 +++ b/tools/libxc/xc_linux_restore.c Wed Aug 03 09:22:03 2005 +0000 121.3 @@ -48,7 +48,8 @@ read_exact(int fd, void *buf, size_t cou 121.4 return r; 121.5 } 121.6 121.7 -int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns) 121.8 +int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, 121.9 + unsigned int store_evtchn, unsigned long *store_mfn) 121.10 { 121.11 dom0_op_t op; 121.12 int rc = 1, i, n, k; 121.13 @@ -464,10 +465,13 @@ int xc_linux_restore(int xc_handle, int 121.14 } 121.15 ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn]; 121.16 p_srec = xc_map_foreign_range( 121.17 - xc_handle, dom, PAGE_SIZE, PROT_WRITE, mfn); 121.18 + xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn); 121.19 p_srec->resume_info.nr_pages = nr_pfns; 121.20 p_srec->resume_info.shared_info = shared_info_frame << PAGE_SHIFT; 121.21 p_srec->resume_info.flags = 0; 121.22 + *store_mfn = p_srec->resume_info.store_mfn = 121.23 + pfn_to_mfn_table[p_srec->resume_info.store_mfn]; 121.24 + p_srec->resume_info.store_evtchn = store_evtchn; 121.25 munmap(p_srec, PAGE_SIZE); 121.26 121.27 /* Uncanonicalise each GDT frame number. */
122.1 --- a/tools/libxc/xc_linux_save.c Tue Aug 02 15:38:45 2005 -0700 122.2 +++ b/tools/libxc/xc_linux_save.c Wed Aug 03 09:22:03 2005 +0000 122.3 @@ -20,7 +20,7 @@ 122.4 #define DEBUG 0 122.5 122.6 #if 1 122.7 -#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a ) 122.8 +#define ERR(_f, _a...) do { fprintf(stderr, _f , ## _a); fflush(stderr); } while (0) 122.9 #else 122.10 #define ERR(_f, _a...) ((void)0) 122.11 #endif 122.12 @@ -643,6 +643,22 @@ int xc_linux_save(int xc_handle, int io_ 122.13 goto out; 122.14 } 122.15 122.16 + /* Map the suspend-record MFN to pin it. The page must be owned by 122.17 + dom for this to succeed. */ 122.18 + p_srec = xc_map_foreign_range(xc_handle, dom, 122.19 + sizeof(*p_srec), PROT_READ | PROT_WRITE, 122.20 + ctxt.user_regs.esi); 122.21 + if (!p_srec){ 122.22 + ERR("Couldn't map suspend record"); 122.23 + goto out; 122.24 + } 122.25 + 122.26 + /* Canonicalize store mfn. */ 122.27 + if ( !translate_mfn_to_pfn(&p_srec->resume_info.store_mfn) ) { 122.28 + ERR("Store frame is not in range of pseudophys map"); 122.29 + goto out; 122.30 + } 122.31 + 122.32 print_stats( xc_handle, dom, 0, &stats, 0 ); 122.33 122.34 /* Now write out each data page, canonicalising page tables as we go... */ 122.35 @@ -983,16 +999,6 @@ int xc_linux_save(int xc_handle, int io_ 122.36 } 122.37 } 122.38 122.39 - /* Map the suspend-record MFN to pin it. The page must be owned by 122.40 - dom for this to succeed. */ 122.41 - p_srec = xc_map_foreign_range(xc_handle, dom, 122.42 - sizeof(*p_srec), PROT_READ, 122.43 - ctxt.user_regs.esi); 122.44 - if (!p_srec){ 122.45 - ERR("Couldn't map suspend record"); 122.46 - goto out; 122.47 - } 122.48 - 122.49 if (nr_pfns != p_srec->nr_pfns ) 122.50 { 122.51 ERR("Suspend record nr_pfns unexpected (%ld != %ld)",
131.1 --- a/tools/python/xen/lowlevel/xs/xs.c Tue Aug 02 15:38:45 2005 -0700 131.2 +++ b/tools/python/xen/lowlevel/xs/xs.c Wed Aug 03 09:22:03 2005 +0000 131.3 @@ -254,11 +254,11 @@ static PyObject *xspy_get_permissions(Py 131.4 val = PyList_New(perms_n); 131.5 for (i = 0; i < perms_n; i++, perms++) { 131.6 PyObject *p = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i}", 131.7 - "dom", perms->id, 131.8 - "read", (perms->perms & XS_PERM_READ), 131.9 - "write", (perms->perms & XS_PERM_WRITE), 131.10 - "create", (perms->perms & XS_PERM_CREATE), 131.11 - "owner", (perms->perms & XS_PERM_OWNER)); 131.12 + "dom", perms->id, 131.13 + "read", (perms->perms & XS_PERM_READ), 131.14 + "write", (perms->perms & XS_PERM_WRITE), 131.15 + "exist", (perms->perms & XS_PERM_ENOENT_OK), 131.16 + "owner", (perms->perms & XS_PERM_OWNER)); 131.17 PyList_SetItem(val, i, p); 131.18 } 131.19 exit:
149.1 --- a/tools/python/xen/xend/XendCheckpoint.py Tue Aug 02 15:38:45 2005 -0700 149.2 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Aug 03 09:22:03 2005 +0000 149.3 @@ -6,6 +6,7 @@ 149.4 149.5 import errno 149.6 import os 149.7 +import re 149.8 import select 149.9 import sxp 149.10 from string import join 149.11 @@ -64,6 +65,13 @@ def save(xd, fd, dominfo): 149.12 if l.rstrip() == "suspend": 149.13 log.info("suspending %d" % dominfo.id) 149.14 xd.domain_shutdown(dominfo.id, reason='suspend') 149.15 + if dominfo.store_channel: 149.16 + try: 149.17 + dominfo.db.releaseDomain(dominfo.id) 149.18 + except Exception, ex: 149.19 + log.warning("error in domain release on xenstore: %s", 149.20 + ex) 149.21 + pass 149.22 dominfo.state_wait("suspended") 149.23 log.info("suspend %d done" % dominfo.id) 149.24 child.tochild.write("done\n") 149.25 @@ -76,6 +84,11 @@ def save(xd, fd, dominfo): 149.26 if child.wait() != 0: 149.27 raise XendError("xc_save failed: %s" % lasterr) 149.28 149.29 + if dominfo.store_channel: 149.30 + dominfo.store_channel.close() 149.31 + dominfo.db['store_channel'].delete() 149.32 + dominfo.db.saveDB(save=True) 149.33 + dominfo.store_channel = None 149.34 xd.domain_destroy(dominfo.id) 149.35 return None 149.36 149.37 @@ -107,8 +120,13 @@ def restore(xd, fd): 149.38 raise XendError( 149.39 "not a valid guest state file: pfn count out of range") 149.40 149.41 + if dominfo.store_channel: 149.42 + evtchn = dominfo.store_channel.port2 149.43 + else: 149.44 + evtchn = 0 149.45 + 149.46 cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd), 149.47 - str(dominfo.id), str(nr_pfns)] 149.48 + str(dominfo.id), str(nr_pfns), str(evtchn)] 149.49 log.info("[xc_restore] " + join(cmd)) 149.50 child = xPopen3(cmd, True, -1, [fd, xc.handle()]) 149.51 child.tochild.close() 149.52 @@ -128,7 +146,21 @@ def restore(xd, fd): 149.53 lasterr = l.rstrip() 149.54 if fd == child.fromchild.fileno(): 149.55 l = child.fromchild.readline() 149.56 - log.info(l.rstrip()) 149.57 + while l: 149.58 + m = re.match(r"^(store-mfn) (\d+)\n$", l) 149.59 + if m: 149.60 + if dominfo.store_channel: 149.61 + dominfo.store_mfn = int(m.group(2)) 149.62 + if dominfo.store_mfn >= 0: 149.63 + dominfo.db.introduceDomain(dominfo.id, 149.64 + dominfo.store_mfn, 149.65 + dominfo.store_channel) 149.66 + dominfo.exportToDB(save=True, sync=True) 149.67 + log.info(l.rstrip()) 149.68 + try: 149.69 + l = child.fromchild.readline() 149.70 + except: 149.71 + l = None 149.72 if filter(lambda (fd, event): event & select.POLLHUP, r): 149.73 break 149.74
183.1 --- a/tools/xcutils/xc_restore.c Tue Aug 02 15:38:45 2005 -0700 183.2 +++ b/tools/xcutils/xc_restore.c Wed Aug 03 09:22:03 2005 +0000 183.3 @@ -16,15 +16,23 @@ 183.4 int 183.5 main(int argc, char **argv) 183.6 { 183.7 - unsigned int xc_fd, io_fd, domid, nr_pfns; 183.8 + unsigned int xc_fd, io_fd, domid, nr_pfns, evtchn; 183.9 + int ret; 183.10 + unsigned long mfn; 183.11 183.12 - if (argc != 5) 183.13 - errx(1, "usage: %s xcfd iofd domid nr_pfns", argv[0]); 183.14 + if (argc != 6) 183.15 + errx(1, "usage: %s xcfd iofd domid nr_pfns evtchn", argv[0]); 183.16 183.17 xc_fd = atoi(argv[1]); 183.18 io_fd = atoi(argv[2]); 183.19 domid = atoi(argv[3]); 183.20 nr_pfns = atoi(argv[4]); 183.21 + evtchn = atoi(argv[5]); 183.22 183.23 - return xc_linux_restore(xc_fd, io_fd, domid, nr_pfns); 183.24 + ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, evtchn, &mfn); 183.25 + if (ret == 0) { 183.26 + printf("store-mfn %li\n", mfn); 183.27 + fflush(stdout); 183.28 + } 183.29 + return ret; 183.30 }
187.1 --- a/tools/xenstore/testsuite/07watch.sh Tue Aug 02 15:38:45 2005 -0700 187.2 +++ b/tools/xenstore/testsuite/07watch.sh Wed Aug 03 09:22:03 2005 +0000 187.3 @@ -160,3 +160,22 @@ 1 ackwatch token 187.4 1 waitwatch' | ./xs_test 2>&1`" = "1:/test2/foo:token 187.5 1:contents2 187.6 1:waitwatch timeout" ] 187.7 + 187.8 +# We can watch something which doesn't exist. 187.9 +[ "`echo '1 watch /dir/subdir token 187.10 +2 mkdir /dir/subdir 187.11 +1 waitwatch' | ./xs_test 2>&1`" = "1:/dir/subdir:token" ] 187.12 + 187.13 +# If we don't have permission, we won't see event (rm). 187.14 +[ "`echo '1 setid 1 187.15 +1 watch /dir/subdir token 187.16 +setperm /dir 0 NONE 187.17 +rm /dir/subdir 187.18 +1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ] 187.19 + 187.20 +# If we don't have permission, we won't see event (create). 187.21 +[ "`echo '1 setid 1 187.22 +1 watch /dir/subdir token 187.23 +mkdir /dir/subdir 187.24 +write /dir/subdir/entry create contents 187.25 +1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
194.1 --- a/tools/xenstore/testsuite/test.sh Tue Aug 02 15:38:45 2005 -0700 194.2 +++ b/tools/xenstore/testsuite/test.sh Wed Aug 03 09:22:03 2005 +0000 194.3 @@ -14,7 +14,10 @@ run_test() 194.4 PID=`cat /tmp/pid` 194.5 rm /tmp/pid 194.6 else 194.7 - PID=`./xenstored_test --output-pid` 194.8 + ./xenstored_test --output-pid --trace-file=testsuite/tmp/trace --no-fork > /tmp/pid 2> testsuite/tmp/xenstored_errors & 194.9 + while [ ! -s /tmp/pid ]; do sleep 0; done 194.10 + PID=`cat /tmp/pid` 194.11 + rm /tmp/pid 194.12 fi 194.13 if sh -e $2 $1; then 194.14 if [ -s testsuite/tmp/vgout ]; then
195.1 --- a/tools/xenstore/xenstored_core.c Tue Aug 02 15:38:45 2005 -0700 195.2 +++ b/tools/xenstore/xenstored_core.c Wed Aug 03 09:22:03 2005 +0000 195.3 @@ -504,11 +504,13 @@ void send_error(struct connection *conn, 195.4 { 195.5 unsigned int i; 195.6 195.7 - for (i = 0; error != xsd_errors[i].errnum; i++) 195.8 - if (i == ARRAY_SIZE(xsd_errors) - 1) 195.9 - corrupt(conn, "Unknown error %i (%s)", error, 195.10 - strerror(error)); 195.11 - 195.12 + for (i = 0; error != xsd_errors[i].errnum; i++) { 195.13 + if (i == ARRAY_SIZE(xsd_errors) - 1) { 195.14 + eprintf("xenstored: error %i untranslatable", error); 195.15 + i = 0; /* EINVAL */ 195.16 + break; 195.17 + } 195.18 + } 195.19 send_reply(conn, XS_ERROR, xsd_errors[i].errstring, 195.20 strlen(xsd_errors[i].errstring) + 1); 195.21 } 195.22 @@ -705,7 +707,7 @@ static enum xs_perm_type perm_for_id(dom 195.23 195.24 /* Owners and tools get it all... */ 195.25 if (!id || perms[0].id == id) 195.26 - return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_CREATE|XS_PERM_OWNER; 195.27 + return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER; 195.28 195.29 for (i = 1; i < num; i++) 195.30 if (perms[i].id == id) 195.31 @@ -714,20 +716,13 @@ static enum xs_perm_type perm_for_id(dom 195.32 return perms[0].perms; 195.33 } 195.34 195.35 -/* We have a weird permissions system. You can allow someone into a 195.36 - * specific node without allowing it in the parents. If it's going to 195.37 - * fail, however, we don't want the errno to indicate any information 195.38 - * about the node. */ 195.39 -static int check_with_parents(struct connection *conn, const char *node, 195.40 - int errnum) 195.41 +/* What do parents say? */ 195.42 +static enum xs_perm_type ask_parents(struct connection *conn, 195.43 + const char *node) 195.44 { 195.45 struct xs_permissions *perms; 195.46 unsigned int num; 195.47 195.48 - /* We always tell them about memory failures. */ 195.49 - if (errnum == ENOMEM) 195.50 - return errnum; 195.51 - 195.52 do { 195.53 node = get_parent(node); 195.54 perms = get_perms(conn->transaction, node, &num); 195.55 @@ -739,10 +734,23 @@ static int check_with_parents(struct con 195.56 if (!perms) 195.57 corrupt(conn, "No permissions file at root"); 195.58 195.59 - if (!(perm_for_id(conn->id, perms, num) & XS_PERM_READ)) 195.60 - return EACCES; 195.61 + return perm_for_id(conn->id, perms, num); 195.62 +} 195.63 195.64 - return errnum; 195.65 +/* We have a weird permissions system. You can allow someone into a 195.66 + * specific node without allowing it in the parents. If it's going to 195.67 + * fail, however, we don't want the errno to indicate any information 195.68 + * about the node. */ 195.69 +static int errno_from_parents(struct connection *conn, const char *node, 195.70 + int errnum) 195.71 +{ 195.72 + /* We always tell them about memory failures. */ 195.73 + if (errnum == ENOMEM) 195.74 + return errnum; 195.75 + 195.76 + if (ask_parents(conn, node) & XS_PERM_READ) 195.77 + return errnum; 195.78 + return EACCES; 195.79 } 195.80 195.81 char *canonicalize(struct connection *conn, const char *node) 195.82 @@ -774,24 +782,26 @@ bool check_node_perms(struct connection 195.83 } 195.84 195.85 perms = get_perms(conn->transaction, node, &num); 195.86 - /* No permissions. If we want to create it and 195.87 - * it doesn't exist, check parent directory. */ 195.88 - if (!perms && errno == ENOENT && (perm & XS_PERM_CREATE)) { 195.89 - char *parent = get_parent(node); 195.90 - if (!parent) 195.91 - return false; 195.92 195.93 - perms = get_perms(conn->transaction, parent, &num); 195.94 - } 195.95 - if (!perms) { 195.96 - errno = check_with_parents(conn, node, errno); 195.97 + if (perms) { 195.98 + if (perm_for_id(conn->id, perms, num) & perm) 195.99 + return true; 195.100 + errno = EACCES; 195.101 return false; 195.102 } 195.103 195.104 - if (perm_for_id(conn->id, perms, num) & perm) 195.105 - return true; 195.106 + /* If it's OK not to exist, we consult parents. */ 195.107 + if (errno == ENOENT && (perm & XS_PERM_ENOENT_OK)) { 195.108 + if (ask_parents(conn, node) & perm) 195.109 + return true; 195.110 + /* Parents say they should not know. */ 195.111 + errno = EACCES; 195.112 + return false; 195.113 + } 195.114 195.115 - errno = check_with_parents(conn, node, EACCES); 195.116 + /* They might not have permission to even *see* this node, in 195.117 + * which case we return EACCES even if it's ENOENT or EIO. */ 195.118 + errno = errno_from_parents(conn, node, errno); 195.119 return false; 195.120 } 195.121 195.122 @@ -928,9 +938,9 @@ static void do_write(struct connection * 195.123 if (streq(vec[1], XS_WRITE_NONE)) 195.124 mode = XS_PERM_WRITE; 195.125 else if (streq(vec[1], XS_WRITE_CREATE)) 195.126 - mode = XS_PERM_WRITE|XS_PERM_CREATE; 195.127 + mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK; 195.128 else if (streq(vec[1], XS_WRITE_CREATE_EXCL)) 195.129 - mode = XS_PERM_WRITE|XS_PERM_CREATE; 195.130 + mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK; 195.131 else { 195.132 send_error(conn, EINVAL); 195.133 return; 195.134 @@ -949,7 +959,7 @@ static void do_write(struct connection * 195.135 } 195.136 195.137 /* Not going to create it? */ 195.138 - if (!(mode & XS_PERM_CREATE)) { 195.139 + if (streq(vec[1], XS_WRITE_NONE)) { 195.140 send_error(conn, ENOENT); 195.141 return; 195.142 } 195.143 @@ -983,7 +993,7 @@ static void do_write(struct connection * 195.144 static void do_mkdir(struct connection *conn, const char *node) 195.145 { 195.146 node = canonicalize(conn, node); 195.147 - if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) { 195.148 + if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) { 195.149 send_error(conn, errno); 195.150 return; 195.151 }
201.1 --- a/tools/xenstore/xenstored_watch.c Tue Aug 02 15:38:45 2005 -0700 201.2 +++ b/tools/xenstore/xenstored_watch.c Wed Aug 03 09:22:03 2005 +0000 201.3 @@ -95,10 +95,19 @@ static int destroy_watch_event(void *_ev 201.4 return 0; 201.5 } 201.6 201.7 -static void add_event(struct watch *watch, const char *node) 201.8 +static void add_event(struct connection *conn, 201.9 + struct watch *watch, const char *node) 201.10 { 201.11 struct watch_event *event; 201.12 201.13 + /* Check read permission: no permission, no watch event. 201.14 + * If it doesn't exist, we need permission to read parent. 201.15 + */ 201.16 + if (!check_node_perms(conn, node, XS_PERM_READ|XS_PERM_ENOENT_OK)) { 201.17 + fprintf(stderr, "No permission for %s\n", node); 201.18 + return; 201.19 + } 201.20 + 201.21 if (watch->relative_path) { 201.22 node += strlen(watch->relative_path); 201.23 if (*node == '/') /* Could be "" */ 201.24 @@ -132,9 +141,9 @@ void fire_watches(struct connection *con 201.25 201.26 list_for_each_entry(watch, &i->watches, list) { 201.27 if (is_child(node, watch->node)) 201.28 - add_event(watch, node); 201.29 + add_event(i, watch, node); 201.30 else if (recurse && is_child(watch->node, node)) 201.31 - add_event(watch, watch->node); 201.32 + add_event(i, watch, watch->node); 201.33 else 201.34 continue; 201.35 /* If connection not doing anything, queue this. */ 201.36 @@ -206,7 +215,7 @@ void do_watch(struct connection *conn, s 201.37 201.38 relative = !strstarts(vec[0], "/"); 201.39 vec[0] = canonicalize(conn, vec[0]); 201.40 - if (!check_node_perms(conn, vec[0], XS_PERM_READ)) { 201.41 + if (!is_valid_nodename(vec[0])) { 201.42 send_error(conn, errno); 201.43 return; 201.44 }
205.1 --- a/tools/xenstore/xs_lib.h Tue Aug 02 15:38:45 2005 -0700 205.2 +++ b/tools/xenstore/xs_lib.h Wed Aug 03 09:22:03 2005 +0000 205.3 @@ -30,7 +30,7 @@ enum xs_perm_type { 205.4 XS_PERM_READ = 1, 205.5 XS_PERM_WRITE = 2, 205.6 /* Internal use. */ 205.7 - XS_PERM_CREATE = 4, 205.8 + XS_PERM_ENOENT_OK = 4, 205.9 XS_PERM_OWNER = 8, 205.10 }; 205.11