[Lguest] [lguest] Reboot Implemented

Balaji Rao balajirrao at gmail.com
Fri Dec 28 19:56:24 EST 2007


hi rusty,

here's the patch with the mistakes corrected.

Signed-off-by : Balaji Rao <balajirrao at gmail.com>
---
Index: linux/arch/x86/lguest/boot.c
===================================================================
--- linux.orig/arch/x86/lguest/boot.c	2007-12-11 09:18:43.000000000 +0530
+++ linux/arch/x86/lguest/boot.c	2007-12-28 13:53:37.000000000 +0530
@@ -67,6 +67,7 @@
 #include <asm/mce.h>
 #include <asm/io.h>
 #include <asm/i387.h>
+#include <asm/reboot.h>		/* for struct machine_ops */
 
 /*G:010 Welcome to the Guest!
  *
@@ -812,7 +813,7 @@
  * rather than virtual addresses, so we use __pa() here. */
 static void lguest_power_off(void)
 {
-	hcall(LHCALL_CRASH, __pa("Power down"), 0, 0);
+	hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0);
 }
 
 /*
@@ -822,7 +823,7 @@
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-	hcall(LHCALL_CRASH, __pa(p), 0, 0);
+	hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0);
 	/* The hcall won't return, but to keep gcc happy, we're "done". */
 	return NOTIFY_DONE;
 }
@@ -926,6 +927,11 @@
 	return insn_len;
 }
 
+static void lguest_restart(char *reason)
+{
+	hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
+}
+
 /*G:030 Once we get to lguest_init(), we know we're a Guest.  The pv_ops
  * structures in the kernel provide points for (almost) every routine we have
  * to override to avoid privileged instructions. */
@@ -1059,6 +1065,7 @@
 	 * the Guest routine to power off. */
 	pm_power_off = lguest_power_off;
 
+	machine_ops.restart = lguest_restart;
 	/* Now we're set up, call start_kernel() in init/main.c and we proceed
 	 * to boot as normal.  It never returns. */
 	start_kernel();
Index: linux/Documentation/lguest/lguest.c
===================================================================
--- linux.orig/Documentation/lguest/lguest.c	2007-12-11 09:18:43.000000000 +0530
+++ linux/Documentation/lguest/lguest.c	2007-12-28 14:21:03.000000000 +0530
@@ -153,6 +153,9 @@
 	void (*handle_output)(int fd, struct virtqueue *me);
 };
 
+/* Remember the arguments to the program so we can "reboot" */
+static char **main_args;
+
 /* Since guest is UP and we don't run at the same time, we don't need barriers.
  * But I include them in the code in case others copy it. */
 #define wmb()
@@ -1489,7 +1492,9 @@
 
 	/* Create stack for thread and run it */
 	stack = malloc(32768);
-	if (clone(io_thread, stack + 32768, CLONE_VM, dev) == -1)
+	/* SIGCHLD - We dont "wait" for our cloned thread, so prevent it from becoming
+	 * a zombie. */
+	if (clone(io_thread, stack + 32768,  CLONE_VM | SIGCHLD, dev) == -1)
 		err(1, "Creating clone");
 
 	/* We don't need to keep the I/O thread's end of the pipes open. */
@@ -1501,6 +1506,24 @@
 }
 /* That's the end of device setup. */
 
+/* Restart the guest */
+static void restart_guest(void)
+{
+	struct device *dev;
+	struct vblk_info *vblk;
+
+	/* Closing the waked_fd causes the waker thread to die */
+	close  (waker_fd);
+	/* Closing the workpipe[1] causes io_thread thread to die */
+	for(dev = devices.device;dev!= NULL;dev = dev->next) {
+		if (strcmp(dev->name, "block") == 0) {
+			vblk = dev->priv;
+			close (vblk->workpipe[1]);
+		}
+	}
+	if(execv(main_args[0],main_args))
+		errx(1,"Could not exec %s", main_args[0]);
+}
 /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves
  * its input and output, and finally, lays it to rest. */
 static void __attribute__((noreturn)) run_guest(int lguest_fd)
