From e80ef0e67fd6645e05cf6840a919b3329ade5ae6 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 25 Apr 2006 09:32:14 +0000 Subject: [PATCH] test backend connections at allocation time. General bush-wacking in the fetch code. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@156 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_backend.c | 35 +++++++++++++++++ varnish-cache/bin/varnishd/cache_fetch.c | 44 +++++++++++----------- varnish-cache/bin/varnishd/cache_http.c | 16 +++++--- 3 files changed, 67 insertions(+), 28 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index fe97e52e..2305dcbb 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "libvarnish.h" #include "shmlog.h" @@ -90,12 +91,42 @@ connect_to_backend(struct vbe_conn *vc, struct backend *bp) /*--------------------------------------------------------------------*/ +int +tst_fd(int fd) +{ + fd_set r,w,e; + int i; + struct timeval tv; + char c; + + FD_ZERO(&r); + FD_ZERO(&w); + FD_ZERO(&e); + FD_SET(fd, &r); + FD_SET(fd, &w); + FD_SET(fd, &e); + tv.tv_sec = 0; + tv.tv_usec = 0; + i = select(fd + 1, &r, &w, &e, &tv); + printf("tst_fd fd %d i %d flag %d/%d/%d\n", + fd, i, FD_ISSET(fd, &r), FD_ISSET(fd, &w), FD_ISSET(fd, &e)); + if (FD_ISSET(fd, &r)) { + i = read(fd, &c, 1); + if (i == 0) + return (1); + } + return (0); +} + +/*--------------------------------------------------------------------*/ + int VBE_GetFd(struct backend *bp, void **ptr) { struct vbe *vp; struct vbe_conn *vc; +again: AZ(pthread_mutex_lock(&vbemtx)); vp = bp->vbe; if (vp == NULL) { @@ -118,6 +149,10 @@ VBE_GetFd(struct backend *bp, void **ptr) TAILQ_REMOVE(&vp->fconn, vc, list); TAILQ_INSERT_TAIL(&vp->bconn, vc, list); AZ(pthread_mutex_unlock(&vbemtx)); + if (tst_fd(vc->fd)) { + VBE_ClosedFd(vc); + goto again; + } } else { vc = calloc(sizeof *vc, 1); assert(vc != NULL); diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 39db10e5..2dc7ed05 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -23,11 +23,10 @@ #include "cache.h" static int -fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b) +fetch_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *b) { int i; char *e; - struct sess sp2; unsigned char *p; off_t cl; struct storage *st; @@ -40,25 +39,27 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b) sp->obj->len = cl; p = st->ptr; - i = fcntl(sp2.fd, F_GETFL); /* XXX ? */ + i = fcntl(fd, F_GETFL); /* XXX ? */ i &= ~O_NONBLOCK; - i = fcntl(sp2.fd, F_SETFL, i); + i = fcntl(fd, F_SETFL, i); if (http_GetTail(hp, cl, &b, &e)) { i = e - b; + VSL(SLT_Debug, 0, "Fetch_Tail %jd %d", cl, i); memcpy(p, b, i); p += i; cl -= i; } while (cl != 0) { - i = read(sp2.fd, p, cl); + i = read(fd, p, cl); + VSL(SLT_Debug, 0, "Fetch_Read %jd %d", cl, i); assert(i > 0); p += i; cl -= i; } - http_BuildSbuf(1, w->sb, hp); + http_BuildSbuf(2, w->sb, hp); i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb)); assert(i == sbuf_len(w->sb)); @@ -76,20 +77,19 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b) } static int -fetch_chunked(struct worker *w, struct sess *sp, struct http *hp) +fetch_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp) { int i; char *b, *q, *e; - struct sess sp2; unsigned char *p; struct storage *st; unsigned u; char buf[20]; char *bp, *be; - i = fcntl(sp2.fd, F_GETFL); /* XXX ? */ + i = fcntl(fd, F_GETFL); /* XXX ? */ i &= ~O_NONBLOCK; - i = fcntl(sp2.fd, F_SETFL, i); + i = fcntl(fd, F_SETFL, i); be = buf + sizeof buf; while (1) { @@ -100,7 +100,7 @@ printf("Tail: (H)\n%#H\n", b, e - b); memcpy(bp, b, e - b); bp += e - b; } else { - i = read(sp2.fd, bp, be - bp); + i = read(fd, bp, be - bp); assert(i >= 0); bp += i; } @@ -131,7 +131,7 @@ printf("Tail: (B)\n%#H\n", b, e - b); u -= e - b; } if (u > 0) { - i = read(sp2.fd, p, u); + i = read(fd, p, u); if (0) printf("u = %u i = %d\n", u, i); assert(i == u); @@ -140,7 +140,7 @@ if (0) printf("Store:\n%#H\n", st->ptr, st->len); } - http_BuildSbuf(1, w->sb, hp); + http_BuildSbuf(2, w->sb, hp); i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb)); assert(i == sbuf_len(w->sb)); @@ -165,7 +165,6 @@ FetchSession(struct worker *w, struct sess *sp) { int fd, i, cls; void *fd_token; - struct sess sp2; struct http *hp; char *b; @@ -174,22 +173,21 @@ FetchSession(struct worker *w, struct sess *sp) VSL(SLT_Handling, sp->fd, "Fetch fd %d", fd); hp = http_New(); - http_BuildSbuf(0, w->sb, sp->http); +HERE(); + http_BuildSbuf(1, w->sb, sp->http); +HERE(); i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb)); assert(i == sbuf_len(w->sb)); /* XXX: copy any contents */ - memset(&sp2, 0, sizeof sp2); - sp2.rd_e = &w->e1; - sp2.fd = fd; /* * XXX: It might be cheaper to avoid the event_engine and simply * XXX: read(2) the header */ - http_RecvHead(hp, sp2.fd, w->eb, NULL, NULL); + http_RecvHead(hp, fd, w->eb, NULL, NULL); event_base_loop(w->eb, 0); - http_Dissect(hp, sp2.fd, 2); + http_Dissect(hp, fd, 2); /* XXX: fill in object from headers */ sp->obj->valid = 1; @@ -201,12 +199,12 @@ FetchSession(struct worker *w, struct sess *sp) assert(sp->handling == HND_Insert); if (http_GetHdr(hp, "Content-Length", &b)) { - cls = fetch_straight(w, sp, hp, b); + cls = fetch_straight(w, sp, fd, hp, b); } else if (http_GetHdr(hp, "Transfer-Encoding", &b) && !strcasecmp(b, "chunked")) { - cls = fetch_chunked(w, sp, hp); + cls = fetch_chunked(w, sp, fd, hp); } else { - assert(0 == 1); + VSL(SLT_Debug, fd, "No transfer"); cls = 0; } diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index a4957c20..718980ce 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -137,6 +137,7 @@ http_Dissect(struct http *hp, int fd, int rr) { char *p, *q, *r; + assert(hp->t != NULL); if (rr == 1) { /* First, isolate and possibly identify request type */ hp->req = hp->s; @@ -227,6 +228,8 @@ http_Dissect(struct http *hp, int fd, int rr) /*--------------------------------------------------------------------*/ +#include + static void http_read_f(int fd, short event, void *arg) { @@ -235,13 +238,14 @@ http_read_f(int fd, short event, void *arg) int i; assert(hp->v < hp->e); + errno = 0; i = read(fd, hp->v, hp->e - hp->v); if (i <= 0) { if (hp->v != hp->s) VSL(SLT_SessionClose, fd, - "remote had %d bytes", hp->v - hp->s); + "remote had %d bytes errno %d", hp->v - hp->s, errno); else - VSL(SLT_SessionClose, fd, "remote"); + VSL(SLT_SessionClose, fd, "remote errno %d", errno); hp->t = NULL; event_del(&hp->ev); if (hp->callback != NULL) @@ -329,25 +333,27 @@ http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp) sbuf_clear(sb); assert(sb != NULL); - if (resp) { + if (resp == 2) { sbuf_cat(sb, hp->proto); sbuf_cat(sb, " "); sbuf_cat(sb, hp->status); sbuf_cat(sb, " "); sbuf_cat(sb, hp->response); - } else { + } else if (resp == 1) { sbuf_cat(sb, hp->req); sbuf_cat(sb, " "); sbuf_cat(sb, hp->url); sbuf_cat(sb, " "); sbuf_cat(sb, hp->proto); + } else { + assert(resp == 1 || resp == 2); } sbuf_cat(sb, "\r\n"); for (u = 0; u < hp->nhdr; u++) { if (http_supress(hp->hdr[u], resp)) continue; - if (0) + if (1) VSL(SLT_Debug, 0, "Build %s", hp->hdr[u]); sbuf_cat(sb, hp->hdr[u]); sbuf_cat(sb, "\r\n"); -- 2.39.5