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

Re: [Xen-devel] [PATCH 3/3] libxl: datacopier: Avoid theoretical eof/POLLHUP race



Ian Jackson writes ("[PATCH 3/3] libxl: datacopier: Avoid theoretical 
eof/POLLHUP race"):
> We solve the race with a poll of the reading fd, to double-check, when
> we detect eof via read.  (This is only necessary if the caller has
> specified callback_pollhup, as otherwise POLLHUP|POLLIN - and,
> presumably, POLLIN followed perhaps by POLLHUP|POLLIN, is to be
> treated as eof anyway.)

I have been unable to reproduce this race.  On Linux, the pty master
returns EGAIN from read, not EOF, when the bootloader exits.

Below is the patch I used to test this.  I think this should repro the
bug on FreeBSD when doing "xl create" of a guest which (a) uses pygrub
(b) autoboots within 15 seconds.

Roger, can you conveniently test this ?  With the hacky patch below
you should see the bug, which should in turn be fixed by the 3/3 I am
just replying to.

Thanks,
Ian.

diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c
index a08f780..5ba6d73 100644
--- a/tools/libxl/libxl_aoutils.c
+++ b/tools/libxl/libxl_aoutils.c
@@ -200,6 +200,10 @@ static void datacopier_readable(libxl__egc *egc, 
libxl__ev_fd *ev,
     libxl__datacopier_state *dc = CONTAINER_OF(ev, *dc, toread);
     STATE_AO_GC(dc->ao);
 
+fprintf(stderr, "DC READABLE\n");
+sleep(15);
+fprintf(stderr, "DC READABLE CONTINUING %o\n", revents);
+
     if (datacopier_pollhup_handled(egc, dc, revents, 0))
         return;
 
@@ -211,6 +215,7 @@ static void datacopier_readable(libxl__egc *egc, 
libxl__ev_fd *ev,
     }
     assert(revents & POLLIN);
     for (;;) {
+fprintf(stderr, "DC READABLE LOOP\n");
         while (dc->used >= dc->maxsz) {
             libxl__datacopier_buf *rm = LIBXL_TAILQ_FIRST(&dc->bufs);
             dc->used -= rm->used;
@@ -230,6 +235,7 @@ static void datacopier_readable(libxl__egc *egc, 
libxl__ev_fd *ev,
         int r = read(ev->fd,
                      buf->buf + buf->used,
                      sizeof(buf->buf) - buf->used);
+fprintf(stderr, "DC READABLE READ r=%d %s\n",r,strerror(errno));
         if (r < 0) {
             if (errno == EINTR) continue;
             if (errno == EWOULDBLOCK) break;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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