I never got the S-lshutdown to work properly  :-(

diff -ur orig/linux-source-2.6.23/Documentation/lguest/lguest.c 
linux-source-2.6.23/Documentation/lguest/lguest.c
--- orig/linux-source-2.6.23/Documentation/lguest/lguest.c      2007-10-10 
06:31:38.000000000 +1000
+++ linux-source-2.6.23/Documentation/lguest/lguest.c   2008-01-31 
12:06:40.310997465 +1100
@@ -696,8 +696,23 @@
        int count;
        /* When did they start? */
        struct timeval start;
+
+       /* was the last char a ctrl-A ? */
+       int ctrla;
 };
 
+/* The console code to kill the guest */
+static void console_exit(int fd) {
+       u32 args[] = { LHREQ_BREAK, 0 };
+       /* Close the fd so Waker will know it has to
+        * exit. */
+       close(waker_fd);
+       /* Just in case waker is blocked in BREAK, send
+        * unbreak now. */
+       write(fd, args, sizeof(args));
+       exit(2);
+}
+
 /* This is the routine which handles console input (ie. stdin). */
 static bool handle_console_input(int fd, struct device *dev)
 {
@@ -734,32 +749,51 @@
                trigger_irq(fd, irq);
        }
 
-       /* Three ^C within one second?  Exit.
-        *
-        * This is such a hack, but works surprisingly well.  Each ^C has to be
-        * in a buffer by itself, so they can't be too fast.  But we check that
-        * we get three within about a second, so they can't be too slow. */
-       if (len == 1 && ((char *)iov[0].iov_base)[0] == 3) {
-               if (!abort->count++)
-                       gettimeofday(&abort->start, NULL);
-               else if (abort->count == 3) {
-                       struct timeval now;
-                       gettimeofday(&now, NULL);
-                       if (now.tv_sec <= abort->start.tv_sec+1) {
-                               u32 args[] = { LHREQ_BREAK, 0 };
-                               /* Close the fd so Waker will know it has to
-                                * exit. */
-                               close(waker_fd);
-                               /* Just in case waker is blocked in BREAK, send
-                                * unbreak now. */
-                               write(fd, args, sizeof(args));
-                               exit(2);
+       /* If it is a one char buffer, consider it for ctrl-char processing */
+       /*
+        * This is such a hack, but works surprisingly well.  Each char
+        * has to be in a buffer by itself, so they can't be
+        * too fast.  But we check that * we get three within
+        * about a second, so they can't be too slow. */
+       if (len == 1) {
+               switch ( ((char *)iov[0].iov_base)[0] ) {
+
+               /* Three ^C within one second?  Exit.  */
+               case 3:
+                       if (!abort->count++) 
+                               gettimeofday(&abort->start, NULL);
+                       else if (abort->count == 3) {
+                               struct timeval now;
+                               gettimeofday(&now, NULL);
+                               if (now.tv_sec <= abort->start.tv_sec+1) {
+                                       console_exit(fd);
+                               }
+                               abort->count = 0;
                        }
+                       break;
+
+               /* ctrl-A: console command prefix */
+               case 1:
+                       abort->ctrla=1;
+                       break;
+               /* ctrl-K: Kill */
+               case 11:
+                       if (abort->ctrla)
+                               console_exit(fd);
+                       break;
+               /* ctrl-R: Reboot */
+               case 19:
+                       
+               default:
+                       /* Any other key resets the abort counter. */
                        abort->count = 0;
+                       abort->ctrla=0;
                }
-       } else
+       } else {
                /* Any other key resets the abort counter. */
                abort->count = 0;
+               abort->ctrla=0;
+       }
 
        /* Now, if we didn't read anything, put the input terminal back and
         * return failure (meaning, don't call us again). */
@@ -1342,8 +1376,18 @@
                /* ENOENT means the Guest died.  Reading tells us why. */
                } else if (errno == ENOENT) {
                        char reason[1024] = { 0 };
-                       read(lguest_fd, reason, sizeof(reason)-1);
-                       errx(1, "%s", reason);
+                       int read_size;
+                       int exit_code = 1;
+
+                       read_size = read(lguest_fd, reason, sizeof(reason)-1);
+
+                       /* If the reason is empty, then this is a clean
+                        * shutdown
+                        */
+                       if (!read_size) {
+                               exit_code=0;
+                       }
+                       errx(exit_code, "%s", reason);
                /* EAGAIN means the waker wanted us to look at some input.
                 * Anything else means a bug or incompatible change. */
                } else if (errno != EAGAIN)
diff -ur orig/linux-source-2.6.23/drivers/lguest/hypercalls.c 
linux-source-2.6.23/drivers/lguest/hypercalls.c
--- orig/linux-source-2.6.23/drivers/lguest/hypercalls.c        2007-10-10 
06:31:38.000000000 +1000
+++ linux-source-2.6.23/drivers/lguest/hypercalls.c     2008-01-31 
12:24:54.661795468 +1100
@@ -29,7 +29,7 @@
 #include "lg.h"
 
 /*H:120 This is the core hypercall routine: where the Guest gets what it
- * wants.  Or gets killed.  Or, in the case of LHCALL_CRASH, both.
+ * wants.  Or gets killed.  Or, in the case of LHCALL_STOP, both.
  *
  * Remember from the Guest: %eax == which call to make, and the arguments are
  * packed into %edx, %ebx and %ecx if needed. */
@@ -45,7 +45,7 @@
                 * do that. */
                kill_guest(lg, "already have lguest_data");
                break;
-       case LHCALL_CRASH: {
+       case LHCALL_STOP: {
                /* Crash is such a trivial hypercall that we do it in four
                 * lines right here. */
                char msg[128];
@@ -53,7 +53,13 @@
                 * kill_guest() with the message will be ignored. */
                lgread(lg, msg, regs->edx, sizeof(msg));
                msg[sizeof(msg)-1] = '\0';
-               kill_guest(lg, "CRASH: %s", msg);
+
+               if (regs->ebx== LHCALL_STOP_SHUTDOWN) {
+                       /* tell the launcher that we actually shutdown */
+                       lg->dead = 0;
+               }
+
+               kill_guest(lg, "STOP(%i): %s", regs->ebx, msg);
                break;
        }
        case LHCALL_FLUSH_TLB:
diff -ur orig/linux-source-2.6.23/drivers/lguest/lguest.c 
linux-source-2.6.23/drivers/lguest/lguest.c
--- orig/linux-source-2.6.23/drivers/lguest/lguest.c    2007-10-10 
06:31:38.000000000 +1000
+++ linux-source-2.6.23/drivers/lguest/lguest.c 2008-01-31 12:16:55.622746489 
+1100
@@ -65,6 +65,8 @@
 #include <asm/e820.h>
 #include <asm/mce.h>
 #include <asm/io.h>
+#include <asm/reboot.h>
+
 
 /*G:010 Welcome to the Guest!
  *
@@ -857,7 +859,7 @@
        hcall(LHCALL_HALT, 0, 0, 0);
 }
 
-/* Perhaps CRASH isn't the best name for this hypercall, but we use it to get a
+/* HC FIXME - message now incorrect: Perhaps CRASH isn't the best name for 
this hypercall, but we use it to get a
  * message out when we're crashing as well as elegant termination like powering
  * off.
  *
@@ -865,7 +867,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_STOP, __pa("Power down"), LHCALL_STOP_SHUTDOWN, 0);
 }
 
 /*
@@ -875,7 +877,7 @@
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-       hcall(LHCALL_CRASH, __pa(p), 0, 0);
+       hcall(LHCALL_STOP, __pa(p), LHCALL_STOP_CRASH, 0);
        /* The hcall won't return, but to keep gcc happy, we're "done". */
        return NOTIFY_DONE;
 }
@@ -957,6 +959,19 @@
        return insn_len;
 }
 
