[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2] libxl: reimplement buffer for bootloading and drop data if buffer is full



# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1318337123 -7200
# Node ID a0b8b4fb418af35cd2e2d34b11883f8250c40a35
# Parent  64f17c7e6c33e5f1c22711ae9cbdcbe191c20062
libxl: reimplement buffer for bootloading and drop data if buffer is full.

Implement a buffer for the bootloading process that appends data to the end 
until it's full. Drop output from bootloader if a timeout has occurred and the 
buffer is full. Prevents the bootloader from getting stuck when using ptys with 
small buffers.

Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>

diff -r 64f17c7e6c33 -r a0b8b4fb418a tools/libxl/libxl_bootloader.c
--- a/tools/libxl/libxl_bootloader.c    Tue Oct 11 10:26:32 2011 +0200
+++ b/tools/libxl/libxl_bootloader.c    Tue Oct 11 14:45:23 2011 +0200
@@ -21,6 +21,7 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 
 #include "libxl.h"
 #include "libxl_internal.h"
@@ -28,7 +29,8 @@
 #include "flexarray.h"
 
 #define XENCONSOLED_BUF_SIZE 16
-#define BOOTLOADER_BUF_SIZE 1024
+#define BOOTLOADER_BUF_SIZE 4096
+#define BOOTLOADER_TIMEOUT 1
 
 static char **make_bootloader_args(libxl__gc *gc,
                                    libxl_domain_build_info *info,
@@ -165,10 +167,11 @@ static pid_t fork_exec_bootloader(int *m
  */
 static char * bootloader_interact(libxl__gc *gc, int xenconsoled_fd, int 
bootloader_fd, int fifo_fd)
 {
-    int ret;
+    int ret, read_ahead, timeout = 0;
 
     size_t nr_out = 0, size_out = 0;
     char *output = NULL;
+    struct timeval wait;
 
     /* input from xenconsole. read on xenconsoled_fd write to bootloader_fd */
     int xenconsoled_prod = 0, xenconsoled_cons = 0;
@@ -177,6 +180,10 @@ static char * bootloader_interact(libxl_
     int bootloader_prod = 0, bootloader_cons = 0;
     char bootloader_buf[BOOTLOADER_BUF_SIZE];
 
+    /* Set timeout to 1s before starting to discard data */
+    wait.tv_sec = BOOTLOADER_TIMEOUT;
+    wait.tv_usec = 0;
+
     while(1) {
         fd_set wsel, rsel;
         int nfds;
@@ -185,15 +192,26 @@ static char * bootloader_interact(libxl_
             xenconsoled_prod = xenconsoled_cons = 0;
         if (bootloader_prod == bootloader_cons)
             bootloader_prod = bootloader_cons = 0;
+        /* Move buffers around to drop already consumed data */
+        if (xenconsoled_cons > 0) {
+            xenconsoled_prod -= xenconsoled_cons;
+            memmove(xenconsoled_buf, &xenconsoled_buf[xenconsoled_cons], 
xenconsoled_prod);
+            xenconsoled_cons = 0;
+        }
+        if (bootloader_cons > 0) {
+            bootloader_prod -= bootloader_cons;
+            memmove(bootloader_buf, &bootloader_buf[bootloader_cons], 
bootloader_prod);
+            bootloader_cons = 0;
+        }
 
         FD_ZERO(&rsel);
         FD_SET(fifo_fd, &rsel);
         nfds = fifo_fd + 1;
-        if (xenconsoled_prod == 0 || (xenconsoled_prod < BOOTLOADER_BUF_SIZE 
&& xenconsoled_cons == 0)) {
+        if (xenconsoled_prod == 0 || (xenconsoled_prod < BOOTLOADER_BUF_SIZE 
&& xenconsoled_cons == 0) || timeout) {
             FD_SET(xenconsoled_fd, &rsel);
             nfds = xenconsoled_fd + 1 > nfds ? xenconsoled_fd + 1 : nfds;
         }
-        if (bootloader_prod == 0 || (bootloader_prod < BOOTLOADER_BUF_SIZE && 
bootloader_cons == 0)) {
+        if (bootloader_prod == 0 || (bootloader_prod < BOOTLOADER_BUF_SIZE && 
bootloader_cons == 0) || timeout) {
             FD_SET(bootloader_fd, &rsel);
             nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
         }
@@ -208,12 +226,23 @@ static char * bootloader_interact(libxl_
             nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
         }
 
-        ret = select(nfds, &rsel, &wsel, NULL, NULL);
+        ret = select(nfds, &rsel, &wsel, NULL, &wait);
         if (ret < 0)
             goto out_err;
+        if (ret == 0) {
+            timeout = 1;
+            continue;
+        }
+        timeout = 0;
 
         /* Input from xenconsole, read xenconsoled_fd, write bootloader_fd */
         if (FD_ISSET(xenconsoled_fd, &rsel)) {
+            if (xenconsoled_prod == XENCONSOLED_BUF_SIZE) {
+                if (ioctl(xenconsoled_fd, FIONREAD, &read_ahead) < 0)
+                    goto out_err;
+                memmove(xenconsoled_buf, &xenconsoled_buf[read_ahead], 
XENCONSOLED_BUF_SIZE - read_ahead);
+                xenconsoled_prod -= read_ahead;
+            }
             ret = read(xenconsoled_fd, &xenconsoled_buf[xenconsoled_prod], 
XENCONSOLED_BUF_SIZE - xenconsoled_prod);
             if (ret < 0 && errno != EIO && errno != EAGAIN)
                 goto out_err;
@@ -230,6 +259,12 @@ static char * bootloader_interact(libxl_
 
         /* Input from bootloader, read bootloader_fd, write xenconsoled_fd */
         if (FD_ISSET(bootloader_fd, &rsel)) {
+            if (bootloader_prod == BOOTLOADER_BUF_SIZE) {
+                if (ioctl(bootloader_fd, FIONREAD, &read_ahead) < 0)
+                    goto out_err;
+                memmove(bootloader_buf, &bootloader_buf[read_ahead], 
BOOTLOADER_BUF_SIZE - read_ahead);
+                bootloader_prod -= read_ahead;
+            }
             ret = read(bootloader_fd, &bootloader_buf[bootloader_prod], 
BOOTLOADER_BUF_SIZE - bootloader_prod);
             if (ret < 0 && errno != EIO && errno != EAGAIN)
                 goto out_err;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.