ia64/xen-unstable

changeset 17812:2197a263a300

minios: add proper shutdown facilities

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jun 09 13:26:30 2008 +0100 (2008-06-09)
parents 8b5b0512ed6a
children adf05a812edb
files extras/mini-os/arch/ia64/common.c extras/mini-os/arch/ia64/time.c extras/mini-os/arch/x86/setup.c extras/mini-os/arch/x86/time.c extras/mini-os/arch/x86/traps.c extras/mini-os/blkfront.c extras/mini-os/console/console.c extras/mini-os/events.c extras/mini-os/fbfront.c extras/mini-os/fs-front.c extras/mini-os/gnttab.c extras/mini-os/include/console.h extras/mini-os/include/events.h extras/mini-os/include/gnttab.h extras/mini-os/include/ia64/os.h extras/mini-os/include/ia64/traps.h extras/mini-os/include/kernel.h extras/mini-os/include/mm.h extras/mini-os/include/netfront.h extras/mini-os/include/time.h extras/mini-os/include/x86/os.h extras/mini-os/include/xenbus.h extras/mini-os/kernel.c extras/mini-os/lwip-net.c extras/mini-os/mm.c extras/mini-os/netfront.c extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/arch/ia64/common.c	Mon Jun 09 13:26:05 2008 +0100
     1.2 +++ b/extras/mini-os/arch/ia64/common.c	Mon Jun 09 13:26:30 2008 +0100
     1.3 @@ -236,6 +236,12 @@ arch_init(start_info_t *si)
     1.4  }
     1.5  
     1.6  void
     1.7 +arch_fini(void)
     1.8 +{
     1.9 +	/* TODO */
    1.10 +}
    1.11 +
    1.12 +void
    1.13  arch_print_info(void)
    1.14  {
    1.15  	int major, minor;
     2.1 --- a/extras/mini-os/arch/ia64/time.c	Mon Jun 09 13:26:05 2008 +0100
     2.2 +++ b/extras/mini-os/arch/ia64/time.c	Mon Jun 09 13:26:30 2008 +0100
     2.3 @@ -280,3 +280,9 @@ init_time(void)
     2.4  	ia64_set_itm(new);
     2.5  	ia64_srlz_d();
     2.6  }
     2.7 +
     2.8 +void
     2.9 +fini_time(void)
    2.10 +{
    2.11 +	/* TODO */
    2.12 +}
     3.1 --- a/extras/mini-os/arch/x86/setup.c	Mon Jun 09 13:26:05 2008 +0100
     3.2 +++ b/extras/mini-os/arch/x86/setup.c	Mon Jun 09 13:26:30 2008 +0100
     3.3 @@ -100,6 +100,16 @@ arch_init(start_info_t *si)
     3.4  }
     3.5  
     3.6  void
     3.7 +arch_fini(void)
     3.8 +{
     3.9 +#ifdef __i386__
    3.10 +	HYPERVISOR_set_callbacks(0, 0, 0, 0);
    3.11 +#else
    3.12 +	HYPERVISOR_set_callbacks(0, 0, 0);
    3.13 +#endif
    3.14 +}
    3.15 +
    3.16 +void
    3.17  arch_print_info(void)
    3.18  {
    3.19  	printk("  stack:      %p-%p\n", stack, stack + sizeof(stack));
     4.1 --- a/extras/mini-os/arch/x86/time.c	Mon Jun 09 13:26:05 2008 +0100
     4.2 +++ b/extras/mini-os/arch/x86/time.c	Mon Jun 09 13:26:30 2008 +0100
     4.3 @@ -222,10 +222,17 @@ static void timer_handler(evtchn_port_t 
     4.4  
     4.5  
     4.6  
     4.7 +static evtchn_port_t port;
     4.8  void init_time(void)
     4.9  {
    4.10 -    evtchn_port_t port;
    4.11      printk("Initialising timer interface\n");
    4.12      port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
    4.13      unmask_evtchn(port);
    4.14  }
    4.15 +
    4.16 +void fini_time(void)
    4.17 +{
    4.18 +    /* Clear any pending timer */
    4.19 +    HYPERVISOR_set_timer_op(0);
    4.20 +    unbind_evtchn(port);
    4.21 +}
     5.1 --- a/extras/mini-os/arch/x86/traps.c	Mon Jun 09 13:26:05 2008 +0100
     5.2 +++ b/extras/mini-os/arch/x86/traps.c	Mon Jun 09 13:26:30 2008 +0100
     5.3 @@ -268,3 +268,7 @@ void trap_init(void)
     5.4      HYPERVISOR_set_trap_table(trap_table);    
     5.5  }
     5.6  
     5.7 +void trap_fini(void)
     5.8 +{
     5.9 +    HYPERVISOR_set_trap_table(NULL);
    5.10 +}
     6.1 --- a/extras/mini-os/blkfront.c	Mon Jun 09 13:26:05 2008 +0100
     6.2 +++ b/extras/mini-os/blkfront.c	Mon Jun 09 13:26:30 2008 +0100
     6.3 @@ -240,6 +240,8 @@ void shutdown_blkfront(struct blkfront_d
     6.4  
     6.5      xenbus_unwatch_path(XBT_NIL, path);
     6.6  
     6.7 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
     6.8 +
     6.9      free_blkfront(dev);
    6.10  }
    6.11  
     7.1 --- a/extras/mini-os/console/console.c	Mon Jun 09 13:26:05 2008 +0100
     7.2 +++ b/extras/mini-os/console/console.c	Mon Jun 09 13:26:30 2008 +0100
     7.3 @@ -150,3 +150,8 @@ void init_console(void)
     7.4      /* This is also required to notify the daemon */
     7.5      printk("done.\n");
     7.6  }
     7.7 +
     7.8 +void fini_console(void)
     7.9 +{
    7.10 +    /* Destruct the console and get the parameters of the restarted one */
    7.11 +}
     8.1 --- a/extras/mini-os/events.c	Mon Jun 09 13:26:05 2008 +0100
     8.2 +++ b/extras/mini-os/events.c	Mon Jun 09 13:26:30 2008 +0100
     8.3 @@ -39,19 +39,29 @@ static unsigned long bound_ports[NR_EVS/
     8.4  void unbind_all_ports(void)
     8.5  {
     8.6      int i;
     8.7 +    int cpu = 0;
     8.8 +    shared_info_t *s = HYPERVISOR_shared_info;
     8.9 +    vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
    8.10  
    8.11      for (i = 0; i < NR_EVS; i++)
    8.12      {
    8.13 +        if (i == start_info.console.domU.evtchn ||
    8.14 +            i == start_info.store_evtchn)
    8.15 +            continue;
    8.16          if (test_and_clear_bit(i, bound_ports))
    8.17          {
    8.18              struct evtchn_close close;
    8.19 +            printk("port %d still bound!\n", i);
    8.20              mask_evtchn(i);
    8.21              close.port = i;
    8.22              HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
    8.23 +            clear_evtchn(i);
    8.24          }
    8.25      }
    8.26 +    vcpu_info->evtchn_upcall_pending = 0;
    8.27 +    vcpu_info->evtchn_pending_sel = 0;
    8.28  }
    8.29 -  
    8.30 +
    8.31  /*
    8.32   * Demux events to different handlers.
    8.33   */
    8.34 @@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t 
    8.35  	ev_actions[port].data = data;
    8.36  	wmb();
    8.37  	ev_actions[port].handler = handler;
    8.38 +	set_bit(port, bound_ports);
    8.39  
    8.40  	return port;
    8.41  }
    8.42  
    8.43  void unbind_evtchn(evtchn_port_t port )
    8.44  {
    8.45 +	struct evtchn_close close;
    8.46 +
    8.47  	if (ev_actions[port].handler == default_handler)
    8.48  		printk("WARN: No handler for port %d when unbinding\n", port);
    8.49 +	mask_evtchn(port);
    8.50 +	clear_evtchn(port);
    8.51 +
    8.52  	ev_actions[port].handler = default_handler;
    8.53  	wmb();
    8.54  	ev_actions[port].data = NULL;
    8.55 +	clear_bit(port, bound_ports);
    8.56 +
    8.57 +	close.port = port;
    8.58 +	HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
    8.59  }
    8.60  
    8.61  evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
    8.62 @@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, e
    8.63  		printk("Failed to bind virtual IRQ %d\n", virq);
    8.64  		return -1;
    8.65      }
    8.66 -    set_bit(op.port,bound_ports);
    8.67      bind_evtchn(op.port, handler, data);
    8.68  	return op.port;
    8.69  }
    8.70 @@ -147,6 +166,15 @@ void init_events(void)
    8.71      }
    8.72  }
    8.73  
    8.74 +void fini_events(void)
    8.75 +{
    8.76 +    /* Dealloc all events */
    8.77 +    unbind_all_ports();
    8.78 +#if defined(__x86_64__)
    8.79 +    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
    8.80 +#endif
    8.81 +}
    8.82 +
    8.83  void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
    8.84  {
    8.85      printk("[Port %d] - event received\n", port);
    8.86 @@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal,
    8.87      int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
    8.88      if (err)
    8.89  		return err;
    8.90 -    set_bit(op.local_port,bound_ports);
    8.91      evtchn_port_t port = op.local_port;
    8.92      *local_port = bind_evtchn(port, handler, data);
    8.93      return err;
     9.1 --- a/extras/mini-os/fbfront.c	Mon Jun 09 13:26:05 2008 +0100
     9.2 +++ b/extras/mini-os/fbfront.c	Mon Jun 09 13:26:30 2008 +0100
     9.3 @@ -225,6 +225,8 @@ void shutdown_kbdfront(struct kbdfront_d
     9.4  
     9.5      xenbus_unwatch_path(XBT_NIL, path);
     9.6  
     9.7 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
     9.8 +
     9.9      free_kbdfront(dev);
    9.10  }
    9.11  
    9.12 @@ -549,6 +551,8 @@ void shutdown_fbfront(struct fbfront_dev
    9.13  
    9.14      xenbus_unwatch_path(XBT_NIL, path);
    9.15  
    9.16 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    9.17 +
    9.18      unbind_evtchn(dev->evtchn);
    9.19  
    9.20      free_fbfront(dev);
    10.1 --- a/extras/mini-os/fs-front.c	Mon Jun 09 13:26:05 2008 +0100
    10.2 +++ b/extras/mini-os/fs-front.c	Mon Jun 09 13:26:30 2008 +0100
    10.3 @@ -1127,3 +1127,5 @@ void init_fs_frontend(void)
    10.4      if (!fs_import)
    10.5  	printk("No FS import\n");
    10.6  }
    10.7 +
    10.8 +/* TODO: shutdown */
    11.1 --- a/extras/mini-os/gnttab.c	Mon Jun 09 13:26:05 2008 +0100
    11.2 +++ b/extras/mini-os/gnttab.c	Mon Jun 09 13:26:30 2008 +0100
    11.3 @@ -193,3 +193,14 @@ init_gnttab(void)
    11.4      gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
    11.5      printk("gnttab_table mapped at %p.\n", gnttab_table);
    11.6  }
    11.7 +
    11.8 +void
    11.9 +fini_gnttab(void)
   11.10 +{
   11.11 +    struct gnttab_setup_table setup;
   11.12 +
   11.13 +    setup.dom = DOMID_SELF;
   11.14 +    setup.nr_frames = 0;
   11.15 +
   11.16 +    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
   11.17 +}
    12.1 --- a/extras/mini-os/include/console.h	Mon Jun 09 13:26:05 2008 +0100
    12.2 +++ b/extras/mini-os/include/console.h	Mon Jun 09 13:26:30 2008 +0100
    12.3 @@ -51,6 +51,7 @@ void xencons_tx(void);
    12.4  
    12.5  void init_console(void);
    12.6  void console_print(char *data, int length);
    12.7 +void fini_console(void);
    12.8  
    12.9  /* Low level functions defined in xencons_ring.c */
   12.10  extern struct wait_queue_head console_queue;
    13.1 --- a/extras/mini-os/include/events.h	Mon Jun 09 13:26:05 2008 +0100
    13.2 +++ b/extras/mini-os/include/events.h	Mon Jun 09 13:26:30 2008 +0100
    13.3 @@ -45,5 +45,6 @@ static inline int notify_remote_via_evtc
    13.4      return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
    13.5  }
    13.6  
    13.7 +void fini_events(void);
    13.8  
    13.9  #endif /* _EVENTS_H_ */
    14.1 --- a/extras/mini-os/include/gnttab.h	Mon Jun 09 13:26:05 2008 +0100
    14.2 +++ b/extras/mini-os/include/gnttab.h	Mon Jun 09 13:26:30 2008 +0100
    14.3 @@ -11,5 +11,6 @@ grant_ref_t gnttab_grant_transfer(domid_
    14.4  unsigned long gnttab_end_transfer(grant_ref_t gref);
    14.5  int gnttab_end_access(grant_ref_t ref);
    14.6  const char *gnttabop_error(int16_t status);
    14.7 +void fini_gnttab(void);
    14.8  
    14.9  #endif /* !__GNTTAB_H__ */
    15.1 --- a/extras/mini-os/include/ia64/os.h	Mon Jun 09 13:26:05 2008 +0100
    15.2 +++ b/extras/mini-os/include/ia64/os.h	Mon Jun 09 13:26:30 2008 +0100
    15.3 @@ -35,6 +35,7 @@
    15.4  #include "sal.h"
    15.5  #include "pal.h"
    15.6  #include "hypervisor.h"
    15.7 +#include <kernel.h>
    15.8  
    15.9  
   15.10  typedef uint64_t paddr_t;		/* Physical address. */
   15.11 @@ -46,9 +47,9 @@ typedef uint64_t caddr_t;		/* rr7/kernel
   15.12  #include "mm.h"
   15.13  
   15.14  
   15.15 -void do_exit(void) __attribute__((noreturn));
   15.16  void arch_init(start_info_t *si);	/* in common.c */
   15.17  void arch_print_info(void);		/* in common.c */
   15.18 +void arch_fini(void);
   15.19  
   15.20  
   15.21  /* Size of xen_ia64_boot_param.command_line */
    16.1 --- a/extras/mini-os/include/ia64/traps.h	Mon Jun 09 13:26:05 2008 +0100
    16.2 +++ b/extras/mini-os/include/ia64/traps.h	Mon Jun 09 13:26:30 2008 +0100
    16.3 @@ -38,6 +38,10 @@ inline static void trap_init(void)
    16.4  {
    16.5  	//printk("trap_init() until now not needed!\n");
    16.6  }
    16.7 +inline static void trap_fini(void)
    16.8 +{
    16.9 +	//printk("trap_fini() until now not needed!\n");
   16.10 +}
   16.11  
   16.12  
   16.13  #endif /* !defined(__ASSEMBLY__) */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/extras/mini-os/include/kernel.h	Mon Jun 09 13:26:30 2008 +0100
    17.3 @@ -0,0 +1,7 @@
    17.4 +#ifndef _KERNEL_H_
    17.5 +#define _KERNEL_H_
    17.6 +
    17.7 +extern void do_exit(void) __attribute__((noreturn));
    17.8 +extern void stop_kernel(void);
    17.9 +
   17.10 +#endif /* _KERNEL_H_ */
    18.1 --- a/extras/mini-os/include/mm.h	Mon Jun 09 13:26:05 2008 +0100
    18.2 +++ b/extras/mini-os/include/mm.h	Mon Jun 09 13:26:30 2008 +0100
    18.3 @@ -75,5 +75,6 @@ extern unsigned long heap, brk, heap_map
    18.4  #endif
    18.5  
    18.6  int free_physical_pages(xen_pfn_t *mfns, int n);
    18.7 +void fini_mm(void);
    18.8  
    18.9  #endif /* _MM_H_ */
    19.1 --- a/extras/mini-os/include/netfront.h	Mon Jun 09 13:26:05 2008 +0100
    19.2 +++ b/extras/mini-os/include/netfront.h	Mon Jun 09 13:26:30 2008 +0100
    19.3 @@ -18,6 +18,7 @@ extern struct wait_queue_head netfront_q
    19.4   * N.B. _must_ be called from a thread; it's not safe to call this from 
    19.5   * app_main(). */
    19.6  void start_networking(void);
    19.7 +void stop_networking(void);
    19.8  
    19.9  void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw);
   19.10  #endif
    20.1 --- a/extras/mini-os/include/time.h	Mon Jun 09 13:26:05 2008 +0100
    20.2 +++ b/extras/mini-os/include/time.h	Mon Jun 09 13:26:30 2008 +0100
    20.3 @@ -54,6 +54,7 @@ typedef long suseconds_t;
    20.4  
    20.5  /* prototypes */
    20.6  void     init_time(void);
    20.7 +void     fini_time(void);
    20.8  s_time_t get_s_time(void);
    20.9  s_time_t get_v_time(void);
   20.10  u64      monotonic_clock(void);
    21.1 --- a/extras/mini-os/include/x86/os.h	Mon Jun 09 13:26:05 2008 +0100
    21.2 +++ b/extras/mini-os/include/x86/os.h	Mon Jun 09 13:26:30 2008 +0100
    21.3 @@ -18,10 +18,10 @@
    21.4  #ifndef __ASSEMBLY__
    21.5  #include <types.h>
    21.6  #include <hypervisor.h>
    21.7 +#include <kernel.h>
    21.8  
    21.9  #define USED    __attribute__ ((used))
   21.10  
   21.11 -extern void do_exit(void) __attribute__((noreturn));
   21.12  #define BUG do_exit
   21.13  
   21.14  #endif
   21.15 @@ -61,9 +61,11 @@ extern void do_exit(void) __attribute__(
   21.16  extern shared_info_t *HYPERVISOR_shared_info;
   21.17  
   21.18  void trap_init(void);
   21.19 +void trap_fini(void);
   21.20  
   21.21  void arch_init(start_info_t *si);
   21.22  void arch_print_info(void);
   21.23 +void arch_fini(void);
   21.24  
   21.25  
   21.26  
    22.1 --- a/extras/mini-os/include/xenbus.h	Mon Jun 09 13:26:05 2008 +0100
    22.2 +++ b/extras/mini-os/include/xenbus.h	Mon Jun 09 13:26:30 2008 +0100
    22.3 @@ -90,4 +90,7 @@ char* xenbus_printf(xenbus_transaction_t
    22.4                                    char* node, char* path,
    22.5                                    char* fmt, ...);
    22.6  
    22.7 +/* Reset the XenBus system. */
    22.8 +void fini_xenbus(void);
    22.9 +
   22.10  #endif /* XENBUS_H__ */
    23.1 --- a/extras/mini-os/kernel.c	Mon Jun 09 13:26:05 2008 +0100
    23.2 +++ b/extras/mini-os/kernel.c	Mon Jun 09 13:26:30 2008 +0100
    23.3 @@ -46,6 +46,7 @@
    23.4  #include <xen/features.h>
    23.5  #include <xen/version.h>
    23.6  
    23.7 +static struct netfront_dev *net_dev;
    23.8  
    23.9  u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
   23.10  
   23.11 @@ -87,7 +88,7 @@ static void periodic_thread(void *p)
   23.12  
   23.13  static void netfront_thread(void *p)
   23.14  {
   23.15 -    init_netfront(NULL, NULL, NULL, NULL);
   23.16 +    net_dev = init_netfront(NULL, NULL, NULL, NULL);
   23.17  }
   23.18  
   23.19  static struct blkfront_dev *blk_dev;
   23.20 @@ -347,9 +348,9 @@ static void refresh_cursor(int new_x, in
   23.21      fbfront_update(fb_dev, new_x, new_y, 9, 9);
   23.22  }
   23.23  
   23.24 +static struct kbdfront_dev *kbd_dev;
   23.25  static void kbdfront_thread(void *p)
   23.26  {
   23.27 -    struct kbdfront_dev *kbd_dev;
   23.28      DEFINE_WAIT(w);
   23.29      int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
   23.30  
   23.31 @@ -509,6 +510,49 @@ void start_kernel(start_info_t *si)
   23.32      run_idle_thread();
   23.33  }
   23.34  
   23.35 +void stop_kernel(void)
   23.36 +{
   23.37 +    if (net_dev)
   23.38 +        shutdown_netfront(net_dev);
   23.39 +
   23.40 +    if (blk_dev)
   23.41 +        shutdown_blkfront(blk_dev);
   23.42 +
   23.43 +    if (fb_dev)
   23.44 +        shutdown_fbfront(fb_dev);
   23.45 +
   23.46 +    if (kbd_dev)
   23.47 +        shutdown_kbdfront(kbd_dev);
   23.48 +
   23.49 +    /* TODO: fs import */
   23.50 +
   23.51 +    local_irq_disable();
   23.52 +
   23.53 +    /* Reset grant tables */
   23.54 +    fini_gnttab();
   23.55 +
   23.56 +    /* Reset the console driver. */
   23.57 +    fini_console();
   23.58 +    /* TODO: record new ring mfn & event in start_info */
   23.59 +
   23.60 +    /* Reset XenBus */
   23.61 +    fini_xenbus();
   23.62 +
   23.63 +    /* Reset timers */
   23.64 +    fini_time();
   23.65 +
   23.66 +    /* Reset memory management. */
   23.67 +    fini_mm();
   23.68 +
   23.69 +    /* Reset events. */
   23.70 +    fini_events();
   23.71 +
   23.72 +    /* Reset traps */
   23.73 +    trap_fini();
   23.74 +
   23.75 +    /* Reset arch details */
   23.76 +    arch_fini();
   23.77 +}
   23.78  
   23.79  /*
   23.80   * do_exit: This is called whenever an IRET fails in entry.S.
    24.1 --- a/extras/mini-os/lwip-net.c	Mon Jun 09 13:26:05 2008 +0100
    24.2 +++ b/extras/mini-os/lwip-net.c	Mon Jun 09 13:26:30 2008 +0100
    24.3 @@ -376,3 +376,9 @@ void start_networking(void)
    24.4  
    24.5    tprintk("Network is ready.\n");
    24.6  }
    24.7 +
    24.8 +/* Shut down the network */
    24.9 +void stop_networking(void)
   24.10 +{
   24.11 +  shutdown_netfront(dev);
   24.12 +}
    25.1 --- a/extras/mini-os/mm.c	Mon Jun 09 13:26:05 2008 +0100
    25.2 +++ b/extras/mini-os/mm.c	Mon Jun 09 13:26:30 2008 +0100
    25.3 @@ -419,6 +419,10 @@ void init_mm(void)
    25.4      arch_init_demand_mapping_area(max_pfn);
    25.5  }
    25.6  
    25.7 +void fini_mm(void)
    25.8 +{
    25.9 +}
   25.10 +
   25.11  void sanity_check(void)
   25.12  {
   25.13      int x;
    26.1 --- a/extras/mini-os/netfront.c	Mon Jun 09 13:26:05 2008 +0100
    26.2 +++ b/extras/mini-os/netfront.c	Mon Jun 09 13:26:30 2008 +0100
    26.3 @@ -501,6 +501,8 @@ void shutdown_netfront(struct netfront_d
    26.4  
    26.5      xenbus_unwatch_path(XBT_NIL, path);
    26.6  
    26.7 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    26.8 +
    26.9      free_netfront(dev);
   26.10  }
   26.11  
    27.1 --- a/extras/mini-os/xenbus/xenbus.c	Mon Jun 09 13:26:05 2008 +0100
    27.2 +++ b/extras/mini-os/xenbus/xenbus.c	Mon Jun 09 13:26:30 2008 +0100
    27.3 @@ -124,7 +124,7 @@ char* xenbus_wait_for_value(const char* 
    27.4  static void xenbus_thread_func(void *ign)
    27.5  {
    27.6      struct xsd_sockmsg msg;
    27.7 -    unsigned prod = 0;
    27.8 +    unsigned prod = xenstore_buf->rsp_prod;
    27.9  
   27.10      for (;;) 
   27.11      {
   27.12 @@ -174,9 +174,14 @@ static void xenbus_thread_func(void *ign
   27.13                          break;
   27.14                      }
   27.15  
   27.16 -		event->next = *events;
   27.17 -		*events = event;
   27.18 -                wake_up(&xenbus_watch_queue);
   27.19 +                if (events) {
   27.20 +                    event->next = *events;
   27.21 +                    *events = event;
   27.22 +                    wake_up(&xenbus_watch_queue);
   27.23 +                } else {
   27.24 +                    printk("unexpected watch token %s\n", event->token);
   27.25 +                    free(event);
   27.26 +                }
   27.27              }
   27.28  
   27.29              else
   27.30 @@ -265,6 +270,10 @@ void init_xenbus(void)
   27.31      DEBUG("xenbus on irq %d\n", err);
   27.32  }
   27.33  
   27.34 +void fini_xenbus(void)
   27.35 +{
   27.36 +}
   27.37 +
   27.38  /* Send data to xenbus.  This can block.  All of the requests are seen
   27.39     by xenbus as if sent atomically.  The header is added
   27.40     automatically, using type %type, req_id %req_id, and trans_id