From phk at projects.linpro.no Mon Dec 1 14:13:49 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 1 Dec 2008 15:13:49 +0100 (CET) Subject: r3447 - trunk/varnish-cache/bin/varnishstat Message-ID: <20081201141349.87D761EC29D@projects.linpro.no> Author: phk Date: 2008-12-01 15:13:49 +0100 (Mon, 01 Dec 2008) New Revision: 3447 Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.c Log: Supress stats in the curses mode until we have see a non-zero value. Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.c =================================================================== --- trunk/varnish-cache/bin/varnishstat/varnishstat.c 2008-11-26 16:10:19 UTC (rev 3446) +++ trunk/varnish-cache/bin/varnishstat/varnishstat.c 2008-12-01 14:13:49 UTC (rev 3447) @@ -52,6 +52,7 @@ #define FIELD_EXCLUSION_CHARACTER '^' + static void myexp(double *acc, double val, unsigned *n, unsigned nmax) { @@ -95,6 +96,7 @@ do_curses(struct varnish_stats *VSL_stats, int delay, const char *fields) { struct varnish_stats copy; + struct varnish_stats seen; intmax_t ju; struct timeval tv; double tt, lt, hit, miss, ratio, up; @@ -104,6 +106,7 @@ int ch, line; memset(©, 0, sizeof copy); + memset(&seen, 0, sizeof seen); a1 = a2 = a3 = 0.0; n1 = n2 = n3 = 0; @@ -144,13 +147,18 @@ line = 3; #define MAC_STAT(n, t, f, d) \ - if ((fields == NULL || show_field( #n, fields )) && ++line < LINES) { \ + if ((fields == NULL || show_field( #n, fields )) && line < LINES) { \ ju = VSL_stats->n; \ - if (f == 'a') { \ + if (ju == 0 && !seen.n) { \ + } else if (f == 'a') { \ + seen.n = 1; \ + line++; \ mvprintw(line, 0, "%12ju %12.2f %12.2f %s\n", \ ju, (ju - (intmax_t)copy.n)/lt, ju / up, d); \ copy.n = ju; \ } else { \ + seen.n = 1; \ + line++; \ mvprintw(line, 0, "%12ju %12s %12s %s\n", \ ju, ". ", ". ", d); \ } \ From phk at projects.linpro.no Mon Dec 1 20:24:47 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 1 Dec 2008 21:24:47 +0100 (CET) Subject: r3448 - trunk/varnish-cache/bin/varnishd Message-ID: <20081201202447.48B3A1EC0FC@projects.linpro.no> Author: phk Date: 2008-12-01 21:24:46 +0100 (Mon, 01 Dec 2008) New Revision: 3448 Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c Log: We cannot gain a reference to an object unless it has an objhead, assert that we have one. Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-01 14:13:49 UTC (rev 3447) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-01 20:24:46 UTC (rev 3448) @@ -427,14 +427,11 @@ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oh = o->objhead; - if (oh != NULL) { - CHECK_OBJ(oh, OBJHEAD_MAGIC); - Lck_Lock(&oh->mtx); - } + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + Lck_Lock(&oh->mtx); assert(o->refcnt > 0); o->refcnt++; - if (oh != NULL) - Lck_Unlock(&oh->mtx); + Lck_Unlock(&oh->mtx); } void From phk at projects.linpro.no Mon Dec 1 21:34:53 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 1 Dec 2008 22:34:53 +0100 (CET) Subject: r3449 - in trunk/varnish-cache: include lib/libvarnish Message-ID: <20081201213453.90BB11EC2AE@projects.linpro.no> Author: phk Date: 2008-12-01 22:34:53 +0100 (Mon, 01 Dec 2008) New Revision: 3449 Modified: trunk/varnish-cache/include/vsha256.h trunk/varnish-cache/lib/libvarnish/vsha256.c Log: Shut FlexeLint up about SHA256 implementation. Modified: trunk/varnish-cache/include/vsha256.h =================================================================== --- trunk/varnish-cache/include/vsha256.h 2008-12-01 20:24:46 UTC (rev 3448) +++ trunk/varnish-cache/include/vsha256.h 2008-12-01 21:34:53 UTC (rev 3449) @@ -33,7 +33,7 @@ typedef struct SHA256Context { uint32_t state[8]; - uint32_t count[2]; + uint64_t count; unsigned char buf[64]; } SHA256_CTX; Modified: trunk/varnish-cache/lib/libvarnish/vsha256.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-01 20:24:46 UTC (rev 3448) +++ trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-01 21:34:53 UTC (rev 3449) @@ -33,18 +33,19 @@ #ifdef HAVE_ENDIAN_H #include -#define BYTE_ORDER __BYTE_ORDER -#define BIG_ENDIAN __BIG_ENDIAN +#define VBYTE_ORDER __BYTE_ORDER +#define VBIG_ENDIAN __BIG_ENDIAN #endif #ifdef HAVE_SYS_ENDIAN_H #include -#define BYTE_ORDER _BYTE_ORDER -#define BIG_ENDIAN _BIG_ENDIAN +#define VBYTE_ORDER _BYTE_ORDER +#define VBIG_ENDIAN _BIG_ENDIAN #endif +#include "libvarnish.h" #include "vsha256.h" -#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +#if defined(VBYTE_ORDER) && VBYTE_ORDER == VBIG_ENDIAN /* Copy a vector of big-endian uint32_t into a vector of bytes */ #define be32enc_vect(dst, src, len) \ @@ -61,7 +62,7 @@ { unsigned char const *p = (unsigned char const *)pp; - return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); } static __inline void @@ -75,6 +76,15 @@ p[3] = u & 0xff; } +static __inline void +mybe64enc(void *pp, uint64_t u) +{ + unsigned char *p = (unsigned char *)pp; + + be32enc(p, u >> 32); + be32enc(p + 4, u & 0xffffffff); +} + /* * Encode a length len/4 vector of (uint32_t) into a length len vector of * (unsigned char) in big-endian form. Assumes len is a multiple of 4. @@ -126,7 +136,7 @@ S[(66 - i) % 8], S[(67 - i) % 8], \ S[(68 - i) % 8], S[(69 - i) % 8], \ S[(70 - i) % 8], S[(71 - i) % 8], \ - W[i] + k) + (W[i] + k)) /* * SHA256 block compression function. The 256-bit state is transformed via @@ -219,7 +229,7 @@ state[i] += S[i]; } -static unsigned char PAD[64] = { +static const unsigned char PAD[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -234,14 +244,20 @@ uint32_t r, plen; /* + * Rescale from bytes to bits + */ + ctx->count <<= 3; + + /* * Convert length to a vector of bytes -- we do this now rather * than later because the length will change after we pad. */ - be32enc_vect(len, ctx->count, 8); + mybe64enc(len, ctx->count); /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ - r = (ctx->count[1] >> 3) & 0x3f; + r = ctx->count & 0x3f; plen = (r < 56) ? (56 - r) : (120 - r); + assert(plen <= sizeof PAD); SHA256_Update(ctx, PAD, (size_t)plen); /* Add the terminating bit-count */ @@ -254,7 +270,7 @@ { /* Zero bits processed so far */ - ctx->count[0] = ctx->count[1] = 0; + ctx->count = 0; /* Magic initialization constants */ ctx->state[0] = 0x6A09E667; @@ -271,43 +287,23 @@ void SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len) { - uint32_t bitlen[2]; - uint32_t r; + uint32_t r, l; const unsigned char *src = in; /* Number of bytes left in the buffer from previous updates */ - r = (ctx->count[1] >> 3) & 0x3f; - - /* Convert the length into a number of bits */ - bitlen[1] = ((uint32_t)len) << 3; - bitlen[0] = (uint32_t)(len >> 29); - - /* Update number of bits */ - if ((ctx->count[1] += bitlen[1]) < bitlen[1]) - ctx->count[0]++; - ctx->count[0] += bitlen[0]; - - /* Handle the case where we don't need to perform any transforms */ - if (len < 64 - r) { - memcpy(&ctx->buf[r], src, len); - return; + r = ctx->count & 0x3f; + while (len > 0) { + l = 64 - r; + if (l > len) + l = len; + memcpy(&ctx->buf[r], src, l); + len -= l; + src += l; + ctx->count += l; + r = ctx->count & 0x3f; + if (r == 0) + SHA256_Transform(ctx->state, ctx->buf); } - - /* Finish the current block */ - memcpy(&ctx->buf[r], src, 64 - r); - SHA256_Transform(ctx->state, ctx->buf); - src += 64 - r; - len -= 64 - r; - - /* Perform complete blocks */ - while (len >= 64) { - SHA256_Transform(ctx->state, src); - src += 64; - len -= 64; - } - - /* Copy left over data into buffer */ - memcpy(ctx->buf, src, len); } /* From phk at projects.linpro.no Mon Dec 1 21:46:21 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 1 Dec 2008 22:46:21 +0100 (CET) Subject: r3450 - trunk/varnish-cache/bin/varnishd Message-ID: <20081201214621.1CA051EC0FC@projects.linpro.no> Author: phk Date: 2008-12-01 22:46:20 +0100 (Mon, 01 Dec 2008) New Revision: 3450 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/cache_lck.c trunk/varnish-cache/bin/varnishd/cache_vrt_re.c trunk/varnish-cache/bin/varnishd/hash_classic.c trunk/varnish-cache/bin/varnishd/hash_simple_list.c Log: Various minor cleanups while we wait... Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/cache.h 2008-12-01 21:46:20 UTC (rev 3450) @@ -509,7 +509,7 @@ void Lck__Unlock(struct lock *lck, const char *p, const char *f, int l); int Lck__Trylock(struct lock *lck, const char *p, const char *f, int l); void Lck__New(struct lock *lck, const char *w); -void Lck__Assert(struct lock *lck, int held); +void Lck__Assert(const struct lock *lck, int held); /* public interface: */ void LCK_Init(void); Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-01 21:46:20 UTC (rev 3450) @@ -83,6 +83,8 @@ HSH_Prealloc(struct sess *sp) { struct worker *w; + struct objhead *oh; + struct object *o; struct storage *st; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -90,47 +92,39 @@ w = sp->wrk; if (w->nobjhead == NULL) { - w->nobjhead = calloc(sizeof *w->nobjhead, 1); - XXXAN(w->nobjhead); - w->nobjhead->magic = OBJHEAD_MAGIC; - w->nobjhead->refcnt = 1; - VTAILQ_INIT(&w->nobjhead->objects); - VTAILQ_INIT(&w->nobjhead->waitinglist); - Lck_New(&w->nobjhead->mtx); + ALLOC_OBJ(oh, OBJHEAD_MAGIC); + XXXAN(oh); + oh->refcnt = 1; + VTAILQ_INIT(&oh->objects); + VTAILQ_INIT(&oh->waitinglist); + Lck_New(&oh->mtx); + w->nobjhead = oh; VSL_stats->n_objecthead++; } else CHECK_OBJ_NOTNULL(w->nobjhead, OBJHEAD_MAGIC); -#if 0 - /* Make sure there is space enough for the hash-string */ - if (w->nobjhead->hashlen < sp->lhashptr) { - w->objhead->hash = realloc(w->objhead->hash, sp->lhashptr); - w->objhead->hashlen = sp->lhashptr; - AN(w->objhead->hash); - } -#endif - if (w->nobj == NULL) { st = STV_alloc(sp, params->obj_workspace); XXXAN(st); assert(st->space > sizeof *w->nobj); - w->nobj = (void *)st->ptr; /* XXX: align ? */ - st->len = sizeof *w->nobj; - memset(w->nobj, 0, sizeof *w->nobj); - w->nobj->objstore = st; - WS_Init(w->nobj->ws_o, "obj", + o = (void *)st->ptr; /* XXX: align ? */ + st->len = sizeof *o; + memset(o, 0, sizeof *o); + o->objstore = st; + WS_Init(o->ws_o, "obj", st->ptr + st->len, st->space - st->len); st->len = st->space; - WS_Assert(w->nobj->ws_o); - http_Setup(w->nobj->http, w->nobj->ws_o); - w->nobj->magic = OBJECT_MAGIC; - w->nobj->http->magic = HTTP_MAGIC; - w->nobj->busy = 1; - w->nobj->refcnt = 1; - w->nobj->grace = NAN; - w->nobj->entered = NAN; - VTAILQ_INIT(&w->nobj->store); - VTAILQ_INIT(&w->nobj->esibits); + WS_Assert(o->ws_o); + http_Setup(o->http, o->ws_o); + o->magic = OBJECT_MAGIC; + o->http->magic = HTTP_MAGIC; + o->busy = 1; + o->refcnt = 1; + o->grace = NAN; + o->entered = NAN; + VTAILQ_INIT(&o->store); + VTAILQ_INIT(&o->esibits); + w->nobj = o; VSL_stats->n_object++; } else Modified: trunk/varnish-cache/bin/varnishd/cache_lck.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_lck.c 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/cache_lck.c 2008-12-01 21:46:20 UTC (rev 3450) @@ -125,7 +125,7 @@ } void -Lck__Assert(struct lock *lck, int held) +Lck__Assert(const struct lock *lck, int held) { struct ilck *ilck; Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_re.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt_re.c 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/cache_vrt_re.c 2008-12-01 21:46:20 UTC (rev 3450) @@ -43,7 +43,6 @@ #include "shmlog.h" #include "vrt.h" -#include "vsb.h" #include "vcl.h" #include "cache.h" Modified: trunk/varnish-cache/bin/varnishd/hash_classic.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_classic.c 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/hash_classic.c 2008-12-01 21:46:20 UTC (rev 3450) @@ -124,7 +124,7 @@ int i; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_ORNULL(noh, OBJHEAD_MAGIC); + CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); digest = ~0U; for (u = 0; u < sp->ihashptr; u += 2) { Modified: trunk/varnish-cache/bin/varnishd/hash_simple_list.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_simple_list.c 2008-12-01 21:34:53 UTC (rev 3449) +++ trunk/varnish-cache/bin/varnishd/hash_simple_list.c 2008-12-01 21:46:20 UTC (rev 3450) @@ -71,6 +71,8 @@ struct objhead *oh; int i; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); Lck_Lock(&hsl_mtx); VTAILQ_FOREACH(oh, &hsl_head, hoh_list) { i = HSH_Compare(sp, oh); From phk at projects.linpro.no Mon Dec 1 22:17:37 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 1 Dec 2008 23:17:37 +0100 (CET) Subject: r3451 - trunk/varnish-cache/lib/libvarnish Message-ID: <20081201221737.9FA0D1EC55D@projects.linpro.no> Author: phk Date: 2008-12-01 23:17:37 +0100 (Mon, 01 Dec 2008) New Revision: 3451 Modified: trunk/varnish-cache/lib/libvarnish/vsha256.c Log: Fix build on !FreeBSD systems. Modified: trunk/varnish-cache/lib/libvarnish/vsha256.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-01 21:46:20 UTC (rev 3450) +++ trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-01 22:17:37 UTC (rev 3451) @@ -81,8 +81,8 @@ { unsigned char *p = (unsigned char *)pp; - be32enc(p, u >> 32); - be32enc(p + 4, u & 0xffffffff); + mybe32enc(p, u >> 32); + mybe32enc(p + 4, u & 0xffffffff); } /* From phk at projects.linpro.no Tue Dec 2 20:48:11 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Tue, 2 Dec 2008 21:48:11 +0100 (CET) Subject: r3452 - in trunk/varnish-cache: include lib/libvarnish Message-ID: <20081202204811.936EA1EC2AE@projects.linpro.no> Author: phk Date: 2008-12-02 21:48:11 +0100 (Tue, 02 Dec 2008) New Revision: 3452 Modified: trunk/varnish-cache/include/vsha256.h trunk/varnish-cache/lib/libvarnish/vsha256.c Log: Fix an embarrasing bug in my Flexlinting of this code yesterday, and add a couple of test-vectors to avoid it happening again. And now for the funny and educational story: In july of 1994, I added the "libmd" to FreeBSD, containing the MD2, MD4 and MD5 functions from RFC 1319, RFC 1186 and RFC1321. I meticulously replicated the test-vectors from the RFCs, so that "make test" would validate the result. Duing the intermediate 14 years, various slight shifts and adjustments to things like the make(1) programs defaults, the shared library resolution algorithm and other totally unrelated things, meant that "make test" now tests the installed version of the library, rather than the version you just built with "make all". Needless to say, when I tested my patch yesterday, I didn't install the built version, wanting first to hear what Colin Percival, FreeBSD Security Wiz, generally swell fella and the guy who wrote this SHA256 implementation, thought of these "stylistic" patches. Modified: trunk/varnish-cache/include/vsha256.h =================================================================== --- trunk/varnish-cache/include/vsha256.h 2008-12-01 22:17:37 UTC (rev 3451) +++ trunk/varnish-cache/include/vsha256.h 2008-12-02 20:48:11 UTC (rev 3452) @@ -41,6 +41,7 @@ void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX *, const void *, size_t); void SHA256_Final(unsigned char [32], SHA256_CTX *); +void SHA256_Test(void); __END_DECLS #endif /* !_SHA256_H_ */ Modified: trunk/varnish-cache/lib/libvarnish/vsha256.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-01 22:17:37 UTC (rev 3451) +++ trunk/varnish-cache/lib/libvarnish/vsha256.c 2008-12-02 20:48:11 UTC (rev 3452) @@ -244,20 +244,15 @@ uint32_t r, plen; /* - * Rescale from bytes to bits + * Convert length to bits and encode as a vector of bytes + * -- we do this now rather than later because the length + * will change after we pad. */ - ctx->count <<= 3; + mybe64enc(len, ctx->count << 3); - /* - * Convert length to a vector of bytes -- we do this now rather - * than later because the length will change after we pad. - */ - mybe64enc(len, ctx->count); - /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ r = ctx->count & 0x3f; plen = (r < 56) ? (56 - r) : (120 - r); - assert(plen <= sizeof PAD); SHA256_Update(ctx, PAD, (size_t)plen); /* Add the terminating bit-count */ @@ -323,3 +318,43 @@ /* Clear the context state */ memset((void *)ctx, 0, sizeof(*ctx)); } + +/* + * A few test-vectors, just in case + */ + +static const struct sha256test { + const char *input; + const unsigned char output[32]; +} sha256test[] = { + { "", + {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, + 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, + 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55} }, + { "message digest", + {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, + 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, + 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50} }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0xdb, 0x4b, 0xfc, 0xbd, 0x4d, 0xa0, 0xcd, 0x85, 0xa6, 0x0c, 0x3c, + 0x37, 0xd3, 0xfb, 0xd8, 0x80, 0x5c, 0x77, 0xf1, 0x5f, 0xc6, 0xb1, + 0xfd, 0xfe, 0x61, 0x4e, 0xe0, 0xa7, 0xc8, 0xfd, 0xb4, 0xc0} }, + { NULL } +}; + + +void +SHA256_Test(void) +{ + struct SHA256Context c; + const struct sha256test *p; + unsigned char o[32]; + + for (p = sha256test; p->input != NULL; p++) { + SHA256_Init(&c); + SHA256_Update(&c, p->input, strlen(p->input)); + SHA256_Final(o, &c); + assert(!memcmp(o, p->output, 32)); + } +} + From phk at projects.linpro.no Wed Dec 3 10:39:15 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Wed, 3 Dec 2008 11:39:15 +0100 (CET) Subject: r3453 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081203103915.B0D671EC874@projects.linpro.no> Author: phk Date: 2008-12-03 11:39:15 +0100 (Wed, 03 Dec 2008) New Revision: 3453 Modified: trunk/varnish-cache/bin/varnishtest/tests/c00008.vtc Log: Wrap some long lines Modified: trunk/varnish-cache/bin/varnishtest/tests/c00008.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/c00008.vtc 2008-12-02 20:48:11 UTC (rev 3452) +++ trunk/varnish-cache/bin/varnishtest/tests/c00008.vtc 2008-12-03 10:39:15 UTC (rev 3453) @@ -5,7 +5,8 @@ server s1 { rxreq expect req.url == "/foo" - txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" -body "11111\n" + txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "11111\n" } -start varnish v1 -vcl+backend { } -start @@ -16,15 +17,18 @@ expect resp.status == 200 expect resp.http.content-length == 6 - txreq -url "/foo" -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:00 GMT" + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:00 GMT" rxresp expect resp.status == 200 - txreq -url "/foo" -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" rxresp expect resp.status == 304 - txreq -url "/foo" -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:02 GMT" + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:02 GMT" rxresp expect resp.status == 304 } From phk at projects.linpro.no Wed Dec 3 10:49:34 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Wed, 3 Dec 2008 11:49:34 +0100 (CET) Subject: r3454 - in trunk/varnish-cache: bin/varnishd include Message-ID: <20081203104934.B16931EC0FC@projects.linpro.no> Author: phk Date: 2008-12-03 11:49:34 +0100 (Wed, 03 Dec 2008) New Revision: 3454 Modified: trunk/varnish-cache/bin/varnishd/Makefile.am trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/hash_slinger.h trunk/varnish-cache/bin/varnishd/mgt_param.c trunk/varnish-cache/bin/varnishd/varnishd.c trunk/varnish-cache/include/stat_field.h Log: Add preliminary version of lock-less tree based lookup (see below) Enable SHA256 digests by default, and put it in the objhead. This increases the size of the objhead by 32 bytes, but may drop a bit again later, when other now unnecessary fields go away. Test SHA256 for correct operation on startup. About the "critbit" lookup: To enable this, use "-hcritbit" argument. "Crit Bit" trees, are also known under various other names, the original version of the idea is probably the PATRICIA tree. The basic concept is a tree structure which has nodes only where necessary to tell the indices apart. Our version of it, has some additional bells and whistles. First lookups do not require any locks until we reach the objhead we were looking for, or until we need to insert one which wasn't there. Second, the branch nodes are part of the objhead, as all but the very first will need one, this saves malloc operations big time. Now the down-sides: There are still missing bits, amongst these the "cooling off" list, for objheads that have been dereferenced, but where the branch-node is not. Currently we just leak that memory. There is a race relating to node deref and unlocked lookup that is not closed, weird things may happen until I fix it. I'd be interested to hear how long it survives before it croaks, but apart from that, would not advocate that you use it, until I fix those remaining issues. Modified: trunk/varnish-cache/bin/varnishd/Makefile.am =================================================================== --- trunk/varnish-cache/bin/varnishd/Makefile.am 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/bin/varnishd/Makefile.am 2008-12-03 10:49:34 UTC (rev 3454) @@ -40,6 +40,7 @@ cache_vrt_re.c \ cache_ws.c \ hash_classic.c \ + hash_critbit.c \ hash_simple_list.c \ instance.c \ mgt_child.c \ Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-03 10:49:34 UTC (rev 3454) @@ -251,7 +251,6 @@ struct http *h; struct objhead *oh; struct object *o, *busy_o, *grace_o; - unsigned char sha256[32]; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); @@ -259,12 +258,14 @@ AN(hash); w = sp->wrk; h = sp->http; + + HSH_Prealloc(sp); if (params->hash_sha256) { - SHA256_Final(sha256, sp->wrk->sha256ctx); + SHA256_Final(sp->wrk->nobjhead->digest, sp->wrk->sha256ctx); + sp->wrk->nobjhead->digest_len = 32; /* WSP(sp, SLT_Debug, "SHA256: <%.32s>", sha256); */ } - - HSH_Prealloc(sp); + if (sp->objhead != NULL) { CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC); oh = sp->objhead; Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-03 10:49:34 UTC (rev 3454) @@ -73,14 +73,24 @@ VTAILQ_HEAD(,object) objects; char *hash; unsigned hashlen; + unsigned char digest[32]; + unsigned char digest_len; VTAILQ_HEAD(, sess) waitinglist; - /*------------------------------------------------------------ - * The fields below are for the sole private use of the hash - * implementation. + /*---------------------------------------------------- + * The fields below are for the sole private use of + * the hash implementation(s). */ - VTAILQ_ENTRY(objhead) hoh_list; - void *hoh_head; - unsigned hoh_digest; + union { + void *filler[3]; + struct { + VTAILQ_ENTRY(objhead) u_n_hoh_list; + void *u_n_hoh_head; + unsigned u_n_hoh_digest; + } n; + } u; +#define hoh_list u.n.u_n_hoh_list +#define hoh_head u.n.u_n_hoh_head +#define hoh_digest u.n.u_n_hoh_digest }; #endif /* VARNISH_CACHE_CHILD */ Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-03 10:49:34 UTC (rev 3454) @@ -713,7 +713,7 @@ { "hash_sha256", tweak_bool, &master.hash_sha256, 0, 0, "Use SHA256 compression of hash-strings", 0, - "off", "bool" }, + "on", "bool" }, { "log_hashstring", tweak_bool, &master.log_hash, 0, 0, "Log the hash string to shared memory log.\n", 0, Modified: trunk/varnish-cache/bin/varnishd/varnishd.c =================================================================== --- trunk/varnish-cache/bin/varnishd/varnishd.c 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/bin/varnishd/varnishd.c 2008-12-03 10:49:34 UTC (rev 3454) @@ -59,6 +59,7 @@ #include "vsb.h" #include "vpf.h" +#include "vsha256.h" #include "cli.h" #include "cli_priv.h" @@ -157,11 +158,13 @@ extern struct hash_slinger hsl_slinger; extern struct hash_slinger hcl_slinger; +extern struct hash_slinger hcb_slinger; static const struct choice hsh_choice[] = { { "classic", &hcl_slinger }, { "simple", &hsl_slinger }, { "simple_list", &hsl_slinger }, /* backwards compat */ + { "critbit", &hcb_slinger }, { NULL, NULL } }; @@ -450,6 +453,11 @@ assert(TIM_parse("Sunday, 06-Nov-94 08:49:37 GMT") == 784111777); assert(TIM_parse("Sun Nov 6 08:49:37 1994") == 784111777); + /* + * Check that our SHA256 works + */ + SHA256_Test(); + memset(cli, 0, sizeof cli); cli[0].sb = vsb_newauto(); XXXAN(cli[0].sb); Modified: trunk/varnish-cache/include/stat_field.h =================================================================== --- trunk/varnish-cache/include/stat_field.h 2008-12-03 10:39:15 UTC (rev 3453) +++ trunk/varnish-cache/include/stat_field.h 2008-12-03 10:49:34 UTC (rev 3454) @@ -126,3 +126,7 @@ MAC_STAT(n_purge_obj_test, uint64_t, 'a', "N objects tested") MAC_STAT(n_purge_re_test, uint64_t, 'a', "N regexps tested against") MAC_STAT(n_purge_dups, uint64_t, 'a', "N duplicate purges removed") + +MAC_STAT(hcb_nolock, uint64_t, 'a', "HCB Lookups without lock") +MAC_STAT(hcb_lock, uint64_t, 'a', "HCB Lookups with lock") +MAC_STAT(hcb_insert, uint64_t, 'a', "HCB Inserts") From phk at projects.linpro.no Wed Dec 3 10:50:04 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Wed, 3 Dec 2008 11:50:04 +0100 (CET) Subject: r3455 - trunk/varnish-cache/bin/varnishd Message-ID: <20081203105004.58E051EC7C4@projects.linpro.no> Author: phk Date: 2008-12-03 11:50:04 +0100 (Wed, 03 Dec 2008) New Revision: 3455 Added: trunk/varnish-cache/bin/varnishd/hash_critbit.c Log: And as always I forgot to svn add the new file... Added: trunk/varnish-cache/bin/varnishd/hash_critbit.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_critbit.c (rev 0) +++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-03 10:50:04 UTC (rev 3455) @@ -0,0 +1,418 @@ +/*- + * Copyright (c) 2008 Linpro AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + * + * A Crit Bit tree based hash + */ + +#include "config.h" + +#include +#include +#include + +#include "shmlog.h" +#include "cache.h" +#include "hash_slinger.h" + +static struct lock hcb_mtx; + +/********************************************************************** + * Table for finding out how many bits two bytes have in common, + * counting from the MSB towards the LSB. + * ie: + * hcb_bittbl[0x01 ^ 0x22] == 2 + * hcb_bittbl[0x10 ^ 0x0b] == 3 + * + */ + +static unsigned char hcb_bittbl[256]; + +static unsigned char +hcb_bits(unsigned char x, unsigned char y) +{ + return hcb_bittbl[x ^ y]; +} + +static void +hcb_build_bittbl(void) +{ + unsigned x, y; + + y = 0; + for (x = 0; x < 8; x++) + for (; y < (1U << x); y++) + hcb_bittbl[y] = 8 - x; + + /* Quick asserts for sanity check */ + assert(hcb_bits(0x34, 0x34) == 8); + assert(hcb_bits(0xaa, 0x55) == 0); + assert(hcb_bits(0x01, 0x22) == 2); + assert(hcb_bits(0x10, 0x0b) == 3); +} + +/********************************************************************** + * For space reasons we overload the two pointers with two different + * kinds of of pointers. We cast them to uintptr_t's and abuse the + * low two bits to tell them apart, assuming that Varnish will never + * run on machines with less than 32bit alignment. + * + * Asserts will explode if these assumptions are not met. + */ + +struct hcb_y { + unsigned short critbit; + unsigned char ptr; + unsigned char bitmask; + uintptr_t leaf[2]; +}; + +#define HCB_BIT_NODE (1<<0) +#define HCB_BIT_Y (1<<1) + +struct hcb_root { + uintptr_t origo; + unsigned cmps; +}; + +static struct hcb_root hcb_root; + +/********************************************************************** + * Pointer accessor functions + */ +static int +hcb_is_node(uintptr_t u) +{ + + return (u & HCB_BIT_NODE); +} + +static int +hcb_is_y(uintptr_t u) +{ + + return (u & HCB_BIT_Y); +} + +static uintptr_t +hcb_r_node(struct objhead *n) +{ + + assert(!((uintptr_t)n & (HCB_BIT_NODE|HCB_BIT_Y))); + return (HCB_BIT_NODE | (uintptr_t)n); +} + +static struct objhead * +hcb_l_node(uintptr_t u) +{ + + assert(u & HCB_BIT_NODE); + assert(!(u & HCB_BIT_Y)); + return ((struct objhead *)(u & ~HCB_BIT_NODE)); +} + +static uintptr_t +hcb_r_y(struct hcb_y *y) +{ + + assert(!((uintptr_t)y & (HCB_BIT_NODE|HCB_BIT_Y))); + return (HCB_BIT_Y | (uintptr_t)y); +} + +static struct hcb_y * +hcb_l_y(uintptr_t u) +{ + + assert(!(u & HCB_BIT_NODE)); + assert(u & HCB_BIT_Y); + return ((struct hcb_y *)(u & ~HCB_BIT_Y)); +} + +/**********************************************************************/ + +static unsigned +hcb_crit_bit(const struct objhead *oh1, const struct objhead *oh2, struct hcb_y *y) +{ + unsigned u, r; + + for (u = 0; u < oh1->digest_len && oh1->digest[u] == oh2->digest[u]; u++) + ; + r = hcb_bits(oh1->digest[u], oh2->digest[u]); + y->ptr = u; + y->bitmask = 0x80 >> r; + y->critbit = u * 8 + r; + return (y->critbit); +} + +/**********************************************************************/ + +static struct objhead * +hcb_insert(struct hcb_root *root, struct objhead *oh, int has_lock) +{ + uintptr_t *p; + struct hcb_y *y, *y2; + struct objhead *oh2; + unsigned s, s2; + + + p = &root->origo; + if (*p == 0) { + if (!has_lock) + return (NULL); + *p = hcb_r_node(oh); + return (oh); + } + + while(hcb_is_y(*p)) { + y = hcb_l_y(*p); + if (y->ptr > oh->digest_len) + s = 0; + else + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + root->cmps++; + p = &y->leaf[s]; + } + + assert(hcb_is_node(*p)); + + /* We found a node, does it match ? */ + oh2 = hcb_l_node(*p); + if (oh2->digest_len == oh->digest_len && + !memcmp(oh2->digest, oh->digest, oh->digest_len)) + return (oh2); + + if (!has_lock) + return (NULL); + + /* Insert */ + + y2 = (void*)&oh->u; + memset(y2, 0, sizeof *y2); + (void)hcb_crit_bit(oh, hcb_l_node(*p), y2); + s2 = (oh->digest[y2->ptr] & y2->bitmask) != 0; + assert(s2 < 2); + y2->leaf[s2] = hcb_r_node(oh); + s2 = 1-s2; + + p = &root->origo; + assert(*p != 0); + + while(hcb_is_y(*p)) { + y = hcb_l_y(*p); + if (y->critbit > y2->critbit) + break; + if (y->ptr > oh->digest_len) + s = 0; + else + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + root->cmps++; + p = &y->leaf[s]; + } + y2->leaf[s2] = *p; + *p = hcb_r_y(y2); + return(oh); +} + +/**********************************************************************/ + +static void +hcb_delete(struct hcb_root *r, struct objhead *oh) +{ + struct hcb_y *y; + uintptr_t *p; + unsigned s; + + if (r->origo == hcb_r_node(oh)) { + r->origo = 0; + return; + } + p = &r->origo; + assert(hcb_is_y(*p)); + + y = NULL; + while(hcb_is_y(*p)) { + y = hcb_l_y(*p); + if (y->ptr > oh->digest_len) + s = 0; + else + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + if (y->leaf[s] == hcb_r_node(oh)) { + *p = y->leaf[1 - s]; + y->leaf[0] = 0; + y->leaf[1] = 0; + return; + } + r->cmps++; + p = &y->leaf[s]; + } +abort(); + *p = y->leaf[1 - s]; +} + +/**********************************************************************/ + +static void +dumptree(uintptr_t p, int indent, FILE *fd) +{ + int i; + const struct objhead *oh; + const struct hcb_y *y; + + if (p == 0) + return; + if (hcb_is_node(p)) { + oh = hcb_l_node(p); + fprintf(fd, "%*.*sN %u %u r%d <%02x%02x%02x...> <%s>\n", + indent, indent, "", oh->digest_len, indent / 2, + oh->refcnt, + oh->digest[0], oh->digest[1], oh->digest[2], + oh->hash); + return; + } + assert(hcb_is_y(p)); + y = hcb_l_y(p); + fprintf(fd, "%*.*sY c %u p %u b %02x i %d\n", + indent, indent, "", + y->critbit, y->ptr, y->bitmask, indent / 2); + indent += 2; + for (i = 0; i < 2; i++) + dumptree(y->leaf[i], indent, fd); +} + +static void +dump(const struct hcb_root *root, FILE *fd) +{ + fprintf(fd, "-------------\n"); + dumptree(root->origo, 0, fd); + fprintf(fd, "-------------\n"); + fflush(fd); +} + + +/**********************************************************************/ + +static void +hcb_start(void) +{ + struct objhead *oh = NULL; + + (void)oh; + assert(params->hash_sha256); + assert(sizeof(struct hcb_y) <= sizeof(oh->u)); + memset(&hcb_root, 0, sizeof hcb_root); + hcb_build_bittbl(); + Lck_New(&hcb_mtx); +} + +static int +hcb_deref(struct objhead *oh) +{ + int r; + struct hcb_y *y; + + r = 1; + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + Lck_Lock(&oh->mtx); + if (--oh->refcnt == 0) { + Lck_Lock(&hcb_mtx); + hcb_delete(&hcb_root, oh); + y = (void*)&oh->u; + if (y->leaf[0] == 0 && y->leaf[1] == 0) + r = 0; + else { + /* XXX: on waiting list */ + } + Lck_Unlock(&hcb_mtx); + } + Lck_Unlock(&oh->mtx); + if (0) { + fprintf(stderr, "%s %d %d <%s>\n", __func__, __LINE__, r, oh->hash); + dump(&hcb_root, stderr); + } + return (r); +} + +static struct objhead * +hcb_lookup(const struct sess *sp, struct objhead *noh) +{ + struct objhead *oh; + + assert(params->hash_sha256); + oh = hcb_insert(&hcb_root, noh, 0); + if (oh != NULL) { + /* Assert that we didn't muck with the tree without lock */ + assert(oh != noh); + Lck_Lock(&oh->mtx); + oh->refcnt++; + Lck_Unlock(&oh->mtx); + VSL_stats->hcb_nolock++; + if (0) { + fprintf(stderr, "%s %d\n", __func__, __LINE__); + dump(&hcb_root, stderr); + } + return (oh); + } + + /* + * Try again, holding lock and fully ready objhead, so that if + * somebody else beats us back, they do not get surprised. + */ + HSH_Copy(sp, noh); + Lck_Lock(&hcb_mtx); + oh = hcb_insert(&hcb_root, noh, 1); + if (oh == noh) { + VSL_stats->hcb_insert++; + if (0) { + fprintf(stderr, "%s %d\n", __func__, __LINE__); + dump(&hcb_root, stderr); + } + } else { + free(noh->hash); + noh->hash = NULL; + noh->hashlen = 0; + VSL_stats->hcb_lock++; + if (0) { + fprintf(stderr, "%s %d\n", __func__, __LINE__); + dump(&hcb_root, stderr); + } + } + Lck_Unlock(&hcb_mtx); + return (oh); +} + + +struct hash_slinger hcb_slinger = { + .magic = SLINGER_MAGIC, + .name = "critbit", + .start = hcb_start, + .lookup = hcb_lookup, + .deref = hcb_deref, +}; From phk at projects.linpro.no Wed Dec 3 16:40:46 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Wed, 3 Dec 2008 17:40:46 +0100 (CET) Subject: r3456 - trunk/varnish-cache/bin/varnishd Message-ID: <20081203164046.288881EC874@projects.linpro.no> Author: phk Date: 2008-12-03 17:40:45 +0100 (Wed, 03 Dec 2008) New Revision: 3456 Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c Log: Resolve the remove/lookup race the simple way. Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-03 10:50:04 UTC (rev 3455) +++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-03 16:40:45 UTC (rev 3456) @@ -364,6 +364,7 @@ hcb_lookup(const struct sess *sp, struct objhead *noh) { struct objhead *oh; + unsigned u; assert(params->hash_sha256); oh = hcb_insert(&hcb_root, noh, 0); @@ -371,14 +372,14 @@ /* Assert that we didn't muck with the tree without lock */ assert(oh != noh); Lck_Lock(&oh->mtx); - oh->refcnt++; + u = oh->refcnt; + if (u) + oh->refcnt++; Lck_Unlock(&oh->mtx); - VSL_stats->hcb_nolock++; - if (0) { - fprintf(stderr, "%s %d\n", __func__, __LINE__); - dump(&hcb_root, stderr); + if (u) { + VSL_stats->hcb_nolock++; + return (oh); } - return (oh); } /* From phk at projects.linpro.no Mon Dec 8 10:03:31 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 8 Dec 2008 11:03:31 +0100 (CET) Subject: r3457 - trunk/varnish-cache/bin/varnishd Message-ID: <20081208100331.BA7661EC7C5@projects.linpro.no> Author: phk Date: 2008-12-08 11:03:31 +0100 (Mon, 08 Dec 2008) New Revision: 3457 Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/hash_critbit.c trunk/varnish-cache/bin/varnishd/hash_slinger.h Log: Implement the cooling period before objhead's are deleted in the critbit hasher. Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-03 16:40:45 UTC (rev 3456) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-08 10:03:31 UTC (rev 3457) @@ -262,7 +262,6 @@ HSH_Prealloc(sp); if (params->hash_sha256) { SHA256_Final(sp->wrk->nobjhead->digest, sp->wrk->sha256ctx); - sp->wrk->nobjhead->digest_len = 32; /* WSP(sp, SLT_Debug, "SHA256: <%.32s>", sha256); */ } Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-03 16:40:45 UTC (rev 3456) +++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-08 10:03:31 UTC (rev 3457) @@ -30,6 +30,8 @@ * A Crit Bit tree based hash */ +#define PHK 1 + #include "config.h" #include @@ -42,6 +44,8 @@ static struct lock hcb_mtx; +static VTAILQ_HEAD(,objhead) laylow = VTAILQ_HEAD_INITIALIZER(laylow); + /********************************************************************** * Table for finding out how many bits two bytes have in common, * counting from the MSB towards the LSB. @@ -160,7 +164,7 @@ { unsigned u, r; - for (u = 0; u < oh1->digest_len && oh1->digest[u] == oh2->digest[u]; u++) + for (u = 0; u < DIGEST_LEN && oh1->digest[u] == oh2->digest[u]; u++) ; r = hcb_bits(oh1->digest[u], oh2->digest[u]); y->ptr = u; @@ -190,7 +194,7 @@ while(hcb_is_y(*p)) { y = hcb_l_y(*p); - if (y->ptr > oh->digest_len) + if (y->ptr > DIGEST_LEN) s = 0; else s = (oh->digest[y->ptr] & y->bitmask) != 0; @@ -203,8 +207,7 @@ /* We found a node, does it match ? */ oh2 = hcb_l_node(*p); - if (oh2->digest_len == oh->digest_len && - !memcmp(oh2->digest, oh->digest, oh->digest_len)) + if (!memcmp(oh2->digest, oh->digest, DIGEST_LEN)) return (oh2); if (!has_lock) @@ -227,7 +230,7 @@ y = hcb_l_y(*p); if (y->critbit > y2->critbit) break; - if (y->ptr > oh->digest_len) + if (y->ptr > DIGEST_LEN) s = 0; else s = (oh->digest[y->ptr] & y->bitmask) != 0; @@ -259,7 +262,7 @@ y = NULL; while(hcb_is_y(*p)) { y = hcb_l_y(*p); - if (y->ptr > oh->digest_len) + if (y->ptr > DIGEST_LEN) s = 0; else s = (oh->digest[y->ptr] & y->bitmask) != 0; @@ -291,7 +294,7 @@ if (hcb_is_node(p)) { oh = hcb_l_node(p); fprintf(fd, "%*.*sN %u %u r%d <%02x%02x%02x...> <%s>\n", - indent, indent, "", oh->digest_len, indent / 2, + indent, indent, "", DIGEST_LEN, indent / 2, oh->refcnt, oh->digest[0], oh->digest[1], oh->digest[2], oh->hash); @@ -319,12 +322,49 @@ /**********************************************************************/ +#define COOL_DURATION 15 /* seconds */ + +static void * +hcb_cleaner(void *priv) +{ + struct objhead *oh, *oh2; + struct hcb_y *y; + + THR_SetName("hcb_cleaner"); + (void)priv; + while (1) { + sleep(1); + Lck_Lock(&hcb_mtx); + VTAILQ_FOREACH_SAFE(oh, &laylow, coollist, oh2) { + if (oh->hash != NULL) { + free(oh->hash); + oh->hash = NULL; + } + y = (void *)&oh->u; + if (y->leaf[0] || y->leaf[1]) + continue; + if (++oh->refcnt > COOL_DURATION) { + VTAILQ_REMOVE(&laylow, oh, coollist); + if (PHK) + fprintf(stderr, "OH %p is cold enough\n", oh); + free(oh); + VSL_stats->n_objecthead--; + } + } + Lck_Unlock(&hcb_mtx); + } +} + +/**********************************************************************/ + static void hcb_start(void) { struct objhead *oh = NULL; + pthread_t tp; (void)oh; + AZ(pthread_create(&tp, NULL, hcb_cleaner, NULL)); assert(params->hash_sha256); assert(sizeof(struct hcb_y) <= sizeof(oh->u)); memset(&hcb_root, 0, sizeof hcb_root); @@ -336,7 +376,6 @@ hcb_deref(struct objhead *oh) { int r; - struct hcb_y *y; r = 1; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); @@ -344,16 +383,11 @@ if (--oh->refcnt == 0) { Lck_Lock(&hcb_mtx); hcb_delete(&hcb_root, oh); - y = (void*)&oh->u; - if (y->leaf[0] == 0 && y->leaf[1] == 0) - r = 0; - else { - /* XXX: on waiting list */ - } + VTAILQ_INSERT_TAIL(&laylow, oh, coollist); Lck_Unlock(&hcb_mtx); } Lck_Unlock(&oh->mtx); - if (0) { + if (PHK) { fprintf(stderr, "%s %d %d <%s>\n", __func__, __LINE__, r, oh->hash); dump(&hcb_root, stderr); } @@ -391,7 +425,7 @@ oh = hcb_insert(&hcb_root, noh, 1); if (oh == noh) { VSL_stats->hcb_insert++; - if (0) { + if (PHK) { fprintf(stderr, "%s %d\n", __func__, __LINE__); dump(&hcb_root, stderr); } @@ -400,7 +434,7 @@ noh->hash = NULL; noh->hashlen = 0; VSL_stats->hcb_lock++; - if (0) { + if (PHK) { fprintf(stderr, "%s %d\n", __func__, __LINE__); dump(&hcb_root, stderr); } Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-03 16:40:45 UTC (rev 3456) +++ trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-08 10:03:31 UTC (rev 3457) @@ -64,6 +64,9 @@ #ifdef VARNISH_CACHE_CHILD + +#define DIGEST_LEN 32 + struct objhead { unsigned magic; #define OBJHEAD_MAGIC 0x1b96615d @@ -73,9 +76,13 @@ VTAILQ_HEAD(,object) objects; char *hash; unsigned hashlen; - unsigned char digest[32]; - unsigned char digest_len; - VTAILQ_HEAD(, sess) waitinglist; + unsigned char digest[DIGEST_LEN]; + union { + VTAILQ_HEAD(, sess) __u_waitinglist; + VTAILQ_ENTRY(objhead) __u_coollist; + } __u; +#define waitinglist __u.__u_waitinglist +#define coollist __u.__u_coollist /*---------------------------------------------------- * The fields below are for the sole private use of From phk at projects.linpro.no Mon Dec 8 10:16:26 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 8 Dec 2008 11:16:26 +0100 (CET) Subject: r3458 - trunk/varnish-cache/bin/varnishd Message-ID: <20081208101626.2093B1EC4A8@projects.linpro.no> Author: phk Date: 2008-12-08 11:16:25 +0100 (Mon, 08 Dec 2008) New Revision: 3458 Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c Log: Silence debug noise Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-08 10:03:31 UTC (rev 3457) +++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-08 10:16:25 UTC (rev 3458) @@ -30,7 +30,7 @@ * A Crit Bit tree based hash */ -#define PHK 1 +#define PHK 0 #include "config.h" From phk at projects.linpro.no Mon Dec 8 12:37:42 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Mon, 8 Dec 2008 13:37:42 +0100 (CET) Subject: r3459 - trunk/varnish-cache/bin/varnishd Message-ID: <20081208123742.5957F1ED71B@projects.linpro.no> Author: phk Date: 2008-12-08 13:37:42 +0100 (Mon, 08 Dec 2008) New Revision: 3459 Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c Log: Increase session workspace to 16k Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-08 10:16:25 UTC (rev 3458) +++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-08 12:37:42 UTC (rev 3459) @@ -489,7 +489,7 @@ "header and any edits done to it in the VCL code.\n" "Minimum is 1024 bytes.", DELAYED_EFFECT, - "8192", "bytes" }, + "16384", "bytes" }, { "obj_workspace", tweak_uint, &master.obj_workspace, 1024, UINT_MAX, "Bytes of HTTP protocol workspace allocated for objects. " "This space must be big enough for the entire HTTP protocol " From phk at projects.linpro.no Tue Dec 9 13:54:10 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Tue, 9 Dec 2008 14:54:10 +0100 (CET) Subject: r3460 - in trunk/varnish-cache: bin/varnishd lib/libvcl Message-ID: <20081209135410.11CA61EC200@projects.linpro.no> Author: phk Date: 2008-12-09 14:54:09 +0100 (Tue, 09 Dec 2008) New Revision: 3460 Modified: trunk/varnish-cache/bin/varnishd/default.vcl trunk/varnish-cache/lib/libvcl/vcc_action.c Log: Add support for, and use a new syntax for terminating actions in VCL, basically "return(action)" instead of just "action". The previos syntax is still available. Modified: trunk/varnish-cache/bin/varnishd/default.vcl =================================================================== --- trunk/varnish-cache/bin/varnishd/default.vcl 2008-12-08 12:37:42 UTC (rev 3459) +++ trunk/varnish-cache/bin/varnishd/default.vcl 2008-12-09 13:54:09 UTC (rev 3460) @@ -48,25 +48,25 @@ req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ - pipe; + return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ - pass; + return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ - pass; + return (pass); } - lookup; + return (lookup); } sub vcl_pipe { - pipe; + return (pipe); } sub vcl_pass { - pass; + return (pass); } sub vcl_hash { @@ -76,48 +76,48 @@ } else { set req.hash += server.ip; } - hash; + return (hash); } sub vcl_hit { if (!obj.cacheable) { - pass; + return (pass); } - deliver; + return (deliver); } sub vcl_miss { - fetch; + return (fetch); } sub vcl_fetch { if (!obj.cacheable) { - pass; + return (pass); } if (obj.http.Set-Cookie) { - pass; + return (pass); } set obj.prefetch = -30s; - deliver; + return (deliver); } sub vcl_deliver { - deliver; + return (deliver); } sub vcl_discard { /* XXX: Do not redefine vcl_discard{}, it is not yet supported */ - discard; + return (discard); } sub vcl_prefetch { /* XXX: Do not redefine vcl_prefetch{}, it is not yet supported */ - fetch; + return (fetch); } sub vcl_timeout { /* XXX: Do not redefine vcl_timeout{}, it is not yet supported */ - discard; + return (discard); } sub vcl_error { @@ -141,5 +141,5 @@ "}; - deliver; + return (deliver); } Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-08 12:37:42 UTC (rev 3459) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-09 13:54:09 UTC (rev 3460) @@ -41,23 +41,37 @@ /*--------------------------------------------------------------------*/ -#define VCL_RET_MAC(l,u,b,i) \ -static void \ -parse_##l(struct tokenlist *tl) \ -{ \ - \ - Fb(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #u); \ - vcc_ProcAction(tl->curproc, i, tl->t); \ - vcc_NextToken(tl); \ -} +static void +parse_action(struct tokenlist *tl) +{ + int retval = 0; + Expect(tl, ID); + +#define VCL_RET_MAC(l, u, b, i) \ + do { \ + if (vcc_IdIs(tl->t, #l)) { \ + Fb(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #u); \ + vcc_ProcAction(tl->curproc, i, tl->t); \ + retval = 1; \ + } \ + } while (0); +#define VCL_RET_MAC_E(l, u, b, i) VCL_RET_MAC(l, u, b, i) #include "vcl_returns.h" #undef VCL_RET_MAC +#undef VCL_RET_MAC_E + if (!retval) { + vsb_printf(tl->sb, "Expected action name.\n"); + vcc_ErrWhere(tl, tl->t); + ERRCHK(tl); + } + vcc_NextToken(tl); +} /*--------------------------------------------------------------------*/ static void -parse_restart_real(struct tokenlist *tl) +parse_restart(struct tokenlist *tl) { struct token *t1; @@ -70,7 +84,9 @@ vcc_ErrWhere(tl, t1); ERRCHK(tl); } - parse_restart(tl); + Fb(tl, 1, "VRT_done(sp, VCL_RET_RESTART);\n"); + vcc_ProcAction(tl->curproc, VCL_RET_RESTART, tl->t); + vcc_NextToken(tl); } /*--------------------------------------------------------------------*/ @@ -407,6 +423,22 @@ /*--------------------------------------------------------------------*/ static void +parse_return(struct tokenlist *tl) +{ + vcc_NextToken(tl); + Expect(tl, '('); + vcc_NextToken(tl); + Expect(tl, ID); + + parse_action(tl); + ERRCHK(tl); + Expect(tl, ')'); + vcc_NextToken(tl); +} + +/*--------------------------------------------------------------------*/ + +static void parse_synthetic(struct tokenlist *tl) { vcc_NextToken(tl); @@ -430,12 +462,11 @@ const char *name; action_f *func; } action_table[] = { - { "restart", parse_restart_real }, -#define VCL_RET_MAC(l, u, b, i) { #l, parse_##l }, -#define VCL_RET_MAC_E(l, u, b, i) VCL_RET_MAC(l, u, b, i) + { "restart", parse_restart }, + { "error", parse_error }, +#define VCL_RET_MAC(l, u, b, i) { #l, parse_action }, #include "vcl_returns.h" #undef VCL_RET_MAC -#undef VCL_RET_MAC_E /* Keep list sorted from here */ { "call", parse_call }, @@ -447,6 +478,7 @@ { "set", parse_set }, { "synthetic", parse_synthetic }, { "unset", parse_unset }, + { "return", parse_return }, { NULL, NULL } }; From petter at projects.linpro.no Fri Dec 12 10:10:05 2008 From: petter at projects.linpro.no (petter at projects.linpro.no) Date: Fri, 12 Dec 2008 11:10:05 +0100 (CET) Subject: r3461 - in trunk/varnish-tools: . webgui webgui/Varnish webgui/css webgui/images webgui/templates webgui/test Message-ID: <20081212101005.941C51EC100@projects.linpro.no> Author: petter Date: 2008-12-12 11:10:05 +0100 (Fri, 12 Dec 2008) New Revision: 3461 Added: trunk/varnish-tools/webgui/ trunk/varnish-tools/webgui/README trunk/varnish-tools/webgui/Varnish/ trunk/varnish-tools/webgui/Varnish/Management.pm trunk/varnish-tools/webgui/Varnish/Node.pm trunk/varnish-tools/webgui/Varnish/NodeManager.pm trunk/varnish-tools/webgui/Varnish/RequestHandler.pm trunk/varnish-tools/webgui/Varnish/Statistics.pm trunk/varnish-tools/webgui/Varnish/Util.pm trunk/varnish-tools/webgui/css/ trunk/varnish-tools/webgui/css/web.css trunk/varnish-tools/webgui/images/ trunk/varnish-tools/webgui/images/favicon.png trunk/varnish-tools/webgui/images/nograph.png trunk/varnish-tools/webgui/images/running.png trunk/varnish-tools/webgui/images/running_nok.png trunk/varnish-tools/webgui/images/stopped.png trunk/varnish-tools/webgui/images/varnish-logo-christmas.png trunk/varnish-tools/webgui/images/varnish-logo.png trunk/varnish-tools/webgui/start.pl trunk/varnish-tools/webgui/templates/ trunk/varnish-tools/webgui/templates/.master.tmpl.swp trunk/varnish-tools/webgui/templates/configure_parameters.tmpl trunk/varnish-tools/webgui/templates/edit_vcl.tmpl trunk/varnish-tools/webgui/templates/management_console.tmpl trunk/varnish-tools/webgui/templates/master.tmpl trunk/varnish-tools/webgui/templates/node_management.tmpl trunk/varnish-tools/webgui/templates/view_stats.tmpl trunk/varnish-tools/webgui/test/ trunk/varnish-tools/webgui/test/test_management.pl Log: Initial checkin of a work in progress of the web GUI Added: trunk/varnish-tools/webgui/README =================================================================== --- trunk/varnish-tools/webgui/README (rev 0) +++ trunk/varnish-tools/webgui/README 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,107 @@ +Web GUI for Varnish, very limited christmas edition +=================================================== + +This is a preview of the upcoming web GUI for Varnish, which will be released with version 2.1 It has most of the features intended for the final version, but a number of things are still missing, so it is just inteded to get feedback. The following known things are _not_ implemented + - saving of state: if the web server goes down, the information is lost. + - smart data collection: it stores ALL the polled data with the given poll intervlal. It does not truncate data used for the hour, day, week and month graph. So eventually you will go out of memory. + - simple configuration: currently, you must edit the start.pl script by hand to set the configuration, and edit Varnish/RequestHandler.pl to add graphs and summary statistics. + - security: there is no form for access control or security implemented. + +So I wouldn't use it for anything with 'prod' in its name, but as a preview of what is to come. It should be noted that when adding nodes to an existing group, all the parameters and VCL of that node are replaced with the default parameters and VCL of the group. So if you add more nodes to a group, be aware of this. + +Any feedback is most welcome, so just post it to varnish-misc at projects.linpro.no. + +So what can you actually do with this thing? + + +Overview +-------- + +The web GUI is written in Perl and runs in its own server container, so a web server is not required, only the necessary Perl modules. The GUI consists of five sections: 'View stats', 'Configure parameters', 'Edit VCL', 'Node management' and 'Management console'. As the names might suggest, the GUI let you + +- view statistics from the Varnish nodes +- configure the parameters of the Varnish nodes and clusters +- edit the VCL for each cluster, which will be shared between all the nodes +- perform node management, like adding clusters and nodes, get the state of the nodes and backend healths +- get access to the management console of each node + +Requirements +------------ + +The web GUI is written in Perl, and uses some modules that might not be installed by default: + +- HTTP::Daemon (libwww-perl) +- HTML::Template (libhtml-template-perl) +- GD::Graph (libgd-graph-perl) +- LWP::UserAgent (libwww-perl) + +The name in the paranthesis are the package name on a standard Ubuntu system. The rest of the modules should be pretty standard. + +As the management port of the Varnish instances are used for collecting data, this must be enaled when starting varnish. This is done with the -T option to varnish, e.g. like this + +$ /opt/varnish/sbin/varnishd -a :80 -b :8080 -T :9003 + +Configuration +------------- + +The configuration is done directly in the Perl code for this very limited christmas edition, but will be more userfriendly in the final version. As this version doesn't save your state, e.g. the nodes and clusters added, I would recommend adding this in the start.pl. The files needing customisation are + +- start.pl: early in the file you'll see '# Configuration starts here', and this is where to set the config. It is all commented, so should be fairly straight forward. +- Varnish/RequestHandler.pl: this is the main enging of the whole web GUI, including the parts creating the summary stats and graphs. This is well documented in the code, so look at line 380 for adding values to the summary statistics and 826 for adding custom graphs (and removing the dummy 'Missing graph'). + +That is configuration for this version. Remember that when creating and editing VCLs, the information is stored on the node, so if the web server is restarted, the nodes will still have the VCLs (unless they are restarted too, of course). + +Starting it +----------- + +'perl start.pl' shoud do it, after reading the Configuration section and setting the values to something reasonable for your setup. If the shebang matches your perl, and the script is executable, './start.pl' should also do it. + +The GUI +====== + +View stats +---------- + +In 'View stats' you will see statistics gathered from the nodes. The 'Summary statistics' is/will be customisable (see Configuration) and shows the most important statistics. If you want to see all the statistics from the Varnish nodes you turn 'Raw statistics' on. If you want the page to be refreshed automatically in order to follow the graph 'live', you can turn 'Auto refresh' on. The refresh rate is the same as the rate the statistics are collected from the nodes. + +Configure parameters +-------------------- + +'Configure' parameters let you configure the parameters for a group (cluster) or a single node. For this version, the parameters for the groups are a copy of the parameters of the first node added to the group, so if a group has not been populated, it will not contain any values. Changing a value in a group will change the same value of all the nodes in that group. Changing a value for node only changes that node, naturally. + +Edit VCL +-------- + +'Edit VCL' lets you edit the VCL of the group, and any changes made here will be reflected on all the nodes of the group. You can add, edit, save and discard VCLs as well as making a VCL active. It discards without warning (isn't baby safe yet), so be carefull. + +A note about the editor: it is a simple text are, with giving you an indent as expected. If you save a VCL with error, the errors are listed and you can click on the 'Line X Pos Y' information in the error list to jump to that position in the editor. + + +Node management +--------------- + +From 'Node management' you can manage groups and nodes. It will let you add, remove, stop and start the nodes and groups. It also displays information about the state of the node: + - the V column is the state of Varnish. Green means it responds with a 200 message to a probe (it probes http://varnish-host/), a yellow light means it anwers with a non-200 status code and a red light means it does not respond at all. + - the M columns is the state of the management port, with green meaning OK and red meaning it is not reachable. As almost all functionality is dependent on the management port, it should never have a red light. + + If a health probe is defined in the VCL, a list of backend healths for the running VCL is shown as well. + + Since this version does not let you save the configuration, it is recommended that you add groups and nodes in the stat.pl file as explained in Configuration. + + WARNING: as noted earlier, adding nodes to a group will replace that nodes parameter and VCL. + +Management console +------------------ + +'Management console' gives you access to the management console of each node. The input field has magical tab completion for the CLI commands and a command history accessable by arrow up/down. In addition to the standard CLI commands, 'cls' can be issued to clear the console. + +The color and size of the console can be changed, but this information is unfortunately not stored when switching nodes. + + +Road ahead +========== + +This is a sneak preview of the web GUI for 2.1, and as such is not complete. It is mostly feature complete (minus things mentioned in the start of this file), so any comments on what is working, what is lacking etc. is most appreciated. Please use the varnish-misc at projects.linpro.no mailing list for discussion. + + +Merry christmas! Added: trunk/varnish-tools/webgui/Varnish/Management.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/Management.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/Management.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,286 @@ +package Varnish::Management; + +use strict; +use IO::Socket::INET; +use Exporter; +use List::Util qw(first); + +{ + my %hostname_of; + my %port_of; + my %error_of; + my %socket_of; + + sub new { + my ($class, $hostname, $port) = @_; + + my $new_object = bless \do{ my $anon_scalar; }, $class; + + $hostname_of{$new_object} = $hostname; + $port_of{$new_object} = $port; + $error_of{$new_object} = ""; + + return $new_object; + } + + sub _send_command { + my ($self, $command) = @_; + + if (!$socket_of{$self} || !$socket_of{$self}->connected ) { + my $socket = new IO::Socket::INET->new( + PeerPort => $port_of{$self}, + Proto => 'tcp', + PeerAddr => $hostname_of{$self} + ); + return ("666", "Could not connect to node") if (!$socket); + $socket_of{$self} = $socket; + } + my $socket = $socket_of{$self}; + + print $socket "$command\n"; + my ($status_code, $response_size) = <$socket> =~ m/^(\d+) (\d+)/; + my $response; + my $remaining_bytes = $response_size; + while ($remaining_bytes > 0 ) { + my $data; + my $read = read $socket, $data, $remaining_bytes; + $response .= $data; + $remaining_bytes -= $read; + } + my $eat_newline = <$socket>; + return ($status_code, $response); + } + + sub send_command { + my ($self, $command) = @_; + + my ($status_code, $response) = _send_command($self, $command); + + return no_error($self, $response) if $status_code eq "200"; + return set_error($self, $response); + } + + sub get_parameters { + my ($self) = @_; + + my %param; + my $current_param; + + my ($status_code, $response) = _send_command($self, "param.show -l"); + return set_error($self, $response) if ($status_code ne "200"); + for my $line (split( '\n', $response)) { + + if ($line =~ /^(\w+)\s+(\w+) (.*)$/) { + my %param_info = ( + value => $2, + unit => $3 + ); + + $current_param = $1; + $param{$1} = \%param_info; + } + elsif ($line =~ /^\s+(.+)$/) { +# The first comment line contains no . and describes the default value. + if (!$param{$current_param}->{'description'}) { + $param{$current_param}->{'description'} = "$1. "; + } + else { + $param{$current_param}->{'description'} .= "$1 "; + } + } + } + + return \%param; + } + + sub get_parameter($) { + my ($self, $parameter) = @_; + + my ($status_code, $response) = _send_command($self, "param.show $parameter"); + + return no_error($self, $1) if ($response =~ /^(?:\w+)\s+(\w+)/); + return set_error($self, $response); + } + + sub set_parameter { + my ($self, $parameter, $value) = @_; + + my ($status_code, $response) = _send_command($self, "param.set $parameter $value"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub get_vcl_names { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "vcl.list"); + return set_error($self, $response) if ($status_code ne "200"); + + my @vcl_infos = ($response =~ /^(\w+)\s+\d+\s+(\w+)$/gm); + my $vcl_names_ref = []; + my $active_vcl_name = ""; + while (my ($status, $name) = splice @vcl_infos, 0, 2) { + next if ($status eq "discarded"); + + if ($status eq "active") { + $active_vcl_name = $name; + } + push @$vcl_names_ref, $name; + } + + unshift @$vcl_names_ref, $active_vcl_name; + return no_error($self, $vcl_names_ref) if ($status_code eq "200"); + } + + sub get_vcl { + my ($self, $vcl_name) = @_; + + my ($status_code, $response) = _send_command($self, "vcl.show $vcl_name"); + + return no_error($self, $response) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub set_vcl { + my ($self, $vcl_name, $vcl) = @_; + $vcl =~ s/"/\\"/g; + $vcl =~ s/\r//g; + $vcl =~ s/\n/\\n/g; + + my $need_restart = 0; + my ($active_vcl_name, @vcl_names) = @{get_vcl_names($self)}; + my $editing_active_vcl = $vcl_name eq $active_vcl_name; + + # try to compile the new vcl + my ($status_code, $response) = _send_command($self, "vcl.inline _new_vcl \"$vcl\""); + if ($status_code ne "200") { + _send_command($self, "vcl.discard _new_vcl"); + return set_error($self, $response); + } + + if ($editing_active_vcl) { + ($status_code, $response) = _send_command($self, "vcl.use _new_vcl"); + } + + if (grep { $_ eq $vcl_name } @vcl_names) { + ($status_code, $response) = _send_command($self, "vcl.discard $vcl_name"); + if ($status_code ne "200") { + _send_command($self, "vcl.use $vcl_name"); + _send_command($self, "vcl.discard _new_vcl"); + return set_error($self, $response); + } + } + ($status_code, $response) = _send_command($self, "vcl.inline $vcl_name \"$vcl\""); + + if ($editing_active_vcl) { + ($status_code, $response) = _send_command($self, "vcl.use $vcl_name"); + } + _send_command($self, "vcl.discard _new_vcl"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub discard_vcl { + my ($self, $vcl_name) = @_; + + my ($status_code, $response) = _send_command($self, "vcl.discard $vcl_name"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub make_vcl_active { + my ($self, $vcl_name) = @_; + + my ($status_code, $response) = _send_command($self, "vcl.use $vcl_name"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub get_stats { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "stats"); + + my %stat_counter = map { + /^\s*(\d+)\s+(.*?)$/; + $2 => $1 + } split /\n/, $response; + + return no_error($self, \%stat_counter) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub ping { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "stats"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub start { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "start"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub stop { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "stop"); + + return no_error($self) if ($status_code eq "200"); + return set_error($self, $response); + } + + sub set_error { + my ($self, $error) = @_; + + $error_of{$self} = $error; + + return; + } + + sub get_error { + my ($self) = @_; + + return $error_of{$self}; + } + + sub no_error { + my ($self, $return_value) = @_; + + $error_of{$self} = ""; + + return defined($return_value) ? $return_value : 1; + } + + sub close { + my ($self) = @_; + + if ($socket_of{$self} && $socket_of{$self}->connected) { + $socket_of{$self}->close(); + } + } + + sub get_backend_health { + my ($self) = @_; + + my ($status_code, $response) = _send_command($self, "debug.health"); + return set_error($self, $response) if ($status_code ne "200"); + + my %backend_health = ($response =~ /^Backend (\w+) is (\w+)$/gm); + + return no_error($self, \%backend_health); + } +} + +1; Added: trunk/varnish-tools/webgui/Varnish/Node.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/Node.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/Node.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,128 @@ +package Varnish::Node; + +use strict; +use LWP::UserAgent; +use Varnish::Management; + +{ + my %name_of; + my %address_of; + my %port_of; + my %group_of; + my %management_of; + my %management_port_of; + my %is_master_of; + my %node_id_of; + + my $next_node_id = 1; + + sub new { + my ($class, $arg_ref) = @_; + + my $new_object = bless \do{ my $anon_scalar; }, $class; + + $name_of{$new_object} = $arg_ref->{'name'}; + $address_of{$new_object} = $arg_ref->{'address'}; + $port_of{$new_object} = $arg_ref->{'port'}; + $group_of{$new_object} = $arg_ref->{'group'}; + $management_port_of{$new_object} = $arg_ref->{'management_port'}; + $management_of{$new_object} = Varnish::Management->new($arg_ref->{'address'}, + $arg_ref->{'management_port'}); + $is_master_of{$new_object} = 0; + $node_id_of{$new_object} = $next_node_id++; + + return $new_object; + } + + sub get_id { + my ($self) = @_; + + return $node_id_of{$self}; + } + + sub get_name { + my ($self) = @_; + + return $name_of{$self}; + } + + sub get_address { + my ($self) = @_; + + return $address_of{$self}; + } + + sub get_port { + my ($self) = @_; + + return $port_of{$self}; + } + + sub get_group { + my ($self) = @_; + + return $group_of{$self}; + } + + sub get_management { + my ($self) = @_; + + return $management_of{$self}; + } + + sub get_management_port { + my ($self) = @_; + + return $management_port_of{$self}; + } + + sub is_master { + my ($self) = @_; + + return $is_master_of{$self}; + } + + sub set_master { + my ($self, $master) = @_; + + $is_master_of{$self} = $master; + } + + sub is_running_ok { + my ($self) = @_; + + my $user_agent = LWP::UserAgent->new; + $user_agent->timeout(1); + + my $url = 'http://' . get_address($self) . ':' . get_port($self); + my $response = $user_agent->head($url); + return $response->is_success; + } + + sub is_running { + my ($self) = @_; + + my $user_agent = LWP::UserAgent->new; + $user_agent->timeout(1); + + my $url = 'http://' . get_address($self) . ':' . get_port($self); + my $response = $user_agent->head($url); + return $response->code != 500; + } + + + sub is_management_running { + my ($self) = @_; + + my $management = get_management($self); + if ($management) { + my $ping = $management->ping(); + return defined($ping) && $ping; + } + else { + return 0; + } + } +} + +1; Added: trunk/varnish-tools/webgui/Varnish/NodeManager.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/NodeManager.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/NodeManager.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,221 @@ +package Varnish::NodeManager; +use strict; +use warnings; +use Varnish::Node; +use List::Util qw(first); + +{ + my @groups = (); + my @nodes = (); + my %group_parameters = (); + + my $error = ""; + + sub add_node { + my ($self, $node) = @_; + + my $group = $node->get_group(); + if (! grep { $_->get_group eq $group } @nodes ) { + $node->set_master(1); + my %node_parameters = %{$node->get_management()->get_parameters()}; + while (my ($parameter, $value) = each %node_parameters) { + $group_parameters{$group}->{$parameter} = $value; + } + } + else { +# inherit the VCL and the parameters of the group + my %group_parameters = %{$group_parameters{$group}}; + my $management = $node->get_management(); + while (my ($parameter, $value) = each %group_parameters) { + $management->set_parameter($parameter, $value->{'value'}); + } + + my $vcl_names_ref = $management->get_vcl_names(); + my $active_vcl_name; + my @vcl_names; + if ($vcl_names_ref) { + @vcl_names = @{$vcl_names_ref}; + $active_vcl_name = shift @vcl_names; + } + + for my $vcl_name (@vcl_names) { + if ($vcl_name ne $active_vcl_name) { + $management->discard_vcl($vcl_name); + } + } + + my $discard_active_vcl = 1; + my $group_master = first { + $_->get_group() eq $group + && $_->is_master() + } @nodes; + my $master_management = $group_master->get_management(); + my $master_active_vcl_name; + my @master_vcl_names; + my $master_vcl_names_ref = $group_master->get_management()->get_vcl_names(); + if ($master_vcl_names_ref) { + @master_vcl_names = @{$master_vcl_names_ref}; + $master_active_vcl_name = shift @master_vcl_names; + } + + for my $vcl_name (@master_vcl_names) { + my $vcl = $master_management->get_vcl($vcl_name); + $management->set_vcl($vcl_name, $vcl); + + if ($vcl_name eq $master_active_vcl_name) { + $management->make_vcl_active($vcl_name); + } + if ($vcl_name eq $active_vcl_name) { + $discard_active_vcl = 0; + } + } + + if ($discard_active_vcl) { + $management->discard_vcl($active_vcl_name); + } + } + + push @nodes, $node; + } + + sub remove_node { + my ($self, $node) = @_; + + if ($node) { + @nodes = grep { $_ != $node } @nodes; + + if ($node->is_master()) { + my $new_master = first { + $_->is_master + && $_->get_group() eq $node->get_group() + } @nodes; + if ($new_master) { + $new_master->set_master(1); + } + } + } + } + + sub get_node { + my ($self, $node_id) = @_; + + my $node = first { + $_->get_id() == $node_id + } @nodes; + + return $node; + } + + sub add_group { + my ($self, $name) = @_; + + push @groups, $name; + } + + sub remove_group { + my ($self, $name) = @_; + + @groups = grep { $_ ne $name } @groups; + my @nodes_to_remove = grep { $_->get_group() eq $name } @nodes; + for my $node (@nodes_to_remove) { + remove_node($self, $node); + } + } + + sub get_groups { + + return @groups; + } + + sub get_nodes { + + return @nodes; + } + + sub get_nodes_for_group { + my ($self, $group) = @_; + + return grep { $_->get_group() eq $group } @nodes; + } + + sub get_group_masters { + my ($self) = @_; + + return grep { $_->is_master() } @nodes; + } + + sub load { + + + } + + sub save { + my ($self) = @_; + + } + + sub quit { + my ($self) = @_; + + for my $node (@nodes) { + my $management = $node->get_management(); + if ($management) { + $management->close(); + } + } + + save($self); + } + + sub set_error { + my ($self, $new_error) = @_; + + $error = $new_error; + + return; + } + + sub get_error { + my ($self) = @_; + + return $error; + } + + sub no_error { + my ($self, $return_value) = @_; + + $error = ""; + + return defined($return_value) ? $return_value : 1; + } + + sub set_group_parameter { + my ($self, $group, $parameter, $value) = @_; + + my $error; + + $group_parameters{$group}->{$parameter}->{'value'} = $value; + my @nodes_in_group = grep { $_->get_group() eq $group } @nodes; + for my $node (@nodes_in_group) { + my $management = $node->get_management(); + if (!$management->set_parameter($parameter, $value)) { + $error .= $management->get_error() . "\n"; + } + } + + if ($error) { + return set_error($self, $error); + } + else { + return no_error(); + } + } + + sub get_group_parameters { + my ($self, $group) = @_; + + return $group_parameters{$group}; + } +} + +1; Added: trunk/varnish-tools/webgui/Varnish/RequestHandler.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/RequestHandler.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/RequestHandler.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,1005 @@ +package Varnish::RequestHandler; + +use strict; +use warnings; +use HTML::Template; +use HTTP::Request; +use Varnish::Util; +use Varnish::Management; +use Varnish::NodeManager; +use Varnish::Node; +use Varnish::Statistics; +use URI::Escape; +use GD::Graph::lines; +use POSIX qw(strftime); +use List::Util qw(first); + +{ + my %request_ref_of; + my %response_content_ref_of; + my %response_header_ref_of; + my %master_tmpl_var_of; + + sub new { + my ($class, $request_ref, $connection) = @_; + + my $new_object = bless \do{ my $anon_scalar; }, $class; + + $request_ref_of{$new_object} = $request_ref; + $response_content_ref_of{$new_object} = \""; + $response_header_ref_of{$new_object} = {}; + + $master_tmpl_var_of{$new_object}->{'server_host'} = $connection->sockhost(); + $master_tmpl_var_of{$new_object}->{'server_port'} = $connection->sockport(); + + return $new_object; + } + + sub DESTROY { + my ($self) = @_; + + delete $request_ref_of{$self}; + + return; + } + + sub get_response_header { + my ($self) = @_; + + return $response_header_ref_of{$self}; + } + sub get_response_content { + my ($self) = @_; + + return ${$response_content_ref_of{$self}}; + } + + sub _parse_request_parameters { + my ($content_ref) = @_; + + my %parameter = (); + for my $pair (split /&/,$$content_ref) { + my ($key,$value) = split /=/,$pair; + $value = uri_unescape($value); + $value =~ s/\+/ /g; + $parameter{$key} = $value; + } + + return %parameter; + } + + sub process { + my ($self) = @_; + + my $request = ${$request_ref_of{$self}}; + my $operation = $request->uri(); + my $content = $request->content(); + + $operation =~ s:^/::; + if ($operation =~ /^(.*?)\?(.*)/) { + $operation = $1; + $content = $2; + } + + my $content_template; + my $response_content; + my %request_parameter = _parse_request_parameters(\$content); + +# while (my ($k, $v) = each %request_parameter) { +# print "$k => $v\n"; +# } + + my $param; + if ($operation eq 'view_stats' || $operation eq '') { + ($content_template, $param) = view_stats(\%request_parameter); + } + elsif ($operation eq 'configure_parameters') { + ($content_template, $param) = configure_parameters(\%request_parameter); + } + elsif ($operation eq 'edit_vcl') { + ($content_template, $param) = edit_vcl(\%request_parameter); + } + elsif ($operation eq 'node_management') { + ($content_template, $param) = node_management(\%request_parameter); + } + elsif ($operation eq 'management_console') { + ($content_template, $param) = management_console(\%request_parameter); + } + elsif ($operation eq 'send_management_command') { + $response_content = send_management_command(\%request_parameter); + } + elsif ($operation eq 'generate_graph') { + $response_header_ref_of{$self}->{'Content-Type'} = "image/png"; + $response_content = generate_graph(\%request_parameter); + if (!$response_content) { + $response_content = read_file('images/nograph.png'); + } + } + elsif ($operation eq 'collect_data') { + Varnish::Statistics->collect_data(); + $response_content = "Ok"; + } + else { + return; + } + + if ($content_template) { + my $template_text = read_file("templates/master.tmpl"); + $template_text =~ s/CONTENT_TEMPLATE/$content_template/; + + my $template = HTML::Template->new_scalar_ref( \$template_text, + die_on_bad_params => 0); + + my $tmpl_var = $master_tmpl_var_of{$self}; + if ($param) { + while (my ($parameter, $value) = each %{$param}) { + $tmpl_var->{$parameter} = $value; + } + } + $template->param($tmpl_var); + $response_content = $template->output; + } + $response_content_ref_of{$self} = \$response_content; + } + + sub edit_vcl { + my ($parameter_ref) = @_; + + my %param = %{$parameter_ref}; + $param{'vcl'} ||= ""; + $param{'operation'} ||= "load"; + $param{'group_name'} ||= ""; + $param{'vcl_name'} ||= ""; + $param{'new_vcl_name'} ||= ""; + + + my $template = "edit_vcl.tmpl"; + my %tmpl_var; + $tmpl_var{'error'} = ""; + $tmpl_var{'vcl_name'} = $param{'vcl_name'}; + $tmpl_var{'status'} = ""; + $tmpl_var{'vcl_infos'} = []; + $tmpl_var{'group_infos'} = []; + $tmpl_var{'vcl_error'} = ""; + $tmpl_var{'vcl'} = ""; + + my $successfull_save = 0; + my $editing_new_vcl = 0; + + my @group_masters = Varnish::NodeManager->get_group_masters(); + if ($param{'operation'} eq "make_active") { + my $group_master = first { + $_->get_group() eq $param{'group_name'}; + } @group_masters; + + if ($group_master) { + my $management = $group_master->get_management(); + if ($management->make_vcl_active($param{'vcl_name'})) { + my @nodes = Varnish::NodeManager->get_nodes(); + for my $node (@nodes) { + if ($node != $group_master && $node->get_group() eq $param{'group_name'}) { + $node->get_management()->make_vcl_active($param{'vcl_name'}); + } + } + $tmpl_var{'status'} = "VCL activated successfully"; + } + else { + $tmpl_var{'error'} .= "Error activating configuration:\n" . $management->get_error() . "\n"; + } + } + } + elsif ($param{'operation'} eq 'new') { + if ($param{'new_vcl_name'}) { + $tmpl_var{'vcl_name'} = $param{'new_vcl_name'}; + $tmpl_var{'vcl'} = ""; + push @{$tmpl_var{'vcl_infos'}}, { + name => $param{'new_vcl_name'}, + selected => 1, + active => 0 + }; + $editing_new_vcl = 1; + } + } + elsif ($param{'operation'} eq 'save') { + my $group_master = first { + $_->get_group() eq $param{'group_name'} + } @group_masters; + + if ($group_master && $param{'vcl'} ne "" && $param{'vcl_name'} ne "") { + my $master_management = $group_master->get_management(); + if ($master_management->set_vcl($param{'vcl_name'}, $param{'vcl'})) { + my @nodes = Varnish::NodeManager->get_nodes(); + for my $node (@nodes) { + if ($node != $group_master && $node->get_group() eq $param{'group_name'}) { + my $management = $node->get_management(); + if (!$management->set_vcl($param{'vcl_name'}, $param{'vcl'})) { + $tmpl_var{'error'} .= "Error saving configuration for " . $node->get_name() + . ":\n" . $management->get_error() . "\n"; + } + } + } + $successfull_save = 1; + $tmpl_var{'status'} = "VCL saved successfully"; + } + else { + push @{$tmpl_var{'vcl_infos'}}, { + name => $param{'vcl_name'}, + selected => 1, + active => 0 + }; + $editing_new_vcl = 1; + $tmpl_var{'vcl'} = $param{'vcl'}; + my $vcl_error = $master_management->get_error(); + # it is bad bad bad mixing presentation and code, I know, but sometimes you have to + $vcl_error =~ s/Line (\d+) Pos (\d+)/$&<\/a>/g; + $vcl_error =~ s/\n//g; + $tmpl_var{'vcl_error'} = $vcl_error; + } + } + } + elsif ($param{'operation'} eq "discard") { + my ($group_master) = grep { + $_->get_group() eq $param{'group_name'} + } @group_masters; + if ($group_master && $param{'vcl_name'} ne "") { + my $management = $group_master->get_management(); + if ($management->discard_vcl($param{'vcl_name'})) { + my @nodes = Varnish::NodeManager->get_nodes(); + for my $node (@nodes) { + if ($node != $group_master && $node->get_group() eq $param{'group_name'}) { + $node->get_management()->discard_vcl($param{'vcl_name'}); + } + } + + $tmpl_var{'vcl_name'} = ""; + $tmpl_var{'status'} = "VCL discarded successfully"; + } + else { + $tmpl_var{'error'} .= "Error discarding configuration:\n" . $management->get_error() . "\n"; + } + } + } + + my $selected_group_master; + for my $group_master (@group_masters) { + my %group_info = ( + name => $group_master->get_group(), + selected => 0, + ); + if ($param{'group_name'} eq $group_master->get_group()) { + $group_info{'selected'} = '1'; + $selected_group_master = $group_master; + } + push @{$tmpl_var{'group_infos'}}, \%group_info; + } + if (!$selected_group_master && @group_masters > 0) { + $selected_group_master = $group_masters[0]; + $tmpl_var{'group_infos'}->[0]->{'selected'} = 1; + } + + if ($selected_group_master) { + my $active_vcl_name; + my @vcl_names; + my $vcl_names_ref = $selected_group_master->get_management()->get_vcl_names(); + if ($vcl_names_ref) { + @vcl_names = @{$vcl_names_ref}; + $active_vcl_name = shift @vcl_names; + + for my $vcl_name (@vcl_names) { + my %vcl_info = ( + name => $vcl_name, + selected => 0, + active => 0, + ); + if ($vcl_name eq $tmpl_var{'vcl_name'}) { + $vcl_info{'selected'} = 1; + $tmpl_var{'vcl_name'} = $vcl_name; + } + if ($vcl_name eq $active_vcl_name) { + $vcl_info{'active'} = 1; + } + push @{$tmpl_var{'vcl_infos'}}, \%vcl_info; + } + if ($tmpl_var{'vcl_name'} eq "") { + FIND_ACTIVE_VCL: + for my $vcl_info (@{$tmpl_var{'vcl_infos'}}) { + if ($vcl_info->{'active'}) { + $tmpl_var{'vcl_name'} = $vcl_info->{'name'}; + $vcl_info->{'selected'} = 1; + last FIND_ACTIVE_VCL; + } + } + if ($tmpl_var{'vcl_name'} eq "") { + $tmpl_var{'vcl_name'} = $tmpl_var{'vcl_infos'}->[0]->{'name'}; + $tmpl_var{'vcl_infos'}->[0]->{'selected'} = 1; + } + } + + if (!(($param{'operation'} eq 'save' && !$successfull_save + || $param{'operation'} eq 'new'))) { + my $vcl = $selected_group_master->get_management()->get_vcl($tmpl_var{'vcl_name'}); + if ($vcl) { + $tmpl_var{'vcl'} = $vcl; + } + else { + $tmpl_var{'error'} .= "Error retrieving VCL: " . $selected_group_master->get_management()->get_error() . "\n"; + } + } + } + else { + $tmpl_var{'error'} .= "Error retrieving the VCLs: " . $selected_group_master->get_management()->get_error(); + } + } + + $tmpl_var{'editing_new_vcl'} = $editing_new_vcl; + $tmpl_var{'successfull_save'} = $successfull_save; + + return ($template, \%tmpl_var); + } + + + sub view_stats { + my ($parameter_ref) = @_; + + my $template = "view_stats.tmpl"; + + my %param = %{$parameter_ref}; + $param{'view_raw_stats'} ||= 0; + $param{'auto_refresh'} ||= 0; + + my %tmpl_var; + $tmpl_var{'error'} = ""; + $tmpl_var{'stat_time'} = 0; + $tmpl_var{'node_infos'} = []; + $tmpl_var{'summary_stats'} = []; + $tmpl_var{'raw_stats'} = []; + $tmpl_var{'auto_refresh'} = $param{'toggle_auto_refresh'} ? 1 - $param{'auto_refresh'} : $param{'auto_refresh'}; + $tmpl_var{'auto_refresh_interval'} = $tmpl_var{'auto_refresh'} ? get_config_value('poll_interval') : 0; + $tmpl_var{'view_raw_stats'} = $param{'view_raw_stats'}; + + my $error = ""; + + my ($stat_time, $stat_ref) = Varnish::Statistics->get_last_measure(); + my @nodes = Varnish::NodeManager->get_nodes(); + + if ($stat_time) { + $stat_time = strftime("%a %b %e %H:%M:%S %Y", localtime($stat_time)); + } + + my %summary_stat_list; + my %raw_stat_list; + for my $node (@nodes) { + push @{$tmpl_var{'node_infos'}}, { + name => $node->get_name(), + }; + + my $node_stat_ref = $stat_ref->{$node}; + my $node_id = $node->get_id(); + my $time_span = 'minute'; + + # example of adding graph the graph ID must match that of a predefind graph + # which is created in generate_graph found around line 826 + push @{$summary_stat_list{'Hit ratio'}}, { + is_graph => 1, + node_id => $node_id, + graph_id => 'cache_hit_ratio', + }; + push @{$summary_stat_list{'Connect requests'}}, { + is_graph => 1, + node_id => $node_id, + graph_id => 'connect_rate', + }; + + # example of missing graph_id + push @{$summary_stat_list{'Missing graph'}}, { + is_graph => 1, + node_id => $node_id, + graph_id => 'missing_graph', + }; + + # to add custom values, just add values by adding it to the list. The + # get_formatted_bytes() function is usefull for displaying byte values + # as it will convert to MB, GB etc as needed. + push @{$summary_stat_list{'% of requests served from cache'}}, { + value => get_formatted_percentage($$node_stat_ref{'Cache hits'} + , $$node_stat_ref{'Client requests received'}) + }; + + # these are examples of adding plain values from the raw stats + push @{$summary_stat_list{'Client connections accepted'}}, { + value => $$node_stat_ref{'Client connections accepted'} + }; + push @{$summary_stat_list{'Client requests received'}}, { + value => $$node_stat_ref{'Client requests received'} + }; + + my $total_bytes_served; + if ($$node_stat_ref{'Total header bytes'} + && $$node_stat_ref{'Total body bytes'}) { + $total_bytes_served = $$node_stat_ref{'Total header bytes'} + $$node_stat_ref{'Total header bytes'}; + } + push @{$summary_stat_list{'Total bytes served'}}, { + 'value' + => get_formatted_bytes($total_bytes_served) + }; + + if ($param{'view_raw_stats'}) { + while (my ($stat_name, $value) = each %{$node_stat_ref}) { + push @{$raw_stat_list{$stat_name}}, { + value => $value, + }; + } + } + } + + my $row = 1; + while (my ($stat_name, $values_ref) = each %raw_stat_list) { + push @{$tmpl_var{'raw_stats'}}, { + name => $stat_name, + values => $values_ref, + odd_row => $row++ % 2, + } + } + + $row = 1; + my $graph_row = 0; + while (my ($stat_name, $values_ref) = each %summary_stat_list) { + if ($values_ref->[0]->{'is_graph'}) { + unshift @{$tmpl_var{'summary_stats'}}, { + name => $stat_name, + values => $values_ref, + odd_row => $graph_row++ % 2, + } + } + else { + push @{$tmpl_var{'summary_stats'}}, { + name => $stat_name, + values => $values_ref, + odd_row => $row++ % 2, + } + } + } + + $tmpl_var{'error'} = $error; + $tmpl_var{'stat_time'} = $stat_time; + + return ($template, \%tmpl_var); + } + + sub configure_parameters { + my ($parameter_ref) = @_; + + my %param = %{$parameter_ref}; + $param{'node_id'} = $$parameter_ref{'node_id'} || ""; + $param{'group'} = $$parameter_ref{'group'} || ""; + + my $template = "configure_parameters.tmpl"; + my %tmpl_var; + $tmpl_var{'error'} = ""; + $tmpl_var{'status'} = ""; + $tmpl_var{'unit_infos'} = []; + $tmpl_var{'parameter_infos'} = []; + + my $unit_parameter_ref = {}; + my $error = ""; + + my %changed_parameters; + while (my ($parameter, $value) = each %$parameter_ref) { + if ($parameter =~ /^new_(.*?)$/ && + $$parameter_ref{"old_$1"} ne $value) { + $changed_parameters{$1} = $value; + } + } + + my @nodes = Varnish::NodeManager->get_nodes(); + my @groups = Varnish::NodeManager->get_groups(); + if (%changed_parameters) { + my $node = first { $_->get_id() eq $param{'node_id'} } @nodes; + if ($node) { + my $management = $node->get_management(); + while (my ($parameter, $value) = each %changed_parameters) { + if (!$management->set_parameter($parameter, $value)) { + $error .= "Could not set parameter $parameter: ". $node->get_management()->get_error() . "\n"; + } + } + } + else { + my $group = first { $_ eq $param{'group'} } @groups; + if ($group ne "") { + while (my ($parameter, $value) = each %changed_parameters) { + if (!Varnish::NodeManager->set_group_parameter($group, $parameter, $value)) { + $error .= "Could not set parameter $parameter for group $group: " + . Varnish::NodeManager->get_error() . "\n"; + } + } + } + } + if ($error eq "") { + my @changed_parameters = keys %changed_parameters; + my $status = "Parameter" . (@changed_parameters > 1 ? "s " : " "); + + $status .= shift @changed_parameters; + for my $parameter (@changed_parameters) { + $status .= ", $parameter"; + } + $status .= " configured successfully"; + $tmpl_var{'status'} = $status; + } + } + + for my $group (@groups) { + my %unit_info = ( + name => $group, + id => $group, + is_node => 0, + selected => 0, + ); + if ($group eq $param{'group'}) { + $unit_info{'selected'} = 1; + $unit_parameter_ref = Varnish::NodeManager->get_group_parameters($group); + if (!$unit_parameter_ref) { + $error .= "Could not get parameters for group $group. You need to have added a node to set these.\n"; + } + } + push @{$tmpl_var{'unit_infos'}}, \%unit_info; + } + + for my $node (@nodes) { + my %unit_info = ( + name => $node->get_name(), + id => $node->get_id(), + is_node => 1, + selected => 0, + ); + if ($node->get_id() eq $param{'node_id'}) { + $unit_info{'selected'} = 1; + $unit_parameter_ref = $node->get_management()->get_parameters(); + if (!$unit_parameter_ref) { + $error .= "Could not get parameters for node " . $node->get_name() . "\n"; + } + } + push @{$tmpl_var{'unit_infos'}}, \%unit_info; + } + + if ($param{'group'} eq "" && $param{'node_id'} eq "" + && @{$tmpl_var{'unit_infos'}} > 0) { + $tmpl_var{'unit_infos'}->[0]->{'selected'} = 1; + my $group = $tmpl_var{'unit_infos'}->[0]->{'name'}; + $unit_parameter_ref = Varnish::NodeManager->get_group_parameters($group); + if (!$unit_parameter_ref) { + $error .= "Could not get parameters for group $group\n"; + } + } + + my $row = 0; + while (my ($parameter, $info) = each %{$unit_parameter_ref} ) { + my $value = $info->{'value'}; + my $unit = $info->{'unit'}; + my $is_boolean = $unit eq "[bool]"; + if ($is_boolean) { + $value = $value eq "on"; + $unit = ''; + } + + push @{$tmpl_var{'parameter_infos'}}, { + name => $parameter, + value => $value, + unit => $unit, + description => $info->{'description'}, + is_boolean => $is_boolean, + odd_row => $row++ % 2, + }; + } + + $tmpl_var{'error'} = $error; + + return ($template, \%tmpl_var); + } + + + sub node_management { + my ($parameter_ref) = @_; + + my %param = %{$parameter_ref}; + $param{'node_id'} ||= ""; + $param{'group'} ||= ""; + $param{'operation'} ||= ""; + $param{'name'} ||= ""; + $param{'address'} = $$parameter_ref{'address'} || ""; + $param{'port'} ||= ""; + $param{'management_port'} ||= ""; + + my $template = "node_management.tmpl"; + my %tmpl_var = (); + $tmpl_var{'error'} = ""; + $tmpl_var{'status'} = ""; + $tmpl_var{'add_group'} = 0; + $tmpl_var{'group_infos'} = []; + $tmpl_var{'group'} = $param{'group'} || ""; + $tmpl_var{'node_infos'} = []; + $tmpl_var{'default_managment_port'} = 9001; + $tmpl_var{'backend_health_infos'} = []; + + my $error = ""; + my $status = ""; + + if ($param{'operation'} eq "add_group") { + if ($param{'group'}) { + Varnish::NodeManager->add_group($param{'group'}); + $status .= "Group " . $param{'group'} . " added successfully."; + } + else { + $tmpl_var{'add_group'} = 1; + } + } + elsif ($param{'operation'} eq "remove_group") { + if ($param{'group'}) { + Varnish::NodeManager->remove_group($param{'group'}); + $status = "Group " . $param{'group'} . " removed successfully"; + $tmpl_var{'group'} = ""; + } + } + elsif ($param{'operation'} eq "start_group") { + my $node_errors = ""; + for my $node (Varnish::NodeManager->get_nodes()) { + if ($node->get_group() eq $param{'group'} + && !$node->is_running()) { + my $management = $node->get_management(); + if (!$management->start()) { + $node_errors .= "Could not start " . $node->get_name() . ": " + . $management->get_error() . ". "; + } + } + } + + if ($node_errors eq "") { + $status .= "Group " . $param{'group'} . " started successfully."; + } + else { + $status .= "Group " . $param{'group'} . " started with errors: $node_errors."; + } + } + elsif ($param{'operation'} eq "stop_group") { + my $node_errors = ""; + for my $node (Varnish::NodeManager->get_nodes()) { + if ($node->get_group() eq $param{'group'} + && $node->is_running()) { + my $management = $node->get_management(); + if (!$management->stop()) { + $node_errors .= "Could not stop " . $node->get_name() . ": " + . $management->get_error() . ". "; + } + } + } + if ($node_errors eq "") { + $status .= "Group " . $param{'group'} . " stopped successfully."; + } + else { + $status .= "Group " . $param{'group'} . " stopped with errors: $node_errors."; + } + } + elsif ($param{'operation'} eq 'add_node') { + if ($param{'name'} && $param{'address'} && $param{'port'} + && $param{'group'} && $param{'management_port'}) { + my $node = Varnish::Node->new({ + name => $param{'name'}, + address => $param{'address'}, + port => $param{'port'}, + group => $param{'group'}, + management_port => $param{'management_port'} + }); + Varnish::NodeManager->add_node($node); + $status .= "Node " . $node->get_name() . " added successfully."; + } + else { + $error .= "Not enough information to add node:\n"; + $error .= "Name: " . $param{'name'} . ":\n"; + $error .= "Address: " . $param{'address'} . ":\n"; + $error .= "Port: " . $param{'port'} . ":\n"; + $error .= "Group: " . $param{'group'} . ":\n"; + $error .= "Management port: " . $param{'management_port'} . ":\n"; + } + } + elsif ($param{'operation'} eq "remove_node") { + if ($param{'node_id'}) { + my $node = Varnish::NodeManager->get_node($param{'node_id'}); + if ($node) { + $tmpl_var{'group'} = $node->get_group(); + Varnish::NodeManager->remove_node($node); + $status .= "Node " . $node->get_name() . " removed successfully."; + } + } + else { + $error .= "Could not remove node: Missing node ID\n"; + } + } + elsif ($param{'operation'} eq "start_node") { + if ($param{'node_id'}) { + my $node = Varnish::NodeManager->get_node($param{'node_id'}); + if ($node) { + my $management = $node->get_management(); + if ($node->is_running()) { + $status .= "Node " . $node->get_name() . " already running."; + } + elsif ($management->start() ) { + $status .= "Node " . $node->get_name() . " started successfully."; + } + else { + $error .= "Could not start " . $node->get_name() + . ": " . $management->get_error() . "\n"; + } + $tmpl_var{'group'} = $node->get_group(); + } + } + else { + $error .= "Could not start node: Missing node ID\n"; + } + } + elsif ($param{'operation'} eq "stop_node") { + if ($param{'node_id'}) { + my $node = Varnish::NodeManager->get_node($param{'node_id'}); + if ($node) { + my $management = $node->get_management(); + if (!$node->is_running()) { + $status .= "Node " . $node->get_name() . " already stopped."; + } + elsif ($management->stop()) { + $status .= "Node " . $node->get_name() . " stopped successfully."; + } + else { + $error .= "Could not stop " . $node->get_name() + . ": " . $management->get_error() . "\n"; + } + } + $tmpl_var{'group'} = $node->get_group(); + } + else { + $error .= "Could not stop node: Missing node ID\n"; + } + } + + # Populate the node table + my @groups = Varnish::NodeManager->get_groups(); + if (@groups) { + if (!$tmpl_var{'group'} && !$tmpl_var{'add_group'}) { + $tmpl_var{'group'} = $groups[0]; + } + my @group_infos = map { + { + name => $_, + selected => $_ eq $tmpl_var{'group'}, + } + } @groups; + $tmpl_var{'group_infos'} = \@group_infos; + + my @nodes = Varnish::NodeManager->get_nodes(); + for my $node (@nodes) { + next if ($node->get_group() ne $tmpl_var{'group'}); + + push @{$tmpl_var{'node_infos'}}, { + id => $node->get_id(), + is_running_ok => $node->is_running_ok(), + is_running => $node->is_running(), + is_management_running => $node->is_management_running(), + name => $node->get_name(), + address => $node->get_address(), + port => $node->get_port(), + management_port => $node->get_management_port(), + group => $node->get_group(), + }; + + if (@{$tmpl_var{'backend_health_infos'}} == 0) { + my $backend_health = $node->get_management()->get_backend_health(); + if ($backend_health) { + while (my ($backend, $health) = each %{$backend_health}) { + push @{$tmpl_var{'backend_health_infos'}}, { + name => $backend, + health => $health, + }; + } + } + } + } + } + else { + $tmpl_var{'add_group'} = 1; + } + + $tmpl_var{'error'} = $error; + $tmpl_var{'status'} = $status; + + return ($template, \%tmpl_var); + } + +sub generate_graph { + my ($parameter_ref) = @_; + + my %param = %{$parameter_ref}; + $param{'width'} ||= 250; + $param{'height'} ||= 150; + $param{'time_span'} ||= "minute"; + $param{'type'} ||= ""; + $param{'node_id'} ||= 0; + + my $interval = get_config_value('poll_interval'); + + # this hash holds available graphs which can be added to the summary stats in the view_stats + # function. + my %graph_info = ( + # the name of the graph + cache_hit_ratio => { + # the parameters to GD::Graph. y_number_format should be noted, as it let you format + # the presentation, like multiplying with 100 to get the percentage as shown here + graph_parameter => { + y_label => '%', + title => "Cache hit ratio last " . $param{'time_span'}, + y_max_value => 1, + y_min_value => 0, + y_number_format => sub { return $_[0] * 100 } + }, + # the divisors and dividends are lists of names of the statistics to + # use when calculating the values in the graph. The names can be obtained + # by turning 'Raw statistics' on in the GUI. The value in the graph is calculated + # by taking the sum of divisors and divide witht the sum of the dividends, i.e. + # value = (divisor1 + divisor2 + divisor3 ...) / (dividend1 + dividend 2 +..) + # if divisor or dividend is emitted, the value of 1 is used instead + divisors => [ 'Cache hits' ], + dividends => [ 'Cache hits', 'Cache misses' ], + }, + connect_rate => { + graph_parameter => { + y_label => 'Reqs', + title => "Reqs / $interval s last " . $param{'time_span'}, + y_min_value => 0, + }, + # here we have no dividends as we only want to plot 'Client requests received' + divisors => [ 'Client requests received' ], + # if use_delta is set to 1, the derived value is used, i.e. the difference + # in value between two measurements. This is usefull for graphs showing rates + # like this connect rate + use_delta => 1, + }, + ); + my %time_span_graph_parameters = ( + minute => { + x_label => 'Time', + x_tick_number => 6, # need to be set to make x_number_format work + x_number_format => sub { return strftime(":%S", localtime($_[0])); }, + x_max_value => time + }, + hour => { + x_label => 'Time', + x_tick_number => 6, # need to be set to make x_number_format work + x_number_format => sub { return strftime("%H:%M", localtime($_[0])); }, + }, + day => { + x_label => 'Time', + x_tick_number => 4, # need to be set to make x_number_format work + x_number_format => sub { return strftime("%H", localtime($_[0])); }, + }, + week => { + x_label => 'Time', + x_tick_number => 7, # need to be set to make x_number_format work + x_number_format => sub { return strftime("%d", localtime($_[0])); }, + }, + month => { + x_label => 'Time', + x_tick_number => 4, # need to be set to make x_number_format work + x_number_format => sub { return strftime("%d.%m", localtime($_[0])); }, + }, + ); + + + if ( !$graph_info{$param{'type'}} + || !$time_span_graph_parameters{$param{'time_span'}}) { + #print "Error: Missing data"; + return; + } + my $data_ref = Varnish::Statistics->generate_graph_data( + $param{'node_id'}, + $param{'time_span'}, + $graph_info{$param{'type'}}->{'divisors'}, + $graph_info{$param{'type'}}->{'dividends'}, + $graph_info{$param{'type'}}->{'use_delta'} + ); + if (!$data_ref) { + #print "Error generating graph data\n"; + return; + } + my $graph = GD::Graph::lines->new($param{'width'}, $param{'height'}); + $graph->set((%{$graph_info{$param{'type'}}->{'graph_parameter'}}, + %{$time_span_graph_parameters{$param{'time_span'}}}), + dclrs => ["#990200"]); + + my $graph_image = $graph->plot($data_ref); + + if (!$graph_image) { + return; + } + + return $graph_image->png; + } + + sub management_console { + my ($parameter_ref) = @_; + + my %param = %{$parameter_ref}; + $param{'node_id'} = $$parameter_ref{'node_id'} || 0; + + my $template = "management_console.tmpl"; + my %tmpl_var; + $tmpl_var{'error'} = ""; + $tmpl_var{'unit_infos'} = []; + $tmpl_var{'parameter_infos'} = []; + $tmpl_var{'default_console_font_size'} = '1.1em', + $tmpl_var{'default_console_cols'} = 80, + $tmpl_var{'default_console_rows'} = 30, + + my @nodes = Varnish::NodeManager->get_nodes(); + if (@nodes) { + my $node_id = $param{'node_id'} ? $param{'node_id'} : $nodes[0]->get_id(); + for my $node (@nodes) { + my $selected = $node->get_id() == $node_id; + push @{$tmpl_var{'node_infos'}}, { + id => $node->get_id(), + name => $node->get_name(), + selected => $selected, + }; + + if ($selected) { + $tmpl_var{'current_node_name'} = $node->get_name(); + } + } + } + + $tmpl_var{'console_themes'} = [ + { + name => 'Grey on black', + foreground => '#bbb', + background => 'black', + }, + { + name => 'Black on white', + foreground => 'black', + background => 'white', + }, + { + name => 'Retro', + foreground => 'green', + background => 'black', + } + ]; + $tmpl_var{'default_console_foreground'} = $tmpl_var{'console_themes'}->[0]->{'foreground'}, + $tmpl_var{'default_console_background'} = $tmpl_var{'console_themes'}->[0]->{'background'}, + + return ($template, \%tmpl_var); + } + + sub send_management_command { + my ($parameter_ref) = @_; + + my $node_id = $$parameter_ref{'node_id'}; + my $command = $$parameter_ref{'command'}; + + if ($node_id && $command) { + my $node = Varnish::NodeManager->get_node($node_id); + return "Error: Node not found." if (!$node); + + my $management = $node->get_management(); + my $response = $management->send_command($command); + if ($response) { + return $response; + } + else { + return "Error: " . $management->get_error(); + } + } + else { + return "Error: Not valid input"; + } + } + +} + + +1; Added: trunk/varnish-tools/webgui/Varnish/Statistics.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/Statistics.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/Statistics.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,132 @@ +package Varnish::Statistics; + +use strict; +use POSIX qw(strftime); +use List::Util qw(first); + +use Varnish::Util; +use Varnish::NodeManager; + +{ + my %data; + my $last_measure_ref; + my $last_measure_time; + + sub collect_data { + my $time_stamp = time(); + my %measure; + my $good_stat_ref; + my @nodes = Varnish::NodeManager->get_nodes(); + + my @bad_nodes; + for my $node (@nodes) { + my $management = $node->get_management(); + my $stat_ref; + if ($management) { + $stat_ref = $management->get_stats(); + } + if ($stat_ref) { + $measure{$node} = $stat_ref; + if (!$good_stat_ref) { + $good_stat_ref = $stat_ref; + } + } + else { + push @bad_nodes, $node; + } + } + + if (@bad_nodes && $good_stat_ref) { + for my $bad_node (@bad_nodes) { + $measure{$bad_node}->{'missing data'} = 1; + for my $key (keys %$good_stat_ref) { + $measure{$bad_node}->{$key} = -1; + } + } + } + + $data{$time_stamp} = \%measure; + $last_measure_ref = \%measure; + $last_measure_time = $time_stamp; + } + + + sub get_last_measure { + + return ($last_measure_time, $last_measure_ref); + } + + sub generate_graph_data { + my ($self, $node_id, $time_span, $divisors_ref, $dividends_ref, $use_delta) = @_; + + my %seconds_for = ( + minute => 60, + hour => 3600, + day => 86400, + week => 604800, + month => 18144000, # 30 days + ); + my $start_time = time() - $seconds_for{$time_span}; + if ($use_delta) { + $start_time -= get_config_value('poll_interval'); + } + my $node = first { + $_->get_id() == $node_id + } Varnish::NodeManager->get_nodes(); + + my @measures = grep { + $_ > $start_time + } (sort keys %data); + my @values; + my $last_value; + GENERATE_DATA: + for my $measure (@measures) { + my $value; + if (!$data{$measure}->{$node}->{'missing data'}) { + my $divisor_value = 0; + my $dividend_value = 0; + + if ($divisors_ref && @$divisors_ref) { + for my $divisor (@$divisors_ref) { + $divisor_value += $data{$measure}->{$node}->{$divisor}; + } + } + else { + $divisor_value = 1; + } + if ($dividends_ref && @$dividends_ref) { + for my $dividend (@$dividends_ref) { + $dividend_value += $data{$measure}->{$node}->{$dividend}; + } + } + else { + $dividend_value = 1; + } + if ($dividend_value) { + $value = $divisor_value / $dividend_value; + } + + if ($use_delta) { + if (!$last_value) { + $last_value = $value; + next GENERATE_DATA; + } + my $delta_value = $value - $last_value; + $last_value = $value; + # if the value is negative, then we have had restart and don't plot it. + if ($delta_value < 0) { + $value = undef; + } + else { + $value = $delta_value; + } + } + } + push @values, $value; + } + + return [ \@measures, \@values ]; + } +} + +1; Added: trunk/varnish-tools/webgui/Varnish/Util.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/Util.pm (rev 0) +++ trunk/varnish-tools/webgui/Varnish/Util.pm 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,68 @@ +package Varnish::Util; + +use strict; +use Exporter; +use base qw(Exporter); + +our @EXPORT = qw( + set_config + get_config_value + read_file + get_formatted_percentage + get_formatted_bytes + ); + +{ + my %config; + + sub set_config { + my ($config_ref) = @_; + + %config = %{$config_ref}; + } + + sub get_config_value { + my ($key) = @_; + + return $config{$key}; + } + + sub read_file($) { + my ($filename) = @_; + + open(my $fh, "<$filename" ); + my $content = do { local($/); <$fh> }; + close($fh); + + return $content; + } + + sub get_formatted_percentage { + my ($divisor, $dividend) = @_; + + return $dividend > 0 ? sprintf( "%.2f", 100 * ($divisor / $dividend)) : "inf"; + } + + # thanks to foxdie at #varnish for php snippet + sub get_formatted_bytes { + my ($bytes) = @_; + + if ($bytes > 1099511627776) { + return sprintf( "%.3f TB", $bytes / 1099511627776); + } + elsif ($bytes > 1073741824) { + return sprintf( "%.3f GB", $bytes / 1073741824); + } + elsif ($bytes > 1048576) { + return sprintf( "%.3f MB", $bytes / 1048576); + } + elsif ($bytes > 1024) { + return sprintf( "%.3f KB", $bytes / 1024); + } + else { + return $bytes . " B"; + } + } +} + +1; Added: trunk/varnish-tools/webgui/css/web.css =================================================================== --- trunk/varnish-tools/webgui/css/web.css (rev 0) +++ trunk/varnish-tools/webgui/css/web.css 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,189 @@ +* { + padding: 0px; + margin: 0px; +} + +a { + color: black; +} + +body { + background-color: #d7d7d7; + padding: 10px; +} + +#header { + background-color: #990200; + border-style: solid; + padding-bottom: 3px; + border-width: 0px 0px 2px 0px; +} + +img#headerLogo { + background-color: #d7d7d7; +} + +#menu { + padding: 5px 3px 5px 3px; + text-align: center; +} + +a.menu { + color: #fff; + padding-right: 20px; +} + +#error { + font-size: 1.1em; + padding: 5px; + border-width: 3px; + border-style: solid; + border-color: #6c0000; + background-color: #a21616; + margin-bottom: 10px; +} + +#content { + background-color: #f2f2f2; + padding: 10px; +} + +td.header { + font-weight: bold; + border-style: solid; + border-width: 0px 0px 1px 0px; +} + +td.footer { + font-size: 0.7em; + padding-top: 10px; + border-style: solid; + border-width: 1px 0px 0px 0px; +} + + +table#parameters { + padding: 2px; +} + +td.parameterLabel { + padding: 0px 5px 0px 5px; +} + +td.parameterValue { + padding: 0px 5px 0px 5px; + text-align: right; +} + +td.parameterUnit { + font-style: italic; + padding: 0px 5px 0px 5px; +} + +td.parameterDescription { + padding: 0px 5px 0px 5px; +} + +td.parameterEdit { + padding: 0px 5px 0px 5px; + text-align: center; +} + +tr.evenRow { + background-color:#fff; + vertical-align: top; +} + +tr.oddRow { + background-color:#eee; + vertical-align: top; +} + +textarea#vclEditor { + margin: 5px 0px 10px 0px; +} + +span.tab { + padding: 0px 10px 0px 10px; + width: 10em; + background-color: #ddd; + border-style: solid; + border-width: 1px 1px 1px 1px; +} + +span.selectedTab { + padding: 1px 10px 1px 10px; + border-style: solid; + background-color: #fff; + border-width: 1px 1px 0px 1px; +} + +span.space { + border-style: solid; + border-width: 0 0 1px 0; +} + +div.tabArea { + background-color: #fff; + padding: 5px; + border-style: solid; + border-width: 0px 1px 1px 1px; +} + +table#statsTable { + background-color: #fff; + border-style: solid; + border-width: 1px; +} + +option { + padding-right: 10px; +} + +#groupControls { + padding-top: 30px; +} + +td { + padding: 1px 2px 1px 2px; +} + +textarea#vclConfig { + font-size: 1.1em; + border-style: solid; + border-width: 2px; + border-color: #990200; + padding: 2px 0 0 5px; +} + +#themeSelection { + padding: 3px; +} + +li.consoleSetting { + margin-left: 30px; + margin-top: 10px; +} + +input.removeNode { + margin-left: 50px; +} + +#status { + border-color: #2e6c00; + border-style: solid; + border-width: 3px; + background-color: #419a00; + padding: 5px; + margin-bottom: 10px; +} + +#vclError { + font-family: monospace; + font-size: 1.1em; + border-color: black; + border-style: solid; + border-width: 3px; + background-color: red; + padding: 5px; +} Added: trunk/varnish-tools/webgui/images/favicon.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/favicon.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/nograph.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/nograph.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/running.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/running.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/running_nok.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/running_nok.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/stopped.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/stopped.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/varnish-logo-christmas.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/varnish-logo-christmas.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/images/varnish-logo.png =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/images/varnish-logo.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/start.pl =================================================================== --- trunk/varnish-tools/webgui/start.pl (rev 0) +++ trunk/varnish-tools/webgui/start.pl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,138 @@ +#!/usr/bin/perl +use threads; +use strict; +use warnings; +use HTTP::Daemon; +use HTTP::Status; +use HTTP::Request; +use LWP::UserAgent; +use Varnish::Util; +use Varnish::RequestHandler; +use Varnish::NodeManager; +use Varnish::Node; +use Varnish::Statistics; + + +# Configuration starts here +my %config = ( +# 'address' is the IP to bind to. If not set, it listens on all. +# address => localhost, + +# 'port' is the port of the web server + port => 8000, + +# 'poll_intervall' is the polling interval for the statistics + poll_interval => 5, +); + +# create some default groups +my @groups = qw(default images); + +# create some default nodes +my @node_params = ( + { + name => 'varnish-1', + address => 'localhost', + port => '80', + group => 'default', + management_port => 9001, + }, + { + name => 'varnish-2', + address => 'localhost', + port => '8181', + group => 'default', + management_port => 9002, + }, + { + name => 'varnish-1', + address => 'localhost', + port => '8888', + group => 'images', + management_port => 9003, + }, +); + +# End of configuration + +set_config(\%config); + +for my $group (@groups) { + Varnish::NodeManager->add_group($group); +} + +for my $node_param_ref (@node_params) { + my $group_exists = grep { + $_ eq $node_param_ref->{'group'} + } @groups; + if ($group_exists) { + my $node = Varnish::Node->new($node_param_ref); + Varnish::NodeManager->add_node($node); + } + else { + print "Node " . $node_param_ref->{'name'} . " has an invalid group " + . $node_param_ref->{'group'} . ". Skipping."; + } +} + +# catch interupt to stop the daemon +$SIG{'INT'} = sub { + print "Interrupt detected.\n"; +}; + +# ignore the occational sigpipe +$SIG{'PIPE'} = sub { +# print "Pipe ignored\n"; +}; + +my $daemon = HTTP::Daemon->new( LocalPort => $config{'port'}, + LocalAddr => $config{'address'}, + ReuseAddr => 1 ) || die "Could not start web server"; +print "Web server started with URL: " . $daemon->url, "\n"; +my $data_collector_handle = threads->create('data_collector_thread'); +while (my $connection = $daemon->accept) { + REQUEST: + while (my $request = $connection->get_request) { + $connection->force_last_request; + if ($request->uri =~ m{/(.*?\.png)} || + $request->uri =~ m{/(.*?\.css)} || + $request->uri =~ m{/(.*?\.ico)}) { + my $filename = $1; + + $connection->send_file($filename); + next REQUEST; + } + + my $request_handler = Varnish::RequestHandler->new(\$request, $connection); + $request_handler->process(); + + my $response = HTTP::Response->new(200); + $response->header( $request_handler->get_response_header() ); + $response->content( $request_handler->get_response_content() ); + $connection->send_response($response); + } + $connection->close(); + undef($connection); +} +print "Shutting down!\n"; +$daemon->close(); +Varnish::NodeManager->quit(); +print "Stopping data collector thread\n"; +$data_collector_handle->join(); + +sub data_collector_thread { + my $url = $daemon->url . "collect_data"; + my $interval = $config{'poll_interval'}; + print "Data collector thread started. Polling URL $url at $interval seconds interval\n"; + + sleep 1; # wait for the server to come up + while (1) { + my $user_agent = LWP::UserAgent->new; + $user_agent->timeout(6); + my $response = $user_agent->get($url); + + last if ($response->code eq "500"); + sleep $interval; + } + print "Data collector thread stopped.\n"; +} Property changes on: trunk/varnish-tools/webgui/start.pl ___________________________________________________________________ Name: svn:executable + * Added: trunk/varnish-tools/webgui/templates/.master.tmpl.swp =================================================================== (Binary files differ) Property changes on: trunk/varnish-tools/webgui/templates/.master.tmpl.swp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/varnish-tools/webgui/templates/configure_parameters.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/configure_parameters.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/configure_parameters.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,89 @@ + + + +
+ +
+ + + + + + + + + + + + + + + + +
NameValueUnit
+ + + + + + + + + + + + + + + + + +? + +
+
+ +No nodes available + Added: trunk/varnish-tools/webgui/templates/edit_vcl.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/edit_vcl.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/edit_vcl.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,182 @@ + + +
+
+ + + + + + + + + +
+
+ +
+ + + + + + + +
+ + +| + + + + + + + + + + + + + + + +| +
+
+ + + + +Errors found in the VCL: +
+ +
+
+
+ +No groups available +
Added: trunk/varnish-tools/webgui/templates/management_console.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/management_console.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/management_console.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,248 @@ + + + +
+ + + + + + + + + +
+
+
+> +
+Console settings: +
    +
  • +Color theme: + + + + + +
  • +
  • Size: + x + +
  • +