@@ -1523,6 +1546,9 @@
 			char reason[1024] = { 0 };
 			read(lguest_fd, reason, sizeof(reason)-1);
 			errx(1, "%s", reason);
+		/* ERESTART means that we need to reboot the guest */
+		} else if (errno == ERESTART) {
+			restart_guest();
 		/* EAGAIN means the Waker wanted us to look at some input.
 		 * Anything else means a bug or incompatible change. */
 		} else if (errno != EAGAIN)
@@ -1571,6 +1597,11 @@
 	/* If they specify an initrd file to load. */
 	const char *initrd_name = NULL;
 
+	main_args = argv;
+	/* We don't "wait" for the children, so prevent them from becoming
+	 * zombies. */
+	signal(SIGCHLD, SIG_IGN);
+
 	/* First we initialize the device list.  Since console and network
 	 * device receive input from a file descriptor, we keep an fdset
 	 * (infds) and the maximum fd number (max_infd) with the head of the
Index: linux/drivers/lguest/hypercalls.c
===================================================================
--- linux.orig/drivers/lguest/hypercalls.c	2007-12-11 09:18:43.000000000 +0530
+++ linux/drivers/lguest/hypercalls.c	2007-12-28 13:53:37.000000000 +0530
@@ -41,8 +41,8 @@
 		 * do that. */
 		kill_guest(lg, "already have lguest_data");
 		break;
-	case LHCALL_CRASH: {
-		/* Crash is such a trivial hypercall that we do it in four
+	case LHCALL_SHUTDOWN: {
+		/* Shutdown is such a trivial hypercall that we do it in four
 		 * lines right here. */
 		char msg[128];
 		/* If the lgread fails, it will call kill_guest() itself; the
@@ -50,6 +50,8 @@
 		__lgread(lg, msg, args->arg1, sizeof(msg));
 		msg[sizeof(msg)-1] = '\0';
 		kill_guest(lg, "CRASH: %s", msg);
+		if (args->arg2 == LGUEST_SHUTDOWN_RESTART)
+			lg->dead = ERR_PTR(-ERESTART);
 		break;
 	}
 	case LHCALL_FLUSH_TLB:
Index: linux/drivers/lguest/core.c
===================================================================
--- linux.orig/drivers/lguest/core.c	2007-12-11 09:18:43.000000000 +0530
+++ linux/drivers/lguest/core.c	2007-12-28 13:53:37.000000000 +0530
@@ -235,6 +235,8 @@
 		lguest_arch_handle_trap(lg);
 	}
 
+	if (lg->dead == ERR_PTR(-ERESTART))
+		return -ERESTART;
 	/* The Guest is dead => "No such file or directory" */
 	return -ENOENT;
 }
Index: linux/include/asm/lguest_hcall.h
===================================================================
--- linux.orig/include/asm/lguest_hcall.h	2007-12-11 09:18:43.000000000 +0530
+++ linux/include/asm/lguest_hcall.h	2007-12-28 13:53:37.000000000 +0530
@@ -4,7 +4,7 @@
 
 #define LHCALL_FLUSH_ASYNC	0
 #define LHCALL_LGUEST_INIT	1
-#define LHCALL_CRASH		2
+#define LHCALL_SHUTDOWN		2
 #define LHCALL_LOAD_GDT		3
 #define LHCALL_NEW_PGTABLE	4
 #define LHCALL_FLUSH_TLB	5
@@ -20,6 +20,10 @@
 
 #define LGUEST_TRAP_ENTRY 0x1F
 
+/* Argument number 3 to LHCALL_LGUEST_SHUTDOWN */
+#define LGUEST_SHUTDOWN_POWEROFF	1
+#define LGUEST_SHUTDOWN_RESTART		2
+
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
 
---

regards,
balaji rao



More information about the Lguest mailing list