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