+ + +No nodes to manage. +
Added: trunk/varnish-tools/webgui/templates/master.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/master.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/master.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,43 @@ + + + + + + + + + +Varnish - Lust controller christmas edition + + +
+ +
+ +
+An error occured:
+
+
+
+
+
+ +
+ +
+
+ +
+
+ + Added: trunk/varnish-tools/webgui/templates/node_management.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/node_management.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/node_management.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,138 @@ +
+ + + + + + + + + + + + + + +Add.. + +
+
+ +
+ + + + +
Name:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VMNameAddressPortManagement port
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + +
+
+ +
+ + + + + + +
BackendHealth
+ +No backend health information available +
+
+ + + + + + +
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ +
Added: trunk/varnish-tools/webgui/templates/view_stats.tmpl =================================================================== --- trunk/varnish-tools/webgui/templates/view_stats.tmpl (rev 0) +++ trunk/varnish-tools/webgui/templates/view_stats.tmpl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,99 @@ + + + +

+ +Statistics collected at + +(auto-refreshing) + + +No statistics yet collected + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Summary

+
+ + +
+ +
+
+Last: +Mi +H +D +W +Mo +
+ + + +
+

Raw statistics

+
+ + +
+Raw statistics: On Off + + +Raw statistics: On Off +
+| Auto refresh: + +On Off + +On Off + + +No nodes available + Added: trunk/varnish-tools/webgui/test/test_management.pl =================================================================== --- trunk/varnish-tools/webgui/test/test_management.pl (rev 0) +++ trunk/varnish-tools/webgui/test/test_management.pl 2008-12-12 10:10:05 UTC (rev 3461) @@ -0,0 +1,41 @@ +use strict; +use warnings; +use Varnish::Management; + +my $console = Varnish::Management->new("localhost", "9001"); + +my $status = $console->set_config("testing", "backend b0 { .host = \"localhost\"; .port = \"8080\"; }"); + +if ($status ne "") { + print "Error:\n$status\n"; +} + +for my $config ($console->get_config_names()) { + print "Config: $config\n"; + print "-" x 80 . "\n"; + print $console->get_config($config) . "\n"; +} + + +my %stats_counter = $console->get_stats(); +while (my ($stat, $value) = each %stats_counter) { + print "$stat = $value\n"; +} + +if ($console->ping()) { + print "I am alive!\n"; +} +else { + print "I am dead: " . $console->get_error() . "\n"; +} + +my $console2 = Varnish::Management->new("localhost", "9002"); + + +if ($console2->ping()) { + print "I am alive!\n"; +} +else { + print "I am dead: " . $console2->get_error() . "\n"; +} + From petter at projects.linpro.no Fri Dec 12 11:47:32 2008 From: petter at projects.linpro.no (petter at projects.linpro.no) Date: Fri, 12 Dec 2008 12:47:32 +0100 (CET) Subject: r3462 - trunk/varnish-tools/webgui/Varnish Message-ID: <20081212114732.C0E641EC4A8@projects.linpro.no> Author: petter Date: 2008-12-12 12:47:32 +0100 (Fri, 12 Dec 2008) New Revision: 3462 Modified: trunk/varnish-tools/webgui/Varnish/RequestHandler.pm Log: Fixed so that server_host is the hostname and not IP, as javscript will fail if the URL doesn't match. Modified: trunk/varnish-tools/webgui/Varnish/RequestHandler.pm =================================================================== --- trunk/varnish-tools/webgui/Varnish/RequestHandler.pm 2008-12-12 10:10:05 UTC (rev 3461) +++ trunk/varnish-tools/webgui/Varnish/RequestHandler.pm 2008-12-12 11:47:32 UTC (rev 3462) @@ -13,6 +13,7 @@ use GD::Graph::lines; use POSIX qw(strftime); use List::Util qw(first); +use Socket; { my %request_ref_of; @@ -29,7 +30,9 @@ $response_content_ref_of{$new_object} = \""; $response_header_ref_of{$new_object} = {}; - $master_tmpl_var_of{$new_object}->{'server_host'} = $connection->sockhost(); + my $server_ip = $connection->sockhost(); + my $server_hostname = gethostbyaddr(inet_aton($server_ip), AF_INET); + $master_tmpl_var_of{$new_object}->{'server_host'} = $server_hostname; $master_tmpl_var_of{$new_object}->{'server_port'} = $connection->sockport(); return $new_object; From ingvar at projects.linpro.no Thu Dec 18 09:47:06 2008 From: ingvar at projects.linpro.no (ingvar at projects.linpro.no) Date: Thu, 18 Dec 2008 10:47:06 +0100 (CET) Subject: r3463 - trunk/varnish-cache/redhat Message-ID: <20081218094706.2710F1EC7C3@projects.linpro.no> Author: ingvar Date: 2008-12-18 10:47:05 +0100 (Thu, 18 Dec 2008) New Revision: 3463 Modified: trunk/varnish-cache/redhat/varnish.spec Log: Changed rpm summary string as requested by the Fedora project Modified: trunk/varnish-cache/redhat/varnish.spec =================================================================== --- trunk/varnish-cache/redhat/varnish.spec 2008-12-12 11:47:32 UTC (rev 3462) +++ trunk/varnish-cache/redhat/varnish.spec 2008-12-18 09:47:05 UTC (rev 3463) @@ -1,4 +1,4 @@ -Summary: Varnish is a high-performance HTTP accelerator +Summary: High-performance HTTP accelerator Name: varnish Version: 2.0.2 Release: 1%{?dist} From phk at projects.linpro.no Thu Dec 18 10:04:16 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:04:16 +0100 (CET) Subject: r3464 - trunk/varnish-cache/bin/varnishd Message-ID: <20081218100416.1B0501EC20C@projects.linpro.no> Author: phk Date: 2008-12-18 11:04:15 +0100 (Thu, 18 Dec 2008) New Revision: 3464 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_backend.c trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/cache_expire.c trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_hash.c trunk/varnish-cache/bin/varnishd/cache_pipe.c trunk/varnish-cache/bin/varnishd/hash_slinger.h Log: A bit of cleanup while I ponder ticket 412: make VBE_free_bereq() and HSH_Deref() null their argument pointer. Add HSH_Drop() for deorbiting unwanted busy objects. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache.h 2008-12-18 10:04:15 UTC (rev 3464) @@ -407,7 +407,7 @@ void VBE_ClosedFd(struct sess *sp); void VBE_RecycleFd(struct sess *sp); struct bereq * VBE_new_bereq(void); -void VBE_free_bereq(struct bereq *bereq); +void VBE_free_bereq(struct bereq **bereq); void VBE_AddHostHeader(const struct sess *sp); void VBE_Poll(void); Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_backend.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -172,9 +172,14 @@ */ void -VBE_free_bereq(struct bereq *bereq) +VBE_free_bereq(struct bereq **bereqp) { + struct bereq *bereq; + AN(bereqp); + bereq = *bereqp; + *bereqp = NULL; + CHECK_OBJ_NOTNULL(bereq, BEREQ_MAGIC); WS_Reset(bereq->ws, NULL); Lck_Lock(&VBE_mtx); Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -177,8 +177,7 @@ RES_WriteObj(sp); AZ(sp->wrk->wfd); - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Deref(&sp->obj); sp->step = STP_DONE; return (0); } @@ -391,13 +390,9 @@ if (i) { sp->err_code = 503; sp->step = STP_ERROR; - VBE_free_bereq(sp->bereq); - sp->bereq = NULL; - sp->obj->ttl = 0; - sp->obj->cacheable = 0; - HSH_Unbusy(sp); - HSH_Deref(sp->obj); - sp->obj = NULL; + VBE_free_bereq(&sp->bereq); + HSH_Drop(sp); + AZ(sp->obj); return (0); } @@ -406,16 +401,11 @@ sp->err_code = http_GetStatus(sp->obj->http); VCL_fetch_method(sp); - VBE_free_bereq(sp->bereq); - sp->bereq = NULL; + VBE_free_bereq(&sp->bereq); switch (sp->handling) { case VCL_RET_RESTART: - sp->obj->ttl = 0; - sp->obj->cacheable = 0; - HSH_Unbusy(sp); - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Drop(sp); sp->director = NULL; sp->restarts++; sp->step = STP_RECV; @@ -427,11 +417,7 @@ break; case VCL_RET_ERROR: sp->step = STP_ERROR; - sp->obj->ttl = 0; - sp->obj->cacheable = 0; - HSH_Unbusy(sp); - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Drop(sp); return (0); default: WRONG("Illegal action in vcl_fetch{}"); @@ -535,8 +521,7 @@ } /* Drop our object, we won't need it */ - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Deref(&sp->obj); switch(sp->handling) { case VCL_RET_PASS: @@ -625,8 +610,7 @@ if (sp->obj->pass) { VSL_stats->cache_hitpass++; WSP(sp, SLT_HitPass, "%u", sp->obj->xid); - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Deref(&sp->obj); sp->step = STP_PASS; return (0); } @@ -670,24 +654,17 @@ http_FilterHeader(sp, HTTPH_R_FETCH); VCL_miss_method(sp); + AZ(sp->obj->cacheable); switch(sp->handling) { case VCL_RET_ERROR: - sp->obj->cacheable = 0; - HSH_Unbusy(sp); - HSH_Deref(sp->obj); - sp->obj = NULL; - VBE_free_bereq(sp->bereq); - sp->bereq = NULL; + HSH_Drop(sp); + VBE_free_bereq(&sp->bereq); sp->step = STP_ERROR; return (0); case VCL_RET_PASS: - sp->obj->cacheable = 0; - HSH_Unbusy(sp); - HSH_Deref(sp->obj); - sp->obj = NULL; + HSH_Drop(sp); + VBE_free_bereq(&sp->bereq); sp->step = STP_PASS; - VBE_free_bereq(sp->bereq); - sp->bereq = NULL; return (0); case VCL_RET_FETCH: sp->step = STP_FETCH; Modified: trunk/varnish-cache/bin/varnishd/cache_expire.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_expire.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_expire.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -337,7 +337,7 @@ VSL_stats->n_expired++; Lck_Unlock(&exp_mtx); del_objexp(o); - HSH_Deref(o); + HSH_Deref(&o); } } } @@ -406,7 +406,7 @@ if (sp->handling == VCL_RET_DISCARD) { WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid); del_objexp(o); - HSH_Deref(o); + HSH_Deref(&o); return (1); } Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -322,7 +322,7 @@ CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); AN(sp->director); - assert(sp->obj->busy != 0); + AN(sp->obj->busy); w = sp->wrk; bereq = sp->bereq; hp = bereq->http; Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -379,6 +379,22 @@ } void +HSH_Drop(struct sess *sp) +{ + struct object *o; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + o = sp->obj; + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + assert(o->busy); + assert(o->refcnt > 0); + o->ttl = 0; + o->cacheable = 0; + HSH_Unbusy(sp); + HSH_Deref(&sp->obj); +} + +void HSH_Unbusy(const struct sess *sp) { struct object *o; @@ -411,7 +427,7 @@ if (oh != NULL) Lck_Unlock(&oh->mtx); if (parent != NULL) - HSH_Deref(parent); + HSH_Deref(&parent); } void @@ -429,11 +445,15 @@ } void -HSH_Deref(struct object *o) +HSH_Deref(struct object **oo) { + struct object *o; struct objhead *oh; unsigned r; + AN(oo); + o = *oo; + *oo = NULL; CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); oh = o->objhead; if (oh != NULL) { Modified: trunk/varnish-cache/bin/varnishd/cache_pipe.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_pipe.c 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/cache_pipe.c 2008-12-18 10:04:15 UTC (rev 3464) @@ -96,8 +96,7 @@ return; } - VBE_free_bereq(bereq); - bereq = NULL; + VBE_free_bereq(&bereq); sp->t_resp = TIM_real(); Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-18 09:47:05 UTC (rev 3463) +++ trunk/varnish-cache/bin/varnishd/hash_slinger.h 2008-12-18 10:04:15 UTC (rev 3464) @@ -56,7 +56,8 @@ struct object *HSH_Lookup(struct sess *sp); void HSH_Unbusy(const struct sess *sp); void HSH_Ref(struct object *o); -void HSH_Deref(struct object *o); +void HSH_Deref(struct object **o); +void HSH_Drop(struct sess *sp); double HSH_Grace(double g); void HSH_Init(void); void HSH_AddString(struct sess *sp, const char *str); From phk at projects.linpro.no Thu Dec 18 10:13:42 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:13:42 +0100 (CET) Subject: r3465 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081218101342.390D31EC1F5@projects.linpro.no> Author: phk Date: 2008-12-18 11:13:42 +0100 (Thu, 18 Dec 2008) New Revision: 3465 Added: trunk/varnish-cache/bin/varnishtest/tests/r00412.vtc Log: Add regression test for ticket 412 Added: trunk/varnish-cache/bin/varnishtest/tests/r00412.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00412.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00412.vtc 2008-12-18 10:13:42 UTC (rev 3465) @@ -0,0 +1,36 @@ +# $Id$ + +test "Regression test for ticket 412" + +server s1 { + rxreq + expect req.url == "/" + txresp -status 303 -hdr "Location: /foo" + rxreq + expect req.url == "/foo" + txresp -body "12345" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + if (obj.status == 303) { + set obj.cacheable = true; + set obj.ttl = 60 s; + set obj.http.X-Magic-Redirect = "1"; + set req.url = obj.http.Location; + restart; + } + } + sub vcl_hit { + if (obj.http.X-Magic-Redirect == "1") { + set req.url = obj.http.Location; + restart; + } + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 +} -run From phk at projects.linpro.no Thu Dec 18 10:31:09 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:31:09 +0100 (CET) Subject: r3466 - trunk/varnish-cache/lib/libvcl Message-ID: <20081218103109.0BC811EC20C@projects.linpro.no> Author: phk Date: 2008-12-18 11:31:08 +0100 (Thu, 18 Dec 2008) New Revision: 3466 Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c Log: Add a missing error check. Fixes #409 Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2008-12-18 10:13:42 UTC (rev 3465) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2008-12-18 10:31:08 UTC (rev 3466) @@ -251,6 +251,7 @@ vcc_NextToken(tl); ExpectErr(tl, CSTR); p = vcc_regexp(tl, 0); + ERRCHK(tl); vcc_NextToken(tl); Fb(tl, 1, "VRT_re_match(%s, %s)\n", vp->rname, p); break; From phk at projects.linpro.no Thu Dec 18 10:32:30 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:32:30 +0100 (CET) Subject: r3467 - trunk/varnish-cache/bin/varnishd Message-ID: <20081218103230.A867A1EC421@projects.linpro.no> Author: phk Date: 2008-12-18 11:32:30 +0100 (Thu, 18 Dec 2008) New Revision: 3467 Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c Log: Add a missing newline Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2008-12-18 10:31:08 UTC (rev 3466) +++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2008-12-18 10:32:30 UTC (rev 3467) @@ -468,7 +468,7 @@ vf = mgt_VccCompile(&sb, av[3], 0); if (vsb_len(sb) > 0) - cli_out(cli, "%s", vsb_data(sb)); + cli_out(cli, "%s\n", vsb_data(sb)); vsb_delete(sb); if (vf == NULL) { cli_out(cli, "VCL compilation failed"); From phk at projects.linpro.no Thu Dec 18 10:32:48 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:32:48 +0100 (CET) Subject: r3468 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081218103248.6DB9D1EC47D@projects.linpro.no> Author: phk Date: 2008-12-18 11:32:48 +0100 (Thu, 18 Dec 2008) New Revision: 3468 Added: trunk/varnish-cache/bin/varnishtest/tests/r00409.vtc Log: Add regressiont test for #409 Added: trunk/varnish-cache/bin/varnishtest/tests/r00409.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00409.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00409.vtc 2008-12-18 10:32:48 UTC (rev 3468) @@ -0,0 +1,11 @@ +# $Id$ + +test "Regression test for ticket 409" + +varnish v1 -badvcl { + sub vcl_recv { + if ( req.url ~ ! "\.(png|jpg|gif|js|css)$" ) { + return (pass); + } + } +} From phk at projects.linpro.no Thu Dec 18 10:58:17 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 11:58:17 +0100 (CET) Subject: r3469 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081218105817.8AD831EC421@projects.linpro.no> Author: phk Date: 2008-12-18 11:58:17 +0100 (Thu, 18 Dec 2008) New Revision: 3469 Modified: trunk/varnish-cache/bin/varnishtest/tests/b00023.vtc Log: We should have a body length on a 200 reply Modified: trunk/varnish-cache/bin/varnishtest/tests/b00023.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/b00023.vtc 2008-12-18 10:32:48 UTC (rev 3468) +++ trunk/varnish-cache/bin/varnishtest/tests/b00023.vtc 2008-12-18 10:58:17 UTC (rev 3469) @@ -5,7 +5,7 @@ server s1 { rxreq delay 1.5 - txresp + txresp -body "foo" } -start varnish v1 -vcl+backend {} -start @@ -21,7 +21,7 @@ server s1 { rxreq delay 0.5 - txresp + txresp -body "foo" } -start client c1 { From phk at projects.linpro.no Thu Dec 18 11:30:03 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 12:30:03 +0100 (CET) Subject: r3470 - trunk/varnish-cache/bin/varnishd Message-ID: <20081218113003.58F721EC1F5@projects.linpro.no> Author: phk Date: 2008-12-18 12:30:02 +0100 (Thu, 18 Dec 2008) New Revision: 3470 Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c trunk/varnish-cache/bin/varnishd/cache_http.c Log: Change the logic that decides when we attempt EOF fetches from the backend. The new logic is: If (HEAD) /* happens only on pass */ do not fetch body. else if (Content-Length) fetch body according to length else if (chunked) fetch body as chunked else if (other transfer-encoding) fail else if (Connection: keep-alive) fetch no body, set Length = 0 else if (Connection: close) fetch body until EOF else if (HTTP < 1.1) fetch body until EOF else fetch no body, set Length = 0 let me know if this breaks anything that should work. Fixes #400 Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2008-12-18 10:58:17 UTC (rev 3469) +++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2008-12-18 11:30:02 UTC (rev 3470) @@ -414,15 +414,31 @@ WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding"); VBE_ClosedFd(sp); return (__LINE__); + } else if (http_HdrIs(hp, H_Connection, "keep-alive")) { + /* + * If we have Connection: keep-alive, it cannot possibly be + * EOF encoded, and since it is neither length nor chunked + * it must be zero length. + */ + mklen = 1; + } else if (http_HdrIs(hp, H_Connection, "close")) { + /* + * If we have connection closed, it is safe to read what + * comes in any case. + */ + cls = fetch_eof(sp, htc); + mklen = 1; + } else if (hp->protover < 1.1) { + /* + * With no Connection header, assume EOF + */ + cls = fetch_eof(sp, htc); + mklen = 1; } else { - switch (http_GetStatus(hp)) { - case 200: - cls = fetch_eof(sp, htc); - mklen = 1; - break; - default: - break; - } + /* + * Assume zero length + */ + mklen = 1; } if (cls < 0) { @@ -451,7 +467,7 @@ http_PrintfHeader(sp->wrk, sp->fd, hp2, "Content-Length: %u", sp->obj->len); - if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close")) + if (http_HdrIs(hp, H_Connection, "close")) cls = 1; if (cls) Modified: trunk/varnish-cache/bin/varnishd/cache_http.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_http.c 2008-12-18 10:58:17 UTC (rev 3469) +++ trunk/varnish-cache/bin/varnishd/cache_http.c 2008-12-18 11:30:02 UTC (rev 3470) @@ -251,7 +251,7 @@ unsigned u; if (!http_GetHdr(hp, H_Connection, &p)) { - if (strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) + if (hp->protover < 1.1) return ("not HTTP/1.1"); return (NULL); } @@ -442,6 +442,21 @@ /*--------------------------------------------------------------------*/ +static void +http_ProtoVer(struct http *hp) +{ + + if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) + hp->protover = 1.0; + else if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) + hp->protover = 1.1; + else + hp->protover = 0.9; +} + + +/*--------------------------------------------------------------------*/ + int http_DissectRequest(struct sess *sp) { @@ -463,13 +478,7 @@ WSPR(sp, SLT_HttpGarbage, htc->rxbuf); return (i); } - - if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0")) - hp->protover = 1.0; - else if (!strcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.1")) - hp->protover = 1.1; - else - hp->protover = 0.9; + http_ProtoVer(hp); return (i); } @@ -497,6 +506,7 @@ hp->status = strtoul(hp->hd[HTTP_HDR_STATUS].b, NULL /* XXX */, 10); } + http_ProtoVer(hp); if (hp->hd[HTTP_HDR_RESPONSE].b == NULL || !Tlen(hp->hd[HTTP_HDR_RESPONSE])) { /* Backend didn't send a response string, use the standard */ From phk at projects.linpro.no Thu Dec 18 11:30:18 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 12:30:18 +0100 (CET) Subject: r3471 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081218113018.18AE81EC2A5@projects.linpro.no> Author: phk Date: 2008-12-18 12:30:17 +0100 (Thu, 18 Dec 2008) New Revision: 3471 Added: trunk/varnish-cache/bin/varnishtest/tests/r00400.vtc Log: Add regression test for #400 Added: trunk/varnish-cache/bin/varnishtest/tests/r00400.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/r00400.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/r00400.vtc 2008-12-18 11:30:17 UTC (rev 3471) @@ -0,0 +1,21 @@ +# $Id$ + +test "Regression test for ticket 409" + +server s1 { + rxreq + expect req.url == "/" + send "HTTP/1.0 400 Not funny\r\n" + send "\r\n" + send "12345\r\n" +} -start + +varnish v1 -vcl+backend { +} -start + +client c1 { + txreq + rxresp + expect resp.status == 400 + expect resp.bodylen == 7 +} -run From phk at projects.linpro.no Thu Dec 18 11:48:56 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 12:48:56 +0100 (CET) Subject: r3472 - trunk/varnish-cache/bin/varnishtest/tests Message-ID: <20081218114856.355F51EC1F5@projects.linpro.no> Author: phk Date: 2008-12-18 12:48:56 +0100 (Thu, 18 Dec 2008) New Revision: 3472 Added: trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc Log: Add test for two corner cases in backend body determination. Added: trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc =================================================================== --- trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc (rev 0) +++ trunk/varnish-cache/bin/varnishtest/tests/b00027.vtc 2008-12-18 11:48:56 UTC (rev 3472) @@ -0,0 +1,28 @@ +# $Id$ + +test "test backend transmission corner cases" + +server s1 { + rxreq + txresp + rxreq + txresp -proto HTTP/1.0 -hdr "Connection: keep-alive" + rxreq + txresp -hdr "Transfer-encoding: foobar" +} -start + +varnish v1 -vcl+backend {} -start + +client c1 { + txreq -url /foo + rxresp + expect resp.status == 200 + expect resp.bodylen == 0 + txreq -url /bar + rxresp + expect resp.status == 200 + expect resp.bodylen == 0 + txreq -url /barf + rxresp + expect resp.status == 503 +} -run From phk at projects.linpro.no Thu Dec 18 12:00:43 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 13:00:43 +0100 (CET) Subject: r3473 - trunk/varnish-cache/bin/varnishd Message-ID: <20081218120043.5122C1EC20C@projects.linpro.no> Author: phk Date: 2008-12-18 13:00:43 +0100 (Thu, 18 Dec 2008) New Revision: 3473 Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c Log: Only fail -T argument if none of the addresses it resolves to can be listend on. Fixes #97 Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-12-18 11:48:56 UTC (rev 3472) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-12-18 12:00:43 UTC (rev 3473) @@ -459,22 +459,23 @@ { struct vss_addr **ta; char *addr, *port; - int i, n, sock; + int i, n, sock, good; struct telnet *tn; dflag_copy = dflag; XXXAZ(VSS_parse(T_arg, &addr, &port)); n = VSS_resolve(addr, port, &ta); - free(addr); - free(port); if (n == 0) { fprintf(stderr, "Could not open management port\n"); exit(2); } + good = 0; for (i = 0; i < n; ++i) { sock = VSS_listen(ta[i], 10); - assert(sock >= 0); + if (sock < 0) + continue; + good++; tn = telnet_new(sock); tn->ev = vev_new(); XXXAN(tn->ev); @@ -486,5 +487,12 @@ ta[i] = NULL; } free(ta); + if (good == 0) { + REPORT(LOG_ERR, "-T %s:%s could not be listened on.", + addr, port); + exit(2); + } + free(addr); + free(port); return (0); } From phk at projects.linpro.no Thu Dec 18 12:16:45 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Thu, 18 Dec 2008 13:16:45 +0100 (CET) Subject: r3474 - trunk/varnish-cache/bin/varnishd Message-ID: <20081218121645.D8D8D1EC1F5@projects.linpro.no> Author: phk Date: 2008-12-18 13:16:45 +0100 (Thu, 18 Dec 2008) New Revision: 3474 Modified: trunk/varnish-cache/bin/varnishd/storage_file.c Log: Assert lock properly held, inspired by unease about #378. Modified: trunk/varnish-cache/bin/varnishd/storage_file.c =================================================================== --- trunk/varnish-cache/bin/varnishd/storage_file.c 2008-12-18 12:00:43 UTC (rev 3473) +++ trunk/varnish-cache/bin/varnishd/storage_file.c 2008-12-18 12:16:45 UTC (rev 3474) @@ -343,6 +343,7 @@ assert(sp->alloc == 0); assert(sp->flist == NULL); + Lck_AssertHeld(&sc->mtx); b = sp->size / sc->pagesize; if (b >= NBUCKET) { b = NBUCKET - 1; @@ -372,6 +373,7 @@ assert(sp->alloc == 0); assert(sp->flist != NULL); + Lck_AssertHeld(&sc->mtx); b = sp->size / sc->pagesize; if (b >= NBUCKET) { b = NBUCKET - 1; @@ -602,14 +604,16 @@ sc = st->priv; + Lck_New(&sc->mtx); + Lck_Lock(&sc->mtx); smf_open_chunk(sc, sc->filesize, 0, &fail, &sum); + Lck_Unlock(&sc->mtx); printf("managed to mmap %ju bytes of %ju\n", (uintmax_t)sum, sc->filesize); /* XXX */ if (sum < MINPAGES * (off_t)getpagesize()) exit (2); - Lck_New(&sc->mtx); VSL_stats->sm_bfree += sc->filesize; } From phk at projects.linpro.no Sat Dec 20 23:27:00 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 00:27:00 +0100 (CET) Subject: r3475 - trunk/varnish-cache/bin/varnishd Message-ID: <20081220232700.A790C1EC20C@projects.linpro.no> Author: phk Date: 2008-12-21 00:27:00 +0100 (Sun, 21 Dec 2008) New Revision: 3475 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_http.c Log: Remove http_GetProto(), it's unused. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2008-12-18 12:16:45 UTC (rev 3474) +++ trunk/varnish-cache/bin/varnishd/cache.h 2008-12-20 23:27:00 UTC (rev 3475) @@ -476,7 +476,6 @@ const char *field, char **ptr); int http_GetStatus(const struct http *hp); const char *http_GetReq(const struct http *hp); -const char *http_GetProto(const struct http *hp); int http_HdrIs(const struct http *hp, const char *hdr, const char *val); int http_DissectRequest(struct sess *sp); int http_DissectResponse(struct worker *w, const struct http_conn *htc, Modified: trunk/varnish-cache/bin/varnishd/cache_http.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_http.c 2008-12-18 12:16:45 UTC (rev 3474) +++ trunk/varnish-cache/bin/varnishd/cache_http.c 2008-12-20 23:27:00 UTC (rev 3475) @@ -303,14 +303,6 @@ } const char * -http_GetProto(const struct http *hp) -{ - - Tcheck(hp->hd[HTTP_HDR_PROTO]); - return (hp->hd[HTTP_HDR_PROTO].b); -} - -const char * http_GetReq(const struct http *hp) { From phk at projects.linpro.no Sat Dec 20 23:47:45 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 00:47:45 +0100 (CET) Subject: r3476 - trunk/varnish-cache/lib/libvcl Message-ID: <20081220234745.8D2BC1EC114@projects.linpro.no> Author: phk Date: 2008-12-21 00:47:45 +0100 (Sun, 21 Dec 2008) New Revision: 3476 Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c Log: This is a bandaid for a pointer dereference when "restart" is used. Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-20 23:27:00 UTC (rev 3475) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-20 23:47:45 UTC (rev 3476) @@ -85,7 +85,8 @@ ERRCHK(tl); } Fb(tl, 1, "VRT_done(sp, VCL_RET_RESTART);\n"); - vcc_ProcAction(tl->curproc, VCL_RET_RESTART, tl->t); + assert(VCL_RET_RESTART == (1 << 9)); /* XXX: BANDAID FIXME! */ + vcc_ProcAction(tl->curproc, 9, tl->t); vcc_NextToken(tl); } From phk at projects.linpro.no Sun Dec 21 10:45:33 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 11:45:33 +0100 (CET) Subject: r3477 - trunk/varnish-cache/include Message-ID: <20081221104533.CDC4F1EC20C@projects.linpro.no> Author: phk Date: 2008-12-21 11:45:33 +0100 (Sun, 21 Dec 2008) New Revision: 3477 Modified: trunk/varnish-cache/include/libvarnish.h Log: Make it entirely clear to the compiler that the WRONG() macro stops Modified: trunk/varnish-cache/include/libvarnish.h =================================================================== --- trunk/varnish-cache/include/libvarnish.h 2008-12-20 23:47:45 UTC (rev 3476) +++ trunk/varnish-cache/include/libvarnish.h 2008-12-21 10:45:33 UTC (rev 3477) @@ -128,4 +128,5 @@ #define WRONG(expl) \ do { \ lbv_assert(__func__, __FILE__, __LINE__, expl, errno, 3); \ + abort(); \ } while (0) From phk at projects.linpro.no Sun Dec 21 10:46:34 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 11:46:34 +0100 (CET) Subject: r3478 - in trunk/varnish-cache: include lib/libvcl Message-ID: <20081221104634.93E2C1EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 11:46:34 +0100 (Sun, 21 Dec 2008) New Revision: 3478 Modified: trunk/varnish-cache/include/libvcl.h trunk/varnish-cache/lib/libvcl/vcc_compile.c Log: Add a VCC_Return_Name() function to convert a return action to a string. Modified: trunk/varnish-cache/include/libvcl.h =================================================================== --- trunk/varnish-cache/include/libvcl.h 2008-12-21 10:45:33 UTC (rev 3477) +++ trunk/varnish-cache/include/libvcl.h 2008-12-21 10:46:34 UTC (rev 3478) @@ -31,5 +31,5 @@ char *VCC_Compile(struct vsb *sb, const char *b, const char *e); void VCC_InitCompile(const char *default_vcl); +const char *VCC_Return_Name(unsigned action); - Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 10:45:33 UTC (rev 3477) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 10:46:34 UTC (rev 3478) @@ -662,6 +662,23 @@ return (r); } +/*--------------------------------------------------------------------*/ + +const char * +VCC_Return_Name(unsigned method) +{ + + switch (method) { + case 0: return (""); +#define VCL_RET_MAC(l, u, b, i) case b: return(#u); +#define VCL_RET_MAC_E(l, u, b, i) case b: return(#u); +#include "vcl_returns.h" +#undef VCL_RET_MAC_E +#undef VCL_RET_MAC + } + return (NULL); +} + /*-------------------------------------------------------------------- * Initialize the compiler and register the default VCL code for later * compilation runs. From phk at projects.linpro.no Sun Dec 21 10:47:09 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 11:47:09 +0100 (CET) Subject: r3479 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221104709.730C71EC20C@projects.linpro.no> Author: phk Date: 2008-12-21 11:47:09 +0100 (Sun, 21 Dec 2008) New Revision: 3479 Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c Log: Use VCC_Return_Name() instead of rolling our own. Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_panic.c 2008-12-21 10:46:34 UTC (rev 3478) +++ trunk/varnish-cache/bin/varnishd/cache_panic.c 2008-12-21 10:47:09 UTC (rev 3479) @@ -40,6 +40,7 @@ #include "cache.h" #include "cache_backend.h" #include "vcl.h" +#include "libvcl.h" /* * The panic string is constructed in memory, then copied to the @@ -214,16 +215,7 @@ /*lint -restore */ default: stp = NULL; } - switch (sp->handling) { -/*lint -save -e525 */ -#define VCL_RET_MAC(l, u, b, v) case VCL_RET_##u: hand = #u; break; -#define VCL_RET_MAC_E(l, u, b, v) case VCL_RET_##u: hand = #u; break; -#include "vcl_returns.h" -#undef VCL_RET_MAC -#undef VCL_RET_MAC_E -/*lint -restore */ - default: hand = NULL; - } + hand = VCC_Return_Name(sp->handling); if (stp != NULL) vsb_printf(vsp, " step = %s,\n", stp); else From phk at projects.linpro.no Sun Dec 21 10:55:53 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 11:55:53 +0100 (CET) Subject: r3480 - in trunk/varnish-cache: bin/varnishd lib/libvcl Message-ID: <20081221105553.4E5501EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 11:55:53 +0100 (Sun, 21 Dec 2008) New Revision: 3480 Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c trunk/varnish-cache/lib/libvcl/vcc_compile.c Log: Make VCC_Return_Name() return lower case, and use it also for the SMH logging. Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vcl.c 2008-12-21 10:47:09 UTC (rev 3479) +++ trunk/varnish-cache/bin/varnishd/cache_vcl.c 2008-12-21 10:55:53 UTC (rev 3480) @@ -46,6 +46,7 @@ #include "shmlog.h" #include "vcl.h" #include "cache.h" +#include "libvcl.h" struct vcls { unsigned magic; @@ -299,21 +300,6 @@ /*--------------------------------------------------------------------*/ -static const char * -vcl_handlingname(unsigned u) -{ - - switch (u) { -#define VCL_RET_MAC(a, b, c,d) case VCL_RET_##b: return(#a); -#define VCL_RET_MAC_E(a, b, c,d) case VCL_RET_##b: return(#a); -#include "vcl_returns.h" -#undef VCL_RET_MAC -#undef VCL_RET_MAC_E - default: - return (NULL); - } -} - #define VCL_RET_MAC(l,u,b,n) #define VCL_MET_MAC(func, upper, bitmap) \ @@ -325,7 +311,7 @@ sp->cur_method = VCL_MET_ ## upper; \ WSP(sp, SLT_VCL_call, "%s", #func); \ sp->vcl->func##_func(sp); \ - WSP(sp, SLT_VCL_return, "%s", vcl_handlingname(sp->handling)); \ + WSP(sp, SLT_VCL_return, "%s", VCC_Return_Name(sp->handling)); \ sp->cur_method = 0; \ assert(sp->handling & bitmap); \ assert(!(sp->handling & ~bitmap)); \ Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 10:47:09 UTC (rev 3479) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 10:55:53 UTC (rev 3480) @@ -670,8 +670,8 @@ switch (method) { case 0: return (""); -#define VCL_RET_MAC(l, u, b, i) case b: return(#u); -#define VCL_RET_MAC_E(l, u, b, i) case b: return(#u); +#define VCL_RET_MAC(l, u, b, i) case b: return(#l); +#define VCL_RET_MAC_E(l, u, b, i) case b: return(#l); #include "vcl_returns.h" #undef VCL_RET_MAC_E #undef VCL_RET_MAC From phk at projects.linpro.no Sun Dec 21 10:56:11 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 11:56:11 +0100 (CET) Subject: r3481 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221105611.D21161EC20C@projects.linpro.no> Author: phk Date: 2008-12-21 11:56:11 +0100 (Sun, 21 Dec 2008) New Revision: 3481 Modified: trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/bin/varnishd/flint.sh Log: Flexelint adjustments Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 10:55:53 UTC (rev 3480) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 10:56:11 UTC (rev 3481) @@ -69,6 +69,8 @@ -ffc // No automatic custody +-e455 // thread lock +-e458 // unprotected read -e763 // Redundant declaration for symbol '...' previously declared -e726 // Extraneous comma ignored -e728 // Symbol ... not explicitly initialized Modified: trunk/varnish-cache/bin/varnishd/flint.sh =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.sh 2008-12-21 10:55:53 UTC (rev 3480) +++ trunk/varnish-cache/bin/varnishd/flint.sh 2008-12-21 10:56:11 UTC (rev 3481) @@ -10,25 +10,4 @@ flint.lnt \ *.c \ ../../lib/libvarnish/*.c \ - ../../lib/libvcl/*.c \ - > $T 2>&1 - -for t in Error Warning Info Note -do - sed -n "/$t [0-9][0-9][0-9]:/s/.*\($t [0-9][0-9][0-9]\).*/\1/p" $T -done | awk ' -$2 == 830 { next } -$2 == 831 { next } - { - i=$2"_"$1 - h[i]++ - n++ - } -END { - printf "%5d %s\n", n, "Total" - for (i in h) - printf "%5d %s\n", h[i], i - } -' | sort -rn - -cat $T + ../../lib/libvcl/*.c From phk at projects.linpro.no Sun Dec 21 16:18:39 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 17:18:39 +0100 (CET) Subject: r3482 - trunk/varnish-cache/lib/libvcl Message-ID: <20081221161839.3257D1EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 17:18:39 +0100 (Sun, 21 Dec 2008) New Revision: 3482 Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl Log: Move the enum MET/RET macros to vcl.h Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2008-12-21 10:56:11 UTC (rev 3481) +++ trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2008-12-21 16:18:39 UTC (rev 3482) @@ -109,7 +109,7 @@ puts $fd " *" puts $fd " * NB: This file is machine generated, DO NOT EDIT!" puts $fd " *" - puts $fd " * Edit vcc_gen_fixed_token.tcl instead" + puts $fd " * Edit and run vcc_gen_fixed_token.tcl instead" puts $fd " */" puts $fd "" } @@ -126,6 +126,29 @@ typedef void vcl_fini_f(struct cli *); typedef int vcl_func_f(struct sess *sp); } + +puts $fo "/* VCL Methods */" +set u 0 +foreach m $methods { + if {[string length [lindex $m 0]] < 8} { + set sp "\t" + } else { + set sp "" + } + puts $fo "#define VCL_MET_[string toupper [lindex $m 0]]\t${sp}(1 << $u)" + incr u +} + +puts $fo "\n#define VCL_MET_MAX\t\t$u\n" + +puts $fo "/* VCL Returns */" +set i 0 +foreach k $returns { + puts $fo "#define VCL_RET_[string toupper $k]\t\t(1 << $i)" + incr i +} +puts $fo "\n#define VCL_RET_MAX\t\t$i\n" + puts $fo "struct VCL_conf {" puts $fo { unsigned magic; #define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */ @@ -171,13 +194,6 @@ } incr i } -puts $for "#else" -set i 0 -foreach k $returns { - puts $for "#define VCL_RET_[string toupper $k] (1 << $i)" - incr i -} -puts $for "#define VCL_RET_MAX $i" puts $for "#endif" puts $for "" puts $for "#ifdef VCL_MET_MAC" @@ -186,7 +202,7 @@ puts -nonewline $for "VCL_MET_MAC([lindex $m 0]" puts -nonewline $for ",[string toupper [lindex $m 0]]" set l [lindex $m 1] - puts -nonewline $for ",(\n VCL_RET_[string toupper [lindex $l 0]]" + puts -nonewline $for ",\n (VCL_RET_[string toupper [lindex $l 0]]" foreach r [lrange $l 1 end] { puts -nonewline $for "|VCL_RET_[string toupper $r]" } @@ -194,14 +210,7 @@ puts $for ")" incr u } -puts $for "#else" -set u 0 -foreach m $methods { - puts $for "#define VCL_MET_[string toupper [lindex $m 0]]\t(1 << $u)" - incr u -} puts $for "#endif" -puts $for "#define N_METHODS $u" close $for #---------------------------------------------------------------------- From phk at projects.linpro.no Sun Dec 21 16:19:14 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 17:19:14 +0100 (CET) Subject: r3483 - in trunk/varnish-cache: bin/varnishd include lib/libvcl Message-ID: <20081221161914.6ADD91EC114@projects.linpro.no> Author: phk Date: 2008-12-21 17:19:14 +0100 (Sun, 21 Dec 2008) New Revision: 3483 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_expire.c trunk/varnish-cache/include/vcl.h trunk/varnish-cache/include/vcl_returns.h trunk/varnish-cache/lib/libvcl/vcc_compile.c trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c trunk/varnish-cache/lib/libvcl/vcc_parse.c trunk/varnish-cache/lib/libvcl/vcc_token_defs.h Log: Move the enum MET/RET macros to vcl.h Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/bin/varnishd/cache.h 2008-12-21 16:19:14 UTC (rev 3483) @@ -54,7 +54,6 @@ #include "libvarnish.h" -#include "vcl_returns.h" #include "common.h" #include "heritage.h" #include "miniobj.h" Modified: trunk/varnish-cache/bin/varnishd/cache_expire.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_expire.c 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/bin/varnishd/cache_expire.c 2008-12-21 16:19:14 UTC (rev 3483) @@ -60,6 +60,7 @@ #include "shmlog.h" #include "binary_heap.h" #include "cache.h" +#include "vcl.h" #include "hash_slinger.h" /* Modified: trunk/varnish-cache/include/vcl.h =================================================================== --- trunk/varnish-cache/include/vcl.h 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/include/vcl.h 2008-12-21 16:19:14 UTC (rev 3483) @@ -3,7 +3,7 @@ * * NB: This file is machine generated, DO NOT EDIT! * - * Edit vcc_gen_fixed_token.tcl instead + * Edit and run vcc_gen_fixed_token.tcl instead */ struct sess; @@ -13,6 +13,36 @@ typedef void vcl_fini_f(struct cli *); typedef int vcl_func_f(struct sess *sp); +/* VCL Methods */ +#define VCL_MET_RECV (1 << 0) +#define VCL_MET_PIPE (1 << 1) +#define VCL_MET_PASS (1 << 2) +#define VCL_MET_HASH (1 << 3) +#define VCL_MET_MISS (1 << 4) +#define VCL_MET_HIT (1 << 5) +#define VCL_MET_FETCH (1 << 6) +#define VCL_MET_DELIVER (1 << 7) +#define VCL_MET_PREFETCH (1 << 8) +#define VCL_MET_TIMEOUT (1 << 9) +#define VCL_MET_DISCARD (1 << 10) +#define VCL_MET_ERROR (1 << 11) + +#define VCL_MET_MAX 12 + +/* VCL Returns */ +#define VCL_RET_ERROR (1 << 0) +#define VCL_RET_LOOKUP (1 << 1) +#define VCL_RET_HASH (1 << 2) +#define VCL_RET_PIPE (1 << 3) +#define VCL_RET_PASS (1 << 4) +#define VCL_RET_FETCH (1 << 5) +#define VCL_RET_DELIVER (1 << 6) +#define VCL_RET_DISCARD (1 << 7) +#define VCL_RET_KEEP (1 << 8) +#define VCL_RET_RESTART (1 << 9) + +#define VCL_RET_MAX 10 + struct VCL_conf { unsigned magic; #define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */ Modified: trunk/varnish-cache/include/vcl_returns.h =================================================================== --- trunk/varnish-cache/include/vcl_returns.h 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/include/vcl_returns.h 2008-12-21 16:19:14 UTC (rev 3483) @@ -3,7 +3,7 @@ * * NB: This file is machine generated, DO NOT EDIT! * - * Edit vcc_gen_fixed_token.tcl instead + * Edit and run vcc_gen_fixed_token.tcl instead */ #ifdef VCL_RET_MAC @@ -19,57 +19,31 @@ VCL_RET_MAC(discard, DISCARD, (1 << 7), 7) VCL_RET_MAC(keep, KEEP, (1 << 8), 8) VCL_RET_MAC(restart, RESTART, (1 << 9), 9) -#else -#define VCL_RET_ERROR (1 << 0) -#define VCL_RET_LOOKUP (1 << 1) -#define VCL_RET_HASH (1 << 2) -#define VCL_RET_PIPE (1 << 3) -#define VCL_RET_PASS (1 << 4) -#define VCL_RET_FETCH (1 << 5) -#define VCL_RET_DELIVER (1 << 6) -#define VCL_RET_DISCARD (1 << 7) -#define VCL_RET_KEEP (1 << 8) -#define VCL_RET_RESTART (1 << 9) -#define VCL_RET_MAX 10 #endif #ifdef VCL_MET_MAC -VCL_MET_MAC(recv,RECV,( - VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_LOOKUP)) -VCL_MET_MAC(pipe,PIPE,( - VCL_RET_ERROR|VCL_RET_PIPE)) -VCL_MET_MAC(pass,PASS,( - VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS)) -VCL_MET_MAC(hash,HASH,( - VCL_RET_HASH)) -VCL_MET_MAC(miss,MISS,( - VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_FETCH)) -VCL_MET_MAC(hit,HIT,( - VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) -VCL_MET_MAC(fetch,FETCH,( - VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) -VCL_MET_MAC(deliver,DELIVER,( - VCL_RET_RESTART|VCL_RET_DELIVER)) -VCL_MET_MAC(prefetch,PREFETCH,( - VCL_RET_FETCH|VCL_RET_PASS)) -VCL_MET_MAC(timeout,TIMEOUT,( - VCL_RET_FETCH|VCL_RET_DISCARD)) -VCL_MET_MAC(discard,DISCARD,( - VCL_RET_DISCARD|VCL_RET_KEEP)) -VCL_MET_MAC(error,ERROR,( - VCL_RET_DELIVER)) -#else -#define VCL_MET_RECV (1 << 0) -#define VCL_MET_PIPE (1 << 1) -#define VCL_MET_PASS (1 << 2) -#define VCL_MET_HASH (1 << 3) -#define VCL_MET_MISS (1 << 4) -#define VCL_MET_HIT (1 << 5) -#define VCL_MET_FETCH (1 << 6) -#define VCL_MET_DELIVER (1 << 7) -#define VCL_MET_PREFETCH (1 << 8) -#define VCL_MET_TIMEOUT (1 << 9) -#define VCL_MET_DISCARD (1 << 10) -#define VCL_MET_ERROR (1 << 11) +VCL_MET_MAC(recv,RECV, + (VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_LOOKUP)) +VCL_MET_MAC(pipe,PIPE, + (VCL_RET_ERROR|VCL_RET_PIPE)) +VCL_MET_MAC(pass,PASS, + (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS)) +VCL_MET_MAC(hash,HASH, + (VCL_RET_HASH)) +VCL_MET_MAC(miss,MISS, + (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_FETCH)) +VCL_MET_MAC(hit,HIT, + (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) +VCL_MET_MAC(fetch,FETCH, + (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) +VCL_MET_MAC(deliver,DELIVER, + (VCL_RET_RESTART|VCL_RET_DELIVER)) +VCL_MET_MAC(prefetch,PREFETCH, + (VCL_RET_FETCH|VCL_RET_PASS)) +VCL_MET_MAC(timeout,TIMEOUT, + (VCL_RET_FETCH|VCL_RET_DISCARD)) +VCL_MET_MAC(discard,DISCARD, + (VCL_RET_DISCARD|VCL_RET_KEEP)) +VCL_MET_MAC(error,ERROR, + (VCL_RET_DELIVER)) #endif -#define N_METHODS 12 Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 16:19:14 UTC (rev 3483) @@ -500,7 +500,7 @@ assert(tl->ff != NULL); /* body code of methods */ - for (i = 0; i < N_METHODS; i++) { + for (i = 0; i < VCL_MET_MAX; i++) { tl->fm[i] = vsb_newauto(); assert(tl->fm[i] != NULL); } @@ -532,7 +532,7 @@ vsb_delete(tl->fc); vsb_delete(tl->fi); vsb_delete(tl->ff); - for (i = 0; i < N_METHODS; i++) + for (i = 0; i < VCL_MET_MAX; i++) vsb_delete(tl->fm[i]); free(tl); @@ -611,7 +611,7 @@ return (vcc_DestroyTokenList(tl, NULL)); /* Emit method functions */ - for (i = 0; i < N_METHODS; i++) { + for (i = 0; i < VCL_MET_MAX; i++) { Fc(tl, 1, "\nstatic int\n"); Fc(tl, 1, "VGC_function_%s (struct sess *sp)\n", method_tab[i].name); Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2008-12-21 16:19:14 UTC (rev 3483) @@ -31,7 +31,7 @@ #include "vqueue.h" -#include "vcl_returns.h" +#include "vcl.h" #define INDENT 2 @@ -77,7 +77,7 @@ int findent; unsigned cnt; struct vsb *fc, *fh, *fi, *ff, *fb; - struct vsb *fm[N_METHODS]; + struct vsb *fm[VCL_MET_MAX]; VTAILQ_HEAD(, ref) refs; struct vsb *sb; int err; @@ -85,7 +85,7 @@ int ndirector; VTAILQ_HEAD(, proc) procs; struct proc *curproc; - struct proc *mprocs[N_METHODS]; + struct proc *mprocs[VCL_MET_MAX]; VTAILQ_HEAD(, acl_e) acl; Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2008-12-21 16:19:14 UTC (rev 3483) @@ -3,7 +3,7 @@ * * NB: This file is machine generated, DO NOT EDIT! * - * Edit vcc_gen_fixed_token.tcl instead + * Edit and run vcc_gen_fixed_token.tcl instead */ #include "config.h" @@ -167,14 +167,38 @@ /* ../../include/vcl.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3377 2008-11-10 11"); - vsb_cat(sb, ":55:15Z tfheen $\n *\n * NB: This file is machine gen"); - vsb_cat(sb, "erated, DO NOT EDIT!\n *\n * Edit vcc_gen_fixed_token."); - vsb_cat(sb, "tcl instead\n */\n\nstruct sess;\n"); + vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3482 2008-12-21 16"); + vsb_cat(sb, ":18:39Z phk $\n *\n * NB: This file is machine genera"); + vsb_cat(sb, "ted, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_t"); + vsb_cat(sb, "oken.tcl instead\n */\n\nstruct sess;\n"); vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\n"); vsb_cat(sb, "typedef void vcl_fini_f(struct cli *);\n"); vsb_cat(sb, "typedef int vcl_func_f(struct sess *sp);\n"); - vsb_cat(sb, "\nstruct VCL_conf {\n\tunsigned\tmagic;\n"); + vsb_cat(sb, "\n/* VCL Methods */\n#define VCL_MET_RECV\t\t(1 << 0)\n"); + vsb_cat(sb, "#define VCL_MET_PIPE\t\t(1 << 1)\n"); + vsb_cat(sb, "#define VCL_MET_PASS\t\t(1 << 2)\n"); + vsb_cat(sb, "#define VCL_MET_HASH\t\t(1 << 3)\n"); + vsb_cat(sb, "#define VCL_MET_MISS\t\t(1 << 4)\n"); + vsb_cat(sb, "#define VCL_MET_HIT\t\t(1 << 5)\n"); + vsb_cat(sb, "#define VCL_MET_FETCH\t\t(1 << 6)\n"); + vsb_cat(sb, "#define VCL_MET_DELIVER\t\t(1 << 7)\n"); + vsb_cat(sb, "#define VCL_MET_PREFETCH\t(1 << 8)\n"); + vsb_cat(sb, "#define VCL_MET_TIMEOUT\t\t(1 << 9)\n"); + vsb_cat(sb, "#define VCL_MET_DISCARD\t\t(1 << 10)\n"); + vsb_cat(sb, "#define VCL_MET_ERROR\t\t(1 << 11)\n"); + vsb_cat(sb, "\n#define VCL_MET_MAX\t\t12\n\n"); + vsb_cat(sb, "/* VCL Returns */\n#define VCL_RET_ERROR\t\t(1 << 0)\n"); + vsb_cat(sb, "#define VCL_RET_LOOKUP\t\t(1 << 1)\n"); + vsb_cat(sb, "#define VCL_RET_HASH\t\t(1 << 2)\n"); + vsb_cat(sb, "#define VCL_RET_PIPE\t\t(1 << 3)\n"); + vsb_cat(sb, "#define VCL_RET_PASS\t\t(1 << 4)\n"); + vsb_cat(sb, "#define VCL_RET_FETCH\t\t(1 << 5)\n"); + vsb_cat(sb, "#define VCL_RET_DELIVER\t\t(1 << 6)\n"); + vsb_cat(sb, "#define VCL_RET_DISCARD\t\t(1 << 7)\n"); + vsb_cat(sb, "#define VCL_RET_KEEP\t\t(1 << 8)\n"); + vsb_cat(sb, "#define VCL_RET_RESTART\t\t(1 << 9)\n"); + vsb_cat(sb, "\n#define VCL_RET_MAX\t\t10\n\n"); + vsb_cat(sb, "struct VCL_conf {\n\tunsigned\tmagic;\n"); vsb_cat(sb, "#define VCL_CONF_MAGIC\t0x7406c509\t/* from /dev/rando"); vsb_cat(sb, "m */\n\n\tstruct director\t**director;\n"); vsb_cat(sb, "\tunsigned\tndirector;\n\tstruct vrt_ref\t*ref;\n"); @@ -223,10 +247,10 @@ vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI"); vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT"); vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3393 2008-11-14 09:"); - vsb_cat(sb, "49:28Z phk $\n *\n * Runtime support for compiled VCL "); - vsb_cat(sb, "programs.\n *\n * XXX: When this file is changed, lib/"); - vsb_cat(sb, "libvcl/vcc_gen_fixed_token.tcl\n"); + vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3406 2008-11-19 14:"); + vsb_cat(sb, "13:57Z petter $\n *\n * Runtime support for compiled V"); + vsb_cat(sb, "CL programs.\n *\n * XXX: When this file is changed, l"); + vsb_cat(sb, "ib/libvcl/vcc_gen_fixed_token.tcl\n"); vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n"); vsb_cat(sb, "\nstruct sess;\nstruct vsb;\nstruct cli;\n"); vsb_cat(sb, "struct director;\nstruct VCL_conf;\n"); @@ -311,9 +335,9 @@ /* ../../include/vrt_obj.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_obj.tcl 3324 2008-10-18 20:50:10Z "); - vsb_cat(sb, "phk $\n *\n * NB: This file is machine generated, DO "); - vsb_cat(sb, "NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); + vsb_cat(sb, "/*\n * $Id: vrt_obj.h 3406 2008-11-19 14:13:57Z petter"); + vsb_cat(sb, " $\n *\n * NB: This file is machine generated, DO NOT"); + vsb_cat(sb, " EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct "); vsb_cat(sb, "sess *);\nstruct sockaddr * VRT_r_server_ip(struct ses"); vsb_cat(sb, "s *);\nint VRT_r_server_port(struct sess *);\n"); Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_parse.c 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/lib/libvcl/vcc_parse.c 2008-12-21 16:19:14 UTC (rev 3483) @@ -540,7 +540,7 @@ m = IsMethod(tl->t); if (m != -1) { - assert(m < N_METHODS); + assert(m < VCL_MET_MAX); tl->fb = tl->fm[m]; if (tl->mprocs[m] == NULL) { tl->mprocs[m] = vcc_AddProc(tl, tl->t); Modified: trunk/varnish-cache/lib/libvcl/vcc_token_defs.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_token_defs.h 2008-12-21 16:18:39 UTC (rev 3482) +++ trunk/varnish-cache/lib/libvcl/vcc_token_defs.h 2008-12-21 16:19:14 UTC (rev 3483) @@ -3,7 +3,7 @@ * * NB: This file is machine generated, DO NOT EDIT! * - * Edit vcc_gen_fixed_token.tcl instead + * Edit and run vcc_gen_fixed_token.tcl instead */ #define LOW_TOKEN 128 From phk at projects.linpro.no Sun Dec 21 17:01:58 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 18:01:58 +0100 (CET) Subject: r3484 - trunk/varnish-cache/lib/libvcl Message-ID: <20081221170158.4907E1EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 18:01:58 +0100 (Sun, 21 Dec 2008) New Revision: 3484 Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl Log: Generate VCL_RET_* as enumbering instead of bitmap, compensate elsewhere as required. Remove unecessary args to VCL_[RM]ET_MAC(). Rely on VCL_RET_* definition in vcl.h Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2008-12-21 16:19:14 UTC (rev 3483) +++ trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2008-12-21 17:01:58 UTC (rev 3484) @@ -144,7 +144,7 @@ puts $fo "/* VCL Returns */" set i 0 foreach k $returns { - puts $fo "#define VCL_RET_[string toupper $k]\t\t(1 << $i)" + puts $fo "#define VCL_RET_[string toupper $k]\t\t$i" incr i } puts $fo "\n#define VCL_RET_MAX\t\t$i\n" @@ -186,11 +186,9 @@ foreach k $returns { set u [string toupper $k] if {$k == "error"} { - puts $for "#ifdef VCL_RET_MAC_E" - puts $for "VCL_RET_MAC_E($k, $u, (1 << $i), $i)" - puts $for "#endif" + puts $for "VCL_RET_MAC($k, $u)" } else { - puts $for "VCL_RET_MAC($k, $u, (1 << $i), $i)" + puts $for "VCL_RET_MAC($k, $u)" } incr i } @@ -202,12 +200,12 @@ puts -nonewline $for "VCL_MET_MAC([lindex $m 0]" puts -nonewline $for ",[string toupper [lindex $m 0]]" set l [lindex $m 1] - puts -nonewline $for ",\n (VCL_RET_[string toupper [lindex $l 0]]" + puts $for "," + puts $for " ((1 << VCL_RET_[string toupper [lindex $l 0]])" foreach r [lrange $l 1 end] { - puts -nonewline $for "|VCL_RET_[string toupper $r]" + puts $for " | (1 << VCL_RET_[string toupper $r])" } - puts -nonewline $for ")" - puts $for ")" + puts $for "))" incr u } puts $for "#endif" @@ -400,12 +398,6 @@ puts $fo "void" puts $fo "vcl_output_lang_h(struct vsb *sb)" puts $fo "{" -set i 0 -foreach k $returns { - set u [string toupper $k] - puts $fo "\tvsb_cat(sb, \"#define VCL_RET_$u (1 << $i)\\n\");" - incr i -} copy_include ../../include/vcl.h copy_include ../../include/vrt.h From phk at projects.linpro.no Sun Dec 21 17:03:37 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 18:03:37 +0100 (CET) Subject: r3485 - in trunk/varnish-cache: bin/varnishd include lib/libvcl Message-ID: <20081221170337.DE1111EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 18:03:37 +0100 (Sun, 21 Dec 2008) New Revision: 3485 Modified: trunk/varnish-cache/bin/varnishd/cache.h trunk/varnish-cache/bin/varnishd/cache_vcl.c trunk/varnish-cache/bin/varnishd/cache_vrt.c trunk/varnish-cache/include/vcl.h trunk/varnish-cache/include/vcl_returns.h trunk/varnish-cache/lib/libvcl/vcc_action.c trunk/varnish-cache/lib/libvcl/vcc_compile.c trunk/varnish-cache/lib/libvcl/vcc_compile.h trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c trunk/varnish-cache/lib/libvcl/vcc_xref.c Log: Adjust to VCL_RET_* being enum instead of bitmap. This solves the "restart" procaction issue in a non-hackish way and looks better overall. Modified: trunk/varnish-cache/bin/varnishd/cache.h =================================================================== --- trunk/varnish-cache/bin/varnishd/cache.h 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/bin/varnishd/cache.h 2008-12-21 17:03:37 UTC (rev 3485) @@ -595,11 +595,9 @@ void VCL_Get(struct VCL_conf **vcc); void VCL_Poll(void); -#define VCL_RET_MAC(l,u,b,n) #define VCL_MET_MAC(l,u,b) void VCL_##l##_method(struct sess *); #include "vcl_returns.h" #undef VCL_MET_MAC -#undef VCL_RET_MAC /* cache_vrt_esi.c */ Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vcl.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/bin/varnishd/cache_vcl.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -300,8 +300,6 @@ /*--------------------------------------------------------------------*/ -#define VCL_RET_MAC(l,u,b,n) - #define VCL_MET_MAC(func, upper, bitmap) \ void \ VCL_##func##_method(struct sess *sp) \ @@ -313,13 +311,12 @@ sp->vcl->func##_func(sp); \ WSP(sp, SLT_VCL_return, "%s", VCC_Return_Name(sp->handling)); \ sp->cur_method = 0; \ - assert(sp->handling & bitmap); \ - assert(!(sp->handling & ~bitmap)); \ + assert((1 << sp->handling) & bitmap); \ + assert(!((1 << sp->handling) & ~bitmap)); \ } #include "vcl_returns.h" #undef VCL_MET_MAC -#undef VCL_RET_MAC /*--------------------------------------------------------------------*/ Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_vrt.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/bin/varnishd/cache_vrt.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -348,7 +348,7 @@ { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - assert(!(hand & (hand -1))); /* must be power of two */ + assert(hand < VCL_RET_MAX); sp->handling = hand; } Modified: trunk/varnish-cache/include/vcl.h =================================================================== --- trunk/varnish-cache/include/vcl.h 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/include/vcl.h 2008-12-21 17:03:37 UTC (rev 3485) @@ -30,16 +30,16 @@ #define VCL_MET_MAX 12 /* VCL Returns */ -#define VCL_RET_ERROR (1 << 0) -#define VCL_RET_LOOKUP (1 << 1) -#define VCL_RET_HASH (1 << 2) -#define VCL_RET_PIPE (1 << 3) -#define VCL_RET_PASS (1 << 4) -#define VCL_RET_FETCH (1 << 5) -#define VCL_RET_DELIVER (1 << 6) -#define VCL_RET_DISCARD (1 << 7) -#define VCL_RET_KEEP (1 << 8) -#define VCL_RET_RESTART (1 << 9) +#define VCL_RET_ERROR 0 +#define VCL_RET_LOOKUP 1 +#define VCL_RET_HASH 2 +#define VCL_RET_PIPE 3 +#define VCL_RET_PASS 4 +#define VCL_RET_FETCH 5 +#define VCL_RET_DELIVER 6 +#define VCL_RET_DISCARD 7 +#define VCL_RET_KEEP 8 +#define VCL_RET_RESTART 9 #define VCL_RET_MAX 10 Modified: trunk/varnish-cache/include/vcl_returns.h =================================================================== --- trunk/varnish-cache/include/vcl_returns.h 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/include/vcl_returns.h 2008-12-21 17:03:37 UTC (rev 3485) @@ -7,43 +7,72 @@ */ #ifdef VCL_RET_MAC -#ifdef VCL_RET_MAC_E -VCL_RET_MAC_E(error, ERROR, (1 << 0), 0) +VCL_RET_MAC(error, ERROR) +VCL_RET_MAC(lookup, LOOKUP) +VCL_RET_MAC(hash, HASH) +VCL_RET_MAC(pipe, PIPE) +VCL_RET_MAC(pass, PASS) +VCL_RET_MAC(fetch, FETCH) +VCL_RET_MAC(deliver, DELIVER) +VCL_RET_MAC(discard, DISCARD) +VCL_RET_MAC(keep, KEEP) +VCL_RET_MAC(restart, RESTART) #endif -VCL_RET_MAC(lookup, LOOKUP, (1 << 1), 1) -VCL_RET_MAC(hash, HASH, (1 << 2), 2) -VCL_RET_MAC(pipe, PIPE, (1 << 3), 3) -VCL_RET_MAC(pass, PASS, (1 << 4), 4) -VCL_RET_MAC(fetch, FETCH, (1 << 5), 5) -VCL_RET_MAC(deliver, DELIVER, (1 << 6), 6) -VCL_RET_MAC(discard, DISCARD, (1 << 7), 7) -VCL_RET_MAC(keep, KEEP, (1 << 8), 8) -VCL_RET_MAC(restart, RESTART, (1 << 9), 9) -#endif #ifdef VCL_MET_MAC VCL_MET_MAC(recv,RECV, - (VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_PIPE|VCL_RET_LOOKUP)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_PASS) + | (1 << VCL_RET_PIPE) + | (1 << VCL_RET_LOOKUP) +)) VCL_MET_MAC(pipe,PIPE, - (VCL_RET_ERROR|VCL_RET_PIPE)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_PIPE) +)) VCL_MET_MAC(pass,PASS, - (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_RESTART) + | (1 << VCL_RET_PASS) +)) VCL_MET_MAC(hash,HASH, - (VCL_RET_HASH)) + ((1 << VCL_RET_HASH) +)) VCL_MET_MAC(miss,MISS, - (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_FETCH)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_RESTART) + | (1 << VCL_RET_PASS) + | (1 << VCL_RET_FETCH) +)) VCL_MET_MAC(hit,HIT, - (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_RESTART) + | (1 << VCL_RET_PASS) + | (1 << VCL_RET_DELIVER) +)) VCL_MET_MAC(fetch,FETCH, - (VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) + ((1 << VCL_RET_ERROR) + | (1 << VCL_RET_RESTART) + | (1 << VCL_RET_PASS) + | (1 << VCL_RET_DELIVER) +)) VCL_MET_MAC(deliver,DELIVER, - (VCL_RET_RESTART|VCL_RET_DELIVER)) + ((1 << VCL_RET_RESTART) + | (1 << VCL_RET_DELIVER) +)) VCL_MET_MAC(prefetch,PREFETCH, - (VCL_RET_FETCH|VCL_RET_PASS)) + ((1 << VCL_RET_FETCH) + | (1 << VCL_RET_PASS) +)) VCL_MET_MAC(timeout,TIMEOUT, - (VCL_RET_FETCH|VCL_RET_DISCARD)) + ((1 << VCL_RET_FETCH) + | (1 << VCL_RET_DISCARD) +)) VCL_MET_MAC(discard,DISCARD, - (VCL_RET_DISCARD|VCL_RET_KEEP)) + ((1 << VCL_RET_DISCARD) + | (1 << VCL_RET_KEEP) +)) VCL_MET_MAC(error,ERROR, - (VCL_RET_DELIVER)) + ((1 << VCL_RET_DELIVER) +)) #endif Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/lib/libvcl/vcc_action.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -48,18 +48,16 @@ Expect(tl, ID); -#define VCL_RET_MAC(l, u, b, i) \ +#define VCL_RET_MAC(l, U) \ do { \ if (vcc_IdIs(tl->t, #l)) { \ - Fb(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #u); \ - vcc_ProcAction(tl->curproc, i, tl->t); \ + Fb(tl, 1, "VRT_done(sp, VCL_RET_" #U ");\n"); \ + vcc_ProcAction(tl->curproc, VCL_RET_##U, tl->t);\ retval = 1; \ } \ } while (0); -#define VCL_RET_MAC_E(l, u, b, i) VCL_RET_MAC(l, u, b, i) #include "vcl_returns.h" #undef VCL_RET_MAC -#undef VCL_RET_MAC_E if (!retval) { vsb_printf(tl->sb, "Expected action name.\n"); vcc_ErrWhere(tl, tl->t); @@ -85,8 +83,7 @@ ERRCHK(tl); } Fb(tl, 1, "VRT_done(sp, VCL_RET_RESTART);\n"); - assert(VCL_RET_RESTART == (1 << 9)); /* XXX: BANDAID FIXME! */ - vcc_ProcAction(tl->curproc, 9, tl->t); + vcc_ProcAction(tl->curproc, VCL_RET_RESTART, tl->t); vcc_NextToken(tl); } @@ -465,7 +462,7 @@ } action_table[] = { { "restart", parse_restart }, { "error", parse_error }, -#define VCL_RET_MAC(l, u, b, i) { #l, parse_action }, +#define VCL_RET_MAC(l, U) { #l, parse_action }, #include "vcl_returns.h" #undef VCL_RET_MAC Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -84,11 +84,9 @@ #include "libvarnish.h" struct method method_tab[] = { -#define VCL_RET_MAC(l,U,b,n) #define VCL_MET_MAC(l,U,m) { "vcl_"#l, m, VCL_MET_##U }, #include "vcl_returns.h" #undef VCL_MET_MAC -#undef VCL_RET_MAC { NULL, 0U, 0} }; @@ -360,12 +358,10 @@ Fc(tl, 0, "\t.srcname = srcname,\n"); Fc(tl, 0, "\t.srcbody = srcbody,\n"); Fc(tl, 0, "\t.nhashcount = %u,\n", tl->nhashcount); -#define VCL_RET_MAC(l,u,b,n) #define VCL_MET_MAC(l,u,b) \ Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); #include "vcl_returns.h" #undef VCL_MET_MAC -#undef VCL_RET_MAC Fc(tl, 0, "};\n"); } @@ -669,11 +665,8 @@ { switch (method) { - case 0: return (""); -#define VCL_RET_MAC(l, u, b, i) case b: return(#l); -#define VCL_RET_MAC_E(l, u, b, i) case b: return(#l); +#define VCL_RET_MAC(l, U) case VCL_RET_##U: return(#l); #include "vcl_returns.h" -#undef VCL_RET_MAC_E #undef VCL_RET_MAC } return (NULL); Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2008-12-21 17:03:37 UTC (rev 3485) @@ -142,7 +142,7 @@ struct method { const char *name; - unsigned returns; + unsigned ret_bitmap; unsigned bitval; }; Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -154,21 +154,11 @@ void vcl_output_lang_h(struct vsb *sb) { - vsb_cat(sb, "#define VCL_RET_ERROR (1 << 0)\n"); - vsb_cat(sb, "#define VCL_RET_LOOKUP (1 << 1)\n"); - vsb_cat(sb, "#define VCL_RET_HASH (1 << 2)\n"); - vsb_cat(sb, "#define VCL_RET_PIPE (1 << 3)\n"); - vsb_cat(sb, "#define VCL_RET_PASS (1 << 4)\n"); - vsb_cat(sb, "#define VCL_RET_FETCH (1 << 5)\n"); - vsb_cat(sb, "#define VCL_RET_DELIVER (1 << 6)\n"); - vsb_cat(sb, "#define VCL_RET_DISCARD (1 << 7)\n"); - vsb_cat(sb, "#define VCL_RET_KEEP (1 << 8)\n"); - vsb_cat(sb, "#define VCL_RET_RESTART (1 << 9)\n"); /* ../../include/vcl.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3482 2008-12-21 16"); - vsb_cat(sb, ":18:39Z phk $\n *\n * NB: This file is machine genera"); + vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3484 2008-12-21 17"); + vsb_cat(sb, ":01:58Z phk $\n *\n * NB: This file is machine genera"); vsb_cat(sb, "ted, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_t"); vsb_cat(sb, "oken.tcl instead\n */\n\nstruct sess;\n"); vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\n"); @@ -187,18 +177,14 @@ vsb_cat(sb, "#define VCL_MET_DISCARD\t\t(1 << 10)\n"); vsb_cat(sb, "#define VCL_MET_ERROR\t\t(1 << 11)\n"); vsb_cat(sb, "\n#define VCL_MET_MAX\t\t12\n\n"); - vsb_cat(sb, "/* VCL Returns */\n#define VCL_RET_ERROR\t\t(1 << 0)\n"); - vsb_cat(sb, "#define VCL_RET_LOOKUP\t\t(1 << 1)\n"); - vsb_cat(sb, "#define VCL_RET_HASH\t\t(1 << 2)\n"); - vsb_cat(sb, "#define VCL_RET_PIPE\t\t(1 << 3)\n"); - vsb_cat(sb, "#define VCL_RET_PASS\t\t(1 << 4)\n"); - vsb_cat(sb, "#define VCL_RET_FETCH\t\t(1 << 5)\n"); - vsb_cat(sb, "#define VCL_RET_DELIVER\t\t(1 << 6)\n"); - vsb_cat(sb, "#define VCL_RET_DISCARD\t\t(1 << 7)\n"); - vsb_cat(sb, "#define VCL_RET_KEEP\t\t(1 << 8)\n"); - vsb_cat(sb, "#define VCL_RET_RESTART\t\t(1 << 9)\n"); - vsb_cat(sb, "\n#define VCL_RET_MAX\t\t10\n\n"); - vsb_cat(sb, "struct VCL_conf {\n\tunsigned\tmagic;\n"); + vsb_cat(sb, "/* VCL Returns */\n#define VCL_RET_ERROR\t\t0\n"); + vsb_cat(sb, "#define VCL_RET_LOOKUP\t\t1\n#define VCL_RET_HASH\t\t2"); + vsb_cat(sb, "\n#define VCL_RET_PIPE\t\t3\n#define VCL_RET_PASS\t\t4"); + vsb_cat(sb, "\n#define VCL_RET_FETCH\t\t5\n#define VCL_RET_DELIVER\t"); + vsb_cat(sb, "\t6\n#define VCL_RET_DISCARD\t\t7\n"); + vsb_cat(sb, "#define VCL_RET_KEEP\t\t8\n#define VCL_RET_RESTART\t\t"); + vsb_cat(sb, "9\n\n#define VCL_RET_MAX\t\t10\n"); + vsb_cat(sb, "\nstruct VCL_conf {\n\tunsigned\tmagic;\n"); vsb_cat(sb, "#define VCL_CONF_MAGIC\t0x7406c509\t/* from /dev/rando"); vsb_cat(sb, "m */\n\n\tstruct director\t**director;\n"); vsb_cat(sb, "\tunsigned\tndirector;\n\tstruct vrt_ref\t*ref;\n"); Modified: trunk/varnish-cache/lib/libvcl/vcc_xref.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_xref.c 2008-12-21 17:01:58 UTC (rev 3484) +++ trunk/varnish-cache/lib/libvcl/vcc_xref.c 2008-12-21 17:03:37 UTC (rev 3485) @@ -68,7 +68,7 @@ VTAILQ_HEAD(,proccall) calls; VTAILQ_HEAD(,procuse) uses; struct token *name; - unsigned returns; + unsigned ret_bitmap; unsigned exists; unsigned called; unsigned active; @@ -242,14 +242,15 @@ vcc_ProcAction(struct proc *p, unsigned returns, struct token *t) { - p->returns |= (1U << returns); + assert(returns < VCL_RET_MAX); + p->ret_bitmap |= (1U << returns); /* Record the first instance of this return */ if (p->return_tok[returns] == NULL) p->return_tok[returns] = t; } static int -vcc_CheckActionRecurse(struct tokenlist *tl, struct proc *p, unsigned returns) +vcc_CheckActionRecurse(struct tokenlist *tl, struct proc *p, unsigned bitmap) { unsigned u; struct proccall *pc; @@ -264,13 +265,13 @@ vcc_ErrWhere(tl, p->name); return (1); } - u = p->returns & ~returns; + u = p->ret_bitmap & ~bitmap; if (u) { /*lint -save -e525 -e539 */ -#define VCL_RET_MAC(a, b, c, d) \ - if (u & VCL_RET_##b) { \ - vsb_printf(tl->sb, "Invalid return \"%s\"\n", #a); \ - vcc_ErrWhere(tl, p->return_tok[d]); \ +#define VCL_RET_MAC(l, U) \ + if (u & (1 << (VCL_RET_##U))) { \ + vsb_printf(tl->sb, "Invalid return \"" #l "\"\n");\ + vcc_ErrWhere(tl, p->return_tok[VCL_RET_##U]); \ } #include "vcl_returns.h" #undef VCL_RET_MAC @@ -281,7 +282,7 @@ } p->active = 1; VTAILQ_FOREACH(pc, &p->calls, list) { - if (vcc_CheckActionRecurse(tl, pc->p, returns)) { + if (vcc_CheckActionRecurse(tl, pc->p, bitmap)) { vsb_printf(tl->sb, "\n...called from \"%.*s\"\n", PF(p->name)); vcc_ErrWhere(tl, pc->t); @@ -305,19 +306,17 @@ if (i < 0) continue; m = method_tab + i; - if (vcc_CheckActionRecurse(tl, p, m->returns)) { + if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) { vsb_printf(tl->sb, "\n...which is the \"%s\" method\n", m->name); vsb_printf(tl->sb, "Legal returns are:"); -#define VCL_RET_MAC(a, b, c, d) \ - if (m->returns & c) \ - vsb_printf(tl->sb, " \"%s\"", #a); -#define VCL_RET_MAC_E(a, b, c, d) VCL_RET_MAC(a, b, c, d) +#define VCL_RET_MAC(l, U) \ + if (m->ret_bitmap & ((1 << VCL_RET_##U))) \ + vsb_printf(tl->sb, " \"%s\"", #l); /*lint -save -e525 -e539 */ #include "vcl_returns.h" /*lint +e525 */ #undef VCL_RET_MAC -#undef VCL_RET_MAC_E /*lint -restore */ vsb_printf(tl->sb, "\n"); return (1); From phk at projects.linpro.no Sun Dec 21 17:40:50 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 18:40:50 +0100 (CET) Subject: r3486 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221174050.BBCA51EC114@projects.linpro.no> Author: phk Date: 2008-12-21 18:40:50 +0100 (Sun, 21 Dec 2008) New Revision: 3486 Modified: trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/bin/varnishd/hash_critbit.c Log: Flexelint'ing Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 17:03:37 UTC (rev 3485) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 17:40:50 UTC (rev 3486) @@ -51,6 +51,7 @@ -emacro(736, isnan) // isnanf -efile(766, ../../config.h) -emacro(413, offsetof) // likely null pointer +-emacro(527, WRONG) // unreachable code -emacro(702, WEXITSTATUS) // signed shift right Modified: trunk/varnish-cache/bin/varnishd/hash_critbit.c =================================================================== --- trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-21 17:03:37 UTC (rev 3485) +++ trunk/varnish-cache/bin/varnishd/hash_critbit.c 2008-12-21 17:40:50 UTC (rev 3486) @@ -30,7 +30,7 @@ * A Crit Bit tree based hash */ -#define PHK 0 +#undef PHK #include "config.h" @@ -66,7 +66,8 @@ static void hcb_build_bittbl(void) { - unsigned x, y; + unsigned char x; + unsigned y; y = 0; for (x = 0; x < 8; x++) @@ -162,10 +163,11 @@ static unsigned hcb_crit_bit(const struct objhead *oh1, const struct objhead *oh2, struct hcb_y *y) { - unsigned u, r; + unsigned char u, r; for (u = 0; u < DIGEST_LEN && oh1->digest[u] == oh2->digest[u]; u++) ; + assert(u < DIGEST_LEN); r = hcb_bits(oh1->digest[u], oh2->digest[u]); y->ptr = u; y->bitmask = 0x80 >> r; @@ -260,7 +262,8 @@ assert(hcb_is_y(*p)); y = NULL; - while(hcb_is_y(*p)) { + while(1) { + assert(hcb_is_y(*p)); y = hcb_l_y(*p); if (y->ptr > DIGEST_LEN) s = 0; @@ -276,12 +279,10 @@ r->cmps++; p = &y->leaf[s]; } -abort(); - *p = y->leaf[1 - s]; } /**********************************************************************/ - +#ifdef PHK static void dumptree(uintptr_t p, int indent, FILE *fd) { @@ -293,9 +294,8 @@ return; if (hcb_is_node(p)) { oh = hcb_l_node(p); - fprintf(fd, "%*.*sN %u %u r%d <%02x%02x%02x...> <%s>\n", - indent, indent, "", DIGEST_LEN, indent / 2, - oh->refcnt, + fprintf(fd, "%*.*sN %d r%u <%02x%02x%02x...> <%s>\n", + indent, indent, "", indent / 2, oh->refcnt, oh->digest[0], oh->digest[1], oh->digest[2], oh->hash); return; @@ -316,8 +316,9 @@ fprintf(fd, "-------------\n"); dumptree(root->origo, 0, fd); fprintf(fd, "-------------\n"); - fflush(fd); + (void)fflush(fd); } +#endif /**********************************************************************/ @@ -333,7 +334,7 @@ THR_SetName("hcb_cleaner"); (void)priv; while (1) { - sleep(1); + (void)sleep(1); Lck_Lock(&hcb_mtx); VTAILQ_FOREACH_SAFE(oh, &laylow, coollist, oh2) { if (oh->hash != NULL) { @@ -345,8 +346,9 @@ continue; if (++oh->refcnt > COOL_DURATION) { VTAILQ_REMOVE(&laylow, oh, coollist); - if (PHK) - fprintf(stderr, "OH %p is cold enough\n", oh); +#ifdef PHK + fprintf(stderr, "OH %p is cold enough\n", oh); +#endif free(oh); VSL_stats->n_objecthead--; } @@ -387,10 +389,10 @@ Lck_Unlock(&hcb_mtx); } Lck_Unlock(&oh->mtx); - if (PHK) { - fprintf(stderr, "%s %d %d <%s>\n", __func__, __LINE__, r, oh->hash); - dump(&hcb_root, stderr); - } +#ifdef PHK + fprintf(stderr, "hcb_defef %d %d <%s>\n", __LINE__, r, oh->hash); + dump(&hcb_root, stderr); +#endif return (r); } @@ -425,19 +427,19 @@ oh = hcb_insert(&hcb_root, noh, 1); if (oh == noh) { VSL_stats->hcb_insert++; - if (PHK) { - fprintf(stderr, "%s %d\n", __func__, __LINE__); - dump(&hcb_root, stderr); - } +#ifdef PHK + fprintf(stderr, "hcb_lookup %d\n", __LINE__); + dump(&hcb_root, stderr); +#endif } else { free(noh->hash); noh->hash = NULL; noh->hashlen = 0; VSL_stats->hcb_lock++; - if (PHK) { - fprintf(stderr, "%s %d\n", __func__, __LINE__); - dump(&hcb_root, stderr); - } +#ifdef PHK + fprintf(stderr, "hcb_lookup %d\n", __LINE__); + dump(&hcb_root, stderr); +#endif } Lck_Unlock(&hcb_mtx); return (oh); From phk at projects.linpro.no Sun Dec 21 17:46:52 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 18:46:52 +0100 (CET) Subject: r3487 - in trunk/varnish-cache: bin/varnishd lib/libvcl Message-ID: <20081221174652.1E2EC1EC213@projects.linpro.no> Author: phk Date: 2008-12-21 18:46:51 +0100 (Sun, 21 Dec 2008) New Revision: 3487 Modified: trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/lib/libvcl/vcc_compile.c Log: More flexelinting. Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 17:40:50 UTC (rev 3486) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 17:46:51 UTC (rev 3487) @@ -40,7 +40,7 @@ -esym(458, heritage) -esym(458, name_key) ////////////// --passes=1 +-passes=3 +libh mgt_event.h +libh ../../config.h @@ -54,6 +54,7 @@ -emacro(527, WRONG) // unreachable code -emacro(702, WEXITSTATUS) // signed shift right +-efunc(525, VCC_Return_Name) // Negative indent // -header(../../config.h) Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c =================================================================== --- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 17:40:50 UTC (rev 3486) +++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2008-12-21 17:46:51 UTC (rev 3487) @@ -668,8 +668,9 @@ #define VCL_RET_MAC(l, U) case VCL_RET_##U: return(#l); #include "vcl_returns.h" #undef VCL_RET_MAC + default: + return (NULL); } - return (NULL); } /*-------------------------------------------------------------------- From phk at projects.linpro.no Sun Dec 21 18:33:31 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:33:31 +0100 (CET) Subject: r3488 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183331.028AF1EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 19:33:30 +0100 (Sun, 21 Dec 2008) New Revision: 3488 Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c Log: Assert fcntl(2) have not failed. Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c 2008-12-21 17:46:51 UTC (rev 3487) +++ trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c 2008-12-21 18:33:30 UTC (rev 3488) @@ -209,8 +209,10 @@ int i; i = fcntl(vca_pipes[0], F_GETFL); + assert(i != -1); i |= O_NONBLOCK; i = fcntl(vca_pipes[0], F_SETFL, i); + assert(i != -1); AZ(pthread_create(&vca_kqueue_thread, NULL, vca_kqueue_main, NULL)); } From phk at projects.linpro.no Sun Dec 21 18:33:44 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:33:44 +0100 (CET) Subject: r3489 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183344.8F9841EC114@projects.linpro.no> Author: phk Date: 2008-12-21 19:33:44 +0100 (Sun, 21 Dec 2008) New Revision: 3489 Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c Log: remove pointless assignment Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2008-12-21 18:33:30 UTC (rev 3488) +++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c 2008-12-21 18:33:44 UTC (rev 3489) @@ -75,7 +75,6 @@ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_RANDOM_MAGIC); - k = 0; for (k = 0; k < vs->retries; ) { /* Sum up the weights of healty backends */ From phk at projects.linpro.no Sun Dec 21 18:34:02 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:34:02 +0100 (CET) Subject: r3490 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183402.A9D561EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 19:34:02 +0100 (Sun, 21 Dec 2008) New Revision: 3490 Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c Log: Assert that realloc() did. Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-21 18:33:44 UTC (rev 3489) +++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2008-12-21 18:34:02 UTC (rev 3490) @@ -908,6 +908,7 @@ n++; } parspec = realloc(parspec, (nparspec + n + 1) * sizeof *parspec); + XXXAN(parspec); for (pp = ps; pp->name != NULL; pp++) parspec[nparspec++] = pp; parspec[nparspec] = NULL; From phk at projects.linpro.no Sun Dec 21 18:34:39 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:34:39 +0100 (CET) Subject: r3491 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183439.4E9241EC114@projects.linpro.no> Author: phk Date: 2008-12-21 19:34:39 +0100 (Sun, 21 Dec 2008) New Revision: 3491 Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c Log: Check close(2) status. Assert that we read the C-source file. Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2008-12-21 18:34:02 UTC (rev 3490) +++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c 2008-12-21 18:34:39 UTC (rev 3491) @@ -174,7 +174,7 @@ fprintf(stderr, "Cannot write %s", vp->sf); exit (1); } - close(fd); + AZ(close(fd)); free(csrc); exit (0); } @@ -213,6 +213,7 @@ if (C_flag) { csrc = vreadfile(sf); + XXXAN(csrc); (void)fputs(csrc, stdout); free(csrc); } From phk at projects.linpro.no Sun Dec 21 18:35:24 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:35:24 +0100 (CET) Subject: r3492 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183524.E91651EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 19:35:24 +0100 (Sun, 21 Dec 2008) New Revision: 3492 Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c Log: Be more stringent about our timeout: fail even if we did get a socket, but took to. Modified: trunk/varnish-cache/bin/varnishd/cache_backend_poll.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2008-12-21 18:34:39 UTC (rev 3491) +++ trunk/varnish-cache/bin/varnishd/cache_backend_poll.c 2008-12-21 18:35:24 UTC (rev 3492) @@ -157,6 +157,11 @@ /* Got no connection: failed */ return; } + if (tmo <= 0) { + /* Spent too long time getting it */ + TCP_close(&s); + return; + } /* Send the request */ i = write(s, vt->req, vt->req_len); From phk at projects.linpro.no Sun Dec 21 18:35:48 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:35:48 +0100 (CET) Subject: r3493 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221183548.1EE811EC213@projects.linpro.no> Author: phk Date: 2008-12-21 19:35:47 +0100 (Sun, 21 Dec 2008) New Revision: 3493 Modified: trunk/varnish-cache/bin/varnishd/cache_session.c Log: Remove pointless initialization. Fix indentation. Modified: trunk/varnish-cache/bin/varnishd/cache_session.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_session.c 2008-12-21 18:35:24 UTC (rev 3492) +++ trunk/varnish-cache/bin/varnishd/cache_session.c 2008-12-21 18:35:47 UTC (rev 3493) @@ -382,7 +382,7 @@ void SES_InheritBackendTimeouts(struct sess *sp) { - struct backend *be = NULL; + struct backend *be; AN(sp); AN(sp->vbe); @@ -395,13 +395,12 @@ * is parameter < backend definition < VCL. */ if (be->connect_timeout > 1e-3 && - sp->connect_timeout == params->connect_timeout) + sp->connect_timeout == params->connect_timeout) sp->connect_timeout = be->connect_timeout; if (be->first_byte_timeout > 1e-3 && - sp->first_byte_timeout == params->first_byte_timeout) + sp->first_byte_timeout == params->first_byte_timeout) sp->first_byte_timeout = be->first_byte_timeout; - if (be->between_bytes_timeout > 1e-3 - && sp->between_bytes_timeout == params->between_bytes_timeout) + if (be->between_bytes_timeout > 1e-3 && + sp->between_bytes_timeout == params->between_bytes_timeout) sp->between_bytes_timeout = be->between_bytes_timeout; } - From phk at projects.linpro.no Sun Dec 21 18:40:10 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:40:10 +0100 (CET) Subject: r3494 - trunk/varnish-cache/lib/libvarnish Message-ID: <20081221184010.B1D251EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 19:40:10 +0100 (Sun, 21 Dec 2008) New Revision: 3494 Modified: trunk/varnish-cache/lib/libvarnish/cli_common.c Log: Set the status to CLIS_COMMS if we fal to read the body. Modified: trunk/varnish-cache/lib/libvarnish/cli_common.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/cli_common.c 2008-12-21 18:35:47 UTC (rev 3493) +++ trunk/varnish-cache/lib/libvarnish/cli_common.c 2008-12-21 18:40:10 UTC (rev 3494) @@ -123,7 +123,7 @@ if (cli != NULL) cli->result = res; /*lint !e64 type mismatch */ else - printf("CLI result = %d\n", res); + printf("CLI result = %u\n", res); } void @@ -192,15 +192,16 @@ { char res[CLI_LINE0_LEN]; /* For NUL */ int i, j; - unsigned u, v; + unsigned u, v, s; char *p; + if (status == NULL) + status = &s; if (ptr != NULL) *ptr = NULL; i = read_tmo(fd, res, CLI_LINE0_LEN, tmo); if (i != CLI_LINE0_LEN) { - if (status != NULL) - *status = CLIS_COMMS; + *status = CLIS_COMMS; if (ptr != NULL) *ptr = strdup("CLI communication error"); return (1); @@ -211,12 +212,12 @@ res[CLI_LINE0_LEN - 1] = '\0'; j = sscanf(res, "%u %u\n", &u, &v); assert(j == 2); - if (status != NULL) - *status = u; + *status = u; p = malloc(v + 1); assert(p != NULL); i = read_tmo(fd, p, v + 1, tmo); if (i < 0) { + *status = CLIS_COMMS; free(p); return (i); } From phk at projects.linpro.no Sun Dec 21 18:40:35 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:40:35 +0100 (CET) Subject: r3495 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221184035.5EE291EC213@projects.linpro.no> Author: phk Date: 2008-12-21 19:40:35 +0100 (Sun, 21 Dec 2008) New Revision: 3495 Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c Log: Properly ignore the return value from cli_readres(), we get it in status. Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c =================================================================== --- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-12-21 18:40:10 UTC (rev 3494) +++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-12-21 18:40:35 UTC (rev 3495) @@ -189,7 +189,7 @@ return (CLIS_COMMS); } - i = cli_readres(cli_i, &u, resp, params->cli_timeout); + (void)cli_readres(cli_i, &u, resp, params->cli_timeout); if (status != NULL) *status = u; return (u == CLIS_OK ? 0 : u); @@ -270,7 +270,7 @@ xxxassert(i == strlen(p)); i = write(cli_o, "\n", 1); xxxassert(i == 1); - i = cli_readres(cli_i, &u, &q, params->cli_timeout); + (void)cli_readres(cli_i, &u, &q, params->cli_timeout); cli_result(cp->cli, u); cli_out(cp->cli, "%s", q); free(q); From phk at projects.linpro.no Sun Dec 21 18:41:43 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:41:43 +0100 (CET) Subject: r3496 - in trunk/varnish-cache: bin/varnishd lib/libvarnish Message-ID: <20081221184143.B4AFC1EC1E7@projects.linpro.no> Author: phk Date: 2008-12-21 19:41:43 +0100 (Sun, 21 Dec 2008) New Revision: 3496 Modified: trunk/varnish-cache/bin/varnishd/flint.lnt trunk/varnish-cache/lib/libvarnish/vsb.c Log: Make vsb_new() a tad easier for FlexeLint to figure out. Give it proper semantics Modified: trunk/varnish-cache/bin/varnishd/flint.lnt =================================================================== --- trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 18:40:35 UTC (rev 3495) +++ trunk/varnish-cache/bin/varnishd/flint.lnt 2008-12-21 18:41:43 UTC (rev 3496) @@ -56,13 +56,12 @@ -emacro(702, WEXITSTATUS) // signed shift right -efunc(525, VCC_Return_Name) // Negative indent - // -header(../../config.h) // Fix strchr() semtics, it can only return NULL if arg2 != 0 -sem(strchr, 1p, type(1), 2n == 0 ? (@p < 1p) : (@p < 1p || @p == 0 )) --sem(vsb_new, @p == malloc(1)) +-sem(vsb_new, @p == (1p ? 1p : malloc(1))) -sem(vsb_delete, custodial(1)) -sem(lbv_assert, r_no) -sem(lbv_xxxassert, r_no) Modified: trunk/varnish-cache/lib/libvarnish/vsb.c =================================================================== --- trunk/varnish-cache/lib/libvarnish/vsb.c 2008-12-21 18:40:35 UTC (rev 3495) +++ trunk/varnish-cache/lib/libvarnish/vsb.c 2008-12-21 18:41:43 UTC (rev 3496) @@ -162,15 +162,17 @@ s = (struct vsb *)SBMALLOC(sizeof *s); if (s == NULL) return (NULL); - memset(s, 0, sizeof *s); - s->s_flags = flags; - s->s_magic = VSB_MAGIC; + if (vsb_new(s, buf, length, flags) == NULL) { + free(s); + return (NULL); + } VSB_SETFLAG(s, VSB_DYNSTRUCT); - } else { - memset(s, 0, sizeof *s); - s->s_flags = flags; - s->s_magic = VSB_MAGIC; + return (s); } + + memset(s, 0, sizeof *s); + s->s_flags = flags; + s->s_magic = VSB_MAGIC; s->s_size = length; if (buf) { s->s_buf = buf; @@ -179,11 +181,8 @@ if (flags & VSB_AUTOEXTEND) s->s_size = vsb_extendsize(s->s_size); s->s_buf = (char *)SBMALLOC(s->s_size); - if (s->s_buf == NULL) { - if (VSB_ISDYNSTRUCT(s)) - SBFREE(s); + if (s->s_buf == NULL) return (NULL); - } VSB_SETFLAG(s, VSB_DYNAMIC); return (s); } From phk at projects.linpro.no Sun Dec 21 18:42:48 2008 From: phk at projects.linpro.no (phk at projects.linpro.no) Date: Sun, 21 Dec 2008 19:42:48 +0100 (CET) Subject: r3497 - trunk/varnish-cache/bin/varnishd Message-ID: <20081221184248.572B31EC213@projects.linpro.no> Author: phk Date: 2008-12-21 19:42:48 +0100 (Sun, 21 Dec 2008) New Revision: 3497 Modified: trunk/varnish-cache/bin/varnishd/cache_center.c trunk/varnish-cache/bin/varnishd/varnishd.c Log: Minor polishing for the benefit of Glorius Checker of Code FlexeLint. Modified: trunk/varnish-cache/bin/varnishd/cache_center.c =================================================================== --- trunk/varnish-cache/bin/varnishd/cache_center.c 2008-12-21 18:41:43 UTC (rev 3496) +++ trunk/varnish-cache/bin/varnishd/cache_center.c 2008-12-21 18:42:48 UTC (rev 3497) @@ -298,7 +298,6 @@ { struct worker *w; struct http *h; - time_t now; char date[40]; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -322,8 +321,7 @@ http_PutProtocol(w, sp->fd, h, "HTTP/1.1"); http_PutStatus(w, sp->fd, h, sp->err_code); - now = TIM_real(); - TIM_format(now, date); + TIM_format(TIM_real(), date); http_PrintfHeader(w, sp->fd, h, "Date: %s", date); http_PrintfHeader(w, sp->fd, h, "Server: Varnish"); http_PrintfHeader(w, sp->fd, h, "Retry-After: %d", params->err_ttl); @@ -537,7 +535,6 @@ return (0); default: WRONG("Illegal action in vcl_hit{}"); - return (0); } } @@ -671,10 +668,8 @@ return (0); case VCL_RET_RESTART: INCOMPL(); - return (0); default: WRONG("Illegal action in vcl_miss{}"); - return (0); } } @@ -849,7 +844,6 @@ return (0); default: WRONG("Illegal action in vcl_recv{}"); - return (0); } } @@ -1025,11 +1019,15 @@ cli_out(cli, "XID is %u", xids); } +/* + * Default to seed=1, this is the only seed value POSIXl guarantees will + * result in a reproducible random number sequence. + */ static void cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) { (void)priv; - unsigned long seed; + unsigned seed = 1; if (av[2] != NULL) seed = strtoul(av[2], NULL, 0); Modified: trunk/varnish-cache/bin/varnishd/varnishd.c =================================================================== --- trunk/varnish-cache/bin/varnishd/varnishd.c 2008-12-21 18:41:43 UTC (rev 3496) +++ trunk/varnish-cache/bin/varnishd/varnishd.c 2008-12-21 18:42:48 UTC (rev 3497) @@ -543,7 +543,7 @@ argv += optind; if (argc != 0) { - fprintf(stderr, "Too many arguments\n"); + fprintf(stderr, "Too many arguments (%s...)\n", argv[0]); usage(); }