Skip to contentSkip to conversation

minios: add proper shutdown facilities

PATCH New Samuel Thibault 1 participant 1 message Jun 9, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 minios: add proper shutdown facilities

minios: add proper shutdown facilities

extras/mini-os/arch/ia64/common.c +6 -0
diff -r a40c23c25b0d extras/mini-os/arch/ia64/common.c
@@ -236,6 +236,12 @@
 }
 
 void
+arch_fini(void)
+{
+	/* TODO */
+}
+
+void
 arch_print_info(void)
 {
 	int major, minor;
extras/mini-os/arch/ia64/time.c +6 -0
@@ -280,3 +280,9 @@
 	ia64_set_itm(new);
 	ia64_srlz_d();
 }
+
+void
+fini_time(void)
+{
+	/* TODO */
+}
extras/mini-os/arch/x86/setup.c +10 -0
@@ -100,6 +100,16 @@
 }
 
 void
+arch_fini(void)
+{
+#ifdef __i386__
+	HYPERVISOR_set_callbacks(0, 0, 0, 0);
+#else
+	HYPERVISOR_set_callbacks(0, 0, 0);
+#endif
+}
+
+void
 arch_print_info(void)
 {
 	printk("  stack:      %p-%p\n", stack, stack + sizeof(stack));
extras/mini-os/arch/x86/time.c +8 -1
@@ -222,10 +222,17 @@
 
 
 
+static evtchn_port_t port;
 void init_time(void)
 {
-    evtchn_port_t port;
     printk("Initialising timer interface\n");
     port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
     unmask_evtchn(port);
 }
+
+void fini_time(void)
+{
+    /* Clear any pending timer */
+    HYPERVISOR_set_timer_op(0);
+    unbind_evtchn(port);
+}
extras/mini-os/arch/x86/traps.c +4 -0
@@ -268,3 +268,7 @@
     HYPERVISOR_set_trap_table(trap_table);    
 }
 
+void trap_fini(void)
+{
+    HYPERVISOR_set_trap_table(NULL);
+}
extras/mini-os/blkfront.c +2 -0
@@ -239,6 +239,8 @@
     xenbus_wait_for_value(path, "6", &dev->events);
 
     xenbus_unwatch_path(XBT_NIL, path);
+
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
 
     free_blkfront(dev);
 }
extras/mini-os/console/console.c +5 -0
@@ -150,3 +150,8 @@
     /* This is also required to notify the daemon */
     printk("done.\n");
 }
+
+void fini_console(void)
+{
+    /* Destruct the console and get the parameters of the restarted one */
+}
extras/mini-os/events.c +30 -3
@@ -39,19 +39,29 @@
 void unbind_all_ports(void)
 {
     int i;
+    int cpu = 0;
+    shared_info_t *s = HYPERVISOR_shared_info;
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
     for (i = 0; i < NR_EVS; i++)
     {
+        if (i == start_info.console.domU.evtchn ||
+            i == start_info.store_evtchn)
+            continue;
         if (test_and_clear_bit(i, bound_ports))
         {
             struct evtchn_close close;
+            printk("port %d still bound!\n", i);
             mask_evtchn(i);
             close.port = i;
             HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+            clear_evtchn(i);
         }
     }
+    vcpu_info->evtchn_upcall_pending = 0;
+    vcpu_info->evtchn_pending_sel = 0;
 }
-  
+
 /*
  * Demux events to different handlers.
  */
@@ -86,17 +96,27 @@
 	ev_actions[port].data = data;
 	wmb();
 	ev_actions[port].handler = handler;
+	set_bit(port, bound_ports);
 
 	return port;
 }
 
 void unbind_evtchn(evtchn_port_t port )
 {
+	struct evtchn_close close;
+
 	if (ev_actions[port].handler == default_handler)
 		printk("WARN: No handler for port %d when unbinding\n", port);
+	mask_evtchn(port);
+	clear_evtchn(port);
+
 	ev_actions[port].handler = default_handler;
 	wmb();
 	ev_actions[port].data = NULL;
+	clear_bit(port, bound_ports);
+
+	close.port = port;
+	HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
 }
 
 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
@@ -112,7 +132,6 @@
 		printk("Failed to bind virtual IRQ %d\n", virq);
 		return -1;
     }
-    set_bit(op.port,bound_ports);
     bind_evtchn(op.port, handler, data);
 	return op.port;
 }
@@ -145,6 +164,15 @@
         ev_actions[i].handler = default_handler;
         mask_evtchn(i);
     }
+}
+
+void fini_events(void)
+{
+    /* Dealloc all events */
+    unbind_all_ports();
+#if defined(__x86_64__)
+    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
 }
 
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
@@ -185,7 +213,6 @@
     int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
     if (err)
 		return err;
-    set_bit(op.local_port,bound_ports);
     evtchn_port_t port = op.local_port;
     *local_port = bind_evtchn(port, handler, data);
     return err;
extras/mini-os/fbfront.c +4 -0
@@ -224,6 +224,8 @@
     xenbus_wait_for_value(path, "6", &dev->events);
 
     xenbus_unwatch_path(XBT_NIL, path);
+
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
 
     free_kbdfront(dev);
 }
@@ -549,6 +551,8 @@
 
     xenbus_unwatch_path(XBT_NIL, path);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+
     unbind_evtchn(dev->evtchn);
 
     free_fbfront(dev);
extras/mini-os/fs-front.c +2 -0
@@ -1127,3 +1127,5 @@
     if (!fs_import)
 	printk("No FS import\n");
 }
+
+/* TODO: shutdown */
extras/mini-os/gnttab.c +11 -0
@@ -193,3 +193,14 @@
     gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
     printk("gnttab_table mapped at %p.\n", gnttab_table);
 }
