diff -U3 linux-plastic-2.6.23.12/Documentation/lguest/lguest.c linux-plastic-2.6.23.12-lguest/Documentation/lguest/lguest.c
--- linux-plastic-2.6.23.12/Documentation/lguest/lguest.c	2007-12-19 08:55:57.000000000 +1100
+++ linux-plastic-2.6.23.12-lguest/Documentation/lguest/lguest.c	2008-01-31 11:53:47.000000000 +1100
@@ -85,11 +85,18 @@
 	struct device **lastdev;
 };
 
+/* The list of Guest devices, based on command line arguments. */
+struct device_list device_list;
+
 /* The device structure describes a single device. */
 struct device
 {
 	/* The linked-list pointer. */
 	struct device *next;
+
+        /* The name of the device. */
+        const char *name;
+
 	/* The descriptor for this device, as mapped into the Guest. */
 	struct lguest_device_desc *desc;
 	/* The memory page(s) of this device, if any.  Also mapped in Guest. */
@@ -780,6 +787,43 @@
 	return writev(STDOUT_FILENO, iov, num);
 }
 
+static bool handle_control_input(int fd, struct device *dev)
+{
+    char buf[1024];
+    int nread;
+    struct device *scan;
+
+    nread = read(dev->fd, buf, 1024);
+    if (nread < 0) {
+        warn("launcher: Couldn't read from control fifo");
+        return false;
+    }
+
+    /* XXX They disconnected. This is dead forevermore. If you like, you could
+     * close our end, reopen it, dup the new fd back onto dev->fd (which is in
+     * a select set) then return true and carry on as before. If you like.
+     */
+    if (nread == 0)
+        return false;
+    
+    if (nread >= 6 && !strncmp(buf, "status", 6)) {
+        for (scan = device_list.dev; scan != NULL; scan = scan->next) {
+            printf("device status: %s\n", scan->name);
+            printf("    type: 0x%04x\n", scan->desc->type);
+            printf("features: 0x%04x\n", scan->desc->features);
+            printf("  status: 0x%04x\n", scan->desc->status);
+            if (scan->desc->num_pages)
+                printf("  memory: %d pages at %p\n", scan->desc->num_pages, scan->mem);
+
+        }
+        return true;
+    }
+
+    printf("control: %.*s\n", nread, buf);
+
+    return true;
+}
+
 /* Guest->Host network output is also pretty easy. */
 static u32 handle_tun_output(int fd, const struct iovec *iov,
 			     unsigned num, struct device *dev)
@@ -1011,6 +1055,7 @@
  * including caling new_dev_desc() to allocate the descriptor and device
  * memory. */
 static struct device *new_device(struct device_list *devices,
+                                 const char *name,
 				 u16 type, u16 num_pages, u16 features,
 				 int fd,
 				 bool (*handle_input)(int, struct device *),
@@ -1031,6 +1076,7 @@
 	devices->lastdev = &dev->next;
 
 	/* Now we populate the fields one at a time. */
+        dev->name = name;
 	dev->fd = fd;
 	/* If we have an input handler for this file descriptor, then we add it
 	 * to the device_list's fdset and maxfd. */
@@ -1044,6 +1090,18 @@
 	return dev;
 }
 
+static void setup_control(const char *control_fifo_name, struct device_list *devices)
+{
+    int fd;
+
+    if (mkfifo(control_fifo_name, 0600) < 0 && errno != EEXIST)
+        err(1, "Couldn't create control fifo %s", control_fifo_name);
+
+    fd = open_or_die(control_fifo_name, O_RDONLY | O_NONBLOCK);
+
+    new_device(devices, "control", 0xffff, 0, 0, fd, handle_control_input, 0, NULL);
+}
+
 /* Our first setup routine is the console.  It's a fairly simple device, but
  * UNIX tty handling makes it uglier than it could be. */
 static void setup_console(struct device_list *devices)
