[Lguest] [lguest] Reboot Implemented
Balaji Rao
balajirrao at gmail.com
Thu Dec 27 16:45:56 EST 2007
Hi rusty,
Thanks for the review!
I have incorporated your suggestions into the patch. Please review it and let me know if there are any more mistakes.
--
Index: linux/arch/x86/lguest/boot.c
===================================================================
--- linux.orig/arch/x86/lguest/boot.c 2007-12-27 10:54:00.000000000 +0530
+++ linux/arch/x86/lguest/boot.c 2007-12-27 10:54:39.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-27 10:54:00.000000000 +0530
+++ linux/Documentation/lguest/lguest.c 2007-12-27 11:10:49.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,23 @@
}
/* That's the end of device setup. */
+/* Restart the guest */
+static int restart_guest() {
+ struct device *dev = devices.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 */
+ while (dev) {
+ if (strcmp(dev->name, "block") == 0) {
+ vblk = dev->priv;
+ close (vblk->workpipe[1]);
+ }
+ dev = dev->next;
+ }
+ return execv(main_args[0],main_args);
+}
/*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 +1545,10 @@
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) {
+ if (restart_guest())
+ errx(1,"%s", "Restart Failed");
/* 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-27 10:54:00.000000000 +0530
+++ linux/drivers/lguest/hypercalls.c 2007-12-27 10:54:39.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-27 10:54:00.000000000 +0530
+++ linux/drivers/lguest/core.c 2007-12-27 11:04:32.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-27 10:54:00.000000000 +0530
+++ linux/include/asm/lguest_hcall.h 2007-12-27 10:54:39.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