+
+void
+fini_gnttab(void)
+{
+    struct gnttab_setup_table setup;
+
+    setup.dom = DOMID_SELF;
+    setup.nr_frames = 0;
+
+    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+}
extras/mini-os/include/console.h +1 -0
@@ -51,6 +51,7 @@
 
 void init_console(void);
 void console_print(char *data, int length);
+void fini_console(void);
 
 /* Low level functions defined in xencons_ring.c */
 extern struct wait_queue_head console_queue;
extras/mini-os/include/events.h +1 -0
@@ -45,5 +45,6 @@
     return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
 }
 
+void fini_events(void);
 
 #endif /* _EVENTS_H_ */
extras/mini-os/include/gnttab.h +1 -0
@@ -11,5 +11,6 @@
 unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
 const char *gnttabop_error(int16_t status);
+void fini_gnttab(void);
 
 #endif /* !__GNTTAB_H__ */
extras/mini-os/include/ia64/os.h +2 -1
@@ -35,6 +35,7 @@
 #include "sal.h"
 #include "pal.h"
 #include "hypervisor.h"
+#include <kernel.h>
 
 
 typedef uint64_t paddr_t;		/* Physical address. */
@@ -46,9 +47,9 @@
 #include "mm.h"
 
 
-void do_exit(void) __attribute__((noreturn));
 void arch_init(start_info_t *si);	/* in common.c */
 void arch_print_info(void);		/* in common.c */
+void arch_fini(void);
 
 
 /* Size of xen_ia64_boot_param.command_line */
extras/mini-os/include/ia64/traps.h +4 -0
@@ -38,6 +38,10 @@
 {
 	//printk("trap_init() until now not needed!\n");
 }
+inline static void trap_fini(void)
+{
+	//printk("trap_fini() until now not needed!\n");
+}
 
 
 #endif /* !defined(__ASSEMBLY__) */
extras/mini-os/include/kernel.h new file +7 -0
@@ -0,0 +1,7 @@
+#ifndef _KERNEL_H_
+#define _KERNEL_H_
+
+extern void do_exit(void) __attribute__((noreturn));
+extern void stop_kernel(void);
+
+#endif /* _KERNEL_H_ */
extras/mini-os/include/mm.h +1 -0
@@ -75,5 +75,6 @@
 #endif
 
 int free_physical_pages(xen_pfn_t *mfns, int n);
+void fini_mm(void);
 
 #endif /* _MM_H_ */
extras/mini-os/include/netfront.h +1 -0
@@ -18,6 +18,7 @@
  * N.B. _must_ be called from a thread; it's not safe to call this from 
  * app_main(). */
 void start_networking(void);
+void stop_networking(void);
 
 void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw);
 #endif
extras/mini-os/include/time.h +1 -0
@@ -54,6 +54,7 @@
 
 /* prototypes */
 void     init_time(void);
+void     fini_time(void);
 s_time_t get_s_time(void);
 s_time_t get_v_time(void);
 u64      monotonic_clock(void);
extras/mini-os/include/x86/os.h +3 -1
@@ -18,10 +18,10 @@
 #ifndef __ASSEMBLY__
 #include <types.h>
 #include <hypervisor.h>
+#include <kernel.h>
 
 #define USED    __attribute__ ((used))
 
-extern void do_exit(void) __attribute__((noreturn));
 #define BUG do_exit
 
 #endif
@@ -61,9 +61,11 @@
 extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
+void trap_fini(void);
 
 void arch_init(start_info_t *si);
 void arch_print_info(void);
+void arch_fini(void);
 
 
 
extras/mini-os/include/xenbus.h +3 -0
@@ -90,4 +90,7 @@
                                   char* node, char* path,
                                   char* fmt, ...);
 
+/* Reset the XenBus system. */
+void fini_xenbus(void);
+
 #endif /* XENBUS_H__ */
extras/mini-os/kernel.c +46 -2

74 lines not on this page · raw message

extras/mini-os/lwip-net.c +6 -0
@@ -376,3 +376,9 @@
 
   tprintk("Network is ready.\n");
 }
+
+/* Shut down the network */
+void stop_networking(void)
+{
+  shutdown_netfront(dev);
+}
extras/mini-os/mm.c +4 -0
@@ -419,6 +419,10 @@
     arch_init_demand_mapping_area(max_pfn);
 }
 
+void fini_mm(void)
+{
+}
+
 void sanity_check(void)
 {
     int x;
extras/mini-os/netfront.c +2 -0
@@ -501,6 +501,8 @@
 
     xenbus_unwatch_path(XBT_NIL, path);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+
     free_netfront(dev);
 }
 
extras/mini-os/xenbus/xenbus.c +13 -4
@@ -124,7 +124,7 @@
 static void xenbus_thread_func(void *ign)
 {
     struct xsd_sockmsg msg;
-    unsigned prod = 0;
+    unsigned prod = xenstore_buf->rsp_prod;
 
     for (;;) 
     {
@@ -174,9 +174,14 @@
                         break;
                     }
 
-		event->next = *events;
-		*events = event;
-                wake_up(&xenbus_watch_queue);
+                if (events) {
+                    event->next = *events;
+                    *events = event;
+                    wake_up(&xenbus_watch_queue);
+                } else {
+                    printk("unexpected watch token %s\n", event->token);
+                    free(event);
+                }
             }
 
             else
@@ -263,6 +268,10 @@
               NULL);
     unmask_evtchn(start_info.store_evtchn);
     DEBUG("xenbus on irq %d\n", err);
+}
+
+void fini_xenbus(void)
+{
 }
 
 /* Send data to xenbus.  This can block.  All of the requests are seen