[issue647] rough-draft VKERNEL host-initiated shutdown patch

Chris Turner c.turner at 199technologies.org
Sun Jun 17 09:24:01 PDT 2007


Chris Turner wrote:

> 
> Okay. All set (+= roff updates per Sascha).
> 

updated -u format, per Sacha. Good eyes! (or bad ones on my part :)

Thanks,

- Chris

Index: share/man/man7/vkernel.7
===================================================================
RCS file: /var/local/apps/dcvs/src/share/man/man7/vkernel.7,v
retrieving revision 1.18
diff -u -r1.18 vkernel.7
--- share/man/man7/vkernel.7	14 Jun 2007 21:11:29 -0000	1.18
+++ share/man/man7/vkernel.7	17 Jun 2007 04:05:58 -0000
@@ -202,15 +206,24 @@
 .Xr tap 4
 device.
 .Sh SIGNALS
-The virtual kernel enables all terminal signals while in
-.Xr ddb 4
-mode but only enables
+The virtual kernel only enables 
+.Dv SIGQUIT
+and 
+.Dv SIGTERM 
+while operating in regular console mode. 
+Sending 
 .Ql \&^\e
 .Pq Dv SIGQUIT
-while operating as a console which causes the virtual kernel to enter its
-internal
+to the virtual kernel causes the virtual kernel to enter its internal
 .Xr ddb 4
-debugger.
+debugger and re-enable all other terminal signals. 
+Sending
+.Dv SIGTERM 
+to the virtual kernel triggers a clean shutdown by passing a 
+.Dv SIGUSR2 
+to the virtual kernel's 
+.Xr init 8
+process.
 .Sh DEBUGGING
 It is possible to directly gdb the virtual kernel's process.
 It is recommended that you do a
Index: sys/platform/vkernel/i386/exception.c
===================================================================
RCS file: /var/local/apps/dcvs/src/sys/platform/vkernel/i386/exception.c,v
retrieving revision 1.5
diff -u -r1.5 exception.c
--- sys/platform/vkernel/i386/exception.c	15 Jan 2007 05:27:29 -0000	1.5
+++ sys/platform/vkernel/i386/exception.c	16 Jun 2007 23:08:05 -0000
@@ -39,6 +39,8 @@
 #include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/reboot.h>
 #include <ddb/ddb.h>
 
 #include <sys/thread2.h>
@@ -56,6 +58,14 @@
 static void exc_debugger(int signo, siginfo_t *info, void *ctx);
 #endif
 
+/* signal shutdown thread misc. */
+
+static void sigshutdown_daemon( void );
+static struct thread *sigshutdown_thread;
+static struct kproc_desc sigshut_kp = {
+	"sigshutdown", sigshutdown_daemon, &sigshutdown_thread
+};
+
 void
 init_exceptions(void)
 {
@@ -67,10 +77,17 @@
 	sigemptyset(&sa.sa_mask);
 	sigaction(SIGSEGV, &sa, NULL);
 	sigaction(SIGTRAP, &sa, NULL);
+
 #ifdef DDB
 	sa.sa_sigaction = exc_debugger;
 	sigaction(SIGQUIT, &sa, NULL);
 #endif
+
+	bzero(&sa, sizeof(sa));
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags |= SA_MAILBOX | SA_NODEFER;
+	sa.sa_mailbox = &mdcpu->gd_shutdown;
+	sigaction(SIGTERM, &sa, NULL);
 }
 
 /*
@@ -95,6 +112,31 @@
 	splz();
 }
 
+/*
+ * This function runs in a thread dedicated to external shutdown signals.
+ *
+ * Currently, when a vkernel recieves a SIGTERM, either the VKERNEL init(8) 
+ * is signaled with SIGUSR2, or the VKERNEL simply shuts down, preventing
+ * fsck's when the VKERNEL is restarted.
+ */ 
+static void
+sigshutdown_daemon( void )
+{
+	while (mdcpu->gd_shutdown == 0) {
+		tsleep(&mdcpu->gd_shutdown, 0, "sswait", 0);
+	}
+	mdcpu->gd_shutdown = 0;
+	kprintf("Caught SIGTERM from host system. Shutting down...\n");
+	if (initproc != NULL) {
+		ksignal(initproc, SIGUSR2);
+	}
+	else {
+		reboot(RB_POWEROFF);
+	}	
+}
+SYSINIT(sigshutdown, SI_BOOT2_PROC0, SI_ORDER_ANY, 
+	kproc_start, &sigshut_kp); 
+
 #ifdef DDB
 
 static void
Index: sys/platform/vkernel/include/globaldata.h
===================================================================
RCS file: /var/local/apps/dcvs/src/sys/platform/vkernel/include/globaldata.h,v
retrieving revision 1.5
diff -u -r1.5 globaldata.h
--- sys/platform/vkernel/include/globaldata.h	14 Jan 2007 07:59:06 -0000	1.5
+++ sys/platform/vkernel/include/globaldata.h	10 Jun 2007 21:10:26 -0000
@@ -83,7 +83,8 @@
 	int		gd_spending;	/* software interrupt pending */
 	int		gd_sdelayed;	/* delayed software ints */
 	int		gd_currentldt;
-	int		gd_mailbox;	/* signal delivery mailbox */
+	int		gd_mailbox;	/* I/O signal delivery mailbox */
+	int		gd_shutdown;    /* Shutdown signal delivery mailbox */
 	u_int		unused001;
 	u_int		gd_other_cpus;
 	u_int		gd_ss_eflags;
Index: sys/platform/vkernel/platform/kqueue.c
===================================================================
RCS file: /var/local/apps/dcvs/src/sys/platform/vkernel/platform/kqueue.c,v
retrieving revision 1.3
diff -u -r1.3 kqueue.c
--- sys/platform/vkernel/platform/kqueue.c	15 Jan 2007 19:08:10 -0000	1.3
+++ sys/platform/vkernel/platform/kqueue.c	17 Jun 2007 16:19:18 -0000
@@ -107,6 +107,16 @@
 	int n;
 	int i;
 
+	/*
+	 * we only need to wake up our shutdown thread once.  
+	 * Keep it non-zero so the shutdown thread can detect it.
+	 */
+
+	if (mdcpu->gd_shutdown > 0) {
+		mdcpu->gd_shutdown = -1;
+		wakeup(&mdcpu->gd_shutdown);
+	}
+
 	if (gd->gd_mailbox == 0)
 		return;
 	gd->gd_mailbox = 0;




More information about the Bugs mailing list