aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-10-25 01:02:50 -0400
committerRusty Russell <rusty@rustcorp.com.au>2007-10-25 01:02:50 -0400
commite1e72965ec2c02db99b415cd06c17ea90767e3a4 (patch)
tree94e43aac35bdc33220e64f285b72b3b2b787fd57 /Documentation
parent568a17ffce2eeceae0cd9fc37e97cbad12f70278 (diff)
lguest: documentation update
Went through the documentation doing typo and content fixes. This patch contains only comment and whitespace changes. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/lguest/lguest.c155
1 files changed, 95 insertions, 60 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index c91c28ae8290..f2668390e8f7 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -360,8 +360,8 @@ static unsigned long load_bzimage(int fd)
360} 360}
361 361
362/*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels 362/*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels
363 * come wrapped up in the self-decompressing "bzImage" format. With some funky 363 * come wrapped up in the self-decompressing "bzImage" format. With a little
364 * coding, we can load those, too. */ 364 * work, we can load those, too. */
365static unsigned long load_kernel(int fd) 365static unsigned long load_kernel(int fd)
366{ 366{
367 Elf32_Ehdr hdr; 367 Elf32_Ehdr hdr;
@@ -464,6 +464,7 @@ static unsigned long setup_pagetables(unsigned long mem,
464 * to know where it is. */ 464 * to know where it is. */
465 return to_guest_phys(pgdir); 465 return to_guest_phys(pgdir);
466} 466}
467/*:*/
467 468
468/* Simple routine to roll all the commandline arguments together with spaces 469/* Simple routine to roll all the commandline arguments together with spaces
469 * between them. */ 470 * between them. */
@@ -480,9 +481,9 @@ static void concat(char *dst, char *args[])
480 dst[len] = '\0'; 481 dst[len] = '\0';
481} 482}
482 483
483/* This is where we actually tell the kernel to initialize the Guest. We saw 484/*L:185 This is where we actually tell the kernel to initialize the Guest. We
484 * the arguments it expects when we looked at initialize() in lguest_user.c: 485 * saw the arguments it expects when we looked at initialize() in lguest_user.c:
485 * the base of guest "physical" memory, the top physical page to allow, the 486 * the base of Guest "physical" memory, the top physical page to allow, the
486 * top level pagetable and the entry point for the Guest. */ 487 * top level pagetable and the entry point for the Guest. */
487static int tell_kernel(unsigned long pgdir, unsigned long start) 488static int tell_kernel(unsigned long pgdir, unsigned long start)
488{ 489{
@@ -512,13 +513,14 @@ static void add_device_fd(int fd)
512/*L:200 513/*L:200
513 * The Waker. 514 * The Waker.
514 * 515 *
515 * With a console and network devices, we can have lots of input which we need 516 * With console, block and network devices, we can have lots of input which we
516 * to process. We could try to tell the kernel what file descriptors to watch, 517 * need to process. We could try to tell the kernel what file descriptors to
517 * but handing a file descriptor mask through to the kernel is fairly icky. 518 * watch, but handing a file descriptor mask through to the kernel is fairly
519 * icky.
518 * 520 *
519 * Instead, we fork off a process which watches the file descriptors and writes 521 * Instead, we fork off a process which watches the file descriptors and writes
520 * the LHREQ_BREAK command to the /dev/lguest filedescriptor to tell the Host 522 * the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host
521 * loop to stop running the Guest. This causes it to return from the 523 * stop running the Guest. This causes the Launcher to return from the
522 * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset 524 * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset
523 * the LHREQ_BREAK and wake us up again. 525 * the LHREQ_BREAK and wake us up again.
524 * 526 *
@@ -544,7 +546,9 @@ static void wake_parent(int pipefd, int lguest_fd)
544 if (read(pipefd, &fd, sizeof(fd)) == 0) 546 if (read(pipefd, &fd, sizeof(fd)) == 0)
545 exit(0); 547 exit(0);
546 /* Otherwise it's telling us to change what file 548 /* Otherwise it's telling us to change what file
547 * descriptors we're to listen to. */ 549 * descriptors we're to listen to. Positive means
550 * listen to a new one, negative means stop
551 * listening. */
548 if (fd >= 0) 552 if (fd >= 0)
549 FD_SET(fd, &devices.infds); 553 FD_SET(fd, &devices.infds);
550 else 554 else
@@ -559,7 +563,7 @@ static int setup_waker(int lguest_fd)
559{ 563{
560 int pipefd[2], child; 564 int pipefd[2], child;
561 565
562 /* We create a pipe to talk to the waker, and also so it knows when the 566 /* We create a pipe to talk to the Waker, and also so it knows when the
563 * Launcher dies (and closes pipe). */ 567 * Launcher dies (and closes pipe). */
564 pipe(pipefd); 568 pipe(pipefd);
565 child = fork(); 569 child = fork();
@@ -567,7 +571,8 @@ static int setup_waker(int lguest_fd)
567 err(1, "forking"); 571 err(1, "forking");
568 572
569 if (child == 0) { 573 if (child == 0) {
570 /* Close the "writing" end of our copy of the pipe */ 574 /* We are the Waker: close the "writing" end of our copy of the
575 * pipe and start waiting for input. */
571 close(pipefd[1]); 576 close(pipefd[1]);
572 wake_parent(pipefd[0], lguest_fd); 577 wake_parent(pipefd[0], lguest_fd);
573 } 578 }
@@ -578,12 +583,12 @@ static int setup_waker(int lguest_fd)
578 return pipefd[1]; 583 return pipefd[1];
579} 584}
580 585
581/*L:210 586/*
582 * Device Handling. 587 * Device Handling.
583 * 588 *
584 * When the Guest sends DMA to us, it sends us an array of addresses and sizes. 589 * When the Guest gives us a buffer, it sends an array of addresses and sizes.
585 * We need to make sure it's not trying to reach into the Launcher itself, so 590 * We need to make sure it's not trying to reach into the Launcher itself, so
586 * we have a convenient routine which check it and exits with an error message 591 * we have a convenient routine which checks it and exits with an error message
587 * if something funny is going on: 592 * if something funny is going on:
588 */ 593 */
589static void *_check_pointer(unsigned long addr, unsigned int size, 594static void *_check_pointer(unsigned long addr, unsigned int size,
@@ -600,7 +605,9 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
600/* A macro which transparently hands the line number to the real function. */ 605/* A macro which transparently hands the line number to the real function. */
601#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__) 606#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
602 607
603/* This function returns the next descriptor in the chain, or vq->vring.num. */ 608/* Each buffer in the virtqueues is actually a chain of descriptors. This
609 * function returns the next descriptor in the chain, or vq->vring.num if we're
610 * at the end. */
604static unsigned next_desc(struct virtqueue *vq, unsigned int i) 611static unsigned next_desc(struct virtqueue *vq, unsigned int i)
605{ 612{
606 unsigned int next; 613 unsigned int next;
@@ -679,13 +686,14 @@ static unsigned get_vq_desc(struct virtqueue *vq,
679 return head; 686 return head;
680} 687}
681 688
682/* Once we've used one of their buffers, we tell them about it. We'll then 689/* After we've used one of their buffers, we tell them about it. We'll then
683 * want to send them an interrupt, using trigger_irq(). */ 690 * want to send them an interrupt, using trigger_irq(). */
684static void add_used(struct virtqueue *vq, unsigned int head, int len) 691static void add_used(struct virtqueue *vq, unsigned int head, int len)
685{ 692{
686 struct vring_used_elem *used; 693 struct vring_used_elem *used;
687 694
688 /* Get a pointer to the next entry in the used ring. */ 695 /* The virtqueue contains a ring of used buffers. Get a pointer to the
696 * next entry in that used ring. */
689 used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num]; 697 used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
690 used->id = head; 698 used->id = head;
691 used->len = len; 699 used->len = len;
@@ -699,6 +707,7 @@ static void trigger_irq(int fd, struct virtqueue *vq)
699{ 707{
700 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; 708 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
701 709
710 /* If they don't want an interrupt, don't send one. */
702 if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) 711 if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
703 return; 712 return;
704 713
@@ -715,8 +724,11 @@ static void add_used_and_trigger(int fd, struct virtqueue *vq,
715 trigger_irq(fd, vq); 724 trigger_irq(fd, vq);
716} 725}
717 726
718/* Here is the input terminal setting we save, and the routine to restore them 727/*
719 * on exit so the user can see what they type next. */ 728 * The Console
729 *
730 * Here is the input terminal setting we save, and the routine to restore them
731 * on exit so the user gets their terminal back. */
720static struct termios orig_term; 732static struct termios orig_term;
721static void restore_term(void) 733static void restore_term(void)
722{ 734{
@@ -817,7 +829,10 @@ static void handle_console_output(int fd, struct virtqueue *vq)
817 } 829 }
818} 830}
819 831
820/* Handling output for network is also simple: we get all the output buffers 832/*
833 * The Network
834 *
835 * Handling output for network is also simple: we get all the output buffers
821 * and write them (ignoring the first element) to this device's file descriptor 836 * and write them (ignoring the first element) to this device's file descriptor
822 * (stdout). */ 837 * (stdout). */
823static void handle_net_output(int fd, struct virtqueue *vq) 838static void handle_net_output(int fd, struct virtqueue *vq)
@@ -830,8 +845,9 @@ static void handle_net_output(int fd, struct virtqueue *vq)
830 while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) { 845 while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
831 if (in) 846 if (in)
832 errx(1, "Input buffers in output queue?"); 847 errx(1, "Input buffers in output queue?");
833 /* Check header, but otherwise ignore it (we said we supported 848 /* Check header, but otherwise ignore it (we told the Guest we
834 * no features). */ 849 * supported no features, so it shouldn't have anything
850 * interesting). */
835 (void)convert(&iov[0], struct virtio_net_hdr); 851 (void)convert(&iov[0], struct virtio_net_hdr);
836 len = writev(vq->dev->fd, iov+1, out-1); 852 len = writev(vq->dev->fd, iov+1, out-1);
837 add_used_and_trigger(fd, vq, head, len); 853 add_used_and_trigger(fd, vq, head, len);
@@ -882,7 +898,8 @@ static bool handle_tun_input(int fd, struct device *dev)
882 return true; 898 return true;
883} 899}
884 900
885/* This callback ensures we try again, in case we stopped console or net 901/*L:215 This is the callback attached to the network and console input
902 * virtqueues: it ensures we try again, in case we stopped console or net
886 * delivery because Guest didn't have any buffers. */ 903 * delivery because Guest didn't have any buffers. */
887static void enable_fd(int fd, struct virtqueue *vq) 904static void enable_fd(int fd, struct virtqueue *vq)
888{ 905{
@@ -918,7 +935,7 @@ static void handle_output(int fd, unsigned long addr)
918 strnlen(from_guest_phys(addr), guest_limit - addr)); 935 strnlen(from_guest_phys(addr), guest_limit - addr));
919} 936}
920 937
921/* This is called when the waker wakes us up: check for incoming file 938/* This is called when the Waker wakes us up: check for incoming file
922 * descriptors. */ 939 * descriptors. */
923static void handle_input(int fd) 940static void handle_input(int fd)
924{ 941{
@@ -985,8 +1002,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type)
985} 1002}
986 1003
987/* Each device descriptor is followed by some configuration information. 1004/* Each device descriptor is followed by some configuration information.
988 * The first byte is a "status" byte for the Guest to report what's happening. 1005 * Each configuration field looks like: u8 type, u8 len, [... len bytes...].
989 * After that are fields: u8 type, u8 len, [... len bytes...].
990 * 1006 *
991 * This routine adds a new field to an existing device's descriptor. It only 1007 * This routine adds a new field to an existing device's descriptor. It only
992 * works for the last device, but that's OK because that's how we use it. */ 1008 * works for the last device, but that's OK because that's how we use it. */
@@ -1043,14 +1059,17 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1043 /* Link virtqueue back to device. */ 1059 /* Link virtqueue back to device. */
1044 vq->dev = dev; 1060 vq->dev = dev;
1045 1061
1046 /* Set up handler. */ 1062 /* Set the routine to call when the Guest does something to this
1063 * virtqueue. */
1047 vq->handle_output = handle_output; 1064 vq->handle_output = handle_output;
1065
1066 /* Set the "Don't Notify Me" flag if we don't have a handler */
1048 if (!handle_output) 1067 if (!handle_output)
1049 vq->vring.used->flags = VRING_USED_F_NO_NOTIFY; 1068 vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
1050} 1069}
1051 1070
1052/* This routine does all the creation and setup of a new device, including 1071/* This routine does all the creation and setup of a new device, including
1053 * caling new_dev_desc() to allocate the descriptor and device memory. */ 1072 * calling new_dev_desc() to allocate the descriptor and device memory. */
1054static struct device *new_device(const char *name, u16 type, int fd, 1073static struct device *new_device(const char *name, u16 type, int fd,
1055 bool (*handle_input)(int, struct device *)) 1074 bool (*handle_input)(int, struct device *))
1056{ 1075{
@@ -1059,7 +1078,7 @@ static struct device *new_device(const char *name, u16 type, int fd,
1059 /* Append to device list. Prepending to a single-linked list is 1078 /* Append to device list. Prepending to a single-linked list is
1060 * easier, but the user expects the devices to be arranged on the bus 1079 * easier, but the user expects the devices to be arranged on the bus
1061 * in command-line order. The first network device on the command line 1080 * in command-line order. The first network device on the command line
1062 * is eth0, the first block device /dev/lgba, etc. */ 1081 * is eth0, the first block device /dev/vda, etc. */
1063 *devices.lastdev = dev; 1082 *devices.lastdev = dev;
1064 dev->next = NULL; 1083 dev->next = NULL;
1065 devices.lastdev = &dev->next; 1084 devices.lastdev = &dev->next;
@@ -1103,7 +1122,7 @@ static void setup_console(void)
1103 /* The console needs two virtqueues: the input then the output. When 1122 /* The console needs two virtqueues: the input then the output. When
1104 * they put something the input queue, we make sure we're listening to 1123 * they put something the input queue, we make sure we're listening to
1105 * stdin. When they put something in the output queue, we write it to 1124 * stdin. When they put something in the output queue, we write it to
1106 * stdout. */ 1125 * stdout. */
1107 add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd); 1126 add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
1108 add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output); 1127 add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
1109 1128
@@ -1251,21 +1270,17 @@ static void setup_tun_net(const char *arg)
1251 verbose("attached to bridge: %s\n", br_name); 1270 verbose("attached to bridge: %s\n", br_name);
1252} 1271}
1253 1272
1254 1273/* Our block (disk) device should be really simple: the Guest asks for a block
1255/* 1274 * number and we read or write that position in the file. Unfortunately, that
1256 * Block device. 1275 * was amazingly slow: the Guest waits until the read is finished before
1276 * running anything else, even if it could have been doing useful work.
1257 * 1277 *
1258 * Serving a block device is really easy: the Guest asks for a block number and 1278 * We could use async I/O, except it's reputed to suck so hard that characters
1259 * we read or write that position in the file. 1279 * actually go missing from your code when you try to use it.
1260 *
1261 * Unfortunately, this is amazingly slow: the Guest waits until the read is
1262 * finished before running anything else, even if it could be doing useful
1263 * work. We could use async I/O, except it's reputed to suck so hard that
1264 * characters actually go missing from your code when you try to use it.
1265 * 1280 *
1266 * So we farm the I/O out to thread, and communicate with it via a pipe. */ 1281 * So we farm the I/O out to thread, and communicate with it via a pipe. */
1267 1282
1268/* This hangs off device->priv, with the data. */ 1283/* This hangs off device->priv. */
1269struct vblk_info 1284struct vblk_info
1270{ 1285{
1271 /* The size of the file. */ 1286 /* The size of the file. */
@@ -1281,8 +1296,14 @@ struct vblk_info
1281 * Launcher triggers interrupt to Guest. */ 1296 * Launcher triggers interrupt to Guest. */
1282 int done_fd; 1297 int done_fd;
1283}; 1298};
1299/*:*/
1284 1300
1285/* This is the core of the I/O thread. It returns true if it did something. */ 1301/*L:210
1302 * The Disk
1303 *
1304 * Remember that the block device is handled by a separate I/O thread. We head
1305 * straight into the core of that thread here:
1306 */
1286static bool service_io(struct device *dev) 1307static bool service_io(struct device *dev)
1287{ 1308{
1288 struct vblk_info *vblk = dev->priv; 1309 struct vblk_info *vblk = dev->priv;
@@ -1293,10 +1314,14 @@ static bool service_io(struct device *dev)
1293 struct iovec iov[dev->vq->vring.num]; 1314 struct iovec iov[dev->vq->vring.num];
1294 off64_t off; 1315 off64_t off;
1295 1316
1317 /* See if there's a request waiting. If not, nothing to do. */
1296 head = get_vq_desc(dev->vq, iov, &out_num, &in_num); 1318 head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
1297 if (head == dev->vq->vring.num) 1319 if (head == dev->vq->vring.num)
1298 return false; 1320 return false;
1299 1321
1322 /* Every block request should contain at least one output buffer
1323 * (detailing the location on disk and the type of request) and one
1324 * input buffer (to hold the result). */
1300 if (out_num == 0 || in_num == 0) 1325 if (out_num == 0 || in_num == 0)
1301 errx(1, "Bad virtblk cmd %u out=%u in=%u", 1326 errx(1, "Bad virtblk cmd %u out=%u in=%u",
1302 head, out_num, in_num); 1327 head, out_num, in_num);
@@ -1305,10 +1330,15 @@ static bool service_io(struct device *dev)
1305 in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr); 1330 in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
1306 off = out->sector * 512; 1331 off = out->sector * 512;
1307 1332
1308 /* This is how we implement barriers. Pretty poor, no? */ 1333 /* The block device implements "barriers", where the Guest indicates
1334 * that it wants all previous writes to occur before this write. We
1335 * don't have a way of asking our kernel to do a barrier, so we just
1336 * synchronize all the data in the file. Pretty poor, no? */
1309 if (out->type & VIRTIO_BLK_T_BARRIER) 1337 if (out->type & VIRTIO_BLK_T_BARRIER)
1310 fdatasync(vblk->fd); 1338 fdatasync(vblk->fd);
1311 1339
1340 /* In general the virtio block driver is allowed to try SCSI commands.
1341 * It'd be nice if we supported eject, for example, but we don't. */
1312 if (out->type & VIRTIO_BLK_T_SCSI_CMD) { 1342 if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
1313 fprintf(stderr, "Scsi commands unsupported\n"); 1343 fprintf(stderr, "Scsi commands unsupported\n");
1314 in->status = VIRTIO_BLK_S_UNSUPP; 1344 in->status = VIRTIO_BLK_S_UNSUPP;
@@ -1374,7 +1404,7 @@ static int io_thread(void *_dev)
1374 1404
1375 /* When this read fails, it means Launcher died, so we follow. */ 1405 /* When this read fails, it means Launcher died, so we follow. */
1376 while (read(vblk->workpipe[0], &c, 1) == 1) { 1406 while (read(vblk->workpipe[0], &c, 1) == 1) {
1377 /* We acknowledge each request immediately, to reduce latency, 1407 /* We acknowledge each request immediately to reduce latency,
1378 * rather than waiting until we've done them all. I haven't 1408 * rather than waiting until we've done them all. I haven't
1379 * measured to see if it makes any difference. */ 1409 * measured to see if it makes any difference. */
1380 while (service_io(dev)) 1410 while (service_io(dev))
@@ -1383,12 +1413,14 @@ static int io_thread(void *_dev)
1383 return 0; 1413 return 0;
1384} 1414}
1385 1415
1386/* When the thread says some I/O is done, we interrupt the Guest. */ 1416/* Now we've seen the I/O thread, we return to the Launcher to see what happens
1417 * when the thread tells us it's completed some I/O. */
1387static bool handle_io_finish(int fd, struct device *dev) 1418static bool handle_io_finish(int fd, struct device *dev)
1388{ 1419{
1389 char c; 1420 char c;
1390 1421
1391 /* If child died, presumably it printed message. */ 1422 /* If the I/O thread died, presumably it printed the error, so we
1423 * simply exit. */
1392 if (read(dev->fd, &c, 1) != 1) 1424 if (read(dev->fd, &c, 1) != 1)
1393 exit(1); 1425 exit(1);
1394 1426
@@ -1397,7 +1429,7 @@ static bool handle_io_finish(int fd, struct device *dev)
1397 return true; 1429 return true;
1398} 1430}
1399 1431
1400/* When the Guest submits some I/O, we wake the I/O thread. */ 1432/* When the Guest submits some I/O, we just need to wake the I/O thread. */
1401static void handle_virtblk_output(int fd, struct virtqueue *vq) 1433static void handle_virtblk_output(int fd, struct virtqueue *vq)
1402{ 1434{
1403 struct vblk_info *vblk = vq->dev->priv; 1435 struct vblk_info *vblk = vq->dev->priv;
@@ -1409,7 +1441,7 @@ static void handle_virtblk_output(int fd, struct virtqueue *vq)
1409 exit(1); 1441 exit(1);
1410} 1442}
1411 1443
1412/* This creates a virtual block device. */ 1444/*L:198 This actually sets up a virtual block device. */
1413static void setup_block_file(const char *filename) 1445static void setup_block_file(const char *filename)
1414{ 1446{
1415 int p[2]; 1447 int p[2];
@@ -1425,7 +1457,7 @@ static void setup_block_file(const char *filename)
1425 /* The device responds to return from I/O thread. */ 1457 /* The device responds to return from I/O thread. */
1426 dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish); 1458 dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish);
1427 1459
1428 /* The device has a virtqueue. */ 1460 /* The device has one virtqueue, where the Guest places requests. */
1429 add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output); 1461 add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output);
1430 1462
1431 /* Allocate the room for our own bookkeeping */ 1463 /* Allocate the room for our own bookkeeping */
@@ -1447,7 +1479,8 @@ static void setup_block_file(const char *filename)
1447 /* The I/O thread writes to this end of the pipe when done. */ 1479 /* The I/O thread writes to this end of the pipe when done. */
1448 vblk->done_fd = p[1]; 1480 vblk->done_fd = p[1];
1449 1481
1450 /* This is how we tell the I/O thread about more work. */ 1482 /* This is the second pipe, which is how we tell the I/O thread about
1483 * more work. */
1451 pipe(vblk->workpipe); 1484 pipe(vblk->workpipe);
1452 1485
1453 /* Create stack for thread and run it */ 1486 /* Create stack for thread and run it */
@@ -1486,24 +1519,25 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
1486 char reason[1024] = { 0 }; 1519 char reason[1024] = { 0 };
1487 read(lguest_fd, reason, sizeof(reason)-1); 1520 read(lguest_fd, reason, sizeof(reason)-1);
1488 errx(1, "%s", reason); 1521 errx(1, "%s", reason);
1489 /* EAGAIN means the waker wanted us to look at some input. 1522 /* EAGAIN means the Waker wanted us to look at some input.
1490 * Anything else means a bug or incompatible change. */ 1523 * Anything else means a bug or incompatible change. */
1491 } else if (errno != EAGAIN) 1524 } else if (errno != EAGAIN)
1492 err(1, "Running guest failed"); 1525 err(1, "Running guest failed");
1493 1526
1494 /* Service input, then unset the BREAK which releases 1527 /* Service input, then unset the BREAK to release the Waker. */
1495 * the Waker. */
1496 handle_input(lguest_fd); 1528 handle_input(lguest_fd);
1497 if (write(lguest_fd, args, sizeof(args)) < 0) 1529 if (write(lguest_fd, args, sizeof(args)) < 0)
1498 err(1, "Resetting break"); 1530 err(1, "Resetting break");
1499 } 1531 }
1500} 1532}
1501/* 1533/*
1502 * This is the end of the Launcher. 1534 * This is the end of the Launcher. The good news: we are over halfway
1535 * through! The bad news: the most fiendish part of the code still lies ahead
1536 * of us.
1503 * 1537 *
1504 * But wait! We've seen I/O from the Launcher, and we've seen I/O from the 1538 * Are you ready? Take a deep breath and join me in the core of the Host, in
1505 * Drivers. If we were to see the Host kernel I/O code, our understanding 1539 * "make Host".
1506 * would be complete... :*/ 1540 :*/
1507 1541
1508static struct option opts[] = { 1542static struct option opts[] = {
1509 { "verbose", 0, NULL, 'v' }, 1543 { "verbose", 0, NULL, 'v' },
@@ -1526,7 +1560,7 @@ int main(int argc, char *argv[])
1526 /* Memory, top-level pagetable, code startpoint and size of the 1560 /* Memory, top-level pagetable, code startpoint and size of the
1527 * (optional) initrd. */ 1561 * (optional) initrd. */
1528 unsigned long mem = 0, pgdir, start, initrd_size = 0; 1562 unsigned long mem = 0, pgdir, start, initrd_size = 0;
1529 /* A temporary and the /dev/lguest file descriptor. */ 1563 /* Two temporaries and the /dev/lguest file descriptor. */
1530 int i, c, lguest_fd; 1564 int i, c, lguest_fd;
1531 /* The boot information for the Guest. */ 1565 /* The boot information for the Guest. */
1532 struct boot_params *boot; 1566 struct boot_params *boot;
@@ -1621,6 +1655,7 @@ int main(int argc, char *argv[])
1621 /* The boot header contains a command line pointer: we put the command 1655 /* The boot header contains a command line pointer: we put the command
1622 * line after the boot header. */ 1656 * line after the boot header. */
1623 boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1); 1657 boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
1658 /* We use a simple helper to copy the arguments separated by spaces. */
1624 concat((char *)(boot + 1), argv+optind+2); 1659 concat((char *)(boot + 1), argv+optind+2);
1625 1660
1626 /* Boot protocol version: 2.07 supports the fields for lguest. */ 1661 /* Boot protocol version: 2.07 supports the fields for lguest. */