+/* HC
+ */
+static void lguest_reboot(char *msg) {
+       /* Without checking the users of machine_ops.restart, I guess
+         that they are not setting a message */
+       char *buf = "";
+       if (!msg)
+               msg = buf;
+
+       hcall(LHCALL_STOP,__pa(msg),LHCALL_STOP_REBOOT,0);
+       /* TODO - crash? */
+}
+
 /*G:030 Once we get to lguest_init(), we know we're a Guest.  The paravirt_ops
  * structure in the kernel provides a single point for (almost) every routine
  * we have to override to avoid privileged instructions. */
@@ -1025,6 +1040,11 @@
        /* Now is a good time to look at the implementations of these functions
         * before returning to the rest of lguest_init(). */
 
+       /* overwrite the standard reboot hook with our own */
+       machine_ops.restart = lguest_reboot;
+       /* some user-spaces dont use power management to halt */
+       machine_ops.halt = lguest_power_off;
+
        /*G:070 Now we've seen all the paravirt_ops, we return to
         * lguest_init() where the rest of the fairly chaotic boot setup
         * occurs.
@@ -1092,6 +1112,7 @@
 
        /* Now we're set up, call start_kernel() in init/main.c and we proceed
         * to boot as normal.  It never returns. */
+
        start_kernel();
 }
 /*


-- 
Use Linux!                                                  [EMAIL PROTECTED]
*********************************** O- ***********************************
``Life is like a grapefruit ... it's sort of orangey-yellow and dimpled on
the outside, wet and squidgy in the middle.  It's got pips inside too. Oh,
and some people have half a one for breakfast.'' -- Ford Prefect

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Lguest mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/lguest

Reply via email to