rough-draft VKERNEL host-initiated shutdown patch

Chris Turner c.turner at 199technologies.org
Sun May 20 14:05:24 PDT 2007


Took a quick attempt at getting the VKERNEL to shutdown cleanly against
1.8,
and it seems to work just fine as suggested with mailbox signals, etc.

Attached is my 'cumulative' 1.8 vkernel patch against 1.8_Release
/usr/src/sys/platform/vkernel including the previous multi-vk changes.

Of course I will clean up and resubmit against Preview/Head, (along with
a patch for vkernel(7), but I wanted to have the general approach
validated before going too much further.

(plus I don't  have a -HEAD / Preview machine set up at the moment,
 but am working on it)

status:
   - OK for simple shutdown case with init already fork()'ed.
   - VK is too fast for me to catch the 'no init yet' shutdown case..
   - need to merge against Preview, as things have changed there,
     and re-submit. patch here includes previous multivkd work.

changes in:
  - platform/vkernel/include/globaldata.h : maibox slot
  - platform/vkernel/include/md_var.h : vk_shutdown prototype
  - platform/vkernel/platform/kqueue.c : mailbox hook
  - platform/vkernel/platform/init.c : vk_shutdown function

questions/notes:
  - I didn't think I really needed a separate sigaction in
    kqueue_setup..
  - should shutdown mailbox handler dispatch happen higher up
    (e.g. in platform/vkernel/i386/trap.c)
  - should this actually follow
    'vke_intr(void *xsc, struct intrframe *frame __unused)' conventions?
    - we're not really checking for FD related IO kevents() ..
    - this implies a more 'full device' kind of thing , with a struct,
      etc.
  - should the other init(8) signals for e.g. single user, etc. be
    implemented? Currently, these are not implement as shutdown is
    ~90% of cases, and wanted to verify I'm taking the proper direction.
  - mailbox signals aren't really documented in the manual at the
    moment..

Comments / Questions / feedback welcome.

Thanks!

  - Chris

Index: include/globaldata.h
===================================================================
RCS file: /nbsd/dcvs/src/sys/platform/vkernel/include/globaldata.h,v
retrieving revision 1.5
diff -u -w -r1.5 globaldata.h
--- include/globaldata.h	14 Jan 2007 07:59:06 -0000	1.5
+++ include/globaldata.h	20 May 2007 17:50:44 -0000
@@ -84,6 +84,7 @@
 	int		gd_sdelayed;	/* delayed software ints */
 	int		gd_currentldt;
 	int		gd_mailbox;	/* signal delivery mailbox */
+	int		gd_powerbutton; /* shutdown signal mailbox */
 	u_int		unused001;
 	u_int		gd_other_cpus;
 	u_int		gd_ss_eflags;
Index: include/md_var.h
===================================================================
RCS file: /nbsd/dcvs/src/sys/platform/vkernel/include/md_var.h,v
retrieving revision 1.17
diff -u -w -r1.17 md_var.h
--- include/md_var.h	22 Jan 2007 19:37:05 -0000	1.17
+++ include/md_var.h	20 May 2007 20:34:04 -0000
@@ -45,6 +45,7 @@
 #endif
 
 #define VKNETIF_MAX	16
+#define VKD_MAX		16
 
 struct vknetif_info {
 	int		tap_fd;
@@ -53,6 +54,12 @@
 	in_addr_t	netif_mask;
 };
 
+struct vkd_info {
+        int fd;
+        int unit;
+        char fname[MAXPATHLEN];
+};
+
 extern	char	sigcode[];
 extern	int	szsigcode;
 extern	vpte_t	*KernelPTA;	/* NOTE: Offset for direct VA translation */
@@ -63,7 +70,8 @@
 extern  char    cpu_vendor[];	/* XXX belongs in i386 */
 extern  u_int   cpu_id;		/* XXX belongs in i386 */
 
-extern int	RootImageFd;
+extern struct vkd_info VkdInfo[VKD_MAX];
+extern int	VkdNum;
 extern int	MemImageFd;
 extern int	KQueueFd;
 extern struct vknetif_info NetifInfo[VKNETIF_MAX];
@@ -83,6 +91,7 @@
 void cpu_setregs (void);
 void cpu_idle (void);
 void go_user (struct intrframe *frame);
+void vk_poweroff (void);
 
 void init_exceptions(void);
 void init_kqueue(void);
Index: platform/init.c
===================================================================
RCS file: /nbsd/dcvs/src/sys/platform/vkernel/platform/init.c,v
retrieving revision 1.28.2.2
diff -u -w -r1.28.2.2 init.c
--- platform/init.c	13 Apr 2007 16:46:03 -0000	1.28.2.2
+++ platform/init.c	20 May 2007 20:32:08 -0000
@@ -47,6 +47,7 @@
 #include <sys/proc.h>
 #include <sys/msgbuf.h>
 #include <sys/vmspace.h>
+#include <sys/signalvar.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <vm/vm_page.h>
@@ -76,9 +77,10 @@
 vm_paddr_t Maxmem;
 vm_paddr_t Maxmem_bytes;
 int MemImageFd = -1;
-int RootImageFd = -1;
+struct vkd_info VkdInfo[VKD_MAX];
+int VkdNum = 0;
 struct vknetif_info NetifInfo[VKNETIF_MAX];
-int NetifNum;
+int NetifNum = 0;
 vm_offset_t KvaStart;
 vm_offset_t KvaEnd;
 vm_offset_t KvaSize;
@@ -104,8 +106,8 @@
 static void init_kern_memory(void);
 static void init_globaldata(void);
 static void init_vkernel(void);
-static void init_rootdevice(char *imageFile);
-static void init_netif(char *netifFile[], int netifFileNum);
+static void init_vkd(char *vkdFile[], int vkdExpNum); 
+static void init_netif(char *netifExp[], int netifExpNum);
 static void usage(const char *ctl);
 
 /*
@@ -115,10 +117,11 @@
 main(int ac, char **av)
 {
 	char *memImageFile = NULL;
-	char *rootImageFile = NULL;
 	char *netifFile[VKNETIF_MAX];
+	char *vkdFile[VKD_MAX];
 	char *suffix;
 	int netifFileNum = 0;
+	int vkdFileNum = 0;
 	int c;
 	int i;
 	int n;
@@ -159,7 +162,8 @@
 				netifFile[netifFileNum++] = optarg;
 			break;
 		case 'r':
-			rootImageFile = optarg;
+			if ( vkdFileNum < VKD_MAX )
+				vkdFile[vkdFileNum++] = optarg;
 			break;
 		case 'm':
 			Maxmem_bytes = strtoull(optarg, &suffix, 0);
@@ -197,7 +201,7 @@
 	init_globaldata();
 	init_vkernel();
 	init_kqueue();
-	init_rootdevice(rootImageFile);
+	init_vkd(vkdFile, vkdFileNum);
 	init_netif(netifFile, netifFileNum);
 	init_exceptions();
 	mi_startup();
@@ -556,8 +560,9 @@
 }
 
 /*
- * The root filesystem path for the virtual kernel is optional.  If specified
- * it points to a filesystem image.
+ * Filesystem image paths for the virtual kernel are optional.  
+ * If specified they each should point to a disk image, 
+ * the first of which will become the VKERNEL root disk.
  *
  * The virtual kernel caches data from our 'disk' just like a normal kernel,
  * so we do not really want the real kernel to cache the data too.  Use
@@ -565,17 +570,52 @@
  */
 static
 void
-init_rootdevice(char *imageFile)
+init_vkd ( char *vkdExp[], int vkdExpNum ) 
 {
+	int i;	
+
+        if (vkdExpNum == 0)
+                return;
+
+	for(i=0; i < vkdExpNum; i++){
+		char *fname;
+		fname = vkdExp[i];
+
+        	if (fname == NULL) {
+                        warnx("Invalid argument to '-r'");
+                        continue;
+                }
+
+		if (VkdNum < VKD_MAX ) {
 	struct stat st;
+			struct vkd_info* info = NULL;
+			int fd;
+       			size_t l = 0;
 
-	if (imageFile) {
-		RootImageFd = open(imageFile, O_RDWR|O_DIRECT, 0644);
-		if (RootImageFd < 0 || fstat(RootImageFd, &st) < 0) {
-			err(1, "Unable to open/create %s", imageFile);
+			fd = open(fname, O_RDWR|O_DIRECT, 0644);
+			if (fd < 0 || fstat(fd, &st) < 0) {
+				err(1, "Unable to open/create %s: %s",
+				    fname, strerror(errno));
 			/* NOT REACHED */
 		}
+	       		info = &VkdInfo[VkdNum];
+			l = strlen(fname);
+
+	       		info->unit = i;
+			info->fd = fd;
+	        	memcpy(info->fname, fname, l);
+
+			if(i == 0)
 		rootdevnames[0] = "ufs:vkd0a";
+
+			VkdNum++;
+
+		}
+		else {
+                        warnx("vkd%d (%s) > VKD_MAX",
+				VkdNum, fname);
+                        continue;
+ 		}
 	}
 }
 
@@ -932,7 +972,7 @@
 
 		netif = strtok(netifExp[i], ":");
 		if (netif == NULL) {
-			warnx("Invalide argument to '-I'");
+			warnx("Invalid argument to '-I'");
 			continue;
 		}
 
@@ -994,3 +1034,13 @@
 	for (;;)
 		__asm__ __volatile("hlt");
 }
+
+void
+vk_poweroff(void)
+{
+	if(initproc != NULL) {
+		ksignal(initproc, SIGUSR2);
+	} else {
+		reboot(RB_POWEROFF);
+	}
+}
Index: platform/kqueue.c
===================================================================
RCS file: /nbsd/dcvs/src/sys/platform/vkernel/platform/kqueue.c,v
retrieving revision 1.3
diff -u -w -r1.3 kqueue.c
--- platform/kqueue.c	15 Jan 2007 19:08:10 -0000	1.3
+++ platform/kqueue.c	20 May 2007 20:29:51 -0000
@@ -82,6 +82,10 @@
 	sa.sa_flags = SA_MAILBOX | SA_NODEFER;
 	sigemptyset(&sa.sa_mask);
 	sigaction(SIGIO, &sa, NULL);
+
+	sa.sa_mailbox = &mdcpu->gd_powerbutton;
+	sigaction(SIGTERM, &sa, NULL);
+
 	KQueueFd = kqueue();
 	if (fcntl(KQueueFd, F_SETOWN, getpid()) < 0)
 		panic("Cannot configure kqueue for SIGIO, update your kernel");
@@ -107,8 +111,17 @@
 	int n;
 	int i;
 
-	if (gd->gd_mailbox == 0)
-		return;
+	/* note: 
+         *   should this be a separate mailbox handler call in 
+         *   platform/vkernel/i386/trap.c?
+         */
+	if (gd->gd_powerbutton != 0) {
+		kprintf("Caught SIGTERM from host. Shutting down...\n");	
+		gd->gd_powerbutton=0;
+		vk_poweroff();
+	}
+
+	if (gd->gd_mailbox != 0) {
 	gd->gd_mailbox = 0;
 	ts.tv_sec = 0;
 	ts.tv_nsec = 0;
@@ -125,6 +138,8 @@
 	crit_exit();
 }
 
+}
+
 /*
  * Generic I/O event support
  */




More information about the Submit mailing list