@@ -1064,7 +1122,7 @@
 
 	/* We don't currently require any memory for the console, so we ask for
 	 * 0 pages. */
-	dev = new_device(devices, LGUEST_DEVICE_T_CONSOLE, 0, 0,
+	dev = new_device(devices, "console", LGUEST_DEVICE_T_CONSOLE, 0, 0,
 			 STDIN_FILENO, handle_console_input,
 			 LGUEST_CONSOLE_DMA_KEY, handle_console_output);
 	/* We store the console state in dev->priv, and initialize it. */
@@ -1090,7 +1148,7 @@
 	/* We want one page, and have no input handler (the block file never
 	 * has anything interesting to say to us).  Our timing will be quite
 	 * random, so it should be a reasonable randomness source. */
-	dev = new_device(devices, LGUEST_DEVICE_T_BLOCK, 1,
+	dev = new_device(devices, "block", LGUEST_DEVICE_T_BLOCK, 1,
 			 LGUEST_DEVICE_F_RANDOMNESS,
 			 fd, NULL, 0, handle_block_output);
 
@@ -1170,7 +1228,7 @@
 	 * no checksum is needed.  We never touch this device again; it's
 	 * between the Guests on the network, so we don't register input or
 	 * output handlers. */
-	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
+	dev = new_device(devices, "net", LGUEST_DEVICE_T_NET, 1,
 			 find_slot(netfd, filename)|LGUEST_NET_F_NOCSUM,
 			 -1, NULL, 0, NULL);
 
@@ -1277,7 +1335,7 @@
 	 *
 	 * We will put our MAC address is slot 0 for the Guest to see, so
 	 * it will send packets to us using the key "peer_offset(0)": */
-	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
+	dev = new_device(devices, "net", LGUEST_DEVICE_T_NET, 1,
 			 NET_PEERNUM|LGUEST_DEVICE_F_RANDOMNESS, netfd,
 			 handle_tun_input, peer_offset(0), handle_tun_output);
 
@@ -1369,13 +1427,14 @@
 	{ "tunnet", 1, NULL, 't' },
 	{ "block", 1, NULL, 'b' },
 	{ "initrd", 1, NULL, 'i' },
+        { "control", 1, NULL, 'c' },
 	{ NULL },
 };
 static void usage(void)
 {
 	errx(1, "Usage: lguest [--verbose] "
 	     "[--sharenet=<filename>|--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
-	     "|--block=<filename>|--initrd=<filename>]...\n"
+	     "|--block=<filename>|--initrd=<filename>|--control=<fifo>]...\n"
 	     "<mem-in-mb> vmlinux [args...]");
 }
 
@@ -1401,12 +1460,12 @@
 	unsigned long mem = 0, pgdir, start, page_offset, initrd_size = 0;
 	/* A temporary and the /dev/lguest file descriptor. */
 	int i, c, lguest_fd;
-	/* The list of Guest devices, based on command line arguments. */
-	struct device_list device_list;
 	/* The boot information for the Guest: at guest-physical address 0. */
 	void *boot = (void *)0;
 	/* If they specify an initrd file to load. */
 	const char *initrd_name = NULL;
+        /* If they specify a control fifo to open. */
+        const char *control_fifo_name = NULL;
 
 	/* First we initialize the device list.  Since console and network
 	 * device receive input from a file descriptor, we keep an fdset
@@ -1449,6 +1508,9 @@
 		case 'i':
 			initrd_name = optarg;
 			break;
+                case 'c':
+                        control_fifo_name = optarg;
+                        break;
 		default:
 			warnx("Unknown argument %s", argv[optind]);
 			usage();
@@ -1459,6 +1521,9 @@
 	if (optind + 2 > argc)
 		usage();
 
+        if (control_fifo_name)
+            setup_control(control_fifo_name, &device_list);
+
 	/* We always have a console device */
 	setup_console(&device_list);
 
