From phk at varnish-cache.org Sat Oct 1 01:12:37 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 01 Oct 2011 03:12:37 +0200 Subject: [master] 6d50fb2 Try harder to fix solaris IOV_MAX related issue. Message-ID: commit 6d50fb287fda1826020bef4e0256d83d35c68d83 Author: Poul-Henning Kamp Date: Sat Oct 1 01:12:19 2011 +0000 Try harder to fix solaris IOV_MAX related issue. diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c index 946f488..61aa2e5 100644 --- a/bin/varnishd/cache_wrw.c +++ b/bin/varnishd/cache_wrw.c @@ -179,14 +179,16 @@ WRW_Write(struct worker *w, const void *ptr, int len) return (0); if (len == -1) len = strlen(ptr); - if (wrw->niov == wrw->siov + (wrw->ciov < wrw->siov ? 1 : 0)) + if (wrw->niov >= wrw->siov - (wrw->ciov < wrw->siov ? 1 : 0)) (void)WRW_Flush(w); wrw->iov[wrw->niov].iov_base = TRUST_ME(ptr); wrw->iov[wrw->niov].iov_len = len; wrw->liov += len; - if (wrw->ciov < wrw->siov) - wrw->cliov += len; wrw->niov++; + if (wrw->ciov < wrw->siov) { + assert(wrw->niov < wrw->siov); + wrw->cliov += len; + } return (len); } @@ -208,6 +210,7 @@ WRW_Chunked(struct worker *w) wrw->ciov = wrw->niov++; wrw->cliov = 0; assert(wrw->ciov < wrw->siov); + assert(wrw->niov < wrw->siov); } /* From perbu at varnish-cache.org Mon Oct 3 07:49:19 2011 From: perbu at varnish-cache.org (Per Buer) Date: Mon, 03 Oct 2011 09:49:19 +0200 Subject: [master] c69d4ca Described some of the counters based on notes in the wiki. Please let me know if any of them are way off Message-ID: commit c69d4ca9cf583c8313ae1b92f27624ceccd7eda5 Author: Per Buer Date: Mon Oct 3 09:49:09 2011 +0200 Described some of the counters based on notes in the wiki. Please let me know if any of them are way off diff --git a/include/vsc_fields.h b/include/vsc_fields.h index ea668cc..0fd7e46 100644 --- a/include/vsc_fields.h +++ b/include/vsc_fields.h @@ -81,19 +81,53 @@ VSC_F(sess_fail, uint64_t, 1, 'c', /*---------------------------------------------------------------------*/ -VSC_F(client_req, uint64_t, 1, 'a', "Client requests received", "") - -VSC_F(cache_hit, uint64_t, 1, 'a', "Cache hits", "") -VSC_F(cache_hitpass, uint64_t, 1, 'a', "Cache hits for pass", "") -VSC_F(cache_miss, uint64_t, 1, 'a', "Cache misses", "") +VSC_F(client_req, uint64_t, 1, 'a', + "Client requests received", + "") + +VSC_F(cache_hit, uint64_t, 1, 'a', + "Cache hits", + "Count of cache hits. " + " A cache hit indicates that an object has been delivered to a" + " client without fetching it from a backend server." +) -VSC_F(backend_conn, uint64_t, 0, 'a', "Backend conn. success", "") -VSC_F(backend_unhealthy, uint64_t, 0, 'a', "Backend conn. not attempted", "") +VSC_F(cache_hitpass, uint64_t, 1, 'a', + "Cache hits for pass", + "Count of hits for pass" + " A cache hit for pass indicates that Varnish is going to" + " pass the request to the backend and this decision has been " + " cached in it self. This counts how many times the cached " + " decision is being used." +) +VSC_F(cache_miss, uint64_t, 1, 'a', + "Cache misses", + "Count of misses" + " A cache miss indicates the object was fetched from the" + " backend before delivering it to the backend.") + +VSC_F(backend_conn, uint64_t, 0, 'a', + "Backend conn. success", + "") + +VSC_F(backend_unhealthy, uint64_t, 0, 'a', + "Backend conn. not attempted", + "" +) VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many", "") VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures", "") -VSC_F(backend_reuse, uint64_t, 0, 'a', "Backend conn. reuses", "") +VSC_F(backend_reuse, uint64_t, 0, 'a', + "Backend conn. reuses", + "Count of backend connection reuses" + " This counter is increased whenever we reuse a recycled connection.") VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed", "") -VSC_F(backend_recycle, uint64_t, 0, 'a', "Backend conn. recycles", "") +VSC_F(backend_recycle, uint64_t, 0, 'a', + "Backend conn. recycles", + "Count of backend connection recycles" + " This counter is increased whenever we have a keep-alive" + " connection that is put back into the pool of connections." + " It has not yet been used, but it might be, unless the backend" + " closes it.") VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry", "") VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head", "") @@ -221,8 +255,13 @@ VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects", "") VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows", "") -VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile", "") -VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write", "") +VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile", + "The number of objects sent with the sendfile system call. If enabled " + "sendfile will be used on object larger than a certain size.") +VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write", + "The number of objects sent with regular write calls." + "Writes are used when the objects are too small for sendfile " + "or if the sendfile call has been disabled") VSC_F(n_objoverflow, uint64_t, 1, 'a', "Objects overflowing workspace", "") From tfheen at varnish-cache.org Mon Oct 3 10:11:04 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 03 Oct 2011 12:11:04 +0200 Subject: [master] b4fee20 Bump minimum number of threads for RPMs Message-ID: commit b4fee2036e2befab57e417bb2c832b55fca7207c Author: Tollef Fog Heen Date: Mon Oct 3 11:15:19 2011 +0200 Bump minimum number of threads for RPMs 1 thread is a bit on the low side, make the default on RPM based distros 50. diff --git a/redhat/varnish.sysconfig b/redhat/varnish.sysconfig index 8ab3c22..d88712f 100644 --- a/redhat/varnish.sysconfig +++ b/redhat/varnish.sysconfig @@ -70,7 +70,7 @@ VARNISH_ADMIN_LISTEN_PORT=6082 VARNISH_SECRET_FILE=/etc/varnish/secret # # # The minimum number of worker threads to start -VARNISH_MIN_THREADS=1 +VARNISH_MIN_THREADS=50 # # # The Maximum number of worker threads to start VARNISH_MAX_THREADS=1000 From tfheen at varnish-cache.org Mon Oct 3 12:37:56 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 03 Oct 2011 14:37:56 +0200 Subject: [master] 04b017e Drop debugging message about which host/port we have connected to Message-ID: commit 04b017efb938826b06aef08b8c1bd592755806a3 Author: Tollef Fog Heen Date: Mon Oct 3 14:37:11 2011 +0200 Drop debugging message about which host/port we have connected to Fixes: #1024 diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index 151a437..68ebbf7 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -135,7 +135,6 @@ cli_sock(const char *T_arg, const char *S_arg) } free(answer); - fprintf(stderr, "CLI connected to %s\n", T_arg); return (sock); } From apj at varnish-cache.org Wed Oct 5 16:58:07 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Wed, 05 Oct 2011 18:58:07 +0200 Subject: [master] e574fbc Fix docs for req.esi Message-ID: commit e574fbcf96ef5e6668c439fb4527e0752041c088 Author: Andreas Plesner Jacobsen Date: Wed Oct 5 18:57:49 2011 +0200 Fix docs for req.esi diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 9fd526c..aaca549 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -740,7 +740,9 @@ req.restarts A count of how many times this request has been restarted. req.esi - True if the request is an ESI request. + Boolean. Set to false to disable ESI processing regardless of any + value in beresp.do_esi. Defaults to true. This variable is subject + to change in future versions, you should avoid using it. req.esi_level A count of how many levels of ESI requests we're currently at. @@ -788,8 +790,9 @@ beresp.do_stream as it is delivered so only client can access the object. beresp.do_esi - Boolean. ESI-process the object after fetching it. Defaults to false. Set it - to true to parse the object for ESI directives. + Boolean. ESI-process the object after fetching it. Defaults to + false. Set it to true to parse the object for ESI directives. Will + only be honored if req.esi is true. beresp.do_gzip Boolean. Gzip the object before storing it. Defaults to false. From phk at varnish-cache.org Thu Oct 6 08:43:41 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 06 Oct 2011 10:43:41 +0200 Subject: [master] 6cd21b2 Sense of exit-code test was wrong. Message-ID: commit 6cd21b29d6670d18ff03cb6e377bf9b70bb0929b Author: Poul-Henning Kamp Date: Thu Oct 6 08:43:22 2011 +0000 Sense of exit-code test was wrong. diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 4181a43..81e1c8d 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -478,7 +478,7 @@ mgt_sigchld(const struct vev *e, int what) vsb = VSB_new_auto(); XXXAN(vsb); VSB_printf(vsb, "Child (%d) %s", r, status ? "died" : "ended"); - if (!WIFEXITED(status) && WEXITSTATUS(status)) { + if (WIFEXITED(status) && WEXITSTATUS(status)) { VSB_printf(vsb, " status=%d", WEXITSTATUS(status)); exit_status |= 0x20; } From phk at varnish-cache.org Thu Oct 6 09:02:51 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 06 Oct 2011 11:02:51 +0200 Subject: [master] 91280b2 Add a "wait-running" primitive to varnish instances, so we can avoid fixed sleeps waiting for the child process to start. Message-ID: commit 91280b2a21406f7553d4d26fdae23ab9e61c1da4 Author: Poul-Henning Kamp Date: Thu Oct 6 09:02:18 2011 +0000 Add a "wait-running" primitive to varnish instances, so we can avoid fixed sleeps waiting for the child process to start. diff --git a/bin/varnishtest/tests/v00010.vtc b/bin/varnishtest/tests/v00010.vtc index ec7b947..0421956 100644 --- a/bin/varnishtest/tests/v00010.vtc +++ b/bin/varnishtest/tests/v00010.vtc @@ -5,6 +5,8 @@ server s1 { txresp -hdr "Foo: bar" -body "abcdef\n" rxreq txresp -hdr "Panic: please" -body "012345\n" + close + sema r1 sync 2 accept rxreq @@ -33,10 +35,10 @@ client c1 { rxresp txreq -url "/foo" # Don't expect answer, the server crashed. - sema r1 sync 2 } -run -delay 2.5 +varnish v1 -wait-running +sema r1 sync 2 client c1 { txreq -url "/" diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 5ef4beb..9ba34a7 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -120,6 +120,30 @@ varnish_ask_cli(const struct varnish *v, const char *cmd, char **repl) } /********************************************************************** + * + */ + +static void +wait_running(const struct varnish *v) +{ + char *r; + enum VCLI_status_e st; + + while (1) { + st = varnish_ask_cli(v, "status", &r); + if (st != CLIS_OK) + vtc_log(v->vl, 0, + "CLI status command failed: %u %s", st, r); + if (!strcmp(r, "Child in state running")) { + free(r); + break; + } + free(r); + (void)usleep(200000); + } +} + +/********************************************************************** * Varnishlog gatherer + thread */ @@ -439,6 +463,7 @@ varnish_start(struct varnish *v) return; if (u != CLIS_OK) vtc_log(v->vl, 0, "CLI start command failed: %u %s", u, resp); + wait_running(v); free(resp); u = varnish_ask_cli(v, "debug.xid 1000", &resp); if (vtc_error) @@ -823,6 +848,10 @@ cmd_varnish(CMD_ARGS) varnish_stop(v); continue; } + if (!strcmp(*av, "-wait-running")) { + wait_running(v); + continue; + } if (!strcmp(*av, "-wait")) { varnish_wait(v); continue; From tfheen at varnish-cache.org Thu Oct 6 09:25:20 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:20 +0200 Subject: [3.0] 03c7a14 Add a "long description field" to the VSC_F() macro Message-ID: commit 03c7a146f6326bc65b2e3b675ea3cb0d7a1c5718 Author: Poul-Henning Kamp Date: Sun Sep 18 07:39:30 2011 +0000 Add a "long description field" to the VSC_F() macro The intent is that they should be mined and dumped into the documentation. Feel free to add (or send patches with descriptions, preferably only one line or paragraph for each. Conflicts: bin/varnishd/cache_wrk.c include/vsc_fields.h diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index e2faf30..3d6982d 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -219,7 +219,7 @@ struct acct { #define L0(n) #define L1(n) uint64_t n; -#define VSC_F(n, t, l, f, e) L##l(n) +#define VSC_F(n, t, l, f, e,d) L##l(n) #define VSC_DO_MAIN struct dstat { #include "vsc_fields.h" diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 0875e07..1260bd0 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -94,7 +94,7 @@ wrk_sumstat(struct worker *w) #define L0(n) #define L1(n) (VSC_C_main->n += w->stats.n) #define VSC_DO_MAIN -#define VSC_F(n, t, l, f, d) L##l(n); +#define VSC_F(n, t, l, f, d, e) L##l(n); #include "vsc_fields.h" #undef VSC_F #undef VSC_DO_MAIN diff --git a/include/vsc.h b/include/vsc.h index 1256dae..7cb3235 100644 --- a/include/vsc.h +++ b/include/vsc.h @@ -38,7 +38,7 @@ #define VSC_TYPE_VBE "VBE" #define VSC_TYPE_LCK "LCK" -#define VSC_F(n, t, l, f, e) t n; +#define VSC_F(n, t, l, f, e, d) t n; #define VSC_DO(u,l,t) struct VSC_C_##l { #define VSC_DONE(u,l,t) }; diff --git a/include/vsc_fields.h b/include/vsc_fields.h index c35acec..4b142d2 100644 --- a/include/vsc_fields.h +++ b/include/vsc_fields.h @@ -20,7 +20,7 @@ * 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) + * 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 @@ -33,134 +33,138 @@ * XXX: turned into a major mess, causing trouble already for backends. * XXX: * XXX: Please converge on: - * XXX: c_* counter (total bytes ever allocated from sma) - * XXX: g_* gauge (presently allocated bytes from sma) + * XXX: c_* counter (total bytes ever allocated from sma, "") + * XXX: g_* gauge (presently allocated bytes from sma, "") */ /**********************************************************************/ #ifdef VSC_DO_MAIN -VSC_F(client_conn, uint64_t, 0, 'a', "Client connections accepted") +VSC_F(client_conn, uint64_t, 1, 'a', "Client connections accepted", "") VSC_F(client_drop, uint64_t, 0, 'a', - "Connection dropped, no sess/wrk") -VSC_F(client_req, uint64_t, 1, 'a', "Client requests received") - -VSC_F(cache_hit, uint64_t, 1, 'a', "Cache hits") -VSC_F(cache_hitpass, uint64_t, 1, 'a', "Cache hits for pass") -VSC_F(cache_miss, uint64_t, 1, 'a', "Cache misses") - -VSC_F(backend_conn, uint64_t, 0, 'a', "Backend conn. success") -VSC_F(backend_unhealthy, uint64_t, 0, 'a', "Backend conn. not attempted") -VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many") -VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures") -VSC_F(backend_reuse, uint64_t, 0, 'a', "Backend conn. reuses") -VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed") -VSC_F(backend_recycle, uint64_t, 0, 'a', "Backend conn. recycles") -VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry") - -VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head") -VSC_F(fetch_length, uint64_t, 1, 'a', "Fetch with Length") -VSC_F(fetch_chunked, uint64_t, 1, 'a', "Fetch chunked") -VSC_F(fetch_eof, uint64_t, 1, 'a', "Fetch EOF") -VSC_F(fetch_bad, uint64_t, 1, 'a', "Fetch had bad headers") -VSC_F(fetch_close, uint64_t, 1, 'a', "Fetch wanted close") -VSC_F(fetch_oldhttp, uint64_t, 1, 'a', "Fetch pre HTTP/1.1 closed") -VSC_F(fetch_zero, uint64_t, 1, 'a', "Fetch zero len") -VSC_F(fetch_failed, uint64_t, 1, 'a', "Fetch failed") -VSC_F(fetch_1xx, uint64_t, 1, 'a', "Fetch no body (1xx)") -VSC_F(fetch_204, uint64_t, 1, 'a', "Fetch no body (204)") -VSC_F(fetch_304, uint64_t, 1, 'a', "Fetch no body (304)") - - -VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem") -VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess") -VSC_F(n_object, uint64_t, 1, 'i', "N struct object") -VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects") -VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore") -VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead") -VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist") - -VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc") -VSC_F(n_wrk, uint64_t, 0, 'i', "N worker threads") -VSC_F(n_wrk_create, uint64_t, 0, 'a', "N worker threads created") + "Connection dropped, no sess/wrk", "") +VSC_F(client_req, uint64_t, 1, 'a', "Client requests received", "") + +VSC_F(cache_hit, uint64_t, 1, 'a', "Cache hits", "") +VSC_F(cache_hitpass, uint64_t, 1, 'a', "Cache hits for pass", "") +VSC_F(cache_miss, uint64_t, 1, 'a', "Cache misses", "") + +VSC_F(backend_conn, uint64_t, 0, 'a', "Backend conn. success", "") +VSC_F(backend_unhealthy, uint64_t, 0, 'a', "Backend conn. not attempted", "") +VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many", "") +VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures", "") +VSC_F(backend_reuse, uint64_t, 0, 'a', "Backend conn. reuses", "") +VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed", "") +VSC_F(backend_recycle, uint64_t, 0, 'a', "Backend conn. recycles", "") +VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry", "") + +VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head", "") +VSC_F(fetch_length, uint64_t, 1, 'a', "Fetch with Length", "") +VSC_F(fetch_chunked, uint64_t, 1, 'a', "Fetch chunked", "") +VSC_F(fetch_eof, uint64_t, 1, 'a', "Fetch EOF", "") +VSC_F(fetch_bad, uint64_t, 1, 'a', "Fetch had bad headers", "") +VSC_F(fetch_close, uint64_t, 1, 'a', "Fetch wanted close", "") +VSC_F(fetch_oldhttp, uint64_t, 1, 'a', "Fetch pre HTTP/1.1 closed", "") +VSC_F(fetch_zero, uint64_t, 1, 'a', "Fetch zero len", "") +VSC_F(fetch_failed, uint64_t, 1, 'a', "Fetch failed", "") +VSC_F(fetch_1xx, uint64_t, 1, 'a', "Fetch no body (1xx)", "") +VSC_F(fetch_204, uint64_t, 1, 'a', "Fetch no body (204)", "") +VSC_F(fetch_304, uint64_t, 1, 'a', "Fetch no body (304)", "") + +/*--------------------------------------------------------------------- + * Session Memory + * see: cache_session.c + */ + +VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem", "") +VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess", "") +VSC_F(n_object, uint64_t, 1, 'i', "N struct object", "") +VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects", "") +VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore", "") +VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead", "") +VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist", "") + +VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc", "") +VSC_F(n_wrk, uint64_t, 0, 'i', "N worker threads", "") +VSC_F(n_wrk_create, uint64_t, 0, 'a', "N worker threads created", "") VSC_F(n_wrk_failed, uint64_t, 0, 'a', - "N worker threads not created") -VSC_F(n_wrk_max, uint64_t, 0, 'a', "N worker threads limited") -VSC_F(n_wrk_lqueue, uint64_t, 0, 'a', "work request queue length") -VSC_F(n_wrk_queued, uint64_t, 0, 'a', "N queued work requests") -VSC_F(n_wrk_drop, uint64_t, 0, 'a', "N dropped work requests") -VSC_F(n_backend, uint64_t, 0, 'i', "N backends") + "N worker threads not created", "") +VSC_F(n_wrk_max, uint64_t, 0, 'a', "N worker threads limited", "") +VSC_F(n_wrk_lqueue, uint64_t, 0, 'a', "work request queue length", "") +VSC_F(n_wrk_queued, uint64_t, 0, 'a', "N queued work requests", "") +VSC_F(n_wrk_drop, uint64_t, 0, 'a', "N dropped work requests", "") +VSC_F(n_backend, uint64_t, 0, 'i', "N backends", "") -VSC_F(n_expired, uint64_t, 0, 'i', "N expired objects") -VSC_F(n_lru_nuked, uint64_t, 0, 'i', "N LRU nuked objects") -VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects") +VSC_F(n_expired, uint64_t, 0, 'i', "N expired objects", "") +VSC_F(n_lru_nuked, uint64_t, 0, 'i', "N LRU nuked objects", "") +VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects", "") -VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows") +VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows", "") -VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile") -VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write") +VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile", "") +VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write", "") VSC_F(n_objoverflow, uint64_t, 1, 'a', - "Objects overflowing workspace") - -VSC_F(s_sess, uint64_t, 1, 'a', "Total Sessions") -VSC_F(s_req, uint64_t, 1, 'a', "Total Requests") -VSC_F(s_pipe, uint64_t, 1, 'a', "Total pipe") -VSC_F(s_pass, uint64_t, 1, 'a', "Total pass") -VSC_F(s_fetch, uint64_t, 1, 'a', "Total fetch") -VSC_F(s_hdrbytes, uint64_t, 1, 'a', "Total header bytes") -VSC_F(s_bodybytes, uint64_t, 1, 'a', "Total body bytes") - -VSC_F(sess_closed, uint64_t, 1, 'a', "Session Closed") -VSC_F(sess_pipeline, uint64_t, 1, 'a', "Session Pipeline") -VSC_F(sess_readahead, uint64_t, 1, 'a', "Session Read Ahead") -VSC_F(sess_linger, uint64_t, 1, 'a', "Session Linger") -VSC_F(sess_herd, uint64_t, 1, 'a', "Session herd") - -VSC_F(shm_records, uint64_t, 0, 'a', "SHM records") -VSC_F(shm_writes, uint64_t, 0, 'a', "SHM writes") -VSC_F(shm_flushes, uint64_t, 0, 'a', "SHM flushes due to overflow") -VSC_F(shm_cont, uint64_t, 0, 'a', "SHM MTX contention") -VSC_F(shm_cycles, uint64_t, 0, 'a', "SHM cycles through buffer") - -VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests") -VSC_F(sms_nobj, uint64_t, 0, 'i', "SMS outstanding allocations") -VSC_F(sms_nbytes, uint64_t, 0, 'i', "SMS outstanding bytes") -VSC_F(sms_balloc, uint64_t, 0, 'i', "SMS bytes allocated") -VSC_F(sms_bfree, uint64_t, 0, 'i', "SMS bytes freed") - -VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made") - -VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total") -VSC_F(n_vcl_avail, uint64_t, 0, 'a', "N vcl available") -VSC_F(n_vcl_discard, uint64_t, 0, 'a', "N vcl discarded") - -VSC_F(n_ban, uint64_t, 0, 'i', "N total active bans") -VSC_F(n_ban_add, uint64_t, 0, 'a', "N new bans added") -VSC_F(n_ban_retire, uint64_t, 0, 'a', "N old bans deleted") -VSC_F(n_ban_obj_test, uint64_t, 0, 'a', "N objects tested") -VSC_F(n_ban_re_test, uint64_t, 0, 'a', "N regexps tested against") -VSC_F(n_ban_dups, uint64_t, 0, 'a', "N duplicate bans removed") - -VSC_F(hcb_nolock, uint64_t, 0, 'a', "HCB Lookups without lock") -VSC_F(hcb_lock, uint64_t, 0, 'a', "HCB Lookups with lock") -VSC_F(hcb_insert, uint64_t, 0, 'a', "HCB Inserts") - -VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)") -VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)") -VSC_F(accept_fail, uint64_t, 0, 'a', "Accept failures") -VSC_F(client_drop_late, uint64_t, 0, 'a', "Connection dropped late") -VSC_F(uptime, uint64_t, 0, 'a', "Client uptime") - -VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups") -VSC_F(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups") -VSC_F(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit") -VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache") - -VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs") - -VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations") -VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations") + "Objects overflowing workspace", "") + +VSC_F(s_sess, uint64_t, 1, 'a', "Total Sessions", "") +VSC_F(s_req, uint64_t, 1, 'a', "Total Requests", "") +VSC_F(s_pipe, uint64_t, 1, 'a', "Total pipe", "") +VSC_F(s_pass, uint64_t, 1, 'a', "Total pass", "") +VSC_F(s_fetch, uint64_t, 1, 'a', "Total fetch", "") +VSC_F(s_hdrbytes, uint64_t, 1, 'a', "Total header bytes", "") +VSC_F(s_bodybytes, uint64_t, 1, 'a', "Total body bytes", "") + +VSC_F(sess_closed, uint64_t, 1, 'a', "Session Closed", "") +VSC_F(sess_pipeline, uint64_t, 1, 'a', "Session Pipeline", "") +VSC_F(sess_readahead, uint64_t, 1, 'a', "Session Read Ahead", "") +VSC_F(sess_linger, uint64_t, 1, 'a', "Session Linger", "") +VSC_F(sess_herd, uint64_t, 1, 'a', "Session herd", "") + +VSC_F(shm_records, uint64_t, 0, 'a', "SHM records", "") +VSC_F(shm_writes, uint64_t, 0, 'a', "SHM writes", "") +VSC_F(shm_flushes, uint64_t, 0, 'a', "SHM flushes due to overflow", "") +VSC_F(shm_cont, uint64_t, 0, 'a', "SHM MTX contention", "") +VSC_F(shm_cycles, uint64_t, 0, 'a', "SHM cycles through buffer", "") + +VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests", "") +VSC_F(sms_nobj, uint64_t, 0, 'i', "SMS outstanding allocations", "") +VSC_F(sms_nbytes, uint64_t, 0, 'i', "SMS outstanding bytes", "") +VSC_F(sms_balloc, uint64_t, 0, 'i', "SMS bytes allocated", "") +VSC_F(sms_bfree, uint64_t, 0, 'i', "SMS bytes freed", "") + +VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made", "") + +VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total", "") +VSC_F(n_vcl_avail, uint64_t, 0, 'a', "N vcl available", "") +VSC_F(n_vcl_discard, uint64_t, 0, 'a', "N vcl discarded", "") + +VSC_F(n_ban, uint64_t, 0, 'i', "N total active bans", "") +VSC_F(n_ban_add, uint64_t, 0, 'a', "N new bans added", "") +VSC_F(n_ban_retire, uint64_t, 0, 'a', "N old bans deleted", "") +VSC_F(n_ban_obj_test, uint64_t, 0, 'a', "N objects tested", "") +VSC_F(n_ban_re_test, uint64_t, 0, 'a', "N regexps tested against", "") +VSC_F(n_ban_dups, uint64_t, 0, 'a', "N duplicate bans removed", "") + +VSC_F(hcb_nolock, uint64_t, 0, 'a', "HCB Lookups without lock", "") +VSC_F(hcb_lock, uint64_t, 0, 'a', "HCB Lookups with lock", "") +VSC_F(hcb_insert, uint64_t, 0, 'a', "HCB Inserts", "") + +VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)", "") +VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)", "") +VSC_F(accept_fail, uint64_t, 0, 'a', "Accept failures", "") +VSC_F(client_drop_late, uint64_t, 0, 'a', "Connection dropped late", "") +VSC_F(uptime, uint64_t, 0, 'a', "Client uptime", "") + +VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups", "") +VSC_F(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups", "") +VSC_F(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit", "") +VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache", "") + +VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs", "") + +VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations", "") +VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations", "") #endif @@ -168,10 +172,10 @@ VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations") #ifdef VSC_DO_LCK -VSC_F(creat, uint64_t, 0, 'a', "Created locks") -VSC_F(destroy, uint64_t, 0, 'a', "Destroyed locks") -VSC_F(locks, uint64_t, 0, 'a', "Lock Operations") -VSC_F(colls, uint64_t, 0, 'a', "Collisions") +VSC_F(creat, uint64_t, 0, 'a', "Created locks", "") +VSC_F(destroy, uint64_t, 0, 'a', "Destroyed locks", "") +VSC_F(locks, uint64_t, 0, 'a', "Lock Operations", "") +VSC_F(colls, uint64_t, 0, 'a', "Collisions", "") #endif @@ -180,13 +184,13 @@ VSC_F(colls, uint64_t, 0, 'a', "Collisions") */ #if defined(VSC_DO_SMA) || defined (VSC_DO_SMF) -VSC_F(c_req, uint64_t, 0, 'a', "Allocator requests") -VSC_F(c_fail, uint64_t, 0, 'a', "Allocator failures") -VSC_F(c_bytes, uint64_t, 0, 'a', "Bytes allocated") -VSC_F(c_freed, uint64_t, 0, 'a', "Bytes freed") -VSC_F(g_alloc, uint64_t, 0, 'i', "Allocations outstanding") -VSC_F(g_bytes, uint64_t, 0, 'i', "Bytes outstanding") -VSC_F(g_space, uint64_t, 0, 'i', "Bytes available") +VSC_F(c_req, uint64_t, 0, 'a', "Allocator requests", "") +VSC_F(c_fail, uint64_t, 0, 'a', "Allocator failures", "") +VSC_F(c_bytes, uint64_t, 0, 'a', "Bytes allocated", "") +VSC_F(c_freed, uint64_t, 0, 'a', "Bytes freed", "") +VSC_F(g_alloc, uint64_t, 0, 'i', "Allocations outstanding", "") +VSC_F(g_bytes, uint64_t, 0, 'i', "Bytes outstanding", "") +VSC_F(g_space, uint64_t, 0, 'i', "Bytes available", "") #endif @@ -199,17 +203,17 @@ VSC_F(g_space, uint64_t, 0, 'i', "Bytes available") /**********************************************************************/ #ifdef VSC_DO_SMF -VSC_F(g_smf, uint64_t, 0, 'i', "N struct smf") -VSC_F(g_smf_frag, uint64_t, 0, 'i', "N small free smf") -VSC_F(g_smf_large, uint64_t, 0, 'i', "N large free smf") +VSC_F(g_smf, uint64_t, 0, 'i', "N struct smf", "") +VSC_F(g_smf_frag, uint64_t, 0, 'i', "N small free smf", "") +VSC_F(g_smf_large, uint64_t, 0, 'i', "N large free smf", "") #endif /**********************************************************************/ #ifdef VSC_DO_VBE -VSC_F(vcls, uint64_t, 0, 'i', "VCL references") -VSC_F(happy, uint64_t, 0, 'b', "Happy health probes") +VSC_F(vcls, uint64_t, 0, 'i', "VCL references", "") +VSC_F(happy, uint64_t, 0, 'b', "Happy health probes", "") #endif diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index fc18cb3..25a1948 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -295,7 +295,7 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv, sp.class = t; \ sp.ident = sha->ident; -#define VSC_F(nn,tt,ll,ff,dd) \ +#define VSC_F(nn,tt,ll,ff,dd,ee) \ sp.name = #nn; \ sp.fmt = #tt; \ sp.flag = ff; \ @@ -331,7 +331,7 @@ VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv) if (strcmp(sha->class, VSC_CLASS)) continue; /*lint -save -e525 -e539 */ -#define VSC_F(a,b,c,d,e) +#define VSC_F(n,t,l,f,d,e) #define VSC_DONE(a,b,c) #define VSC_DO(U,l,t) \ if (!strcmp(sha->type, t)) { \ From tfheen at varnish-cache.org Thu Oct 6 09:25:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:21 +0200 Subject: [3.0] 66bcd31 Add varnish-counters(7) man page Message-ID: commit 66bcd31710a8ecfb18c24adba8d7739d074b34a1 Author: Tollef Fog Heen Date: Wed Sep 21 13:03:54 2011 +0200 Add varnish-counters(7) man page diff --git a/.gitignore b/.gitignore index 6cf0950..f35e990 100644 --- a/.gitignore +++ b/.gitignore @@ -54,8 +54,10 @@ TAGS /lib/libvmod_std/vcc_if.h # Man-files and binaries +/man/vsc2rst /man/vcl.7 /man/varnish-cli.7 +/man/varnish-counters.7 /bin/varnishadm/varnishadm /bin/varnishadm/varnishadm.1 /bin/varnishd/varnishd diff --git a/man/Makefile.am b/man/Makefile.am index bc662b6..da95e8c 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,12 @@ # -dist_man_MANS = vcl.7 varnish-cli.7 +noinst_PROGRAMS = vsc2rst +vsc2rst_SOURCES = vsc2rst.c \ + $(top_srcdir)/include/vsc_fields.h + +INCLUDES = -I$(top_srcdir)/include + +dist_man_MANS = vcl.7 varnish-cli.7 varnish-counters.7 MAINTAINERCLEANFILES = $(dist_man_MANS) vcl.7: $(top_srcdir)/doc/sphinx/reference/vcl.rst \ @@ -23,3 +29,13 @@ else @echo "========================================" @false endif + +varnish-counters.7: vsc2rst +if HAVE_RST2MAN + ./vsc2rst | ${RST2MAN} - $@ +else + @echo "========================================" + @echo "You need rst2man installed to make dist" + @echo "========================================" + @false +endif diff --git a/man/vsc2rst.c b/man/vsc2rst.c new file mode 100644 index 0000000..9b89cce --- /dev/null +++ b/man/vsc2rst.c @@ -0,0 +1,65 @@ + +#include + +#define P(x, ...) printf(x "\n", ##__VA_ARGS__) +#define VSC_F(n, t, l, f, e, d) printf("%s ? %s\n\t%s\n\n", #n, e, d); + +int main(int argc, char **argv) +{ + P("================"); + P("varnish-counters"); + P("================"); + P(""); + + P("---------------------------------"); + P("Varnish counter field definitions"); + P("---------------------------------"); + + P(":Author: Tollef Fog Heen"); + P(":Date: 2011-09-20"); + P(":Version: 1.0"); + P(":Manual section: 7"); + P(""); + + P("MAIN COUNTERS"); + P("============="); + P(""); +#define VSC_DO_MAIN +#include "vsc_fields.h" +#undef VSC_DO_MAIN + + P(""); + P("LOCK COUNTERS"); + P("============="); + P(""); +#define VSC_DO_LCK +#include "vsc_fields.h" +#undef VSC_DO_LCK + + P(""); + P("PER MALLOC STORAGE COUNTERS"); + P("==========================="); + P(""); +#define VSC_DO_SMA +#include "vsc_fields.h" +#undef VSC_DO_SMA + + P(""); + P("PER FILE STORAGE COUNTERS"); + P("========================="); + P(""); +#define VSC_DO_SMF +#include "vsc_fields.h" +#undef VSC_DO_SMF + + P(""); + P("PER BACKEND COUNTERS"); + P("===================="); + P(""); +#define VSC_DO_VBE +#include "vsc_fields.h" +#undef VSC_DO_VBE + + return 0; +} + From tfheen at varnish-cache.org Thu Oct 6 09:25:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:21 +0200 Subject: [3.0] 83fb1b7 Mark argc, argv as unused in vsc2rst Message-ID: commit 83fb1b73723cebdf836596b72fd98b1f7959ede4 Author: Tollef Fog Heen Date: Wed Sep 21 14:28:11 2011 +0200 Mark argc, argv as unused in vsc2rst diff --git a/man/vsc2rst.c b/man/vsc2rst.c index 9b89cce..e6abcf9 100644 --- a/man/vsc2rst.c +++ b/man/vsc2rst.c @@ -6,6 +6,8 @@ int main(int argc, char **argv) { + (void)argc; + (void)argv; P("================"); P("varnish-counters"); P("================"); From tfheen at varnish-cache.org Thu Oct 6 09:25:22 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:22 +0200 Subject: [3.0] 3558ace Format all code examples Message-ID: commit 3558ace01d671a2bc4dea063c1a041329c28974f Author: Andreas Plesner Jacobsen Date: Thu Sep 22 11:10:12 2011 +0200 Format all code examples diff --git a/doc/sphinx/installation/upgrade.rst b/doc/sphinx/installation/upgrade.rst index eda1515..0ed4f9f 100644 --- a/doc/sphinx/installation/upgrade.rst +++ b/doc/sphinx/installation/upgrade.rst @@ -20,11 +20,11 @@ To simplify strings, the %-encoding has been removed. If you need non-printable ``log`` moved to the std vmod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``log`` has moved to the std vmod: +``log`` has moved to the std vmod:: log "log something"; -becomes +becomes:: import std; std.log("log something"); @@ -34,11 +34,11 @@ You only need to import std once. purges are now called bans ~~~~~~~~~~~~~~~~~~~~~~~~~~ -``purge()`` and ``purge_url()`` are now respectively ``ban()`` and ``ban_url()``, so you should replace all occurences: +``purge()`` and ``purge_url()`` are now respectively ``ban()`` and ``ban_url()``, so you should replace all occurences:: purge("req.url = " req.url); -becomes +becomes:: ban("req.url = " + req.url); @@ -84,22 +84,22 @@ becomes:: ``req.hash`` is replaced with ``hash_data()`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You no longer append to the hash with ``+=``, so +You no longer append to the hash with ``+=``, so:: set req.hash += req.url; -becomes +becomes:: hash_data(req.url); ``esi`` is replaced with ``beresp.do_esi`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You no longer enable ESI with ``esi``, so +You no longer enable ESI with ``esi``, so:: esi; -in ``vcl_fetch`` becomes +in ``vcl_fetch`` becomes:: set beresp.do_esi = true; From tfheen at varnish-cache.org Thu Oct 6 09:25:23 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:23 +0200 Subject: [3.0] ea964eb This test is much to brittle due to dependence on random timing. Tighten it up with use of semaphores and collapse s1/s2/s3 using "accept" keyword. Message-ID: commit ea964eb04d60bc1004026e19ae3b09c28dd1cd47 Author: Poul-Henning Kamp Date: Fri Sep 30 18:24:34 2011 +0000 This test is much to brittle due to dependence on random timing. Tighten it up with use of semaphores and collapse s1/s2/s3 using "accept" keyword. diff --git a/bin/varnishtest/tests/v00036.vtc b/bin/varnishtest/tests/v00036.vtc index ff2ecd3..46bcca8 100644 --- a/bin/varnishtest/tests/v00036.vtc +++ b/bin/varnishtest/tests/v00036.vtc @@ -4,12 +4,46 @@ server s1 { rxreq expect req.url == "/" txresp -body "slash" + accept + + sema r1 sync 3 + + rxreq + expect req.url == "/" + txresp -body "slash" + accept + + rxreq + expect req.url == "/" + txresp -body "slash" + + sema r3 sync 2 + accept + + rxreq + expect req.url == "/foo" + txresp -hdr "Foo: 1" -body "foobar" + } -start server s2 { rxreq expect req.url == "/" txresp -body "slash" + accept + + sema r1 sync 3 + + rxreq + expect req.url == "/" + txresp -body "slash" + + sema r2 sync 2 + accept + + rxreq + expect req.url == "/foo" + txresp -hdr "Foo: 2" -body "foobar" } -start server s3 { @@ -65,66 +99,23 @@ varnish v1 -vcl { } } -start -# s1 & s2 have both had 1 probe, so both are unhealthy client c1 { + # s1 & s2 are both sick, expect response from s3 txreq -url "/foo" rxresp expect resp.http.foo == "3" -} -run - -# setup for probe #2 - -server s1 { - rxreq - expect req.url == "/" - txresp -body "slash" -} -start - -server s2 { - rxreq - expect req.url == "/" - txresp -body "slash" -} -start -# if we muck with a running server, the test will wait until it's done, -# which will be after probe #2 completes. b2 will then be healthy. + sema r1 sync 3 -server s2 { - rxreq - expect req.url == "/foo" - txresp -hdr "Foo: 2" -body "foobar" -} -start - -client c1 { + # wait for s2 to become healthy + sema r2 sync 2 txreq -url "/foo" rxresp expect resp.http.foo == "2" -} -run -# setup for probe #3 - -server s1 { - rxreq - expect req.url == "/" - txresp -body "slash" -} -start - -server s2 { - rxreq - expect req.url == "/" - txresp -body "slash" -} -start - -# after probe #3 b1 should be healthy. - -server s1 { - rxreq - expect req.url == "/foo" - txresp -hdr "Foo: 1" -body "foobar" -} -start - -client c1 { + # wait for s1 to become healthy + sema r3 sync 2 txreq -url "/foo" rxresp expect resp.http.foo == "1" From tfheen at varnish-cache.org Thu Oct 6 09:25:23 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:23 +0200 Subject: [3.0] c888c08 Try harder to make v00036 deterministic Message-ID: commit c888c08da77b9aa656e42011989326925936fde7 Author: Poul-Henning Kamp Date: Fri Sep 30 19:09:16 2011 +0000 Try harder to make v00036 deterministic diff --git a/bin/varnishtest/tests/v00036.vtc b/bin/varnishtest/tests/v00036.vtc index 46bcca8..e83acef 100644 --- a/bin/varnishtest/tests/v00036.vtc +++ b/bin/varnishtest/tests/v00036.vtc @@ -4,22 +4,25 @@ server s1 { rxreq expect req.url == "/" txresp -body "slash" - accept + close sema r1 sync 3 + accept rxreq expect req.url == "/" txresp -body "slash" - accept + close + accept rxreq expect req.url == "/" txresp -body "slash" + close sema r3 sync 2 - accept + accept rxreq expect req.url == "/foo" txresp -hdr "Foo: 1" -body "foobar" @@ -30,17 +33,19 @@ server s2 { rxreq expect req.url == "/" txresp -body "slash" - accept + close sema r1 sync 3 + accept rxreq expect req.url == "/" txresp -body "slash" + close sema r2 sync 2 - accept + accept rxreq expect req.url == "/foo" txresp -hdr "Foo: 2" -body "foobar" diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 024e376..fddcd26 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -1059,6 +1059,25 @@ cmd_http_expect_close(CMD_ARGS) } /********************************************************************** + * close a new connection (server only) + */ + +static void +cmd_http_close(CMD_ARGS) +{ + struct http *hp; + + (void)cmd; + (void)vl; + CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); + AZ(av[1]); + assert(hp->sfd != NULL); + assert(*hp->sfd >= 0); + VTCP_close(&hp->fd); + vtc_log(vl, 4, "Closed"); +} + +/********************************************************************** * close and accept a new connection (server only) */ @@ -1073,7 +1092,8 @@ cmd_http_accept(CMD_ARGS) AZ(av[1]); assert(hp->sfd != NULL); assert(*hp->sfd >= 0); - VTCP_close(&hp->fd); + if (hp->fd >= 0) + VTCP_close(&hp->fd); vtc_log(vl, 4, "Accepting"); hp->fd = accept(*hp->sfd, NULL, NULL); if (hp->fd < 0) @@ -1129,6 +1149,7 @@ static const struct cmds http_cmds[] = { { "delay", cmd_delay }, { "sema", cmd_sema }, { "expect_close", cmd_http_expect_close }, + { "close", cmd_http_close }, { "accept", cmd_http_accept }, { "loop", cmd_http_loop }, { NULL, NULL } From tfheen at varnish-cache.org Thu Oct 6 09:25:24 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:24 +0200 Subject: [3.0] c7b92c9 Try harder to fix solaris IOV_MAX related issue. Message-ID: commit c7b92c906bff03e44461878580187903ce48f6a8 Author: Poul-Henning Kamp Date: Sat Oct 1 01:12:19 2011 +0000 Try harder to fix solaris IOV_MAX related issue. diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c index 946f488..61aa2e5 100644 --- a/bin/varnishd/cache_wrw.c +++ b/bin/varnishd/cache_wrw.c @@ -179,14 +179,16 @@ WRW_Write(struct worker *w, const void *ptr, int len) return (0); if (len == -1) len = strlen(ptr); - if (wrw->niov == wrw->siov + (wrw->ciov < wrw->siov ? 1 : 0)) + if (wrw->niov >= wrw->siov - (wrw->ciov < wrw->siov ? 1 : 0)) (void)WRW_Flush(w); wrw->iov[wrw->niov].iov_base = TRUST_ME(ptr); wrw->iov[wrw->niov].iov_len = len; wrw->liov += len; - if (wrw->ciov < wrw->siov) - wrw->cliov += len; wrw->niov++; + if (wrw->ciov < wrw->siov) { + assert(wrw->niov < wrw->siov); + wrw->cliov += len; + } return (len); } @@ -208,6 +210,7 @@ WRW_Chunked(struct worker *w) wrw->ciov = wrw->niov++; wrw->cliov = 0; assert(wrw->ciov < wrw->siov); + assert(wrw->niov < wrw->siov); } /* From tfheen at varnish-cache.org Thu Oct 6 09:25:26 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:26 +0200 Subject: [3.0] 194a75f Drop debugging message about which host/port we have connected to Message-ID: commit 194a75fe5bf3a1e1e7cf4c1e681611ad9d267865 Author: Tollef Fog Heen Date: Mon Oct 3 14:37:11 2011 +0200 Drop debugging message about which host/port we have connected to Fixes: #1024 diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index 151a437..68ebbf7 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -135,7 +135,6 @@ cli_sock(const char *T_arg, const char *S_arg) } free(answer); - fprintf(stderr, "CLI connected to %s\n", T_arg); return (sock); } From tfheen at varnish-cache.org Thu Oct 6 09:25:27 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:27 +0200 Subject: [3.0] 86d77a6 Fix docs for req.esi Message-ID: commit 86d77a661a5d925e81b7f813ac24563bf0d8810d Author: Andreas Plesner Jacobsen Date: Wed Oct 5 18:57:49 2011 +0200 Fix docs for req.esi diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 9fd526c..aaca549 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -740,7 +740,9 @@ req.restarts A count of how many times this request has been restarted. req.esi - True if the request is an ESI request. + Boolean. Set to false to disable ESI processing regardless of any + value in beresp.do_esi. Defaults to true. This variable is subject + to change in future versions, you should avoid using it. req.esi_level A count of how many levels of ESI requests we're currently at. @@ -788,8 +790,9 @@ beresp.do_stream as it is delivered so only client can access the object. beresp.do_esi - Boolean. ESI-process the object after fetching it. Defaults to false. Set it - to true to parse the object for ESI directives. + Boolean. ESI-process the object after fetching it. Defaults to + false. Set it to true to parse the object for ESI directives. Will + only be honored if req.esi is true. beresp.do_gzip Boolean. Gzip the object before storing it. Defaults to false. From tfheen at varnish-cache.org Thu Oct 6 09:25:29 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:29 +0200 Subject: [3.0] 591f9fd Update changes for 3.0.2 rc 1 Message-ID: commit 591f9fd8b9d98ade1d0fcb0fb8dd3e5277b13487 Author: Tollef Fog Heen Date: Thu Oct 6 10:09:43 2011 +0200 Update changes for 3.0.2 rc 1 diff --git a/doc/changes.rst b/doc/changes.rst index 06540bf..c3603df 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,4 +1,64 @@ ================================ +Changes from 3.0.1 to 3.0.2 rc 1 +================================ + +Varnishd +-------- + +- Only log the first 20 bytes of extra headers to prevent overflows. + +- Fix crasher bug which sometimes happened if responses are queued and + the backend sends us Vary. `Bug #994`_. + +- Log correct size of compressed when uncompressing them for clients + that do not support compression. `Bug #996`_. + +- Only send Range responses if we are going to send a body. `Bug #1007`_. + +- When varnishd creates a storage file, also unlink it to avoid + leaking disk space over time. `Bug #1008`_. + +- The default size of the `-s file` parameter has been changed to + 100MB instead of 50% of the available disk space. + +- The limit on the number of objects we remove from the cache to make + room for a new one was mistakenly lowered to 10 in 3.0.1. This has + been raised back to 50. `Bug #1012`_. + +- `http_req_size` and `http_resp_size` have been increased to 8192 + bytes. This better matches what other HTTPds have. `Bug #1016`_. + +.. _bug #994: http://varnish-cache.org/trac/ticket/994 +.. _bug #992: http://varnish-cache.org/trac/ticket/992 +.. _bug #1007: http://varnish-cache.org/trac/ticket/1007 +.. _bug #1008: http://varnish-cache.org/trac/ticket/1008 +.. _bug #1012: http://varnish-cache.org/trac/ticket/1012 +.. _bug #1012: http://varnish-cache.org/trac/ticket/1016 + +VCL +--- + +- Allow relational comparisons of floating point types. + +- Make it possible for vmods to fail loading and so cause the VCL + loading to fail. + +varnishncsa +----------- + +- Fixed crash when client was sending illegal HTTP headers. + +- `%{Varnish:handling}` in format strings was broken, this has been + fixed. + +Other +----- + +- Documentation updates + +- Some Solaris portability updates. + +================================ Changes from 3.0.1 rc 1 to 3.0.1 ================================ From tfheen at varnish-cache.org Thu Oct 6 09:25:30 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:30 +0200 Subject: [3.0] a12288b Update redhat spec file to include release candidate logic. Message-ID: commit a12288b2638c3ccd678e2dfc378c2695dd41b21d Author: Tollef Fog Heen Date: Thu Oct 6 10:56:59 2011 +0200 Update redhat spec file to include release candidate logic. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 115ff54..20c613e 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,12 +1,15 @@ +%define v_rc rc1 +%define vd_rc %{?v_rc:-%{?v_rc}} + Summary: High-performance HTTP accelerator Name: varnish -Version: 3.0.1 -Release: 1%{?dist} +Version: 3.0.2 +Release: 0.%{?v_rc}%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ #Source0: http://repo.varnish-cache.org/source/%{name}-%{version}.tar.gz -Source0: %{name}-%{version}.tar.gz +Source0: %{name}-%{version}%{?vd_rc}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # To build from git, start with a make dist, see redhat/README.redhat # You will need at least automake autoconf libtool python-docutils @@ -72,7 +75,7 @@ Documentation files for %name %prep #%setup -q -%setup -q -n varnish-%{version} +%setup -q -n varnish-%{version}%{?vd_rc} mkdir examples cp bin/varnishd/default.vcl etc/zope-plone.vcl examples From tfheen at varnish-cache.org Thu Oct 6 09:25:31 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:31 +0200 Subject: [3.0] a20e0ea Only build vsc2rst if we have rst2man, fixes build failure Message-ID: commit a20e0ea52092ad627b6cfabdd38e40d84ce919f2 Author: Tollef Fog Heen Date: Thu Oct 6 10:59:07 2011 +0200 Only build vsc2rst if we have rst2man, fixes build failure diff --git a/man/Makefile.am b/man/Makefile.am index da95e8c..9317896 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,8 @@ # +if HAVE_RST2MAN noinst_PROGRAMS = vsc2rst +endif vsc2rst_SOURCES = vsc2rst.c \ $(top_srcdir)/include/vsc_fields.h @@ -30,10 +32,11 @@ else @false endif -varnish-counters.7: vsc2rst if HAVE_RST2MAN +varnish-counters.7: vsc2rst ./vsc2rst | ${RST2MAN} - $@ else +varnish-counters.7: $(top_srcdir)/include/vsc_fields.h @echo "========================================" @echo "You need rst2man installed to make dist" @echo "========================================" From tfheen at varnish-cache.org Thu Oct 6 09:25:33 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 11:25:33 +0200 Subject: [3.0] cb604ba Update version number to 3.0.2-rc1 in configure.ac Message-ID: commit cb604ba3803735845200f1bcb0bc5582f3fef420 Author: Tollef Fog Heen Date: Thu Oct 6 11:24:39 2011 +0200 Update version number to 3.0.2-rc1 in configure.ac diff --git a/configure.ac b/configure.ac index 9ef4c67..7e86ed8 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2011 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [3.0.1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [3.0.2-rc1], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/varnishapi.h) AM_CONFIG_HEADER(config.h) From tfheen at varnish-cache.org Thu Oct 6 10:37:12 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 12:37:12 +0200 Subject: [master] c3073d0 Update redhat spec file to include release candidate logic. Message-ID: commit c3073d0ab4e4ad53d484a423addedcab93094709 Author: Tollef Fog Heen Date: Thu Oct 6 10:56:14 2011 +0200 Update redhat spec file to include release candidate logic. diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 0d66765..e8ea8c7 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,11 +1,15 @@ +%define v_rc +%define vd_rc %{?v_rc:-%{?v_rc}} + Summary: High-performance HTTP accelerator Name: varnish -Version: 3.0.0 -Release: 0.20110715%{?dist} +Version: 3.1.0 +Release: 0.20111006%{?v_rc}%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ #Source0: http://repo.varnish-cache.org/source/%{name}-%{version}.tar.gz +#Source0: %{name}-%{version}%{?vd_rc}.tar.gz Source0: %{name}-trunk.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # To build from git, start with a make dist, see redhat/README.redhat @@ -71,7 +75,7 @@ Documentation files for %name #Varnish Cache is a high-performance HTTP accelerator %prep -#%setup -q +#%setup -q -n varnish-%{version}%{?vd_rc} %setup -q -n varnish-trunk mkdir examples From tfheen at varnish-cache.org Thu Oct 6 10:37:16 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 12:37:16 +0200 Subject: [master] 5c2edfc Only build vsc2rst if we have rst2man, fixes build failure Message-ID: commit 5c2edfc9537e60ea5d61a39601a02a963ab89384 Author: Tollef Fog Heen Date: Thu Oct 6 10:59:07 2011 +0200 Only build vsc2rst if we have rst2man, fixes build failure diff --git a/man/Makefile.am b/man/Makefile.am index da95e8c..9317896 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,8 @@ # +if HAVE_RST2MAN noinst_PROGRAMS = vsc2rst +endif vsc2rst_SOURCES = vsc2rst.c \ $(top_srcdir)/include/vsc_fields.h @@ -30,10 +32,11 @@ else @false endif -varnish-counters.7: vsc2rst if HAVE_RST2MAN +varnish-counters.7: vsc2rst ./vsc2rst | ${RST2MAN} - $@ else +varnish-counters.7: $(top_srcdir)/include/vsc_fields.h @echo "========================================" @echo "You need rst2man installed to make dist" @echo "========================================" From phk at varnish-cache.org Thu Oct 6 11:02:51 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 06 Oct 2011 13:02:51 +0200 Subject: [master] 27ccc76 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 27ccc764ba89b5c919abc9fc487054f57f5903c2 Merge: 0887a4f 5c2edfc Author: Poul-Henning Kamp Date: Thu Oct 6 11:02:45 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From phk at varnish-cache.org Thu Oct 6 11:02:51 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 06 Oct 2011 13:02:51 +0200 Subject: [master] 0887a4f Try to firm up v00010 even more, by explicitly waiting for the crashing child to do so, and then explicitly start it again. Message-ID: commit 0887a4f9891e13c2249558041e743ddc6f6e0e8a Author: Poul-Henning Kamp Date: Thu Oct 6 10:48:57 2011 +0000 Try to firm up v00010 even more, by explicitly waiting for the crashing child to do so, and then explicitly start it again. diff --git a/bin/varnishtest/tests/v00010.vtc b/bin/varnishtest/tests/v00010.vtc index 0421956..45dbc79 100644 --- a/bin/varnishtest/tests/v00010.vtc +++ b/bin/varnishtest/tests/v00010.vtc @@ -27,9 +27,6 @@ varnish v1 -cliok "param.set diag_bitmap 0x00001000" # Force the (random) port selected to be used again after restart. varnish v1 -cliok "param.set listen_address ${v1_addr}:${v1_port}" -# varnishtest defaults to auto_restart off, to avoid masking bugs. -varnish v1 -cliok "param.set auto_restart on" - client c1 { txreq -url "/" rxresp @@ -37,6 +34,11 @@ client c1 { # Don't expect answer, the server crashed. } -run +varnish v1 -wait-stopped +varnish v1 -cliok "panic.show" +varnish v1 -cliok "panic.clear" +varnish v1 -clierr 300 "panic.clear" +varnish v1 -cliok "start" varnish v1 -wait-running sema r1 sync 2 @@ -45,7 +47,3 @@ client c1 { rxresp expect resp.http.foo == "foo" } -run - -varnish v1 -cliok "panic.show" -varnish v1 -cliok "panic.clear" -varnish v1 -clierr 300 "panic.clear" diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 9ba34a7..9690a23 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -124,12 +124,37 @@ varnish_ask_cli(const struct varnish *v, const char *cmd, char **repl) */ static void +wait_stopped(const struct varnish *v) +{ + char *r; + enum VCLI_status_e st; + + while (1) { + vtc_log(v->vl, 3, "wait-stopped"); + st = varnish_ask_cli(v, "status", &r); + if (st != CLIS_OK) + vtc_log(v->vl, 0, + "CLI status command failed: %u %s", st, r); + if (!strcmp(r, "Child in state stopped")) { + free(r); + break; + } + free(r); + (void)usleep(200000); + } +} +/********************************************************************** + * + */ + +static void wait_running(const struct varnish *v) { char *r; enum VCLI_status_e st; while (1) { + vtc_log(v->vl, 3, "wait-running"); st = varnish_ask_cli(v, "status", &r); if (st != CLIS_OK) vtc_log(v->vl, 0, @@ -848,6 +873,10 @@ cmd_varnish(CMD_ARGS) varnish_stop(v); continue; } + if (!strcmp(*av, "-wait-stopped")) { + wait_stopped(v); + continue; + } if (!strcmp(*av, "-wait-running")) { wait_running(v); continue; From tfheen at varnish-cache.org Thu Oct 6 12:21:33 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 06 Oct 2011 14:21:33 +0200 Subject: [master] 1c9bf69 Drop unused variable Message-ID: commit 1c9bf690574fe2fdea90107d42bb45b21f773c7d Author: Tollef Fog Heen Date: Thu Oct 6 13:45:40 2011 +0200 Drop unused variable diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index a34ea1e..8a54c9f 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -215,7 +215,6 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits) struct vsl *vsl; uint32_t *p; unsigned char t; - unsigned u; int i; CHECK_OBJ_NOTNULL(vd, VSM_MAGIC); @@ -226,7 +225,6 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits) i = vsl_nextlog(vsl, &p); if (i != 1) return (i); - u = VSL_ID(p); t = VSL_TAG(p); if (vsl->skip) { --vsl->skip; From perbu at varnish-cache.org Thu Oct 6 15:33:59 2011 From: perbu at varnish-cache.org (Per Buer) Date: Thu, 06 Oct 2011 17:33:59 +0200 Subject: [master] 880b0f8 strange wording. typo Message-ID: commit 880b0f857f0e19358d81561ae346cdc7a1024cfd Author: Per Buer Date: Thu Oct 6 11:03:43 2011 +0200 strange wording. typo diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 6ba912a..019fd3b 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -5,7 +5,7 @@ Welcome to Varnish's documentation! =================================== Varnish is a state of the art web accelerator. Its mission is to sit -in front of a web server an cache the content. It makes your web site +in front of a web server and to cache the content. It makes your web site go fast. We suggest you start by reading the installation guide From perbu at varnish-cache.org Thu Oct 6 15:33:59 2011 From: perbu at varnish-cache.org (Per Buer) Date: Thu, 06 Oct 2011 17:33:59 +0200 Subject: [master] bc19f22 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit bc19f22d2b42914adff665fb447802dedf25ecbe Merge: 880b0f8 1c9bf69 Author: Per Buer Date: Thu Oct 6 17:33:53 2011 +0200 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From phk at varnish-cache.org Fri Oct 7 10:04:03 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 07 Oct 2011 12:04:03 +0200 Subject: [master] c327e76 Elminiate pthread poisoning of manager process. Message-ID: commit c327e7651c2b4b24730d7b8f8ec2e10115d50455 Author: Poul-Henning Kamp Date: Fri Oct 7 10:03:50 2011 +0000 Elminiate pthread poisoning of manager process. diff --git a/bin/varnishd/heritage.h b/bin/varnishd/heritage.h index 7aebf11..bb684b3 100644 --- a/bin/varnishd/heritage.h +++ b/bin/varnishd/heritage.h @@ -29,7 +29,6 @@ * This file contains the heritage passed when mgt forks cache */ -#include #include "vre.h" struct listen_sock { diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 24293c2..a21ca1c 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -107,3 +107,7 @@ extern unsigned mgt_vcc_err_unref; #define VSM_Free(a) VSM__Free(a) #define VSM_Clean() VSM__Clean() + +#if defined(PTHREAD_CANCELED) || defined(PTHREAD_MUTEX_DEFAULT) +#error "Keep pthreads out of in manager process" +#endif diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 49e0f81..fd91d08 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -653,3 +653,7 @@ main(int argc, char * const *argv) (void)VPF_Remove(pfh); exit(exit_status); } + +#if defined(PTHREAD_CANCELED) || defined(PTHREAD_MUTEX_DEFAULT) +#error "Keep pthreads out of in manager process" +#endif From phk at varnish-cache.org Fri Oct 7 14:05:06 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 07 Oct 2011 16:05:06 +0200 Subject: [master] 2766a70 Think about and document how we encode bans into bytestrings. Message-ID: commit 2766a700cae5bbeef7149598eff3666c66c3333a Author: Poul-Henning Kamp Date: Fri Oct 7 14:04:47 2011 +0000 Think about and document how we encode bans into bytestrings. diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index fed958c..97d961d 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -38,6 +38,26 @@ * We make the "&&" mandatory from the start, leaving the syntax space * for latter handling of "||" as well. * + * Bans are compiled into bytestrings as follows: + * 8 bytes - double: timestamp XXX: Byteorder ? + * 4 bytes - be32: length + * 1 byte - flags: 0x01: BAN_F_REQ + * N tests + * A test have this form: + * 1 byte - arg (see ban_vars.h col 3 "BAN_ARG_XXX") + * (n bytes) - http header name, canonical encoding + * lump - comparison arg + * 1 byte - operation (BAN_OPER_) + * (lump) - compiled regexp + * A lump is: + * 4 bytes - be32: length + * n bytes - content + * + * In a perfect world, we should vector through VRE to get to PCRE, + * but since we rely on PCRE's ability to encode the regexp into a + * byte string, that would be a little bit artificial, so this is + * the exception that confirmes the rule. + * */ #include "config.h" @@ -286,8 +306,6 @@ ban_parse_http(const struct ban *b, const char *a1) /*-------------------------------------------------------------------- * Parse and add a ban test specification - * - * XXX: This should vector through VRE. */ static int From phk at varnish-cache.org Fri Oct 7 20:57:42 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 07 Oct 2011 22:57:42 +0200 Subject: [master] 6c17a35 Enforce the convention that varnish related files are included with "..." and external files are included with <...> Message-ID: commit 6c17a356c8b36bf1ae29a5e97473abba5b36a78c Author: Poul-Henning Kamp Date: Fri Oct 7 20:57:13 2011 +0000 Enforce the convention that varnish related files are included with "..." and external files are included with <...> diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c index 01a3c96..f49c736 100644 --- a/lib/libvarnish/binary_heap.c +++ b/lib/libvarnish/binary_heap.c @@ -455,7 +455,7 @@ binheap_reorder(const struct binheap *bh, unsigned idx) #ifdef TEST_DRIVER /* Test driver -------------------------------------------------------*/ #include -#include +#include "miniobj.h" static void vasfail(const char *func, const char *file, int line, diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index dc4a89b..854c2ff 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -38,15 +38,15 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "vqueue.h" +#include "vsb.h" +#include "vlu.h" +#include "vcli.h" +#include "cli_priv.h" +#include "cli_common.h" +#include "cli_serve.h" +#include "libvarnish.h" +#include "miniobj.h" struct VCLS_func { unsigned magic; diff --git a/lib/libvarnish/num.c b/lib/libvarnish/num.c index 5ef2cd7..70255db 100644 --- a/lib/libvarnish/num.c +++ b/lib/libvarnish/num.c @@ -35,7 +35,7 @@ #include #include -#include +#include "libvarnish.h" static const char err_miss_num[] = "Missing number"; static const char err_invalid_num[] = "Invalid number"; diff --git a/lib/libvarnish/vct.c b/lib/libvarnish/vct.c index adcffdb..2740aa1 100644 --- a/lib/libvarnish/vct.c +++ b/lib/libvarnish/vct.c @@ -31,7 +31,7 @@ #include "config.h" #include -#include +#include "vct.h" /* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */ From phk at varnish-cache.org Sat Oct 8 09:20:22 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 11:20:22 +0200 Subject: [master] e37a675 Cleanup some #inclues Message-ID: commit e37a675a170c69bcad462d4af12da1cbc07425b7 Author: Poul-Henning Kamp Date: Sat Oct 8 09:20:10 2011 +0000 Cleanup some #inclues diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index dd26303..79ac6f6 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -49,7 +49,6 @@ #include "cli_common.h" #include "cli_serve.h" #include "cache.h" -#include "vsb.h" #include "hash_slinger.h" pthread_t cli_thread; diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index a21ca1c..8958ab5 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -33,6 +33,7 @@ #include "vqueue.h" #include "common.h" +#include "vsb.h" #include "miniobj.h" #include "libvarnish.h" diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 81e1c8d..3d6fa28 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -51,7 +51,6 @@ #include "mgt_cli.h" #include "vev.h" #include "vlu.h" -#include "vsb.h" #include "vss.h" #include "vbm.h" diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index e31f3f8..45f08af 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -48,7 +48,6 @@ #include "cli_priv.h" #include "vcli.h" -#include "vsb.h" #include "cli_common.h" #include "cli_serve.h" #include "vev.h" diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index 9e204bc..6c100bb 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -41,14 +41,13 @@ #include #include -#include "vsb.h" +#include "mgt.h" #include "libvcl.h" #include "vcli.h" #include "cli_priv.h" #include "cli_common.h" -#include "mgt.h" #include "mgt_cli.h" #include "heritage.h" diff --git a/bin/varnishd/storage_synth.c b/bin/varnishd/storage_synth.c index 24479e3..1c16b44 100644 --- a/bin/varnishd/storage_synth.c +++ b/bin/varnishd/storage_synth.c @@ -36,7 +36,6 @@ #include #include "cache.h" -#include "vsb.h" #include "stevedore.h" #include "hash_slinger.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index fd91d08..2962e74 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -50,7 +50,6 @@ #include "compat/daemon.h" -#include "vsb.h" #include "vev.h" #include "vpf.h" #include "vsha256.h" diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 3bee42a..f39b628 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -43,9 +43,6 @@ #include "libvarnish.h" #include "vev.h" -#include "vsb.h" -#include "vqueue.h" -#include "miniobj.h" #include "vtc.h" diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 5e5cce7..e96940d 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -33,7 +33,10 @@ #ifdef HAVE_PTHREAD_NP_H #include #endif + #include "vqueue.h" +#include "vsb.h" +#include "miniobj.h" struct vsb; struct vtclog; diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 3bd430b..d06b478 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -38,9 +38,6 @@ #include "vtc.h" -#include "vsb.h" -#include "vqueue.h" -#include "miniobj.h" #include "vss.h" #include "libvarnish.h" diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index fddcd26..a0ee01c 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -41,8 +41,6 @@ #include "libvarnish.h" #include "vct.h" -#include "miniobj.h" -#include "vsb.h" #include "vtc.h" diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 18f295a..6b36aa5 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -36,8 +36,6 @@ #include #include "libvarnish.h" -#include "vsb.h" -#include "miniobj.h" #include "vas.h" #include "vtc.h" diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 01a5fe2..d80aa6a 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -42,9 +42,6 @@ #include "libvarnish.h" #include "vev.h" -#include "vsb.h" -#include "vqueue.h" -#include "miniobj.h" #include "vtc.h" diff --git a/bin/varnishtest/vtc_sema.c b/bin/varnishtest/vtc_sema.c index 071b4c0..4df1979 100644 --- a/bin/varnishtest/vtc_sema.c +++ b/bin/varnishtest/vtc_sema.c @@ -35,7 +35,6 @@ #include "vtc.h" -#include "vqueue.h" #include "miniobj.h" #include "libvarnish.h" diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index d1787b1..9390e5b 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -39,9 +39,6 @@ #include "vtc.h" -#include "vqueue.h" -#include "miniobj.h" -#include "vsb.h" #include "vss.h" #include "libvarnish.h" diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 9690a23..ce6a45a 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -42,13 +42,10 @@ #include #include -#include "vqueue.h" -#include "miniobj.h" #include "libvarnish.h" #include "varnishapi.h" #include "vcli.h" #include "vss.h" -#include "vsb.h" #include "vtc.h" diff --git a/lib/libvcl/vcc_acl.c b/lib/libvcl/vcc_acl.c index 30c9eea..6eb451c 100644 --- a/lib/libvcl/vcc_acl.c +++ b/lib/libvcl/vcc_acl.c @@ -38,7 +38,6 @@ #include #include -#include "vsb.h" #include "vrt.h" #include "vcc_priv.h" diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 353a40b..8c538ef 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -35,8 +35,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index f79447f..dfe58d2 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -60,7 +60,6 @@ #include #include -#include "vsb.h" #include "vss.h" #include "vcc_priv.h" diff --git a/lib/libvcl/vcc_backend_util.c b/lib/libvcl/vcc_backend_util.c index 968ec4e..8d2cc1a 100644 --- a/lib/libvcl/vcc_backend_util.c +++ b/lib/libvcl/vcc_backend_util.c @@ -34,8 +34,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index f4a85a0..36efa4b 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -62,10 +62,6 @@ #include #include -#include "vqueue.h" - -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index ec7caed..a3aa800 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -31,6 +31,7 @@ #include "vqueue.h" #include "miniobj.h" +#include "vsb.h" #include "vcl.h" #define INDENT 2 diff --git a/lib/libvcl/vcc_dir_dns.c b/lib/libvcl/vcc_dir_dns.c index 8168a26..a8cb24b 100644 --- a/lib/libvcl/vcc_dir_dns.c +++ b/lib/libvcl/vcc_dir_dns.c @@ -36,8 +36,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_dir_random.c b/lib/libvcl/vcc_dir_random.c index 125e7d1..aa362f9 100644 --- a/lib/libvcl/vcc_dir_random.c +++ b/lib/libvcl/vcc_dir_random.c @@ -36,8 +36,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_dir_round_robin.c b/lib/libvcl/vcc_dir_round_robin.c index 6229c86..67fb118 100644 --- a/lib/libvcl/vcc_dir_round_robin.c +++ b/lib/libvcl/vcc_dir_round_robin.c @@ -35,8 +35,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c index 1f1c274..b7b6ba6 100644 --- a/lib/libvcl/vcc_expr.c +++ b/lib/libvcl/vcc_expr.c @@ -37,8 +37,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_parse.c b/lib/libvcl/vcc_parse.c index c616c3c..23c9bf7 100644 --- a/lib/libvcl/vcc_parse.c +++ b/lib/libvcl/vcc_parse.c @@ -32,8 +32,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_storage.c b/lib/libvcl/vcc_storage.c index 1acb2ed..77c657c 100644 --- a/lib/libvcl/vcc_storage.c +++ b/lib/libvcl/vcc_storage.c @@ -59,8 +59,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_string.c b/lib/libvcl/vcc_string.c index f643a4b..c6353d7 100644 --- a/lib/libvcl/vcc_string.c +++ b/lib/libvcl/vcc_string.c @@ -32,8 +32,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_symb.c b/lib/libvcl/vcc_symb.c index d473a50..4975c12 100644 --- a/lib/libvcl/vcc_symb.c +++ b/lib/libvcl/vcc_symb.c @@ -32,8 +32,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_token.c b/lib/libvcl/vcc_token.c index c5766c0..5a79732 100644 --- a/lib/libvcl/vcc_token.c +++ b/lib/libvcl/vcc_token.c @@ -34,10 +34,6 @@ #include #include -#include "vqueue.h" - -#include "vsb.h" - #include "libvarnish.h" #include "vcc_priv.h" #include "vcc_compile.h" diff --git a/lib/libvcl/vcc_var.c b/lib/libvcl/vcc_var.c index 3871dbc..b6e1ea7 100644 --- a/lib/libvcl/vcc_var.c +++ b/lib/libvcl/vcc_var.c @@ -32,8 +32,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c index f74f874..37a98fd 100644 --- a/lib/libvcl/vcc_vmod.c +++ b/lib/libvcl/vcc_vmod.c @@ -32,8 +32,6 @@ #include #include -#include "vsb.h" - #include "vcc_priv.h" #include "vcc_compile.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_xref.c b/lib/libvcl/vcc_xref.c index 2188ef5..560fe78 100644 --- a/lib/libvcl/vcc_xref.c +++ b/lib/libvcl/vcc_xref.c @@ -41,8 +41,6 @@ #include -#include "vsb.h" - #include "libvarnish.h" #include "vcc_priv.h" #include "vcc_compile.h" From phk at varnish-cache.org Sat Oct 8 10:46:28 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 12:46:28 +0200 Subject: [master] 0e63559 First sweep to remove needless #includes. Message-ID: commit 0e63559a6cf53997d4dfa3ec601c472eb6889a23 Author: Poul-Henning Kamp Date: Sat Oct 8 10:45:26 2011 +0000 First sweep to remove needless #includes. This is based on output from some scripts and basic sanity testing. diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index e2be560..c02e170 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -31,12 +31,6 @@ #include "config.h" #include -#include -#include -#include - -#include -#include #include "vcli.h" #include "cli_priv.h" diff --git a/bin/varnishd/cache_backend_cfg.c b/bin/varnishd/cache_backend_cfg.c index 0582f72..e08e09e 100644 --- a/bin/varnishd/cache_backend_cfg.c +++ b/bin/varnishd/cache_backend_cfg.c @@ -34,11 +34,6 @@ #include #include -#include -#include -#include - -#include #include "cache.h" #include "vrt.h" diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index 0854dfd..5fae557 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -40,12 +40,8 @@ #include #include #include -#include -#include #include -#include - #include "cli_priv.h" #include "cache.h" #include "vrt.h" diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index 79ac6f6..bfc1cbc 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -37,19 +37,14 @@ #include "config.h" #include -#include -#include -#include -#include -#include -#include +#include // offsetof #include "vcli.h" #include "cli_priv.h" #include "cli_common.h" #include "cli_serve.h" #include "cache.h" -#include "hash_slinger.h" +#include "hash_slinger.h" // objhead pthread_t cli_thread; static struct lock cli_mtx; diff --git a/bin/varnishd/cache_dir_random.c b/bin/varnishd/cache_dir_random.c index c2b74dd..f05d8f4 100644 --- a/bin/varnishd/cache_dir_random.c +++ b/bin/varnishd/cache_dir_random.c @@ -46,15 +46,8 @@ #include "config.h" -#include -#include - -#include -#include #include #include -#include -#include #include "cache.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache_dir_round_robin.c b/bin/varnishd/cache_dir_round_robin.c index 8e47198..9d0a257 100644 --- a/bin/varnishd/cache_dir_round_robin.c +++ b/bin/varnishd/cache_dir_round_robin.c @@ -29,13 +29,7 @@ #include "config.h" -#include -#include - -#include #include -#include -#include #include "cache.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index 5bfa654..063464a 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -36,9 +36,7 @@ #include "cache.h" #include "cache_esi.h" #include "vend.h" -#include "vct.h" #include "vgz.h" -#include "stevedore.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index c8df1b1..cac2eb6 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -30,7 +30,6 @@ #include "config.h" -#include #include #include "cache.h" diff --git a/bin/varnishd/cache_esi_parse.c b/bin/varnishd/cache_esi_parse.c index afef1fb..c659dd5 100644 --- a/bin/varnishd/cache_esi_parse.c +++ b/bin/varnishd/cache_esi_parse.c @@ -38,7 +38,6 @@ #include "vend.h" #include "vct.h" #include "vgz.h" -#include "stevedore.h" //#define Debug(fmt, ...) printf(fmt, __VA_ARGS__) #define Debug(fmt, ...) /**/ diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index a07ab6d..35d0a1e 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -51,10 +51,6 @@ #include "config.h" -#include -#include -#include -#include #include #include "binary_heap.h" diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index b32b5cf..28d61d9 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -68,9 +68,7 @@ #include #include -#include "vsl.h" #include "cache.h" -#include "stevedore.h" #include "vgz.h" diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 58c3b6a..7e45b8a 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -56,9 +56,6 @@ #include #include #include -#include -#include -#include #include "cache.h" #include "stevedore.h" diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index c8a5415..25a6627 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -31,7 +31,6 @@ #include "config.h" -#include #include #include #include diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index ea5189d..e02da80 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -32,11 +32,7 @@ #include "config.h" #include -#include -#include #include -#include -#include #include "cache.h" diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 6be7613..1aaa2ac 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -49,11 +49,7 @@ #include #include #include -#include -#include -#include "vcl.h" -#include "cli_priv.h" #include "cache.h" #include "cache_waiter.h" #include "stevedore.h" diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c index 4956154..1f500ba 100644 --- a/bin/varnishd/cache_session.c +++ b/bin/varnishd/cache_session.c @@ -36,10 +36,7 @@ #include "config.h" #include -#include #include -#include -#include #include "cache.h" #include "cache_waiter.h" diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c index b2afaa5..ef2376f 100644 --- a/bin/varnishd/cache_vrt_re.c +++ b/bin/varnishd/cache_vrt_re.c @@ -31,10 +31,6 @@ #include "config.h" -#include - -#include -#include #include #include diff --git a/bin/varnishd/cache_wrk.c b/bin/varnishd/cache_wrk.c index 0c3b18e..ba2e41a 100644 --- a/bin/varnishd/cache_wrk.c +++ b/bin/varnishd/cache_wrk.c @@ -31,17 +31,11 @@ #include "config.h" -#include - -#include #include #include #include -#include -#include #include "vcl.h" -#include "cli_priv.h" #include "cache.h" #include "hash_slinger.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_ws.c b/bin/varnishd/cache_ws.c index a803797..9fca215 100644 --- a/bin/varnishd/cache_ws.c +++ b/bin/varnishd/cache_ws.c @@ -30,17 +30,6 @@ #include "config.h" -#include -#include - -#include -#include -#include -#include -#include - -#include "vcl.h" -#include "cli_priv.h" #include "cache.h" void diff --git a/bin/varnishd/hash_critbit.c b/bin/varnishd/hash_critbit.c index 0a1ccca..7428097 100644 --- a/bin/varnishd/hash_critbit.c +++ b/bin/varnishd/hash_critbit.c @@ -32,7 +32,6 @@ #include "config.h" -#include #include #include "cache.h" diff --git a/bin/varnishd/hash_simple_list.c b/bin/varnishd/hash_simple_list.c index 5cb1fc1..13cf0ee 100644 --- a/bin/varnishd/hash_simple_list.c +++ b/bin/varnishd/hash_simple_list.c @@ -31,10 +31,6 @@ #include "config.h" -#include -#include -#include - #include "cache.h" #include "hash_slinger.h" diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index 45f08af..eccf268 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -31,8 +31,6 @@ #include "config.h" -#include - #include #include #include @@ -51,7 +49,6 @@ #include "cli_common.h" #include "cli_serve.h" #include "vev.h" -#include "vsc.h" #include "vlu.h" #include "vss.h" diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c index 84e95f4..51d4c74 100644 --- a/bin/varnishd/rfc2616.c +++ b/bin/varnishd/rfc2616.c @@ -29,8 +29,6 @@ #include "config.h" -#include - #include #include #include diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index 624d2b1..c1e52cb 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -35,11 +35,9 @@ #include #include -#include #include "cache.h" #include "stevedore.h" -#include "hash_slinger.h" #include "cli_priv.h" #include "vrt_obj.h" diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c index bd4e368..1dcfd63 100644 --- a/bin/varnishd/stevedore_utils.c +++ b/bin/varnishd/stevedore_utils.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_SYS_MOUNT_H diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index 30203f8..7388878 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -35,9 +35,6 @@ #include #include -#include -#include -#include #include #include #include diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index a4ba598..3ba7061 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -35,8 +35,6 @@ #include "config.h" -#include -#include #include #include #include diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c index a1eb98b..ba84b79 100644 --- a/bin/varnishd/storage_persistent_silo.c +++ b/bin/varnishd/storage_persistent_silo.c @@ -34,11 +34,8 @@ #include "config.h" -#include #include -#include #include -#include #include "cache.h" #include "stevedore.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 2962e74..8b35970 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -36,9 +36,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -64,11 +61,6 @@ #include "hash_slinger.h" #include "stevedore.h" -/* INFTIM indicates an infinite timeout for poll(2) */ -#ifndef INFTIM -#define INFTIM -1 -#endif - struct heritage heritage; volatile struct params *params; unsigned d_flag = 0; From phk at varnish-cache.org Sat Oct 8 14:26:15 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 16:26:15 +0200 Subject: [master] 7a24aa3 Start #include reorg. The table-building #includes will all go into the tbl/ subdirectory Message-ID: commit 7a24aa37d753c951a1df67709e3e3238d6befac7 Author: Poul-Henning Kamp Date: Sat Oct 8 14:25:44 2011 +0000 Start #include reorg. The table-building #includes will all go into the tbl/ subdirectory diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 5a91dd8..11e952e 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -224,7 +224,7 @@ struct acct { #define VSC_F(n, t, l, f, e,d) L##l(t, n) #define VSC_DO_MAIN struct dstat { -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" }; #undef VSC_F #undef VSC_DO_MAIN diff --git a/bin/varnishd/cache_wrk.c b/bin/varnishd/cache_wrk.c index ba2e41a..bb88664 100644 --- a/bin/varnishd/cache_wrk.c +++ b/bin/varnishd/cache_wrk.c @@ -53,7 +53,7 @@ wrk_sumstat(struct worker *w) #define L1(n) (VSC_C_main->n += w->stats.n) #define VSC_DO_MAIN #define VSC_F(n, t, l, f, d, e) L##l(n); -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_F #undef VSC_DO_MAIN #undef L0 diff --git a/include/Makefile.am b/include/Makefile.am index f0e2daf..3f2994c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,14 +1,14 @@ # pkginclude_HEADERS = \ - vsm.h \ - vsl.h \ + tbl/vsc_all.h \ + tbl/vsc_fields.h \ + tbl/vsl_tags.h \ + varnishapi.h \ vcli.h \ - vsl_tags.h \ - vsc_fields.h \ - vsc_all.h \ vsc.h \ - varnishapi.h + vsl.h \ + vsm.h nobase_noinst_HEADERS = \ ban_vars.h \ diff --git a/include/tbl/README b/include/tbl/README new file mode 100644 index 0000000..bbb9afc --- /dev/null +++ b/include/tbl/README @@ -0,0 +1,4 @@ +The include files in this directory are special, they are used to +define sets of objects using macros, such that a list of all such +objects can be compiled into the code by including these files with +a properly defined macro. diff --git a/include/tbl/vsc_all.h b/include/tbl/vsc_all.h new file mode 100644 index 0000000..e12bd2f --- /dev/null +++ b/include/tbl/vsc_all.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2010 Varnish Software 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. + * + */ + + + +VSC_DO(LCK, lck, VSC_TYPE_LCK) +#define VSC_DO_LCK +#include "tbl/vsc_fields.h" +#undef VSC_DO_LCK +VSC_DONE(LCK, lck, VSC_TYPE_LCK) + +VSC_DO(MAIN, main, VSC_TYPE_MAIN) +#define VSC_DO_MAIN +#include "tbl/vsc_fields.h" +#undef VSC_DO_MAIN +VSC_DONE(MAIN, main, VSC_TYPE_MAIN) + +VSC_DO(SMA, sma, VSC_TYPE_SMA) +#define VSC_DO_SMA +#include "tbl/vsc_fields.h" +#undef VSC_DO_SMA +VSC_DONE(SMA, sma, VSC_TYPE_SMA) + +VSC_DO(SMF, smf, VSC_TYPE_SMF) +#define VSC_DO_SMF +#include "tbl/vsc_fields.h" +#undef VSC_DO_SMF +VSC_DONE(SMF, smf, VSC_TYPE_SMF) + +VSC_DO(VBE, vbe, VSC_TYPE_VBE) +#define VSC_DO_VBE +#include "tbl/vsc_fields.h" +#undef VSC_DO_VBE +VSC_DONE(VBE, vbe, VSC_TYPE_VBE) diff --git a/include/tbl/vsc_fields.h b/include/tbl/vsc_fields.h new file mode 100644 index 0000000..0fd7e46 --- /dev/null +++ b/include/tbl/vsc_fields.h @@ -0,0 +1,376 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Definition of all shared memory statistics below. + * + * Fields (n, t, l, f, e, d): + * n - Name: Field name, in C-source and stats programs + * t - Type: C-type, uint64_t, unless marked in 'f' + * l - Local: Local counter in worker thread. + * f - Format: Semantics of the value in this field + * 'a' - Accumulator (deprecated, use 'c') + * 'b' - Bitmap + * 'c' - Counter, never decreases. + * 'g' - Gauge, goes up and down + * 'i' - Integer (deprecated, use 'g') + * e - Explantion: Short explanation of field (for screen use) + * d - Description: Long explanation of field (for doc use) + * + * ----------------------- + * NB: Cleanup in progress + * ----------------------- + * + * Insufficient attention has caused this to become a swamp of conflicting + * conventions, shorthands and general mumbo-jumbo. I'm trying to clean + * it up as I go over the code in other business. + * + * Please see the sessmem section for how it should look. + * + */ + +/**********************************************************************/ + +#ifdef VSC_DO_MAIN + +/*--------------------------------------------------------------------- + * Sessions + * see: cache_acceptor.c and cache_pool.c + */ + +VSC_F(sess_conn, uint64_t, 1, 'c', + "Sessions accepted", + "Count of sessions succesfully accepted" +) +VSC_F(sess_drop, uint64_t, 1, 'c', + "Sessions dropped", + "Count of sessions silently dropped due to lack of session memory." + " See parameter 'max_sess'." +) + +VSC_F(sess_fail, uint64_t, 1, 'c', + "Session accept failures", + "Count of failures to accept TCP connection." + " Either the client changed its mind, or the kernel ran out of" + " some resource like filedescriptors." +) + +/*---------------------------------------------------------------------*/ + +VSC_F(client_req, uint64_t, 1, 'a', + "Client requests received", + "") + +VSC_F(cache_hit, uint64_t, 1, 'a', + "Cache hits", + "Count of cache hits. " + " A cache hit indicates that an object has been delivered to a" + " client without fetching it from a backend server." +) + +VSC_F(cache_hitpass, uint64_t, 1, 'a', + "Cache hits for pass", + "Count of hits for pass" + " A cache hit for pass indicates that Varnish is going to" + " pass the request to the backend and this decision has been " + " cached in it self. This counts how many times the cached " + " decision is being used." +) +VSC_F(cache_miss, uint64_t, 1, 'a', + "Cache misses", + "Count of misses" + " A cache miss indicates the object was fetched from the" + " backend before delivering it to the backend.") + +VSC_F(backend_conn, uint64_t, 0, 'a', + "Backend conn. success", + "") + +VSC_F(backend_unhealthy, uint64_t, 0, 'a', + "Backend conn. not attempted", + "" +) +VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many", "") +VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures", "") +VSC_F(backend_reuse, uint64_t, 0, 'a', + "Backend conn. reuses", + "Count of backend connection reuses" + " This counter is increased whenever we reuse a recycled connection.") +VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed", "") +VSC_F(backend_recycle, uint64_t, 0, 'a', + "Backend conn. recycles", + "Count of backend connection recycles" + " This counter is increased whenever we have a keep-alive" + " connection that is put back into the pool of connections." + " It has not yet been used, but it might be, unless the backend" + " closes it.") +VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry", "") + +VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head", "") +VSC_F(fetch_length, uint64_t, 1, 'a', "Fetch with Length", "") +VSC_F(fetch_chunked, uint64_t, 1, 'a', "Fetch chunked", "") +VSC_F(fetch_eof, uint64_t, 1, 'a', "Fetch EOF", "") +VSC_F(fetch_bad, uint64_t, 1, 'a', "Fetch had bad headers", "") +VSC_F(fetch_close, uint64_t, 1, 'a', "Fetch wanted close", "") +VSC_F(fetch_oldhttp, uint64_t, 1, 'a', "Fetch pre HTTP/1.1 closed", "") +VSC_F(fetch_zero, uint64_t, 1, 'a', "Fetch zero len", "") +VSC_F(fetch_failed, uint64_t, 1, 'a', "Fetch failed", "") +VSC_F(fetch_1xx, uint64_t, 1, 'a', "Fetch no body (1xx)", "") +VSC_F(fetch_204, uint64_t, 1, 'a', "Fetch no body (204)", "") +VSC_F(fetch_304, uint64_t, 1, 'a', "Fetch no body (304)", "") + +/*--------------------------------------------------------------------- + * Session Memory + * see: cache_session.c + */ + +VSC_F(sessmem_size, uint64_t, 1, 'g', + "Session mem size", + "Bytes of memory allocated for last allocated session." +) + +VSC_F(sessmem_alloc, uint64_t, 1, 'c', + "Session mem allocated", + "Count of all allocations of session memory." +) + +VSC_F(sessmem_free, uint64_t, 1, 'c', + "Session mem freed", + "Count of all frees of session memory." +) + +VSC_F(sessmem_fail, uint64_t, 1, 'c', + "Session mem alloc failed", + "Count of session memory allocation failures." +) + +VSC_F(sessmem_limit, uint64_t, 1, 'c', + "Session mem alloc limited", + "Count of session memory allocations blocked by limit (max_sess)." +) + +/*--------------------------------------------------------------------- + * Pools, threads, and sessions + * see: cache_pool.c + * + */ + +VSC_F(pools, uint64_t, 1, 'g', + "Number of thread pools", + "Number of thread pools. See also param wthread_pools." + " NB: Presently pools cannot be removed once created." +) + +VSC_F(threads, uint64_t, 1, 'g', + "Total number of threads", + "Number of threads in all pools." + " See also params thread_pools, thread_pool_min & thread_pool_max." +) + +VSC_F(threads_limited, uint64_t, 1, 'c', + "Threads hit max", + "Number of times more threads were needed, but limit was reached" + " in a thread pool." + " See also param thread_pool_max." +) + +VSC_F(threads_created, uint64_t, 1, 'c', + "Threads created", + "Total number of threads created in all pools." +) + +VSC_F(threads_destroyed, uint64_t, 1, 'c', + "Threads destoryed", + "Total number of threads destroyed in all pools." +) + +VSC_F(threads_failed, uint64_t, 1, 'c', + "Thread creation failed", + "Number of times creating a thread failed." + " See VSL::Debug for diagnostics." + " See also param thread_fail_delay." +) + +VSC_F(thread_queue_len, uint64_t, 1, 'g', + "Length of session queue", + "Length of session queue waiting for threads." + " NB: Only updates once per second." + " See also param queue_max." +) + +VSC_F(sess_queued, uint64_t, 1, 'c', + "Sessions queued for thread", + "Number of times session was queued waiting for a thread." + " See also param queue_max." +) + +VSC_F(sess_dropped, uint64_t, 1, 'c', + "Sessions dropped for thread", + "Number of times session was dropped because the queue were too" + " long already." + " See also param queue_max." +) + +/*---------------------------------------------------------------------*/ + +VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem", "") +VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess", "") +VSC_F(n_object, uint64_t, 1, 'i', "N struct object", "") +VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects", "") +VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore", "") +VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead", "") +VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist", "") + +VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc", "") + +VSC_F(n_backend, uint64_t, 0, 'i', "N backends", "") + +VSC_F(n_expired, uint64_t, 0, 'i', "N expired objects", "") +VSC_F(n_lru_nuked, uint64_t, 0, 'i', "N LRU nuked objects", "") +VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects", "") + +VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows", "") + +VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile", + "The number of objects sent with the sendfile system call. If enabled " + "sendfile will be used on object larger than a certain size.") +VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write", + "The number of objects sent with regular write calls." + "Writes are used when the objects are too small for sendfile " + "or if the sendfile call has been disabled") +VSC_F(n_objoverflow, uint64_t, 1, 'a', + "Objects overflowing workspace", "") + +VSC_F(s_sess, uint64_t, 1, 'a', "Total Sessions", "") +VSC_F(s_req, uint64_t, 1, 'a', "Total Requests", "") +VSC_F(s_pipe, uint64_t, 1, 'a', "Total pipe", "") +VSC_F(s_pass, uint64_t, 1, 'a', "Total pass", "") +VSC_F(s_fetch, uint64_t, 1, 'a', "Total fetch", "") +VSC_F(s_hdrbytes, uint64_t, 1, 'a', "Total header bytes", "") +VSC_F(s_bodybytes, uint64_t, 1, 'a', "Total body bytes", "") + +VSC_F(sess_closed, uint64_t, 1, 'a', "Session Closed", "") +VSC_F(sess_pipeline, uint64_t, 1, 'a', "Session Pipeline", "") +VSC_F(sess_readahead, uint64_t, 1, 'a', "Session Read Ahead", "") +VSC_F(sess_linger, uint64_t, 1, 'a', "Session Linger", "") +VSC_F(sess_herd, uint64_t, 1, 'a', "Session herd", "") + +VSC_F(shm_records, uint64_t, 0, 'a', "SHM records", "") +VSC_F(shm_writes, uint64_t, 0, 'a', "SHM writes", "") +VSC_F(shm_flushes, uint64_t, 0, 'a', "SHM flushes due to overflow", "") +VSC_F(shm_cont, uint64_t, 0, 'a', "SHM MTX contention", "") +VSC_F(shm_cycles, uint64_t, 0, 'a', "SHM cycles through buffer", "") + +VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests", "") +VSC_F(sms_nobj, uint64_t, 0, 'i', "SMS outstanding allocations", "") +VSC_F(sms_nbytes, uint64_t, 0, 'i', "SMS outstanding bytes", "") +VSC_F(sms_balloc, uint64_t, 0, 'i', "SMS bytes allocated", "") +VSC_F(sms_bfree, uint64_t, 0, 'i', "SMS bytes freed", "") + +VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made", "") + +VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total", "") +VSC_F(n_vcl_avail, uint64_t, 0, 'a', "N vcl available", "") +VSC_F(n_vcl_discard, uint64_t, 0, 'a', "N vcl discarded", "") + +VSC_F(n_ban, uint64_t, 0, 'i', "N total active bans", "") +VSC_F(n_ban_add, uint64_t, 0, 'a', "N new bans added", "") +VSC_F(n_ban_retire, uint64_t, 0, 'a', "N old bans deleted", "") +VSC_F(n_ban_obj_test, uint64_t, 0, 'a', "N objects tested", "") +VSC_F(n_ban_re_test, uint64_t, 0, 'a', "N regexps tested against", "") +VSC_F(n_ban_dups, uint64_t, 0, 'a', "N duplicate bans removed", "") + +VSC_F(hcb_nolock, uint64_t, 0, 'a', "HCB Lookups without lock", "") +VSC_F(hcb_lock, uint64_t, 0, 'a', "HCB Lookups with lock", "") +VSC_F(hcb_insert, uint64_t, 0, 'a', "HCB Inserts", "") + +VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)", "") +VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)", "") +VSC_F(client_drop_late, uint64_t, 0, 'a', "Connection dropped late", "") +VSC_F(uptime, uint64_t, 0, 'a', "Client uptime", "") + +VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups", "") +VSC_F(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups", "") +VSC_F(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit", "") +VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache", "") + +VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs", "") + +VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations", "") +VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations", "") + +#endif + +/**********************************************************************/ + +#ifdef VSC_DO_LCK + +VSC_F(creat, uint64_t, 0, 'a', "Created locks", "") +VSC_F(destroy, uint64_t, 0, 'a', "Destroyed locks", "") +VSC_F(locks, uint64_t, 0, 'a', "Lock Operations", "") +VSC_F(colls, uint64_t, 0, 'a', "Collisions", "") + +#endif + +/********************************************************************** + * All Stevedores support these counters + */ + +#if defined(VSC_DO_SMA) || defined (VSC_DO_SMF) +VSC_F(c_req, uint64_t, 0, 'a', "Allocator requests", "") +VSC_F(c_fail, uint64_t, 0, 'a', "Allocator failures", "") +VSC_F(c_bytes, uint64_t, 0, 'a', "Bytes allocated", "") +VSC_F(c_freed, uint64_t, 0, 'a', "Bytes freed", "") +VSC_F(g_alloc, uint64_t, 0, 'i', "Allocations outstanding", "") +VSC_F(g_bytes, uint64_t, 0, 'i', "Bytes outstanding", "") +VSC_F(g_space, uint64_t, 0, 'i', "Bytes available", "") +#endif + + +/**********************************************************************/ + +#ifdef VSC_DO_SMA +/* No SMA specific counters */ +#endif + +/**********************************************************************/ + +#ifdef VSC_DO_SMF +VSC_F(g_smf, uint64_t, 0, 'i', "N struct smf", "") +VSC_F(g_smf_frag, uint64_t, 0, 'i', "N small free smf", "") +VSC_F(g_smf_large, uint64_t, 0, 'i', "N large free smf", "") +#endif + +/**********************************************************************/ + +#ifdef VSC_DO_VBE + +VSC_F(vcls, uint64_t, 0, 'i', "VCL references", "") +VSC_F(happy, uint64_t, 0, 'b', "Happy health probes", "") + +#endif + diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h new file mode 100644 index 0000000..21ca1df --- /dev/null +++ b/include/tbl/vsl_tags.h @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + * Define the tags in the shared memory in a reusable format. + * Whoever includes this get to define what the SLTM macro does. + * + * REMEMBER to update the documentation (especially the varnishlog(1) man + * page) whenever this list changes. + * + * XXX: Please add new entries a the end to not break saved log-segments. + * XXX: we can resort them when we have a major release. + */ + +SLTM(Debug) +SLTM(Error) +SLTM(CLI) +SLTM(StatSess) +SLTM(ReqEnd) +SLTM(SessionOpen) +SLTM(SessionClose) +SLTM(BackendOpen) +SLTM(BackendXID) +SLTM(BackendReuse) +SLTM(BackendClose) +SLTM(HttpGarbage) +SLTM(Backend) +SLTM(Length) + +SLTM(FetchError) + +SLTM(RxRequest) +SLTM(RxResponse) +SLTM(RxStatus) +SLTM(RxURL) +SLTM(RxProtocol) +SLTM(RxHeader) + +SLTM(TxRequest) +SLTM(TxResponse) +SLTM(TxStatus) +SLTM(TxURL) +SLTM(TxProtocol) +SLTM(TxHeader) + +SLTM(ObjRequest) +SLTM(ObjResponse) +SLTM(ObjStatus) +SLTM(ObjURL) +SLTM(ObjProtocol) +SLTM(ObjHeader) + +SLTM(LostHeader) + +SLTM(TTL) +SLTM(Fetch_Body) +SLTM(VCL_acl) +SLTM(VCL_call) +SLTM(VCL_trace) +SLTM(VCL_return) +SLTM(VCL_error) +SLTM(ReqStart) +SLTM(Hit) +SLTM(HitPass) +SLTM(ExpBan) +SLTM(ExpKill) +SLTM(WorkThread) + +SLTM(ESI_xmlerror) + +SLTM(Hash) + +SLTM(Backend_health) + +SLTM(VCL_Debug) +SLTM(VCL_Log) +SLTM(VCL_Error) + +SLTM(Gzip) diff --git a/include/vsc.h b/include/vsc.h index 7cb3235..0a9cbf9 100644 --- a/include/vsc.h +++ b/include/vsc.h @@ -43,7 +43,7 @@ #define VSC_DO(u,l,t) struct VSC_C_##l { #define VSC_DONE(u,l,t) }; -#include "vsc_all.h" +#include "tbl/vsc_all.h" #undef VSC_DO #undef VSC_F diff --git a/include/vsc_all.h b/include/vsc_all.h deleted file mode 100644 index 24fa8ec..0000000 --- a/include/vsc_all.h +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2010 Varnish Software 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. - * - */ - - - -VSC_DO(LCK, lck, VSC_TYPE_LCK) -#define VSC_DO_LCK -#include "vsc_fields.h" -#undef VSC_DO_LCK -VSC_DONE(LCK, lck, VSC_TYPE_LCK) - -VSC_DO(MAIN, main, VSC_TYPE_MAIN) -#define VSC_DO_MAIN -#include "vsc_fields.h" -#undef VSC_DO_MAIN -VSC_DONE(MAIN, main, VSC_TYPE_MAIN) - -VSC_DO(SMA, sma, VSC_TYPE_SMA) -#define VSC_DO_SMA -#include "vsc_fields.h" -#undef VSC_DO_SMA -VSC_DONE(SMA, sma, VSC_TYPE_SMA) - -VSC_DO(SMF, smf, VSC_TYPE_SMF) -#define VSC_DO_SMF -#include "vsc_fields.h" -#undef VSC_DO_SMF -VSC_DONE(SMF, smf, VSC_TYPE_SMF) - -VSC_DO(VBE, vbe, VSC_TYPE_VBE) -#define VSC_DO_VBE -#include "vsc_fields.h" -#undef VSC_DO_VBE -VSC_DONE(VBE, vbe, VSC_TYPE_VBE) diff --git a/include/vsc_fields.h b/include/vsc_fields.h deleted file mode 100644 index 0fd7e46..0000000 --- a/include/vsc_fields.h +++ /dev/null @@ -1,376 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Definition of all shared memory statistics below. - * - * Fields (n, t, l, f, e, d): - * n - Name: Field name, in C-source and stats programs - * t - Type: C-type, uint64_t, unless marked in 'f' - * l - Local: Local counter in worker thread. - * f - Format: Semantics of the value in this field - * 'a' - Accumulator (deprecated, use 'c') - * 'b' - Bitmap - * 'c' - Counter, never decreases. - * 'g' - Gauge, goes up and down - * 'i' - Integer (deprecated, use 'g') - * e - Explantion: Short explanation of field (for screen use) - * d - Description: Long explanation of field (for doc use) - * - * ----------------------- - * NB: Cleanup in progress - * ----------------------- - * - * Insufficient attention has caused this to become a swamp of conflicting - * conventions, shorthands and general mumbo-jumbo. I'm trying to clean - * it up as I go over the code in other business. - * - * Please see the sessmem section for how it should look. - * - */ - -/**********************************************************************/ - -#ifdef VSC_DO_MAIN - -/*--------------------------------------------------------------------- - * Sessions - * see: cache_acceptor.c and cache_pool.c - */ - -VSC_F(sess_conn, uint64_t, 1, 'c', - "Sessions accepted", - "Count of sessions succesfully accepted" -) -VSC_F(sess_drop, uint64_t, 1, 'c', - "Sessions dropped", - "Count of sessions silently dropped due to lack of session memory." - " See parameter 'max_sess'." -) - -VSC_F(sess_fail, uint64_t, 1, 'c', - "Session accept failures", - "Count of failures to accept TCP connection." - " Either the client changed its mind, or the kernel ran out of" - " some resource like filedescriptors." -) - -/*---------------------------------------------------------------------*/ - -VSC_F(client_req, uint64_t, 1, 'a', - "Client requests received", - "") - -VSC_F(cache_hit, uint64_t, 1, 'a', - "Cache hits", - "Count of cache hits. " - " A cache hit indicates that an object has been delivered to a" - " client without fetching it from a backend server." -) - -VSC_F(cache_hitpass, uint64_t, 1, 'a', - "Cache hits for pass", - "Count of hits for pass" - " A cache hit for pass indicates that Varnish is going to" - " pass the request to the backend and this decision has been " - " cached in it self. This counts how many times the cached " - " decision is being used." -) -VSC_F(cache_miss, uint64_t, 1, 'a', - "Cache misses", - "Count of misses" - " A cache miss indicates the object was fetched from the" - " backend before delivering it to the backend.") - -VSC_F(backend_conn, uint64_t, 0, 'a', - "Backend conn. success", - "") - -VSC_F(backend_unhealthy, uint64_t, 0, 'a', - "Backend conn. not attempted", - "" -) -VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many", "") -VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures", "") -VSC_F(backend_reuse, uint64_t, 0, 'a', - "Backend conn. reuses", - "Count of backend connection reuses" - " This counter is increased whenever we reuse a recycled connection.") -VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed", "") -VSC_F(backend_recycle, uint64_t, 0, 'a', - "Backend conn. recycles", - "Count of backend connection recycles" - " This counter is increased whenever we have a keep-alive" - " connection that is put back into the pool of connections." - " It has not yet been used, but it might be, unless the backend" - " closes it.") -VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry", "") - -VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head", "") -VSC_F(fetch_length, uint64_t, 1, 'a', "Fetch with Length", "") -VSC_F(fetch_chunked, uint64_t, 1, 'a', "Fetch chunked", "") -VSC_F(fetch_eof, uint64_t, 1, 'a', "Fetch EOF", "") -VSC_F(fetch_bad, uint64_t, 1, 'a', "Fetch had bad headers", "") -VSC_F(fetch_close, uint64_t, 1, 'a', "Fetch wanted close", "") -VSC_F(fetch_oldhttp, uint64_t, 1, 'a', "Fetch pre HTTP/1.1 closed", "") -VSC_F(fetch_zero, uint64_t, 1, 'a', "Fetch zero len", "") -VSC_F(fetch_failed, uint64_t, 1, 'a', "Fetch failed", "") -VSC_F(fetch_1xx, uint64_t, 1, 'a', "Fetch no body (1xx)", "") -VSC_F(fetch_204, uint64_t, 1, 'a', "Fetch no body (204)", "") -VSC_F(fetch_304, uint64_t, 1, 'a', "Fetch no body (304)", "") - -/*--------------------------------------------------------------------- - * Session Memory - * see: cache_session.c - */ - -VSC_F(sessmem_size, uint64_t, 1, 'g', - "Session mem size", - "Bytes of memory allocated for last allocated session." -) - -VSC_F(sessmem_alloc, uint64_t, 1, 'c', - "Session mem allocated", - "Count of all allocations of session memory." -) - -VSC_F(sessmem_free, uint64_t, 1, 'c', - "Session mem freed", - "Count of all frees of session memory." -) - -VSC_F(sessmem_fail, uint64_t, 1, 'c', - "Session mem alloc failed", - "Count of session memory allocation failures." -) - -VSC_F(sessmem_limit, uint64_t, 1, 'c', - "Session mem alloc limited", - "Count of session memory allocations blocked by limit (max_sess)." -) - -/*--------------------------------------------------------------------- - * Pools, threads, and sessions - * see: cache_pool.c - * - */ - -VSC_F(pools, uint64_t, 1, 'g', - "Number of thread pools", - "Number of thread pools. See also param wthread_pools." - " NB: Presently pools cannot be removed once created." -) - -VSC_F(threads, uint64_t, 1, 'g', - "Total number of threads", - "Number of threads in all pools." - " See also params thread_pools, thread_pool_min & thread_pool_max." -) - -VSC_F(threads_limited, uint64_t, 1, 'c', - "Threads hit max", - "Number of times more threads were needed, but limit was reached" - " in a thread pool." - " See also param thread_pool_max." -) - -VSC_F(threads_created, uint64_t, 1, 'c', - "Threads created", - "Total number of threads created in all pools." -) - -VSC_F(threads_destroyed, uint64_t, 1, 'c', - "Threads destoryed", - "Total number of threads destroyed in all pools." -) - -VSC_F(threads_failed, uint64_t, 1, 'c', - "Thread creation failed", - "Number of times creating a thread failed." - " See VSL::Debug for diagnostics." - " See also param thread_fail_delay." -) - -VSC_F(thread_queue_len, uint64_t, 1, 'g', - "Length of session queue", - "Length of session queue waiting for threads." - " NB: Only updates once per second." - " See also param queue_max." -) - -VSC_F(sess_queued, uint64_t, 1, 'c', - "Sessions queued for thread", - "Number of times session was queued waiting for a thread." - " See also param queue_max." -) - -VSC_F(sess_dropped, uint64_t, 1, 'c', - "Sessions dropped for thread", - "Number of times session was dropped because the queue were too" - " long already." - " See also param queue_max." -) - -/*---------------------------------------------------------------------*/ - -VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem", "") -VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess", "") -VSC_F(n_object, uint64_t, 1, 'i', "N struct object", "") -VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects", "") -VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore", "") -VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead", "") -VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist", "") - -VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc", "") - -VSC_F(n_backend, uint64_t, 0, 'i', "N backends", "") - -VSC_F(n_expired, uint64_t, 0, 'i', "N expired objects", "") -VSC_F(n_lru_nuked, uint64_t, 0, 'i', "N LRU nuked objects", "") -VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects", "") - -VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows", "") - -VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile", - "The number of objects sent with the sendfile system call. If enabled " - "sendfile will be used on object larger than a certain size.") -VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write", - "The number of objects sent with regular write calls." - "Writes are used when the objects are too small for sendfile " - "or if the sendfile call has been disabled") -VSC_F(n_objoverflow, uint64_t, 1, 'a', - "Objects overflowing workspace", "") - -VSC_F(s_sess, uint64_t, 1, 'a', "Total Sessions", "") -VSC_F(s_req, uint64_t, 1, 'a', "Total Requests", "") -VSC_F(s_pipe, uint64_t, 1, 'a', "Total pipe", "") -VSC_F(s_pass, uint64_t, 1, 'a', "Total pass", "") -VSC_F(s_fetch, uint64_t, 1, 'a', "Total fetch", "") -VSC_F(s_hdrbytes, uint64_t, 1, 'a', "Total header bytes", "") -VSC_F(s_bodybytes, uint64_t, 1, 'a', "Total body bytes", "") - -VSC_F(sess_closed, uint64_t, 1, 'a', "Session Closed", "") -VSC_F(sess_pipeline, uint64_t, 1, 'a', "Session Pipeline", "") -VSC_F(sess_readahead, uint64_t, 1, 'a', "Session Read Ahead", "") -VSC_F(sess_linger, uint64_t, 1, 'a', "Session Linger", "") -VSC_F(sess_herd, uint64_t, 1, 'a', "Session herd", "") - -VSC_F(shm_records, uint64_t, 0, 'a', "SHM records", "") -VSC_F(shm_writes, uint64_t, 0, 'a', "SHM writes", "") -VSC_F(shm_flushes, uint64_t, 0, 'a', "SHM flushes due to overflow", "") -VSC_F(shm_cont, uint64_t, 0, 'a', "SHM MTX contention", "") -VSC_F(shm_cycles, uint64_t, 0, 'a', "SHM cycles through buffer", "") - -VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests", "") -VSC_F(sms_nobj, uint64_t, 0, 'i', "SMS outstanding allocations", "") -VSC_F(sms_nbytes, uint64_t, 0, 'i', "SMS outstanding bytes", "") -VSC_F(sms_balloc, uint64_t, 0, 'i', "SMS bytes allocated", "") -VSC_F(sms_bfree, uint64_t, 0, 'i', "SMS bytes freed", "") - -VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made", "") - -VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total", "") -VSC_F(n_vcl_avail, uint64_t, 0, 'a', "N vcl available", "") -VSC_F(n_vcl_discard, uint64_t, 0, 'a', "N vcl discarded", "") - -VSC_F(n_ban, uint64_t, 0, 'i', "N total active bans", "") -VSC_F(n_ban_add, uint64_t, 0, 'a', "N new bans added", "") -VSC_F(n_ban_retire, uint64_t, 0, 'a', "N old bans deleted", "") -VSC_F(n_ban_obj_test, uint64_t, 0, 'a', "N objects tested", "") -VSC_F(n_ban_re_test, uint64_t, 0, 'a', "N regexps tested against", "") -VSC_F(n_ban_dups, uint64_t, 0, 'a', "N duplicate bans removed", "") - -VSC_F(hcb_nolock, uint64_t, 0, 'a', "HCB Lookups without lock", "") -VSC_F(hcb_lock, uint64_t, 0, 'a', "HCB Lookups with lock", "") -VSC_F(hcb_insert, uint64_t, 0, 'a', "HCB Inserts", "") - -VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)", "") -VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)", "") -VSC_F(client_drop_late, uint64_t, 0, 'a', "Connection dropped late", "") -VSC_F(uptime, uint64_t, 0, 'a', "Client uptime", "") - -VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups", "") -VSC_F(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups", "") -VSC_F(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit", "") -VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache", "") - -VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs", "") - -VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations", "") -VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations", "") - -#endif - -/**********************************************************************/ - -#ifdef VSC_DO_LCK - -VSC_F(creat, uint64_t, 0, 'a', "Created locks", "") -VSC_F(destroy, uint64_t, 0, 'a', "Destroyed locks", "") -VSC_F(locks, uint64_t, 0, 'a', "Lock Operations", "") -VSC_F(colls, uint64_t, 0, 'a', "Collisions", "") - -#endif - -/********************************************************************** - * All Stevedores support these counters - */ - -#if defined(VSC_DO_SMA) || defined (VSC_DO_SMF) -VSC_F(c_req, uint64_t, 0, 'a', "Allocator requests", "") -VSC_F(c_fail, uint64_t, 0, 'a', "Allocator failures", "") -VSC_F(c_bytes, uint64_t, 0, 'a', "Bytes allocated", "") -VSC_F(c_freed, uint64_t, 0, 'a', "Bytes freed", "") -VSC_F(g_alloc, uint64_t, 0, 'i', "Allocations outstanding", "") -VSC_F(g_bytes, uint64_t, 0, 'i', "Bytes outstanding", "") -VSC_F(g_space, uint64_t, 0, 'i', "Bytes available", "") -#endif - - -/**********************************************************************/ - -#ifdef VSC_DO_SMA -/* No SMA specific counters */ -#endif - -/**********************************************************************/ - -#ifdef VSC_DO_SMF -VSC_F(g_smf, uint64_t, 0, 'i', "N struct smf", "") -VSC_F(g_smf_frag, uint64_t, 0, 'i', "N small free smf", "") -VSC_F(g_smf_large, uint64_t, 0, 'i', "N large free smf", "") -#endif - -/**********************************************************************/ - -#ifdef VSC_DO_VBE - -VSC_F(vcls, uint64_t, 0, 'i', "VCL references", "") -VSC_F(happy, uint64_t, 0, 'b', "Happy health probes", "") - -#endif - diff --git a/include/vsl.h b/include/vsl.h index 7f771ce..64b0516 100644 --- a/include/vsl.h +++ b/include/vsl.h @@ -74,7 +74,7 @@ enum VSL_tag_e { SLT_Bogus = 0, #define SLTM(foo) SLT_##foo, -#include "vsl_tags.h" +#include "tbl/vsl_tags.h" #undef SLTM SLT_Reserved = 255 }; diff --git a/include/vsl_tags.h b/include/vsl_tags.h deleted file mode 100644 index 21ca1df..0000000 --- a/include/vsl_tags.h +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - * Define the tags in the shared memory in a reusable format. - * Whoever includes this get to define what the SLTM macro does. - * - * REMEMBER to update the documentation (especially the varnishlog(1) man - * page) whenever this list changes. - * - * XXX: Please add new entries a the end to not break saved log-segments. - * XXX: we can resort them when we have a major release. - */ - -SLTM(Debug) -SLTM(Error) -SLTM(CLI) -SLTM(StatSess) -SLTM(ReqEnd) -SLTM(SessionOpen) -SLTM(SessionClose) -SLTM(BackendOpen) -SLTM(BackendXID) -SLTM(BackendReuse) -SLTM(BackendClose) -SLTM(HttpGarbage) -SLTM(Backend) -SLTM(Length) - -SLTM(FetchError) - -SLTM(RxRequest) -SLTM(RxResponse) -SLTM(RxStatus) -SLTM(RxURL) -SLTM(RxProtocol) -SLTM(RxHeader) - -SLTM(TxRequest) -SLTM(TxResponse) -SLTM(TxStatus) -SLTM(TxURL) -SLTM(TxProtocol) -SLTM(TxHeader) - -SLTM(ObjRequest) -SLTM(ObjResponse) -SLTM(ObjStatus) -SLTM(ObjURL) -SLTM(ObjProtocol) -SLTM(ObjHeader) - -SLTM(LostHeader) - -SLTM(TTL) -SLTM(Fetch_Body) -SLTM(VCL_acl) -SLTM(VCL_call) -SLTM(VCL_trace) -SLTM(VCL_return) -SLTM(VCL_error) -SLTM(ReqStart) -SLTM(Hit) -SLTM(HitPass) -SLTM(ExpBan) -SLTM(ExpKill) -SLTM(WorkThread) - -SLTM(ESI_xmlerror) - -SLTM(Hash) - -SLTM(Backend_health) - -SLTM(VCL_Debug) -SLTM(VCL_Log) -SLTM(VCL_Error) - -SLTM(Gzip) diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index 25a1948..18f1fc7 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -309,7 +309,7 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv, return (0); \ } -#include "vsc_all.h" +#include "tbl/vsc_all.h" #undef VSC_DO #undef VSC_F #undef VSC_DONE @@ -339,7 +339,7 @@ VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv) if (!i) \ continue; \ } -#include "vsc_all.h" +#include "tbl/vsc_all.h" #undef VSC_F #undef VSC_DO #undef VSC_DONE diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index 8a54c9f..ab538c5 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -53,7 +53,7 @@ const char *VSL_tags[256] = { #define SLTM(foo) [SLT_##foo] = #foo, -#include "vsl_tags.h" +#include "tbl/vsl_tags.h" #undef SLTM }; diff --git a/man/vsc2rst.c b/man/vsc2rst.c index e6abcf9..ad5dec6 100644 --- a/man/vsc2rst.c +++ b/man/vsc2rst.c @@ -27,7 +27,7 @@ int main(int argc, char **argv) P("============="); P(""); #define VSC_DO_MAIN -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_DO_MAIN P(""); @@ -35,7 +35,7 @@ int main(int argc, char **argv) P("============="); P(""); #define VSC_DO_LCK -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_DO_LCK P(""); @@ -43,7 +43,7 @@ int main(int argc, char **argv) P("==========================="); P(""); #define VSC_DO_SMA -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_DO_SMA P(""); @@ -51,7 +51,7 @@ int main(int argc, char **argv) P("========================="); P(""); #define VSC_DO_SMF -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_DO_SMF P(""); @@ -59,7 +59,7 @@ int main(int argc, char **argv) P("===================="); P(""); #define VSC_DO_VBE -#include "vsc_fields.h" +#include "tbl/vsc_fields.h" #undef VSC_DO_VBE return 0; From phk at varnish-cache.org Sat Oct 8 14:43:30 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 16:43:30 +0200 Subject: [master] 8b98c9e Move more table-generating #includes into tbl/ subdir Message-ID: commit 8b98c9ed9befa096e2fe0b862ed9720a71e33646 Author: Poul-Henning Kamp Date: Sat Oct 8 14:43:13 2011 +0000 Move more table-generating #includes into tbl/ subdir diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 11e952e..f46634a 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -804,7 +804,7 @@ ssize_t HTC_Read(struct http_conn *htc, void *d, size_t len); int HTC_Complete(struct http_conn *htc); #define HTTPH(a, b, c, d, e, f, g) extern char b[]; -#include "http_headers.h" +#include "tbl/http_headers.h" #undef HTTPH /* cache_main.c */ @@ -924,7 +924,7 @@ void VCL_Rel(struct VCL_conf **vcc); void VCL_Poll(void); #define VCL_MET_MAC(l,u,b) void VCL_##l##_method(struct sess *); -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_MET_MAC /* cache_vrt.c */ diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index 97d961d..fe1efd0 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -127,7 +127,7 @@ static const struct pvar { uint8_t tag; } pvars[] = { #define PVAR(a, b, c) { (a), (b), (c) }, -#include "ban_vars.h" +#include "tbl/ban_vars.h" #undef PVAR { 0, 0, 0} }; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index 25a6627..bd0380b 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -41,7 +41,7 @@ #include "cache.h" #define HTTPH(a, b, c, d, e, f, g) char b[] = "*" a ":"; -#include "http_headers.h" +#include "tbl/http_headers.h" #undef HTTPH /*lint -save -e773 not () */ @@ -91,7 +91,7 @@ static struct http_msg { const char *txt; } http_msg[] = { #define HTTP_RESP(n, t) { n, t}, -#include "http_response.h" +#include "tbl/http_response.h" { 0, NULL } }; @@ -830,7 +830,7 @@ http_EstimateWS(const struct http *fm, unsigned how, uint16_t *nhd) #define HTTPH(a, b, c, d, e, f, g) \ if (((e) & how) && http_IsHdr(&fm->hd[u], (b))) \ continue; -#include "http_headers.h" +#include "tbl/http_headers.h" #undef HTTPH l += PRNDUP(Tlen(fm->hd[u]) + 1); (*nhd)++; @@ -859,7 +859,7 @@ http_FilterFields(struct worker *w, unsigned vsl_id, struct http *to, #define HTTPH(a, b, c, d, e, f, g) \ if (((e) & how) && http_IsHdr(&fm->hd[u], (b))) \ continue; -#include "http_headers.h" +#include "tbl/http_headers.h" #undef HTTPH http_copyheader(w, vsl_id, to, fm, u); } @@ -1111,6 +1111,6 @@ HTTP_Init(void) { #define HTTPH(a, b, c, d, e, f, g) b[0] = (char)strlen(b + 1); -#include "http_headers.h" +#include "tbl/http_headers.h" #undef HTTPH } diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c index ac712fb..8848ddd 100644 --- a/bin/varnishd/cache_vcl.c +++ b/bin/varnishd/cache_vcl.c @@ -331,7 +331,7 @@ VCL_##func##_method(struct sess *sp) \ assert(!((1U << sp->handling) & ~bitmap)); \ } -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_MET_MAC /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index c1e52cb..143e534 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -597,5 +597,5 @@ VRT_Stv_##nm(const char *nm) \ return (stv->var_##nm(stv)); \ } -#include "vrt_stv_var.h" +#include "tbl/vrt_stv_var.h" #undef VRTSTVVAR diff --git a/bin/varnishd/stevedore.h b/bin/varnishd/stevedore.h index 0ccf834..9cd0b7b 100644 --- a/bin/varnishd/stevedore.h +++ b/bin/varnishd/stevedore.h @@ -47,7 +47,7 @@ typedef void storage_close_f(const struct stevedore *); /* Prototypes for VCL variable responders */ #define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); -#include "vrt_stv_var.h" +#include "tbl/vrt_stv_var.h" #undef VRTSTVTYPE /*--------------------------------------------------------------------*/ @@ -77,7 +77,7 @@ struct stevedore { struct lru *lru; #define VRTSTVVAR(nm, vtype, ctype, dval) storage_var_##ctype *var_##nm; -#include "vrt_stv_var.h" +#include "tbl/vrt_stv_var.h" #undef VRTSTVVAR /* private fields */ diff --git a/include/Makefile.am b/include/Makefile.am index 3f2994c..de1b19a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -11,7 +11,7 @@ pkginclude_HEADERS = \ vsm.h nobase_noinst_HEADERS = \ - ban_vars.h \ + tbl/ban_vars.h \ binary_heap.h \ cli_common.h \ cli_priv.h \ @@ -20,8 +20,8 @@ nobase_noinst_HEADERS = \ compat/execinfo.h \ compat/srandomdev.h \ flopen.h \ - http_headers.h \ - http_response.h \ + tbl/http_headers.h \ + tbl/http_response.h \ libvarnish.h \ libvcl.h \ miniobj.h \ @@ -98,7 +98,9 @@ vmod_abi.h: vcs_version.h fi ; \ echo "#define VMOD_ABI_Version \"@PACKAGE_STRING@ $$GITID\"" > vmod_abi.h -CLEANFILES = vcl_returns.h \ +CLEANFILES = \ + tbl/vcl_returns.h \ + tbl/vrt_stv_var.h \ vcl.h \ vrt_obj.h \ vmod_abi.h diff --git a/include/ban_vars.h b/include/ban_vars.h deleted file mode 100644 index 669b9b1..0000000 --- a/include/ban_vars.h +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Define which variables we can ban on, and which function does it. - * - */ - -#define PVAR_HTTP 1 -#define PVAR_REQ 2 - -PVAR("req.url", PVAR_REQ, BAN_ARG_URL) -PVAR("req.http.", PVAR_REQ|PVAR_HTTP, BAN_ARG_REQHTTP) -PVAR("obj.http.", PVAR_HTTP, BAN_ARG_OBJHTTP) diff --git a/include/http_headers.h b/include/http_headers.h deleted file mode 100644 index afb463c..0000000 --- a/include/http_headers.h +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - * Argument list: - * --------------------------------------- - * a Http header name - * b session field name - * c Request(1)/Response(2) bitfield - * d (obsolete) - * e Supress header in filter ops - * f unused - * g unused - * - * see [RFC2616 13.5.1 End-to-end and Hop-by-hop Headers] - * - */ - -/*lint -save -e525 -e539 */ - -#ifndef HTTPH_R_PASS -#define HTTPH_R_PASS (1 << 0) /* Request (c->b) in pass mode */ -#define HTTPH_A_PASS (1 << 1) /* Response (b->c)in pass mode */ -#define HTTPH_R_PIPE (1 << 2) /* Request (c->b) in pipe mode */ -#define HTTPH_R_FETCH (1 << 3) /* Request (c->b) for fetch */ -#define HTTPH_A_INS (1 << 4) /* Response (b->o) for insert */ -#define HTTPH_A_DELIVER (1 << 5) /* Response (o->c) for deliver */ -#endif - -HTTPH("Keep-Alive", H_Keep_Alive, 3, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH, 0, 0) /* RFC2068 */ -HTTPH("Accept", H_Accept, 1, 0, 0, 0, 0) /* RFC2616 14.1 */ -HTTPH("Accept-Charset", H_Accept_Charset, 1, 0, 0, 0, 0) /* RFC2616 14.2 */ -HTTPH("Accept-Encoding", H_Accept_Encoding, 1, 0, 0, 0, 0) /* RFC2616 14.3 */ -HTTPH("Accept-Language", H_Accept_Language, 1, 0, 0, 0, 0) /* RFC2616 14.4 */ -HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.5 */ -HTTPH("Age", H_Age, 2, 0, HTTPH_A_INS, 0, 0) /* RFC2616 14.6 */ -HTTPH("Allow", H_Allow, 2, 0, 0, 0, 0) /* RFC2616 14.7 */ -HTTPH("Authorization", H_Authorization, 1, 0, 0, 0, 0) /* RFC2616 14.8 */ -HTTPH("Cache-Control", H_Cache_Control, 3, 3, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.9 */ -HTTPH("Connection", H_Connection, 3, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.10 */ -HTTPH("Content-Encoding", H_Content_Encoding, 2, 0, 0, 0, 0) /* RFC2616 14.11 */ -HTTPH("Content-Langugae", H_Content_Language, 2, 0, 0, 0, 0) /* RFC2616 14.12 */ -HTTPH("Content-Length", H_Content_Length, 2, 2, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.13 */ -HTTPH("Content-Location", H_Content_Location, 2, 0, 0, 0, 0) /* RFC2616 14.14 */ -HTTPH("Content-MD5", H_Content_MD5, 2, 0, 0, 0, 0) /* RFC2616 14.15 */ -HTTPH("Content-Range", H_Content_Range, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.16 */ -HTTPH("Content-Type", H_Content_Type, 2, 0, 0, 0, 0) /* RFC2616 14.17 */ -HTTPH("Date", H_Date, 2, 0, HTTPH_A_DELIVER, 0, 0) /* RFC2616 14.18 */ -HTTPH("ETag", H_ETag, 2, 0, 0, 0, 0) /* RFC2616 14.19 */ -HTTPH("Expect", H_Expect, 1, 0, 0, 0, 0) /* RFC2616 14.20 */ -HTTPH("Expires", H_Expires, 2, 0, 0, 0, 0) /* RFC2616 14.21 */ -HTTPH("From", H_From, 1, 0, 0, 0, 0) /* RFC2616 14.22 */ -HTTPH("Host", H_Host, 1, 0, 0, 0, 0) /* RFC2616 14.23 */ -HTTPH("If-Match", H_If_Match, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.24 */ -HTTPH("If-Modified-Since", H_If_Modified_Since, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.25 */ -HTTPH("If-None-Match", H_If_None_Match, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.26 */ -HTTPH("If-Range", H_If_Range, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.27 */ -HTTPH("If-Unmodified-Since", H_If_Unmodifed_Since, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.28 */ -HTTPH("Last-Modified", H_Last_Modified, 2, 0, 0, 0, 0) /* RFC2616 14.29 */ -HTTPH("Location", H_Location, 2, 0, 0, 0, 0) /* RFC2616 14.30 */ -HTTPH("Max-Forwards", H_Max_Forwards, 1, 0, 0, 0, 0) /* RFC2616 14.31 */ -HTTPH("Pragma", H_Pragma, 1, 0, 0, 0, 0) /* RFC2616 14.32 */ -HTTPH("Proxy-Authenticate", H_Proxy_Authenticate, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.33 */ -HTTPH("Proxy-Authorization", H_Proxy_Authorization, 1, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.34 */ -HTTPH("Range", H_Range, 1, 0, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.35 */ -HTTPH("Referer", H_Referer, 1, 0, 0, 0, 0) /* RFC2616 14.36 */ -HTTPH("Retry-After", H_Retry_After, 2, 0, 0, 0, 0) /* RFC2616 14.37 */ -HTTPH("Server", H_Server, 2, 0, 0, 0, 0) /* RFC2616 14.38 */ -HTTPH("TE", H_TE, 1, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.39 */ -HTTPH("Trailer", H_Trailer, 1, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.40 */ -HTTPH("Transfer-Encoding", H_Transfer_Encoding, 2, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.41 */ -HTTPH("Upgrade", H_Upgrade, 2, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.42 */ -HTTPH("User-Agent", H_User_Agent, 1, 0, 0, 0, 0) /* RFC2616 14.43 */ -HTTPH("Vary", H_Vary, 2, 0, 0, 0, 0) /* RFC2616 14.44 */ -HTTPH("Via", H_Via, 2, 0, 0, 0, 0) /* RFC2616 14.45 */ -HTTPH("Warning", H_Warning, 2, 0, 0, 0, 0) /* RFC2616 14.46 */ -HTTPH("WWW-Authenticate", H_WWW_Authenticate, 2, 0, 0, 0, 0) /* RFC2616 14.47 */ - -/*lint -restore */ diff --git a/include/http_response.h b/include/http_response.h deleted file mode 100644 index f60820c..0000000 --- a/include/http_response.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - */ - -HTTP_RESP(101, "Switching Protocols") -HTTP_RESP(200, "OK") -HTTP_RESP(201, "Created") -HTTP_RESP(202, "Accepted") -HTTP_RESP(203, "Non-Authoritative Information") -HTTP_RESP(204, "No Content") -HTTP_RESP(205, "Reset Content") -HTTP_RESP(206, "Partial Content") -HTTP_RESP(300, "Multiple Choices") -HTTP_RESP(301, "Moved Permanently") -HTTP_RESP(302, "Found") -HTTP_RESP(303, "See Other") -HTTP_RESP(304, "Not Modified") -HTTP_RESP(305, "Use Proxy") -HTTP_RESP(306, "(Unused)") -HTTP_RESP(307, "Temporary Redirect") -HTTP_RESP(400, "Bad Request") -HTTP_RESP(401, "Unauthorized") -HTTP_RESP(402, "Payment Required") -HTTP_RESP(403, "Forbidden") -HTTP_RESP(404, "Not Found") -HTTP_RESP(405, "Method Not Allowed") -HTTP_RESP(406, "Not Acceptable") -HTTP_RESP(407, "Proxy Authentication Required") -HTTP_RESP(408, "Request Timeout") -HTTP_RESP(409, "Conflict") -HTTP_RESP(410, "Gone") -HTTP_RESP(411, "Length Required") -HTTP_RESP(412, "Precondition Failed") -HTTP_RESP(413, "Request Entity Too Large") -HTTP_RESP(414, "Request-URI Too Long") -HTTP_RESP(415, "Unsupported Media Type") -HTTP_RESP(416, "Requested Range Not Satisfiable") -HTTP_RESP(417, "Expectation Failed") -HTTP_RESP(500, "Internal Server Error") -HTTP_RESP(501, "Not Implemented") -HTTP_RESP(502, "Bad Gateway") -HTTP_RESP(503, "Service Unavailable") -HTTP_RESP(504, "Gateway Timeout") -HTTP_RESP(505, "HTTP Version Not Supported") diff --git a/include/tbl/ban_vars.h b/include/tbl/ban_vars.h new file mode 100644 index 0000000..669b9b1 --- /dev/null +++ b/include/tbl/ban_vars.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Define which variables we can ban on, and which function does it. + * + */ + +#define PVAR_HTTP 1 +#define PVAR_REQ 2 + +PVAR("req.url", PVAR_REQ, BAN_ARG_URL) +PVAR("req.http.", PVAR_REQ|PVAR_HTTP, BAN_ARG_REQHTTP) +PVAR("obj.http.", PVAR_HTTP, BAN_ARG_OBJHTTP) diff --git a/include/tbl/http_headers.h b/include/tbl/http_headers.h new file mode 100644 index 0000000..afb463c --- /dev/null +++ b/include/tbl/http_headers.h @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + * Argument list: + * --------------------------------------- + * a Http header name + * b session field name + * c Request(1)/Response(2) bitfield + * d (obsolete) + * e Supress header in filter ops + * f unused + * g unused + * + * see [RFC2616 13.5.1 End-to-end and Hop-by-hop Headers] + * + */ + +/*lint -save -e525 -e539 */ + +#ifndef HTTPH_R_PASS +#define HTTPH_R_PASS (1 << 0) /* Request (c->b) in pass mode */ +#define HTTPH_A_PASS (1 << 1) /* Response (b->c)in pass mode */ +#define HTTPH_R_PIPE (1 << 2) /* Request (c->b) in pipe mode */ +#define HTTPH_R_FETCH (1 << 3) /* Request (c->b) for fetch */ +#define HTTPH_A_INS (1 << 4) /* Response (b->o) for insert */ +#define HTTPH_A_DELIVER (1 << 5) /* Response (o->c) for deliver */ +#endif + +HTTPH("Keep-Alive", H_Keep_Alive, 3, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH, 0, 0) /* RFC2068 */ +HTTPH("Accept", H_Accept, 1, 0, 0, 0, 0) /* RFC2616 14.1 */ +HTTPH("Accept-Charset", H_Accept_Charset, 1, 0, 0, 0, 0) /* RFC2616 14.2 */ +HTTPH("Accept-Encoding", H_Accept_Encoding, 1, 0, 0, 0, 0) /* RFC2616 14.3 */ +HTTPH("Accept-Language", H_Accept_Language, 1, 0, 0, 0, 0) /* RFC2616 14.4 */ +HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.5 */ +HTTPH("Age", H_Age, 2, 0, HTTPH_A_INS, 0, 0) /* RFC2616 14.6 */ +HTTPH("Allow", H_Allow, 2, 0, 0, 0, 0) /* RFC2616 14.7 */ +HTTPH("Authorization", H_Authorization, 1, 0, 0, 0, 0) /* RFC2616 14.8 */ +HTTPH("Cache-Control", H_Cache_Control, 3, 3, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.9 */ +HTTPH("Connection", H_Connection, 3, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.10 */ +HTTPH("Content-Encoding", H_Content_Encoding, 2, 0, 0, 0, 0) /* RFC2616 14.11 */ +HTTPH("Content-Langugae", H_Content_Language, 2, 0, 0, 0, 0) /* RFC2616 14.12 */ +HTTPH("Content-Length", H_Content_Length, 2, 2, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.13 */ +HTTPH("Content-Location", H_Content_Location, 2, 0, 0, 0, 0) /* RFC2616 14.14 */ +HTTPH("Content-MD5", H_Content_MD5, 2, 0, 0, 0, 0) /* RFC2616 14.15 */ +HTTPH("Content-Range", H_Content_Range, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.16 */ +HTTPH("Content-Type", H_Content_Type, 2, 0, 0, 0, 0) /* RFC2616 14.17 */ +HTTPH("Date", H_Date, 2, 0, HTTPH_A_DELIVER, 0, 0) /* RFC2616 14.18 */ +HTTPH("ETag", H_ETag, 2, 0, 0, 0, 0) /* RFC2616 14.19 */ +HTTPH("Expect", H_Expect, 1, 0, 0, 0, 0) /* RFC2616 14.20 */ +HTTPH("Expires", H_Expires, 2, 0, 0, 0, 0) /* RFC2616 14.21 */ +HTTPH("From", H_From, 1, 0, 0, 0, 0) /* RFC2616 14.22 */ +HTTPH("Host", H_Host, 1, 0, 0, 0, 0) /* RFC2616 14.23 */ +HTTPH("If-Match", H_If_Match, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.24 */ +HTTPH("If-Modified-Since", H_If_Modified_Since, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.25 */ +HTTPH("If-None-Match", H_If_None_Match, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.26 */ +HTTPH("If-Range", H_If_Range, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.27 */ +HTTPH("If-Unmodified-Since", H_If_Unmodifed_Since, 1, 1, HTTPH_R_FETCH, 0, 0) /* RFC2616 14.28 */ +HTTPH("Last-Modified", H_Last_Modified, 2, 0, 0, 0, 0) /* RFC2616 14.29 */ +HTTPH("Location", H_Location, 2, 0, 0, 0, 0) /* RFC2616 14.30 */ +HTTPH("Max-Forwards", H_Max_Forwards, 1, 0, 0, 0, 0) /* RFC2616 14.31 */ +HTTPH("Pragma", H_Pragma, 1, 0, 0, 0, 0) /* RFC2616 14.32 */ +HTTPH("Proxy-Authenticate", H_Proxy_Authenticate, 2, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.33 */ +HTTPH("Proxy-Authorization", H_Proxy_Authorization, 1, 3, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.34 */ +HTTPH("Range", H_Range, 1, 0, HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.35 */ +HTTPH("Referer", H_Referer, 1, 0, 0, 0, 0) /* RFC2616 14.36 */ +HTTPH("Retry-After", H_Retry_After, 2, 0, 0, 0, 0) /* RFC2616 14.37 */ +HTTPH("Server", H_Server, 2, 0, 0, 0, 0) /* RFC2616 14.38 */ +HTTPH("TE", H_TE, 1, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.39 */ +HTTPH("Trailer", H_Trailer, 1, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.40 */ +HTTPH("Transfer-Encoding", H_Transfer_Encoding, 2, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.41 */ +HTTPH("Upgrade", H_Upgrade, 2, 3, HTTPH_R_PASS | HTTPH_A_PASS | HTTPH_R_FETCH | HTTPH_A_INS, 0, 0) /* RFC2616 14.42 */ +HTTPH("User-Agent", H_User_Agent, 1, 0, 0, 0, 0) /* RFC2616 14.43 */ +HTTPH("Vary", H_Vary, 2, 0, 0, 0, 0) /* RFC2616 14.44 */ +HTTPH("Via", H_Via, 2, 0, 0, 0, 0) /* RFC2616 14.45 */ +HTTPH("Warning", H_Warning, 2, 0, 0, 0, 0) /* RFC2616 14.46 */ +HTTPH("WWW-Authenticate", H_WWW_Authenticate, 2, 0, 0, 0, 0) /* RFC2616 14.47 */ + +/*lint -restore */ diff --git a/include/tbl/http_response.h b/include/tbl/http_response.h new file mode 100644 index 0000000..f60820c --- /dev/null +++ b/include/tbl/http_response.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + */ + +HTTP_RESP(101, "Switching Protocols") +HTTP_RESP(200, "OK") +HTTP_RESP(201, "Created") +HTTP_RESP(202, "Accepted") +HTTP_RESP(203, "Non-Authoritative Information") +HTTP_RESP(204, "No Content") +HTTP_RESP(205, "Reset Content") +HTTP_RESP(206, "Partial Content") +HTTP_RESP(300, "Multiple Choices") +HTTP_RESP(301, "Moved Permanently") +HTTP_RESP(302, "Found") +HTTP_RESP(303, "See Other") +HTTP_RESP(304, "Not Modified") +HTTP_RESP(305, "Use Proxy") +HTTP_RESP(306, "(Unused)") +HTTP_RESP(307, "Temporary Redirect") +HTTP_RESP(400, "Bad Request") +HTTP_RESP(401, "Unauthorized") +HTTP_RESP(402, "Payment Required") +HTTP_RESP(403, "Forbidden") +HTTP_RESP(404, "Not Found") +HTTP_RESP(405, "Method Not Allowed") +HTTP_RESP(406, "Not Acceptable") +HTTP_RESP(407, "Proxy Authentication Required") +HTTP_RESP(408, "Request Timeout") +HTTP_RESP(409, "Conflict") +HTTP_RESP(410, "Gone") +HTTP_RESP(411, "Length Required") +HTTP_RESP(412, "Precondition Failed") +HTTP_RESP(413, "Request Entity Too Large") +HTTP_RESP(414, "Request-URI Too Long") +HTTP_RESP(415, "Unsupported Media Type") +HTTP_RESP(416, "Requested Range Not Satisfiable") +HTTP_RESP(417, "Expectation Failed") +HTTP_RESP(500, "Internal Server Error") +HTTP_RESP(501, "Not Implemented") +HTTP_RESP(502, "Bad Gateway") +HTTP_RESP(503, "Service Unavailable") +HTTP_RESP(504, "Gateway Timeout") +HTTP_RESP(505, "HTTP Version Not Supported") diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index 779091e..335cfd5 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -671,7 +671,7 @@ for i in returns: ####################################################################### -fo = open(buildroot + "/include/vcl_returns.h", "w") +fo = open(buildroot + "/include/tbl/vcl_returns.h", "w") file_header(fo) @@ -891,7 +891,7 @@ fo.close() ####################################################################### -fo = open(buildroot + "/include/vrt_stv_var.h", "w") +fo = open(buildroot + "/include/tbl/vrt_stv_var.h", "w") file_header(fo) diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 8c538ef..c11f5b2 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -269,7 +269,7 @@ parse_return(struct vcc *tl) retval = 1; \ } \ } while (0); -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_RET_MAC if (!retval) { VSB_printf(tl->sb, "Expected return action name.\n"); @@ -330,7 +330,7 @@ static struct action_table { #define VCL_RET_MAC(l, U, B) \ { #l, parse_new_syntax }, -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_RET_MAC /* Keep list sorted from here */ diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index 36efa4b..a09f396 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -70,7 +70,7 @@ struct method method_tab[] = { #define VCL_MET_MAC(l,U,m) { "vcl_"#l, m, VCL_MET_##U }, -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_MET_MAC { NULL, 0U, 0} }; @@ -374,7 +374,7 @@ EmitStruct(const struct vcc *tl) Fc(tl, 0, "\t.srcbody = srcbody,\n"); #define VCL_MET_MAC(l,u,b) \ Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_MET_MAC Fc(tl, 0, "};\n"); } @@ -722,7 +722,7 @@ VCC_Return_Name(unsigned method) switch (method) { #define VCL_RET_MAC(l, U, B) case VCL_RET_##U: return(#l); -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_RET_MAC default: return (NULL); diff --git a/lib/libvcl/vcc_storage.c b/lib/libvcl/vcc_storage.c index 77c657c..5aff6e7 100644 --- a/lib/libvcl/vcc_storage.c +++ b/lib/libvcl/vcc_storage.c @@ -80,7 +80,7 @@ vcc_Stv_mkvar(struct vcc *tl, const struct token *t, enum var_type fmt) v->name = TlDupTok(tl, t); v->r_methods = 0 #define VCL_MET_MAC(l,u,b) | VCL_MET_##u -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_MET_MAC ; v->fmt = fmt; @@ -93,7 +93,7 @@ static struct stvars { enum var_type fmt; } stvars[] = { #define VRTSTVVAR(nm, vtype, ctype, dval) { #nm, vtype }, -#include "vrt_stv_var.h" +#include "tbl/vrt_stv_var.h" #undef VRTSTVVAR { NULL, BOOL } }; diff --git a/lib/libvcl/vcc_xref.c b/lib/libvcl/vcc_xref.c index 560fe78..56a2747 100644 --- a/lib/libvcl/vcc_xref.c +++ b/lib/libvcl/vcc_xref.c @@ -226,7 +226,7 @@ vcc_CheckActionRecurse(struct vcc *tl, struct proc *p, unsigned bitmap) VSB_printf(tl->sb, "Invalid return \"" #l "\"\n");\ vcc_ErrWhere(tl, p->return_tok[VCL_RET_##U]); \ } -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_RET_MAC VSB_printf(tl->sb, "\n...in subroutine \"%.*s\"\n", @@ -271,7 +271,7 @@ vcc_checkaction1(struct vcc *tl, const struct symbol *sym) if (m->ret_bitmap & ((1 << VCL_RET_##U))) \ VSB_printf(tl->sb, " \"%s\"", #l); -#include "vcl_returns.h" +#include "tbl/vcl_returns.h" #undef VCL_RET_MAC VSB_printf(tl->sb, "\n"); tl->err = 1; From phk at varnish-cache.org Sat Oct 8 14:57:06 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 16:57:06 +0200 Subject: [master] 17937b2 Move the varnishd table building #includes under tbl/ as well. Message-ID: commit 17937b2954fb6b422d8c7b9b0b68a95f46fc825b Author: Poul-Henning Kamp Date: Sat Oct 8 14:56:41 2011 +0000 Move the varnishd table building #includes under tbl/ as well. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 0dbc745..b1f2a5c 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -78,21 +78,16 @@ varnishd_SOURCES = \ vsm.c noinst_HEADERS = \ - acct_fields.h \ - body_status.h \ cache.h \ cache_backend.h \ - cache_backend_poll.h \ cache_esi.h \ cache_waiter.h \ common.h \ default_vcl.h \ hash_slinger.h \ heritage.h \ - locks.h \ mgt.h \ mgt_cli.h \ - steps.h \ stevedore.h \ storage_persistent.h \ vparam.h diff --git a/bin/varnishd/acct_fields.h b/bin/varnishd/acct_fields.h deleted file mode 100644 index 154f106..0000000 --- a/bin/varnishd/acct_fields.h +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * Copyright (c) 2008 Verdens Gang AS - * Copyright (c) 2008-2009 Varnish Software 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. - * - * These are the stats we keep track of per session. They will be summed, - * via the sp->wrk->stats into the s_ fields in the SHM file. - * NB: Remember to mark those in vsc_fields.h to be included in struct dstat. - */ - -ACCT(sess) -ACCT(req) -ACCT(pipe) -ACCT(pass) -ACCT(fetch) -ACCT(hdrbytes) -ACCT(bodybytes) diff --git a/bin/varnishd/body_status.h b/bin/varnishd/body_status.h deleted file mode 100644 index 33803f9..0000000 --- a/bin/varnishd/body_status.h +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * Copyright (c) 2011 Varnish Software 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. - * - * Various ways to handle the body coming from the backend. - */ - -/*lint -save -e525 -e539 */ -BODYSTATUS(NONE, none) -BODYSTATUS(ZERO, zero) -BODYSTATUS(ERROR, error) -BODYSTATUS(CHUNKED, chunked) -BODYSTATUS(LENGTH, length) -BODYSTATUS(EOF, eof) -/*lint -restore */ diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index f46634a..c9b3ac2 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -67,7 +67,7 @@ enum body_status { #define BODYSTATUS(U,l) BS_##U, -#include "body_status.h" +#include "tbl/body_status.h" #undef BODYSTATUS }; @@ -76,7 +76,7 @@ body_status(enum body_status e) { switch(e) { #define BODYSTATUS(U,l) case BS_##U: return (#l); -#include "body_status.h" +#include "tbl/body_status.h" #undef BODYSTATUS default: return ("?"); @@ -143,7 +143,7 @@ typedef struct { enum step { #define STEP(l, u) STP_##u, -#include "steps.h" +#include "tbl/steps.h" #undef STEP }; @@ -213,7 +213,7 @@ struct http_conn { struct acct { double first; #define ACCT(foo) uint64_t foo; -#include "acct_fields.h" +#include "tbl/acct_fields.h" #undef ACCT }; @@ -834,7 +834,7 @@ int Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts); #define Lck_AssertHeld(a) Lck__Assert(a, 1) #define LOCK(nam) extern struct VSC_C_lck *lck_##nam; -#include "locks.h" +#include "tbl/locks.h" #undef LOCK /* cache_panic.c */ diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index 5fae557..be8ee6a 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -78,7 +78,7 @@ struct vbp_target { /* Collected statistics */ #define BITMAP(n, c, t, b) uint64_t n; -#include "cache_backend_poll.h" +#include "tbl/backend_poll.h" #undef BITMAP double last; @@ -236,7 +236,7 @@ vbp_start_poke(struct vbp_target *vt) CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC); #define BITMAP(n, c, t, b) vt->n <<= 1; -#include "cache_backend_poll.h" +#include "tbl/backend_poll.h" #undef BITMAP vt->last = 0; @@ -262,7 +262,7 @@ vbp_has_poked(struct vbp_target *vt) i = 0; #define BITMAP(n, c, t, b) bits[i++] = (vt->n & 1) ? c : '-'; -#include "cache_backend_poll.h" +#include "tbl/backend_poll.h" #undef BITMAP bits[i] = '\0'; @@ -396,7 +396,7 @@ vbp_health_one(struct cli *cli, const struct vbp_target *vt) #define BITMAP(n, c, t, b) \ if ((vt->n != 0) || (b)) \ vbp_bitmap(cli, (c), vt->n, (t)); -#include "cache_backend_poll.h" +#include "tbl/backend_poll.h" #undef BITMAP } diff --git a/bin/varnishd/cache_backend_poll.h b/bin/varnishd/cache_backend_poll.h deleted file mode 100644 index a9ee3a3..0000000 --- a/bin/varnishd/cache_backend_poll.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - */ - -BITMAP(good_ipv4, '4', "Good IPv4", 0) -BITMAP(good_ipv6, '6', "Good IPv6", 0) -BITMAP( err_xmit, 'x', "Error Xmit", 0) -BITMAP(good_xmit, 'X', "Good Xmit", 0) -BITMAP( err_recv, 'r', "Error Recv", 0) -BITMAP(good_recv, 'R', "Good Recv", 0) -BITMAP(happy, 'H', "Happy", 1) diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index b4a056d..7e91137 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -1605,7 +1605,7 @@ CNT_Session(struct sess *sp) cnt_diag(sp, #u); \ done = cnt_##l(sp); \ break; -#include "steps.h" +#include "tbl/steps.h" #undef STEP default: WRONG("State engine misfire"); @@ -1621,7 +1621,7 @@ CNT_Session(struct sess *sp) AZ(w->do_gunzip); AZ(w->do_esi); #define ACCT(foo) AZ(w->acct_tmp.foo); -#include "acct_fields.h" +#include "tbl/acct_fields.h" #undef ACCT assert(WRW_IsReleased(w)); } diff --git a/bin/varnishd/cache_lck.c b/bin/varnishd/cache_lck.c index b9229b3..18d1b41 100644 --- a/bin/varnishd/cache_lck.c +++ b/bin/varnishd/cache_lck.c @@ -196,7 +196,7 @@ Lck_Delete(struct lock *lck) } #define LOCK(nam) struct VSC_C_lck *lck_##nam; -#include "locks.h" +#include "tbl/locks.h" #undef LOCK void @@ -207,6 +207,6 @@ LCK_Init(void) #define LOCK(nam) \ lck_##nam = VSM_Alloc(sizeof(struct VSC_C_lck), \ VSC_CLASS, VSC_TYPE_LCK, #nam); -#include "locks.h" +#include "tbl/locks.h" #undef LOCK } diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index 8ca1b4f..a9c5c15 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -223,7 +223,7 @@ pan_sess(const struct sess *sp) sp->port ? sp->port : "?"); switch (sp->step) { #define STEP(l, u) case STP_##u: stp = "STP_" #u; break; -#include "steps.h" +#include "tbl/steps.h" #undef STEP default: stp = NULL; } diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c index 1f500ba..bb96780 100644 --- a/bin/varnishd/cache_session.c +++ b/bin/varnishd/cache_session.c @@ -83,7 +83,7 @@ SES_Charge(struct sess *sp) sp->wrk->stats.s_##foo += a->foo; \ sp->acct_ses.foo += a->foo; \ a->foo = 0; -#include "acct_fields.h" +#include "tbl/acct_fields.h" #undef ACCT } diff --git a/bin/varnishd/locks.h b/bin/varnishd/locks.h deleted file mode 100644 index f1b634b..0000000 --- a/bin/varnishd/locks.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2010 Varnish Software 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. - * - */ - -/*lint -save -e525 -e539 */ -LOCK(sms) -LOCK(smp) -LOCK(sma) -LOCK(smf) -LOCK(hsl) -LOCK(hcb) -LOCK(hcl) -LOCK(vcl) -LOCK(sessmem) -LOCK(wstat) -LOCK(herder) -LOCK(wq) -LOCK(objhdr) -LOCK(exp) -LOCK(lru) -LOCK(cli) -LOCK(ban) -LOCK(vbp) -LOCK(vbe) -LOCK(backend) -LOCK(vcapace) -/*lint -restore */ diff --git a/bin/varnishd/steps.h b/bin/varnishd/steps.h deleted file mode 100644 index c88e434..0000000 --- a/bin/varnishd/steps.h +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -/*lint -save -e525 -e539 */ -STEP(wait, WAIT) -STEP(first, FIRST) -STEP(recv, RECV) -STEP(start, START) -STEP(pipe, PIPE) -STEP(pass, PASS) -STEP(lookup, LOOKUP) -STEP(miss, MISS) -STEP(hit, HIT) -STEP(fetch, FETCH) -STEP(fetchbody, FETCHBODY) -STEP(streambody,STREAMBODY) -STEP(prepresp, PREPRESP) -STEP(deliver, DELIVER) -STEP(error, ERROR) -STEP(done, DONE) -/*lint -restore */ diff --git a/include/Makefile.am b/include/Makefile.am index de1b19a..652689b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,11 @@ # pkginclude_HEADERS = \ + tbl/acct_fields.h \ + tbl/backend_poll.h \ + tbl/body_status.h \ + tbl/locks.h \ + tbl/steps.h \ tbl/vsc_all.h \ tbl/vsc_fields.h \ tbl/vsl_tags.h \ diff --git a/include/tbl/acct_fields.h b/include/tbl/acct_fields.h new file mode 100644 index 0000000..154f106 --- /dev/null +++ b/include/tbl/acct_fields.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2008 Verdens Gang AS + * Copyright (c) 2008-2009 Varnish Software 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. + * + * These are the stats we keep track of per session. They will be summed, + * via the sp->wrk->stats into the s_ fields in the SHM file. + * NB: Remember to mark those in vsc_fields.h to be included in struct dstat. + */ + +ACCT(sess) +ACCT(req) +ACCT(pipe) +ACCT(pass) +ACCT(fetch) +ACCT(hdrbytes) +ACCT(bodybytes) diff --git a/include/tbl/backend_poll.h b/include/tbl/backend_poll.h new file mode 100644 index 0000000..a9ee3a3 --- /dev/null +++ b/include/tbl/backend_poll.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + */ + +BITMAP(good_ipv4, '4', "Good IPv4", 0) +BITMAP(good_ipv6, '6', "Good IPv6", 0) +BITMAP( err_xmit, 'x', "Error Xmit", 0) +BITMAP(good_xmit, 'X', "Good Xmit", 0) +BITMAP( err_recv, 'r', "Error Recv", 0) +BITMAP(good_recv, 'R', "Good Recv", 0) +BITMAP(happy, 'H', "Happy", 1) diff --git a/include/tbl/body_status.h b/include/tbl/body_status.h new file mode 100644 index 0000000..33803f9 --- /dev/null +++ b/include/tbl/body_status.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2011 Varnish Software 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. + * + * Various ways to handle the body coming from the backend. + */ + +/*lint -save -e525 -e539 */ +BODYSTATUS(NONE, none) +BODYSTATUS(ZERO, zero) +BODYSTATUS(ERROR, error) +BODYSTATUS(CHUNKED, chunked) +BODYSTATUS(LENGTH, length) +BODYSTATUS(EOF, eof) +/*lint -restore */ diff --git a/include/tbl/locks.h b/include/tbl/locks.h new file mode 100644 index 0000000..f1b634b --- /dev/null +++ b/include/tbl/locks.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2010 Varnish Software 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. + * + */ + +/*lint -save -e525 -e539 */ +LOCK(sms) +LOCK(smp) +LOCK(sma) +LOCK(smf) +LOCK(hsl) +LOCK(hcb) +LOCK(hcl) +LOCK(vcl) +LOCK(sessmem) +LOCK(wstat) +LOCK(herder) +LOCK(wq) +LOCK(objhdr) +LOCK(exp) +LOCK(lru) +LOCK(cli) +LOCK(ban) +LOCK(vbp) +LOCK(vbe) +LOCK(backend) +LOCK(vcapace) +/*lint -restore */ diff --git a/include/tbl/steps.h b/include/tbl/steps.h new file mode 100644 index 0000000..c88e434 --- /dev/null +++ b/include/tbl/steps.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/*lint -save -e525 -e539 */ +STEP(wait, WAIT) +STEP(first, FIRST) +STEP(recv, RECV) +STEP(start, START) +STEP(pipe, PIPE) +STEP(pass, PASS) +STEP(lookup, LOOKUP) +STEP(miss, MISS) +STEP(hit, HIT) +STEP(fetch, FETCH) +STEP(fetchbody, FETCHBODY) +STEP(streambody,STREAMBODY) +STEP(prepresp, PREPRESP) +STEP(deliver, DELIVER) +STEP(error, ERROR) +STEP(done, DONE) +/*lint -restore */ From phk at varnish-cache.org Sat Oct 8 15:21:43 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 17:21:43 +0200 Subject: [master] 272aaa3 Exempt all tbl/* includes from multiple include guards (451) Message-ID: commit 272aaa35e1f8fa1a56bff758ac92a0ff4a94869b Author: Poul-Henning Kamp Date: Sat Oct 8 15:21:00 2011 +0000 Exempt all tbl/* includes from multiple include guards (451) diff --git a/bin/varnishd/flint.lnt b/bin/varnishd/flint.lnt index f2d2a6b..ec0d955 100644 --- a/bin/varnishd/flint.lnt +++ b/bin/varnishd/flint.lnt @@ -85,17 +85,10 @@ ////////////// -efile(451, "sys/\*.h") // No include guard -efile(451, "machine/\*.h") // No include guard --efile(451, "vcl_returns.h") // No include guard --efile(451, "body_status.h") // No include guard --efile(451, "locks.h") // No include guard --efile(451, "cache_backend_poll.h") // No include guard --efile(451, "steps.h") // No include guard --efile(451, "http_headers.h") // No include guard --efile(451, "acct_fields.h") // No include guard +-efile(451, "tbl/*.h") // No include guard -efile(451, "vcc_types.h") // No include guard -efile(451, "symbol_kind.h") // No include guard -efile(451, "config.h") // No include guard --efile(451, "vrt_stv_var.h") // No include guard ////////////// // -e458 // unprotected access // -e456 // merged locking paths From phk at varnish-cache.org Sat Oct 8 15:21:45 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 17:21:45 +0200 Subject: [master] 4a1413b Remove unused #includes Message-ID: commit 4a1413b3b0ac8f80565ba781e2926b8f93167ae2 Author: Poul-Henning Kamp Date: Sat Oct 8 15:21:27 2011 +0000 Remove unused #includes diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index c02e170..af5edec 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -30,11 +30,10 @@ #include "config.h" -#include +#include "cache.h" #include "vcli.h" #include "cli_priv.h" -#include "cache.h" static pthread_t VCA_thread; static struct timeval tv_sndtimeo; diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index fe1efd0..09e68cc 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -62,19 +62,16 @@ #include "config.h" -#include - #include -#include -#include #include #include +#include "cache.h" + #include "vcli.h" #include "vend.h" #include "cli_priv.h" -#include "cache.h" #include "hash_slinger.h" struct ban { diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 7e91137..0b7f8bf 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -62,16 +62,15 @@ DOT acceptor -> start [style=bold,color=green] #include #include #include -#include -#include #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" #endif +#include "cache.h" + #include "vcl.h" #include "cli_priv.h" -#include "cache.h" #include "hash_slinger.h" #include "stevedore.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index bfc1cbc..3635aec 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -36,14 +36,14 @@ #include "config.h" -#include #include // offsetof +#include "cache.h" + #include "vcli.h" #include "cli_priv.h" #include "cli_common.h" #include "cli_serve.h" -#include "cache.h" #include "hash_slinger.h" // objhead pthread_t cli_thread; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index bd0380b..3703b00 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -31,15 +31,14 @@ #include "config.h" -#include #include #include -#include #include -#include "vct.h" #include "cache.h" +#include "vct.h" + #define HTTPH(a, b, c, d, e, f, g) char b[] = "*" a ":"; #include "tbl/http_headers.h" #undef HTTPH diff --git a/bin/varnishd/cache_httpconn.c b/bin/varnishd/cache_httpconn.c index 3ba5d7f..d1ceb6e 100644 --- a/bin/varnishd/cache_httpconn.c +++ b/bin/varnishd/cache_httpconn.c @@ -31,14 +31,13 @@ #include "config.h" -#include #include -#include #include -#include #include "cache.h" +#include "vct.h" + /*-------------------------------------------------------------------- * Check if we have a complete HTTP request or response yet * @@ -55,7 +54,7 @@ htc_header_complete(txt *t) Tcheck(*t); assert(*t->e == '\0'); /* Skip any leading white space */ - for (p = t->b ; isspace(*p); p++) + for (p = t->b ; vct_issp(*p); p++) continue; if (*p == '\0') { t->e = t->b; diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 1aaa2ac..c5183a4 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -42,17 +42,13 @@ #include "config.h" -#include - #include -#include #include #include -#include #include "cache.h" + #include "cache_waiter.h" -#include "stevedore.h" #include "hash_slinger.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index 86cb10f..02d2a42 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -31,22 +31,19 @@ #include "config.h" -#include -#include - #include #include #include -#include #include #include #include +#include "cache.h" + #include "vrt.h" #include "vrt_obj.h" #include "vcl.h" -#include "cache.h" #include "hash_slinger.h" #include "cache_backend.h" diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c index ef2376f..d28510f 100644 --- a/bin/varnishd/cache_vrt_re.c +++ b/bin/varnishd/cache_vrt_re.c @@ -34,10 +34,10 @@ #include #include +#include "cache.h" + #include "vrt.h" #include "vre.h" -#include "vcl.h" -#include "cache.h" void VRT_re_init(void **rep, const char *re) diff --git a/bin/varnishd/cache_vrt_vmod.c b/bin/varnishd/cache_vrt_vmod.c index 557b01b..4eb3e84 100644 --- a/bin/varnishd/cache_vrt_vmod.c +++ b/bin/varnishd/cache_vrt_vmod.c @@ -31,13 +31,13 @@ #include "config.h" -#include #include #include +#include "cache.h" + #include "cli_priv.h" #include "vrt.h" -#include "cache.h" /*-------------------------------------------------------------------- * Modules stuff diff --git a/bin/varnishd/cache_waiter_poll.c b/bin/varnishd/cache_waiter_poll.c index 4678255..df0439b 100644 --- a/bin/varnishd/cache_waiter_poll.c +++ b/bin/varnishd/cache_waiter_poll.c @@ -30,14 +30,11 @@ #include "config.h" -#include -#include -#include #include -#include #include #include "cache.h" + #include "cache_waiter.h" #define NEEV 128 diff --git a/bin/varnishd/cache_wrk.c b/bin/varnishd/cache_wrk.c index bb88664..7e80f04 100644 --- a/bin/varnishd/cache_wrk.c +++ b/bin/varnishd/cache_wrk.c @@ -31,11 +31,9 @@ #include "config.h" -#include #include #include -#include "vcl.h" #include "cache.h" #include "hash_slinger.h" #include "vsha256.h" diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 3d6fa28..ba2effe 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index f247b71..7138369 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -29,9 +29,6 @@ #include "config.h" -#include -#include - #include #include #include diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c index 51d4c74..36936b6 100644 --- a/bin/varnishd/rfc2616.c +++ b/bin/varnishd/rfc2616.c @@ -29,13 +29,10 @@ #include "config.h" -#include #include -#include #include #include "cache.h" -#include "vrt.h" /*-------------------------------------------------------------------- * TTL and Age calculation in Varnish diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index 7388878..c363f4e 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -31,16 +31,12 @@ #include "config.h" -#include #include -#include - #include #include -#include -#include #include "cache.h" + #include "stevedore.h" #ifndef MAP_NOCORE diff --git a/bin/varnishd/storage_malloc.c b/bin/varnishd/storage_malloc.c index f72cd48..500e74c 100644 --- a/bin/varnishd/storage_malloc.c +++ b/bin/varnishd/storage_malloc.c @@ -31,12 +31,11 @@ #include "config.h" -#include - #include #include #include "cache.h" + #include "stevedore.h" struct sma_sc { diff --git a/bin/varnishd/storage_synth.c b/bin/varnishd/storage_synth.c index 1c16b44..0792dbd 100644 --- a/bin/varnishd/storage_synth.c +++ b/bin/varnishd/storage_synth.c @@ -30,14 +30,11 @@ #include "config.h" -#include - -#include #include #include "cache.h" + #include "stevedore.h" -#include "hash_slinger.h" static struct lock sms_mtx; diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 8b35970..0219eb0 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -52,7 +51,6 @@ #include "vsha256.h" #include "vcli.h" -#include "cli_priv.h" #include "cli_common.h" #include "vin.h" From phk at varnish-cache.org Sat Oct 8 16:23:52 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 18:23:52 +0200 Subject: [master] 23baabd Get closer to distcheck working Message-ID: commit 23baabde796dea577d09fa22c82e497f1af6624b Author: Poul-Henning Kamp Date: Sat Oct 8 16:23:44 2011 +0000 Get closer to distcheck working diff --git a/.gitignore b/.gitignore index f35e990..eb2db8c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,9 +43,9 @@ TAGS # Various auto-generated code snippets /include/vcl.h -/include/vcl_returns.h +/include/tbl/vcl_returns.h /include/vrt_obj.h -/include/vrt_stv_var.h +/include/tbl/vrt_stv_var.h /include/vcs_version.h /lib/libvcl/vcc_fixed_token.c /lib/libvcl/vcc_obj.c diff --git a/bin/flint.lnt b/bin/flint.lnt index d2f7c0e..4ad63d1 100644 --- a/bin/flint.lnt +++ b/bin/flint.lnt @@ -9,8 +9,7 @@ +libh ../../config.h -efile(451, ../../config.h) // No include guard --efile(451, vsl_tags.h) // No include guard --efile(451, vsc_fields.h) // No include guard +-efile(451, "tbl/*.h") // No include guard /////////////////////////////////////////////////////////////////////// // assert() support, common to libvarnish and libvarnishapi diff --git a/include/Makefile.am b/include/Makefile.am index 652689b..9f317f4 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,7 +16,6 @@ pkginclude_HEADERS = \ vsm.h nobase_noinst_HEADERS = \ - tbl/ban_vars.h \ binary_heap.h \ cli_common.h \ cli_priv.h \ @@ -25,36 +24,37 @@ nobase_noinst_HEADERS = \ compat/execinfo.h \ compat/srandomdev.h \ flopen.h \ - tbl/http_headers.h \ - tbl/http_response.h \ libvarnish.h \ libvcl.h \ miniobj.h \ persistent.h \ + tbl/ban_vars.h \ + tbl/http_headers.h \ + tbl/http_response.h \ + tbl/vcl_returns.h \ + tbl/vrt_stv_var.h \ vas.h \ vav.h \ - vsha256.h \ - vqueue.h \ - vpf.h \ - vsb.h \ + vbm.h \ vcl.h \ - vcl_returns.h \ vcs_version.h \ vct.h \ vend.h \ vev.h \ vin.h \ vlu.h \ - vbm.h \ vmb.h \ vmod_abi.h \ + vpf.h \ + vqueue.h \ vre.h \ vrt.h \ vrt_obj.h \ - vrt_stv_var.h \ + vsb.h \ + vsha256.h \ vss.h -vrt_stv_var.h vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h +tbl/vrt_stv_var.h tbl/vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h @PYTHON@ $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir) $(top_builddir) BUILT_SOURCES = vcs_version.h vmod_abi.h diff --git a/man/Makefile.am b/man/Makefile.am index 9317896..9118c34 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -4,7 +4,7 @@ if HAVE_RST2MAN noinst_PROGRAMS = vsc2rst endif vsc2rst_SOURCES = vsc2rst.c \ - $(top_srcdir)/include/vsc_fields.h + $(top_srcdir)/include/tbl/vsc_fields.h INCLUDES = -I$(top_srcdir)/include @@ -36,7 +36,7 @@ if HAVE_RST2MAN varnish-counters.7: vsc2rst ./vsc2rst | ${RST2MAN} - $@ else -varnish-counters.7: $(top_srcdir)/include/vsc_fields.h +varnish-counters.7: $(top_srcdir)/include/tbl/vsc_fields.h @echo "========================================" @echo "You need rst2man installed to make dist" @echo "========================================" From phk at varnish-cache.org Sat Oct 8 17:38:15 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 19:38:15 +0200 Subject: [master] b18e8d0 Make distcheck work again. Message-ID: commit b18e8d0c9309ccdc5fa4c2c4d3ea8fb5bfd617c0 Author: Poul-Henning Kamp Date: Sat Oct 8 17:38:05 2011 +0000 Make distcheck work again. diff --git a/include/Makefile.am b/include/Makefile.am index 9f317f4..e40ea2a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -55,6 +55,7 @@ nobase_noinst_HEADERS = \ vss.h tbl/vrt_stv_var.h tbl/vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h + mkdir -p tbl @PYTHON@ $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir) $(top_builddir) BUILT_SOURCES = vcs_version.h vmod_abi.h From phk at varnish-cache.org Sat Oct 8 21:58:10 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 23:58:10 +0200 Subject: [master] 2ac54a0 Remove unncessary #includes Message-ID: commit 2ac54a0443c15f1031fbfd447029de8a7fb01fbe Author: Poul-Henning Kamp Date: Sat Oct 8 21:30:13 2011 +0000 Remove unncessary #includes diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index f39b628..506aee1 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -31,20 +31,16 @@ #include #include #include -#include -#include -#include #include #include #include -#include #include #include +#include "vtc.h" + #include "libvarnish.h" -#include "vev.h" -#include "vtc.h" #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index d06b478..2c75622 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -30,7 +30,6 @@ #include #include -#include #include #include diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index a0ee01c..4582d4c 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -28,20 +28,18 @@ #include "config.h" -#include +#include #include #include -#include -#include #include -#include #include #include -#include "libvarnish.h" #include "vct.h" +#include "libvarnish.h" + #include "vtc.h" #include "vgz.h" diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 6b36aa5..51c6646 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -30,16 +30,13 @@ #include #include -#include #include -#include #include -#include "libvarnish.h" -#include "vas.h" - #include "vtc.h" +#include "libvarnish.h" + static pthread_mutex_t vtclog_mtx; static char *vtclog_buf; static unsigned vtclog_left; diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index d80aa6a..d201946 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include #include @@ -40,11 +38,11 @@ #include #include +#include "vtc.h" + #include "libvarnish.h" #include "vev.h" -#include "vtc.h" - #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" #endif diff --git a/bin/varnishtest/vtc_sema.c b/bin/varnishtest/vtc_sema.c index 4df1979..8a9228a 100644 --- a/bin/varnishtest/vtc_sema.c +++ b/bin/varnishtest/vtc_sema.c @@ -35,7 +35,6 @@ #include "vtc.h" -#include "miniobj.h" #include "libvarnish.h" struct sema { diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 9390e5b..d541d67 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -39,8 +38,8 @@ #include "vtc.h" -#include "vss.h" #include "libvarnish.h" +#include "vss.h" struct server { unsigned magic; diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index ce6a45a..aea29a4 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -42,13 +41,14 @@ #include #include +#include "vtc.h" + #include "libvarnish.h" #include "varnishapi.h" + #include "vcli.h" #include "vss.h" -#include "vtc.h" - struct varnish { unsigned magic; #define VARNISH_MAGIC 0x208cd8e3 From phk at varnish-cache.org Sat Oct 8 21:58:10 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sat, 08 Oct 2011 23:58:10 +0200 Subject: [master] f971cdf Even more #include cleanup Message-ID: commit f971cdfa6ce63ab7b4fbd2c1191f6b044dd2f488 Author: Poul-Henning Kamp Date: Sat Oct 8 21:58:01 2011 +0000 Even more #include cleanup diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index c9b3ac2..d3228a5 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -34,8 +34,6 @@ */ #define VARNISH_CACHE_CHILD 1 -#include -#include #include #include @@ -52,15 +50,9 @@ #include #endif -#include "vqueue.h" - -#include "vsb.h" - -#include "libvarnish.h" - #include "common.h" + #include "heritage.h" -#include "miniobj.h" #include "vsc.h" #include "vsl.h" @@ -99,6 +91,7 @@ enum { HTTP_HDR_FIRST, }; +struct iovec; struct cli; struct vsb; struct sess; diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c index 1061612..a724923 100644 --- a/bin/varnishd/cache_backend.c +++ b/bin/varnishd/cache_backend.c @@ -32,16 +32,11 @@ #include "config.h" -#include -#include #include -#include -#include #include -#include - #include "cache.h" + #include "cache_backend.h" #include "vrt.h" diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index 09e68cc..f346b4d 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -63,7 +63,6 @@ #include "config.h" #include -#include #include diff --git a/bin/varnishd/cache_dir_dns.c b/bin/varnishd/cache_dir_dns.c index d3635a9..3fd2aa1 100644 --- a/bin/varnishd/cache_dir_dns.c +++ b/bin/varnishd/cache_dir_dns.c @@ -29,14 +29,9 @@ #include "config.h" -#include -#include - #include #include -#include #include -#include #include #include diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 7c6e2e5..df56c7a 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -31,7 +31,6 @@ #include #include -#include #include #include diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index 3703b00..dd55990 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -31,9 +31,7 @@ #include "config.h" -#include #include -#include #include "cache.h" diff --git a/bin/varnishd/cache_httpconn.c b/bin/varnishd/cache_httpconn.c index d1ceb6e..ba881c9 100644 --- a/bin/varnishd/cache_httpconn.c +++ b/bin/varnishd/cache_httpconn.c @@ -31,9 +31,6 @@ #include "config.h" -#include -#include - #include "cache.h" #include "vct.h" diff --git a/bin/varnishd/cache_lck.c b/bin/varnishd/cache_lck.c index 18d1b41..ee93b9f 100644 --- a/bin/varnishd/cache_lck.c +++ b/bin/varnishd/cache_lck.c @@ -35,8 +35,6 @@ #include "config.h" -#include - #include #include "cache.h" diff --git a/bin/varnishd/cache_main.c b/bin/varnishd/cache_main.c index 5660893..b4ee185 100644 --- a/bin/varnishd/cache_main.c +++ b/bin/varnishd/cache_main.c @@ -30,11 +30,10 @@ #include "config.h" #include -#include #include -#include #include "cache.h" + #include "stevedore.h" #include "hash_slinger.h" #include "cache_waiter.h" diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index a9c5c15..464924a 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -29,19 +29,17 @@ #include "config.h" -#include -#include #include #include -#include -#include #ifndef HAVE_EXECINFO_H #include "compat/execinfo.h" #else #include #endif + #include "cache.h" + #include "vsm.h" #include "cache_backend.h" #include "cache_waiter.h" diff --git a/bin/varnishd/cache_shmlog.c b/bin/varnishd/cache_shmlog.c index 023c20a..8c06897 100644 --- a/bin/varnishd/cache_shmlog.c +++ b/bin/varnishd/cache_shmlog.c @@ -30,8 +30,6 @@ #include "config.h" #include -#include -#include #include "cache.h" #include "vmb.h" diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index b7a6b01..4440d55 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -54,10 +54,8 @@ #include "config.h" -#include -#include - #include "cache.h" + #include "vend.h" #include "vct.h" diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c index 8848ddd..99364b5 100644 --- a/bin/varnishd/cache_vcl.c +++ b/bin/varnishd/cache_vcl.c @@ -34,15 +34,13 @@ #include "config.h" #include -#include -#include #include #include +#include "cache.h" #include "vcli.h" #include "cli_priv.h" #include "vcl.h" -#include "cache.h" #include "libvcl.h" struct vcls { diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index 02d2a42..f0407cc 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -35,9 +35,7 @@ #include #include -#include #include -#include #include "cache.h" diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index e26b433..ae65058 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -31,12 +31,12 @@ #include "config.h" #include -#include #include +#include "cache.h" + #include "vrt.h" #include "vrt_obj.h" -#include "cache.h" #include "cache_backend.h" #include "hash_slinger.h" diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c index 28776cd..d4168db 100644 --- a/bin/varnishd/cache_waiter_epoll.c +++ b/bin/varnishd/cache_waiter_epoll.c @@ -35,22 +35,18 @@ #if defined(HAVE_EPOLL_CTL) -#include -#include #include #include #include -#include - #include +#include "cache.h" +#include "cache_waiter.h" + #ifndef EPOLLRDHUP # define EPOLLRDHUP 0 #endif -#include "cache.h" -#include "cache_waiter.h" - #define NEEV 100 struct vwe { diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c index 9575dc8..f023c3f 100644 --- a/bin/varnishd/cache_waiter_kqueue.c +++ b/bin/varnishd/cache_waiter_kqueue.c @@ -35,13 +35,10 @@ #if defined(HAVE_KQUEUE) -#include -#include #include #include #include #include - #include #include "cache.h" diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c index 695e9c0..04c6e92 100644 --- a/bin/varnishd/cache_waiter_ports.c +++ b/bin/varnishd/cache_waiter_ports.c @@ -35,9 +35,7 @@ #include #include -#include #include -#include #include #include diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c index 61aa2e5..5f9c29b 100644 --- a/bin/varnishd/cache_wrw.c +++ b/bin/varnishd/cache_wrw.c @@ -40,13 +40,13 @@ #ifdef SENDFILE_WORKS #if defined(__FreeBSD__) || defined(__DragonFly__) -#include + // We're fine #elif defined(__linux__) -#include +# include #elif defined(__sun) -#include +# include #else -#error Unknown sendfile() implementation +# error Unknown sendfile() implementation #endif #endif /* SENDFILE_WORKS */ diff --git a/bin/varnishd/common.h b/bin/varnishd/common.h index 3708b45..f755b97 100644 --- a/bin/varnishd/common.h +++ b/bin/varnishd/common.h @@ -28,6 +28,11 @@ * */ +#include "libvarnish.h" +#include "vsb.h" +#include "vqueue.h" +#include "miniobj.h" + struct cli; extern pid_t mgt_pid; diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 8958ab5..9d12752 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -30,13 +30,7 @@ #include -#include "vqueue.h" - #include "common.h" -#include "vsb.h" -#include "miniobj.h" - -#include "libvarnish.h" struct cli; diff --git a/bin/varnishd/mgt_pool.c b/bin/varnishd/mgt_pool.c index 1238f5e..4b3fe92 100644 --- a/bin/varnishd/mgt_pool.c +++ b/bin/varnishd/mgt_pool.c @@ -46,9 +46,7 @@ #include #include #include -#include -#include "cli_priv.h" #include "mgt.h" #include "vparam.h" diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 15b7c95..2c975d9 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -36,8 +36,6 @@ #include #include -#include -#include #ifdef HAVE_PRIV_H #include diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index 6c100bb..f8e81ca 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -31,9 +31,6 @@ #include "config.h" -#include -#include - #include #include #include @@ -45,13 +42,9 @@ #include "libvcl.h" #include "vcli.h" +#include "vcl.h" #include "cli_priv.h" -#include "cli_common.h" - #include "mgt_cli.h" -#include "heritage.h" - -#include "vcl.h" struct vclprog { VTAILQ_ENTRY(vclprog) list; diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c index 1dcfd63..af7fc7f 100644 --- a/bin/varnishd/stevedore_utils.c +++ b/bin/varnishd/stevedore_utils.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include diff --git a/bin/varnishd/storage_persistent.h b/bin/varnishd/storage_persistent.h index 2a5bd77..84f3d21 100644 --- a/bin/varnishd/storage_persistent.h +++ b/bin/varnishd/storage_persistent.h @@ -33,14 +33,6 @@ * XXX: Do we ever free the LRU-lists ? */ -#ifndef MAP_NOCORE -#define MAP_NOCORE 0 /* XXX Linux */ -#endif - -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 /* XXX Linux */ -#endif - #define ASSERT_SILO_THREAD(sc) \ do {assert(pthread_self() == (sc)->thread);} while (0) diff --git a/bin/varnishd/storage_persistent_mgt.c b/bin/varnishd/storage_persistent_mgt.c index 3bd5809..c91fb43 100644 --- a/bin/varnishd/storage_persistent_mgt.c +++ b/bin/varnishd/storage_persistent_mgt.c @@ -47,6 +47,14 @@ #include "persistent.h" #include "storage_persistent.h" +#ifndef MAP_NOCORE +#define MAP_NOCORE 0 /* XXX Linux */ +#endif + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 /* XXX Linux */ +#endif + /*-------------------------------------------------------------------- * Calculate cleaner metrics from silo dimensions */ diff --git a/bin/varnishd/vsm.c b/bin/varnishd/vsm.c index 62047ff..28f98e5 100644 --- a/bin/varnishd/vsm.c +++ b/bin/varnishd/vsm.c @@ -51,8 +51,6 @@ #include #include -#include "miniobj.h" -#include "libvarnish.h" #include "common.h" #include "vsm.h" #include "vmb.h" From phk at varnish-cache.org Sun Oct 9 08:24:39 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 10:24:39 +0200 Subject: [master] b4bb850 More #include cleanuppery Message-ID: commit b4bb85057482f1fcb79d86f340a4e6665ca4352d Author: Poul-Henning Kamp Date: Sun Oct 9 08:24:21 2011 +0000 More #include cleanuppery diff --git a/include/Makefile.am b/include/Makefile.am index e40ea2a..c68e07c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,9 +3,15 @@ pkginclude_HEADERS = \ tbl/acct_fields.h \ tbl/backend_poll.h \ + tbl/ban_vars.h \ tbl/body_status.h \ + tbl/http_headers.h \ + tbl/http_response.h \ tbl/locks.h \ tbl/steps.h \ + tbl/vcc_types.h \ + tbl/vcl_returns.h \ + tbl/vrt_stv_var.h \ tbl/vsc_all.h \ tbl/vsc_fields.h \ tbl/vsl_tags.h \ @@ -28,11 +34,6 @@ nobase_noinst_HEADERS = \ libvcl.h \ miniobj.h \ persistent.h \ - tbl/ban_vars.h \ - tbl/http_headers.h \ - tbl/http_response.h \ - tbl/vcl_returns.h \ - tbl/vrt_stv_var.h \ vas.h \ vav.h \ vbm.h \ diff --git a/include/tbl/vcc_types.h b/include/tbl/vcc_types.h new file mode 100644 index 0000000..469b56c --- /dev/null +++ b/include/tbl/vcc_types.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2010 Varnish Software 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. + * + */ + +/*lint -save -e525 -e539 */ +VCC_TYPE(VOID) +VCC_TYPE(BACKEND) +VCC_TYPE(BOOL) +VCC_TYPE(INT) +VCC_TYPE(TIME) +VCC_TYPE(DURATION) +VCC_TYPE(STRING) +VCC_TYPE(STRING_LIST) +VCC_TYPE(IP) +VCC_TYPE(HEADER) +VCC_TYPE(BYTES) +VCC_TYPE(REAL) +VCC_TYPE(ENUM) +/*lint -restore */ diff --git a/lib/libvcl/Makefile.am b/lib/libvcl/Makefile.am index fa61423..099ad36 100644 --- a/lib/libvcl/Makefile.am +++ b/lib/libvcl/Makefile.am @@ -10,7 +10,6 @@ libvcl_la_SOURCES = \ vcc_priv.h \ vcc_compile.h \ vcc_token_defs.h \ - vcc_types.h \ symbol_kind.h \ \ vcc_acl.c \ diff --git a/lib/libvcl/vcc_acl.c b/lib/libvcl/vcc_acl.c index 6eb451c..bd94a5b 100644 --- a/lib/libvcl/vcc_acl.c +++ b/lib/libvcl/vcc_acl.c @@ -30,7 +30,6 @@ #include "config.h" #include -#include #include #include #include @@ -38,10 +37,10 @@ #include #include -#include "vrt.h" -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vrt.h" +#include "vcc_priv.h" #include "libvarnish.h" struct acl_e { diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index c11f5b2..1fafe98 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -32,11 +32,9 @@ #include "config.h" -#include -#include -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index dfe58d2..67fecd6 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -55,16 +55,13 @@ #include #include -#include -#include #include #include -#include "vss.h" - -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvarnish.h" +#include "vss.h" struct host { VTAILQ_ENTRY(host) list; diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index a09f396..be3ec63 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -52,18 +52,15 @@ #include "config.h" -#include - #include #include #include #include #include #include -#include -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvcl.h" #include "libvarnish.h" diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index a3aa800..438fe58 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -44,7 +44,7 @@ struct symbol; enum var_type { #define VCC_TYPE(foo) foo, -#include "vcc_types.h" +#include "tbl/vcc_types.h" #undef VCC_TYPE }; diff --git a/lib/libvcl/vcc_dir_dns.c b/lib/libvcl/vcc_dir_dns.c index a8cb24b..a5952c8 100644 --- a/lib/libvcl/vcc_dir_dns.c +++ b/lib/libvcl/vcc_dir_dns.c @@ -28,16 +28,12 @@ #include "config.h" -#include -#include - #include -#include #include #include -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvarnish.h" /*-------------------------------------------------------------------- diff --git a/lib/libvcl/vcc_dir_random.c b/lib/libvcl/vcc_dir_random.c index aa362f9..46f74c2 100644 --- a/lib/libvcl/vcc_dir_random.c +++ b/lib/libvcl/vcc_dir_random.c @@ -29,15 +29,8 @@ #include "config.h" -#include -#include - -#include -#include -#include - -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvarnish.h" /*-------------------------------------------------------------------- diff --git a/lib/libvcl/vcc_dir_round_robin.c b/lib/libvcl/vcc_dir_round_robin.c index 67fb118..b1094fe 100644 --- a/lib/libvcl/vcc_dir_round_robin.c +++ b/lib/libvcl/vcc_dir_round_robin.c @@ -28,15 +28,8 @@ #include "config.h" -#include -#include - -#include -#include -#include - -#include "vcc_priv.h" #include "vcc_compile.h" +#include "vcc_priv.h" #include "libvarnish.h" /*-------------------------------------------------------------------- diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c index b7b6ba6..4fbcd85 100644 --- a/lib/libvcl/vcc_expr.c +++ b/lib/libvcl/vcc_expr.c @@ -46,7 +46,7 @@ vcc_Type(enum var_type fmt) { switch(fmt) { #define VCC_TYPE(a) case a: return(#a); -#include "vcc_types.h" +#include "tbl/vcc_types.h" #undef VCC_TYPE default: assert("Unknwon Type"); @@ -403,7 +403,7 @@ vcc_arg_type(const char **p) { #define VCC_TYPE(a) if (!strcmp(#a, *p)) { *p += strlen(#a) + 1; return (a);} -#include "vcc_types.h" +#include "tbl/vcc_types.h" #undef VCC_TYPE return (VOID); } diff --git a/lib/libvcl/vcc_types.h b/lib/libvcl/vcc_types.h deleted file mode 100644 index 469b56c..0000000 --- a/lib/libvcl/vcc_types.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2010 Varnish Software 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. - * - */ - -/*lint -save -e525 -e539 */ -VCC_TYPE(VOID) -VCC_TYPE(BACKEND) -VCC_TYPE(BOOL) -VCC_TYPE(INT) -VCC_TYPE(TIME) -VCC_TYPE(DURATION) -VCC_TYPE(STRING) -VCC_TYPE(STRING_LIST) -VCC_TYPE(IP) -VCC_TYPE(HEADER) -VCC_TYPE(BYTES) -VCC_TYPE(REAL) -VCC_TYPE(ENUM) -/*lint -restore */ From phk at varnish-cache.org Sun Oct 9 08:42:21 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 10:42:21 +0200 Subject: [master] c5c9e33 Eliminate a redundant include file Message-ID: commit c5c9e33ee5f2bf4dd278841a6d82e25a647acef5 Author: Poul-Henning Kamp Date: Sun Oct 9 08:42:03 2011 +0000 Eliminate a redundant include file diff --git a/lib/libvcl/Makefile.am b/lib/libvcl/Makefile.am index 099ad36..8406ed7 100644 --- a/lib/libvcl/Makefile.am +++ b/lib/libvcl/Makefile.am @@ -7,7 +7,6 @@ pkglib_LTLIBRARIES = libvcl.la libvcl_la_LDFLAGS = -avoid-version libvcl_la_SOURCES = \ - vcc_priv.h \ vcc_compile.h \ vcc_token_defs.h \ symbol_kind.h \ diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index 335cfd5..9342aaf 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -866,8 +866,7 @@ fo.write(""" #include #include #include "config.h" -#include "vcc_priv.h" -#include "vsb.h" +#include "vcc_compile.h" """) emit_vcl_fixed_token(fo, tokens) diff --git a/lib/libvcl/vcc_acl.c b/lib/libvcl/vcc_acl.c index bd94a5b..985a18e 100644 --- a/lib/libvcl/vcc_acl.c +++ b/lib/libvcl/vcc_acl.c @@ -40,8 +40,6 @@ #include "vcc_compile.h" #include "vrt.h" -#include "vcc_priv.h" -#include "libvarnish.h" struct acl_e { VTAILQ_ENTRY(acl_e) list; diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 1fafe98..61bfb87 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -34,8 +34,6 @@ #include "vcc_compile.h" -#include "vcc_priv.h" -#include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index 67fecd6..0c72c1c 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -59,8 +59,6 @@ #include #include "vcc_compile.h" -#include "vcc_priv.h" -#include "libvarnish.h" #include "vss.h" struct host { diff --git a/lib/libvcl/vcc_backend_util.c b/lib/libvcl/vcc_backend_util.c index 8d2cc1a..28510f5 100644 --- a/lib/libvcl/vcc_backend_util.c +++ b/lib/libvcl/vcc_backend_util.c @@ -34,9 +34,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" /*-------------------------------------------------------------------- * Helper functions to complain about duplicate and missing fields diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index be3ec63..3af30c6 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -60,10 +60,7 @@ #include #include "vcc_compile.h" -#include "vcc_priv.h" - #include "libvcl.h" -#include "libvarnish.h" struct method method_tab[] = { #define VCL_MET_MAC(l,U,m) { "vcl_"#l, m, VCL_MET_##U }, diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index 438fe58..141f4f1 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -33,6 +33,20 @@ #include "miniobj.h" #include "vsb.h" #include "vcl.h" +#include "libvarnish.h" + +#include "vcc_token_defs.h" + +struct vsb; + +#define isident1(c) (isalpha(c)) +#define isident(c) (isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-') +#define isvar(c) (isident(c) || (c) == '.') +unsigned vcl_fixed_token(const char *p, const char **q); +extern const char * const vcl_tnames[256]; +void vcl_output_lang_h(struct vsb *sb); + +#define PF(t) (int)((t)->e - (t)->b), (t)->b #define INDENT 2 diff --git a/lib/libvcl/vcc_dir_dns.c b/lib/libvcl/vcc_dir_dns.c index a5952c8..2e3951e 100644 --- a/lib/libvcl/vcc_dir_dns.c +++ b/lib/libvcl/vcc_dir_dns.c @@ -33,8 +33,6 @@ #include #include "vcc_compile.h" -#include "vcc_priv.h" -#include "libvarnish.h" /*-------------------------------------------------------------------- * Parse directors diff --git a/lib/libvcl/vcc_dir_random.c b/lib/libvcl/vcc_dir_random.c index 46f74c2..4166918 100644 --- a/lib/libvcl/vcc_dir_random.c +++ b/lib/libvcl/vcc_dir_random.c @@ -30,8 +30,6 @@ #include "config.h" #include "vcc_compile.h" -#include "vcc_priv.h" -#include "libvarnish.h" /*-------------------------------------------------------------------- * Parse directors diff --git a/lib/libvcl/vcc_dir_round_robin.c b/lib/libvcl/vcc_dir_round_robin.c index b1094fe..835d969 100644 --- a/lib/libvcl/vcc_dir_round_robin.c +++ b/lib/libvcl/vcc_dir_round_robin.c @@ -29,8 +29,6 @@ #include "config.h" #include "vcc_compile.h" -#include "vcc_priv.h" -#include "libvarnish.h" /*-------------------------------------------------------------------- * Parse directors diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c index 4fbcd85..dc7d99d 100644 --- a/lib/libvcl/vcc_expr.c +++ b/lib/libvcl/vcc_expr.c @@ -37,9 +37,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" static const char * vcc_Type(enum var_type fmt) diff --git a/lib/libvcl/vcc_parse.c b/lib/libvcl/vcc_parse.c index 23c9bf7..4023287 100644 --- a/lib/libvcl/vcc_parse.c +++ b/lib/libvcl/vcc_parse.c @@ -32,9 +32,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_priv.h b/lib/libvcl/vcc_priv.h deleted file mode 100644 index 1e990b2..0000000 --- a/lib/libvcl/vcc_priv.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - * Stuff shared between main.c and fixed_token.c - */ - -#include "vcc_token_defs.h" - -struct vsb; - -#define isident1(c) (isalpha(c)) -#define isident(c) (isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-') -#define isvar(c) (isident(c) || (c) == '.') -unsigned vcl_fixed_token(const char *p, const char **q); -extern const char * const vcl_tnames[256]; -void vcl_output_lang_h(struct vsb *sb); - -#define PF(t) (int)((t)->e - (t)->b), (t)->b diff --git a/lib/libvcl/vcc_storage.c b/lib/libvcl/vcc_storage.c index 5aff6e7..5f9712a 100644 --- a/lib/libvcl/vcc_storage.c +++ b/lib/libvcl/vcc_storage.c @@ -59,9 +59,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" #define PFX "storage." diff --git a/lib/libvcl/vcc_string.c b/lib/libvcl/vcc_string.c index c6353d7..dfc82cf 100644 --- a/lib/libvcl/vcc_string.c +++ b/lib/libvcl/vcc_string.c @@ -32,9 +32,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" #include "vrt.h" #include "vre.h" diff --git a/lib/libvcl/vcc_symb.c b/lib/libvcl/vcc_symb.c index 4975c12..0acb0cd 100644 --- a/lib/libvcl/vcc_symb.c +++ b/lib/libvcl/vcc_symb.c @@ -32,9 +32,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_token.c b/lib/libvcl/vcc_token.c index 5a79732..63ebbf3 100644 --- a/lib/libvcl/vcc_token.c +++ b/lib/libvcl/vcc_token.c @@ -34,8 +34,6 @@ #include #include -#include "libvarnish.h" -#include "vcc_priv.h" #include "vcc_compile.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_var.c b/lib/libvcl/vcc_var.c index b6e1ea7..1bbac15 100644 --- a/lib/libvcl/vcc_var.c +++ b/lib/libvcl/vcc_var.c @@ -32,9 +32,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c index 37a98fd..40c9ed5 100644 --- a/lib/libvcl/vcc_vmod.c +++ b/lib/libvcl/vcc_vmod.c @@ -32,9 +32,7 @@ #include #include -#include "vcc_priv.h" #include "vcc_compile.h" -#include "libvarnish.h" #include "vmod_abi.h" void diff --git a/lib/libvcl/vcc_xref.c b/lib/libvcl/vcc_xref.c index 56a2747..c3ef375 100644 --- a/lib/libvcl/vcc_xref.c +++ b/lib/libvcl/vcc_xref.c @@ -41,8 +41,6 @@ #include -#include "libvarnish.h" -#include "vcc_priv.h" #include "vcc_compile.h" /*--------------------------------------------------------------------*/ From phk at varnish-cache.org Sun Oct 9 16:13:15 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 18:13:15 +0200 Subject: [master] 2dbbcb4 More #include shufflery Message-ID: commit 2dbbcb4405a4bd25401f40ffcfc27bef2e42fb64 Author: Poul-Henning Kamp Date: Sun Oct 9 16:12:58 2011 +0000 More #include shufflery diff --git a/include/Makefile.am b/include/Makefile.am index c68e07c..93f61e0 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -15,6 +15,7 @@ pkginclude_HEADERS = \ tbl/vsc_all.h \ tbl/vsc_fields.h \ tbl/vsl_tags.h \ + vapi/vsm.h \ varnishapi.h \ vcli.h \ vsc.h \ diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h new file mode 100644 index 0000000..8948028 --- /dev/null +++ b/include/vapi/vsm.h @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#ifndef VAPI_VSM_H_INCLUDED +#define VAPI_VSM_H_INCLUDED + +// #include + +/*--------------------------------------------------------------------- + * VSM level access functions + */ + +struct VSM_data *VSM_New(void); + /* + * Allocate and initialize a VSL_data handle structure. + * This is the first thing you will have to do, always. + * You can have multiple active VSL_data handles at the same time + * referencing the same or different shared memory files. + * Returns: + * Pointer to usable VSL_data handle. + */ + +typedef void VSM_diag_f(void *priv, const char *fmt, ...); + +void VSM_Diag(struct VSM_data *vd, VSM_diag_f *func, void *priv); + /* + * Set the diagnostics reporting function. + * Default is fprintf(stderr, ...) + * If func is NULL, diagnostics are disabled. + */ + +#define VSM_n_USAGE "[-n varnish_name]" + +int VSM_n_Arg(struct VSM_data *vd, const char *n_arg); + /* + * Configure which varnishd instance to access. + * Can also be, and normally is done through the VSL_Log_arg() + * and VSC_Arg() functions. + * Returns: + * 1 on success + * -1 on failure, with diagnostic on stderr. + */ + +const char *VSM_Name(const struct VSM_data *vd); + /* + * Return the instance name. + */ + +void VSM_Delete(struct VSM_data *vd); + /* + * Close and deallocate all storage and mappings. + */ + +/* XXX: extension: Patience argument for sleeps */ + +int VSM_Open(struct VSM_data *vd, int diag); + /* + * Attempt to open and map the shared memory file. + * If diag is non-zero, diagnostics are emitted. + * Returns: + * 0 on success + * != 0 on failure + */ + +int VSM_ReOpen(struct VSM_data *vd, int diag); + /* + * Check if shared memory segment needs to be reopened/remapped + * typically when the varnishd master process restarts. + * diag is passed to VSM_Open() + * Returns: + * 0 No reopen needed. + * 1 shared memory reopened/remapped. + * -1 failure to reopen. + */ + +unsigned VSM_Seq(const struct VSM_data *vd); + /* + * Return the allocation sequence number + */ + +struct VSM_head *VSM_Head(const struct VSM_data *vd); + /* + * Return the head of the VSM. + */ + +void *VSM_Find_Chunk(struct VSM_data *vd, const char *class, + const char *type, const char *ident, unsigned *lenp); + /* + * Find a given chunk in the shared memory. + * Returns pointer or NULL. + * Lenp, if non-NULL, is set to length of chunk. + */ + +void VSM_Close(struct VSM_data *vd); + /* + * Unmap shared memory + * Deallocate all storage (including VSC and VSL allocations) + */ + +struct VSM_chunk *VSM_iter0(struct VSM_data *vd); +void VSM_itern(const struct VSM_data *vd, struct VSM_chunk **pp); + +#define VSM_FOREACH(var, vd) \ + for((var) = VSM_iter0((vd)); (var) != NULL; VSM_itern((vd), &(var))) + + /* + * Iterate over all chunks in shared memory + * var = "struct VSM_chunk *" + * vd = "struct VSM_data" + */ + +#endif /* VAPI_VSM_H_INCLUDED */ diff --git a/include/varnishapi.h b/include/varnishapi.h index dcdd74f..235308a 100644 --- a/include/varnishapi.h +++ b/include/varnishapi.h @@ -31,6 +31,8 @@ #ifndef VARNISHAPI_H_INCLUDED #define VARNISHAPI_H_INCLUDED +#include + #include #include "vsl.h" @@ -43,109 +45,6 @@ /*--------------------------------------------------------------------- - * VSM level access functions - */ - -struct VSM_data *VSM_New(void); - /* - * Allocate and initialize a VSL_data handle structure. - * This is the first thing you will have to do, always. - * You can have multiple active VSL_data handles at the same time - * referencing the same or different shared memory files. - * Returns: - * Pointer to usable VSL_data handle. - */ - -typedef void VSM_diag_f(void *priv, const char *fmt, ...); - -void VSM_Diag(struct VSM_data *vd, VSM_diag_f *func, void *priv); - /* - * Set the diagnostics reporting function. - * Default is fprintf(stderr, ...) - * If func is NULL, diagnostics are disabled. - */ - -#define VSM_n_USAGE "[-n varnish_name]" - -int VSM_n_Arg(struct VSM_data *vd, const char *n_arg); - /* - * Configure which varnishd instance to access. - * Can also be, and normally is done through the VSL_Log_arg() - * and VSC_Arg() functions. - * Returns: - * 1 on success - * -1 on failure, with diagnostic on stderr. - */ - -const char *VSM_Name(const struct VSM_data *vd); - /* - * Return the instance name. - */ - -void VSM_Delete(struct VSM_data *vd); - /* - * Close and deallocate all storage and mappings. - */ - -/* XXX: extension: Patience argument for sleeps */ - -int VSM_Open(struct VSM_data *vd, int diag); - /* - * Attempt to open and map the shared memory file. - * If diag is non-zero, diagnostics are emitted. - * Returns: - * 0 on success - * != 0 on failure - */ - -int VSM_ReOpen(struct VSM_data *vd, int diag); - /* - * Check if shared memory segment needs to be reopened/remapped - * typically when the varnishd master process restarts. - * diag is passed to VSM_Open() - * Returns: - * 0 No reopen needed. - * 1 shared memory reopened/remapped. - * -1 failure to reopen. - */ - -unsigned VSM_Seq(const struct VSM_data *vd); - /* - * Return the allocation sequence number - */ - -struct VSM_head *VSM_Head(const struct VSM_data *vd); - /* - * Return the head of the VSM. - */ - -void *VSM_Find_Chunk(struct VSM_data *vd, const char *class, - const char *type, const char *ident, unsigned *lenp); - /* - * Find a given chunk in the shared memory. - * Returns pointer or NULL. - * Lenp, if non-NULL, is set to length of chunk. - */ - -void VSM_Close(struct VSM_data *vd); - /* - * Unmap shared memory - * Deallocate all storage (including VSC and VSL allocations) - */ - -struct VSM_chunk *VSM_iter0(struct VSM_data *vd); -void VSM_itern(const struct VSM_data *vd, struct VSM_chunk **pp); - -#define VSM_FOREACH(var, vd) \ - for((var) = VSM_iter0((vd)); (var) != NULL; VSM_itern((vd), &(var))) - - /* - * Iterate over all chunks in shared memory - * var = "struct VSM_chunk *" - * vd = "struct VSM_data" - */ - -/*--------------------------------------------------------------------- * VSC level access functions */ From phk at varnish-cache.org Sun Oct 9 16:20:20 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 18:20:20 +0200 Subject: [master] 4507c59 Also split out the VSC part of the (v)abi Message-ID: commit 4507c59580f9e5089d9d4e863ca2740daf975fc0 Author: Poul-Henning Kamp Date: Sun Oct 9 16:20:05 2011 +0000 Also split out the VSC part of the (v)abi diff --git a/include/Makefile.am b/include/Makefile.am index 93f61e0..47fede9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,6 +16,7 @@ pkginclude_HEADERS = \ tbl/vsc_fields.h \ tbl/vsl_tags.h \ vapi/vsm.h \ + vapi/vsc.h \ varnishapi.h \ vcli.h \ vsc.h \ diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h new file mode 100644 index 0000000..290db9d --- /dev/null +++ b/include/vapi/vsc.h @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#ifndef VAPI_VSC_H_INCLUDED +#define VAPI_VSC_H_INCLUDED + +/*--------------------------------------------------------------------- + * VSC level access functions + */ + +void VSC_Setup(struct VSM_data *vd); + /* + * Setup vd for use with VSC functions. + */ + +#define VSC_ARGS "f:n:" +#define VSC_n_USAGE VSM_n_USAGE +#define VSC_USAGE VSC_N_USAGE + +int VSC_Arg(struct VSM_data *vd, int arg, const char *opt); + /* + * Handle standard stat-presenter arguments + * Return: + * -1 error + * 0 not handled + * 1 Handled. + */ + +int VSC_Open(struct VSM_data *vd, int diag); + /* + * Open shared memory for VSC processing. + * args and returns as VSM_Open() + */ + +struct VSC_C_main *VSC_Main(struct VSM_data *vd); + /* + * return Main stats structure + */ + +struct VSC_point { + const char *class; /* stat struct type */ + const char *ident; /* stat struct ident */ + const char *name; /* field name */ + const char *fmt; /* field format ("uint64_t") */ + int flag; /* 'a' = counter, 'i' = gauge */ + const char *desc; /* description */ + const volatile void *ptr; /* field value */ +}; + +typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt); + +int VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv); + /* + * Iterate over all statistics counters, calling "func" for + * each counter not suppressed by any "-f" arguments. + */ + +#endif /* VAPI_VSC_H_INCLUDED */ diff --git a/include/varnishapi.h b/include/varnishapi.h index 235308a..6960720 100644 --- a/include/varnishapi.h +++ b/include/varnishapi.h @@ -32,6 +32,7 @@ #define VARNISHAPI_H_INCLUDED #include +#include #include @@ -43,58 +44,6 @@ * API use failures will trip assert. */ - -/*--------------------------------------------------------------------- - * VSC level access functions - */ - -void VSC_Setup(struct VSM_data *vd); - /* - * Setup vd for use with VSC functions. - */ - -#define VSC_ARGS "f:n:" -#define VSC_n_USAGE VSM_n_USAGE -#define VSC_USAGE VSC_N_USAGE - -int VSC_Arg(struct VSM_data *vd, int arg, const char *opt); - /* - * Handle standard stat-presenter arguments - * Return: - * -1 error - * 0 not handled - * 1 Handled. - */ - -int VSC_Open(struct VSM_data *vd, int diag); - /* - * Open shared memory for VSC processing. - * args and returns as VSM_Open() - */ - -struct VSC_C_main *VSC_Main(struct VSM_data *vd); - /* - * return Main stats structure - */ - -struct VSC_point { - const char *class; /* stat struct type */ - const char *ident; /* stat struct ident */ - const char *name; /* field name */ - const char *fmt; /* field format ("uint64_t") */ - int flag; /* 'a' = counter, 'i' = gauge */ - const char *desc; /* description */ - const volatile void *ptr; /* field value */ -}; - -typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt); - -int VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv); - /* - * Iterate over all statistics counters, calling "func" for - * each counter not suppressed by any "-f" arguments. - */ - /*--------------------------------------------------------------------- * VSL level access functions */ From phk at varnish-cache.org Sun Oct 9 16:57:35 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 18:57:35 +0200 Subject: [master] 6e6edd0 Complete (?) the varnish API #include cleanup. Message-ID: commit 6e6edd08227b1ced1c0d15117e3ea9f0afde40e7 Author: Poul-Henning Kamp Date: Sun Oct 9 16:56:04 2011 +0000 Complete (?) the varnish API #include cleanup. We now have for the programmatic API for the underlying structure, shared between API and varnishd diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index 68ebbf7..d371b9f 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -29,6 +29,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -44,7 +47,6 @@ #include "vcli.h" #include "cli_common.h" #include "libvarnish.h" -#include "varnishapi.h" #include "vss.h" #ifdef HAVE_LIBEDIT diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index d3228a5..c5bc614 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -34,6 +34,9 @@ */ #define VARNISH_CACHE_CHILD 1 +#include "vapi/vsc_int.h" +#include "vapi/vsl_int.h" + #include #include @@ -54,9 +57,6 @@ #include "heritage.h" -#include "vsc.h" -#include "vsl.h" - enum body_status { #define BODYSTATUS(U,l) BS_##U, #include "tbl/body_status.h" diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index 17789f8..5b717b0 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -86,6 +86,9 @@ #include "config.h" +#include "vapi/vsl_int.h" +#include "vapi/vsc_int.h" + #include #include #include @@ -95,8 +98,6 @@ #include #include -#include "vsc.h" -#include "vsl.h" #include "mgt.h" #include "heritage.h" #include "vmb.h" diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 75f7bd9..9485df7 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -32,6 +32,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -46,8 +49,6 @@ #include #include "libvarnish.h" -#include "vsl.h" -#include "varnishapi.h" #define HIST_N 2000 /* how far back we remember */ #define HIST_LOW -6 /* low end of log range */ diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index c7749cb..c67432d 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -31,6 +31,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -45,8 +48,6 @@ #include "vpf.h" #include "libvarnish.h" -#include "vsl.h" -#include "varnishapi.h" static int b_flag, c_flag; diff --git a/bin/varnishncsa/base64.c b/bin/varnishncsa/base64.c index 23dae14..3758604 100644 --- a/bin/varnishncsa/base64.c +++ b/bin/varnishncsa/base64.c @@ -6,8 +6,10 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include -#include "varnishapi.h" #include "base64.h" static const char b64[] = diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 7c35c3e..bbaa366 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -59,6 +59,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -74,9 +77,7 @@ #include "vqueue.h" #include "libvarnish.h" -#include "vsl.h" #include "vre.h" -#include "varnishapi.h" #include "base64.h" static volatile sig_atomic_t reopen; diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index f7355cb..dbb6f51 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -28,6 +28,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -46,7 +49,6 @@ #include "vqueue.h" #include "libvarnish.h" -#include "varnishapi.h" #include "vss.h" #define freez(x) do { if (x) free(x); x = NULL; } while (0); diff --git a/bin/varnishsizes/varnishsizes.c b/bin/varnishsizes/varnishsizes.c index ccff669..ac9dbf8 100644 --- a/bin/varnishsizes/varnishsizes.c +++ b/bin/varnishsizes/varnishsizes.c @@ -32,6 +32,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -46,8 +49,6 @@ #include #include "libvarnish.h" -#include "vsl.h" -#include "varnishapi.h" #define HIST_N 2000 /* how far back we remember */ #define HIST_LOW 1 /* low end of log range */ diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index a8b1d5f..76a2e03 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -32,6 +32,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsc.h" + #include #include @@ -42,8 +45,6 @@ #include #include "libvarnish.h" -#include "vsc.h" -#include "varnishapi.h" #include "varnishstat.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 22d21fc..fc948e9 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -32,6 +32,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsc.h" + #include #ifdef HAVE_NCURSES_CURSES_H @@ -48,9 +51,7 @@ #include #include "libvarnish.h" -#include "vsc.h" #include "vqueue.h" -#include "varnishapi.h" #include "varnishstat.h" #if 0 diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index aea29a4..7362f1f 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -28,6 +28,10 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsc.h" +#include "vapi/vsl.h" + #include #include @@ -44,7 +48,6 @@ #include "vtc.h" #include "libvarnish.h" -#include "varnishapi.h" #include "vcli.h" #include "vss.h" diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 8459ab5..de3789f 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -32,6 +32,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include #include @@ -48,8 +51,6 @@ #include "vsb.h" #include "libvarnish.h" -#include "vsl.h" -#include "varnishapi.h" #if 0 #define AC(x) assert((x) != ERR) diff --git a/configure.ac b/configure.ac index ef7d76c..cf1f566 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2011 Varnish Software AS]) AC_REVISION([$Id$]) AC_INIT([Varnish], [trunk], [varnish-dev at varnish-cache.org]) -AC_CONFIG_SRCDIR(include/varnishapi.h) +AC_CONFIG_SRCDIR(include/miniobj.h) AM_CONFIG_HEADER(config.h) # save command line CFLAGS for use in VCC_CC (to pass through things like -m64) diff --git a/include/Makefile.am b/include/Makefile.am index 47fede9..0f1782f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -17,10 +17,10 @@ pkginclude_HEADERS = \ tbl/vsl_tags.h \ vapi/vsm.h \ vapi/vsc.h \ - varnishapi.h \ + vapi/vsc_int.h \ + vapi/vsl.h \ + vapi/vsl_int.h \ vcli.h \ - vsc.h \ - vsl.h \ vsm.h nobase_noinst_HEADERS = \ diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h index 290db9d..1101e53 100644 --- a/include/vapi/vsc.h +++ b/include/vapi/vsc.h @@ -31,6 +31,8 @@ #ifndef VAPI_VSC_H_INCLUDED #define VAPI_VSC_H_INCLUDED +#include "vapi/vsc_int.h" + /*--------------------------------------------------------------------- * VSC level access functions */ diff --git a/include/vapi/vsc_int.h b/include/vapi/vsc_int.h new file mode 100644 index 0000000..0a9cbf9 --- /dev/null +++ b/include/vapi/vsc_int.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + */ + +#include + +#define VSC_CLASS "Stat" + +#define VSC_TYPE_MAIN "" +#define VSC_TYPE_SMA "SMA" +#define VSC_TYPE_SMF "SMF" +#define VSC_TYPE_VBE "VBE" +#define VSC_TYPE_LCK "LCK" + +#define VSC_F(n, t, l, f, e, d) t n; + +#define VSC_DO(u,l,t) struct VSC_C_##l { +#define VSC_DONE(u,l,t) }; + +#include "tbl/vsc_all.h" + +#undef VSC_DO +#undef VSC_F +#undef VSC_DONE diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h new file mode 100644 index 0000000..5068f1c --- /dev/null +++ b/include/vapi/vsl.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#ifndef VAPI_VSL_H_INCLUDED +#define VAPI_VSL_H_INCLUDED + +#include + +#include "vapi/vsl_int.h" + +/*--------------------------------------------------------------------- + * VSL level access functions + */ + +void VSL_Setup(struct VSM_data *vd); + /* + * Setup vd for use with VSL functions. + */ + +int VSL_Open(struct VSM_data *vd, int diag); + /* + * Attempt to open and map the shared memory file. + * If diag is non-zero, diagnostics are emitted. + * Returns: + * 0 on success + * != 0 on failure + */ + +#define VSL_ARGS "bCcdI:i:k:n:r:s:X:x:m:" +#define VSL_b_USAGE "[-b]" +#define VSL_c_USAGE "[-c]" +#define VSL_C_USAGE "[-C]" +#define VSL_d_USAGE "[-d]" +#define VSL_i_USAGE "[-i tag]" +#define VSL_I_USAGE "[-I regexp]" +#define VSL_k_USAGE "[-k keep]" +#define VSL_m_USAGE "[-m tag:regex]" +#define VSL_n_USAGE VSM_n_USAGE +#define VSL_r_USAGE "[-r file]" +#define VSL_s_USAGE "[-s skip]" +#define VSL_x_USAGE "[-x tag]" +#define VSL_X_USAGE "[-X regexp]" +#define VSL_USAGE "[-bCcd] " \ + VSL_i_USAGE " " \ + VSL_I_USAGE " " \ + VSL_k_USAGE " " \ + VSL_m_USAGE " " \ + VSL_n_USAGE " " \ + VSL_r_USAGE " " \ + VSL_s_USAGE " " \ + VSL_X_USAGE " " \ + VSL_x_USAGE + +int VSL_Arg(struct VSM_data *vd, int arg, const char *opt); + /* + * Handle standard log-presenter arguments + * Return: + * -1 error + * 0 not handled + * 1 Handled. + */ + +typedef int VSL_handler_f(void *priv, enum VSL_tag_e tag, unsigned fd, + unsigned len, unsigned spec, const char *ptr, uint64_t bitmap); + +#define VSL_S_CLIENT (1 << 0) +#define VSL_S_BACKEND (1 << 1) +VSL_handler_f VSL_H_Print; +struct VSM_data; +void VSL_Select(const struct VSM_data *vd, unsigned tag); +void VSL_NonBlocking(const struct VSM_data *vd, int nb); +int VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv); +int VSL_NextLog(const struct VSM_data *lh, uint32_t **pp, uint64_t *bitmap); +int VSL_Matched(const struct VSM_data *vd, uint64_t bitmap); +int VSL_Name2Tag(const char *name, int l); +extern const char *VSL_tags[256]; + +#endif /* VAPI_VSL_H_INCLUDED */ diff --git a/include/vapi/vsl_int.h b/include/vapi/vsl_int.h new file mode 100644 index 0000000..8176cce --- /dev/null +++ b/include/vapi/vsl_int.h @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + * Define the layout of the shared memory log segment. + * + * NB: THIS IS NOT A PUBLIC API TO VARNISH! + */ + +#ifndef VAPI_VSL_FMT_H_INCLUDED +#define VAPI_VSL_FMT_H_INCLUDED + +#define VSL_CLASS "Log" + +/* + * Shared memory log format + * + * The log is structured as an array of 32bit unsigned integers. + * + * The first integer contains a non-zero serial number, which changes + * whenever writing the log starts from the front. + * + * Each logrecord consist of: + * [n] = ((type & 0xff) << 24) | (length & 0xffff) + * [n + 1] = identifier + * [n + 2] ... [m] = content + */ + +#define VSL_CLIENTMARKER (1U<<30) +#define VSL_BACKENDMARKER (1U<<31) +#define VSL_IDENTMASK (~(3U<<30)) + +#define VSL_WORDS(len) (((len) + 3) / 4) +#define VSL_END(ptr, len) ((ptr) + 2 + VSL_WORDS(len)) +#define VSL_NEXT(ptr) VSL_END(ptr, VSL_LEN(ptr)) +#define VSL_LEN(ptr) ((ptr)[0] & 0xffff) +#define VSL_TAG(ptr) ((ptr)[0] >> 24) +#define VSL_ID(ptr) (((ptr)[1]) & VSL_IDENTMASK) +#define VSL_CLIENT(ptr) (((ptr)[1]) & VSL_CLIENTMARKER) +#define VSL_BACKEND(ptr) (((ptr)[1]) & VSL_BACKENDMARKER) +#define VSL_DATA(ptr) ((char*)((ptr)+2)) + +#define VSL_ENDMARKER (((uint32_t)SLT_Reserved << 24) | 0x454545) /* "EEE" */ +#define VSL_WRAPMARKER (((uint32_t)SLT_Reserved << 24) | 0x575757) /* "WWW" */ + +/* + * The identifiers in shmlogtag are "SLT_" + XML tag. A script may be run + * on this file to extract the table rather than handcode it + */ +enum VSL_tag_e { + SLT_Bogus = 0, +#define SLTM(foo) SLT_##foo, +#include "tbl/vsl_tags.h" +#undef SLTM + SLT_Reserved = 255 +}; + +#endif /* VAPI_VSL_FMT_H_INCLUDED */ diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h index 8948028..0b7cdd8 100644 --- a/include/vapi/vsm.h +++ b/include/vapi/vsm.h @@ -31,8 +31,6 @@ #ifndef VAPI_VSM_H_INCLUDED #define VAPI_VSM_H_INCLUDED -// #include - /*--------------------------------------------------------------------- * VSM level access functions */ diff --git a/include/varnishapi.h b/include/varnishapi.h deleted file mode 100644 index 6960720..0000000 --- a/include/varnishapi.h +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -#ifndef VARNISHAPI_H_INCLUDED -#define VARNISHAPI_H_INCLUDED - -#include -#include - -#include - -#include "vsl.h" - -/* - * Various notes: - * All malloc failures will result in assert tripping. - * API use failures will trip assert. - */ - -/*--------------------------------------------------------------------- - * VSL level access functions - */ - -void VSL_Setup(struct VSM_data *vd); - /* - * Setup vd for use with VSL functions. - */ - -int VSL_Open(struct VSM_data *vd, int diag); - /* - * Attempt to open and map the shared memory file. - * If diag is non-zero, diagnostics are emitted. - * Returns: - * 0 on success - * != 0 on failure - */ - -#define VSL_ARGS "bCcdI:i:k:n:r:s:X:x:m:" -#define VSL_b_USAGE "[-b]" -#define VSL_c_USAGE "[-c]" -#define VSL_C_USAGE "[-C]" -#define VSL_d_USAGE "[-d]" -#define VSL_i_USAGE "[-i tag]" -#define VSL_I_USAGE "[-I regexp]" -#define VSL_k_USAGE "[-k keep]" -#define VSL_m_USAGE "[-m tag:regex]" -#define VSL_n_USAGE VSM_n_USAGE -#define VSL_r_USAGE "[-r file]" -#define VSL_s_USAGE "[-s skip]" -#define VSL_x_USAGE "[-x tag]" -#define VSL_X_USAGE "[-X regexp]" -#define VSL_USAGE "[-bCcd] " \ - VSL_i_USAGE " " \ - VSL_I_USAGE " " \ - VSL_k_USAGE " " \ - VSL_m_USAGE " " \ - VSL_n_USAGE " " \ - VSL_r_USAGE " " \ - VSL_s_USAGE " " \ - VSL_X_USAGE " " \ - VSL_x_USAGE - -int VSL_Arg(struct VSM_data *vd, int arg, const char *opt); - /* - * Handle standard log-presenter arguments - * Return: - * -1 error - * 0 not handled - * 1 Handled. - */ - -typedef int VSL_handler_f(void *priv, enum VSL_tag_e tag, unsigned fd, - unsigned len, unsigned spec, const char *ptr, uint64_t bitmap); - -#define VSL_S_CLIENT (1 << 0) -#define VSL_S_BACKEND (1 << 1) -VSL_handler_f VSL_H_Print; -struct VSM_data; -void VSL_Select(const struct VSM_data *vd, unsigned tag); -void VSL_NonBlocking(const struct VSM_data *vd, int nb); -int VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv); -int VSL_NextLog(const struct VSM_data *lh, uint32_t **pp, uint64_t *bitmap); -int VSL_Matched(const struct VSM_data *vd, uint64_t bitmap); -int VSL_Name2Tag(const char *name, int l); -extern const char *VSL_tags[256]; - -#endif diff --git a/include/vsc.h b/include/vsc.h deleted file mode 100644 index 0a9cbf9..0000000 --- a/include/vsc.h +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - */ - -#include - -#define VSC_CLASS "Stat" - -#define VSC_TYPE_MAIN "" -#define VSC_TYPE_SMA "SMA" -#define VSC_TYPE_SMF "SMF" -#define VSC_TYPE_VBE "VBE" -#define VSC_TYPE_LCK "LCK" - -#define VSC_F(n, t, l, f, e, d) t n; - -#define VSC_DO(u,l,t) struct VSC_C_##l { -#define VSC_DONE(u,l,t) }; - -#include "tbl/vsc_all.h" - -#undef VSC_DO -#undef VSC_F -#undef VSC_DONE diff --git a/include/vsl.h b/include/vsl.h deleted file mode 100644 index 64b0516..0000000 --- a/include/vsl.h +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - * Define the layout of the shared memory log segment. - * - * NB: THIS IS NOT A PUBLIC API TO VARNISH! - */ - -#ifndef SHMLOG_H_INCLUDED -#define SHMLOG_H_INCLUDED - -#define VSL_CLASS "Log" - -/* - * Shared memory log format - * - * The log is structured as an array of 32bit unsigned integers. - * - * The first integer contains a non-zero serial number, which changes - * whenever writing the log starts from the front. - * - * Each logrecord consist of: - * [n] = ((type & 0xff) << 24) | (length & 0xffff) - * [n + 1] = identifier - * [n + 2] ... [m] = content - */ - -#define VSL_CLIENTMARKER (1U<<30) -#define VSL_BACKENDMARKER (1U<<31) -#define VSL_IDENTMASK (~(3U<<30)) - -#define VSL_WORDS(len) (((len) + 3) / 4) -#define VSL_END(ptr, len) ((ptr) + 2 + VSL_WORDS(len)) -#define VSL_NEXT(ptr) VSL_END(ptr, VSL_LEN(ptr)) -#define VSL_LEN(ptr) ((ptr)[0] & 0xffff) -#define VSL_TAG(ptr) ((ptr)[0] >> 24) -#define VSL_ID(ptr) (((ptr)[1]) & VSL_IDENTMASK) -#define VSL_CLIENT(ptr) (((ptr)[1]) & VSL_CLIENTMARKER) -#define VSL_BACKEND(ptr) (((ptr)[1]) & VSL_BACKENDMARKER) -#define VSL_DATA(ptr) ((char*)((ptr)+2)) - -#define VSL_ENDMARKER (((uint32_t)SLT_Reserved << 24) | 0x454545) /* "EEE" */ -#define VSL_WRAPMARKER (((uint32_t)SLT_Reserved << 24) | 0x575757) /* "WWW" */ - -/* - * The identifiers in shmlogtag are "SLT_" + XML tag. A script may be run - * on this file to extract the table rather than handcode it - */ -enum VSL_tag_e { - SLT_Bogus = 0, -#define SLTM(foo) SLT_##foo, -#include "tbl/vsl_tags.h" -#undef SLTM - SLT_Reserved = 255 -}; - -#endif diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index 18f1fc7..74cf286 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -29,6 +29,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsc.h" + #include #include #include @@ -37,10 +40,8 @@ #include "vas.h" #include "vav.h" #include "vsm.h" -#include "vsc.h" #include "vqueue.h" #include "miniobj.h" -#include "varnishapi.h" #include "vsm_api.h" diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index ab538c5..a2efc5d 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -29,6 +29,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include @@ -39,11 +42,9 @@ #include "vas.h" #include "vsm.h" -#include "vsl.h" #include "vre.h" #include "vbm.h" #include "miniobj.h" -#include "varnishapi.h" #include "vsm_api.h" #include "vsl_api.h" diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c index 21cd8e9..f41129b 100644 --- a/lib/libvarnishapi/vsl_arg.c +++ b/lib/libvarnishapi/vsl_arg.c @@ -29,6 +29,9 @@ #include "config.h" +#include "vapi/vsm.h" +#include "vapi/vsl.h" + #include #include @@ -44,7 +47,6 @@ #include "vre.h" #include "vbm.h" #include "miniobj.h" -#include "varnishapi.h" #include "vsm_api.h" #include "vsl_api.h" diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 888a0d7..422bc74 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -29,6 +29,8 @@ #include "config.h" +#include "vapi/vsm.h" + #include #include #include @@ -45,7 +47,6 @@ #include "vsm.h" #include "vbm.h" #include "miniobj.h" -#include "varnishapi.h" #include "vsm_api.h" From phk at varnish-cache.org Sun Oct 9 17:47:34 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 19:47:34 +0200 Subject: [master] b3d6add Make TIM_parse() return double like all other TIM_ functions. Message-ID: commit b3d6addcbabd1885f7150c6fb45800a2bcbb339b Author: Poul-Henning Kamp Date: Sun Oct 9 17:46:57 2011 +0000 Make TIM_parse() return double like all other TIM_ functions. Eliminate libvarnish.h embedded #includes. diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index c5183a4..0380b55 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -58,6 +58,8 @@ #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 0 +#include + static int clock_gettime(int foo, struct timespec *ts) { diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 2c975d9..3b6182f 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -36,6 +36,7 @@ #include #include +#include #ifdef HAVE_PRIV_H #include diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index bbaa366..d010a73 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -69,6 +69,7 @@ #include #include #include +#include #include "compat/daemon.h" diff --git a/include/libvarnish.h b/include/libvarnish.h index 157a64e..b016848 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -28,10 +28,7 @@ * */ -#include -#include #include -#include #include "vas.h" @@ -88,7 +85,7 @@ void VTCP_set_read_timeout(int s, double seconds); /* from libvarnish/time.c */ #define TIM_FORMAT_SIZE 30 void TIM_format(double t, char *p); -time_t TIM_parse(const char *p); +double TIM_parse(const char *p); double TIM_mono(void); double TIM_real(void); void TIM_sleep(double t); diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index 854c2ff..b7c52f4 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "vqueue.h" diff --git a/lib/libvarnish/time.c b/lib/libvarnish/time.c index 8242853..31fc284 100644 --- a/lib/libvarnish/time.c +++ b/lib/libvarnish/time.c @@ -116,10 +116,10 @@ static const char *fmts[] = { NULL }; -time_t +double TIM_parse(const char *p) { - time_t t; + double t; struct tm tm; const char **r; diff --git a/lib/libvarnish/vmb.c b/lib/libvarnish/vmb.c index 7464bbe..2c004ce 100644 --- a/lib/libvarnish/vmb.c +++ b/lib/libvarnish/vmb.c @@ -27,6 +27,7 @@ */ #include +#include #include "libvarnish.h" #include "vmb.h" From phk at varnish-cache.org Sun Oct 9 18:02:37 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:02:37 +0200 Subject: [master] 7140886 Add missing include Message-ID: commit 71408867ba8fbc2ef5d51e6353ad9ecee0aee2c6 Author: Poul-Henning Kamp Date: Sun Oct 9 17:59:45 2011 +0000 Add missing include diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 422bc74..32d9e3d 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -31,6 +31,7 @@ #include "vapi/vsm.h" +#include #include #include #include From phk at varnish-cache.org Sun Oct 9 18:02:38 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:02:38 +0200 Subject: [master] 58db1e6 Isolate VTCP in its own include file Message-ID: commit 58db1e659a6b6055e27246047ec28218f991d2b2 Author: Poul-Henning Kamp Date: Sun Oct 9 18:02:15 2011 +0000 Isolate VTCP in its own include file diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index af5edec..87a9180 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -33,6 +33,7 @@ #include "cache.h" #include "vcli.h" +#include "vtcp.h" #include "cli_priv.h" static pthread_t VCA_thread; diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c index a724923..3ed7fcd 100644 --- a/bin/varnishd/cache_backend.c +++ b/bin/varnishd/cache_backend.c @@ -39,6 +39,7 @@ #include "cache_backend.h" #include "vrt.h" +#include "vtcp.h" /*-------------------------------------------------------------------- * The "simple" director really isn't, since thats where all the actual diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index be8ee6a..c90cda9 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -45,6 +45,7 @@ #include "cli_priv.h" #include "cache.h" #include "vrt.h" +#include "vtcp.h" #include "cache_backend.h" /* Default averaging rate, we want something pretty responsive */ diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 0b7f8bf..1415170 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -70,6 +70,7 @@ DOT acceptor -> start [style=bold,color=green] #include "cache.h" #include "vcl.h" +#include "vtcp.h" #include "cli_priv.h" #include "hash_slinger.h" #include "stevedore.h" diff --git a/bin/varnishd/cache_dir.c b/bin/varnishd/cache_dir.c index 03fdf26..ef882bf 100644 --- a/bin/varnishd/cache_dir.c +++ b/bin/varnishd/cache_dir.c @@ -34,6 +34,7 @@ #include "cache.h" #include "cache_backend.h" +#include "vtcp.h" /* Close a connection ------------------------------------------------*/ diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index df56c7a..d18e726 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -38,6 +38,7 @@ #include "stevedore.h" #include "cli_priv.h" #include "vct.h" +#include "vtcp.h" static unsigned fetchfrag; diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index e02da80..74343ba 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -35,6 +35,7 @@ #include #include "cache.h" +#include "vtcp.h" static int rdf(int fd0, int fd1) diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 0380b55..e146043 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -50,6 +50,7 @@ #include "cache_waiter.h" #include "hash_slinger.h" +#include "vtcp.h" /*-------------------------------------------------------------------- * MAC OS/X is incredibly moronic when it comes to time and such... diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index ae65058..1343ae4 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -36,6 +36,7 @@ #include "cache.h" #include "vrt.h" +#include "vtcp.h" #include "vrt_obj.h" #include "cache_backend.h" #include "hash_slinger.h" diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index ba2effe..6c1cf71 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -52,6 +52,7 @@ #include "vlu.h" #include "vss.h" #include "vbm.h" +#include "vtcp.h" pid_t child_pid = -1; diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index eccf268..4488d51 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -51,6 +51,7 @@ #include "vev.h" #include "vlu.h" #include "vss.h" +#include "vtcp.h" #include "mgt.h" diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 2c75622..55e25fa 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -38,6 +38,7 @@ #include "vtc.h" #include "vss.h" +#include "vtcp.h" #include "libvarnish.h" struct client { diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 4582d4c..50816bc 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -41,6 +41,7 @@ #include "libvarnish.h" #include "vtc.h" +#include "vtcp.h" #include "vgz.h" diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index d541d67..afe62af 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -37,6 +37,7 @@ #include #include "vtc.h" +#include "vtcp.h" #include "libvarnish.h" #include "vss.h" diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 7362f1f..8b310f6 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -46,6 +46,7 @@ #include #include "vtc.h" +#include "vtcp.h" #include "libvarnish.h" diff --git a/include/Makefile.am b/include/Makefile.am index 0f1782f..66c2ddd 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -55,7 +55,8 @@ nobase_noinst_HEADERS = \ vrt_obj.h \ vsb.h \ vsha256.h \ - vss.h + vss.h \ + vtcp.h tbl/vrt_stv_var.h tbl/vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h mkdir -p tbl diff --git a/include/libvarnish.h b/include/libvarnish.h index b016848..6008781 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -48,40 +48,6 @@ typedef void sub_func_f(void*); int SUB_run(struct vsb *sb, sub_func_f *func, void *priv, const char *name, int maxlines); -/* from libvarnish/tcp.c */ -/* NI_MAXHOST and NI_MAXSERV are ridiculously long for numeric format */ -#define VTCP_ADDRBUFSIZE 64 -#define VTCP_PORTBUFSIZE 16 - -#if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__) -/* - * Solaris returns EINVAL if the other end unexepectedly reset the - * connection. This is a bug in Solaris and documented behaviour on NetBSD. - */ -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN \ - || errno == EINVAL) -#else -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN) -#endif - -#define VTCP_Assert(a) assert(VTCP_Check(a)) - -void VTCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); -void VTCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); -int VTCP_filter_http(int sock); -int VTCP_blocking(int sock); -int VTCP_nonblocking(int sock); -int VTCP_linger(int sock, int linger); -#ifdef SOL_SOCKET -int VTCP_port(const struct sockaddr_storage *addr); -void VTCP_name(const struct sockaddr_storage *addr, unsigned l, char *abuf, - unsigned alen, char *pbuf, unsigned plen); -int VTCP_connect(int s, const struct sockaddr_storage *name, socklen_t namelen, - int msec); -void VTCP_close(int *s); -void VTCP_set_read_timeout(int s, double seconds); -#endif - /* from libvarnish/time.c */ #define TIM_FORMAT_SIZE 30 void TIM_format(double t, char *p); diff --git a/include/vtcp.h b/include/vtcp.h new file mode 100644 index 0000000..022f101 --- /dev/null +++ b/include/vtcp.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* from libvarnish/tcp.c */ +/* NI_MAXHOST and NI_MAXSERV are ridiculously long for numeric format */ +#define VTCP_ADDRBUFSIZE 64 +#define VTCP_PORTBUFSIZE 16 + +#if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__) +/* + * Solaris returns EINVAL if the other end unexepectedly reset the + * connection. This is a bug in Solaris and documented behaviour on NetBSD. + */ +#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN \ + || errno == EINVAL) +#else +#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN) +#endif + +#define VTCP_Assert(a) assert(VTCP_Check(a)) + +void VTCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); +void VTCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); +int VTCP_filter_http(int sock); +int VTCP_blocking(int sock); +int VTCP_nonblocking(int sock); +int VTCP_linger(int sock, int linger); + +#ifdef SOL_SOCKET +int VTCP_port(const struct sockaddr_storage *addr); +void VTCP_name(const struct sockaddr_storage *addr, unsigned l, char *abuf, + unsigned alen, char *pbuf, unsigned plen); +int VTCP_connect(int s, const struct sockaddr_storage *name, socklen_t namelen, + int msec); +void VTCP_close(int *s); +void VTCP_set_read_timeout(int s, double seconds); +#endif diff --git a/lib/libvarnish/tcp.c b/lib/libvarnish/tcp.c index c612e97..e8932e8 100644 --- a/lib/libvarnish/tcp.c +++ b/lib/libvarnish/tcp.c @@ -51,8 +51,7 @@ #include #include -#include "config.h" - +#include "vtcp.h" #include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvarnish/vss.c b/lib/libvarnish/vss.c index 42b4db7..ff19ac7 100644 --- a/lib/libvarnish/vss.c +++ b/lib/libvarnish/vss.c @@ -44,6 +44,7 @@ #include #include "libvarnish.h" +#include "vtcp.h" #include "vss.h" /* lightweight addrinfo */ diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 544e2dc..847c705 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -32,6 +32,7 @@ #include #include #include "vrt.h" +#include "vtcp.h" #include "../../bin/varnishd/cache.h" #include "vcc_if.h" From phk at varnish-cache.org Sun Oct 9 18:20:28 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:20:28 +0200 Subject: [master] 6570945 Isolate VAV from libvarnish.h Message-ID: commit 6570945671d2ab43b3ced048a31df7133d45c1dc Author: Poul-Henning Kamp Date: Sun Oct 9 18:06:29 2011 +0000 Isolate VAV from libvarnish.h diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 7e45b8a..4001c7c 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -61,6 +61,7 @@ #include "stevedore.h" #include "hash_slinger.h" #include "vsha256.h" +#include "vav.h" #include "cache_backend.h" static const struct hash_slinger *hash; diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index f0407cc..a53799e 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -41,6 +41,7 @@ #include "vrt.h" #include "vrt_obj.h" +#include "vav.h" #include "vcl.h" #include "hash_slinger.h" #include "cache_backend.h" diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 7138369..f849fbb 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -47,6 +47,7 @@ #include "vparam.h" #include "cache_waiter.h" +#include "vav.h" #include "vss.h" #define MAGIC_INIT_STRING "\001" diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index 5b717b0..38dc59a 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -102,6 +102,7 @@ #include "heritage.h" #include "vmb.h" #include "vsm.h" +#include "vav.h" #include "flopen.h" #ifndef MAP_HASSEMAPHORE diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index 143e534..6d71635 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -38,6 +38,7 @@ #include "cache.h" #include "stevedore.h" +#include "vav.h" #include "cli_priv.h" #include "vrt_obj.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 0219eb0..2d7db59 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -53,6 +53,7 @@ #include "vcli.h" #include "cli_common.h" +#include "vav.h" #include "vin.h" #include "heritage.h" #include "mgt.h" diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 506aee1..e31eaca 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -39,6 +39,7 @@ #include "vtc.h" +#include "vav.h" #include "libvarnish.h" diff --git a/include/libvarnish.h b/include/libvarnish.h index 6008781..a40aa20 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -38,8 +38,6 @@ struct vsb; -#include "vav.h" - /* from libvarnish/num.c */ const char *str2bytes(const char *p, uintmax_t *r, uintmax_t rel); diff --git a/lib/libvarnish/argv.c b/lib/libvarnish/argv.c index ad088cd..a0c57bb 100644 --- a/lib/libvarnish/argv.c +++ b/lib/libvarnish/argv.c @@ -43,7 +43,8 @@ #include #include -#include "libvarnish.h" +#include "vas.h" +#include "vav.h" int VAV_BackSlash(const char *s, char *res) diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index b7c52f4..03cf1d4 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -41,6 +41,7 @@ #include "vqueue.h" #include "vsb.h" +#include "vav.h" #include "vlu.h" #include "vcli.h" #include "cli_priv.h" From phk at varnish-cache.org Sun Oct 9 18:20:29 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:20:29 +0200 Subject: [master] 7ce0d47 Rename source files to their VTLA names Message-ID: commit 7ce0d474d5b36e4feaf38df30594611060397e0f Author: Poul-Henning Kamp Date: Sun Oct 9 18:20:10 2011 +0000 Rename source files to their VTLA names diff --git a/bin/varnishadm/Makefile.am b/bin/varnishadm/Makefile.am index 93997b9..201a361 100644 --- a/bin/varnishadm/Makefile.am +++ b/bin/varnishadm/Makefile.am @@ -8,8 +8,8 @@ dist_man_MANS = varnishadm.1 varnishadm_SOURCES = \ varnishadm.c \ - $(top_builddir)/lib/libvarnish/assert.c \ - $(top_builddir)/lib/libvarnish/tcp.c \ + $(top_builddir)/lib/libvarnish/vas.c \ + $(top_builddir)/lib/libvarnish/vtcp.c \ $(top_builddir)/lib/libvarnish/vss.c varnishadm_CFLAGS = @LIBEDIT_CFLAGS@ diff --git a/bin/varnishhist/Makefile.am b/bin/varnishhist/Makefile.am index 8f19313..8aafa2d 100644 --- a/bin/varnishhist/Makefile.am +++ b/bin/varnishhist/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = varnishhist dist_man_MANS = varnishhist.1 varnishhist_SOURCES = varnishhist.c \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/version.c varnishhist_LDADD = \ diff --git a/bin/varnishlog/Makefile.am b/bin/varnishlog/Makefile.am index 79bf2ad..e21ee35 100644 --- a/bin/varnishlog/Makefile.am +++ b/bin/varnishlog/Makefile.am @@ -8,7 +8,7 @@ dist_man_MANS = varnishlog.1 varnishlog_SOURCES = \ varnishlog.c \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/flopen.c \ $(top_builddir)/lib/libvarnish/version.c \ $(top_builddir)/lib/libvarnish/vsb.c \ diff --git a/bin/varnishncsa/Makefile.am b/bin/varnishncsa/Makefile.am index 9b652da..8b3f617 100644 --- a/bin/varnishncsa/Makefile.am +++ b/bin/varnishncsa/Makefile.am @@ -10,7 +10,7 @@ varnishncsa_SOURCES = \ varnishncsa.c \ base64.c \ base64.h \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/flopen.c \ $(top_builddir)/lib/libvarnish/version.c \ $(top_builddir)/lib/libvarnish/vsb.c \ diff --git a/bin/varnishreplay/Makefile.am b/bin/varnishreplay/Makefile.am index 553dfda..2be20f7 100644 --- a/bin/varnishreplay/Makefile.am +++ b/bin/varnishreplay/Makefile.am @@ -8,8 +8,8 @@ dist_man_MANS = varnishreplay.1 varnishreplay_SOURCES = \ varnishreplay.c \ - $(top_builddir)/lib/libvarnish/assert.c \ - $(top_builddir)/lib/libvarnish/tcp.c \ + $(top_builddir)/lib/libvarnish/vas.c \ + $(top_builddir)/lib/libvarnish/vtcp.c \ $(top_builddir)/lib/libvarnish/vss.c varnishreplay_LDADD = \ diff --git a/bin/varnishsizes/Makefile.am b/bin/varnishsizes/Makefile.am index a25b280..8029741 100644 --- a/bin/varnishsizes/Makefile.am +++ b/bin/varnishsizes/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = varnishsizes dist_man_MANS = varnishsizes.1 varnishsizes_SOURCES = varnishsizes.c \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/version.c varnishsizes_LDADD = \ diff --git a/bin/varnishstat/Makefile.am b/bin/varnishstat/Makefile.am index 8407eb2..83588c9 100644 --- a/bin/varnishstat/Makefile.am +++ b/bin/varnishstat/Makefile.am @@ -11,7 +11,7 @@ varnishstat_SOURCES = \ \ varnishstat.c \ varnishstat_curses.c \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/version.c varnishstat_LDADD = \ diff --git a/bin/varnishtop/Makefile.am b/bin/varnishtop/Makefile.am index dab412f..630fbf7 100644 --- a/bin/varnishtop/Makefile.am +++ b/bin/varnishtop/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = varnishtop dist_man_MANS = varnishtop.1 varnishtop_SOURCES = varnishtop.c \ - $(top_builddir)/lib/libvarnish/assert.c \ + $(top_builddir)/lib/libvarnish/vas.c \ $(top_builddir)/lib/libvarnish/version.c varnishtop_LDADD = \ diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index 21a9d98..b8651cc 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -5,8 +5,8 @@ pkglib_LTLIBRARIES = libvarnish.la libvarnish_la_LDFLAGS = -avoid-version libvarnish_la_SOURCES = \ - argv.c \ - assert.c \ + vav.c \ + vas.c \ binary_heap.c \ subproc.c \ cli_auth.c \ @@ -15,7 +15,7 @@ libvarnish_la_SOURCES = \ flopen.c \ num.c \ time.c \ - tcp.c \ + vtcp.c \ vct.c \ version.c \ vev.c \ diff --git a/lib/libvarnish/argv.c b/lib/libvarnish/argv.c deleted file mode 100644 index a0c57bb..0000000 --- a/lib/libvarnish/argv.c +++ /dev/null @@ -1,264 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * const char **VAV_Parse(const char *s, int comment) - * Parse a command like line into an argv[] - * Index zero contains NULL or an error message - * "double quotes" and backslash substitution is handled. - * - * void VAV_Free(const char **argv) - * Free the result of VAV_Parse() - * - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "vas.h" -#include "vav.h" - -int -VAV_BackSlash(const char *s, char *res) -{ - int r; - char c; - unsigned u; - - assert(*s == '\\'); - r = c = 0; - switch(s[1]) { - case 'n': - c = '\n'; - r = 2; - break; - case 'r': - c = '\r'; - r = 2; - break; - case 't': - c = '\t'; - r = 2; - break; - case '"': - c = '"'; - r = 2; - break; - case '\\': - c = '\\'; - r = 2; - break; - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - for (r = 1; r < 4; r++) { - if (!isdigit(s[r])) - break; - if (s[r] - '0' > 7) - break; - c <<= 3; /*lint !e701 signed left shift */ - c |= s[r] - '0'; - } - break; - case 'x': - if (1 == sscanf(s + 1, "x%02x", &u)) { - assert(!(u & ~0xff)); - c = u; /*lint !e734 loss of precision */ - r = 4; - } - break; - default: - break; - } - if (res != NULL) - *res = c; - return (r); -} - -char * -VAV_BackSlashDecode(const char *s, const char *e) -{ - const char *q; - char *p, *r; - int i; - - if (e == NULL) - e = strchr(s, '\0'); - assert(e != NULL); - p = calloc((e - s) + 1, 1); - if (p == NULL) - return (p); - for (r = p, q = s; q < e; ) { - if (*q != '\\') { - *r++ = *q++; - continue; - } - i = VAV_BackSlash(q, r); - q += i; - r++; - } - *r = '\0'; - return (p); -} - -static char err_invalid_backslash[] = "Invalid backslash sequence"; -static char err_missing_quote[] = "Missing '\"'"; - -char ** -VAV_Parse(const char *s, int *argc, int flag) -{ - char **argv; - const char *p; - int nargv, largv; - int i, quote; - - assert(s != NULL); - nargv = 1; - largv = 16; - argv = calloc(sizeof *argv, largv); - if (argv == NULL) - return (NULL); - - for (;;) { - if (*s == '\0') - break; - if (isspace(*s)) { - s++; - continue; - } - if ((flag & ARGV_COMMENT) && *s == '#') - break; - if (*s == '"' && !(flag & ARGV_NOESC)) { - p = ++s; - quote = 1; - } else { - p = s; - quote = 0; - } - while (1) { - if (*s == '\\' && !(flag & ARGV_NOESC)) { - i = VAV_BackSlash(s, NULL); - if (i == 0) { - argv[0] = err_invalid_backslash; - return (argv); - } - s += i; - continue; - } - if (!quote) { - if (*s == '\0' || isspace(*s)) - break; - if ((flag & ARGV_COMMA) && *s == ',') - break; - s++; - continue; - } - if (*s == '"' && !(flag & ARGV_NOESC)) - break; - if (*s == '\0') { - argv[0] = err_missing_quote; - return (argv); - } - s++; - } - if (nargv + 1 >= largv) { - argv = realloc(argv, sizeof (*argv) * (largv += largv)); - assert(argv != NULL); - } - if (flag & ARGV_NOESC) { - argv[nargv] = malloc(1 + (s - p)); - assert(argv[nargv] != NULL); - memcpy(argv[nargv], p, s - p); - argv[nargv][s - p] = '\0'; - nargv++; - } else { - argv[nargv++] = VAV_BackSlashDecode(p, s); - } - if (*s != '\0') - s++; - } - argv[nargv] = NULL; - if (argc != NULL) - *argc = nargv; - return (argv); -} - -void -VAV_Free(char **argv) -{ - int i; - - for (i = 1; argv[i] != NULL; i++) - free(argv[i]); - free(argv); -} - -#ifdef TESTPROG - -#include - -static void -VAV_Print(char **argv) -{ - int i; - - printf("---- %p\n", argv); - if (argv[0] != NULL) - printf("err %V\n", argv[0]); - for (i = 1; argv[i] != NULL; i++) - printf("%3d %V\n", i, argv[i]); -} - -static void -Test(const char *str) -{ - char **av; - - printf("Test: <%V>\n", str); - av = VAV_Parse(str, 0); - VAV_Print(av); -} - -int -main(int argc, char **argv) -{ - char buf[BUFSIZ]; - - (void)argc; - (void)argv; - - register_printf_render_std("V"); - - while (fgets(buf, sizeof buf, stdin)) - Test(buf); - - return (0); -} -#endif diff --git a/lib/libvarnish/assert.c b/lib/libvarnish/assert.c deleted file mode 100644 index 82351ce..0000000 --- a/lib/libvarnish/assert.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * This is the default backend function for libvarnish' assert facilities. - */ - -#include "config.h" - -#include -#include -#include - -#include "libvarnish.h" - -static void -VAS_Fail_default(const char *func, const char *file, int line, - const char *cond, int err, int xxx) -{ - - if (xxx) { - fprintf(stderr, - "Missing errorhandling code in %s(), %s line %d:\n" - " Condition(%s) not true.\n", - func, file, line, cond); - } else { - fprintf(stderr, - "Assert error in %s(), %s line %d:\n" - " Condition(%s) not true.\n", - func, file, line, cond); - } - if (err) - fprintf(stderr, - " errno = %d (%s)\n", err, strerror(err)); - abort(); -} - -vas_f *VAS_Fail = VAS_Fail_default; diff --git a/lib/libvarnish/tcp.c b/lib/libvarnish/tcp.c deleted file mode 100644 index e8932e8..0000000 --- a/lib/libvarnish/tcp.c +++ /dev/null @@ -1,290 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - */ - -#include "config.h" - -#include -#include - -#include - -#ifdef __linux -#include -#endif - -#include -#include -#ifdef HAVE_SYS_FILIO_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include "vtcp.h" -#include "libvarnish.h" - -/*--------------------------------------------------------------------*/ - -int -VTCP_port(const struct sockaddr_storage *addr) -{ - - if (addr->ss_family == AF_INET) { - const struct sockaddr_in *ain = (const void *)addr; - return ntohs((ain->sin_port)); - } - if (addr->ss_family == AF_INET6) { - const struct sockaddr_in6 *ain = (const void *)addr; - return ntohs((ain->sin6_port)); - } - return (-1); -} - - -/*--------------------------------------------------------------------*/ - -void -VTCP_name(const struct sockaddr_storage *addr, unsigned l, - char *abuf, unsigned alen, char *pbuf, unsigned plen) -{ - int i; - - i = getnameinfo((const void *)addr, l, abuf, alen, pbuf, plen, - NI_NUMERICHOST | NI_NUMERICSERV); - if (i) { - /* - * XXX this printf is shitty, but we may not have space - * for the gai_strerror in the bufffer :-( - */ - printf("getnameinfo = %d %s\n", i, gai_strerror(i)); - (void)snprintf(abuf, alen, "Conversion"); - (void)snprintf(pbuf, plen, "Failed"); - return; - } - /* XXX dirty hack for v4-to-v6 mapped addresses */ - if (strncmp(abuf, "::ffff:", 7) == 0) { - for (i = 0; abuf[i + 7]; ++i) - abuf[i] = abuf[i + 7]; - abuf[i] = '\0'; - } -} - -/*--------------------------------------------------------------------*/ - -void -VTCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen) -{ - struct sockaddr_storage addr_s; - socklen_t l; - - l = sizeof addr_s; - AZ(getsockname(sock, (void *)&addr_s, &l)); - VTCP_name(&addr_s, l, abuf, alen, pbuf, plen); -} -/*--------------------------------------------------------------------*/ - -void -VTCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen) -{ - struct sockaddr_storage addr_s; - socklen_t l; - - l = sizeof addr_s; - if (!getpeername(sock, (void*)&addr_s, &l)) - VTCP_name(&addr_s, l, abuf, alen, pbuf, plen); - else { - (void)snprintf(abuf, alen, ""); - (void)snprintf(pbuf, plen, ""); - } -} - -/*--------------------------------------------------------------------*/ - -int -VTCP_filter_http(int sock) -{ -#ifdef HAVE_ACCEPT_FILTERS - struct accept_filter_arg afa; - int i; - - memset(&afa, 0, sizeof(afa)); - strcpy(afa.af_name, "httpready"); - errno = 0; - i = setsockopt(sock, SOL_SOCKET, SO_ACCEPTFILTER, - &afa, sizeof(afa)); - /* XXX ugly */ - if (i) - printf("Acceptfilter(%d, httpready): %d %s\n", - sock, i, strerror(errno)); - return (i); -#elif defined(__linux) - int defer = 1; - setsockopt(sock, SOL_TCP,TCP_DEFER_ACCEPT,(char *) &defer, sizeof(int)); - return (0); -#else - (void)sock; - return (0); -#endif -} - -/*-------------------------------------------------------------------- - * Functions for controlling NONBLOCK mode. - * - * We use FIONBIO because it is cheaper than fcntl(2), which requires - * us to do two syscalls, one to get and one to set, the latter of - * which mucks about a bit before it ends up calling ioctl(FIONBIO), - * at least on FreeBSD. - */ - -int -VTCP_blocking(int sock) -{ - int i, j; - - i = 0; - j = ioctl(sock, FIONBIO, &i); - VTCP_Assert(j); - return (j); -} - -int -VTCP_nonblocking(int sock) -{ - int i, j; - - i = 1; - j = ioctl(sock, FIONBIO, &i); - VTCP_Assert(j); - return (j); -} - -/*-------------------------------------------------------------------- - * On TCP a connect(2) can block for a looong time, and we don't want that. - * Unfortunately, the SocketWizards back in those days were happy to wait - * any amount of time for a connection, so the connect(2) syscall does not - * take an argument for patience. - * - * There is a little used work-around, and we employ it at our peril. - * - */ - -int -VTCP_connect(int s, const struct sockaddr_storage *name, socklen_t namelen, int msec) -{ - int i, k; - socklen_t l; - struct pollfd fds[1]; - - assert(s >= 0); - - /* Set the socket non-blocking */ - if (msec > 0) - (void)VTCP_nonblocking(s); - - /* Attempt the connect */ - i = connect(s, (const void *)name, namelen); - if (i == 0 || errno != EINPROGRESS) - return (i); - - assert(msec > 0); - /* Exercise our patience, polling for write */ - fds[0].fd = s; - fds[0].events = POLLWRNORM; - fds[0].revents = 0; - i = poll(fds, 1, msec); - - if (i == 0) { - /* Timeout, close and give up */ - errno = ETIMEDOUT; - return (-1); - } - - /* Find out if we got a connection */ - l = sizeof k; - AZ(getsockopt(s, SOL_SOCKET, SO_ERROR, &k, &l)); - - /* An error means no connection established */ - errno = k; - if (k) - return (-1); - - (void)VTCP_blocking(s); - return (0); -} - -/*-------------------------------------------------------------------- - * When closing a TCP connection, a couple of errno's are legit, we - * can't be held responsible for the other end wanting to talk to us. - */ - -void -VTCP_close(int *s) -{ - int i; - - i = close(*s); - - assert (VTCP_Check(i)); - *s = -1; -} - -void -VTCP_set_read_timeout(int s, double seconds) -{ - struct timeval timeout; - timeout.tv_sec = (int)floor(seconds); - timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec)); -#ifdef SO_RCVTIMEO_WORKS - AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); -#else - (void)s; -#endif -} - -/*-------------------------------------------------------------------- - * Set or reset SO_LINGER flag - */ - -int -VTCP_linger(int sock, int linger) -{ - struct linger lin; - int i; - - memset(&lin, 0, sizeof lin); - lin.l_onoff = linger; - i = setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof lin); - VTCP_Assert(i); - return (i); -} diff --git a/lib/libvarnish/vas.c b/lib/libvarnish/vas.c new file mode 100644 index 0000000..82351ce --- /dev/null +++ b/lib/libvarnish/vas.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * This is the default backend function for libvarnish' assert facilities. + */ + +#include "config.h" + +#include +#include +#include + +#include "libvarnish.h" + +static void +VAS_Fail_default(const char *func, const char *file, int line, + const char *cond, int err, int xxx) +{ + + if (xxx) { + fprintf(stderr, + "Missing errorhandling code in %s(), %s line %d:\n" + " Condition(%s) not true.\n", + func, file, line, cond); + } else { + fprintf(stderr, + "Assert error in %s(), %s line %d:\n" + " Condition(%s) not true.\n", + func, file, line, cond); + } + if (err) + fprintf(stderr, + " errno = %d (%s)\n", err, strerror(err)); + abort(); +} + +vas_f *VAS_Fail = VAS_Fail_default; diff --git a/lib/libvarnish/vav.c b/lib/libvarnish/vav.c new file mode 100644 index 0000000..a0c57bb --- /dev/null +++ b/lib/libvarnish/vav.c @@ -0,0 +1,264 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * const char **VAV_Parse(const char *s, int comment) + * Parse a command like line into an argv[] + * Index zero contains NULL or an error message + * "double quotes" and backslash substitution is handled. + * + * void VAV_Free(const char **argv) + * Free the result of VAV_Parse() + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "vas.h" +#include "vav.h" + +int +VAV_BackSlash(const char *s, char *res) +{ + int r; + char c; + unsigned u; + + assert(*s == '\\'); + r = c = 0; + switch(s[1]) { + case 'n': + c = '\n'; + r = 2; + break; + case 'r': + c = '\r'; + r = 2; + break; + case 't': + c = '\t'; + r = 2; + break; + case '"': + c = '"'; + r = 2; + break; + case '\\': + c = '\\'; + r = 2; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + for (r = 1; r < 4; r++) { + if (!isdigit(s[r])) + break; + if (s[r] - '0' > 7) + break; + c <<= 3; /*lint !e701 signed left shift */ + c |= s[r] - '0'; + } + break; + case 'x': + if (1 == sscanf(s + 1, "x%02x", &u)) { + assert(!(u & ~0xff)); + c = u; /*lint !e734 loss of precision */ + r = 4; + } + break; + default: + break; + } + if (res != NULL) + *res = c; + return (r); +} + +char * +VAV_BackSlashDecode(const char *s, const char *e) +{ + const char *q; + char *p, *r; + int i; + + if (e == NULL) + e = strchr(s, '\0'); + assert(e != NULL); + p = calloc((e - s) + 1, 1); + if (p == NULL) + return (p); + for (r = p, q = s; q < e; ) { + if (*q != '\\') { + *r++ = *q++; + continue; + } + i = VAV_BackSlash(q, r); + q += i; + r++; + } + *r = '\0'; + return (p); +} + +static char err_invalid_backslash[] = "Invalid backslash sequence"; +static char err_missing_quote[] = "Missing '\"'"; + +char ** +VAV_Parse(const char *s, int *argc, int flag) +{ + char **argv; + const char *p; + int nargv, largv; + int i, quote; + + assert(s != NULL); + nargv = 1; + largv = 16; + argv = calloc(sizeof *argv, largv); + if (argv == NULL) + return (NULL); + + for (;;) { + if (*s == '\0') + break; + if (isspace(*s)) { + s++; + continue; + } + if ((flag & ARGV_COMMENT) && *s == '#') + break; + if (*s == '"' && !(flag & ARGV_NOESC)) { + p = ++s; + quote = 1; + } else { + p = s; + quote = 0; + } + while (1) { + if (*s == '\\' && !(flag & ARGV_NOESC)) { + i = VAV_BackSlash(s, NULL); + if (i == 0) { + argv[0] = err_invalid_backslash; + return (argv); + } + s += i; + continue; + } + if (!quote) { + if (*s == '\0' || isspace(*s)) + break; + if ((flag & ARGV_COMMA) && *s == ',') + break; + s++; + continue; + } + if (*s == '"' && !(flag & ARGV_NOESC)) + break; + if (*s == '\0') { + argv[0] = err_missing_quote; + return (argv); + } + s++; + } + if (nargv + 1 >= largv) { + argv = realloc(argv, sizeof (*argv) * (largv += largv)); + assert(argv != NULL); + } + if (flag & ARGV_NOESC) { + argv[nargv] = malloc(1 + (s - p)); + assert(argv[nargv] != NULL); + memcpy(argv[nargv], p, s - p); + argv[nargv][s - p] = '\0'; + nargv++; + } else { + argv[nargv++] = VAV_BackSlashDecode(p, s); + } + if (*s != '\0') + s++; + } + argv[nargv] = NULL; + if (argc != NULL) + *argc = nargv; + return (argv); +} + +void +VAV_Free(char **argv) +{ + int i; + + for (i = 1; argv[i] != NULL; i++) + free(argv[i]); + free(argv); +} + +#ifdef TESTPROG + +#include + +static void +VAV_Print(char **argv) +{ + int i; + + printf("---- %p\n", argv); + if (argv[0] != NULL) + printf("err %V\n", argv[0]); + for (i = 1; argv[i] != NULL; i++) + printf("%3d %V\n", i, argv[i]); +} + +static void +Test(const char *str) +{ + char **av; + + printf("Test: <%V>\n", str); + av = VAV_Parse(str, 0); + VAV_Print(av); +} + +int +main(int argc, char **argv) +{ + char buf[BUFSIZ]; + + (void)argc; + (void)argv; + + register_printf_render_std("V"); + + while (fgets(buf, sizeof buf, stdin)) + Test(buf); + + return (0); +} +#endif diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c new file mode 100644 index 0000000..e8932e8 --- /dev/null +++ b/lib/libvarnish/vtcp.c @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + */ + +#include "config.h" + +#include +#include + +#include + +#ifdef __linux +#include +#endif + +#include +#include +#ifdef HAVE_SYS_FILIO_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "vtcp.h" +#include "libvarnish.h" + +/*--------------------------------------------------------------------*/ + +int +VTCP_port(const struct sockaddr_storage *addr) +{ + + if (addr->ss_family == AF_INET) { + const struct sockaddr_in *ain = (const void *)addr; + return ntohs((ain->sin_port)); + } + if (addr->ss_family == AF_INET6) { + const struct sockaddr_in6 *ain = (const void *)addr; + return ntohs((ain->sin6_port)); + } + return (-1); +} + + +/*--------------------------------------------------------------------*/ + +void +VTCP_name(const struct sockaddr_storage *addr, unsigned l, + char *abuf, unsigned alen, char *pbuf, unsigned plen) +{ + int i; + + i = getnameinfo((const void *)addr, l, abuf, alen, pbuf, plen, + NI_NUMERICHOST | NI_NUMERICSERV); + if (i) { + /* + * XXX this printf is shitty, but we may not have space + * for the gai_strerror in the bufffer :-( + */ + printf("getnameinfo = %d %s\n", i, gai_strerror(i)); + (void)snprintf(abuf, alen, "Conversion"); + (void)snprintf(pbuf, plen, "Failed"); + return; + } + /* XXX dirty hack for v4-to-v6 mapped addresses */ + if (strncmp(abuf, "::ffff:", 7) == 0) { + for (i = 0; abuf[i + 7]; ++i) + abuf[i] = abuf[i + 7]; + abuf[i] = '\0'; + } +} + +/*--------------------------------------------------------------------*/ + +void +VTCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen) +{ + struct sockaddr_storage addr_s; + socklen_t l; + + l = sizeof addr_s; + AZ(getsockname(sock, (void *)&addr_s, &l)); + VTCP_name(&addr_s, l, abuf, alen, pbuf, plen); +} +/*--------------------------------------------------------------------*/ + +void +VTCP_hisname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen) +{ + struct sockaddr_storage addr_s; + socklen_t l; + + l = sizeof addr_s; + if (!getpeername(sock, (void*)&addr_s, &l)) + VTCP_name(&addr_s, l, abuf, alen, pbuf, plen); + else { + (void)snprintf(abuf, alen, ""); + (void)snprintf(pbuf, plen, ""); + } +} + +/*--------------------------------------------------------------------*/ + +int +VTCP_filter_http(int sock) +{ +#ifdef HAVE_ACCEPT_FILTERS + struct accept_filter_arg afa; + int i; + + memset(&afa, 0, sizeof(afa)); + strcpy(afa.af_name, "httpready"); + errno = 0; + i = setsockopt(sock, SOL_SOCKET, SO_ACCEPTFILTER, + &afa, sizeof(afa)); + /* XXX ugly */ + if (i) + printf("Acceptfilter(%d, httpready): %d %s\n", + sock, i, strerror(errno)); + return (i); +#elif defined(__linux) + int defer = 1; + setsockopt(sock, SOL_TCP,TCP_DEFER_ACCEPT,(char *) &defer, sizeof(int)); + return (0); +#else + (void)sock; + return (0); +#endif +} + +/*-------------------------------------------------------------------- + * Functions for controlling NONBLOCK mode. + * + * We use FIONBIO because it is cheaper than fcntl(2), which requires + * us to do two syscalls, one to get and one to set, the latter of + * which mucks about a bit before it ends up calling ioctl(FIONBIO), + * at least on FreeBSD. + */ + +int +VTCP_blocking(int sock) +{ + int i, j; + + i = 0; + j = ioctl(sock, FIONBIO, &i); + VTCP_Assert(j); + return (j); +} + +int +VTCP_nonblocking(int sock) +{ + int i, j; + + i = 1; + j = ioctl(sock, FIONBIO, &i); + VTCP_Assert(j); + return (j); +} + +/*-------------------------------------------------------------------- + * On TCP a connect(2) can block for a looong time, and we don't want that. + * Unfortunately, the SocketWizards back in those days were happy to wait + * any amount of time for a connection, so the connect(2) syscall does not + * take an argument for patience. + * + * There is a little used work-around, and we employ it at our peril. + * + */ + +int +VTCP_connect(int s, const struct sockaddr_storage *name, socklen_t namelen, int msec) +{ + int i, k; + socklen_t l; + struct pollfd fds[1]; + + assert(s >= 0); + + /* Set the socket non-blocking */ + if (msec > 0) + (void)VTCP_nonblocking(s); + + /* Attempt the connect */ + i = connect(s, (const void *)name, namelen); + if (i == 0 || errno != EINPROGRESS) + return (i); + + assert(msec > 0); + /* Exercise our patience, polling for write */ + fds[0].fd = s; + fds[0].events = POLLWRNORM; + fds[0].revents = 0; + i = poll(fds, 1, msec); + + if (i == 0) { + /* Timeout, close and give up */ + errno = ETIMEDOUT; + return (-1); + } + + /* Find out if we got a connection */ + l = sizeof k; + AZ(getsockopt(s, SOL_SOCKET, SO_ERROR, &k, &l)); + + /* An error means no connection established */ + errno = k; + if (k) + return (-1); + + (void)VTCP_blocking(s); + return (0); +} + +/*-------------------------------------------------------------------- + * When closing a TCP connection, a couple of errno's are legit, we + * can't be held responsible for the other end wanting to talk to us. + */ + +void +VTCP_close(int *s) +{ + int i; + + i = close(*s); + + assert (VTCP_Check(i)); + *s = -1; +} + +void +VTCP_set_read_timeout(int s, double seconds) +{ + struct timeval timeout; + timeout.tv_sec = (int)floor(seconds); + timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec)); +#ifdef SO_RCVTIMEO_WORKS + AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); +#else + (void)s; +#endif +} + +/*-------------------------------------------------------------------- + * Set or reset SO_LINGER flag + */ + +int +VTCP_linger(int sock, int linger) +{ + struct linger lin; + int i; + + memset(&lin, 0, sizeof lin); + lin.l_onoff = linger; + i = setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof lin); + VTCP_Assert(i); + return (i); +} diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am index f88d748..492b10d 100644 --- a/lib/libvarnishapi/Makefile.am +++ b/lib/libvarnishapi/Makefile.am @@ -10,8 +10,8 @@ libvarnishapi_la_SOURCES = \ vsm_api.h \ vsl_api.h \ \ - ../libvarnish/assert.c \ - ../libvarnish/argv.c \ + ../libvarnish/vas.c \ + ../libvarnish/vav.c \ ../../include/vcs_version.h \ ../libvarnish/version.c \ ../libvarnish/cli_common.c \ From phk at varnish-cache.org Sun Oct 9 18:51:35 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:51:35 +0200 Subject: [master] c012d86 Cleanup VSUB_ and eliminate from libvarnish.h Message-ID: commit c012d86e43957404511107fb37247c4249d7c841 Author: Poul-Henning Kamp Date: Sun Oct 9 18:29:10 2011 +0000 Cleanup VSUB_ and eliminate from libvarnish.h diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index f8e81ca..bbf813a 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -42,6 +42,7 @@ #include "libvcl.h" #include "vcli.h" +#include "vsub.h" #include "vcl.h" #include "cli_priv.h" #include "mgt_cli.h" @@ -238,7 +239,7 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) vp.magic = VCC_PRIV_MAGIC; vp.sf = sf; vp.vcl = vcl; - if (SUB_run(sb, run_vcc, &vp, "VCC-compiler", -1)) { + if (VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1)) { (void)unlink(sf); return (NULL); } @@ -261,13 +262,13 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) cmdsb = mgt_make_cc_cmd(sf, of); /* Run the C-compiler in a sub-shell */ - i = SUB_run(sb, run_cc, VSB_data(cmdsb), "C-compiler", 10); + i = VSUB_run(sb, run_cc, VSB_data(cmdsb), "C-compiler", 10); (void)unlink(sf); VSB_delete(cmdsb); if (!i) - i = SUB_run(sb, run_dlopen, of, "dlopen", 10); + i = VSUB_run(sb, run_dlopen, of, "dlopen", 10); if (i) { (void)unlink(of); diff --git a/include/Makefile.am b/include/Makefile.am index 66c2ddd..2cbe5d1 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -54,6 +54,7 @@ nobase_noinst_HEADERS = \ vrt.h \ vrt_obj.h \ vsb.h \ + vsub.h \ vsha256.h \ vss.h \ vtcp.h diff --git a/include/libvarnish.h b/include/libvarnish.h index a40aa20..5bbe073 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -41,11 +41,6 @@ struct vsb; /* from libvarnish/num.c */ const char *str2bytes(const char *p, uintmax_t *r, uintmax_t rel); -/* from libvarnish/subproc.c */ -typedef void sub_func_f(void*); -int SUB_run(struct vsb *sb, sub_func_f *func, void *priv, const char *name, - int maxlines); - /* from libvarnish/time.c */ #define TIM_FORMAT_SIZE 30 void TIM_format(double t, char *p); diff --git a/include/vsub.h b/include/vsub.h new file mode 100644 index 0000000..6705b11 --- /dev/null +++ b/include/vsub.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* from libvarnish/subproc.c */ +typedef void vsub_func_f(void*); + +int VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name, + int maxlines); diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index b8651cc..0148460 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -8,7 +8,7 @@ libvarnish_la_SOURCES = \ vav.c \ vas.c \ binary_heap.c \ - subproc.c \ + vsub.c \ cli_auth.c \ cli_common.c \ cli_serve.c \ diff --git a/lib/libvarnish/subproc.c b/lib/libvarnish/subproc.c deleted file mode 100644 index 99f924e..0000000 --- a/lib/libvarnish/subproc.c +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Run stuff in a child process - */ - -#include "config.h" - -#include -#include -#include -#include - -#include - -#include "vsb.h" -#include "vlu.h" -#include "libvarnish.h" - -struct sub_priv { - const char *name; - struct vsb *sb; - int lines; - int maxlines; -}; - -static int -sub_vlu(void *priv, const char *str) -{ - struct sub_priv *sp; - - sp = priv; - if (!sp->lines++) - VSB_printf(sp->sb, "Message from %s:\n", sp->name); - if (sp->maxlines < 0 || sp->lines <= sp->maxlines) - VSB_printf(sp->sb, "%s\n", str); - return (0); -} - -int -SUB_run(struct vsb *sb, sub_func_f *func, void *priv, const char *name, - int maxlines) -{ - int rv, p[2], sfd, status; - pid_t pid; - struct vlu *vlu; - struct sub_priv sp; - - sp.sb = sb; - sp.name = name; - sp.lines = 0; - sp.maxlines = maxlines; - - if (pipe(p) < 0) { - VSB_printf(sb, "Starting %s: pipe() failed: %s", - name, strerror(errno)); - return (-1); - } - assert(p[0] > STDERR_FILENO); - assert(p[1] > STDERR_FILENO); - if ((pid = fork()) < 0) { - VSB_printf(sb, "Starting %s: fork() failed: %s", - name, strerror(errno)); - AZ(close(p[0])); - AZ(close(p[1])); - return (-1); - } - if (pid == 0) { - AZ(close(STDIN_FILENO)); - assert(open("/dev/null", O_RDONLY) == STDIN_FILENO); - assert(dup2(p[1], STDOUT_FILENO) == STDOUT_FILENO); - assert(dup2(p[1], STDERR_FILENO) == STDERR_FILENO); - /* Close all other fds */ - for (sfd = STDERR_FILENO + 1; sfd < 100; sfd++) - (void)close(sfd); - func(priv); - _exit(1); - } - AZ(close(p[1])); - vlu = VLU_New(&sp, sub_vlu, 0); - while (!VLU_Fd(p[0], vlu)) - continue; - AZ(close(p[0])); - VLU_Destroy(vlu); - if (sp.maxlines >= 0 && sp.lines > sp.maxlines) - VSB_printf(sb, "[%d lines truncated]\n", - sp.lines - sp.maxlines); - do { - rv = waitpid(pid, &status, 0); - if (rv < 0 && errno != EINTR) { - VSB_printf(sb, "Running %s: waitpid() failed: %s\n", - name, strerror(errno)); - return (-1); - } - } while (rv < 0); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - VSB_printf(sb, "Running %s failed", name); - if (WIFEXITED(status)) - VSB_printf(sb, ", exit %d", WEXITSTATUS(status)); - if (WIFSIGNALED(status)) - VSB_printf(sb, ", signal %d", WTERMSIG(status)); - if (WCOREDUMP(status)) - VSB_printf(sb, ", core dumped"); - VSB_printf(sb, "\n"); - return (-1); - } - return (0); -} diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c new file mode 100644 index 0000000..90ceacb --- /dev/null +++ b/lib/libvarnish/vsub.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Run stuff in a child process + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include "vas.h" +#include "vlu.h" +#include "vsb.h" +#include "vsub.h" + +struct vsub_priv { + const char *name; + struct vsb *sb; + int lines; + int maxlines; +}; + +static int +vsub_vlu(void *priv, const char *str) +{ + struct vsub_priv *sp; + + sp = priv; + if (!sp->lines++) + VSB_printf(sp->sb, "Message from %s:\n", sp->name); + if (sp->maxlines < 0 || sp->lines <= sp->maxlines) + VSB_printf(sp->sb, "%s\n", str); + return (0); +} + +int +VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name, + int maxlines) +{ + int rv, p[2], sfd, status; + pid_t pid; + struct vlu *vlu; + struct vsub_priv sp; + + sp.sb = sb; + sp.name = name; + sp.lines = 0; + sp.maxlines = maxlines; + + if (pipe(p) < 0) { + VSB_printf(sb, "Starting %s: pipe() failed: %s", + name, strerror(errno)); + return (-1); + } + assert(p[0] > STDERR_FILENO); + assert(p[1] > STDERR_FILENO); + if ((pid = fork()) < 0) { + VSB_printf(sb, "Starting %s: fork() failed: %s", + name, strerror(errno)); + AZ(close(p[0])); + AZ(close(p[1])); + return (-1); + } + if (pid == 0) { + AZ(close(STDIN_FILENO)); + assert(open("/dev/null", O_RDONLY) == STDIN_FILENO); + assert(dup2(p[1], STDOUT_FILENO) == STDOUT_FILENO); + assert(dup2(p[1], STDERR_FILENO) == STDERR_FILENO); + /* Close all other fds */ + for (sfd = STDERR_FILENO + 1; sfd < 100; sfd++) + (void)close(sfd); + func(priv); + _exit(1); + } + AZ(close(p[1])); + vlu = VLU_New(&sp, vsub_vlu, 0); + while (!VLU_Fd(p[0], vlu)) + continue; + AZ(close(p[0])); + VLU_Destroy(vlu); + if (sp.maxlines >= 0 && sp.lines > sp.maxlines) + VSB_printf(sb, "[%d lines truncated]\n", + sp.lines - sp.maxlines); + do { + rv = waitpid(pid, &status, 0); + if (rv < 0 && errno != EINTR) { + VSB_printf(sb, "Running %s: waitpid() failed: %s\n", + name, strerror(errno)); + return (-1); + } + } while (rv < 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + VSB_printf(sb, "Running %s failed", name); + if (WIFEXITED(status)) + VSB_printf(sb, ", exit %d", WEXITSTATUS(status)); + if (WIFSIGNALED(status)) + VSB_printf(sb, ", signal %d", WTERMSIG(status)); + if (WCOREDUMP(status)) + VSB_printf(sb, ", core dumped"); + VSB_printf(sb, "\n"); + return (-1); + } + return (0); +} From phk at varnish-cache.org Sun Oct 9 18:51:37 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 20:51:37 +0200 Subject: [master] b37c01d Since we're cleaning up, rename TIM_ to VTIM_ and take out of libvarnish.h Message-ID: commit b37c01dfe71edd703758f555fdc8c51554ab4993 Author: Poul-Henning Kamp Date: Sun Oct 9 18:51:03 2011 +0000 Since we're cleaning up, rename TIM_ to VTIM_ and take out of libvarnish.h diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index 87a9180..4feefb6 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -34,6 +34,7 @@ #include "vcli.h" #include "vtcp.h" +#include "vtim.h" #include "cli_priv.h" static pthread_t VCA_thread; @@ -167,7 +168,7 @@ vca_pace_check(void) p = vca_pace; Lck_Unlock(&pace_mtx); if (p > 0.0) - TIM_sleep(p); + VTIM_sleep(p); } static void @@ -273,7 +274,7 @@ VCA_SetupSess(struct worker *w) sp->fd = wa->acceptsock; sp->vsl_id = wa->acceptsock | VSL_CLIENTMARKER ; wa->acceptsock = -1; - sp->t_open = TIM_real(); + sp->t_open = VTIM_real(); sp->t_end = sp->t_open; sp->mylsock = wa->acceptlsock; CHECK_OBJ_NOTNULL(sp->mylsock, LISTEN_SOCK_MAGIC); @@ -313,14 +314,14 @@ vca_acct(void *arg) hack_ready = 1; need_test = 1; - t0 = TIM_real(); + t0 = VTIM_real(); while (1) { (void)sleep(1); #ifdef SO_SNDTIMEO_WORKS if (params->send_timeout != send_timeout) { need_test = 1; send_timeout = params->send_timeout; - tv_sndtimeo = TIM_timeval(send_timeout); + tv_sndtimeo = VTIM_timeval(send_timeout); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock < 0) continue; @@ -334,7 +335,7 @@ vca_acct(void *arg) if (params->sess_timeout != sess_timeout) { need_test = 1; sess_timeout = params->sess_timeout; - tv_rcvtimeo = TIM_timeval(sess_timeout); + tv_rcvtimeo = VTIM_timeval(sess_timeout); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock < 0) continue; @@ -344,7 +345,7 @@ vca_acct(void *arg) } } #endif - now = TIM_real(); + now = VTIM_real(); VSC_C_main->uptime = (uint64_t)(now - t0); } NEEDLESS_RETURN(NULL); diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index c90cda9..c9497bb 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -46,6 +46,7 @@ #include "cache.h" #include "vrt.h" #include "vtcp.h" +#include "vtim.h" #include "cache_backend.h" /* Default averaging rate, we want something pretty responsive */ @@ -131,28 +132,28 @@ vbp_poke(struct vbp_target *vt) bp = vt->backend; CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); - t_start = t_now = TIM_real(); + t_start = t_now = VTIM_real(); t_end = t_start + vt->probe.timeout; tmo = (int)round((t_end - t_now) * 1e3); s = -1; if (params->prefer_ipv6 && bp->ipv6 != NULL) { s = vbp_connect(PF_INET6, bp->ipv6, bp->ipv6len, tmo); - t_now = TIM_real(); + t_now = VTIM_real(); tmo = (int)round((t_end - t_now) * 1e3); if (s >= 0) vt->good_ipv6 |= 1; } if (tmo > 0 && s < 0 && bp->ipv4 != NULL) { s = vbp_connect(PF_INET, bp->ipv4, bp->ipv4len, tmo); - t_now = TIM_real(); + t_now = VTIM_real(); tmo = (int)round((t_end - t_now) * 1e3); if (s >= 0) vt->good_ipv4 |= 1; } if (tmo > 0 && s < 0 && bp->ipv6 != NULL) { s = vbp_connect(PF_INET6, bp->ipv6, bp->ipv6len, tmo); - t_now = TIM_real(); + t_now = VTIM_real(); tmo = (int)round((t_end - t_now) * 1e3); if (s >= 0) vt->good_ipv6 |= 1; @@ -208,7 +209,7 @@ vbp_poke(struct vbp_target *vt) return; /* So we have a good receive ... */ - t_now = TIM_real(); + t_now = VTIM_real(); vt->last = t_now - t_start; vt->good_recv |= 1; @@ -350,7 +351,7 @@ vbp_wrk_poll_backend(void *priv) vbp_has_poked(vt); if (!vt->stop) - TIM_sleep(vt->probe.interval); + VTIM_sleep(vt->probe.interval); } return (NULL); } diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index f346b4d..8396c7f 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -70,6 +70,7 @@ #include "vcli.h" #include "vend.h" +#include "vtim.h" #include "cli_priv.h" #include "hash_slinger.h" @@ -402,7 +403,7 @@ BAN_Insert(struct ban *b) b->spec = malloc(ln + 13L); /* XXX */ XXXAN(b->spec); - t0 = TIM_real(); + t0 = VTIM_real(); memcpy(b->spec, &t0, sizeof t0); b->spec[12] = (b->flags & BAN_F_REQ) ? 1 : 0; memcpy(b->spec + 13, VSB_data(b->vsb), ln); @@ -835,10 +836,10 @@ ban_lurker(struct sess *sp, void *priv) while (1) { if (params->ban_lurker_sleep == 0.0) { /* Lurker is disabled. */ - TIM_sleep(1.0); + VTIM_sleep(1.0); continue; } - TIM_sleep(params->ban_lurker_sleep); + VTIM_sleep(params->ban_lurker_sleep); ban_lurker_work(sp); WSL_Flush(sp->wrk, 0); WRK_SumStat(sp->wrk); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 1415170..6ab8a11 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -71,6 +71,7 @@ DOT acceptor -> start [style=bold,color=green] #include "vcl.h" #include "vtcp.h" +#include "vtim.h" #include "cli_priv.h" #include "hash_slinger.h" #include "stevedore.h" @@ -211,7 +212,7 @@ cnt_prepresp(struct sess *sp) } } - sp->t_resp = TIM_real(); + sp->t_resp = VTIM_real(); if (sp->obj->objcore != NULL) { if ((sp->t_resp - sp->obj->last_lru) > params->lru_timeout && EXP_Touch(sp->obj->objcore)) @@ -326,7 +327,7 @@ cnt_done(struct sess *sp) SES_Charge(sp); - sp->t_end = TIM_real(); + sp->t_end = VTIM_real(); sp->wrk->lastused = sp->t_end; if (sp->xid == 0) { sp->t_req = sp->t_end; @@ -466,7 +467,7 @@ cnt_error(struct sess *sp) http_PutProtocol(w, sp->vsl_id, h, "HTTP/1.1"); http_PutStatus(h, sp->err_code); - TIM_format(TIM_real(), date); + VTIM_format(VTIM_real(), date); http_PrintfHeader(w, sp->vsl_id, h, "Date: %s", date); http_PrintfHeader(w, sp->vsl_id, h, "Server: Varnish"); @@ -581,7 +582,7 @@ cnt_fetch(struct sess *sp) * What does RFC2616 think about TTL ? */ EXP_Clr(&sp->wrk->exp); - sp->wrk->exp.entered = TIM_real(); + sp->wrk->exp.entered = VTIM_real(); RFC2616_Ttl(sp); /* pass from vclrecv{} has negative TTL */ @@ -823,7 +824,7 @@ cnt_fetchbody(struct sess *sp) http_CopyHome(sp->wrk, sp->vsl_id, hp2); if (http_GetHdr(hp, H_Last_Modified, &b)) - sp->obj->last_modified = TIM_parse(b); + sp->obj->last_modified = VTIM_parse(b); else sp->obj->last_modified = floor(sp->wrk->exp.entered); @@ -1464,7 +1465,7 @@ cnt_start(struct sess *sp) /* Update stats of various sorts */ sp->wrk->stats.client_req++; - sp->t_req = TIM_real(); + sp->t_req = VTIM_real(); sp->wrk->lastused = sp->t_req; sp->wrk->acct_tmp.req++; diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index 35d0a1e..aed6807 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -57,6 +57,7 @@ #include "cache.h" #include "hash_slinger.h" #include "stevedore.h" +#include "vtim.h" static pthread_t exp_thread; static struct binheap *exp_heap; @@ -337,14 +338,14 @@ exp_timer(struct sess *sp, void *priv) struct object *o; (void)priv; - t = TIM_real(); + t = VTIM_real(); oc = NULL; while (1) { if (oc == NULL) { WSL_Flush(sp->wrk, 0); WRK_SumStat(sp->wrk); - TIM_sleep(params->expiry_sleep); - t = TIM_real(); + VTIM_sleep(params->expiry_sleep); + t = VTIM_real(); } Lck_Lock(&exp_mtx); @@ -360,7 +361,7 @@ exp_timer(struct sess *sp, void *priv) * got out of date, refresh it and check again. */ if (oc->timer_when > t) - t = TIM_real(); + t = VTIM_real(); if (oc->timer_when > t) { Lck_Unlock(&exp_mtx); oc = NULL; diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index 74343ba..418ded1 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -36,6 +36,7 @@ #include "cache.h" #include "vtcp.h" +#include "vtim.h" static int rdf(int fd0, int fd1) @@ -90,7 +91,7 @@ PipeSession(struct sess *sp) return; } - sp->t_resp = TIM_real(); + sp->t_resp = VTIM_real(); memset(fds, 0, sizeof fds); diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index e146043..4421969 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -51,6 +51,7 @@ #include "cache_waiter.h" #include "hash_slinger.h" #include "vtcp.h" +#include "vtim.h" /*-------------------------------------------------------------------- * MAC OS/X is incredibly moronic when it comes to time and such... @@ -224,7 +225,7 @@ Pool_Work_Thread(void *priv, struct worker *w) } else if (VTAILQ_EMPTY(&pp->socks)) { /* Nothing to do: To sleep, perchance to dream ... */ if (isnan(w->lastused)) - w->lastused = TIM_real(); + w->lastused = VTIM_real(); VTAILQ_INSERT_HEAD(&pp->idle, w, list); if (!stats_clean) WRK_SumStat(w); @@ -343,7 +344,7 @@ Pool_Schedule(struct pool *pp, struct sess *sp) * XXX: a notice might be polite, but would potentially * XXX: sleep whichever thread got us here */ - sp->t_end = TIM_real(); + sp->t_end = VTIM_real(); if (sp->vcl != NULL) { /* * A session parked on a busy object can come here @@ -401,10 +402,10 @@ pool_breed(struct pool *qp, const pthread_attr_t *tp_attr) Lck_Lock(&pool_mtx); VSC_C_main->threads_limited++; Lck_Unlock(&pool_mtx); - TIM_sleep(params->wthread_fail_delay * 1e-3); + VTIM_sleep(params->wthread_fail_delay * 1e-3); } else { AZ(pthread_detach(tp)); - TIM_sleep(params->wthread_add_delay * 1e-3); + VTIM_sleep(params->wthread_add_delay * 1e-3); qp->nthr++; Lck_Lock(&pool_mtx); VSC_C_main->threads++; @@ -476,7 +477,7 @@ pool_herder(void *priv) if (pp->nthr <= params->wthread_min) continue; - t_idle = TIM_real() - params->wthread_timeout; + t_idle = VTIM_real() - params->wthread_timeout; Lck_Lock(&pp->mtx); VSC_C_main->sess_queued += pp->nqueued; diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 4d7c88b..b4459da 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -38,6 +38,7 @@ #include "cache.h" #include "stevedore.h" #include "vct.h" +#include "vtim.h" /*--------------------------------------------------------------------*/ @@ -133,7 +134,7 @@ RES_BuildHttp(const struct sess *sp) http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->resp, "Transfer-Encoding: chunked"); - TIM_format(TIM_real(), time_str); + VTIM_format(VTIM_real(), time_str); http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->resp, "Date: %s", time_str); if (sp->xid != sp->obj->xid) diff --git a/bin/varnishd/cache_shmlog.c b/bin/varnishd/cache_shmlog.c index 8c06897..75f662d 100644 --- a/bin/varnishd/cache_shmlog.c +++ b/bin/varnishd/cache_shmlog.c @@ -34,6 +34,7 @@ #include "cache.h" #include "vmb.h" #include "vsm.h" +#include "vtim.h" /* These cannot be struct lock, which depends on vsm/vsl working */ static pthread_mutex_t vsl_mtx; @@ -285,7 +286,7 @@ VSL_Init(void) vsl_ptr = vsl_start + 1; vsl_wrap(); - VSM_head->starttime = (intmax_t)TIM_real(); + VSM_head->starttime = (intmax_t)VTIM_real(); memset(VSM_head->panicstr, '\0', sizeof *VSM_head->panicstr); memset(VSC_C_main, 0, sizeof *VSC_C_main); VSM_head->child_pid = getpid(); diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index a53799e..5c633e2 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -43,6 +43,7 @@ #include "vrt_obj.h" #include "vav.h" #include "vcl.h" +#include "vtim.h" #include "hash_slinger.h" #include "cache_backend.h" @@ -276,7 +277,7 @@ VRT_r_now(const struct sess *sp) { (void)sp; - return (TIM_real()); + return (VTIM_real()); } /*--------------------------------------------------------------------*/ @@ -339,8 +340,8 @@ VRT_time_string(const struct sess *sp, double t) { char *p; - AN(p = WS_Alloc(sp->http->ws, TIM_FORMAT_SIZE)); - TIM_format(t, p); + AN(p = WS_Alloc(sp->http->ws, VTIM_FORMAT_SIZE)); + VTIM_format(t, p); return p; } diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index 1343ae4..ff523df 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -37,6 +37,7 @@ #include "vrt.h" #include "vtcp.h" +#include "vtim.h" #include "vrt_obj.h" #include "cache_backend.h" #include "hash_slinger.h" @@ -535,7 +536,7 @@ VRT_r_obj_lastuse(const struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */ - return (TIM_real() - sp->obj->last_use); + return (VTIM_real() - sp->obj->last_use); } unsigned diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c index d4168db..c66d15a 100644 --- a/bin/varnishd/cache_waiter_epoll.c +++ b/bin/varnishd/cache_waiter_epoll.c @@ -42,6 +42,7 @@ #include "cache.h" #include "cache_waiter.h" +#include "vtim.h" #ifndef EPOLLRDHUP # define EPOLLRDHUP 0 @@ -186,7 +187,7 @@ vwe_thread(void *priv) continue; /* check for timeouts */ - deadline = TIM_real() - params->sess_timeout; + deadline = VTIM_real() - params->sess_timeout; for (;;) { sp = VTAILQ_FIRST(&vwe->sesshead); if (sp == NULL) @@ -215,7 +216,7 @@ vwe_sess_timeout_ticker(void *priv) while (1) { /* ticking */ assert(write(vwe->timer_pipes[1], &ticker, 1)); - TIM_sleep(100 * 1e-3); + VTIM_sleep(100 * 1e-3); } return NULL; } diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c index f023c3f..e7cb299 100644 --- a/bin/varnishd/cache_waiter_kqueue.c +++ b/bin/varnishd/cache_waiter_kqueue.c @@ -43,6 +43,7 @@ #include "cache.h" #include "cache_waiter.h" +#include "vtim.h" #define NKEV 100 @@ -183,7 +184,7 @@ vwk_thread(void *priv) * would not know we meant "the old fd of this number". */ vwk_kq_flush(vwk); - deadline = TIM_real() - params->sess_timeout; + deadline = VTIM_real() - params->sess_timeout; for (;;) { sp = VTAILQ_FIRST(&vwk->sesshead); if (sp == NULL) diff --git a/bin/varnishd/cache_waiter_poll.c b/bin/varnishd/cache_waiter_poll.c index df0439b..f3f3289 100644 --- a/bin/varnishd/cache_waiter_poll.c +++ b/bin/varnishd/cache_waiter_poll.c @@ -36,6 +36,7 @@ #include "cache.h" #include "cache_waiter.h" +#include "vtim.h" #define NEEV 128 @@ -139,7 +140,7 @@ vwp_main(void *priv) assert(vwp->pollfd[vwp->pipes[1]].fd == -1); v = poll(vwp->pollfd, vwp->hpoll + 1, 100); assert(v >= 0); - deadline = TIM_real() - params->sess_timeout; + deadline = VTIM_real() - params->sess_timeout; v2 = v; VTAILQ_FOREACH_SAFE(sp, &vwp->sesshead, list, sp2) { if (v != 0 && v2 == 0) diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c index 04c6e92..ca7e229 100644 --- a/bin/varnishd/cache_waiter_ports.c +++ b/bin/varnishd/cache_waiter_ports.c @@ -43,6 +43,7 @@ #include "cache.h" #include "cache_waiter.h" +#include "vtim.h" #define MAX_EVENTS 256 @@ -195,7 +196,7 @@ vws_thread(void *priv) vws_port_ev(vws, ev + ei); /* check for timeouts */ - now = TIM_real(); + now = VTIM_real(); deadline = now - params->sess_timeout; /* @@ -234,7 +235,7 @@ vws_thread(void *priv) } else if (tmo > max_t) { timeout = &max_ts; } else { - ts = TIM_timespec(tmo); + ts = VTIM_timespec(tmo); timeout = &ts; } } else { diff --git a/bin/varnishd/hash_critbit.c b/bin/varnishd/hash_critbit.c index 7428097..e5b0746 100644 --- a/bin/varnishd/hash_critbit.c +++ b/bin/varnishd/hash_critbit.c @@ -38,6 +38,7 @@ #include "hash_slinger.h" #include "cli_priv.h" #include "vmb.h" +#include "vtim.h" static struct lock hcb_mtx; @@ -367,7 +368,7 @@ hcb_cleaner(void *priv) VTAILQ_CONCAT(&dead_h, &cool_h, hoh_list); Lck_Unlock(&hcb_mtx); WRK_SumStat(&ww); - TIM_sleep(params->critbit_cooloff); + VTIM_sleep(params->critbit_cooloff); } NEEDLESS_RETURN(NULL); } diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 6c1cf71..e676f48 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -53,6 +53,7 @@ #include "vss.h" #include "vbm.h" #include "vtcp.h" +#include "vtim.h" pid_t child_pid = -1; @@ -439,7 +440,7 @@ mgt_save_panic(void) VSB_delete(child_panic); child_panic = VSB_new_auto(); XXXAN(child_panic); - TIM_format(TIM_real(), time_str); + VTIM_format(VTIM_real(), time_str); VSB_printf(child_panic, "Last panic at: %s\n", time_str); VSB_cat(child_panic, VSM_head->panicstr); AZ(VSB_finish(child_panic)); diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c index 36936b6..6de52e2 100644 --- a/bin/varnishd/rfc2616.c +++ b/bin/varnishd/rfc2616.c @@ -33,6 +33,7 @@ #include #include "cache.h" +#include "vtim.h" /*-------------------------------------------------------------------- * TTL and Age calculation in Varnish @@ -88,10 +89,10 @@ RFC2616_Ttl(const struct sess *sp) sp->wrk->exp.age = age; } if (http_GetHdr(hp, H_Expires, &p)) - h_expires = TIM_parse(p); + h_expires = VTIM_parse(p); if (http_GetHdr(hp, H_Date, &p)) - h_date = TIM_parse(p); + h_date = VTIM_parse(p); switch (sp->err_code) { default: @@ -315,7 +316,7 @@ RFC2616_Do_Cond(const struct sess *sp) if (http_GetHdr(sp->http, H_If_Modified_Since, &p) ) { if (!sp->obj->last_modified) return (0); - ims = TIM_parse(p); + ims = VTIM_parse(p); if (ims > sp->t_req) /* [RFC2616 14.25] */ return (0); if (sp->obj->last_modified > ims) diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c index ba84b79..2defc0d 100644 --- a/bin/varnishd/storage_persistent_silo.c +++ b/bin/varnishd/storage_persistent_silo.c @@ -41,6 +41,7 @@ #include "stevedore.h" #include "hash_slinger.h" #include "vsha256.h" +#include "vtim.h" #include "persistent.h" #include "storage_persistent.h" @@ -122,7 +123,7 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_object *so; struct objcore *oc; uint32_t no; - double t_now = TIM_real(); + double t_now = VTIM_real(); struct smp_signctx ctx[1]; ASSERT_SILO_THREAD(sc); diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 2d7db59..360cdad 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -55,6 +55,7 @@ #include "vav.h" #include "vin.h" +#include "vtim.h" #include "heritage.h" #include "mgt.h" #include "hash_slinger.h" @@ -376,9 +377,9 @@ main(int argc, char * const *argv) */ AZ(setenv("TZ", "UTC", 1)); tzset(); - assert(TIM_parse("Sun, 06 Nov 1994 08:49:37 GMT") == 784111777); - assert(TIM_parse("Sunday, 06-Nov-94 08:49:37 GMT") == 784111777); - assert(TIM_parse("Sun Nov 6 08:49:37 1994") == 784111777); + assert(VTIM_parse("Sun, 06 Nov 1994 08:49:37 GMT") == 784111777); + assert(VTIM_parse("Sunday, 06-Nov-94 08:49:37 GMT") == 784111777); + assert(VTIM_parse("Sun Nov 6 08:49:37 1994") == 784111777); /* * Check that our SHA256 works diff --git a/bin/varnishd/vsm.c b/bin/varnishd/vsm.c index 28f98e5..dc265ba 100644 --- a/bin/varnishd/vsm.c +++ b/bin/varnishd/vsm.c @@ -54,6 +54,7 @@ #include "common.h" #include "vsm.h" #include "vmb.h" +#include "vtim.h" /* These two come from beyond (mgt_shmem.c actually) */ struct VSM_head *VSM_head; @@ -87,7 +88,7 @@ vsm_release(unsigned seq) static void vsm_cleanup(void) { - unsigned now = (unsigned)TIM_mono(); + unsigned now = (unsigned)VTIM_mono(); struct VSM_chunk *sha, *sha2; unsigned seq; @@ -203,7 +204,7 @@ VSM__Free(const void *ptr) AN(sha); seq = vsm_mark(); bprintf(sha->class, "%s", VSM_CLASS_COOL); - sha->state = (unsigned)TIM_mono(); + sha->state = (unsigned)VTIM_mono(); vsm_release(seq); } diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index e31eaca..83bbb22 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -40,6 +40,7 @@ #include "vtc.h" #include "vav.h" +#include "vtim.h" #include "libvarnish.h" @@ -129,10 +130,10 @@ macro_get(const char *b, const char *e) l = e - b; if (l == 4 && !memcmp(b, "date", l)) { - double t = TIM_real(); + double t = VTIM_real(); retval = malloc(64); AN(retval); - TIM_format(t, retval); + VTIM_format(t, retval); return (retval); } @@ -415,7 +416,7 @@ cmd_delay(CMD_ARGS) AZ(av[2]); f = strtod(av[1], NULL); vtc_log(vl, 3, "delaying %g second(s)", f); - TIM_sleep(f); + VTIM_sleep(f); } /********************************************************************** diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 51c6646..c06f319 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -36,6 +36,7 @@ #include "vtc.h" #include "libvarnish.h" +#include "vtim.h" static pthread_mutex_t vtclog_mtx; static char *vtclog_buf; @@ -58,7 +59,7 @@ void vtc_loginit(char *buf, unsigned buflen) { - t0 = TIM_mono(); + t0 = VTIM_mono(); vtclog_buf = buf; vtclog_left = buflen; AZ(pthread_mutex_init(&vtclog_mtx, NULL)); @@ -126,7 +127,7 @@ vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...) double tx; CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); - tx = TIM_mono() - t0; + tx = VTIM_mono() - t0; AZ(pthread_mutex_lock(&vl->mtx)); assert(lvl < NLEAD); VSB_clear(vl->vsb); @@ -162,7 +163,7 @@ vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, const char *str, int double tx; CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); - tx = TIM_mono() - t0; + tx = VTIM_mono() - t0; assert(lvl < NLEAD); AZ(pthread_mutex_lock(&vl->mtx)); VSB_clear(vl->vsb); @@ -225,7 +226,7 @@ vtc_hexdump(struct vtclog *vl, unsigned lvl, const char *pfx, const unsigned cha double tx; CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); - tx = TIM_mono() - t0; + tx = VTIM_mono() - t0; assert(len >= 0); assert(lvl < NLEAD); AZ(pthread_mutex_lock(&vl->mtx)); diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index d201946..040afdc 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -42,6 +42,7 @@ #include "libvarnish.h" #include "vev.h" +#include "vtim.h" #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" @@ -193,7 +194,7 @@ tst_cb(const struct vev *ve, int what) njob--; px = wait4(jp->child, &stx, 0, NULL); assert(px == jp->child); - t = TIM_mono() - jp->t0; + t = VTIM_mono() - jp->t0; AZ(close(ve->fd)); if (stx && vtc_verbosity) @@ -283,7 +284,7 @@ start_test(void) AZ(pipe(p)); assert(p[0] > STDERR_FILENO); assert(p[1] > STDERR_FILENO); - jp->t0 = TIM_mono(); + jp->t0 = VTIM_mono(); jp->child = fork(); assert(jp->child >= 0); if (jp->child == 0) { diff --git a/include/Makefile.am b/include/Makefile.am index 2cbe5d1..d62cab3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -57,7 +57,8 @@ nobase_noinst_HEADERS = \ vsub.h \ vsha256.h \ vss.h \ - vtcp.h + vtcp.h \ + vtim.h tbl/vrt_stv_var.h tbl/vcl_returns.h vcl.h vrt_obj.h: $(top_srcdir)/lib/libvcl/generate.py $(top_srcdir)/include/vrt.h mkdir -p tbl diff --git a/include/libvarnish.h b/include/libvarnish.h index 5bbe073..c0851c8 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -41,16 +41,6 @@ struct vsb; /* from libvarnish/num.c */ const char *str2bytes(const char *p, uintmax_t *r, uintmax_t rel); -/* from libvarnish/time.c */ -#define TIM_FORMAT_SIZE 30 -void TIM_format(double t, char *p); -double TIM_parse(const char *p); -double TIM_mono(void); -double TIM_real(void); -void TIM_sleep(double t); -struct timespec TIM_timespec(double t); -struct timeval TIM_timeval(double t); - /* from libvarnish/version.c */ void VCS_Message(const char *); diff --git a/include/vtim.h b/include/vtim.h new file mode 100644 index 0000000..8db4fbe --- /dev/null +++ b/include/vtim.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* from libvarnish/vtim.c */ +#define VTIM_FORMAT_SIZE 30 +void VTIM_format(double t, char *p); +double VTIM_parse(const char *p); +double VTIM_mono(void); +double VTIM_real(void); +void VTIM_sleep(double t); +struct timespec VTIM_timespec(double t); +struct timeval VTIM_timeval(double t); diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index 0148460..3c045e6 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -14,7 +14,7 @@ libvarnish_la_SOURCES = \ cli_serve.c \ flopen.c \ num.c \ - time.c \ + vtim.c \ vtcp.c \ vct.c \ version.c \ diff --git a/lib/libvarnish/time.c b/lib/libvarnish/time.c deleted file mode 100644 index 31fc284..0000000 --- a/lib/libvarnish/time.c +++ /dev/null @@ -1,293 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Semi-trivial functions to handle HTTP header timestamps according to - * RFC 2616 section 3.3. - * - * In the highly unlikely event of performance trouble, handbuilt versions - * would likely be faster than relying on the OS time functions. - * - * We must parse three different formats: - * 000000000011111111112222222222 - * 012345678901234567890123456789 - * ------------------------------ - * "Sun, 06 Nov 1994 08:49:37 GMT" RFC822 & RFC1123 - * "Sunday, 06-Nov-94 08:49:37 GMT" RFC850 - * "Sun Nov 6 08:49:37 1994" ANSI-C asctime() - * - * And always output the RFC1123 format. - * - */ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include - -#include "libvarnish.h" - -/* - * Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not - * implemented in assembly, but falls into a syscall, while gethrtime() doesn't, - * so we save a syscall by using gethrtime() if it is defined. - */ - -double -TIM_mono(void) -{ -#ifdef HAVE_GETHRTIME - return (gethrtime() * 1e-9); -#elif HAVE_CLOCK_GETTIME - struct timespec ts; - - assert(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); - return (ts.tv_sec + 1e-9 * ts.tv_nsec); -#else - struct timeval tv; - - assert(gettimeofday(&tv, NULL) == 0); - return (tv.tv_sec + 1e-6 * tv.tv_usec); -#endif -} - -double -TIM_real(void) -{ -#ifdef HAVE_CLOCK_GETTIME - struct timespec ts; - - assert(clock_gettime(CLOCK_REALTIME, &ts) == 0); - return (ts.tv_sec + 1e-9 * ts.tv_nsec); -#else - struct timeval tv; - - assert(gettimeofday(&tv, NULL) == 0); - return (tv.tv_sec + 1e-6 * tv.tv_usec); -#endif -} - -void -TIM_format(double t, char *p) -{ - struct tm tm; - time_t tt; - - tt = (time_t) t; - (void)gmtime_r(&tt, &tm); - AN(strftime(p, TIM_FORMAT_SIZE, "%a, %d %b %Y %T GMT", &tm)); -} - -/* XXX: add statistics ? */ -static const char *fmts[] = { - "%a, %d %b %Y %T GMT", /* RFC 822 & RFC 1123 */ - "%A, %d-%b-%y %T GMT", /* RFC 850 */ - "%a %b %d %T %Y", /* ANSI-C asctime() */ - "%F %T", /* ISO 8601 */ - NULL -}; - -double -TIM_parse(const char *p) -{ - double t; - struct tm tm; - const char **r; - - for (r = fmts; *r != NULL; r++) { - memset(&tm, 0, sizeof tm); - if (strptime(p, *r, &tm) != NULL) { - /* - * Make sure this is initialized on the off-chance - * that some raving loonie would apply DST to UTC. - */ - tm.tm_isdst = -1; -#if defined(HAVE_TIMEGM) - t = timegm(&tm); -#else - /* - * Ahh, another POSIX_STUPIDITY, how unexpected. - * Instead of, as would have been logical, to have - * tm_timezone element, mktime() is standardized as - * always working in localtime. This brilliant idea - * came from the same people who said "leap-seconds ? - * Naah, screw it!". - * - * On broken systems without a working timegm(), - * it is the responsibility of the calling program - * to set the timezone to UTC. We check that. - */ - t = mktime(&tm); - assert(!strcmp(tzname[0], "UTC")); -#endif - return (t); - } - } - return (0); -} - -void -TIM_sleep(double t) -{ -#ifdef HAVE_NANOSLEEP - struct timespec ts; - - ts = TIM_timespec(t); - - (void)nanosleep(&ts, NULL); -#else - if (t >= 1.) { - (void)sleep(floor(t)); - t -= floor(t); - } - /* XXX: usleep() is not mandated to be thread safe */ - t *= 1e6; - if (t > 0) - (void)usleep(floor(t)); -#endif -} - -struct timeval -TIM_timeval(double t) -{ - struct timeval tv; - - tv.tv_sec = (time_t)trunc(t); - tv.tv_usec = (int)(1e6 * (t - tv.tv_sec)); - return (tv); -} - -struct timespec -TIM_timespec(double t) -{ - struct timespec tv; - - tv.tv_sec = (time_t)trunc(t); - tv.tv_nsec = (int)(1e9 * (t - tv.tv_sec)); - return (tv); -} - - -#ifdef TEST_DRIVER - -#include - -/* - * Compile with: - * cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c - * (Solaris) - * cc -o foo -DTEST_DRIVER -I../.. -I../../include -lm time.c assert.c - * Test with: - * env TZ=UTC ./foo - * env TZ=CET ./foo - */ - -static void -tst(const char *s, time_t good) -{ - time_t t; - char buf[BUFSIZ]; - - t = TIM_parse(s); - TIM_format(t, buf); - printf("%-30s -> %12jd -> %s\n", s, (intmax_t)t, buf); - if (t != good) { - printf("Parse error! Got: %jd should have %jd diff %jd\n", - (intmax_t)t, (intmax_t)good, (intmax_t)(t - good)); - exit (2); - } -} - -static int -tst_delta_check(const char *name, double begin, double end, double ref) -{ - const double tol_max = 1.1; - const double tol_min = 1; - - printf("%s delta for %fs sleep: %f\n", name, ref, (end - begin)); - - if ((end - begin) > tol_max * ref) { - printf("%s delta above tolerance: ((%f - %f) = %f) > %f\n", - name, end, begin, (end - begin), tol_max); - return (1); - } else if ((end - begin) < tol_min * ref) { - printf("%s delta below tolerance: ((%f - %f) = %f) < %f\n", - name, end, begin, (end - begin), tol_min); - return (1); - } - return (0); -} - -static void -tst_delta() -{ - double m_begin, m_end; - double r_begin, r_end; - const double ref = 1; - int err = 0; - - r_begin = TIM_real(); - m_begin = TIM_mono(); - TIM_sleep(ref); - r_end = TIM_real(); - m_end = TIM_mono(); - - err += tst_delta_check("TIM_mono", m_begin, m_end, ref); - err += tst_delta_check("TIM_real", r_begin, r_end, ref); - - if (err) { - printf("%d time delta test errrors\n", err); - exit (2); - } -} - -int -main(int argc, char **argv) -{ - time_t t; - char buf[BUFSIZ]; - - time(&t); - memset(buf, 0x55, sizeof buf); - TIM_format(t, buf); - printf("scan = %d <%s>\n", TIM_parse(buf), buf); - - /* Examples from RFC2616 section 3.3.1 */ - tst("Sun, 06 Nov 1994 08:49:37 GMT", 784111777); - tst("Sunday, 06-Nov-94 08:49:37 GMT", 784111777); - tst("Sun Nov 6 08:49:37 1994", 784111777); - - tst_delta(); - - return (0); -} -#endif diff --git a/lib/libvarnish/vev.c b/lib/libvarnish/vev.c index 8c64562..c55ebfc 100644 --- a/lib/libvarnish/vev.c +++ b/lib/libvarnish/vev.c @@ -39,6 +39,7 @@ #include #include "libvarnish.h" +#include "vtim.h" #include "vev.h" #include "miniobj.h" #include "binary_heap.h" @@ -278,7 +279,7 @@ vev_add(struct vev_base *evb, struct vev *e) e->magic = VEV_MAGIC; /* before binheap_insert() */ if (e->timeout != 0.0) { - e->__when += TIM_mono() + e->timeout; + e->__when += VTIM_mono() + e->timeout; binheap_insert(evb->binheap, e); assert(e->__binheap_idx > 0); DBG(evb, "... bidx = %d\n", e->__binheap_idx); @@ -455,7 +456,7 @@ vev_schedule_one(struct vev_base *evb) if (e != NULL) { CHECK_OBJ_NOTNULL(e, VEV_MAGIC); assert(e->__binheap_idx == 1); - t = TIM_mono(); + t = VTIM_mono(); if (e->__when <= t) return (vev_sched_timeout(evb, e, t)); tmo = (int)((e->__when - t) * 1e3); @@ -478,7 +479,7 @@ vev_schedule_one(struct vev_base *evb) return (vev_sched_signal(evb)); if (i == 0) { assert(e != NULL); - t = TIM_mono(); + t = VTIM_mono(); if (e->__when <= t) return (vev_sched_timeout(evb, e, t)); } diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c new file mode 100644 index 0000000..edfb8a5 --- /dev/null +++ b/lib/libvarnish/vtim.c @@ -0,0 +1,295 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Semi-trivial functions to handle HTTP header timestamps according to + * RFC 2616 section 3.3. + * + * In the highly unlikely event of performance trouble, handbuilt versions + * would likely be faster than relying on the OS time functions. + * + * We must parse three different formats: + * 000000000011111111112222222222 + * 012345678901234567890123456789 + * ------------------------------ + * "Sun, 06 Nov 1994 08:49:37 GMT" RFC822 & RFC1123 + * "Sunday, 06-Nov-94 08:49:37 GMT" RFC850 + * "Sun Nov 6 08:49:37 1994" ANSI-C asctime() + * + * And always output the RFC1123 format. + * + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include + +#include "vas.h" +#include "vtim.h" +//#include "libvarnish.h" + +/* + * Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not + * implemented in assembly, but falls into a syscall, while gethrtime() doesn't, + * so we save a syscall by using gethrtime() if it is defined. + */ + +double +VTIM_mono(void) +{ +#ifdef HAVE_GETHRTIME + return (gethrtime() * 1e-9); +#elif HAVE_CLOCK_GETTIME + struct timespec ts; + + assert(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + return (ts.tv_sec + 1e-9 * ts.tv_nsec); +#else + struct timeval tv; + + assert(gettimeofday(&tv, NULL) == 0); + return (tv.tv_sec + 1e-6 * tv.tv_usec); +#endif +} + +double +VTIM_real(void) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; + + assert(clock_gettime(CLOCK_REALTIME, &ts) == 0); + return (ts.tv_sec + 1e-9 * ts.tv_nsec); +#else + struct timeval tv; + + assert(gettimeofday(&tv, NULL) == 0); + return (tv.tv_sec + 1e-6 * tv.tv_usec); +#endif +} + +void +VTIM_format(double t, char *p) +{ + struct tm tm; + time_t tt; + + tt = (time_t) t; + (void)gmtime_r(&tt, &tm); + AN(strftime(p, VTIM_FORMAT_SIZE, "%a, %d %b %Y %T GMT", &tm)); +} + +/* XXX: add statistics ? */ +static const char *fmts[] = { + "%a, %d %b %Y %T GMT", /* RFC 822 & RFC 1123 */ + "%A, %d-%b-%y %T GMT", /* RFC 850 */ + "%a %b %d %T %Y", /* ANSI-C asctime() */ + "%F %T", /* ISO 8601 */ + NULL +}; + +double +VTIM_parse(const char *p) +{ + double t; + struct tm tm; + const char **r; + + for (r = fmts; *r != NULL; r++) { + memset(&tm, 0, sizeof tm); + if (strptime(p, *r, &tm) != NULL) { + /* + * Make sure this is initialized on the off-chance + * that some raving loonie would apply DST to UTC. + */ + tm.tm_isdst = -1; +#if defined(HAVE_TIMEGM) + t = timegm(&tm); +#else + /* + * Ahh, another POSIX_STUPIDITY, how unexpected. + * Instead of, as would have been logical, to have + * tm_timezone element, mktime() is standardized as + * always working in localtime. This brilliant idea + * came from the same people who said "leap-seconds ? + * Naah, screw it!". + * + * On broken systems without a working timegm(), + * it is the responsibility of the calling program + * to set the timezone to UTC. We check that. + */ + t = mktime(&tm); + assert(!strcmp(tzname[0], "UTC")); +#endif + return (t); + } + } + return (0); +} + +void +VTIM_sleep(double t) +{ +#ifdef HAVE_NANOSLEEP + struct timespec ts; + + ts = VTIM_timespec(t); + + (void)nanosleep(&ts, NULL); +#else + if (t >= 1.) { + (void)sleep(floor(t)); + t -= floor(t); + } + /* XXX: usleep() is not mandated to be thread safe */ + t *= 1e6; + if (t > 0) + (void)usleep(floor(t)); +#endif +} + +struct timeval +VTIM_timeval(double t) +{ + struct timeval tv; + + tv.tv_sec = (time_t)trunc(t); + tv.tv_usec = (int)(1e6 * (t - tv.tv_sec)); + return (tv); +} + +struct timespec +VTIM_timespec(double t) +{ + struct timespec tv; + + tv.tv_sec = (time_t)trunc(t); + tv.tv_nsec = (int)(1e9 * (t - tv.tv_sec)); + return (tv); +} + + +#ifdef TEST_DRIVER + +#include + +/* + * Compile with: + * cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c + * (Solaris) + * cc -o foo -DTEST_DRIVER -I../.. -I../../include -lm time.c assert.c + * Test with: + * env TZ=UTC ./foo + * env TZ=CET ./foo + */ + +static void +tst(const char *s, time_t good) +{ + time_t t; + char buf[BUFSIZ]; + + t = VTIM_parse(s); + VTIM_format(t, buf); + printf("%-30s -> %12jd -> %s\n", s, (intmax_t)t, buf); + if (t != good) { + printf("Parse error! Got: %jd should have %jd diff %jd\n", + (intmax_t)t, (intmax_t)good, (intmax_t)(t - good)); + exit (2); + } +} + +static int +tst_delta_check(const char *name, double begin, double end, double ref) +{ + const double tol_max = 1.1; + const double tol_min = 1; + + printf("%s delta for %fs sleep: %f\n", name, ref, (end - begin)); + + if ((end - begin) > tol_max * ref) { + printf("%s delta above tolerance: ((%f - %f) = %f) > %f\n", + name, end, begin, (end - begin), tol_max); + return (1); + } else if ((end - begin) < tol_min * ref) { + printf("%s delta below tolerance: ((%f - %f) = %f) < %f\n", + name, end, begin, (end - begin), tol_min); + return (1); + } + return (0); +} + +static void +tst_delta() +{ + double m_begin, m_end; + double r_begin, r_end; + const double ref = 1; + int err = 0; + + r_begin = VTIM_real(); + m_begin = VTIM_mono(); + VTIM_sleep(ref); + r_end = VTIM_real(); + m_end = VTIM_mono(); + + err += tst_delta_check("VTIM_mono", m_begin, m_end, ref); + err += tst_delta_check("VTIM_real", r_begin, r_end, ref); + + if (err) { + printf("%d time delta test errrors\n", err); + exit (2); + } +} + +int +main(int argc, char **argv) +{ + time_t t; + char buf[BUFSIZ]; + + time(&t); + memset(buf, 0x55, sizeof buf); + VTIM_format(t, buf); + printf("scan = %d <%s>\n", VTIM_parse(buf), buf); + + /* Examples from RFC2616 section 3.3.1 */ + tst("Sun, 06 Nov 1994 08:49:37 GMT", 784111777); + tst("Sunday, 06-Nov-94 08:49:37 GMT", 784111777); + tst("Sun Nov 6 08:49:37 1994", 784111777); + + tst_delta(); + + return (0); +} +#endif From phk at varnish-cache.org Sun Oct 9 19:30:23 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 21:30:23 +0200 Subject: [master] 368197a And now it is VNUM's turn... Message-ID: commit 368197ad6241b398fd6a50d25385d4bf9ba2cc81 Author: Poul-Henning Kamp Date: Sun Oct 9 19:06:34 2011 +0000 And now it is VNUM's turn... diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index 38dc59a..e42487a 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -103,6 +103,7 @@ #include "vmb.h" #include "vsm.h" #include "vav.h" +#include "vnum.h" #include "flopen.h" #ifndef MAP_HASSEMAPHORE @@ -244,7 +245,7 @@ mgt_SHM_Init(const char *l_arg) /* Size of SHMLOG */ if (*ap != NULL && **ap != '\0') { - q = str2bytes(*ap, &s1, 0); + q = VNUM_2bytes(*ap, &s1, 0); if (q != NULL) ARGV_ERR("\t-l[1] ...: %s\n", q); } else { @@ -255,7 +256,7 @@ mgt_SHM_Init(const char *l_arg) /* Size of space for other stuff */ if (*ap != NULL && **ap != '\0') { - q = str2bytes(*ap, &s2, 0); + q = VNUM_2bytes(*ap, &s2, 0); if (q != NULL) ARGV_ERR("\t-l[2] ...: %s\n", q); } else { diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c index af7fc7f..725a086 100644 --- a/bin/varnishd/stevedore_utils.c +++ b/bin/varnishd/stevedore_utils.c @@ -53,6 +53,7 @@ #include "mgt.h" #include "stevedore.h" +#include "vnum.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -197,7 +198,7 @@ STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) l = st.st_size; } else { AN(size); - q = str2bytes(size, &l, fssize); + q = VNUM_2bytes(size, &l, fssize); if (q != NULL) ARGV_ERR("(%s) size \"%s\": %s\n", size, ctx, q); diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index c363f4e..25c9947 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -38,6 +38,7 @@ #include "cache.h" #include "stevedore.h" +#include "vnum.h" #ifndef MAP_NOCORE #define MAP_NOCORE 0 /* XXX Linux */ @@ -131,7 +132,7 @@ smf_init(struct stevedore *parent, int ac, char * const *av) size = av[1]; if (ac > 2 && *av[2] != '\0') { - r = str2bytes(av[2], &page_size, 0); + r = VNUM_2bytes(av[2], &page_size, 0); if (r != NULL) ARGV_ERR("(-sfile) granularity \"%s\": %s\n", av[2], r); } diff --git a/bin/varnishd/storage_malloc.c b/bin/varnishd/storage_malloc.c index 500e74c..bc5a565 100644 --- a/bin/varnishd/storage_malloc.c +++ b/bin/varnishd/storage_malloc.c @@ -37,6 +37,7 @@ #include "cache.h" #include "stevedore.h" +#include "vnum.h" struct sma_sc { unsigned magic; @@ -216,7 +217,7 @@ sma_init(struct stevedore *parent, int ac, char * const *av) if (ac == 0 || *av[0] == '\0') return; - e = str2bytes(av[0], &u, 0); + e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-smalloc) size \"%s\": %s\n", av[0], e); if ((u != (uintmax_t)(size_t)u)) diff --git a/bin/varnishd/storage_umem.c b/bin/varnishd/storage_umem.c index 6e28a94..197d0ac 100644 --- a/bin/varnishd/storage_umem.c +++ b/bin/varnishd/storage_umem.c @@ -140,7 +140,7 @@ smu_init(struct stevedore *parent, int ac, char * const *av) if (ac == 0 || *av[0] == '\0') return; - e = str2bytes(av[0], &u, 0); + e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); if ((u != (uintmax_t)(size_t)u)) diff --git a/include/Makefile.am b/include/Makefile.am index d62cab3..e852c58 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -48,6 +48,7 @@ nobase_noinst_HEADERS = \ vlu.h \ vmb.h \ vmod_abi.h \ + vnum.h \ vpf.h \ vqueue.h \ vre.h \ diff --git a/include/libvarnish.h b/include/libvarnish.h index c0851c8..1450578 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -38,9 +38,6 @@ struct vsb; -/* from libvarnish/num.c */ -const char *str2bytes(const char *p, uintmax_t *r, uintmax_t rel); - /* from libvarnish/version.c */ void VCS_Message(const char *); diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index 3c045e6..e890904 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -13,7 +13,7 @@ libvarnish_la_SOURCES = \ cli_common.c \ cli_serve.c \ flopen.c \ - num.c \ + vnum.c \ vtim.c \ vtcp.c \ vct.c \ @@ -33,13 +33,13 @@ libvarnish_la_CFLAGS = -DVARNISH_STATE_DIR='"${VARNISH_STATE_DIR}"' libvarnish_la_LIBADD = ${RT_LIBS} ${NET_LIBS} ${LIBM} @PCRE_LIBS@ if ENABLE_TESTS -TESTS = num_c_test +TESTS = vnum_c_test noinst_PROGRAMS = ${TESTS} -num_c_test_SOURCES = num.c -num_c_test_CFLAGS = -DNUM_C_TEST -include config.h -num_c_test_LDADD = ${LIBM} +vnum_c_test_SOURCES = vnum.c +vnum_c_test_CFLAGS = -DNUM_C_TEST -include config.h +vnum_c_test_LDADD = ${LIBM} test: ${TESTS} @for test in ${TESTS} ; do ./$${test} ; done diff --git a/lib/libvarnish/num.c b/lib/libvarnish/num.c deleted file mode 100644 index 70255db..0000000 --- a/lib/libvarnish/num.c +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright (c) 2008-2009 Varnish Software 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. - * - * Deal with numbers with data storage suffix scaling - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "libvarnish.h" - -static const char err_miss_num[] = "Missing number"; -static const char err_invalid_num[] = "Invalid number"; -static const char err_abs_req[] = "Absolute number required"; -static const char err_invalid_suff[] = "Invalid suffix"; - -const char * -str2bytes(const char *p, uintmax_t *r, uintmax_t rel) -{ - double fval; - char *end; - - if (p == NULL || *p == '\0') - return (err_miss_num); - - fval = strtod(p, &end); - if (end == p || !isfinite(fval)) - return (err_invalid_num); - - if (*end == '\0') { - *r = (uintmax_t)fval; - return (NULL); - } - - if (end[0] == '%' && end[1] == '\0') { - if (rel == 0) - return (err_abs_req); - fval *= rel / 100.0; - } else { - /* accept a space before the multiplier */ - if (end[0] == ' ' && end[1] != '\0') - ++end; - - switch (end[0]) { - case 'k': case 'K': - fval *= (uintmax_t)1 << 10; - ++end; - break; - case 'm': case 'M': - fval *= (uintmax_t)1 << 20; - ++end; - break; - case 'g': case 'G': - fval *= (uintmax_t)1 << 30; - ++end; - break; - case 't': case 'T': - fval *= (uintmax_t)1 << 40; - ++end; - break; - case 'p': case 'P': - fval *= (uintmax_t)1 << 50; - ++end; - break; - case 'e': case 'E': - fval *= (uintmax_t)1 << 60; - ++end; - break; - default: - break; - } - - /* [bB] is a generic suffix of no effect */ - if (end[0] == 'b' || end[0] == 'B') - end++; - - if (end[0] != '\0') - return (err_invalid_suff); - } - - *r = (uintmax_t)round(fval); - return (NULL); -} - -#ifdef NUM_C_TEST -/* Compile with: "cc -o foo -DNUM_C_TEST -I../.. -I../../include num.c -lm" */ -#include "vas.h" -#include -#include -#include - -struct test_case { - const char *str; - uintmax_t rel; - uintmax_t val; - const char *err; -} test_cases[] = { - { "1", (uintmax_t)0, (uintmax_t)1 }, - { "1B", (uintmax_t)0, (uintmax_t)1<<0 }, - { "1 B", (uintmax_t)0, (uintmax_t)1<<0 }, - { "1.3B", (uintmax_t)0, (uintmax_t)1 }, - { "1.7B", (uintmax_t)0, (uintmax_t)2 }, - - { "1024", (uintmax_t)0, (uintmax_t)1024 }, - { "1k", (uintmax_t)0, (uintmax_t)1<<10 }, - { "1kB", (uintmax_t)0, (uintmax_t)1<<10 }, - { "1.3kB", (uintmax_t)0, (uintmax_t)1331 }, - { "1.7kB", (uintmax_t)0, (uintmax_t)1741 }, - - { "1048576", (uintmax_t)0, (uintmax_t)1048576 }, - { "1M", (uintmax_t)0, (uintmax_t)1<<20 }, - { "1MB", (uintmax_t)0, (uintmax_t)1<<20 }, - { "1.3MB", (uintmax_t)0, (uintmax_t)1363149 }, - { "1.7MB", (uintmax_t)0, (uintmax_t)1782579 }, - - { "1073741824", (uintmax_t)0, (uintmax_t)1073741824 }, - { "1G", (uintmax_t)0, (uintmax_t)1<<30 }, - { "1GB", (uintmax_t)0, (uintmax_t)1<<30 }, - { "1.3GB", (uintmax_t)0, (uintmax_t)1395864371 }, - { "1.7GB", (uintmax_t)0, (uintmax_t)1825361101 }, - - { "1099511627776", (uintmax_t)0, (uintmax_t)1099511627776ULL }, - { "1T", (uintmax_t)0, (uintmax_t)1<<40 }, - { "1TB", (uintmax_t)0, (uintmax_t)1<<40 }, - { "1.3TB", (uintmax_t)0, (uintmax_t)1429365116109ULL }, - { "1.7TB", (uintmax_t)0, (uintmax_t)1869169767219ULL }, - - { "1%", (uintmax_t)1024, (uintmax_t)10 }, - { "2%", (uintmax_t)1024, (uintmax_t)20 }, - { "3%", (uintmax_t)1024, (uintmax_t)31 }, - - /* Check the error checks */ - { "", 0, 0, err_miss_num }, - { "m", 0, 0, err_invalid_num }, - { "4%", 0, 0, err_abs_req }, - { "3*", 0, 0, err_invalid_suff }, - - /* TODO: add more */ - - { 0, 0, 0 }, -}; - -int -main(int argc, char *argv[]) -{ - struct test_case *tc; - uintmax_t val; - int ec; - const char *e; - - (void)argc; - for (ec = 0, tc = test_cases; tc->str; ++tc) { - e = str2bytes(tc->str, &val, tc->rel); - if (e != tc->err) { - printf("%s: str2bytes(\"%s\", %ju) (%s) != (%s)\n", - *argv, tc->str, tc->rel, tc->err, e); - ++ec; - } else if (e == NULL && val != tc->val) { - printf("%s: str2bytes(\"%s\", %ju) %ju != %ju (%s)\n", - *argv, tc->str, tc->rel, val, tc->val, e); - ++ec; - } - } - /* TODO: test invalid strings */ - if (!ec) - printf("OK\n"); - return (ec > 0); -} -#endif diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c new file mode 100644 index 0000000..7940e9b --- /dev/null +++ b/lib/libvarnish/vnum.c @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 2008-2009 Varnish Software 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. + * + * Deal with numbers with data storage suffix scaling + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "vnum.h" + +static const char err_miss_num[] = "Missing number"; +static const char err_invalid_num[] = "Invalid number"; +static const char err_abs_req[] = "Absolute number required"; +static const char err_invalid_suff[] = "Invalid suffix"; + +const char * +VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel) +{ + double fval; + char *end; + + if (p == NULL || *p == '\0') + return (err_miss_num); + + fval = strtod(p, &end); + if (end == p || !isfinite(fval)) + return (err_invalid_num); + + if (*end == '\0') { + *r = (uintmax_t)fval; + return (NULL); + } + + if (end[0] == '%' && end[1] == '\0') { + if (rel == 0) + return (err_abs_req); + fval *= rel / 100.0; + } else { + /* accept a space before the multiplier */ + if (end[0] == ' ' && end[1] != '\0') + ++end; + + switch (end[0]) { + case 'k': case 'K': + fval *= (uintmax_t)1 << 10; + ++end; + break; + case 'm': case 'M': + fval *= (uintmax_t)1 << 20; + ++end; + break; + case 'g': case 'G': + fval *= (uintmax_t)1 << 30; + ++end; + break; + case 't': case 'T': + fval *= (uintmax_t)1 << 40; + ++end; + break; + case 'p': case 'P': + fval *= (uintmax_t)1 << 50; + ++end; + break; + case 'e': case 'E': + fval *= (uintmax_t)1 << 60; + ++end; + break; + default: + break; + } + + /* [bB] is a generic suffix of no effect */ + if (end[0] == 'b' || end[0] == 'B') + end++; + + if (end[0] != '\0') + return (err_invalid_suff); + } + + *r = (uintmax_t)round(fval); + return (NULL); +} + +#ifdef NUM_C_TEST +/* Compile with: "cc -o foo -DNUM_C_TEST -I../.. -I../../include num.c -lm" */ +#include "vas.h" +#include +#include +#include + +struct test_case { + const char *str; + uintmax_t rel; + uintmax_t val; + const char *err; +} test_cases[] = { + { "1", (uintmax_t)0, (uintmax_t)1 }, + { "1B", (uintmax_t)0, (uintmax_t)1<<0 }, + { "1 B", (uintmax_t)0, (uintmax_t)1<<0 }, + { "1.3B", (uintmax_t)0, (uintmax_t)1 }, + { "1.7B", (uintmax_t)0, (uintmax_t)2 }, + + { "1024", (uintmax_t)0, (uintmax_t)1024 }, + { "1k", (uintmax_t)0, (uintmax_t)1<<10 }, + { "1kB", (uintmax_t)0, (uintmax_t)1<<10 }, + { "1.3kB", (uintmax_t)0, (uintmax_t)1331 }, + { "1.7kB", (uintmax_t)0, (uintmax_t)1741 }, + + { "1048576", (uintmax_t)0, (uintmax_t)1048576 }, + { "1M", (uintmax_t)0, (uintmax_t)1<<20 }, + { "1MB", (uintmax_t)0, (uintmax_t)1<<20 }, + { "1.3MB", (uintmax_t)0, (uintmax_t)1363149 }, + { "1.7MB", (uintmax_t)0, (uintmax_t)1782579 }, + + { "1073741824", (uintmax_t)0, (uintmax_t)1073741824 }, + { "1G", (uintmax_t)0, (uintmax_t)1<<30 }, + { "1GB", (uintmax_t)0, (uintmax_t)1<<30 }, + { "1.3GB", (uintmax_t)0, (uintmax_t)1395864371 }, + { "1.7GB", (uintmax_t)0, (uintmax_t)1825361101 }, + + { "1099511627776", (uintmax_t)0, (uintmax_t)1099511627776ULL }, + { "1T", (uintmax_t)0, (uintmax_t)1<<40 }, + { "1TB", (uintmax_t)0, (uintmax_t)1<<40 }, + { "1.3TB", (uintmax_t)0, (uintmax_t)1429365116109ULL }, + { "1.7TB", (uintmax_t)0, (uintmax_t)1869169767219ULL }, + + { "1%", (uintmax_t)1024, (uintmax_t)10 }, + { "2%", (uintmax_t)1024, (uintmax_t)20 }, + { "3%", (uintmax_t)1024, (uintmax_t)31 }, + + /* Check the error checks */ + { "", 0, 0, err_miss_num }, + { "m", 0, 0, err_invalid_num }, + { "4%", 0, 0, err_abs_req }, + { "3*", 0, 0, err_invalid_suff }, + + /* TODO: add more */ + + { 0, 0, 0 }, +}; + +int +main(int argc, char *argv[]) +{ + struct test_case *tc; + uintmax_t val; + int ec; + const char *e; + + (void)argc; + for (ec = 0, tc = test_cases; tc->str; ++tc) { + e = VNUM_2bytes(tc->str, &val, tc->rel); + if (e != tc->err) { + printf("%s: VNUM_2bytes(\"%s\", %ju) (%s) != (%s)\n", + *argv, tc->str, tc->rel, tc->err, e); + ++ec; + } else if (e == NULL && val != tc->val) { + printf("%s: VNUM_2bytes(\"%s\", %ju) %ju != %ju (%s)\n", + *argv, tc->str, tc->rel, val, tc->val, e); + ++ec; + } + } + /* TODO: test invalid strings */ + if (!ec) + printf("OK\n"); + return (ec > 0); +} +#endif From phk at varnish-cache.org Sun Oct 9 19:30:23 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 21:30:23 +0200 Subject: [master] 06b3c20 And rename the various file-accesors to VFIL_ Message-ID: commit 06b3c206e526c919722ff797aa9e7d0add3fd0b0 Author: Poul-Henning Kamp Date: Sun Oct 9 19:29:19 2011 +0000 And rename the various file-accesors to VFIL_ Remove srandomdev() look-alike, we already have a compat version diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index bbf813a..df46c41 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -44,6 +44,7 @@ #include "vcli.h" #include "vsub.h" #include "vcl.h" +#include "vfil.h" #include "cli_priv.h" #include "mgt_cli.h" @@ -227,7 +228,7 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) struct vcc_priv vp; /* Create temporary C source file */ - sfd = vtmpfile(sf); + sfd = VFIL_tmpfile(sf); if (sfd < 0) { VSB_printf(sb, "Failed to create %s: %s", sf, strerror(errno)); return (NULL); @@ -245,7 +246,7 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) } if (C_flag) { - csrc = vreadfile(NULL, sf, NULL); + csrc = VFIL_readfile(NULL, sf, NULL); XXXAN(csrc); (void)fputs(csrc, stdout); free(csrc); @@ -517,7 +518,7 @@ mcf_config_load(struct cli *cli, const char * const *av, void *priv) return; } - vcl = vreadfile(mgt_vcl_dir, av[3], NULL); + vcl = VFIL_readfile(mgt_vcl_dir, av[3], NULL); if (vcl == NULL) { VCLI_Out(cli, "Cannot open '%s'", av[3]); VCLI_SetResult(cli, CLIS_PARAM); diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 360cdad..bf61ea3 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -55,12 +55,17 @@ #include "vav.h" #include "vin.h" +#include "vfil.h" #include "vtim.h" #include "heritage.h" #include "mgt.h" #include "hash_slinger.h" #include "stevedore.h" +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif + struct heritage heritage; volatile struct params *params; unsigned d_flag = 0; @@ -355,7 +360,7 @@ main(int argc, char * const *argv) for (o = getdtablesize(); o > STDERR_FILENO; o--) (void)close(o); - AZ(seed_random()); + srandomdev(); mgt_got_fd(STDERR_FILENO); @@ -543,7 +548,7 @@ main(int argc, char * const *argv) } if (f_arg != NULL) { - vcl = vreadfile(NULL, f_arg, NULL); + vcl = VFIL_readfile(NULL, f_arg, NULL); if (vcl == NULL) { fprintf(stderr, "Cannot read '%s': %s\n", f_arg, strerror(errno)); diff --git a/include/Makefile.am b/include/Makefile.am index e852c58..70be7f7 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -44,6 +44,7 @@ nobase_noinst_HEADERS = \ vct.h \ vend.h \ vev.h \ + vfil.h \ vin.h \ vlu.h \ vmb.h \ diff --git a/include/libvarnish.h b/include/libvarnish.h index 1450578..65287b5 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -41,12 +41,6 @@ struct vsb; /* from libvarnish/version.c */ void VCS_Message(const char *); -/* from libvarnish/vtmpfile.c */ -int seed_random(void); -int vtmpfile(char *); -char *vreadfile(const char *pfx, const char *fn, ssize_t *sz); -char *vreadfd(int fd, ssize_t *sz); - /* Safe printf into a fixed-size buffer */ #define bprintf(buf, fmt, ...) \ do { \ diff --git a/include/vfil.h b/include/vfil.h new file mode 100644 index 0000000..74885ef --- /dev/null +++ b/include/vfil.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* from libvarnish/vfil.c */ +int seed_random(void); +int VFIL_tmpfile(char *); +char *VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz); +char *VFIL_readfd(int fd, ssize_t *sz); diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index e890904..ab2cc94 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -19,6 +19,7 @@ libvarnish_la_SOURCES = \ vct.c \ version.c \ vev.c \ + vfil.c \ vin.c \ vlu.c \ vmb.c \ @@ -26,8 +27,7 @@ libvarnish_la_SOURCES = \ vre.c \ vsb.c \ vsha256.c \ - vss.c \ - vtmpfile.c + vss.c libvarnish_la_CFLAGS = -DVARNISH_STATE_DIR='"${VARNISH_STATE_DIR}"' libvarnish_la_LIBADD = ${RT_LIBS} ${NET_LIBS} ${LIBM} @PCRE_LIBS@ diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c new file mode 100644 index 0000000..884b106 --- /dev/null +++ b/lib/libvarnish/vfil.c @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software AS + * All rights reserved. + * + * Author: Dag-Erling Sm?rgrav + * + * 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. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "vas.h" +#include "vfil.h" +#include "libvarnish.h" + +int +VFIL_tmpfile(char *template) +{ + char *b, *e, *p; + int fd; + char ran; + + for (b = template; *b != '#'; ++b) + /* nothing */ ; + if (*b == '\0') { + errno = EINVAL; + return (-1); + } + for (e = b; *e == '#'; ++e) + /* nothing */ ; + + for (;;) { + for (p = b; p < e; ++p) { + ran = random() % 63; + if (ran < 10) + *p = '0' + ran; + else if (ran < 36) + *p = 'A' + ran - 10; + else if (ran < 62) + *p = 'a' + ran - 36; + else + *p = '_'; + } + fd = open(template, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd >= 0) + return (fd); + if (errno != EEXIST) + return (-1); + } + /* not reached */ +} + +char * +VFIL_readfd(int fd, ssize_t *sz) +{ + struct stat st; + char *f; + int i; + + assert(0 == fstat(fd, &st)); + if (!S_ISREG(st.st_mode)) + return (NULL); + f = malloc(st.st_size + 1); + assert(f != NULL); + i = read(fd, f, st.st_size); + assert(i == st.st_size); + f[i] = '\0'; + if (sz != NULL) + *sz = st.st_size; + return (f); +} + +char * +VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz) +{ + int fd, err; + char *r; + char fnb[PATH_MAX + 1]; + + if (fn[0] == '/') + fd = open(fn, O_RDONLY); + else if (pfx != NULL) { + bprintf(fnb, "/%s/%s", pfx, fn); /* XXX: graceful length check */ + fd = open(fnb, O_RDONLY); + } else + fd = open(fn, O_RDONLY); + if (fd < 0) + return (NULL); + r = VFIL_readfd(fd, sz); + err = errno; + AZ(close(fd)); + errno = err; + return (r); +} diff --git a/lib/libvarnish/vtmpfile.c b/lib/libvarnish/vtmpfile.c deleted file mode 100644 index 327790a..0000000 --- a/lib/libvarnish/vtmpfile.c +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software AS - * All rights reserved. - * - * Author: Dag-Erling Sm?rgrav - * - * 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. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "libvarnish.h" - -int -seed_random(void) -{ - int fd; - unsigned seed; - - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) { - /* urandom not available, fall back to something - * weaker */ - srandom(time(NULL)); - return (0); - } - if (read(fd, &seed, sizeof seed) != sizeof seed) - return (1); - (void)close(fd); - srandom(seed); - return (0); -} - -int -vtmpfile(char *template) -{ - char *b, *e, *p; - int fd; - char ran; - - for (b = template; *b != '#'; ++b) - /* nothing */ ; - if (*b == '\0') { - errno = EINVAL; - return (-1); - } - for (e = b; *e == '#'; ++e) - /* nothing */ ; - - for (;;) { - for (p = b; p < e; ++p) { - ran = random() % 63; - if (ran < 10) - *p = '0' + ran; - else if (ran < 36) - *p = 'A' + ran - 10; - else if (ran < 62) - *p = 'a' + ran - 36; - else - *p = '_'; - } - fd = open(template, O_RDWR|O_CREAT|O_EXCL, 0600); - if (fd >= 0) - return (fd); - if (errno != EEXIST) - return (-1); - } - /* not reached */ -} - -char * -vreadfd(int fd, ssize_t *sz) -{ - struct stat st; - char *f; - int i; - - assert(0 == fstat(fd, &st)); - if (!S_ISREG(st.st_mode)) - return (NULL); - f = malloc(st.st_size + 1); - assert(f != NULL); - i = read(fd, f, st.st_size); - assert(i == st.st_size); - f[i] = '\0'; - if (sz != NULL) - *sz = st.st_size; - return (f); -} - -char * -vreadfile(const char *pfx, const char *fn, ssize_t *sz) -{ - int fd, err; - char *r; - char fnb[PATH_MAX + 1]; - - if (fn[0] == '/') - fd = open(fn, O_RDONLY); - else if (pfx != NULL) { - bprintf(fnb, "/%s/%s", pfx, fn); /* XXX: graceful length check */ - fd = open(fnb, O_RDONLY); - } else - fd = open(fn, O_RDONLY); - if (fd < 0) - return (NULL); - r = vreadfd(fd, sz); - err = errno; - AZ(close(fd)); - errno = err; - return (r); -} diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index 3af30c6..dbae2ab 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -61,6 +61,7 @@ #include "vcc_compile.h" #include "libvcl.h" +#include "vfil.h" struct method method_tab[] = { #define VCL_MET_MAC(l,U,m) { "vcl_"#l, m, VCL_MET_##U }, @@ -409,7 +410,7 @@ vcc_file_source(const struct vcc *tl, struct vsb *sb, const char *fn) char *f; struct source *sp; - f = vreadfile(tl->vcl_dir, fn, NULL); + f = VFIL_readfile(tl->vcl_dir, fn, NULL); if (f == NULL) { VSB_printf(sb, "Cannot read file '%s': %s\n", fn, strerror(errno)); diff --git a/lib/libvmod_std/vmod_std_fileread.c b/lib/libvmod_std/vmod_std_fileread.c index e1be09a..cae57a2 100644 --- a/lib/libvmod_std/vmod_std_fileread.c +++ b/lib/libvmod_std/vmod_std_fileread.c @@ -42,6 +42,7 @@ #include "../../bin/varnishd/cache.h" #include "vcc_if.h" +#include "vfil.h" struct frfile { unsigned magic; @@ -102,7 +103,7 @@ vmod_fileread(struct sess *sp, struct vmod_priv *priv, const char *file_name) return (frf->contents); } - s = vreadfile(NULL, file_name, NULL); + s = VFIL_readfile(NULL, file_name, NULL); if (s != NULL) { ALLOC_OBJ(frf, CACHED_FILE_MAGIC); AN(frf); From phk at varnish-cache.org Sun Oct 9 19:52:11 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 21:52:11 +0200 Subject: [master] 080f259 Push "vas.h", , and NULL out of libvarnish.h Message-ID: commit 080f2595d2d5f71a6795445cc6f688d221c48f08 Author: Poul-Henning Kamp Date: Sun Oct 9 19:51:08 2011 +0000 Push "vas.h", , and NULL out of libvarnish.h diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index d371b9f..b857f8a 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -46,7 +46,7 @@ #include "vcli.h" #include "cli_common.h" -#include "libvarnish.h" +#include "vas.h" #include "vss.h" #ifdef HAVE_LIBEDIT diff --git a/bin/varnishd/common.h b/bin/varnishd/common.h index f755b97..0e6d95d 100644 --- a/bin/varnishd/common.h +++ b/bin/varnishd/common.h @@ -29,6 +29,7 @@ */ #include "libvarnish.h" +#include "vas.h" #include "vsb.h" #include "vqueue.h" #include "miniobj.h" diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 9485df7..92d17b3 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -48,6 +48,7 @@ #include #include +#include "vas.h" #include "libvarnish.h" #define HIST_N 2000 /* how far back we remember */ diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index c67432d..3142d1b 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -47,6 +47,7 @@ #include "vsb.h" #include "vpf.h" +#include "vas.h" #include "libvarnish.h" static int b_flag, c_flag; diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index d010a73..4805d81 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -73,6 +73,7 @@ #include "compat/daemon.h" +#include "vas.h" #include "vsb.h" #include "vpf.h" #include "vqueue.h" diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index dbb6f51..ef4118a 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -48,6 +48,7 @@ #include "vqueue.h" +#include "vas.h" #include "libvarnish.h" #include "vss.h" diff --git a/bin/varnishsizes/varnishsizes.c b/bin/varnishsizes/varnishsizes.c index ac9dbf8..70fcad1 100644 --- a/bin/varnishsizes/varnishsizes.c +++ b/bin/varnishsizes/varnishsizes.c @@ -48,6 +48,7 @@ #include #include +#include "vas.h" #include "libvarnish.h" #define HIST_N 2000 /* how far back we remember */ diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index 76a2e03..b160a26 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -44,7 +44,6 @@ #include #include -#include "libvarnish.h" #include "varnishstat.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishstat/varnishstat.h b/bin/varnishstat/varnishstat.h index 245af35..322ebc4 100644 --- a/bin/varnishstat/varnishstat.h +++ b/bin/varnishstat/varnishstat.h @@ -27,4 +27,7 @@ * */ +#include "vas.h" +#include "libvarnish.h" + void do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main, int delay); diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index fc948e9..1e93155 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -50,7 +50,6 @@ #include #include -#include "libvarnish.h" #include "vqueue.h" #include "varnishstat.h" diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index e96940d..3621dc5 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -34,11 +34,11 @@ #include #endif +#include "miniobj.h" +#include "vas.h" #include "vqueue.h" #include "vsb.h" -#include "miniobj.h" -struct vsb; struct vtclog; struct cmds; diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index de3789f..1022e32 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -50,6 +50,7 @@ #include "vsb.h" +#include "vas.h" #include "libvarnish.h" #if 0 diff --git a/include/libvarnish.h b/include/libvarnish.h index 65287b5..4cbb18d 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -28,16 +28,6 @@ * */ -#include - -#include "vas.h" - -#ifndef NULL -#define NULL ((void*)0) -#endif - -struct vsb; - /* from libvarnish/version.c */ void VCS_Message(const char *); @@ -54,3 +44,4 @@ void VCS_Message(const char *); assert(vsnprintf(buf, sizeof buf, fmt, ap) \ < sizeof buf); \ } while (0) + diff --git a/include/vnum.h b/include/vnum.h new file mode 100644 index 0000000..a821355 --- /dev/null +++ b/include/vnum.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#include + +/* from libvarnish/vnum.c */ +const char *VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel); diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c index f49c736..4b0edc3 100644 --- a/lib/libvarnish/binary_heap.c +++ b/lib/libvarnish/binary_heap.c @@ -35,12 +35,13 @@ #include "config.h" -#include -#include #include +#include +#include +#include #include "binary_heap.h" -#include "libvarnish.h" +#include "vas.h" /* Parameters --------------------------------------------------------*/ diff --git a/lib/libvarnish/cli_auth.c b/lib/libvarnish/cli_auth.c index fc66fa7..da0a241 100644 --- a/lib/libvarnish/cli_auth.c +++ b/lib/libvarnish/cli_auth.c @@ -32,11 +32,10 @@ #include #include +#include "vas.h" #include "vcli.h" -#include "libvarnish.h" #include "vsha256.h" - void VCLI_AuthResponse(int S_fd, const char *challenge, char response[CLI_AUTH_RESPONSE_LEN + 1]) diff --git a/lib/libvarnish/cli_common.c b/lib/libvarnish/cli_common.c index 994bd9a..e423da4 100644 --- a/lib/libvarnish/cli_common.c +++ b/lib/libvarnish/cli_common.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ #include "vsb.h" -#include "libvarnish.h" +#include "vas.h" #include "vcli.h" #include "cli_priv.h" diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index 03cf1d4..13b9663 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -39,6 +39,7 @@ #include #include +#include "vas.h" #include "vqueue.h" #include "vsb.h" #include "vav.h" @@ -47,7 +48,6 @@ #include "cli_priv.h" #include "cli_common.h" #include "cli_serve.h" -#include "libvarnish.h" #include "miniobj.h" struct VCLS_func { diff --git a/lib/libvarnish/vas.c b/lib/libvarnish/vas.c index 82351ce..6f69928 100644 --- a/lib/libvarnish/vas.c +++ b/lib/libvarnish/vas.c @@ -35,7 +35,7 @@ #include #include -#include "libvarnish.h" +#include "vas.h" static void VAS_Fail_default(const char *func, const char *file, int line, diff --git a/lib/libvarnish/vev.c b/lib/libvarnish/vev.c index c55ebfc..004ce08 100644 --- a/lib/libvarnish/vev.c +++ b/lib/libvarnish/vev.c @@ -38,7 +38,7 @@ #include #include -#include "libvarnish.h" +#include "vas.h" #include "vtim.h" #include "vev.h" #include "miniobj.h" diff --git a/lib/libvarnish/vin.c b/lib/libvarnish/vin.c index 0f1b680..ccd58a9 100644 --- a/lib/libvarnish/vin.c +++ b/lib/libvarnish/vin.c @@ -36,9 +36,10 @@ #include #include -#include "libvarnish.h" +#include "vas.h" #include "vsm.h" #include "vin.h" +#include "libvarnish.h" int VIN_N_Arg(const char *n_arg, char **name, char **dir, char **vsl) diff --git a/lib/libvarnish/vlu.c b/lib/libvarnish/vlu.c index db107a1..01d21de 100644 --- a/lib/libvarnish/vlu.c +++ b/lib/libvarnish/vlu.c @@ -34,6 +34,7 @@ #include #include #include "libvarnish.h" +#include "vas.h" #include "vlu.h" #include "miniobj.h" diff --git a/lib/libvarnish/vpf.c b/lib/libvarnish/vpf.c index c35b3cd..f6543c6 100644 --- a/lib/libvarnish/vpf.c +++ b/lib/libvarnish/vpf.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "libvarnish.h" /* XXX: for assert() */ #include "flopen.h" +#include "vas.h" #include "vpf.h" struct vpf_fh { diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index 68beaf8..e330e99 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -31,6 +31,7 @@ #include "libvarnish.h" #include "miniobj.h" +#include "vas.h" #include "vre.h" struct vre { diff --git a/lib/libvarnish/vsb.c b/lib/libvarnish/vsb.c index 75414f7..4930be2 100644 --- a/lib/libvarnish/vsb.c +++ b/lib/libvarnish/vsb.c @@ -35,7 +35,7 @@ __FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 222004 2011-05-17 06:36:32Z phk $") #include #include -#include "libvarnish.h" +#include "vas.h" #include "vsb.h" #define KASSERT(e, m) assert(e) diff --git a/lib/libvarnish/vsha256.c b/lib/libvarnish/vsha256.c index 83dd6a1..942a186 100644 --- a/lib/libvarnish/vsha256.c +++ b/lib/libvarnish/vsha256.c @@ -42,7 +42,7 @@ #define VBIG_ENDIAN _BIG_ENDIAN #endif -#include "libvarnish.h" +#include "vas.h" #include "vsha256.h" #include "vend.h" diff --git a/lib/libvarnish/vss.c b/lib/libvarnish/vss.c index ff19ac7..297df11 100644 --- a/lib/libvarnish/vss.c +++ b/lib/libvarnish/vss.c @@ -43,7 +43,7 @@ #include #include -#include "libvarnish.h" +#include "vas.h" #include "vtcp.h" #include "vss.h" diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index e8932e8..c955e65 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -51,8 +51,8 @@ #include #include +#include "vas.h" #include "vtcp.h" -#include "libvarnish.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index 141f4f1..ebbba86 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -28,15 +28,22 @@ * */ -#include "vqueue.h" +#include + +#include "libvarnish.h" +#include "vas.h" #include "miniobj.h" -#include "vsb.h" #include "vcl.h" -#include "libvarnish.h" +#include "vqueue.h" +#include "vsb.h" #include "vcc_token_defs.h" +#ifndef NULL +#define NULL ((void*)0) +#endif + struct vsb; #define isident1(c) (isalpha(c)) From phk at varnish-cache.org Sun Oct 9 20:07:57 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 22:07:57 +0200 Subject: [master] a889566 Get rid of the last trace if the libvarnish.h kitchen-sink: bprint macros go in vdef.h, VCS_* in vcs.h Message-ID: commit a88956622c34e38826d5f816dad0e0e936813c0c Author: Poul-Henning Kamp Date: Sun Oct 9 20:07:25 2011 +0000 Get rid of the last trace if the libvarnish.h kitchen-sink: bprint macros go in vdef.h, VCS_* in vcs.h diff --git a/bin/varnishd/common.h b/bin/varnishd/common.h index 0e6d95d..7fd15b7 100644 --- a/bin/varnishd/common.h +++ b/bin/varnishd/common.h @@ -28,11 +28,12 @@ * */ -#include "libvarnish.h" +#include "miniobj.h" #include "vas.h" -#include "vsb.h" +#include "vcs.h" +#include "vdef.h" #include "vqueue.h" -#include "miniobj.h" +#include "vsb.h" struct cli; diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 92d17b3..e2fc652 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -49,7 +49,7 @@ #include #include "vas.h" -#include "libvarnish.h" +#include "vcs.h" #define HIST_N 2000 /* how far back we remember */ #define HIST_LOW -6 /* low end of log range */ diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index 3142d1b..86c8504 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -44,11 +44,10 @@ #include "compat/daemon.h" -#include "vsb.h" -#include "vpf.h" - #include "vas.h" -#include "libvarnish.h" +#include "vcs.h" +#include "vpf.h" +#include "vsb.h" static int b_flag, c_flag; diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 4805d81..05b8dfe 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -74,12 +74,12 @@ #include "compat/daemon.h" #include "vas.h" -#include "vsb.h" +#include "vcs.h" #include "vpf.h" #include "vqueue.h" - -#include "libvarnish.h" #include "vre.h" +#include "vsb.h" + #include "base64.h" static volatile sig_atomic_t reopen; diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index ef4118a..ffc403f 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -46,10 +46,9 @@ #include #include -#include "vqueue.h" - #include "vas.h" -#include "libvarnish.h" +#include "vcs.h" +#include "vqueue.h" #include "vss.h" #define freez(x) do { if (x) free(x); x = NULL; } while (0); diff --git a/bin/varnishsizes/varnishsizes.c b/bin/varnishsizes/varnishsizes.c index 70fcad1..d3e3218 100644 --- a/bin/varnishsizes/varnishsizes.c +++ b/bin/varnishsizes/varnishsizes.c @@ -49,7 +49,7 @@ #include #include "vas.h" -#include "libvarnish.h" +#include "vcs.h" #define HIST_N 2000 /* how far back we remember */ #define HIST_LOW 1 /* low end of log range */ diff --git a/bin/varnishstat/varnishstat.h b/bin/varnishstat/varnishstat.h index 322ebc4..314c7c5 100644 --- a/bin/varnishstat/varnishstat.h +++ b/bin/varnishstat/varnishstat.h @@ -28,6 +28,6 @@ */ #include "vas.h" -#include "libvarnish.h" +#include "vcs.h" void do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main, int delay); diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 83bbb22..4404de9 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -41,7 +41,6 @@ #include "vav.h" #include "vtim.h" -#include "libvarnish.h" #ifndef HAVE_SRANDOMDEV diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 3621dc5..1340314 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -36,6 +36,7 @@ #include "miniobj.h" #include "vas.h" +#include "vdef.h" #include "vqueue.h" #include "vsb.h" diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 55e25fa..2547d80 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -39,7 +39,6 @@ #include "vss.h" #include "vtcp.h" -#include "libvarnish.h" struct client { unsigned magic; diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 50816bc..889891b 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -37,14 +37,10 @@ #include #include "vct.h" - -#include "libvarnish.h" - +#include "vgz.h" #include "vtc.h" #include "vtcp.h" -#include "vgz.h" - #define MAX_HDR 50 struct http { diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index c06f319..753de58 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -34,8 +34,6 @@ #include #include "vtc.h" - -#include "libvarnish.h" #include "vtim.h" static pthread_mutex_t vtclog_mtx; diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 040afdc..3b9d81b 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -38,10 +38,8 @@ #include #include -#include "vtc.h" - -#include "libvarnish.h" #include "vev.h" +#include "vtc.h" #include "vtim.h" #ifndef HAVE_SRANDOMDEV diff --git a/bin/varnishtest/vtc_sema.c b/bin/varnishtest/vtc_sema.c index 8a9228a..c363b4a 100644 --- a/bin/varnishtest/vtc_sema.c +++ b/bin/varnishtest/vtc_sema.c @@ -35,8 +35,6 @@ #include "vtc.h" -#include "libvarnish.h" - struct sema { unsigned magic; #define SEMA_MAGIC 0x29b64317 diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index afe62af..5a768a1 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -36,12 +36,10 @@ #include #include +#include "vss.h" #include "vtc.h" #include "vtcp.h" -#include "libvarnish.h" -#include "vss.h" - struct server { unsigned magic; #define SERVER_MAGIC 0x55286619 diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 8b310f6..ba19464 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -45,13 +45,10 @@ #include #include -#include "vtc.h" -#include "vtcp.h" - -#include "libvarnish.h" - #include "vcli.h" #include "vss.h" +#include "vtc.h" +#include "vtcp.h" struct varnish { unsigned magic; diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 1022e32..34278ea 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -46,13 +46,11 @@ #include #include +#include "vas.h" +#include "vcs.h" #include "vqueue.h" - #include "vsb.h" -#include "vas.h" -#include "libvarnish.h" - #if 0 #define AC(x) assert((x) != ERR) #else diff --git a/include/Makefile.am b/include/Makefile.am index 70be7f7..320f18c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -32,7 +32,6 @@ nobase_noinst_HEADERS = \ compat/execinfo.h \ compat/srandomdev.h \ flopen.h \ - libvarnish.h \ libvcl.h \ miniobj.h \ persistent.h \ @@ -41,7 +40,9 @@ nobase_noinst_HEADERS = \ vbm.h \ vcl.h \ vcs_version.h \ + vcs.h \ vct.h \ + vdef.h \ vend.h \ vev.h \ vfil.h \ diff --git a/include/libvarnish.h b/include/libvarnish.h deleted file mode 100644 index 4cbb18d..0000000 --- a/include/libvarnish.h +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -/* from libvarnish/version.c */ -void VCS_Message(const char *); - -/* Safe printf into a fixed-size buffer */ -#define bprintf(buf, fmt, ...) \ - do { \ - assert(snprintf(buf, sizeof buf, fmt, __VA_ARGS__) \ - < sizeof buf); \ - } while (0) - -/* Safe printf into a fixed-size buffer */ -#define vbprintf(buf, fmt, ap) \ - do { \ - assert(vsnprintf(buf, sizeof buf, fmt, ap) \ - < sizeof buf); \ - } while (0) - diff --git a/include/vcs.h b/include/vcs.h new file mode 100644 index 0000000..f764100 --- /dev/null +++ b/include/vcs.h @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* from libvarnish/version.c */ +void VCS_Message(const char *); diff --git a/include/vdef.h b/include/vdef.h new file mode 100644 index 0000000..c9b24c5 --- /dev/null +++ b/include/vdef.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +/* Safe printf into a fixed-size buffer */ +#define bprintf(buf, fmt, ...) \ + do { \ + assert(snprintf(buf, sizeof buf, fmt, __VA_ARGS__) \ + < sizeof buf); \ + } while (0) + +/* Safe printf into a fixed-size buffer */ +#define vbprintf(buf, fmt, ap) \ + do { \ + assert(vsnprintf(buf, sizeof buf, fmt, ap) \ + < sizeof buf); \ + } while (0) + diff --git a/lib/libvarnish/version.c b/lib/libvarnish/version.c index 014eda4..2220a69 100644 --- a/lib/libvarnish/version.c +++ b/lib/libvarnish/version.c @@ -33,7 +33,7 @@ #include -#include "libvarnish.h" +#include "vcs.h" #include "vcs_version.h" void diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c index 884b106..a4bab9e 100644 --- a/lib/libvarnish/vfil.c +++ b/lib/libvarnish/vfil.c @@ -40,8 +40,8 @@ #include #include "vas.h" +#include "vdef.h" #include "vfil.h" -#include "libvarnish.h" int VFIL_tmpfile(char *template) diff --git a/lib/libvarnish/vin.c b/lib/libvarnish/vin.c index ccd58a9..65fdb5e 100644 --- a/lib/libvarnish/vin.c +++ b/lib/libvarnish/vin.c @@ -37,9 +37,9 @@ #include #include "vas.h" -#include "vsm.h" +#include "vdef.h" #include "vin.h" -#include "libvarnish.h" +#include "vsm.h" int VIN_N_Arg(const char *n_arg, char **name, char **dir, char **vsl) diff --git a/lib/libvarnish/vlu.c b/lib/libvarnish/vlu.c index 01d21de..1334a28 100644 --- a/lib/libvarnish/vlu.c +++ b/lib/libvarnish/vlu.c @@ -33,7 +33,6 @@ #include #include #include -#include "libvarnish.h" #include "vas.h" #include "vlu.h" #include "miniobj.h" diff --git a/lib/libvarnish/vmb.c b/lib/libvarnish/vmb.c index 2c004ce..aa069a7 100644 --- a/lib/libvarnish/vmb.c +++ b/lib/libvarnish/vmb.c @@ -28,7 +28,6 @@ #include #include -#include "libvarnish.h" #include "vmb.h" #ifdef VMB_NEEDS_PTHREAD_WORKAROUND_THIS_IS_BAD_FOR_PERFORMANCE diff --git a/lib/libvarnish/vpf.c b/lib/libvarnish/vpf.c index f6543c6..7875c15 100644 --- a/lib/libvarnish/vpf.c +++ b/lib/libvarnish/vpf.c @@ -40,7 +40,6 @@ #include #include -#include "libvarnish.h" /* XXX: for assert() */ #include "flopen.h" #include "vas.h" #include "vpf.h" diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index e330e99..2810bc2 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -29,7 +29,6 @@ #include #include -#include "libvarnish.h" #include "miniobj.h" #include "vas.h" #include "vre.h" diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c index edfb8a5..772b559 100644 --- a/lib/libvarnish/vtim.c +++ b/lib/libvarnish/vtim.c @@ -56,7 +56,6 @@ #include "vas.h" #include "vtim.h" -//#include "libvarnish.h" /* * Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index ebbba86..a245a36 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -30,11 +30,10 @@ #include -#include "libvarnish.h" -#include "vas.h" - #include "miniobj.h" +#include "vas.h" #include "vcl.h" +#include "vdef.h" #include "vqueue.h" #include "vsb.h" From phk at varnish-cache.org Sun Oct 9 20:14:54 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 22:14:54 +0200 Subject: [master] 6888981 Add necessary #includes Message-ID: commit 6888981c59d95d9832f5fac29a5b2e6aae7752fa Author: Poul-Henning Kamp Date: Sun Oct 9 20:14:45 2011 +0000 Add necessary #includes diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index bf61ea3..9ba9570 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/bin/varnishd/vsm.c b/bin/varnishd/vsm.c index dc265ba..d1717fe 100644 --- a/bin/varnishd/vsm.c +++ b/bin/varnishd/vsm.c @@ -47,13 +47,15 @@ #include "config.h" -#include -#include +#include #include +#include +#include #include "common.h" -#include "vsm.h" + #include "vmb.h" +#include "vsm.h" #include "vtim.h" /* These two come from beyond (mgt_shmem.c actually) */ diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 4404de9..5c6bbfd 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -28,14 +28,15 @@ #include "config.h" -#include -#include #include #include +#include +#include #include -#include +#include #include #include +#include #include "vtc.h" From phk at varnish-cache.org Sun Oct 9 20:50:15 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 22:50:15 +0200 Subject: [master] 1c2a1b3 Add vapi/vsm_int.h to complete the picture. Message-ID: commit 1c2a1b3437df7b39ca94e2cea6d9032ad0fc01b6 Author: Poul-Henning Kamp Date: Sun Oct 9 20:49:59 2011 +0000 Add vapi/vsm_int.h to complete the picture. diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h new file mode 100644 index 0000000..98e8610 --- /dev/null +++ b/include/vapi/vsm_int.h @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Define the layout of the shared memory log segment. + * + * NB: THIS IS NOT A PUBLIC API TO VARNISH! + */ + +#ifndef VSM_H_INCLUDED +#define VSM_H_INCLUDED + +#define VSM_FILENAME "_.vsm" + +#include +#include + +/* + * This structure describes each allocation from the shmlog + */ + +struct VSM_chunk { +#define VSM_CHUNK_MAGIC 0x43907b6e /* From /dev/random */ + unsigned magic; + unsigned len; + unsigned state; + char class[8]; + char type[8]; + char ident[64]; +}; + +#define VSM_NEXT(sha) ((void*)((uintptr_t)(sha) + (sha)->len)) +#define VSM_PTR(sha) ((void*)((uintptr_t)((sha) + 1))) + +struct VSM_head { +#define VSM_HEAD_MAGIC 4185512502U /* From /dev/random */ + unsigned magic; + + unsigned hdrsize; + + time_t starttime; + pid_t master_pid; + pid_t child_pid; + + unsigned shm_size; + + /* Panic message buffer */ + char panicstr[64 * 1024]; + + unsigned alloc_seq; + /* Must be last element */ + struct VSM_chunk head; +}; + +/* + * You must include "miniobj.h" and have an assert function to be + * able to use the VSM_ITER() macro. + */ +#ifdef CHECK_OBJ_NOTNULL + +static inline struct VSM_chunk * +vsm_iter_0(void) +{ + + CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC); + CHECK_OBJ_NOTNULL(&VSM_head->head, VSM_CHUNK_MAGIC); + return (&VSM_head->head); +} + +static inline void +vsm_iter_n(struct VSM_chunk **pp) +{ + + CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC); + CHECK_OBJ_NOTNULL(*pp, VSM_CHUNK_MAGIC); + *pp = VSM_NEXT(*pp); + if (*pp >= vsm_end) { + *pp = NULL; + return; + } + CHECK_OBJ_NOTNULL(*pp, VSM_CHUNK_MAGIC); +} + +#define VSM_ITER(vd) for ((vd) = vsm_iter_0(); (vd) != NULL; vsm_iter_n(&vd)) + +#endif /* CHECK_OBJ_NOTNULL */ + +#endif diff --git a/include/vsm.h b/include/vsm.h deleted file mode 100644 index 98e8610..0000000 --- a/include/vsm.h +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Define the layout of the shared memory log segment. - * - * NB: THIS IS NOT A PUBLIC API TO VARNISH! - */ - -#ifndef VSM_H_INCLUDED -#define VSM_H_INCLUDED - -#define VSM_FILENAME "_.vsm" - -#include -#include - -/* - * This structure describes each allocation from the shmlog - */ - -struct VSM_chunk { -#define VSM_CHUNK_MAGIC 0x43907b6e /* From /dev/random */ - unsigned magic; - unsigned len; - unsigned state; - char class[8]; - char type[8]; - char ident[64]; -}; - -#define VSM_NEXT(sha) ((void*)((uintptr_t)(sha) + (sha)->len)) -#define VSM_PTR(sha) ((void*)((uintptr_t)((sha) + 1))) - -struct VSM_head { -#define VSM_HEAD_MAGIC 4185512502U /* From /dev/random */ - unsigned magic; - - unsigned hdrsize; - - time_t starttime; - pid_t master_pid; - pid_t child_pid; - - unsigned shm_size; - - /* Panic message buffer */ - char panicstr[64 * 1024]; - - unsigned alloc_seq; - /* Must be last element */ - struct VSM_chunk head; -}; - -/* - * You must include "miniobj.h" and have an assert function to be - * able to use the VSM_ITER() macro. - */ -#ifdef CHECK_OBJ_NOTNULL - -static inline struct VSM_chunk * -vsm_iter_0(void) -{ - - CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC); - CHECK_OBJ_NOTNULL(&VSM_head->head, VSM_CHUNK_MAGIC); - return (&VSM_head->head); -} - -static inline void -vsm_iter_n(struct VSM_chunk **pp) -{ - - CHECK_OBJ_NOTNULL(VSM_head, VSM_HEAD_MAGIC); - CHECK_OBJ_NOTNULL(*pp, VSM_CHUNK_MAGIC); - *pp = VSM_NEXT(*pp); - if (*pp >= vsm_end) { - *pp = NULL; - return; - } - CHECK_OBJ_NOTNULL(*pp, VSM_CHUNK_MAGIC); -} - -#define VSM_ITER(vd) for ((vd) = vsm_iter_0(); (vd) != NULL; vsm_iter_n(&vd)) - -#endif /* CHECK_OBJ_NOTNULL */ - -#endif From phk at varnish-cache.org Sun Oct 9 20:54:07 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 22:54:07 +0200 Subject: [master] 874655c Get the rest of the stuff in there too. Message-ID: commit 874655c0bd62f1be7b861b61012dc801cd59ddf8 Author: Poul-Henning Kamp Date: Sun Oct 9 20:53:57 2011 +0000 Get the rest of the stuff in there too. diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index 464924a..63ab6a3 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -29,6 +29,8 @@ #include "config.h" +#include "vapi/vsm_int.h" + #include #include @@ -40,7 +42,6 @@ #include "cache.h" -#include "vsm.h" #include "cache_backend.h" #include "cache_waiter.h" #include "vcl.h" diff --git a/bin/varnishd/cache_shmlog.c b/bin/varnishd/cache_shmlog.c index 75f662d..d16a744 100644 --- a/bin/varnishd/cache_shmlog.c +++ b/bin/varnishd/cache_shmlog.c @@ -29,11 +29,13 @@ #include "config.h" + #include #include "cache.h" + +#include "vapi/vsm_int.h" #include "vmb.h" -#include "vsm.h" #include "vtim.h" /* These cannot be struct lock, which depends on vsm/vsl working */ diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index e676f48..ac76594 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -43,7 +43,7 @@ #include #include "mgt.h" -#include "vsm.h" +#include "vapi/vsm_int.h" #include "heritage.h" #include "vcli.h" #include "cli_priv.h" diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index e42487a..8fa5cd9 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -101,7 +101,7 @@ #include "mgt.h" #include "heritage.h" #include "vmb.h" -#include "vsm.h" +#include "vapi/vsm_int.h" #include "vav.h" #include "vnum.h" #include "flopen.h" diff --git a/bin/varnishd/vsm.c b/bin/varnishd/vsm.c index d1717fe..bc44c21 100644 --- a/bin/varnishd/vsm.c +++ b/bin/varnishd/vsm.c @@ -55,7 +55,7 @@ #include "common.h" #include "vmb.h" -#include "vsm.h" +#include "vapi/vsm_int.h" #include "vtim.h" /* These two come from beyond (mgt_shmem.c actually) */ diff --git a/include/Makefile.am b/include/Makefile.am index 320f18c..948cef7 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,12 +16,12 @@ pkginclude_HEADERS = \ tbl/vsc_fields.h \ tbl/vsl_tags.h \ vapi/vsm.h \ + vapi/vsm_int.h \ vapi/vsc.h \ vapi/vsc_int.h \ vapi/vsl.h \ vapi/vsl_int.h \ - vcli.h \ - vsm.h + vcli.h nobase_noinst_HEADERS = \ binary_heap.h \ diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h index 98e8610..0055b73 100644 --- a/include/vapi/vsm_int.h +++ b/include/vapi/vsm_int.h @@ -31,13 +31,12 @@ * NB: THIS IS NOT A PUBLIC API TO VARNISH! */ -#ifndef VSM_H_INCLUDED -#define VSM_H_INCLUDED +#ifndef VSM_INT_H_INCLUDED +#define VSM_INT_H_INCLUDED #define VSM_FILENAME "_.vsm" -#include -#include +#include /* * This structure describes each allocation from the shmlog @@ -62,9 +61,9 @@ struct VSM_head { unsigned hdrsize; - time_t starttime; - pid_t master_pid; - pid_t child_pid; + uint64_t starttime; + int64_t master_pid; + int64_t child_pid; unsigned shm_size; @@ -107,6 +106,10 @@ vsm_iter_n(struct VSM_chunk **pp) #define VSM_ITER(vd) for ((vd) = vsm_iter_0(); (vd) != NULL; vsm_iter_n(&vd)) +#else + +#define VSM_ITER(vd) while (YOU_NEED_MINIOBJ_TO_USE_VSM_ITER) + #endif /* CHECK_OBJ_NOTNULL */ -#endif +#endif /* VSM_INT_H_INCLUDED */ diff --git a/lib/libvarnish/vin.c b/lib/libvarnish/vin.c index 65fdb5e..cd3e7d0 100644 --- a/lib/libvarnish/vin.c +++ b/lib/libvarnish/vin.c @@ -30,6 +30,8 @@ #include "config.h" +#include "vapi/vsm_int.h" + #include #include #include @@ -39,7 +41,6 @@ #include "vas.h" #include "vdef.h" #include "vin.h" -#include "vsm.h" int VIN_N_Arg(const char *n_arg, char **name, char **dir, char **vsl) diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index 74cf286..211d284 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -30,6 +30,7 @@ #include "config.h" #include "vapi/vsm.h" +#include "vapi/vsm_int.h" #include "vapi/vsc.h" #include @@ -39,7 +40,6 @@ #include "vas.h" #include "vav.h" -#include "vsm.h" #include "vqueue.h" #include "miniobj.h" diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index a2efc5d..9fa6a48 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -30,6 +30,7 @@ #include "config.h" #include "vapi/vsm.h" +#include "vapi/vsm_int.h" #include "vapi/vsl.h" #include @@ -41,7 +42,6 @@ #include #include "vas.h" -#include "vsm.h" #include "vre.h" #include "vbm.h" #include "miniobj.h" diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index 32d9e3d..eeb2b3c 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -30,6 +30,7 @@ #include "config.h" #include "vapi/vsm.h" +#include "vapi/vsm_int.h" #include #include @@ -45,7 +46,6 @@ #include "vas.h" #include "vin.h" -#include "vsm.h" #include "vbm.h" #include "miniobj.h" From phk at varnish-cache.org Sun Oct 9 21:03:05 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 23:03:05 +0200 Subject: [master] 4766dba Don't include config.h in .h files Message-ID: commit 4766dba945e95c5e110f6d625a10bd811836afa3 Author: Poul-Henning Kamp Date: Sun Oct 9 21:02:54 2011 +0000 Don't include config.h in .h files diff --git a/include/vbm.h b/include/vbm.h index 8443ac7..13d2d5f 100644 --- a/include/vbm.h +++ b/include/vbm.h @@ -29,8 +29,6 @@ * Self-sizeing bitmap operations */ -#include "config.h" - /********************************************************************** * Generic bitmap functions, may be generalized at some point. */ From phk at varnish-cache.org Sun Oct 9 21:20:37 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 23:20:37 +0200 Subject: [master] 8d05dae Typo Message-ID: commit 8d05daeb1a577269db075e7fdc269e43281b9e20 Author: Poul-Henning Kamp Date: Sun Oct 9 21:20:31 2011 +0000 Typo diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 3b6182f..a90d8b2 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -36,7 +36,7 @@ #include #include -#include +#include #ifdef HAVE_PRIV_H #include From phk at varnish-cache.org Sun Oct 9 21:58:44 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Sun, 09 Oct 2011 23:58:44 +0200 Subject: [master] 9d0ec2a Add necessary vas.h include Message-ID: commit 9d0ec2a1e58fff1fedcffc98f7955ca2110c0c2f Author: Poul-Henning Kamp Date: Sun Oct 9 21:58:33 2011 +0000 Add necessary vas.h include diff --git a/lib/libvarnish/vmb.c b/lib/libvarnish/vmb.c index aa069a7..e6b0f25 100644 --- a/lib/libvarnish/vmb.c +++ b/lib/libvarnish/vmb.c @@ -28,6 +28,7 @@ #include #include +#include "vas.h" #include "vmb.h" #ifdef VMB_NEEDS_PTHREAD_WORKAROUND_THIS_IS_BAD_FOR_PERFORMANCE From phk at varnish-cache.org Mon Oct 10 09:54:44 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 11:54:44 +0200 Subject: [master] 8aa1d8b Eliminate nested <*.h> includes from include/* Message-ID: commit 8aa1d8b8b87e009ae06f3cfed452bf8c6594b931 Author: Poul-Henning Kamp Date: Mon Oct 10 09:53:50 2011 +0000 Eliminate nested <*.h> includes from include/* Sort #includes according to rules which are for me to know and you to guess. diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index b857f8a..e519b01 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -29,23 +29,25 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" +#include + +#ifdef HAVE_LIBEDIT +#include +#endif +#include #include #include +#include #include #include -#include #include -#include - -#ifdef HAVE_LIBEDIT -#include -#endif +#include #include "vcli.h" #include "cli_common.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vss.h" diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index c5bc614..41efdad 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -34,6 +34,8 @@ */ #define VARNISH_CACHE_CHILD 1 +#include "common.h" + #include "vapi/vsc_int.h" #include "vapi/vsl_int.h" @@ -53,7 +55,6 @@ #include #endif -#include "common.h" #include "heritage.h" diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index 4feefb6..80d7b81 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -32,10 +32,10 @@ #include "cache.h" +#include "cli_priv.h" #include "vcli.h" #include "vtcp.h" #include "vtim.h" -#include "cli_priv.h" static pthread_t VCA_thread; static struct timeval tv_sndtimeo; diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c index 3ed7fcd..0026259 100644 --- a/bin/varnishd/cache_backend.c +++ b/bin/varnishd/cache_backend.c @@ -32,8 +32,8 @@ #include "config.h" -#include #include +#include #include "cache.h" diff --git a/bin/varnishd/cache_backend_cfg.c b/bin/varnishd/cache_backend_cfg.c index e08e09e..2e6d83c 100644 --- a/bin/varnishd/cache_backend_cfg.c +++ b/bin/varnishd/cache_backend_cfg.c @@ -36,9 +36,10 @@ #include #include "cache.h" -#include "vrt.h" + #include "cache_backend.h" #include "cli_priv.h" +#include "vrt.h" struct lock VBE_mtx; diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index c9497bb..a0ad62b 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -37,17 +37,18 @@ #include "config.h" -#include #include -#include #include +#include +#include -#include "cli_priv.h" #include "cache.h" + +#include "cache_backend.h" +#include "cli_priv.h" #include "vrt.h" #include "vtcp.h" #include "vtim.h" -#include "cache_backend.h" /* Default averaging rate, we want something pretty responsive */ #define AVG_RATE 4 diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index 8396c7f..bec8d85 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -62,17 +62,16 @@ #include "config.h" -#include - #include +#include #include "cache.h" +#include "cli_priv.h" +#include "hash_slinger.h" #include "vcli.h" #include "vend.h" #include "vtim.h" -#include "cli_priv.h" -#include "hash_slinger.h" struct ban { unsigned magic; diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 6ab8a11..ba61e9c 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -57,25 +57,25 @@ DOT acceptor -> start [style=bold,color=green] #include "config.h" -#include #include #include #include +#include #include -#ifndef HAVE_SRANDOMDEV -#include "compat/srandomdev.h" -#endif - #include "cache.h" -#include "vcl.h" -#include "vtcp.h" -#include "vtim.h" #include "cli_priv.h" #include "hash_slinger.h" #include "stevedore.h" +#include "vcl.h" #include "vsha256.h" +#include "vtcp.h" +#include "vtim.h" + +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif static unsigned xids; diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index 3635aec..f66075e 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -41,8 +41,8 @@ #include "cache.h" #include "vcli.h" -#include "cli_priv.h" #include "cli_common.h" +#include "cli_priv.h" #include "cli_serve.h" #include "hash_slinger.h" // objhead diff --git a/bin/varnishd/cache_dir.c b/bin/varnishd/cache_dir.c index ef882bf..3fd0475 100644 --- a/bin/varnishd/cache_dir.c +++ b/bin/varnishd/cache_dir.c @@ -33,6 +33,7 @@ #include "config.h" #include "cache.h" + #include "cache_backend.h" #include "vtcp.h" diff --git a/bin/varnishd/cache_dir_dns.c b/bin/varnishd/cache_dir_dns.c index 3fd2aa1..acb3689 100644 --- a/bin/varnishd/cache_dir_dns.c +++ b/bin/varnishd/cache_dir_dns.c @@ -29,14 +29,15 @@ #include "config.h" +#include + #include -#include #include - #include -#include +#include #include "cache.h" + #include "cache_backend.h" #include "vrt.h" diff --git a/bin/varnishd/cache_dir_random.c b/bin/varnishd/cache_dir_random.c index f05d8f4..f18c7d7 100644 --- a/bin/varnishd/cache_dir_random.c +++ b/bin/varnishd/cache_dir_random.c @@ -50,10 +50,11 @@ #include #include "cache.h" + #include "cache_backend.h" +#include "vend.h" #include "vrt.h" #include "vsha256.h" -#include "vend.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache_dir_round_robin.c b/bin/varnishd/cache_dir_round_robin.c index 9d0a257..7d75473 100644 --- a/bin/varnishd/cache_dir_round_robin.c +++ b/bin/varnishd/cache_dir_round_robin.c @@ -32,6 +32,7 @@ #include #include "cache.h" + #include "cache_backend.h" #include "vrt.h" diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index 063464a..f7daeeb 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -30,10 +30,11 @@ #include "config.h" -#include #include +#include #include "cache.h" + #include "cache_esi.h" #include "vend.h" #include "vgz.h" diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index cac2eb6..b6ef527 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -33,9 +33,10 @@ #include #include "cache.h" + #include "cache_esi.h" -#include "vct.h" #include "stevedore.h" +#include "vct.h" /*--------------------------------------------------------------------- * Read some bytes. diff --git a/bin/varnishd/cache_esi_parse.c b/bin/varnishd/cache_esi_parse.c index c659dd5..37c20e7 100644 --- a/bin/varnishd/cache_esi_parse.c +++ b/bin/varnishd/cache_esi_parse.c @@ -34,9 +34,10 @@ #include #include "cache.h" + #include "cache_esi.h" -#include "vend.h" #include "vct.h" +#include "vend.h" #include "vgz.h" //#define Debug(fmt, ...) printf(fmt, __VA_ARGS__) diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index aed6807..8e18cb5 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -53,8 +53,9 @@ #include -#include "binary_heap.h" #include "cache.h" + +#include "binary_heap.h" #include "hash_slinger.h" #include "stevedore.h" #include "vtim.h" diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index d18e726..4bbc272 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -29,14 +29,15 @@ #include "config.h" -#include +#include #include +#include #include -#include #include "cache.h" -#include "stevedore.h" + #include "cli_priv.h" +#include "stevedore.h" #include "vct.h" #include "vtcp.h" diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 28d61d9..156ac52 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -65,6 +65,7 @@ */ #include "config.h" + #include #include diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 4001c7c..67aa3af 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -52,17 +52,18 @@ #include "config.h" +#include #include #include -#include #include #include "cache.h" -#include "stevedore.h" + +#include "cache_backend.h" #include "hash_slinger.h" -#include "vsha256.h" +#include "stevedore.h" #include "vav.h" -#include "cache_backend.h" +#include "vsha256.h" static const struct hash_slinger *hash; diff --git a/bin/varnishd/cache_main.c b/bin/varnishd/cache_main.c index b4ee185..54d71f8 100644 --- a/bin/varnishd/cache_main.c +++ b/bin/varnishd/cache_main.c @@ -34,9 +34,9 @@ #include "cache.h" -#include "stevedore.h" -#include "hash_slinger.h" #include "cache_waiter.h" +#include "hash_slinger.h" +#include "stevedore.h" /*-------------------------------------------------------------------- * Per thread storage for the session currently being processed by diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index 63ab6a3..482708d 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -29,23 +29,23 @@ #include "config.h" -#include "vapi/vsm_int.h" - -#include -#include - #ifndef HAVE_EXECINFO_H #include "compat/execinfo.h" #else #include #endif +#include +#include + #include "cache.h" +#include "vapi/vsm_int.h" + #include "cache_backend.h" #include "cache_waiter.h" -#include "vcl.h" #include "libvcl.h" +#include "vcl.h" /* * The panic string is constructed in memory, then copied to the diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index 418ded1..c9bc0ac 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -31,10 +31,11 @@ #include "config.h" -#include #include +#include #include "cache.h" + #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index b4459da..bacf906 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -36,6 +36,7 @@ #include #include "cache.h" + #include "stevedore.h" #include "vct.h" #include "vtim.h" diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c index bb96780..d55bae0 100644 --- a/bin/varnishd/cache_session.c +++ b/bin/varnishd/cache_session.c @@ -35,10 +35,11 @@ #include "config.h" -#include #include +#include #include "cache.h" + #include "cache_waiter.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache_shmlog.c b/bin/varnishd/cache_shmlog.c index d16a744..da39e2d 100644 --- a/bin/varnishd/cache_shmlog.c +++ b/bin/varnishd/cache_shmlog.c @@ -29,7 +29,6 @@ #include "config.h" - #include #include "cache.h" diff --git a/bin/varnishd/cache_vary.c b/bin/varnishd/cache_vary.c index 4440d55..c528fb8 100644 --- a/bin/varnishd/cache_vary.c +++ b/bin/varnishd/cache_vary.c @@ -56,8 +56,8 @@ #include "cache.h" -#include "vend.h" #include "vct.h" +#include "vend.h" struct vsb * VRY_Create(const struct sess *sp, const struct http *hp) diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c index 99364b5..48568ff 100644 --- a/bin/varnishd/cache_vcl.c +++ b/bin/varnishd/cache_vcl.c @@ -33,15 +33,16 @@ #include "config.h" +#include #include #include -#include #include "cache.h" -#include "vcli.h" + #include "cli_priv.h" -#include "vcl.h" #include "libvcl.h" +#include "vcl.h" +#include "vcli.h" struct vcls { unsigned magic; diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index 5c633e2..2302b86 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -39,13 +39,13 @@ #include "cache.h" -#include "vrt.h" -#include "vrt_obj.h" +#include "cache_backend.h" +#include "hash_slinger.h" #include "vav.h" #include "vcl.h" +#include "vrt.h" +#include "vrt_obj.h" #include "vtim.h" -#include "hash_slinger.h" -#include "cache_backend.h" const void * const vrt_magic_string_end = &vrt_magic_string_end; diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c index d28510f..d9a7090 100644 --- a/bin/varnishd/cache_vrt_re.c +++ b/bin/varnishd/cache_vrt_re.c @@ -36,8 +36,8 @@ #include "cache.h" -#include "vrt.h" #include "vre.h" +#include "vrt.h" void VRT_re_init(void **rep, const char *re) diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index ff523df..a00b1b7 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -35,12 +35,12 @@ #include "cache.h" +#include "cache_backend.h" +#include "hash_slinger.h" #include "vrt.h" +#include "vrt_obj.h" #include "vtcp.h" #include "vtim.h" -#include "vrt_obj.h" -#include "cache_backend.h" -#include "hash_slinger.h" static char vrt_hostname[255] = ""; diff --git a/bin/varnishd/cache_vrt_vmod.c b/bin/varnishd/cache_vrt_vmod.c index 4eb3e84..bb4eeb8 100644 --- a/bin/varnishd/cache_vrt_vmod.c +++ b/bin/varnishd/cache_vrt_vmod.c @@ -31,8 +31,8 @@ #include "config.h" -#include #include +#include #include "cache.h" diff --git a/bin/varnishd/cache_waiter.c b/bin/varnishd/cache_waiter.c index cd3e007..08c5809 100644 --- a/bin/varnishd/cache_waiter.c +++ b/bin/varnishd/cache_waiter.c @@ -30,10 +30,11 @@ #include "config.h" -#include "vcli.h" -#include "cli_priv.h" #include "cache.h" + #include "cache_waiter.h" +#include "cli_priv.h" +#include "vcli.h" static const struct waiter * const vca_waiters[] = { #if defined(HAVE_KQUEUE) diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c index c66d15a..3eaa627 100644 --- a/bin/varnishd/cache_waiter_epoll.c +++ b/bin/varnishd/cache_waiter_epoll.c @@ -35,12 +35,14 @@ #if defined(HAVE_EPOLL_CTL) +#include + #include #include #include -#include #include "cache.h" + #include "cache_waiter.h" #include "vtim.h" diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c index e7cb299..a81f4c2 100644 --- a/bin/varnishd/cache_waiter_kqueue.c +++ b/bin/varnishd/cache_waiter_kqueue.c @@ -35,13 +35,16 @@ #if defined(HAVE_KQUEUE) +#include +#include + #include #include #include #include -#include #include "cache.h" + #include "cache_waiter.h" #include "vtim.h" diff --git a/bin/varnishd/cache_waiter_poll.c b/bin/varnishd/cache_waiter_poll.c index f3f3289..eb48870 100644 --- a/bin/varnishd/cache_waiter_poll.c +++ b/bin/varnishd/cache_waiter_poll.c @@ -30,8 +30,8 @@ #include "config.h" -#include #include +#include #include "cache.h" diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c index ca7e229..2e02406 100644 --- a/bin/varnishd/cache_waiter_ports.c +++ b/bin/varnishd/cache_waiter_ports.c @@ -33,15 +33,16 @@ #if defined(HAVE_PORT_CREATE) -#include +#include + #include -#include #include - #include -#include +#include +#include #include "cache.h" + #include "cache_waiter.h" #include "vtim.h" diff --git a/bin/varnishd/cache_wrk.c b/bin/varnishd/cache_wrk.c index 7e80f04..1032691 100644 --- a/bin/varnishd/cache_wrk.c +++ b/bin/varnishd/cache_wrk.c @@ -35,6 +35,7 @@ #include #include "cache.h" + #include "hash_slinger.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c index 5f9c29b..4fef1aa 100644 --- a/bin/varnishd/cache_wrw.c +++ b/bin/varnishd/cache_wrw.c @@ -34,21 +34,21 @@ #include "config.h" -#include #include -#include - #ifdef SENDFILE_WORKS -#if defined(__FreeBSD__) || defined(__DragonFly__) - // We're fine -#elif defined(__linux__) -# include -#elif defined(__sun) -# include -#else -# error Unknown sendfile() implementation -#endif +# if defined(__FreeBSD__) || defined(__DragonFly__) +# include +# elif defined(__linux__) +# include +# elif defined(__sun) +# include +# else +# error Unknown sendfile() implementation +# endif #endif /* SENDFILE_WORKS */ +#include + +#include #include "cache.h" diff --git a/bin/varnishd/common.h b/bin/varnishd/common.h index 7fd15b7..13249eb 100644 --- a/bin/varnishd/common.h +++ b/bin/varnishd/common.h @@ -28,6 +28,11 @@ * */ +#include +#include + +#include + #include "miniobj.h" #include "vas.h" #include "vcs.h" @@ -73,8 +78,8 @@ const void *pick(const struct choice *cp, const char *which, const char *kind); #define NEEDLESS_RETURN(foo) return (foo) /* vsm.c */ -extern struct VSM_head *VSM_head; -extern const struct VSM_chunk *vsm_end; +// extern struct VSM_head *VSM_head; +// extern const struct VSM_chunk *vsm_end; /* * These three should not be called directly, but only through diff --git a/bin/varnishd/hash_classic.c b/bin/varnishd/hash_classic.c index 9b8c7d8..1428864 100644 --- a/bin/varnishd/hash_classic.c +++ b/bin/varnishd/hash_classic.c @@ -31,12 +31,14 @@ #include "config.h" +#include + #include #include #include -#include #include "cache.h" + #include "hash_slinger.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/hash_critbit.c b/bin/varnishd/hash_critbit.c index e5b0746..add2397 100644 --- a/bin/varnishd/hash_critbit.c +++ b/bin/varnishd/hash_critbit.c @@ -28,15 +28,16 @@ * A Crit Bit tree based hash */ -#undef PHK +// #define PHK #include "config.h" #include #include "cache.h" -#include "hash_slinger.h" + #include "cli_priv.h" +#include "hash_slinger.h" #include "vmb.h" #include "vtim.h" diff --git a/bin/varnishd/hash_simple_list.c b/bin/varnishd/hash_simple_list.c index 13cf0ee..c1c17da 100644 --- a/bin/varnishd/hash_simple_list.c +++ b/bin/varnishd/hash_simple_list.c @@ -32,6 +32,7 @@ #include "config.h" #include "cache.h" + #include "hash_slinger.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index ac76594..7338e6c 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -31,27 +31,30 @@ #include "config.h" -#include -#include -#include +#include +#include + +#include #include -#include +#include #include +#include +#include +#include #include -#include -#include -#include +#include #include "mgt.h" -#include "vapi/vsm_int.h" -#include "heritage.h" -#include "vcli.h" + #include "cli_priv.h" +#include "heritage.h" #include "mgt_cli.h" +#include "vapi/vsm_int.h" +#include "vbm.h" +#include "vcli.h" #include "vev.h" #include "vlu.h" #include "vss.h" -#include "vbm.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index 4488d51..4a7925a 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -31,32 +31,33 @@ #include "config.h" +#include + +#include +#include #include #include -#include #include -#include #include +#include #include -#include -#ifndef HAVE_SRANDOMDEV -#include "compat/srandomdev.h" -#endif +#include "mgt.h" -#include "cli_priv.h" #include "vcli.h" #include "cli_common.h" +#include "cli_priv.h" #include "cli_serve.h" +#include "heritage.h" +#include "mgt_cli.h" #include "vev.h" #include "vlu.h" #include "vss.h" #include "vtcp.h" - -#include "mgt.h" -#include "heritage.h" -#include "mgt_cli.h" +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif static int cli_i = -1, cli_o = -1; static struct VCLS *cls; diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index f849fbb..4bb1adf 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -37,17 +37,16 @@ #include #include -#include "vcli.h" -#include "cli_priv.h" -#include "cli_common.h" #include "mgt.h" -#include "mgt_cli.h" -#include "heritage.h" -#include "vparam.h" +#include "vcli.h" #include "cache_waiter.h" - +#include "cli_common.h" +#include "cli_priv.h" +#include "heritage.h" +#include "mgt_cli.h" #include "vav.h" +#include "vparam.h" #include "vss.h" #define MAGIC_INIT_STRING "\001" diff --git a/bin/varnishd/mgt_pool.c b/bin/varnishd/mgt_pool.c index 4b3fe92..489fab8 100644 --- a/bin/varnishd/mgt_pool.c +++ b/bin/varnishd/mgt_pool.c @@ -42,15 +42,15 @@ #include "config.h" +#include #include #include -#include #include #include "mgt.h" -#include "vparam.h" #include "heritage.h" +#include "vparam.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/mgt_sandbox.c b/bin/varnishd/mgt_sandbox.c index 94f9f4d..3aba7cc 100644 --- a/bin/varnishd/mgt_sandbox.c +++ b/bin/varnishd/mgt_sandbox.c @@ -44,15 +44,16 @@ #include "config.h" -#include -#include -#include - #ifdef __linux__ #include #endif +#include +#include +#include + #include "mgt.h" + #include "heritage.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index a90d8b2..5c50c83 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -34,15 +34,15 @@ #ifdef HAVE_SETPPRIV -#include -#include -#include - #ifdef HAVE_PRIV_H #include #endif +#include +#include +#include #include "mgt.h" + #include "heritage.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c index 8fa5cd9..ae0a50d 100644 --- a/bin/varnishd/mgt_shmem.c +++ b/bin/varnishd/mgt_shmem.c @@ -86,25 +86,27 @@ #include "config.h" -#include "vapi/vsl_int.h" -#include "vapi/vsc_int.h" +#include +#include +#include #include +#include #include #include -#include -#include #include -#include -#include +#include #include "mgt.h" + +#include "flopen.h" #include "heritage.h" -#include "vmb.h" +#include "vapi/vsc_int.h" +#include "vapi/vsl_int.h" #include "vapi/vsm_int.h" #include "vav.h" +#include "vmb.h" #include "vnum.h" -#include "flopen.h" #ifndef MAP_HASSEMAPHORE #define MAP_HASSEMAPHORE 0 /* XXX Linux */ diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index df46c41..78a29dd 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -40,13 +40,13 @@ #include "mgt.h" +#include "cli_priv.h" #include "libvcl.h" -#include "vcli.h" -#include "vsub.h" +#include "mgt_cli.h" #include "vcl.h" +#include "vcli.h" #include "vfil.h" -#include "cli_priv.h" -#include "mgt_cli.h" +#include "vsub.h" struct vclprog { VTAILQ_ENTRY(vclprog) list; diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c index 6de52e2..d4d5a05 100644 --- a/bin/varnishd/rfc2616.c +++ b/bin/varnishd/rfc2616.c @@ -29,10 +29,11 @@ #include "config.h" -#include #include +#include #include "cache.h" + #include "vtim.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index 6d71635..538ae27 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -37,9 +37,11 @@ #include #include "cache.h" + +#include "cli_priv.h" #include "stevedore.h" #include "vav.h" -#include "cli_priv.h" +#include "vrt.h" #include "vrt_obj.h" static VTAILQ_HEAD(, stevedore) stevedores = @@ -560,8 +562,6 @@ struct cli_proto cli_stv[] = { * VRT functions for stevedores */ -#include "vrt.h" - static const struct stevedore * stv_find(const char *nm) { diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c index 725a086..42c2b47 100644 --- a/bin/varnishd/stevedore_utils.c +++ b/bin/varnishd/stevedore_utils.c @@ -31,27 +31,26 @@ #include "config.h" -#include -#include -#include -#include -#include #include #include - #ifdef HAVE_SYS_MOUNT_H -#include +# include #endif - #ifdef HAVE_SYS_STATVFS_H -#include +# include #endif - #ifdef HAVE_SYS_VFS_H -#include +# include #endif +#include +#include +#include +#include +#include + #include "mgt.h" + #include "stevedore.h" #include "vnum.h" diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index 25c9947..171d9d0 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -32,6 +32,7 @@ #include "config.h" #include + #include #include diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index 3ba7061..18b96c3 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -35,22 +35,24 @@ #include "config.h" -#include +#include +#include + #include +#include #include #include -#include -#include #include "cache.h" -#include "stevedore.h" + +#include "cli_priv.h" #include "hash_slinger.h" -#include "vsha256.h" +#include "persistent.h" +#include "stevedore.h" #include "vcli.h" -#include "cli_priv.h" #include "vend.h" +#include "vsha256.h" -#include "persistent.h" #include "storage_persistent.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/storage_persistent_mgt.c b/bin/varnishd/storage_persistent_mgt.c index c91fb43..7ec9089 100644 --- a/bin/varnishd/storage_persistent_mgt.c +++ b/bin/varnishd/storage_persistent_mgt.c @@ -35,12 +35,14 @@ #include "config.h" +#include + #include #include #include -#include #include "cache.h" + #include "stevedore.h" #include "vsha256.h" diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c index 2defc0d..be2e2bf 100644 --- a/bin/varnishd/storage_persistent_silo.c +++ b/bin/varnishd/storage_persistent_silo.c @@ -38,8 +38,9 @@ #include #include "cache.h" -#include "stevedore.h" + #include "hash_slinger.h" +#include "stevedore.h" #include "vsha256.h" #include "vtim.h" diff --git a/bin/varnishd/storage_persistent_subr.c b/bin/varnishd/storage_persistent_subr.c index 6fad388..e3df368 100644 --- a/bin/varnishd/storage_persistent_subr.c +++ b/bin/varnishd/storage_persistent_subr.c @@ -35,12 +35,14 @@ #include "config.h" +#include + +#include #include #include -#include -#include #include "cache.h" + #include "vsha256.h" #include "persistent.h" diff --git a/bin/varnishd/storage_umem.c b/bin/varnishd/storage_umem.c index 197d0ac..4459a47 100644 --- a/bin/varnishd/storage_umem.c +++ b/bin/varnishd/storage_umem.c @@ -37,11 +37,10 @@ #include #include - #include -#include "config.h" #include "cache.h" + #include "stevedore.h" static size_t smu_max = SIZE_MAX; diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 9ba9570..7cecfe4 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -32,6 +32,7 @@ #include "config.h" #include +#include #include #include @@ -43,25 +44,22 @@ #include #include -#include - -#include "compat/daemon.h" - -#include "vev.h" -#include "vpf.h" -#include "vsha256.h" +#include "mgt.h" #include "vcli.h" #include "cli_common.h" - +#include "hash_slinger.h" +#include "heritage.h" +#include "stevedore.h" #include "vav.h" -#include "vin.h" +#include "vev.h" #include "vfil.h" +#include "vin.h" +#include "vpf.h" +#include "vsha256.h" #include "vtim.h" -#include "heritage.h" -#include "mgt.h" -#include "hash_slinger.h" -#include "stevedore.h" + +#include "compat/daemon.h" #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" diff --git a/bin/varnishd/vsm.c b/bin/varnishd/vsm.c index bc44c21..5298381 100644 --- a/bin/varnishd/vsm.c +++ b/bin/varnishd/vsm.c @@ -54,8 +54,8 @@ #include "common.h" -#include "vmb.h" #include "vapi/vsm_int.h" +#include "vmb.h" #include "vtim.h" /* These two come from beyond (mgt_shmem.c actually) */ diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index e2fc652..6d68a5d 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -32,10 +32,8 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include + #include #include #include @@ -48,6 +46,8 @@ #include #include +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index 86c8504..e6c4bf8 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -31,9 +31,6 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include #include #include @@ -42,13 +39,15 @@ #include #include -#include "compat/daemon.h" - +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" #include "vpf.h" #include "vsb.h" +#include "compat/daemon.h" + static int b_flag, c_flag; /* Ordering-----------------------------------------------------------*/ diff --git a/bin/varnishncsa/base64.c b/bin/varnishncsa/base64.c index 3758604..ee1a87b 100644 --- a/bin/varnishncsa/base64.c +++ b/bin/varnishncsa/base64.c @@ -6,11 +6,13 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include + +#include // for test-prog + #include "base64.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -62,7 +64,6 @@ VB64_decode(char *d, unsigned dlen, const char *s) } #ifdef TEST_DRIVER -#include const char *test1 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 05b8dfe..97a3642 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -59,20 +59,19 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include +#include #include #include #include #include #include -#include #include +#include -#include "compat/daemon.h" - +#include "base64.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" #include "vpf.h" @@ -80,7 +79,7 @@ #include "vre.h" #include "vsb.h" -#include "base64.h" +#include "compat/daemon.h" static volatile sig_atomic_t reopen; diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index ffc403f..77758eb 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -28,9 +28,6 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include #include #include @@ -39,13 +36,15 @@ #include #include #include -#include #include +#include #include #include #include #include +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" #include "vqueue.h" diff --git a/bin/varnishsizes/varnishsizes.c b/bin/varnishsizes/varnishsizes.c index d3e3218..a78be9b 100644 --- a/bin/varnishsizes/varnishsizes.c +++ b/bin/varnishsizes/varnishsizes.c @@ -32,10 +32,8 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include + #include #include #include @@ -48,6 +46,8 @@ #include #include +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index b160a26..3c6c4b5 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -32,9 +32,6 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsc.h" - #include #include @@ -46,6 +43,7 @@ #include "varnishstat.h" + /*--------------------------------------------------------------------*/ static int diff --git a/bin/varnishstat/varnishstat.h b/bin/varnishstat/varnishstat.h index 314c7c5..0a5d80f 100644 --- a/bin/varnishstat/varnishstat.h +++ b/bin/varnishstat/varnishstat.h @@ -27,7 +27,13 @@ * */ +#include + +#include "vapi/vsm.h" +#include "vapi/vsc.h" + #include "vas.h" #include "vcs.h" + void do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main, int delay); diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c index 1e93155..9fa6b82 100644 --- a/bin/varnishstat/varnishstat_curses.c +++ b/bin/varnishstat/varnishstat_curses.c @@ -32,15 +32,16 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsc.h" - #include #ifdef HAVE_NCURSES_CURSES_H -#include -#elif HAVE_CURSES_H -#include +# include +#endif + +#ifndef HAVE_NCURSES_CURSES_H +# ifdef HAVE_CURSES_H +# include +# endif #endif #include #include @@ -50,9 +51,12 @@ #include #include -#include "vqueue.h" #include "varnishstat.h" +#include "vapi/vsc.h" +#include "vapi/vsm.h" +#include "vqueue.h" + #if 0 #define AC(x) assert((x) != ERR) #else diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 5c6bbfd..b496f9e 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -28,14 +28,15 @@ #include "config.h" +#include +#include + #include #include #include #include #include #include -#include -#include #include #include "vtc.h" diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 1340314..6093656 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -27,6 +27,7 @@ * */ +#include #include #include #include diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 2547d80..7eb430f 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -28,13 +28,13 @@ #include "config.h" +#include +#include + #include #include #include -#include -#include - #include "vtc.h" #include "vss.h" diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 889891b..698ffb0 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -28,17 +28,18 @@ #include "config.h" -#include -#include +#include +#include + #include +#include #include +#include -#include -#include +#include "vtc.h" #include "vct.h" #include "vgz.h" -#include "vtc.h" #include "vtcp.h" #define MAX_HDR 50 diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 753de58..d6d15c1 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -28,12 +28,13 @@ #include "config.h" +#include #include -#include #include -#include +#include #include "vtc.h" + #include "vtim.h" static pthread_mutex_t vtclog_mtx; diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 3b9d81b..fb1c42e 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -28,18 +28,22 @@ #include "config.h" -#include -#include -#include -#include -#include #include #include #include #include -#include "vev.h" +#include +#include +#include +#include +#include +#include + #include "vtc.h" + +#include "vev.h" +#include "vqueue.h" #include "vtim.h" #ifndef HAVE_SRANDOMDEV diff --git a/bin/varnishtest/vtc_sema.c b/bin/varnishtest/vtc_sema.c index c363b4a..48d4c68 100644 --- a/bin/varnishtest/vtc_sema.c +++ b/bin/varnishtest/vtc_sema.c @@ -30,8 +30,8 @@ #include #include -#include #include +#include #include "vtc.h" diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 5a768a1..75c4f30 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -28,16 +28,17 @@ #include "config.h" -#include +#include +#include + #include +#include #include #include -#include -#include +#include "vtc.h" #include "vss.h" -#include "vtc.h" #include "vtcp.h" struct server { diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index ba19464..87b9423 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -28,26 +28,25 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsc.h" -#include "vapi/vsl.h" - -#include +#include +#include +#include #include +#include +#include +#include #include -#include #include -#include -#include +#include -#include -#include -#include +#include "vtc.h" +#include "vapi/vsc.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vcli.h" #include "vss.h" -#include "vtc.h" #include "vtcp.h" struct varnish { diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 34278ea..07070c8 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -32,20 +32,19 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include #include #include +#include #include #include #include #include #include #include -#include +#include "vapi/vsl.h" +#include "vapi/vsm.h" #include "vas.h" #include "vcs.h" #include "vqueue.h" diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h index 1101e53..bc52d65 100644 --- a/include/vapi/vsc.h +++ b/include/vapi/vsc.h @@ -33,6 +33,8 @@ #include "vapi/vsc_int.h" +struct VSM_data; + /*--------------------------------------------------------------------- * VSC level access functions */ diff --git a/include/vapi/vsc_int.h b/include/vapi/vsc_int.h index 0a9cbf9..6ceb723 100644 --- a/include/vapi/vsc_int.h +++ b/include/vapi/vsc_int.h @@ -28,8 +28,6 @@ * */ -#include - #define VSC_CLASS "Stat" #define VSC_TYPE_MAIN "" diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h index 5068f1c..9c9a4c9 100644 --- a/include/vapi/vsl.h +++ b/include/vapi/vsl.h @@ -31,10 +31,10 @@ #ifndef VAPI_VSL_H_INCLUDED #define VAPI_VSL_H_INCLUDED -#include - #include "vapi/vsl_int.h" +struct VSM_data; + /*--------------------------------------------------------------------- * VSL level access functions */ diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h index 0b7cdd8..fd7fbee 100644 --- a/include/vapi/vsm.h +++ b/include/vapi/vsm.h @@ -31,6 +31,9 @@ #ifndef VAPI_VSM_H_INCLUDED #define VAPI_VSM_H_INCLUDED +struct VSM_head; +struct VSM_data; + /*--------------------------------------------------------------------- * VSM level access functions */ diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h index 0055b73..3554982 100644 --- a/include/vapi/vsm_int.h +++ b/include/vapi/vsm_int.h @@ -36,8 +36,6 @@ #define VSM_FILENAME "_.vsm" -#include - /* * This structure describes each allocation from the shmlog */ @@ -81,6 +79,9 @@ struct VSM_head { */ #ifdef CHECK_OBJ_NOTNULL +extern struct VSM_head *VSM_head; +extern const struct VSM_chunk *vsm_end; + static inline struct VSM_chunk * vsm_iter_0(void) { diff --git a/include/vas.h b/include/vas.h index a4c9c6f..ff20036 100644 --- a/include/vas.h +++ b/include/vas.h @@ -38,8 +38,6 @@ #ifndef VAS_H_INCLUDED #define VAS_H_INCLUDED -#include - typedef void vas_f(const char *, const char *, int, const char *, int, int); extern vas_f *VAS_Fail; diff --git a/include/vct.h b/include/vct.h index fb4c2af..52530a6 100644 --- a/include/vct.h +++ b/include/vct.h @@ -28,8 +28,6 @@ * */ -#include - /* from libvarnish/vct.c */ #define VCT_SP (1<<0) diff --git a/include/vev.h b/include/vev.h index 60737bf..37db60f 100644 --- a/include/vev.h +++ b/include/vev.h @@ -28,10 +28,6 @@ * */ -#include - -#include "vqueue.h" - struct vev; struct vev_base; diff --git a/include/vnum.h b/include/vnum.h index a821355..cf55c9a 100644 --- a/include/vnum.h +++ b/include/vnum.h @@ -28,7 +28,5 @@ * */ -#include - /* from libvarnish/vnum.c */ const char *VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel); diff --git a/include/vsb.h b/include/vsb.h index 5bfbce7..0a8e2bf 100644 --- a/include/vsb.h +++ b/include/vsb.h @@ -31,8 +31,6 @@ #ifndef VSB_H_INCLUDED #define VSB_H_INCLUDED -#include - /* * Structure definition */ diff --git a/include/vsha256.h b/include/vsha256.h index 66811d3..bf42c11 100644 --- a/include/vsha256.h +++ b/include/vsha256.h @@ -29,8 +29,6 @@ #ifndef _SHA256_H_ #define _SHA256_H_ -#include - #define SHA256_LEN 32 typedef struct SHA256Context { diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c index 4b0edc3..ed99f13 100644 --- a/lib/libvarnish/binary_heap.c +++ b/lib/libvarnish/binary_heap.c @@ -35,12 +35,15 @@ #include "config.h" +#include #include #include +#include // for testcase #include #include #include "binary_heap.h" +#include "miniobj.h" // for testcase #include "vas.h" /* Parameters --------------------------------------------------------*/ @@ -455,8 +458,6 @@ binheap_reorder(const struct binheap *bh, unsigned idx) #ifdef TEST_DRIVER /* Test driver -------------------------------------------------------*/ -#include -#include "miniobj.h" static void vasfail(const char *func, const char *file, int line, diff --git a/lib/libvarnish/cli_auth.c b/lib/libvarnish/cli_auth.c index da0a241..396a127 100644 --- a/lib/libvarnish/cli_auth.c +++ b/lib/libvarnish/cli_auth.c @@ -29,6 +29,8 @@ #include "config.h" #include + +#include #include #include diff --git a/lib/libvarnish/cli_common.c b/lib/libvarnish/cli_common.c index e423da4..cb4e8af 100644 --- a/lib/libvarnish/cli_common.c +++ b/lib/libvarnish/cli_common.c @@ -43,13 +43,11 @@ #include #include -#include "vsb.h" - -#include "vas.h" - #include "vcli.h" -#include "cli_priv.h" #include "cli_common.h" +#include "cli_priv.h" +#include "vas.h" +#include "vsb.h" /*lint -e{818} cli could be const */ void diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index 13b9663..2c3a09c 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -32,23 +32,25 @@ #include "config.h" #include +#include #include -#include -#include #include +#include +#include #include #include +#include "miniobj.h" #include "vas.h" -#include "vqueue.h" -#include "vsb.h" -#include "vav.h" -#include "vlu.h" + #include "vcli.h" -#include "cli_priv.h" #include "cli_common.h" +#include "cli_priv.h" #include "cli_serve.h" -#include "miniobj.h" +#include "vav.h" +#include "vlu.h" +#include "vqueue.h" +#include "vsb.h" struct VCLS_func { unsigned magic; diff --git a/lib/libvarnish/vav.c b/lib/libvarnish/vav.c index a0c57bb..24b16b7 100644 --- a/lib/libvarnish/vav.c +++ b/lib/libvarnish/vav.c @@ -39,8 +39,9 @@ #include "config.h" #include -#include +#include #include +#include #include #include "vas.h" diff --git a/lib/libvarnish/vct.c b/lib/libvarnish/vct.c index 2740aa1..f0e1635 100644 --- a/lib/libvarnish/vct.c +++ b/lib/libvarnish/vct.c @@ -31,6 +31,7 @@ #include "config.h" #include + #include "vct.h" /* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */ diff --git a/lib/libvarnish/vev.c b/lib/libvarnish/vev.c index 004ce08..87d1582 100644 --- a/lib/libvarnish/vev.c +++ b/lib/libvarnish/vev.c @@ -29,20 +29,22 @@ #include "config.h" -#include #include #include -#include +#include #include -#include +#include #include -#include +#include +#include -#include "vas.h" -#include "vtim.h" -#include "vev.h" #include "miniobj.h" +#include "vas.h" + #include "binary_heap.h" +#include "vqueue.h" +#include "vev.h" +#include "vtim.h" #undef DEBUG_EVENTS diff --git a/lib/libvarnish/vfil.c b/lib/libvarnish/vfil.c index a4bab9e..ca1d965 100644 --- a/lib/libvarnish/vfil.c +++ b/lib/libvarnish/vfil.c @@ -29,15 +29,15 @@ #include "config.h" +#include + #include #include #include #include #include -#include #include - -#include +#include #include "vas.h" #include "vdef.h" diff --git a/lib/libvarnish/vin.c b/lib/libvarnish/vin.c index cd3e7d0..4dba302 100644 --- a/lib/libvarnish/vin.c +++ b/lib/libvarnish/vin.c @@ -30,14 +30,14 @@ #include "config.h" -#include "vapi/vsm_int.h" - #include #include +#include #include #include #include +#include "vapi/vsm_int.h" #include "vas.h" #include "vdef.h" #include "vin.h" diff --git a/lib/libvarnish/vlu.c b/lib/libvarnish/vlu.c index 1334a28..f149a57 100644 --- a/lib/libvarnish/vlu.c +++ b/lib/libvarnish/vlu.c @@ -29,13 +29,16 @@ #include "config.h" +#include #include -#include #include +#include #include + +#include "miniobj.h" #include "vas.h" + #include "vlu.h" -#include "miniobj.h" struct vlu { unsigned magic; diff --git a/lib/libvarnish/vmb.c b/lib/libvarnish/vmb.c index e6b0f25..3f5c12d 100644 --- a/lib/libvarnish/vmb.c +++ b/lib/libvarnish/vmb.c @@ -26,8 +26,11 @@ * SUCH DAMAGE. */ +#include "config.h" + #include #include + #include "vas.h" #include "vmb.h" diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c index 7940e9b..d2f423b 100644 --- a/lib/libvarnish/vnum.c +++ b/lib/libvarnish/vnum.c @@ -31,10 +31,11 @@ #include "config.h" #include +#include #include #include -#include +#include "vas.h" #include "vnum.h" static const char err_miss_num[] = "Missing number"; @@ -112,10 +113,6 @@ VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel) #ifdef NUM_C_TEST /* Compile with: "cc -o foo -DNUM_C_TEST -I../.. -I../../include num.c -lm" */ -#include "vas.h" -#include -#include -#include struct test_case { const char *str; diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c index 2810bc2..9b1d911 100644 --- a/lib/libvarnish/vre.c +++ b/lib/libvarnish/vre.c @@ -26,11 +26,15 @@ * SUCH DAMAGE. */ +#include "config.h" + +#include #include #include #include "miniobj.h" #include "vas.h" + #include "vre.h" struct vre { diff --git a/lib/libvarnish/vsb.c b/lib/libvarnish/vsb.c index 4930be2..16f6d4b 100644 --- a/lib/libvarnish/vsb.c +++ b/lib/libvarnish/vsb.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 222004 2011-05-17 06:36:32Z phk $") #include "config.h" #include +#include #include #include #include diff --git a/lib/libvarnish/vsha256.c b/lib/libvarnish/vsha256.c index 942a186..10b7a6a 100644 --- a/lib/libvarnish/vsha256.c +++ b/lib/libvarnish/vsha256.c @@ -28,23 +28,24 @@ #include "config.h" -#include -#include +#ifdef HAVE_SYS_ENDIAN_H +#include +#define VBYTE_ORDER _BYTE_ORDER +#define VBIG_ENDIAN _BIG_ENDIAN +#endif #ifdef HAVE_ENDIAN_H #include #define VBYTE_ORDER __BYTE_ORDER #define VBIG_ENDIAN __BIG_ENDIAN #endif -#ifdef HAVE_SYS_ENDIAN_H -#include -#define VBYTE_ORDER _BYTE_ORDER -#define VBIG_ENDIAN _BIG_ENDIAN -#endif +#include +#include +#include #include "vas.h" -#include "vsha256.h" #include "vend.h" +#include "vsha256.h" #if defined(VBYTE_ORDER) && VBYTE_ORDER == VBIG_ENDIAN diff --git a/lib/libvarnish/vss.c b/lib/libvarnish/vss.c index 297df11..77b8f38 100644 --- a/lib/libvarnish/vss.c +++ b/lib/libvarnish/vss.c @@ -44,8 +44,8 @@ #include #include "vas.h" -#include "vtcp.h" #include "vss.h" +#include "vtcp.h" /* lightweight addrinfo */ struct vss_addr { diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c index 90ceacb..497119c 100644 --- a/lib/libvarnish/vsub.c +++ b/lib/libvarnish/vsub.c @@ -31,12 +31,13 @@ #include "config.h" +#include + +#include #include +#include #include #include -#include - -#include #include "vas.h" #include "vlu.h" diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index c955e65..10c3664 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -31,25 +31,24 @@ #include #include +#include +#ifdef HAVE_SYS_FILIO_H +# include +#endif #include - #ifdef __linux -#include +# include #endif #include -#include -#ifdef HAVE_SYS_FILIO_H -#include -#endif +#include #include #include #include #include #include #include -#include #include "vas.h" #include "vtcp.h" diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c index 772b559..42c1558 100644 --- a/lib/libvarnish/vtim.c +++ b/lib/libvarnish/vtim.c @@ -48,11 +48,13 @@ #include +#include +#include #include +#include #include #include #include -#include #include "vas.h" #include "vtim.h" @@ -200,8 +202,6 @@ VTIM_timespec(double t) #ifdef TEST_DRIVER -#include - /* * Compile with: * cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c index 211d284..eea7f5c 100644 --- a/lib/libvarnishapi/vsc.c +++ b/lib/libvarnishapi/vsc.c @@ -29,20 +29,22 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsm_int.h" -#include "vapi/vsc.h" - #include #include -#include + +#include +#include #include +#include +#include "miniobj.h" #include "vas.h" + +#include "vapi/vsc.h" +#include "vapi/vsm.h" +#include "vapi/vsm_int.h" #include "vav.h" #include "vqueue.h" -#include "miniobj.h" - #include "vsm_api.h" struct vsc_sf { diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index 9fa6a48..88bd9d6 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -29,26 +29,27 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsm_int.h" -#include "vapi/vsl.h" - -#include #include +#include +#include +#include #include #include #include #include -#include "vas.h" -#include "vre.h" -#include "vbm.h" #include "miniobj.h" +#include "vas.h" -#include "vsm_api.h" -#include "vsl_api.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" +#include "vapi/vsm_int.h" +#include "vbm.h" #include "vmb.h" +#include "vre.h" +#include "vsl_api.h" +#include "vsm_api.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c index f41129b..56f93e2 100644 --- a/lib/libvarnishapi/vsl_arg.c +++ b/lib/libvarnishapi/vsl_arg.c @@ -29,27 +29,27 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsl.h" - #include #include #include #include #include +#include #include #include #include #include -#include "vas.h" -#include "vre.h" -#include "vbm.h" #include "miniobj.h" +#include "vas.h" -#include "vsm_api.h" +#include "vapi/vsl.h" +#include "vapi/vsm.h" +#include "vbm.h" +#include "vre.h" #include "vsl_api.h" +#include "vsm_api.h" /*-------------------------------------------------------------------- * Look up a tag diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c index eeb2b3c..8e8b27b 100644 --- a/lib/libvarnishapi/vsm.c +++ b/lib/libvarnishapi/vsm.c @@ -29,26 +29,25 @@ #include "config.h" -#include "vapi/vsm.h" -#include "vapi/vsm_int.h" - -#include -#include #include #include +#include #include #include +#include #include #include #include #include -#include "vas.h" -#include "vin.h" -#include "vbm.h" #include "miniobj.h" +#include "vas.h" +#include "vapi/vsm.h" +#include "vapi/vsm_int.h" +#include "vbm.h" +#include "vin.h" #include "vsm_api.h" #ifndef MAP_HASSEMAPHORE diff --git a/lib/libvarnishcompat/daemon.c b/lib/libvarnishcompat/daemon.c index ef14e23..6b3fbb1 100644 --- a/lib/libvarnishcompat/daemon.c +++ b/lib/libvarnishcompat/daemon.c @@ -35,8 +35,8 @@ #include #include -#include #include +#include #include #include "compat/daemon.h" diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py index 9342aaf..dde0e89 100755 --- a/lib/libvcl/generate.py +++ b/lib/libvcl/generate.py @@ -805,7 +805,9 @@ file_header(fo) fo.write(""" #include "config.h" + #include + #include "vcc_compile.h" const struct var vcc_vars[] = { @@ -863,9 +865,10 @@ file_header(fo) fo.write(""" #include "config.h" -#include + #include -#include "config.h" +#include + #include "vcc_compile.h" """) diff --git a/lib/libvcl/vcc_acl.c b/lib/libvcl/vcc_acl.c index 985a18e..c962044 100644 --- a/lib/libvcl/vcc_acl.c +++ b/lib/libvcl/vcc_acl.c @@ -29,16 +29,18 @@ #include "config.h" -#include -#include -#include #include #include -#include + #include +#include +#include +#include +#include #include "vcc_compile.h" + #include "vrt.h" struct acl_e { diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 61bfb87..9d72b51 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -32,7 +32,6 @@ #include "config.h" - #include "vcc_compile.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index 0c72c1c..03482c4 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -59,6 +59,7 @@ #include #include "vcc_compile.h" + #include "vss.h" struct host { @@ -99,8 +100,6 @@ emit_sockaddr(struct vcc *tl, void *sa, unsigned sal) * and put it in an official sockaddr when we load the VCL. */ -#include - void Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port) { diff --git a/lib/libvcl/vcc_backend_util.c b/lib/libvcl/vcc_backend_util.c index 28510f5..efba623 100644 --- a/lib/libvcl/vcc_backend_util.c +++ b/lib/libvcl/vcc_backend_util.c @@ -30,8 +30,8 @@ #include "config.h" -#include #include +#include #include #include "vcc_compile.h" diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c index dbae2ab..a0c6232 100644 --- a/lib/libvcl/vcc_compile.c +++ b/lib/libvcl/vcc_compile.c @@ -54,12 +54,13 @@ #include #include -#include #include +#include #include #include #include "vcc_compile.h" + #include "libvcl.h" #include "vfil.h" diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index a245a36..c59c632 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -28,6 +28,10 @@ * */ +#include + +#include +#include #include #include "miniobj.h" @@ -37,6 +41,7 @@ #include "vqueue.h" #include "vsb.h" + #include "vcc_token_defs.h" #ifndef NULL diff --git a/lib/libvcl/vcc_dir_dns.c b/lib/libvcl/vcc_dir_dns.c index 2e3951e..a91c021 100644 --- a/lib/libvcl/vcc_dir_dns.c +++ b/lib/libvcl/vcc_dir_dns.c @@ -28,9 +28,9 @@ #include "config.h" +#include #include #include -#include #include "vcc_compile.h" diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c index dc7d99d..3dfeeaa 100644 --- a/lib/libvcl/vcc_expr.c +++ b/lib/libvcl/vcc_expr.c @@ -31,11 +31,11 @@ #include "config.h" +#include #include #include #include #include -#include #include "vcc_compile.h" diff --git a/lib/libvcl/vcc_string.c b/lib/libvcl/vcc_string.c index dfc82cf..4e4762e 100644 --- a/lib/libvcl/vcc_string.c +++ b/lib/libvcl/vcc_string.c @@ -34,8 +34,8 @@ #include "vcc_compile.h" -#include "vrt.h" #include "vre.h" +#include "vrt.h" /*--------------------------------------------------------------------*/ diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c index 40c9ed5..55b43d7 100644 --- a/lib/libvcl/vcc_vmod.c +++ b/lib/libvcl/vcc_vmod.c @@ -28,11 +28,12 @@ #include "config.h" -#include #include +#include #include #include "vcc_compile.h" + #include "vmod_abi.h" void diff --git a/lib/libvmod_std/vmod.py b/lib/libvmod_std/vmod.py index 1b0f1c0..6a9b4fc 100755 --- a/lib/libvmod_std/vmod.py +++ b/lib/libvmod_std/vmod.py @@ -278,6 +278,8 @@ fh.write("\n"); fh.write(plist) +fc.write('#include "config.h"\n') +fc.write('\n') fc.write('#include "vrt.h"\n') fc.write('#include "vcc_if.h"\n') fc.write('#include "vmod_abi.h"\n') diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 847c705..79cbf02 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -26,13 +26,20 @@ * SUCH DAMAGE. */ +#include "config.h" + +#include + #include +#include #include +#include #include #include -#include + #include "vrt.h" #include "vtcp.h" + #include "../../bin/varnishd/cache.h" #include "vcc_if.h" diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c index 6f06c2c..156cf13 100644 --- a/lib/libvmod_std/vmod_std_conversions.c +++ b/lib/libvmod_std/vmod_std_conversions.c @@ -27,8 +27,12 @@ * */ +#include "config.h" + #include +#include #include +#include #include #include "../../bin/varnishd/cache.h" diff --git a/lib/libvmod_std/vmod_std_fileread.c b/lib/libvmod_std/vmod_std_fileread.c index cae57a2..8476bd6 100644 --- a/lib/libvmod_std/vmod_std_fileread.c +++ b/lib/libvmod_std/vmod_std_fileread.c @@ -37,13 +37,19 @@ * XXX: underlying file has been updated. */ +#include "config.h" + +#include +#include #include -#include "vrt.h" + #include "../../bin/varnishd/cache.h" -#include "vcc_if.h" +#include "vrt.h" #include "vfil.h" +#include "vcc_if.h" + struct frfile { unsigned magic; #define CACHED_FILE_MAGIC 0xa8e9d87a diff --git a/man/vsc2rst.c b/man/vsc2rst.c index ad5dec6..bf4091f 100644 --- a/man/vsc2rst.c +++ b/man/vsc2rst.c @@ -1,3 +1,5 @@ +/* XXX: Copyright ?? */ +#include "config.h" #include From phk at varnish-cache.org Mon Oct 10 10:14:05 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 12:14:05 +0200 Subject: [master] 81386d6 Add needed #include Message-ID: commit 81386d693ac53fbbf7bde9c8134c84aa2674090c Author: Poul-Henning Kamp Date: Mon Oct 10 10:13:57 2011 +0000 Add needed #include diff --git a/lib/libvarnish/cli_auth.c b/lib/libvarnish/cli_auth.c index 396a127..08bbddc 100644 --- a/lib/libvarnish/cli_auth.c +++ b/lib/libvarnish/cli_auth.c @@ -31,6 +31,7 @@ #include #include +#include #include #include From phk at varnish-cache.org Mon Oct 10 10:24:28 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 12:24:28 +0200 Subject: [master] 8aba928 Add more missing 's Message-ID: commit 8aba928cfd4291a455f9b501b2871cf62d29ccdf Author: Poul-Henning Kamp Date: Mon Oct 10 10:24:16 2011 +0000 Add more missing 's diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 6d68a5d..72bc84b 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index e6c4bf8..e15d102 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/bin/varnishncsa/base64.c b/bin/varnishncsa/base64.c index ee1a87b..a631098 100644 --- a/bin/varnishncsa/base64.c +++ b/bin/varnishncsa/base64.c @@ -11,8 +11,6 @@ #include // for test-prog #include "base64.h" -#include "vapi/vsl.h" -#include "vapi/vsm.h" static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 97a3642..26ede48 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/bin/varnishreplay/varnishreplay.c b/bin/varnishreplay/varnishreplay.c index 77758eb..12b6c41 100644 --- a/bin/varnishreplay/varnishreplay.c +++ b/bin/varnishreplay/varnishreplay.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/bin/varnishsizes/varnishsizes.c b/bin/varnishsizes/varnishsizes.c index a78be9b..ce68a9d 100644 --- a/bin/varnishsizes/varnishsizes.c +++ b/bin/varnishsizes/varnishsizes.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 6093656..a1b6cbd 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #ifdef HAVE_PTHREAD_NP_H #include diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 07070c8..efe312e 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include From phk at varnish-cache.org Mon Oct 10 10:51:29 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 12:51:29 +0200 Subject: [master] 905144b This is a table-generating #include Message-ID: commit 905144b25b68e6c940c71af5164ba2a04868659a Author: Poul-Henning Kamp Date: Mon Oct 10 10:51:18 2011 +0000 This is a table-generating #include diff --git a/include/Makefile.am b/include/Makefile.am index 948cef7..935a6f9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -9,6 +9,7 @@ pkginclude_HEADERS = \ tbl/http_response.h \ tbl/locks.h \ tbl/steps.h \ + tbl/symbol_kind.h \ tbl/vcc_types.h \ tbl/vcl_returns.h \ tbl/vrt_stv_var.h \ diff --git a/include/tbl/symbol_kind.h b/include/tbl/symbol_kind.h new file mode 100644 index 0000000..155d36e --- /dev/null +++ b/include/tbl/symbol_kind.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2010 Varnish Software 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. + * + */ + +/*lint -save -e525 -e539 */ +VCC_SYMB(NONE, none, "undefined") +VCC_SYMB(VAR, var, "variable") +VCC_SYMB(FUNC, func, "function") /* VMOD function */ +VCC_SYMB(PROC, proc, "procedure") /* VMOD procedure */ +VCC_SYMB(VMOD, vmod, "vmod") +VCC_SYMB(ACL, acl, "acl") +VCC_SYMB(SUB, sub, "sub") /* VCL subroutine */ +VCC_SYMB(BACKEND, backend, "backend") +VCC_SYMB(PROBE, probe, "probe") +VCC_SYMB(WILDCARD, wildcard, "wildcard") +/*lint -restore */ diff --git a/lib/libvcl/Makefile.am b/lib/libvcl/Makefile.am index 8406ed7..44e2957 100644 --- a/lib/libvcl/Makefile.am +++ b/lib/libvcl/Makefile.am @@ -9,7 +9,6 @@ libvcl_la_LDFLAGS = -avoid-version libvcl_la_SOURCES = \ vcc_compile.h \ vcc_token_defs.h \ - symbol_kind.h \ \ vcc_acl.c \ vcc_action.c \ diff --git a/lib/libvcl/symbol_kind.h b/lib/libvcl/symbol_kind.h deleted file mode 100644 index 155d36e..0000000 --- a/lib/libvcl/symbol_kind.h +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2010 Varnish Software 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. - * - */ - -/*lint -save -e525 -e539 */ -VCC_SYMB(NONE, none, "undefined") -VCC_SYMB(VAR, var, "variable") -VCC_SYMB(FUNC, func, "function") /* VMOD function */ -VCC_SYMB(PROC, proc, "procedure") /* VMOD procedure */ -VCC_SYMB(VMOD, vmod, "vmod") -VCC_SYMB(ACL, acl, "acl") -VCC_SYMB(SUB, sub, "sub") /* VCL subroutine */ -VCC_SYMB(BACKEND, backend, "backend") -VCC_SYMB(PROBE, probe, "probe") -VCC_SYMB(WILDCARD, wildcard, "wildcard") -/*lint -restore */ diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h index c59c632..8088509 100644 --- a/lib/libvcl/vcc_compile.h +++ b/lib/libvcl/vcc_compile.h @@ -99,7 +99,7 @@ struct token { enum symkind { #define VCC_SYMB(uu, ll, dd) SYM_##uu, -#include "symbol_kind.h" +#include "tbl/symbol_kind.h" #undef VCC_SYMB }; diff --git a/lib/libvcl/vcc_symb.c b/lib/libvcl/vcc_symb.c index 0acb0cd..222680f 100644 --- a/lib/libvcl/vcc_symb.c +++ b/lib/libvcl/vcc_symb.c @@ -41,7 +41,7 @@ VCC_SymKind(struct vcc *tl, const struct symbol *s) { switch(s->kind) { #define VCC_SYMB(uu, ll, dd) case SYM_##uu: return(dd); -#include "symbol_kind.h" +#include "tbl/symbol_kind.h" #undef VCC_SYMB default: ErrInternal(tl); From phk at varnish-cache.org Mon Oct 10 11:14:44 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 13:14:44 +0200 Subject: [master] 44a623a Rename cli_serve.h to vcli_serve.h Message-ID: commit 44a623a6c77bdbec1a0b6154af3c2665bda6db0a Author: Poul-Henning Kamp Date: Mon Oct 10 11:14:25 2011 +0000 Rename cli_serve.h to vcli_serve.h diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index e519b01..818b9ab 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -44,11 +44,10 @@ #include #include -#include "vcli.h" -#include "cli_common.h" #include "vapi/vsl.h" #include "vapi/vsm.h" #include "vas.h" +#include "vcli.h" #include "vss.h" #ifdef HAVE_LIBEDIT diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index f66075e..a278e84 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -43,8 +43,8 @@ #include "vcli.h" #include "cli_common.h" #include "cli_priv.h" -#include "cli_serve.h" #include "hash_slinger.h" // objhead +#include "vcli_serve.h" pthread_t cli_thread; static struct lock cli_mtx; diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index 4a7925a..f1bb2d8 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -47,9 +47,9 @@ #include "vcli.h" #include "cli_common.h" #include "cli_priv.h" -#include "cli_serve.h" #include "heritage.h" #include "mgt_cli.h" +#include "vcli_serve.h" #include "vev.h" #include "vlu.h" #include "vss.h" diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index 18b96c3..d3ab02e 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -47,12 +47,12 @@ #include "cli_priv.h" #include "hash_slinger.h" -#include "persistent.h" #include "stevedore.h" #include "vcli.h" #include "vend.h" #include "vsha256.h" +#include "persistent.h" #include "storage_persistent.h" /*--------------------------------------------------------------------*/ diff --git a/include/Makefile.am b/include/Makefile.am index 935a6f9..9c92b1e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -28,7 +28,6 @@ nobase_noinst_HEADERS = \ binary_heap.h \ cli_common.h \ cli_priv.h \ - cli_serve.h \ compat/daemon.h \ compat/execinfo.h \ compat/srandomdev.h \ @@ -40,6 +39,7 @@ nobase_noinst_HEADERS = \ vav.h \ vbm.h \ vcl.h \ + vcli_serve.h \ vcs_version.h \ vcs.h \ vct.h \ diff --git a/include/cli_serve.h b/include/cli_serve.h deleted file mode 100644 index 0ac29f8..0000000 --- a/include/cli_serve.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2010-2011 Varnish Software 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. - * - */ - -struct VCLS; -typedef void cls_cb_f(void *priv); -typedef void cls_cbc_f(const struct cli*); -struct VCLS *VCLS_New(cls_cbc_f *before, cls_cbc_f *after, unsigned maxlen); -struct cli *VCLS_AddFd(struct VCLS *cs, int fdi, int fdo, cls_cb_f *closefunc, - void *priv); -int VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp); -int VCLS_Poll(struct VCLS *cs, int timeout); -int VCLS_PollFd(struct VCLS *cs, int fd, int timeout); -void VCLS_Destroy(struct VCLS **); - -/* From libvarnish/cli.c */ -cli_func_t VCLS_func_close; -cli_func_t VCLS_func_help; -cli_func_t VCLS_func_ping; - diff --git a/include/flopen.h b/include/flopen.h index e5b6030..9833efa 100644 --- a/include/flopen.h +++ b/include/flopen.h @@ -31,8 +31,6 @@ #ifndef FLOPEN_H_INCLUDED #define FLOPEN_H_INCLUDED -#include - int flopen(const char *, int, ...); int fltest(int fd, pid_t *pid); diff --git a/include/vcli_serve.h b/include/vcli_serve.h new file mode 100644 index 0000000..0ac29f8 --- /dev/null +++ b/include/vcli_serve.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2010-2011 Varnish Software 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. + * + */ + +struct VCLS; +typedef void cls_cb_f(void *priv); +typedef void cls_cbc_f(const struct cli*); +struct VCLS *VCLS_New(cls_cbc_f *before, cls_cbc_f *after, unsigned maxlen); +struct cli *VCLS_AddFd(struct VCLS *cs, int fdi, int fdo, cls_cb_f *closefunc, + void *priv); +int VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp); +int VCLS_Poll(struct VCLS *cs, int timeout); +int VCLS_PollFd(struct VCLS *cs, int fd, int timeout); +void VCLS_Destroy(struct VCLS **); + +/* From libvarnish/cli.c */ +cli_func_t VCLS_func_close; +cli_func_t VCLS_func_help; +cli_func_t VCLS_func_ping; + diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index 2c3a09c..9a9daed 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -46,8 +46,8 @@ #include "vcli.h" #include "cli_common.h" #include "cli_priv.h" -#include "cli_serve.h" #include "vav.h" +#include "vcli_serve.h" #include "vlu.h" #include "vqueue.h" #include "vsb.h" From phk at varnish-cache.org Mon Oct 10 11:33:30 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 13:33:30 +0200 Subject: [master] 92f239c Get the vcli includes into line Message-ID: commit 92f239c0fa236362ec0e6538efccbc71c11bfa91 Author: Poul-Henning Kamp Date: Mon Oct 10 11:33:19 2011 +0000 Get the vcli includes into line diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index 80d7b81..e6ad6e3 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -32,8 +32,8 @@ #include "cache.h" -#include "cli_priv.h" #include "vcli.h" +#include "vcli_priv.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache_backend_cfg.c b/bin/varnishd/cache_backend_cfg.c index 2e6d83c..b10512d 100644 --- a/bin/varnishd/cache_backend_cfg.c +++ b/bin/varnishd/cache_backend_cfg.c @@ -38,7 +38,7 @@ #include "cache.h" #include "cache_backend.h" -#include "cli_priv.h" +#include "vcli_priv.h" #include "vrt.h" struct lock VBE_mtx; diff --git a/bin/varnishd/cache_backend_poll.c b/bin/varnishd/cache_backend_poll.c index a0ad62b..d79a806 100644 --- a/bin/varnishd/cache_backend_poll.c +++ b/bin/varnishd/cache_backend_poll.c @@ -45,7 +45,7 @@ #include "cache.h" #include "cache_backend.h" -#include "cli_priv.h" +#include "vcli_priv.h" #include "vrt.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index bec8d85..d556ace 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -67,9 +67,9 @@ #include "cache.h" -#include "cli_priv.h" #include "hash_slinger.h" #include "vcli.h" +#include "vcli_priv.h" #include "vend.h" #include "vtim.h" diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index ba61e9c..463a05b 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -65,10 +65,10 @@ DOT acceptor -> start [style=bold,color=green] #include "cache.h" -#include "cli_priv.h" #include "hash_slinger.h" #include "stevedore.h" #include "vcl.h" +#include "vcli_priv.h" #include "vsha256.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index a278e84..ea4d367 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -40,10 +40,10 @@ #include "cache.h" -#include "vcli.h" -#include "cli_common.h" -#include "cli_priv.h" #include "hash_slinger.h" // objhead +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" #include "vcli_serve.h" pthread_t cli_thread; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 4bbc272..75319d8 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -36,8 +36,8 @@ #include "cache.h" -#include "cli_priv.h" #include "stevedore.h" +#include "vcli_priv.h" #include "vct.h" #include "vtcp.h" diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c index 48568ff..c77ab08 100644 --- a/bin/varnishd/cache_vcl.c +++ b/bin/varnishd/cache_vcl.c @@ -39,10 +39,10 @@ #include "cache.h" -#include "cli_priv.h" #include "libvcl.h" #include "vcl.h" #include "vcli.h" +#include "vcli_priv.h" struct vcls { unsigned magic; diff --git a/bin/varnishd/cache_vrt_vmod.c b/bin/varnishd/cache_vrt_vmod.c index bb4eeb8..6b3b846 100644 --- a/bin/varnishd/cache_vrt_vmod.c +++ b/bin/varnishd/cache_vrt_vmod.c @@ -36,7 +36,7 @@ #include "cache.h" -#include "cli_priv.h" +#include "vcli_priv.h" #include "vrt.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache_waiter.c b/bin/varnishd/cache_waiter.c index 08c5809..9c30edf 100644 --- a/bin/varnishd/cache_waiter.c +++ b/bin/varnishd/cache_waiter.c @@ -33,8 +33,8 @@ #include "cache.h" #include "cache_waiter.h" -#include "cli_priv.h" #include "vcli.h" +#include "vcli_priv.h" static const struct waiter * const vca_waiters[] = { #if defined(HAVE_KQUEUE) diff --git a/bin/varnishd/hash_critbit.c b/bin/varnishd/hash_critbit.c index add2397..78bda7a 100644 --- a/bin/varnishd/hash_critbit.c +++ b/bin/varnishd/hash_critbit.c @@ -36,8 +36,8 @@ #include "cache.h" -#include "cli_priv.h" #include "hash_slinger.h" +#include "vcli_priv.h" #include "vmb.h" #include "vtim.h" diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 7338e6c..5af26fe 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -46,18 +46,19 @@ #include "mgt.h" -#include "cli_priv.h" #include "heritage.h" -#include "mgt_cli.h" #include "vapi/vsm_int.h" #include "vbm.h" #include "vcli.h" +#include "vcli_priv.h" #include "vev.h" #include "vlu.h" #include "vss.h" #include "vtcp.h" #include "vtim.h" +#include "mgt_cli.h" + pid_t child_pid = -1; diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c index f1bb2d8..dea5e7f 100644 --- a/bin/varnishd/mgt_cli.c +++ b/bin/varnishd/mgt_cli.c @@ -44,17 +44,18 @@ #include "mgt.h" -#include "vcli.h" -#include "cli_common.h" -#include "cli_priv.h" #include "heritage.h" -#include "mgt_cli.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" #include "vcli_serve.h" #include "vev.h" #include "vlu.h" #include "vss.h" #include "vtcp.h" +#include "mgt_cli.h" + #ifndef HAVE_SRANDOMDEV #include "compat/srandomdev.h" #endif diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 4bb1adf..9ded195 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -39,16 +39,17 @@ #include "mgt.h" -#include "vcli.h" #include "cache_waiter.h" -#include "cli_common.h" -#include "cli_priv.h" #include "heritage.h" -#include "mgt_cli.h" #include "vav.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" #include "vparam.h" #include "vss.h" +#include "mgt_cli.h" + #define MAGIC_INIT_STRING "\001" struct params master; static int nparspec; diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c index 78a29dd..5901408 100644 --- a/bin/varnishd/mgt_vcc.c +++ b/bin/varnishd/mgt_vcc.c @@ -40,14 +40,15 @@ #include "mgt.h" -#include "cli_priv.h" #include "libvcl.h" -#include "mgt_cli.h" #include "vcl.h" #include "vcli.h" +#include "vcli_priv.h" #include "vfil.h" #include "vsub.h" +#include "mgt_cli.h" + struct vclprog { VTAILQ_ENTRY(vclprog) list; char *name; diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index 538ae27..ff1bdf5 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -38,9 +38,9 @@ #include "cache.h" -#include "cli_priv.h" #include "stevedore.h" #include "vav.h" +#include "vcli_priv.h" #include "vrt.h" #include "vrt_obj.h" diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index d3ab02e..d379c4a 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -45,10 +45,10 @@ #include "cache.h" -#include "cli_priv.h" #include "hash_slinger.h" #include "stevedore.h" #include "vcli.h" +#include "vcli_priv.h" #include "vend.h" #include "vsha256.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 7cecfe4..722c10e 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -46,12 +46,12 @@ #include "mgt.h" -#include "vcli.h" -#include "cli_common.h" #include "hash_slinger.h" #include "heritage.h" #include "stevedore.h" #include "vav.h" +#include "vcli.h" +#include "vcli_common.h" #include "vev.h" #include "vfil.h" #include "vin.h" diff --git a/include/Makefile.am b/include/Makefile.am index 9c92b1e..62292fc 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,8 +26,6 @@ pkginclude_HEADERS = \ nobase_noinst_HEADERS = \ binary_heap.h \ - cli_common.h \ - cli_priv.h \ compat/daemon.h \ compat/execinfo.h \ compat/srandomdev.h \ @@ -39,6 +37,8 @@ nobase_noinst_HEADERS = \ vav.h \ vbm.h \ vcl.h \ + vcli_common.h \ + vcli_priv.h \ vcli_serve.h \ vcs_version.h \ vcs.h \ diff --git a/include/cli_common.h b/include/cli_common.h deleted file mode 100644 index 80d680f..0000000 --- a/include/cli_common.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -struct vlu; -struct VCLS; - -struct cli { - unsigned magic; -#define CLI_MAGIC 0x4038d570 - struct vsb *sb; - enum VCLI_status_e result; - char *cmd; - unsigned auth; - char challenge[34]; - char *ident; - struct vlu *vlu; - struct VCLS *cls; -}; diff --git a/include/cli_priv.h b/include/cli_priv.h deleted file mode 100644 index 60d6d69..0000000 --- a/include/cli_priv.h +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Varnish process internal CLI stuff. - * - * XXX: at a latter date we may want to move some to cli.h/libvarnishapi - */ - -#define CLI_PRIV_H - -struct cli; /* NB: struct cli is opaque at this level. */ - -typedef void cli_func_t(struct cli*, const char * const *av, void *priv); - -struct cli_proto { - /* These must match the CLI_* macros in cli.h */ - const char *request; - const char *syntax; - const char *help; - unsigned minarg; - unsigned maxarg; - char flags[4]; - - /* Dispatch information */ - cli_func_t *func; - void *priv; -}; - -/* The implementation must provide these functions */ -void VCLI_Out(struct cli *cli, const char *fmt, ...); -void VCLI_Quote(struct cli *cli, const char *str); -void VCLI_SetResult(struct cli *cli, unsigned r); diff --git a/include/vcli_common.h b/include/vcli_common.h new file mode 100644 index 0000000..80d680f --- /dev/null +++ b/include/vcli_common.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +struct vlu; +struct VCLS; + +struct cli { + unsigned magic; +#define CLI_MAGIC 0x4038d570 + struct vsb *sb; + enum VCLI_status_e result; + char *cmd; + unsigned auth; + char challenge[34]; + char *ident; + struct vlu *vlu; + struct VCLS *cls; +}; diff --git a/include/vcli_priv.h b/include/vcli_priv.h new file mode 100644 index 0000000..60d6d69 --- /dev/null +++ b/include/vcli_priv.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Varnish process internal CLI stuff. + * + * XXX: at a latter date we may want to move some to cli.h/libvarnishapi + */ + +#define CLI_PRIV_H + +struct cli; /* NB: struct cli is opaque at this level. */ + +typedef void cli_func_t(struct cli*, const char * const *av, void *priv); + +struct cli_proto { + /* These must match the CLI_* macros in cli.h */ + const char *request; + const char *syntax; + const char *help; + unsigned minarg; + unsigned maxarg; + char flags[4]; + + /* Dispatch information */ + cli_func_t *func; + void *priv; +}; + +/* The implementation must provide these functions */ +void VCLI_Out(struct cli *cli, const char *fmt, ...); +void VCLI_Quote(struct cli *cli, const char *str); +void VCLI_SetResult(struct cli *cli, unsigned r); diff --git a/lib/libvarnish/cli_common.c b/lib/libvarnish/cli_common.c index cb4e8af..43b91c3 100644 --- a/lib/libvarnish/cli_common.c +++ b/lib/libvarnish/cli_common.c @@ -43,10 +43,10 @@ #include #include -#include "vcli.h" -#include "cli_common.h" -#include "cli_priv.h" #include "vas.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" #include "vsb.h" /*lint -e{818} cli could be const */ diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c index 9a9daed..f3def96 100644 --- a/lib/libvarnish/cli_serve.c +++ b/lib/libvarnish/cli_serve.c @@ -43,10 +43,10 @@ #include "miniobj.h" #include "vas.h" -#include "vcli.h" -#include "cli_common.h" -#include "cli_priv.h" #include "vav.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" #include "vcli_serve.h" #include "vlu.h" #include "vqueue.h" From phk at varnish-cache.org Mon Oct 10 12:27:07 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 10 Oct 2011 14:27:07 +0200 Subject: [master] e94b1e8 Move stevedore.h to storage.h and have it contain only the back-side (storage-module facing) bits. Message-ID: commit e94b1e8af31ac7ecfdadbcb5ab376955a397f20e Author: Poul-Henning Kamp Date: Mon Oct 10 12:26:31 2011 +0000 Move stevedore.h to storage.h and have it contain only the back-side (storage-module facing) bits. Move the front-side bits to cache.h diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index b1f2a5c..2b822fa 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -88,7 +88,7 @@ noinst_HEADERS = \ heritage.h \ mgt.h \ mgt_cli.h \ - stevedore.h \ + storage.h \ storage_persistent.h \ vparam.h diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 41efdad..930f197 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -46,7 +46,6 @@ #include #endif #include -#include #include #include #include @@ -94,6 +93,7 @@ enum { struct iovec; struct cli; +struct exp; struct vsb; struct sess; struct director; @@ -379,6 +379,15 @@ struct worker { struct acct acct_tmp; }; +/* LRU ---------------------------------------------------------------*/ + +struct lru { + unsigned magic; +#define LRU_MAGIC 0x3fec7bb0 + VTAILQ_HEAD(,objcore) lru_head; + struct lock mtx; +}; + /* Storage -----------------------------------------------------------*/ struct storage { @@ -961,9 +970,20 @@ enum body_status RFC2616_Body(const struct sess *sp); unsigned RFC2616_Req_Gzip(const struct sess *sp); int RFC2616_Do_Cond(const struct sess *sp); +/* stevedore.c */ +struct object *STV_NewObject(struct sess *sp, const char *hint, unsigned len, + struct exp *, uint16_t nhttp); +struct storage *STV_alloc(const struct sess *sp, size_t size); +void STV_trim(struct storage *st, size_t size); +void STV_free(struct storage *st); +void STV_open(void); +void STV_close(void); +void STV_Freestore(struct object *o); + /* storage_synth.c */ struct vsb *SMS_Makesynth(struct object *obj); void SMS_Finish(struct object *obj); +void SMS_Init(void); /* storage_persistent.c */ void SMP_Init(void); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 463a05b..1eb249e 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -57,7 +57,6 @@ DOT acceptor -> start [style=bold,color=green] #include "config.h" -#include #include #include #include @@ -66,7 +65,6 @@ DOT acceptor -> start [style=bold,color=green] #include "cache.h" #include "hash_slinger.h" -#include "stevedore.h" #include "vcl.h" #include "vcli_priv.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_dir_dns.c b/bin/varnishd/cache_dir_dns.c index acb3689..ae96dbb 100644 --- a/bin/varnishd/cache_dir_dns.c +++ b/bin/varnishd/cache_dir_dns.c @@ -31,7 +31,6 @@ #include -#include #include #include #include diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index b6ef527..1db5259 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -35,8 +35,6 @@ #include "cache.h" #include "cache_esi.h" -#include "stevedore.h" -#include "vct.h" /*--------------------------------------------------------------------- * Read some bytes. diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index 8e18cb5..f9dcdd1 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -57,7 +57,6 @@ #include "binary_heap.h" #include "hash_slinger.h" -#include "stevedore.h" #include "vtim.h" static pthread_t exp_thread; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 75319d8..4300780 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -36,7 +36,6 @@ #include "cache.h" -#include "stevedore.h" #include "vcli_priv.h" #include "vct.h" #include "vtcp.h" diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 67aa3af..12855e1 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -61,7 +61,6 @@ #include "cache_backend.h" #include "hash_slinger.h" -#include "stevedore.h" #include "vav.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_main.c b/bin/varnishd/cache_main.c index 54d71f8..6e62fd2 100644 --- a/bin/varnishd/cache_main.c +++ b/bin/varnishd/cache_main.c @@ -36,7 +36,6 @@ #include "cache_waiter.h" #include "hash_slinger.h" -#include "stevedore.h" /*-------------------------------------------------------------------- * Per thread storage for the session currently being processed by diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 4421969..00eaef5 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -42,7 +42,6 @@ #include "config.h" -#include #include #include diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index bacf906..9768eeb 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -37,7 +37,6 @@ #include "cache.h" -#include "stevedore.h" #include "vct.h" #include "vtim.h" diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c index 3eaa627..301fcf2 100644 --- a/bin/varnishd/cache_waiter_epoll.c +++ b/bin/varnishd/cache_waiter_epoll.c @@ -37,7 +37,6 @@ #include -#include #include #include diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c index a81f4c2..8bee1c9 100644 --- a/bin/varnishd/cache_waiter_kqueue.c +++ b/bin/varnishd/cache_waiter_kqueue.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c index 2e02406..821ebc3 100644 --- a/bin/varnishd/cache_waiter_ports.c +++ b/bin/varnishd/cache_waiter_ports.c @@ -35,7 +35,6 @@ #include -#include #include #include #include diff --git a/bin/varnishd/common.h b/bin/varnishd/common.h index 13249eb..4e56a40 100644 --- a/bin/varnishd/common.h +++ b/bin/varnishd/common.h @@ -77,6 +77,10 @@ const void *pick(const struct choice *cp, const char *which, const char *kind); #define NEEDLESS_RETURN(foo) return (foo) +/* stevedore.c */ +void STV_Config(const char *spec); +void STV_Config_Transient(void); + /* vsm.c */ // extern struct VSM_head *VSM_head; // extern const struct VSM_chunk *vsm_end; diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 9d12752..2b17052 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -86,6 +86,7 @@ extern const char *mgt_vcl_dir; extern const char *mgt_vmod_dir; extern unsigned mgt_vcc_err_unref; + #define REPORT0(pri, fmt) \ do { \ fprintf(stderr, fmt "\n"); \ diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 5af26fe..2108230 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c index ff1bdf5..6deffb4 100644 --- a/bin/varnishd/stevedore.c +++ b/bin/varnishd/stevedore.c @@ -38,7 +38,7 @@ #include "cache.h" -#include "stevedore.h" +#include "storage.h" #include "vav.h" #include "vcli_priv.h" #include "vrt.h" diff --git a/bin/varnishd/stevedore.h b/bin/varnishd/stevedore.h deleted file mode 100644 index 9cd0b7b..0000000 --- a/bin/varnishd/stevedore.h +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -struct stevedore; -struct exp; -struct sess; -struct iovec; -struct object; -struct objcore; -struct stv_objsecrets; - -typedef void storage_init_f(struct stevedore *, int ac, char * const *av); -typedef void storage_open_f(const struct stevedore *); -typedef struct storage *storage_alloc_f(struct stevedore *, size_t size); -typedef void storage_trim_f(struct storage *, size_t size); -typedef void storage_free_f(struct storage *); -typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp, - unsigned ltot, const struct stv_objsecrets *); -typedef void storage_close_f(const struct stevedore *); - -/* Prototypes for VCL variable responders */ -#define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); -#include "tbl/vrt_stv_var.h" -#undef VRTSTVTYPE - -/*--------------------------------------------------------------------*/ - -struct lru { - unsigned magic; -#define LRU_MAGIC 0x3fec7bb0 - VTAILQ_HEAD(,objcore) lru_head; - struct lock mtx; -}; - -/*--------------------------------------------------------------------*/ - -struct stevedore { - unsigned magic; -#define STEVEDORE_MAGIC 0x4baf43db - const char *name; - unsigned transient; - storage_init_f *init; /* called by mgt process */ - storage_open_f *open; /* called by cache process */ - storage_alloc_f *alloc; /* --//-- */ - storage_trim_f *trim; /* --//-- */ - storage_free_f *free; /* --//-- */ - storage_close_f *close; /* --//-- */ - storage_allocobj_f *allocobj; /* --//-- */ - - struct lru *lru; - -#define VRTSTVVAR(nm, vtype, ctype, dval) storage_var_##ctype *var_##nm; -#include "tbl/vrt_stv_var.h" -#undef VRTSTVVAR - - /* private fields */ - void *priv; - - VTAILQ_ENTRY(stevedore) list; - char ident[16]; /* XXX: match VSM_chunk.ident */ -}; - -struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, - const struct stv_objsecrets *soc); - -struct object *STV_NewObject(struct sess *sp, const char *hint, unsigned len, - struct exp *, uint16_t nhttp); -struct storage *STV_alloc(const struct sess *sp, size_t size); -void STV_trim(struct storage *st, size_t size); -void STV_free(struct storage *st); -void STV_open(void); -void STV_close(void); -void STV_Config(const char *spec); -void STV_Config_Transient(void); -void STV_Freestore(struct object *o); - -struct lru *LRU_Alloc(void); -void LRU_Free(struct lru *lru); - -int STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx); -uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity, - const char *ctx); - -/* Synthetic Storage */ -void SMS_Init(void); - -extern const struct stevedore sma_stevedore; -extern const struct stevedore smf_stevedore; -extern const struct stevedore smp_stevedore; -#ifdef HAVE_LIBUMEM -extern const struct stevedore smu_stevedore; -#endif diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c index 42c2b47..e428f58 100644 --- a/bin/varnishd/stevedore_utils.c +++ b/bin/varnishd/stevedore_utils.c @@ -51,7 +51,7 @@ #include "mgt.h" -#include "stevedore.h" +#include "storage.h" #include "vnum.h" #ifndef O_LARGEFILE diff --git a/bin/varnishd/storage.h b/bin/varnishd/storage.h new file mode 100644 index 0000000..80cad13 --- /dev/null +++ b/bin/varnishd/storage.h @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * This defines the backend interface between the stevedore and the + * pluggable storage implementations. + * + */ + +struct stv_objsecrets; +struct stevedore; +struct sess; +struct lru; + +typedef void storage_init_f(struct stevedore *, int ac, char * const *av); +typedef void storage_open_f(const struct stevedore *); +typedef struct storage *storage_alloc_f(struct stevedore *, size_t size); +typedef void storage_trim_f(struct storage *, size_t size); +typedef void storage_free_f(struct storage *); +typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp, + unsigned ltot, const struct stv_objsecrets *); +typedef void storage_close_f(const struct stevedore *); + +/* Prototypes for VCL variable responders */ +#define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); +#include "tbl/vrt_stv_var.h" +#undef VRTSTVTYPE + +/*--------------------------------------------------------------------*/ + +struct stevedore { + unsigned magic; +#define STEVEDORE_MAGIC 0x4baf43db + const char *name; + unsigned transient; + storage_init_f *init; /* called by mgt process */ + storage_open_f *open; /* called by cache process */ + storage_alloc_f *alloc; /* --//-- */ + storage_trim_f *trim; /* --//-- */ + storage_free_f *free; /* --//-- */ + storage_close_f *close; /* --//-- */ + storage_allocobj_f *allocobj; /* --//-- */ + + struct lru *lru; + +#define VRTSTVVAR(nm, vtype, ctype, dval) storage_var_##ctype *var_##nm; +#include "tbl/vrt_stv_var.h" +#undef VRTSTVVAR + + /* private fields */ + void *priv; + + VTAILQ_ENTRY(stevedore) list; + char ident[16]; /* XXX: match VSM_chunk.ident */ +}; + +/*--------------------------------------------------------------------*/ +int STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx); +uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity, + const char *ctx); +struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, + const struct stv_objsecrets *soc); + +struct lru *LRU_Alloc(void); +void LRU_Free(struct lru *lru); + +/*--------------------------------------------------------------------*/ +extern const struct stevedore sma_stevedore; +extern const struct stevedore smf_stevedore; +extern const struct stevedore smp_stevedore; +#ifdef HAVE_LIBUMEM +extern const struct stevedore smu_stevedore; +#endif diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c index 171d9d0..ecfc4ff 100644 --- a/bin/varnishd/storage_file.c +++ b/bin/varnishd/storage_file.c @@ -37,8 +37,8 @@ #include #include "cache.h" +#include "storage.h" -#include "stevedore.h" #include "vnum.h" #ifndef MAP_NOCORE diff --git a/bin/varnishd/storage_malloc.c b/bin/varnishd/storage_malloc.c index bc5a565..967137c 100644 --- a/bin/varnishd/storage_malloc.c +++ b/bin/varnishd/storage_malloc.c @@ -35,8 +35,8 @@ #include #include "cache.h" +#include "storage.h" -#include "stevedore.h" #include "vnum.h" struct sma_sc { diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c index d379c4a..abe25f6 100644 --- a/bin/varnishd/storage_persistent.c +++ b/bin/varnishd/storage_persistent.c @@ -44,9 +44,9 @@ #include #include "cache.h" +#include "storage.h" #include "hash_slinger.h" -#include "stevedore.h" #include "vcli.h" #include "vcli_priv.h" #include "vend.h" diff --git a/bin/varnishd/storage_persistent_mgt.c b/bin/varnishd/storage_persistent_mgt.c index 7ec9089..2cdcc6b 100644 --- a/bin/varnishd/storage_persistent_mgt.c +++ b/bin/varnishd/storage_persistent_mgt.c @@ -42,8 +42,8 @@ #include #include "cache.h" +#include "storage.h" -#include "stevedore.h" #include "vsha256.h" #include "persistent.h" diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c index be2e2bf..8209613 100644 --- a/bin/varnishd/storage_persistent_silo.c +++ b/bin/varnishd/storage_persistent_silo.c @@ -38,9 +38,9 @@ #include #include "cache.h" +#include "storage.h" #include "hash_slinger.h" -#include "stevedore.h" #include "vsha256.h" #include "vtim.h" diff --git a/bin/varnishd/storage_persistent_subr.c b/bin/varnishd/storage_persistent_subr.c index e3df368..b4bbb3f 100644 --- a/bin/varnishd/storage_persistent_subr.c +++ b/bin/varnishd/storage_persistent_subr.c @@ -42,6 +42,7 @@ #include #include "cache.h" +#include "storage.h" #include "vsha256.h" diff --git a/bin/varnishd/storage_synth.c b/bin/varnishd/storage_synth.c index 0792dbd..5df2c08 100644 --- a/bin/varnishd/storage_synth.c +++ b/bin/varnishd/storage_synth.c @@ -33,8 +33,8 @@ #include #include "cache.h" +#include "storage.h" -#include "stevedore.h" static struct lock sms_mtx; diff --git a/bin/varnishd/storage_umem.c b/bin/varnishd/storage_umem.c index 4459a47..9198a99 100644 --- a/bin/varnishd/storage_umem.c +++ b/bin/varnishd/storage_umem.c @@ -40,8 +40,7 @@ #include #include "cache.h" - -#include "stevedore.h" +#include "storage.h" static size_t smu_max = SIZE_MAX; static MTX smu_mtx; diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 722c10e..7fe72aa 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -48,7 +47,6 @@ #include "hash_slinger.h" #include "heritage.h" -#include "stevedore.h" #include "vav.h" #include "vcli.h" #include "vcli_common.h" From apj at varnish-cache.org Mon Oct 10 12:57:11 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Mon, 10 Oct 2011 14:57:11 +0200 Subject: [master] 7a0dc3f Add default values for some fields when logging imcomplete records. Allow %r format to log incomplete records too. Update docs to reflect new defaults Message-ID: commit 7a0dc3f78987b37edc927c231a42879915e9f2ac Author: Andreas Plesner Jacobsen Date: Mon Oct 10 14:55:55 2011 +0200 Add default values for some fields when logging imcomplete records. Allow %r format to log incomplete records too. Update docs to reflect new defaults Fixes #1028 diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 26ede48..47e5e2a 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -603,7 +603,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'H': - VSB_cat(os, lp->df_H); + VSB_cat(os, lp->df_H ? lp->df_H : "HTTP/1.0"); break; case 'h': @@ -617,7 +617,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'm': - VSB_cat(os, lp->df_m); + VSB_cat(os, lp->df_m ? lp->df_m : "-"); break; case 'q': @@ -629,24 +629,19 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, * Fake "%r". This would be a lot easier if Varnish * normalized the request URL. */ - if (!lp->df_m || - !req_header(lp, "Host") || - !lp->df_U || - !lp->df_H) { - clean_logline(lp); - return (reopen); - } - VSB_cat(os, lp->df_m); + VSB_cat(os, lp->df_m ? lp->df_m : "-"); VSB_putc(os, ' '); if (req_header(lp, "Host")) { if (strncmp(req_header(lp, "Host"), "http://", 7) != 0) VSB_cat(os, "http://"); VSB_cat(os, req_header(lp, "Host")); + } else { + VSB_cat(os, "http://localhost"); } - VSB_cat(os, lp->df_U); + VSB_cat(os, lp->df_U ? lp->df_U : "-"); VSB_cat(os, lp->df_q ? lp->df_q : ""); VSB_putc(os, ' '); - VSB_cat(os, lp->df_H); + VSB_cat(os, lp->df_H ? lp->df_H : "HTTP/1.0"); break; case 's': @@ -661,7 +656,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'U': - VSB_cat(os, lp->df_U); + VSB_cat(os, lp->df_U ? lp->df_U : "-"); break; case 'u': diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index a4bac0a..e654e37 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -62,10 +62,12 @@ The following options are available: bytes are sent. %H - The request protocol + The request protocol. Defaults to HTTP/1.0 if not + known. %h - Remote host + Remote host. Defaults to '-' if not known. + Defaults to 127.0.0.1 for backend requests. %{X}i The contents of request header line X. @@ -74,16 +76,18 @@ The following options are available: Remote logname (always '-') %m - Request method + Request method. Defaults to '-' if not known. %q - The query string, if no query string exists, an empty string. + The query string, if no query string exists, an + empty string. %{X}o The contents of response header line X. %r - The first line of the request + The first line of the request. Synthesized from other + fields, so it may not be the request verbatim. %s Status sent to the client @@ -93,7 +97,8 @@ The following options are available: format. %U - The request URL without any query string. + The request URL without any query string. Defaults to + '-' if not known. %u Remote user from auth From apj at varnish-cache.org Mon Oct 10 20:57:13 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Mon, 10 Oct 2011 22:57:13 +0200 Subject: [master] 3ede515 Smartypants is bad for code. People couldn't copy/paste from the reference pages Message-ID: commit 3ede515d3401ffca7766abfee549826c92fbcc3d Author: Andreas Plesner Jacobsen Date: Mon Oct 10 22:56:34 2011 +0200 Smartypants is bad for code. People couldn't copy/paste from the reference pages diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in index 0b07a2b..5cef666 100644 --- a/doc/sphinx/conf.py.in +++ b/doc/sphinx/conf.py.in @@ -155,7 +155,7 @@ html_title = "Varnish version @VERSION@ documentation" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +html_use_smartypants = False # Custom sidebar templates, maps document names to template names. #html_sidebars = {} From lkarsten at varnish-cache.org Tue Oct 11 08:00:52 2011 From: lkarsten at varnish-cache.org (Lasse Karstensen) Date: Tue, 11 Oct 2011 10:00:52 +0200 Subject: [master] f4f1e8a Add short segment on VMs / OpenVZ Message-ID: commit f4f1e8ad2e9ffff37a10c2bf673c2da65a54ece9 Author: Lasse Karstensen Date: Tue Oct 11 09:59:00 2011 +0200 Add short segment on VMs / OpenVZ diff --git a/doc/sphinx/tutorial/index.rst b/doc/sphinx/tutorial/index.rst index e0e5023..59fd94e 100644 --- a/doc/sphinx/tutorial/index.rst +++ b/doc/sphinx/tutorial/index.rst @@ -26,6 +26,7 @@ separate topic. Good luck. vary purging esi + virtualised advanced_backend_servers handling_misbehaving_servers advanced_topics diff --git a/doc/sphinx/tutorial/virtualised.rst b/doc/sphinx/tutorial/virtualised.rst new file mode 100644 index 0000000..ce4b9ad --- /dev/null +++ b/doc/sphinx/tutorial/virtualised.rst @@ -0,0 +1,20 @@ + +Running inside a virtual machine (VM) +------------------------------------- + +It is possible, but not recommended for high performance, to run Varnish on virtualised +hardware. + +OpenVZ +'''''' + +If you are running on 64bit OpenVZ (or Parallels VPS), you must reduce the +maximum stack size before starting Varnish. The default allocates to much memory per thread, +which will make varnish fail as soon as the number of threads (==traffic) increases. + +Reduce the maximum stack size by running:: + + ulimit -s 256 + +in the startup script. + From phk at varnish-cache.org Wed Oct 12 08:19:51 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 10:19:51 +0200 Subject: [master] 3b73cf0 Close a race where varnishtest::client would attempt to connect before varnishd::acceptor had called listen(2) Message-ID: commit 3b73cf0e92f432c23387ca498d7783f1d1b18bee Author: Poul-Henning Kamp Date: Wed Oct 12 08:18:43 2011 +0000 Close a race where varnishtest::client would attempt to connect before varnishd::acceptor had called listen(2) Found and fixed by: slink aka. Nils Goroll diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c index e6ad6e3..f92bace 100644 --- a/bin/varnishd/cache_acceptor.c +++ b/bin/varnishd/cache_acceptor.c @@ -376,6 +376,16 @@ ccf_listen_address(struct cli *cli, const char * const *av, void *priv) (void)cli; (void)av; (void)priv; + + /* + * This CLI command is primarily used by varnishtest. Don't + * respond until liste(2) has been called, in order to avoid + * a race where varnishtest::client would attempt to connect(2) + * before listen(2) has been called. + */ + while(!hack_ready) + (void)usleep(100*1000); + VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock < 0) continue; From phk at varnish-cache.org Wed Oct 12 08:30:16 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 10:30:16 +0200 Subject: [master] 1a80a01 Solaris sandbox changes. Message-ID: commit 1a80a0197d49b231d4fd97d9b01609c187db569b Author: Poul-Henning Kamp Date: Wed Oct 12 08:29:41 2011 +0000 Solaris sandbox changes. Submitted by: Nils Goroll diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 2b17052..1656af8 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -70,6 +70,7 @@ void mgt_sandbox(void); #ifdef HAVE_SETPPRIV void mgt_sandbox_solaris_init(void); void mgt_sandbox_solaris_fini(void); +void mgt_sandbox_solaris_privsep(void); #endif /* mgt_shmem.c */ diff --git a/bin/varnishd/mgt_sandbox.c b/bin/varnishd/mgt_sandbox.c index 3aba7cc..8ac827d 100644 --- a/bin/varnishd/mgt_sandbox.c +++ b/bin/varnishd/mgt_sandbox.c @@ -63,17 +63,17 @@ void mgt_sandbox(void) { - #ifdef HAVE_SETPPRIV mgt_sandbox_solaris_init(); -#endif - + mgt_sandbox_solaris_privsep(); +#else if (geteuid() == 0) { XXXAZ(setgid(params->gid)); XXXAZ(setuid(params->uid)); } else { REPORT0(LOG_INFO, "Not running as root, no priv-sep"); } +#endif /* On Linux >= 2.4, you need to set the dumpable flag to get core dumps after you have done a setuid. */ diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 5c50c83..534f609 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "mgt.h" @@ -153,6 +154,20 @@ mgt_sandbox_solaris_init(void) priv_freeset(priv_all); } +void +mgt_sandbox_solaris_privsep(void) +{ + if (priv_ineffect(PRIV_PROC_SETID)) { + if (getgid() != params->gid) + XXXAZ(setgid(params->gid)); + if (getuid() != params->uid) + XXXAZ(setuid(params->uid)); + } else { + REPORT(LOG_INFO, "Privilege %s missing, will not change uid/gid", + PRIV_PROC_SETID); + } +} + /* * Waive most privileges in the child * From phk at varnish-cache.org Wed Oct 12 08:44:56 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 10:44:56 +0200 Subject: [master] 5a385b5 Add a necessary #include Message-ID: commit 5a385b581d41002e7bdd19776f262bd35b222c41 Author: Poul-Henning Kamp Date: Wed Oct 12 08:44:46 2011 +0000 Add a necessary #include diff --git a/lib/libvarnish/vmb.c b/lib/libvarnish/vmb.c index 3f5c12d..8f130f1 100644 --- a/lib/libvarnish/vmb.c +++ b/lib/libvarnish/vmb.c @@ -28,6 +28,7 @@ #include "config.h" +#include #include #include From phk at varnish-cache.org Wed Oct 12 08:48:01 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 10:48:01 +0200 Subject: [master] e97567d requires Message-ID: commit e97567d452f793d59e93192c55d11be6555b6c03 Author: Poul-Henning Kamp Date: Wed Oct 12 08:47:45 2011 +0000 requires diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index 818b9ab..f5d6054 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -32,6 +32,7 @@ #include #ifdef HAVE_LIBEDIT +#include #include #endif From phk at varnish-cache.org Wed Oct 12 11:19:48 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 13:19:48 +0200 Subject: [master] aff259b Move struct vbc to cache_backend.h Message-ID: commit aff259bc2e0e19af8a0388851bc60af25511b41d Author: Poul-Henning Kamp Date: Wed Oct 12 11:19:37 2011 +0000 Move struct vbc to cache_backend.h diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 930f197..7eb3258 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -91,26 +91,27 @@ enum { HTTP_HDR_FIRST, }; -struct iovec; +struct SHA256Context; +struct VSC_C_lck; +struct ban; +struct busyobj; struct cli; -struct exp; -struct vsb; -struct sess; +struct cli_proto; struct director; +struct exp; +struct iovec; +struct objcore; struct object; struct objhead; -struct objcore; -struct busyobj; -struct storage; +struct pool; +struct sess; struct sesspool; +struct storage; +struct vbc; +struct vef_priv; struct vrt_backend; -struct cli_proto; -struct ban; -struct SHA256Context; -struct VSC_C_lck; +struct vsb; struct waitinglist; -struct vef_priv; -struct pool; #define DIGEST_LEN 32 @@ -627,28 +628,6 @@ struct sess { #endif }; -/* -------------------------------------------------------------------*/ - -/* Backend connection */ -struct vbc { - unsigned magic; -#define VBC_MAGIC 0x0c5e6592 - VTAILQ_ENTRY(vbc) list; - struct backend *backend; - struct vdi_simple *vdis; - unsigned vsl_id; - int fd; - - struct sockaddr_storage *addr; - socklen_t addrlen; - - uint8_t recycled; - - /* Timeouts */ - double first_byte_timeout; - double between_bytes_timeout; -}; - /* Prototypes etc ----------------------------------------------------*/ /* cache_acceptor.c */ diff --git a/bin/varnishd/cache_backend.h b/bin/varnishd/cache_backend.h index 21a7061..47e709d 100644 --- a/bin/varnishd/cache_backend.h +++ b/bin/varnishd/cache_backend.h @@ -134,6 +134,28 @@ struct backend { struct VSC_C_vbe *vsc; }; +/* -------------------------------------------------------------------*/ + +/* Backend connection */ +struct vbc { + unsigned magic; +#define VBC_MAGIC 0x0c5e6592 + VTAILQ_ENTRY(vbc) list; + struct backend *backend; + struct vdi_simple *vdis; + unsigned vsl_id; + int fd; + + struct sockaddr_storage *addr; + socklen_t addrlen; + + uint8_t recycled; + + /* Timeouts */ + double first_byte_timeout; + double between_bytes_timeout; +}; + /* cache_backend.c */ void VBE_ReleaseConn(struct vbc *vc); struct backend *vdi_get_backend_if_simple(const struct director *d); diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index ea4d367..01da3f2 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -40,6 +40,7 @@ #include "cache.h" +#include "cache_backend.h" // struct vbc #include "hash_slinger.h" // objhead #include "vcli.h" #include "vcli_common.h" diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 4300780..26489b6 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -36,6 +36,7 @@ #include "cache.h" +#include "cache_backend.h" #include "vcli_priv.h" #include "vct.h" #include "vtcp.h" diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index c9bc0ac..8f109a5 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -36,6 +36,7 @@ #include "cache.h" +#include "cache_backend.h" #include "vtcp.h" #include "vtim.h" From phk at varnish-cache.org Wed Oct 12 11:33:42 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 13:33:42 +0200 Subject: [master] 53a28ab These #includes look surplus to requirements. Message-ID: commit 53a28ab7ae637884ffa91ac1bed756de6febc32b Author: Poul-Henning Kamp Date: Wed Oct 12 11:33:23 2011 +0000 These #includes look surplus to requirements. diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 26489b6..71fc8e2 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -29,7 +29,6 @@ #include "config.h" -#include #include #include #include diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 12855e1..ebbe281 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -55,7 +55,6 @@ #include #include #include -#include #include "cache.h" diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 9768eeb..4f0334b 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -29,12 +29,6 @@ #include "config.h" -#include -#include - -#include -#include - #include "cache.h" #include "vct.h" diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c index c77ab08..cc67a7f 100644 --- a/bin/varnishd/cache_vcl.c +++ b/bin/varnishd/cache_vcl.c @@ -34,7 +34,6 @@ #include "config.h" #include -#include #include #include "cache.h" diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c index d9a7090..e6f854b 100644 --- a/bin/varnishd/cache_vrt_re.c +++ b/bin/varnishd/cache_vrt_re.c @@ -32,7 +32,6 @@ #include "config.h" #include -#include #include "cache.h" diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index a00b1b7..1a16e16 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -36,8 +36,6 @@ #include "cache.h" #include "cache_backend.h" -#include "hash_slinger.h" -#include "vrt.h" #include "vrt_obj.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/hash_classic.c b/bin/varnishd/hash_classic.c index 1428864..fc88757 100644 --- a/bin/varnishd/hash_classic.c +++ b/bin/varnishd/hash_classic.c @@ -31,11 +31,8 @@ #include "config.h" -#include - #include #include -#include #include "cache.h" From phk at varnish-cache.org Wed Oct 12 15:26:00 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 17:26:00 +0200 Subject: [master] ebd1601 Reduce #include pollution Message-ID: commit ebd1601675c542b9004ae8d89b4e65b80779c668 Author: Poul-Henning Kamp Date: Wed Oct 12 15:25:45 2011 +0000 Reduce #include pollution diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index ebbe281..14c5e7c 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -58,7 +58,6 @@ #include "cache.h" -#include "cache_backend.h" #include "hash_slinger.h" #include "vav.h" #include "vsha256.h" @@ -311,7 +310,7 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC); - CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); + AN(sp->director); AN(hash); w = sp->wrk; From phk at varnish-cache.org Wed Oct 12 15:44:44 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 17:44:44 +0200 Subject: [master] fe78027 Move everything related to the storage-expansion-API into a subdirectory where it will be protected from VMODs. Message-ID: commit fe780278743797013f6f26f0701b478a77d6b32a Author: Poul-Henning Kamp Date: Wed Oct 12 15:44:14 2011 +0000 Move everything related to the storage-expansion-API into a subdirectory where it will be protected from VMODs. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 2b822fa..5260427 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -64,16 +64,16 @@ varnishd_SOURCES = \ mgt_shmem.c \ mgt_vcc.c \ rfc2616.c \ - stevedore.c \ - stevedore_utils.c \ - storage_file.c \ - storage_malloc.c \ - storage_persistent.c \ - storage_persistent_mgt.c \ - storage_persistent_silo.c \ - storage_persistent_subr.c \ - storage_synth.c \ - storage_umem.c \ + storage/stevedore.c \ + storage/stevedore_utils.c \ + storage/storage_file.c \ + storage/storage_malloc.c \ + storage/storage_persistent.c \ + storage/storage_persistent_mgt.c \ + storage/storage_persistent_silo.c \ + storage/storage_persistent_subr.c \ + storage/storage_synth.c \ + storage/storage_umem.c \ varnishd.c \ vsm.c @@ -88,8 +88,8 @@ noinst_HEADERS = \ heritage.h \ mgt.h \ mgt_cli.h \ - storage.h \ - storage_persistent.h \ + storage/storage.h \ + storage/storage_persistent.h \ vparam.h varnishd_CFLAGS = \ diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 7eb3258..33ccc8b 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -98,7 +98,6 @@ struct busyobj; struct cli; struct cli_proto; struct director; -struct exp; struct iovec; struct objcore; struct object; @@ -106,7 +105,6 @@ struct objhead; struct pool; struct sess; struct sesspool; -struct storage; struct vbc; struct vef_priv; struct vrt_backend; diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index 690e445..86d4ad0 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -16,6 +16,7 @@ flexelint \ -I/usr/local/include \ -DVARNISH_STATE_DIR=\"foo\" \ *.c \ + storage/*.c \ ../../lib/libvarnish/*.c \ ../../lib/libvarnishcompat/execinfo.c \ ../../lib/libvcl/*.c \ diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c deleted file mode 100644 index 6deffb4..0000000 --- a/bin/varnishd/stevedore.c +++ /dev/null @@ -1,602 +0,0 @@ -/*- - * Copyright (c) 2007-2011 Varnish Software AS - * All rights reserved. - * - * Author: Dag-Erling Sm?rgav - * - * 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. - * - * STEVEDORE: one who works at or is responsible for loading and - * unloading ships in port. Example: "on the wharves, stevedores were - * unloading cargo from the far corners of the world." Origin: Spanish - * estibador, from estibar to pack. First Known Use: 1788 - */ - -#include "config.h" - -#include -#include - -#include "cache.h" - -#include "storage.h" -#include "vav.h" -#include "vcli_priv.h" -#include "vrt.h" -#include "vrt_obj.h" - -static VTAILQ_HEAD(, stevedore) stevedores = - VTAILQ_HEAD_INITIALIZER(stevedores); - -static const struct stevedore * volatile stv_next; - -static struct stevedore *stv_transient; - -/*--------------------------------------------------------------------- - * Default objcore methods - */ - -static struct object * __match_proto__(getobj_f) -default_oc_getobj(struct worker *wrk, struct objcore *oc) -{ - struct object *o; - - (void)wrk; - if (oc->priv == NULL) - return (NULL); - CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); - return (o); -} - -static void -default_oc_freeobj(struct objcore *oc) -{ - struct object *o; - - CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); - oc->priv = NULL; - oc->methods = NULL; - - STV_Freestore(o); - STV_free(o->objstore); -} - -static struct lru * -default_oc_getlru(const struct objcore *oc) -{ - struct object *o; - - CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); - return (o->objstore->stevedore->lru); -} - -static struct objcore_methods default_oc_methods = { - .getobj = default_oc_getobj, - .freeobj = default_oc_freeobj, - .getlru = default_oc_getlru, -}; - - -/*-------------------------------------------------------------------- - */ - -struct lru * -LRU_Alloc(void) -{ - struct lru *l; - - ALLOC_OBJ(l, LRU_MAGIC); - AN(l); - VTAILQ_INIT(&l->lru_head); - Lck_New(&l->mtx, lck_lru); - return (l); -} - -void -LRU_Free(struct lru *lru) -{ - CHECK_OBJ_NOTNULL(lru, LRU_MAGIC); - Lck_Delete(&lru->mtx); - FREE_OBJ(lru); -} - -/*-------------------------------------------------------------------- - * XXX: trust pointer writes to be atomic - */ - -static struct stevedore * -stv_pick_stevedore(const struct sess *sp, const char **hint) -{ - struct stevedore *stv; - - AN(hint); - if (*hint != NULL && **hint != '\0') { - VTAILQ_FOREACH(stv, &stevedores, list) { - if (!strcmp(stv->ident, *hint)) - return (stv); - } - if (!strcmp(TRANSIENT_STORAGE, *hint)) - return (stv_transient); - - /* Hint was not valid, nuke it */ - WSP(sp, SLT_Debug, "Storage hint not usable"); - *hint = NULL; - } - /* pick a stevedore and bump the head along */ - stv = VTAILQ_NEXT(stv_next, list); - if (stv == NULL) - stv = VTAILQ_FIRST(&stevedores); - AN(stv); - AN(stv->name); - stv_next = stv; - return (stv); -} - -/*-------------------------------------------------------------------*/ - -static struct storage * -stv_alloc(const struct sess *sp, size_t size) -{ - struct storage *st; - struct stevedore *stv; - unsigned fail = 0; - - /* - * Always use the stevedore which allocated the object in order to - * keep an object inside the same stevedore. - */ - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - stv = sp->obj->objstore->stevedore; - CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC); - - if (size > (size_t)(params->fetch_maxchunksize) << 10) - size = (size_t)(params->fetch_maxchunksize) << 10; - - for (;;) { - /* try to allocate from it */ - AN(stv->alloc); - st = stv->alloc(stv, size); - if (st != NULL) - break; - - if (size > params->fetch_chunksize * 1024LL) { - size >>= 1; - continue; - } - - /* no luck; try to free some space and keep trying */ - if (EXP_NukeOne(sp, stv->lru) == -1) - break; - - /* Enough is enough: try another if we have one */ - if (++fail >= params->nuke_limit) - break; - } - if (st != NULL) - CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); - return (st); -} - - -/*-------------------------------------------------------------------* - * Structure used to transport internal knowledge from STV_NewObject() - * to STV_MkObject(). Nobody else should mess with this struct. - */ - -struct stv_objsecrets { - unsigned magic; -#define STV_OBJ_SECRETES_MAGIC 0x78c87247 - uint16_t nhttp; - unsigned lhttp; - unsigned wsl; - struct exp *exp; -}; - -/*-------------------------------------------------------------------- - * This function is called by stevedores ->allocobj() method, which - * very often will be stv_default_allocobj() below, to convert a slab - * of storage into object which the stevedore can then register in its - * internal state, before returning it to STV_NewObject(). - * As you probably guessed: All this for persistence. - */ - -struct object * -STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, - const struct stv_objsecrets *soc) -{ - struct object *o; - unsigned l; - - CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC); - - assert(PAOK(ptr)); - assert(PAOK(soc->wsl)); - assert(PAOK(soc->lhttp)); - - assert(ltot >= sizeof *o + soc->lhttp + soc->wsl); - - o = ptr; - memset(o, 0, sizeof *o); - o->magic = OBJECT_MAGIC; - - l = PRNDDN(ltot - (sizeof *o + soc->lhttp)); - assert(l >= soc->wsl); - - o->http = HTTP_create(o + 1, soc->nhttp); - WS_Init(o->ws_o, "obj", (char *)(o + 1) + soc->lhttp, soc->wsl); - WS_Assert(o->ws_o); - assert(o->ws_o->e <= (char*)ptr + ltot); - - http_Setup(o->http, o->ws_o); - o->http->magic = HTTP_MAGIC; - o->exp = *soc->exp; - VTAILQ_INIT(&o->store); - sp->wrk->stats.n_object++; - - if (sp->objcore != NULL) { - CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); - - o->objcore = sp->objcore; - sp->objcore = NULL; /* refcnt follows pointer. */ - BAN_NewObjCore(o->objcore); - - o->objcore->methods = &default_oc_methods; - o->objcore->priv = o; - } - return (o); -} - -/*-------------------------------------------------------------------- - * This is the default ->allocobj() which all stevedores who do not - * implement persistent storage can rely on. - */ - -static struct object * -stv_default_allocobj(struct stevedore *stv, struct sess *sp, unsigned ltot, - const struct stv_objsecrets *soc) -{ - struct object *o; - struct storage *st; - - CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC); - st = stv->alloc(stv, ltot); - if (st == NULL) - return (NULL); - if (st->space < ltot) { - stv->free(st); - return (NULL); - } - ltot = st->len = st->space; - o = STV_MkObject(sp, st->ptr, ltot, soc); - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - o->objstore = st; - return (o); -} - -/*------------------------------------------------------------------- - * Allocate storage for an object, based on the header information. - * XXX: If we know (a hint of) the length, we could allocate space - * XXX: for the body in the same allocation while we are at it. - */ - -struct object * -STV_NewObject(struct sess *sp, const char *hint, unsigned wsl, struct exp *ep, - uint16_t nhttp) -{ - struct object *o; - struct stevedore *stv, *stv0; - unsigned lhttp, ltot; - struct stv_objsecrets soc; - int i; - - assert(wsl > 0); - wsl = PRNDUP(wsl); - - lhttp = HTTP_estimate(nhttp); - lhttp = PRNDUP(lhttp); - - memset(&soc, 0, sizeof soc); - soc.magic = STV_OBJ_SECRETES_MAGIC; - soc.nhttp = nhttp; - soc.lhttp = lhttp; - soc.wsl = wsl; - soc.exp = ep; - - ltot = sizeof *o + wsl + lhttp; - - stv = stv0 = stv_pick_stevedore(sp, &hint); - AN(stv->allocobj); - o = stv->allocobj(stv, sp, ltot, &soc); - if (o == NULL && hint == NULL) { - do { - stv = stv_pick_stevedore(sp, &hint); - AN(stv->allocobj); - o = stv->allocobj(stv, sp, ltot, &soc); - } while (o == NULL && stv != stv0); - } - if (o == NULL) { - /* no luck; try to free some space and keep trying */ - for (i = 0; o == NULL && i < params->nuke_limit; i++) { - if (EXP_NukeOne(sp, stv->lru) == -1) - break; - o = stv->allocobj(stv, sp, ltot, &soc); - } - } - - if (o == NULL) - return (NULL); - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - CHECK_OBJ_NOTNULL(o->objstore, STORAGE_MAGIC); - return (o); -} - -/*-------------------------------------------------------------------*/ - -void -STV_Freestore(struct object *o) -{ - struct storage *st, *stn; - - if (o->esidata != NULL) { - STV_free(o->esidata); - o->esidata = NULL; - } - VTAILQ_FOREACH_SAFE(st, &o->store, list, stn) { - CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); - VTAILQ_REMOVE(&o->store, st, list); - STV_free(st); - } -} - -/*-------------------------------------------------------------------*/ - -struct storage * -STV_alloc(const struct sess *sp, size_t size) -{ - - return (stv_alloc(sp, size)); -} - -void -STV_trim(struct storage *st, size_t size) -{ - - CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); - AN(st->stevedore); - if (st->stevedore->trim) - st->stevedore->trim(st, size); -} - -void -STV_free(struct storage *st) -{ - - CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); - AN(st->stevedore); - AN(st->stevedore->free); - st->stevedore->free(st); -} - -void -STV_open(void) -{ - struct stevedore *stv; - - VTAILQ_FOREACH(stv, &stevedores, list) { - stv->lru = LRU_Alloc(); - if (stv->open != NULL) - stv->open(stv); - } - stv = stv_transient; - if (stv->open != NULL) { - stv->lru = LRU_Alloc(); - stv->open(stv); - } -} - -void -STV_close(void) -{ - struct stevedore *stv; - - VTAILQ_FOREACH(stv, &stevedores, list) - if (stv->close != NULL) - stv->close(stv); - stv = stv_transient; - if (stv->close != NULL) - stv->close(stv); -} - -/*-------------------------------------------------------------------- - * Parse a stevedore argument on the form: - * [ name '=' ] strategy [ ',' arg ] * - */ - -static const struct choice STV_choice[] = { - { "file", &smf_stevedore }, - { "malloc", &sma_stevedore }, - { "persistent", &smp_stevedore }, -#ifdef HAVE_LIBUMEM - { "umem", &smu_stevedore }, -#endif - { NULL, NULL } -}; - -void -STV_Config(const char *spec) -{ - char **av; - const char *p, *q; - struct stevedore *stv; - const struct stevedore *stv2; - int ac, l; - static unsigned seq = 0; - - ASSERT_MGT(); - p = strchr(spec, '='); - q = strchr(spec, ','); - if (p != NULL && (q == NULL || q > p)) { - av = VAV_Parse(p + 1, NULL, ARGV_COMMA); - } else { - av = VAV_Parse(spec, NULL, ARGV_COMMA); - p = NULL; - } - AN(av); - - if (av[0] != NULL) - ARGV_ERR("%s\n", av[0]); - - if (av[1] == NULL) - ARGV_ERR("-s argument lacks strategy {malloc, file, ...}\n"); - - for (ac = 0; av[ac + 2] != NULL; ac++) - continue; - - stv2 = pick(STV_choice, av[1], "storage"); - AN(stv2); - - /* Append strategy to ident string */ - VSB_printf(vident, ",-s%s", av[1]); - - av += 2; - - CHECK_OBJ_NOTNULL(stv2, STEVEDORE_MAGIC); - ALLOC_OBJ(stv, STEVEDORE_MAGIC); - AN(stv); - - *stv = *stv2; - AN(stv->name); - AN(stv->alloc); - if (stv->allocobj == NULL) - stv->allocobj = stv_default_allocobj; - - if (p == NULL) - bprintf(stv->ident, "s%u", seq++); - else { - l = p - spec; - if (l > sizeof stv->ident - 1) - l = sizeof stv->ident - 1; - bprintf(stv->ident, "%.*s", l, spec); - } - - VTAILQ_FOREACH(stv2, &stevedores, list) { - if (strcmp(stv2->ident, stv->ident)) - continue; - ARGV_ERR("(-s%s=%s) already defined once\n", - stv->ident, stv->name); - } - - if (stv->init != NULL) - stv->init(stv, ac, av); - else if (ac != 0) - ARGV_ERR("(-s%s) too many arguments\n", stv->name); - - if (!strcmp(stv->ident, TRANSIENT_STORAGE)) { - stv->transient = 1; - AZ(stv_transient); - stv_transient = stv; - } else { - VTAILQ_INSERT_TAIL(&stevedores, stv, list); - if (!stv_next) - stv_next = VTAILQ_FIRST(&stevedores); - } -} - -/*--------------------------------------------------------------------*/ - -void -STV_Config_Transient(void) -{ - - ASSERT_MGT(); - - if (stv_transient == NULL) - STV_Config(TRANSIENT_STORAGE "=malloc"); -} - -/*--------------------------------------------------------------------*/ - -static void -stv_cli_list(struct cli *cli, const char * const *av, void *priv) -{ - struct stevedore *stv; - - ASSERT_MGT(); - (void)av; - (void)priv; - VCLI_Out(cli, "Storage devices:\n"); - stv = stv_transient; - VCLI_Out(cli, "\tstorage.%s = %s\n", stv->ident, stv->name); - VTAILQ_FOREACH(stv, &stevedores, list) - VCLI_Out(cli, "\tstorage.%s = %s\n", stv->ident, stv->name); -} - -/*--------------------------------------------------------------------*/ - -struct cli_proto cli_stv[] = { - { "storage.list", "storage.list", "List storage devices\n", - 0, 0, "", stv_cli_list }, - { NULL} -}; - -/*-------------------------------------------------------------------- - * VRT functions for stevedores - */ - -static const struct stevedore * -stv_find(const char *nm) -{ - const struct stevedore *stv; - - VTAILQ_FOREACH(stv, &stevedores, list) - if (!strcmp(stv->ident, nm)) - return (stv); - if (!strcmp(TRANSIENT_STORAGE, nm)) - return (stv_transient); - return (NULL); -} - -int -VRT_Stv(const char *nm) -{ - - if (stv_find(nm) != NULL) - return (1); - return (0); -} - -#define VRTSTVVAR(nm, vtype, ctype, dval) \ -ctype \ -VRT_Stv_##nm(const char *nm) \ -{ \ - const struct stevedore *stv; \ - \ - stv = stv_find(nm); \ - if (stv == NULL) \ - return (dval); \ - if (stv->var_##nm == NULL) \ - return (dval); \ - return (stv->var_##nm(stv)); \ -} - -#include "tbl/vrt_stv_var.h" -#undef VRTSTVVAR diff --git a/bin/varnishd/stevedore_utils.c b/bin/varnishd/stevedore_utils.c deleted file mode 100644 index e428f58..0000000 --- a/bin/varnishd/stevedore_utils.c +++ /dev/null @@ -1,244 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - * Utility functions for stevedores and storage modules - */ - -#include "config.h" - -#include -#include -#ifdef HAVE_SYS_MOUNT_H -# include -#endif -#ifdef HAVE_SYS_STATVFS_H -# include -#endif -#ifdef HAVE_SYS_VFS_H -# include -#endif - -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "storage.h" -#include "vnum.h" - -#ifndef O_LARGEFILE -#define O_LARGEFILE 0 -#endif - -/*-------------------------------------------------------------------- - * Get a storage file. - * - * The fn argument can be an existing file, an existing directory or - * a nonexistent filename in an existing directory. - * - * If a directory is specified, the file will be anonymous (unlinked) - * - * Return: - * 0 if the file was preexisting. - * 1 if the file was created. - * 2 if the file is anonymous. - * - * Uses ARGV_ERR to exit in case of trouble. - */ - -int -STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx) -{ - int fd; - struct stat st; - int retval = 1; - char buf[FILENAME_MAX]; - - AN(fn); - AN(fnp); - AN(fdp); - *fnp = NULL; - *fdp = -1; - - /* try to create a new file of this name */ - fd = open(fn, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, 0600); - if (fd >= 0) { - *fdp = fd; - *fnp = fn; - return (retval); - } - - if (stat(fn, &st)) - ARGV_ERR( - "(%s) \"%s\" does not exist and could not be created\n", - ctx, fn); - - if (S_ISDIR(st.st_mode)) { - bprintf(buf, "%s/varnish.XXXXXX", fn); - fd = mkstemp(buf); - if (fd < 0) - ARGV_ERR("(%s) \"%s\" mkstemp(%s) failed (%s)\n", - ctx, fn, buf, strerror(errno)); - AZ(unlink(buf)); - *fnp = strdup(buf); - AN(*fnp); - retval = 2; - } else if (S_ISREG(st.st_mode)) { - fd = open(fn, O_RDWR | O_LARGEFILE); - if (fd < 0) - ARGV_ERR("(%s) \"%s\" could not open (%s)\n", - ctx, fn, strerror(errno)); - *fnp = fn; - retval = 0; - } else - ARGV_ERR( - "(%s) \"%s\" is neither file nor directory\n", ctx, fn); - - AZ(fstat(fd, &st)); - if (!S_ISREG(st.st_mode)) - ARGV_ERR("(%s) \"%s\" was not a file after opening\n", - ctx, fn); - - *fdp = fd; - return (retval); -} - -/*-------------------------------------------------------------------- - * Figure out how much space is in a filesystem - */ - -static uintmax_t -stv_fsspace(int fd, unsigned *bs) -{ - uintmax_t bsize, bavail; -#if defined(HAVE_SYS_STATVFS_H) - struct statvfs fsst; - - AZ(fstatvfs(fd, &fsst)); - bsize = fsst.f_frsize; - bavail = fsst.f_bavail; -#elif defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H) - struct statfs fsst; - - AZ(fstatfs(sc->fd, &fsst)); - bsize = fsst.f_bsize; - bavail = fsst.f_bavail; -#else -#error no struct statfs / struct statvfs -#endif - - /* We use units of the larger of filesystem blocksize and pagesize */ - if (*bs < bsize) - *bs = bsize; - xxxassert(*bs % bsize == 0); - return (bsize * bavail); -} - - -/*-------------------------------------------------------------------- - * Decide file size. - * - * If the sizespecification is empty and the file exists with non-zero - * size, use that, otherwise, interpret the specification. - * - * Handle off_t sizes and pointer width limitations. - */ - -uintmax_t -STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) -{ - uintmax_t l, fssize; - unsigned bs; - const char *q; - int i; - off_t o; - struct stat st; - - AZ(fstat(fd, &st)); - xxxassert(S_ISREG(st.st_mode)); - - bs = *granularity; - fssize = stv_fsspace(fd, &bs); - xxxassert(bs % *granularity == 0); - - if ((size == NULL || *size == '\0') && st.st_size != 0) { - /* - * We have no size specification, but an existing file, - * use its existing size. - */ - l = st.st_size; - } else { - AN(size); - q = VNUM_2bytes(size, &l, fssize); - - if (q != NULL) - ARGV_ERR("(%s) size \"%s\": %s\n", size, ctx, q); - - if (l < 1024*1024) - ARGV_ERR("(-spersistent) size \"%s\": too small, " - "did you forget to specify M or G?\n", size); - } - - /* - * This trickery wouldn't be necessary if X/Open would - * just add OFF_MAX to ... - */ - i = 0; - while(1) { - o = l; - if (o == l && o > 0) - break; - l >>= 1; - i++; - } - if (i) - fprintf(stderr, "WARNING: (%s) file size reduced" - " to %ju due to system \"off_t\" limitations\n", ctx, l); - else if (l - st.st_size > fssize) { - l = fssize * 80 / 100; - fprintf(stderr, "WARNING: (%s) file size reduced" - " to %ju (80%% of available disk space)\n", ctx, l); - } - - if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */ - fprintf(stderr, - "NB: Storage size limited to 2GB on 32 bit architecture,\n" - "NB: otherwise we could run out of address space.\n" - ); - l = INT32_MAX; - } - - /* round down to multiple of filesystem blocksize or pagesize */ - l -= (l % bs); - - *granularity = bs; - return(l); -} diff --git a/bin/varnishd/storage.h b/bin/varnishd/storage.h deleted file mode 100644 index 80cad13..0000000 --- a/bin/varnishd/storage.h +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * This defines the backend interface between the stevedore and the - * pluggable storage implementations. - * - */ - -struct stv_objsecrets; -struct stevedore; -struct sess; -struct lru; - -typedef void storage_init_f(struct stevedore *, int ac, char * const *av); -typedef void storage_open_f(const struct stevedore *); -typedef struct storage *storage_alloc_f(struct stevedore *, size_t size); -typedef void storage_trim_f(struct storage *, size_t size); -typedef void storage_free_f(struct storage *); -typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp, - unsigned ltot, const struct stv_objsecrets *); -typedef void storage_close_f(const struct stevedore *); - -/* Prototypes for VCL variable responders */ -#define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); -#include "tbl/vrt_stv_var.h" -#undef VRTSTVTYPE - -/*--------------------------------------------------------------------*/ - -struct stevedore { - unsigned magic; -#define STEVEDORE_MAGIC 0x4baf43db - const char *name; - unsigned transient; - storage_init_f *init; /* called by mgt process */ - storage_open_f *open; /* called by cache process */ - storage_alloc_f *alloc; /* --//-- */ - storage_trim_f *trim; /* --//-- */ - storage_free_f *free; /* --//-- */ - storage_close_f *close; /* --//-- */ - storage_allocobj_f *allocobj; /* --//-- */ - - struct lru *lru; - -#define VRTSTVVAR(nm, vtype, ctype, dval) storage_var_##ctype *var_##nm; -#include "tbl/vrt_stv_var.h" -#undef VRTSTVVAR - - /* private fields */ - void *priv; - - VTAILQ_ENTRY(stevedore) list; - char ident[16]; /* XXX: match VSM_chunk.ident */ -}; - -/*--------------------------------------------------------------------*/ -int STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx); -uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity, - const char *ctx); -struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, - const struct stv_objsecrets *soc); - -struct lru *LRU_Alloc(void); -void LRU_Free(struct lru *lru); - -/*--------------------------------------------------------------------*/ -extern const struct stevedore sma_stevedore; -extern const struct stevedore smf_stevedore; -extern const struct stevedore smp_stevedore; -#ifdef HAVE_LIBUMEM -extern const struct stevedore smu_stevedore; -#endif diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c new file mode 100644 index 0000000..65f9f49 --- /dev/null +++ b/bin/varnishd/storage/stevedore.c @@ -0,0 +1,602 @@ +/*- + * Copyright (c) 2007-2011 Varnish Software AS + * All rights reserved. + * + * Author: Dag-Erling Sm?rgav + * + * 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. + * + * STEVEDORE: one who works at or is responsible for loading and + * unloading ships in port. Example: "on the wharves, stevedores were + * unloading cargo from the far corners of the world." Origin: Spanish + * estibador, from estibar to pack. First Known Use: 1788 + */ + +#include "config.h" + +#include +#include + +#include "cache.h" + +#include "storage/storage.h" +#include "vav.h" +#include "vcli_priv.h" +#include "vrt.h" +#include "vrt_obj.h" + +static VTAILQ_HEAD(, stevedore) stevedores = + VTAILQ_HEAD_INITIALIZER(stevedores); + +static const struct stevedore * volatile stv_next; + +static struct stevedore *stv_transient; + +/*--------------------------------------------------------------------- + * Default objcore methods + */ + +static struct object * __match_proto__(getobj_f) +default_oc_getobj(struct worker *wrk, struct objcore *oc) +{ + struct object *o; + + (void)wrk; + if (oc->priv == NULL) + return (NULL); + CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); + return (o); +} + +static void +default_oc_freeobj(struct objcore *oc) +{ + struct object *o; + + CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); + oc->priv = NULL; + oc->methods = NULL; + + STV_Freestore(o); + STV_free(o->objstore); +} + +static struct lru * +default_oc_getlru(const struct objcore *oc) +{ + struct object *o; + + CAST_OBJ_NOTNULL(o, oc->priv, OBJECT_MAGIC); + return (o->objstore->stevedore->lru); +} + +static struct objcore_methods default_oc_methods = { + .getobj = default_oc_getobj, + .freeobj = default_oc_freeobj, + .getlru = default_oc_getlru, +}; + + +/*-------------------------------------------------------------------- + */ + +struct lru * +LRU_Alloc(void) +{ + struct lru *l; + + ALLOC_OBJ(l, LRU_MAGIC); + AN(l); + VTAILQ_INIT(&l->lru_head); + Lck_New(&l->mtx, lck_lru); + return (l); +} + +void +LRU_Free(struct lru *lru) +{ + CHECK_OBJ_NOTNULL(lru, LRU_MAGIC); + Lck_Delete(&lru->mtx); + FREE_OBJ(lru); +} + +/*-------------------------------------------------------------------- + * XXX: trust pointer writes to be atomic + */ + +static struct stevedore * +stv_pick_stevedore(const struct sess *sp, const char **hint) +{ + struct stevedore *stv; + + AN(hint); + if (*hint != NULL && **hint != '\0') { + VTAILQ_FOREACH(stv, &stevedores, list) { + if (!strcmp(stv->ident, *hint)) + return (stv); + } + if (!strcmp(TRANSIENT_STORAGE, *hint)) + return (stv_transient); + + /* Hint was not valid, nuke it */ + WSP(sp, SLT_Debug, "Storage hint not usable"); + *hint = NULL; + } + /* pick a stevedore and bump the head along */ + stv = VTAILQ_NEXT(stv_next, list); + if (stv == NULL) + stv = VTAILQ_FIRST(&stevedores); + AN(stv); + AN(stv->name); + stv_next = stv; + return (stv); +} + +/*-------------------------------------------------------------------*/ + +static struct storage * +stv_alloc(const struct sess *sp, size_t size) +{ + struct storage *st; + struct stevedore *stv; + unsigned fail = 0; + + /* + * Always use the stevedore which allocated the object in order to + * keep an object inside the same stevedore. + */ + CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + stv = sp->obj->objstore->stevedore; + CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC); + + if (size > (size_t)(params->fetch_maxchunksize) << 10) + size = (size_t)(params->fetch_maxchunksize) << 10; + + for (;;) { + /* try to allocate from it */ + AN(stv->alloc); + st = stv->alloc(stv, size); + if (st != NULL) + break; + + if (size > params->fetch_chunksize * 1024LL) { + size >>= 1; + continue; + } + + /* no luck; try to free some space and keep trying */ + if (EXP_NukeOne(sp, stv->lru) == -1) + break; + + /* Enough is enough: try another if we have one */ + if (++fail >= params->nuke_limit) + break; + } + if (st != NULL) + CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); + return (st); +} + + +/*-------------------------------------------------------------------* + * Structure used to transport internal knowledge from STV_NewObject() + * to STV_MkObject(). Nobody else should mess with this struct. + */ + +struct stv_objsecrets { + unsigned magic; +#define STV_OBJ_SECRETES_MAGIC 0x78c87247 + uint16_t nhttp; + unsigned lhttp; + unsigned wsl; + struct exp *exp; +}; + +/*-------------------------------------------------------------------- + * This function is called by stevedores ->allocobj() method, which + * very often will be stv_default_allocobj() below, to convert a slab + * of storage into object which the stevedore can then register in its + * internal state, before returning it to STV_NewObject(). + * As you probably guessed: All this for persistence. + */ + +struct object * +STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, + const struct stv_objsecrets *soc) +{ + struct object *o; + unsigned l; + + CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC); + + assert(PAOK(ptr)); + assert(PAOK(soc->wsl)); + assert(PAOK(soc->lhttp)); + + assert(ltot >= sizeof *o + soc->lhttp + soc->wsl); + + o = ptr; + memset(o, 0, sizeof *o); + o->magic = OBJECT_MAGIC; + + l = PRNDDN(ltot - (sizeof *o + soc->lhttp)); + assert(l >= soc->wsl); + + o->http = HTTP_create(o + 1, soc->nhttp); + WS_Init(o->ws_o, "obj", (char *)(o + 1) + soc->lhttp, soc->wsl); + WS_Assert(o->ws_o); + assert(o->ws_o->e <= (char*)ptr + ltot); + + http_Setup(o->http, o->ws_o); + o->http->magic = HTTP_MAGIC; + o->exp = *soc->exp; + VTAILQ_INIT(&o->store); + sp->wrk->stats.n_object++; + + if (sp->objcore != NULL) { + CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); + + o->objcore = sp->objcore; + sp->objcore = NULL; /* refcnt follows pointer. */ + BAN_NewObjCore(o->objcore); + + o->objcore->methods = &default_oc_methods; + o->objcore->priv = o; + } + return (o); +} + +/*-------------------------------------------------------------------- + * This is the default ->allocobj() which all stevedores who do not + * implement persistent storage can rely on. + */ + +static struct object * +stv_default_allocobj(struct stevedore *stv, struct sess *sp, unsigned ltot, + const struct stv_objsecrets *soc) +{ + struct object *o; + struct storage *st; + + CHECK_OBJ_NOTNULL(soc, STV_OBJ_SECRETES_MAGIC); + st = stv->alloc(stv, ltot); + if (st == NULL) + return (NULL); + if (st->space < ltot) { + stv->free(st); + return (NULL); + } + ltot = st->len = st->space; + o = STV_MkObject(sp, st->ptr, ltot, soc); + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + o->objstore = st; + return (o); +} + +/*------------------------------------------------------------------- + * Allocate storage for an object, based on the header information. + * XXX: If we know (a hint of) the length, we could allocate space + * XXX: for the body in the same allocation while we are at it. + */ + +struct object * +STV_NewObject(struct sess *sp, const char *hint, unsigned wsl, struct exp *ep, + uint16_t nhttp) +{ + struct object *o; + struct stevedore *stv, *stv0; + unsigned lhttp, ltot; + struct stv_objsecrets soc; + int i; + + assert(wsl > 0); + wsl = PRNDUP(wsl); + + lhttp = HTTP_estimate(nhttp); + lhttp = PRNDUP(lhttp); + + memset(&soc, 0, sizeof soc); + soc.magic = STV_OBJ_SECRETES_MAGIC; + soc.nhttp = nhttp; + soc.lhttp = lhttp; + soc.wsl = wsl; + soc.exp = ep; + + ltot = sizeof *o + wsl + lhttp; + + stv = stv0 = stv_pick_stevedore(sp, &hint); + AN(stv->allocobj); + o = stv->allocobj(stv, sp, ltot, &soc); + if (o == NULL && hint == NULL) { + do { + stv = stv_pick_stevedore(sp, &hint); + AN(stv->allocobj); + o = stv->allocobj(stv, sp, ltot, &soc); + } while (o == NULL && stv != stv0); + } + if (o == NULL) { + /* no luck; try to free some space and keep trying */ + for (i = 0; o == NULL && i < params->nuke_limit; i++) { + if (EXP_NukeOne(sp, stv->lru) == -1) + break; + o = stv->allocobj(stv, sp, ltot, &soc); + } + } + + if (o == NULL) + return (NULL); + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(o->objstore, STORAGE_MAGIC); + return (o); +} + +/*-------------------------------------------------------------------*/ + +void +STV_Freestore(struct object *o) +{ + struct storage *st, *stn; + + if (o->esidata != NULL) { + STV_free(o->esidata); + o->esidata = NULL; + } + VTAILQ_FOREACH_SAFE(st, &o->store, list, stn) { + CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); + VTAILQ_REMOVE(&o->store, st, list); + STV_free(st); + } +} + +/*-------------------------------------------------------------------*/ + +struct storage * +STV_alloc(const struct sess *sp, size_t size) +{ + + return (stv_alloc(sp, size)); +} + +void +STV_trim(struct storage *st, size_t size) +{ + + CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); + AN(st->stevedore); + if (st->stevedore->trim) + st->stevedore->trim(st, size); +} + +void +STV_free(struct storage *st) +{ + + CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC); + AN(st->stevedore); + AN(st->stevedore->free); + st->stevedore->free(st); +} + +void +STV_open(void) +{ + struct stevedore *stv; + + VTAILQ_FOREACH(stv, &stevedores, list) { + stv->lru = LRU_Alloc(); + if (stv->open != NULL) + stv->open(stv); + } + stv = stv_transient; + if (stv->open != NULL) { + stv->lru = LRU_Alloc(); + stv->open(stv); + } +} + +void +STV_close(void) +{ + struct stevedore *stv; + + VTAILQ_FOREACH(stv, &stevedores, list) + if (stv->close != NULL) + stv->close(stv); + stv = stv_transient; + if (stv->close != NULL) + stv->close(stv); +} + +/*-------------------------------------------------------------------- + * Parse a stevedore argument on the form: + * [ name '=' ] strategy [ ',' arg ] * + */ + +static const struct choice STV_choice[] = { + { "file", &smf_stevedore }, + { "malloc", &sma_stevedore }, + { "persistent", &smp_stevedore }, +#ifdef HAVE_LIBUMEM + { "umem", &smu_stevedore }, +#endif + { NULL, NULL } +}; + +void +STV_Config(const char *spec) +{ + char **av; + const char *p, *q; + struct stevedore *stv; + const struct stevedore *stv2; + int ac, l; + static unsigned seq = 0; + + ASSERT_MGT(); + p = strchr(spec, '='); + q = strchr(spec, ','); + if (p != NULL && (q == NULL || q > p)) { + av = VAV_Parse(p + 1, NULL, ARGV_COMMA); + } else { + av = VAV_Parse(spec, NULL, ARGV_COMMA); + p = NULL; + } + AN(av); + + if (av[0] != NULL) + ARGV_ERR("%s\n", av[0]); + + if (av[1] == NULL) + ARGV_ERR("-s argument lacks strategy {malloc, file, ...}\n"); + + for (ac = 0; av[ac + 2] != NULL; ac++) + continue; + + stv2 = pick(STV_choice, av[1], "storage"); + AN(stv2); + + /* Append strategy to ident string */ + VSB_printf(vident, ",-s%s", av[1]); + + av += 2; + + CHECK_OBJ_NOTNULL(stv2, STEVEDORE_MAGIC); + ALLOC_OBJ(stv, STEVEDORE_MAGIC); + AN(stv); + + *stv = *stv2; + AN(stv->name); + AN(stv->alloc); + if (stv->allocobj == NULL) + stv->allocobj = stv_default_allocobj; + + if (p == NULL) + bprintf(stv->ident, "s%u", seq++); + else { + l = p - spec; + if (l > sizeof stv->ident - 1) + l = sizeof stv->ident - 1; + bprintf(stv->ident, "%.*s", l, spec); + } + + VTAILQ_FOREACH(stv2, &stevedores, list) { + if (strcmp(stv2->ident, stv->ident)) + continue; + ARGV_ERR("(-s%s=%s) already defined once\n", + stv->ident, stv->name); + } + + if (stv->init != NULL) + stv->init(stv, ac, av); + else if (ac != 0) + ARGV_ERR("(-s%s) too many arguments\n", stv->name); + + if (!strcmp(stv->ident, TRANSIENT_STORAGE)) { + stv->transient = 1; + AZ(stv_transient); + stv_transient = stv; + } else { + VTAILQ_INSERT_TAIL(&stevedores, stv, list); + if (!stv_next) + stv_next = VTAILQ_FIRST(&stevedores); + } +} + +/*--------------------------------------------------------------------*/ + +void +STV_Config_Transient(void) +{ + + ASSERT_MGT(); + + if (stv_transient == NULL) + STV_Config(TRANSIENT_STORAGE "=malloc"); +} + +/*--------------------------------------------------------------------*/ + +static void +stv_cli_list(struct cli *cli, const char * const *av, void *priv) +{ + struct stevedore *stv; + + ASSERT_MGT(); + (void)av; + (void)priv; + VCLI_Out(cli, "Storage devices:\n"); + stv = stv_transient; + VCLI_Out(cli, "\tstorage.%s = %s\n", stv->ident, stv->name); + VTAILQ_FOREACH(stv, &stevedores, list) + VCLI_Out(cli, "\tstorage.%s = %s\n", stv->ident, stv->name); +} + +/*--------------------------------------------------------------------*/ + +struct cli_proto cli_stv[] = { + { "storage.list", "storage.list", "List storage devices\n", + 0, 0, "", stv_cli_list }, + { NULL} +}; + +/*-------------------------------------------------------------------- + * VRT functions for stevedores + */ + +static const struct stevedore * +stv_find(const char *nm) +{ + const struct stevedore *stv; + + VTAILQ_FOREACH(stv, &stevedores, list) + if (!strcmp(stv->ident, nm)) + return (stv); + if (!strcmp(TRANSIENT_STORAGE, nm)) + return (stv_transient); + return (NULL); +} + +int +VRT_Stv(const char *nm) +{ + + if (stv_find(nm) != NULL) + return (1); + return (0); +} + +#define VRTSTVVAR(nm, vtype, ctype, dval) \ +ctype \ +VRT_Stv_##nm(const char *nm) \ +{ \ + const struct stevedore *stv; \ + \ + stv = stv_find(nm); \ + if (stv == NULL) \ + return (dval); \ + if (stv->var_##nm == NULL) \ + return (dval); \ + return (stv->var_##nm(stv)); \ +} + +#include "tbl/vrt_stv_var.h" +#undef VRTSTVVAR diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c new file mode 100644 index 0000000..3daebf8 --- /dev/null +++ b/bin/varnishd/storage/stevedore_utils.c @@ -0,0 +1,244 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + * Utility functions for stevedores and storage modules + */ + +#include "config.h" + +#include +#include +#ifdef HAVE_SYS_MOUNT_H +# include +#endif +#ifdef HAVE_SYS_STATVFS_H +# include +#endif +#ifdef HAVE_SYS_VFS_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "mgt.h" + +#include "storage/storage.h" +#include "vnum.h" + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +/*-------------------------------------------------------------------- + * Get a storage file. + * + * The fn argument can be an existing file, an existing directory or + * a nonexistent filename in an existing directory. + * + * If a directory is specified, the file will be anonymous (unlinked) + * + * Return: + * 0 if the file was preexisting. + * 1 if the file was created. + * 2 if the file is anonymous. + * + * Uses ARGV_ERR to exit in case of trouble. + */ + +int +STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx) +{ + int fd; + struct stat st; + int retval = 1; + char buf[FILENAME_MAX]; + + AN(fn); + AN(fnp); + AN(fdp); + *fnp = NULL; + *fdp = -1; + + /* try to create a new file of this name */ + fd = open(fn, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, 0600); + if (fd >= 0) { + *fdp = fd; + *fnp = fn; + return (retval); + } + + if (stat(fn, &st)) + ARGV_ERR( + "(%s) \"%s\" does not exist and could not be created\n", + ctx, fn); + + if (S_ISDIR(st.st_mode)) { + bprintf(buf, "%s/varnish.XXXXXX", fn); + fd = mkstemp(buf); + if (fd < 0) + ARGV_ERR("(%s) \"%s\" mkstemp(%s) failed (%s)\n", + ctx, fn, buf, strerror(errno)); + AZ(unlink(buf)); + *fnp = strdup(buf); + AN(*fnp); + retval = 2; + } else if (S_ISREG(st.st_mode)) { + fd = open(fn, O_RDWR | O_LARGEFILE); + if (fd < 0) + ARGV_ERR("(%s) \"%s\" could not open (%s)\n", + ctx, fn, strerror(errno)); + *fnp = fn; + retval = 0; + } else + ARGV_ERR( + "(%s) \"%s\" is neither file nor directory\n", ctx, fn); + + AZ(fstat(fd, &st)); + if (!S_ISREG(st.st_mode)) + ARGV_ERR("(%s) \"%s\" was not a file after opening\n", + ctx, fn); + + *fdp = fd; + return (retval); +} + +/*-------------------------------------------------------------------- + * Figure out how much space is in a filesystem + */ + +static uintmax_t +stv_fsspace(int fd, unsigned *bs) +{ + uintmax_t bsize, bavail; +#if defined(HAVE_SYS_STATVFS_H) + struct statvfs fsst; + + AZ(fstatvfs(fd, &fsst)); + bsize = fsst.f_frsize; + bavail = fsst.f_bavail; +#elif defined(HAVE_SYS_MOUNT_H) || defined(HAVE_SYS_VFS_H) + struct statfs fsst; + + AZ(fstatfs(sc->fd, &fsst)); + bsize = fsst.f_bsize; + bavail = fsst.f_bavail; +#else +#error no struct statfs / struct statvfs +#endif + + /* We use units of the larger of filesystem blocksize and pagesize */ + if (*bs < bsize) + *bs = bsize; + xxxassert(*bs % bsize == 0); + return (bsize * bavail); +} + + +/*-------------------------------------------------------------------- + * Decide file size. + * + * If the sizespecification is empty and the file exists with non-zero + * size, use that, otherwise, interpret the specification. + * + * Handle off_t sizes and pointer width limitations. + */ + +uintmax_t +STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx) +{ + uintmax_t l, fssize; + unsigned bs; + const char *q; + int i; + off_t o; + struct stat st; + + AZ(fstat(fd, &st)); + xxxassert(S_ISREG(st.st_mode)); + + bs = *granularity; + fssize = stv_fsspace(fd, &bs); + xxxassert(bs % *granularity == 0); + + if ((size == NULL || *size == '\0') && st.st_size != 0) { + /* + * We have no size specification, but an existing file, + * use its existing size. + */ + l = st.st_size; + } else { + AN(size); + q = VNUM_2bytes(size, &l, fssize); + + if (q != NULL) + ARGV_ERR("(%s) size \"%s\": %s\n", size, ctx, q); + + if (l < 1024*1024) + ARGV_ERR("(-spersistent) size \"%s\": too small, " + "did you forget to specify M or G?\n", size); + } + + /* + * This trickery wouldn't be necessary if X/Open would + * just add OFF_MAX to ... + */ + i = 0; + while(1) { + o = l; + if (o == l && o > 0) + break; + l >>= 1; + i++; + } + if (i) + fprintf(stderr, "WARNING: (%s) file size reduced" + " to %ju due to system \"off_t\" limitations\n", ctx, l); + else if (l - st.st_size > fssize) { + l = fssize * 80 / 100; + fprintf(stderr, "WARNING: (%s) file size reduced" + " to %ju (80%% of available disk space)\n", ctx, l); + } + + if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */ + fprintf(stderr, + "NB: Storage size limited to 2GB on 32 bit architecture,\n" + "NB: otherwise we could run out of address space.\n" + ); + l = INT32_MAX; + } + + /* round down to multiple of filesystem blocksize or pagesize */ + l -= (l % bs); + + *granularity = bs; + return(l); +} diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h new file mode 100644 index 0000000..80cad13 --- /dev/null +++ b/bin/varnishd/storage/storage.h @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * This defines the backend interface between the stevedore and the + * pluggable storage implementations. + * + */ + +struct stv_objsecrets; +struct stevedore; +struct sess; +struct lru; + +typedef void storage_init_f(struct stevedore *, int ac, char * const *av); +typedef void storage_open_f(const struct stevedore *); +typedef struct storage *storage_alloc_f(struct stevedore *, size_t size); +typedef void storage_trim_f(struct storage *, size_t size); +typedef void storage_free_f(struct storage *); +typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp, + unsigned ltot, const struct stv_objsecrets *); +typedef void storage_close_f(const struct stevedore *); + +/* Prototypes for VCL variable responders */ +#define VRTSTVTYPE(ct) typedef ct storage_var_##ct(const struct stevedore *); +#include "tbl/vrt_stv_var.h" +#undef VRTSTVTYPE + +/*--------------------------------------------------------------------*/ + +struct stevedore { + unsigned magic; +#define STEVEDORE_MAGIC 0x4baf43db + const char *name; + unsigned transient; + storage_init_f *init; /* called by mgt process */ + storage_open_f *open; /* called by cache process */ + storage_alloc_f *alloc; /* --//-- */ + storage_trim_f *trim; /* --//-- */ + storage_free_f *free; /* --//-- */ + storage_close_f *close; /* --//-- */ + storage_allocobj_f *allocobj; /* --//-- */ + + struct lru *lru; + +#define VRTSTVVAR(nm, vtype, ctype, dval) storage_var_##ctype *var_##nm; +#include "tbl/vrt_stv_var.h" +#undef VRTSTVVAR + + /* private fields */ + void *priv; + + VTAILQ_ENTRY(stevedore) list; + char ident[16]; /* XXX: match VSM_chunk.ident */ +}; + +/*--------------------------------------------------------------------*/ +int STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx); +uintmax_t STV_FileSize(int fd, const char *size, unsigned *granularity, + const char *ctx); +struct object *STV_MkObject(struct sess *sp, void *ptr, unsigned ltot, + const struct stv_objsecrets *soc); + +struct lru *LRU_Alloc(void); +void LRU_Free(struct lru *lru); + +/*--------------------------------------------------------------------*/ +extern const struct stevedore sma_stevedore; +extern const struct stevedore smf_stevedore; +extern const struct stevedore smp_stevedore; +#ifdef HAVE_LIBUMEM +extern const struct stevedore smu_stevedore; +#endif diff --git a/bin/varnishd/storage/storage_file.c b/bin/varnishd/storage/storage_file.c new file mode 100644 index 0000000..58e1d3d --- /dev/null +++ b/bin/varnishd/storage/storage_file.c @@ -0,0 +1,615 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + * Storage method based on mmap'ed file + */ + +#include "config.h" + +#include + +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "vnum.h" + +#ifndef MAP_NOCORE +#define MAP_NOCORE 0 /* XXX Linux */ +#endif + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 /* XXX Linux */ +#endif + +#define MINPAGES 128 + +/* + * Number of buckets on free-list. + * + * Last bucket is "larger than" so choose number so that the second + * to last bucket matches the 128k CHUNKSIZE in cache_fetch.c when + * using the a 4K minimal page size + */ +#define NBUCKET (128 / 4 + 1) + +/*--------------------------------------------------------------------*/ + +VTAILQ_HEAD(smfhead, smf); + +struct smf { + unsigned magic; +#define SMF_MAGIC 0x0927a8a0 + struct storage s; + struct smf_sc *sc; + + int alloc; + + off_t size; + off_t offset; + unsigned char *ptr; + + VTAILQ_ENTRY(smf) order; + VTAILQ_ENTRY(smf) status; + struct smfhead *flist; +}; + +struct smf_sc { + unsigned magic; +#define SMF_SC_MAGIC 0x52962ee7 + struct lock mtx; + struct VSC_C_smf *stats; + + const char *filename; + int fd; + unsigned pagesize; + uintmax_t filesize; + struct smfhead order; + struct smfhead free[NBUCKET]; + struct smfhead used; +}; + +/*--------------------------------------------------------------------*/ + +static void +smf_initfile(struct smf_sc *sc, const char *size) +{ + sc->filesize = STV_FileSize(sc->fd, size, &sc->pagesize, "-sfile"); + + AZ(ftruncate(sc->fd, (off_t)sc->filesize)); + + /* XXX: force block allocation here or in open ? */ +} + +static const char default_size[] = "100M"; +static const char default_filename[] = "."; + +static void +smf_init(struct stevedore *parent, int ac, char * const *av) +{ + const char *size, *fn, *r; + struct smf_sc *sc; + unsigned u; + uintmax_t page_size; + + AZ(av[ac]); + + fn = default_filename; + size = default_size; + page_size = getpagesize(); + + if (ac > 3) + ARGV_ERR("(-sfile) too many arguments\n"); + if (ac > 0 && *av[0] != '\0') + fn = av[0]; + if (ac > 1 && *av[1] != '\0') + size = av[1]; + if (ac > 2 && *av[2] != '\0') { + + r = VNUM_2bytes(av[2], &page_size, 0); + if (r != NULL) + ARGV_ERR("(-sfile) granularity \"%s\": %s\n", av[2], r); + } + + AN(fn); + AN(size); + + ALLOC_OBJ(sc, SMF_SC_MAGIC); + XXXAN(sc); + VTAILQ_INIT(&sc->order); + for (u = 0; u < NBUCKET; u++) + VTAILQ_INIT(&sc->free[u]); + VTAILQ_INIT(&sc->used); + sc->pagesize = page_size; + + parent->priv = sc; + + (void)STV_GetFile(fn, &sc->fd, &sc->filename, "-sfile"); + + mgt_child_inherit(sc->fd, "storage_file"); + smf_initfile(sc, size); +} + +/*-------------------------------------------------------------------- + * Insert/Remove from correct freelist + */ + +static void +insfree(struct smf_sc *sc, struct smf *sp) +{ + size_t b; + struct smf *sp2; + size_t ns; + + assert(sp->alloc == 0); + assert(sp->flist == NULL); + Lck_AssertHeld(&sc->mtx); + b = sp->size / sc->pagesize; + if (b >= NBUCKET) { + b = NBUCKET - 1; + sc->stats->g_smf_large++; + } else { + sc->stats->g_smf_frag++; + } + sp->flist = &sc->free[b]; + ns = b * sc->pagesize; + VTAILQ_FOREACH(sp2, sp->flist, status) { + assert(sp2->size >= ns); + assert(sp2->alloc == 0); + assert(sp2->flist == sp->flist); + if (sp->offset < sp2->offset) + break; + } + if (sp2 == NULL) + VTAILQ_INSERT_TAIL(sp->flist, sp, status); + else + VTAILQ_INSERT_BEFORE(sp2, sp, status); +} + +static void +remfree(const struct smf_sc *sc, struct smf *sp) +{ + size_t b; + + assert(sp->alloc == 0); + assert(sp->flist != NULL); + Lck_AssertHeld(&sc->mtx); + b = sp->size / sc->pagesize; + if (b >= NBUCKET) { + b = NBUCKET - 1; + sc->stats->g_smf_large--; + } else { + sc->stats->g_smf_frag--; + } + assert(sp->flist == &sc->free[b]); + VTAILQ_REMOVE(sp->flist, sp, status); + sp->flist = NULL; +} + +/*-------------------------------------------------------------------- + * Allocate a range from the first free range that is large enough. + */ + +static struct smf * +alloc_smf(struct smf_sc *sc, size_t bytes) +{ + struct smf *sp, *sp2; + size_t b; + + assert(!(bytes % sc->pagesize)); + b = bytes / sc->pagesize; + if (b >= NBUCKET) + b = NBUCKET - 1; + for (sp = NULL; b < NBUCKET - 1; b++) { + sp = VTAILQ_FIRST(&sc->free[b]); + if (sp != NULL) + break; + } + if (sp == NULL) { + VTAILQ_FOREACH(sp, &sc->free[NBUCKET -1], status) + if (sp->size >= bytes) + break; + } + if (sp == NULL) + return (sp); + + assert(sp->size >= bytes); + remfree(sc, sp); + + if (sp->size == bytes) { + sp->alloc = 1; + VTAILQ_INSERT_TAIL(&sc->used, sp, status); + return (sp); + } + + /* Split from front */ + sp2 = malloc(sizeof *sp2); + XXXAN(sp2); + sc->stats->g_smf++; + *sp2 = *sp; + + sp->offset += bytes; + sp->ptr += bytes; + sp->size -= bytes; + + sp2->size = bytes; + sp2->alloc = 1; + VTAILQ_INSERT_BEFORE(sp, sp2, order); + VTAILQ_INSERT_TAIL(&sc->used, sp2, status); + insfree(sc, sp); + return (sp2); +} + +/*-------------------------------------------------------------------- + * Free a range. Attempt merge forward and backward, then sort into + * free list according to age. + */ + +static void +free_smf(struct smf *sp) +{ + struct smf *sp2; + struct smf_sc *sc = sp->sc; + + CHECK_OBJ_NOTNULL(sp, SMF_MAGIC); + assert(sp->alloc != 0); + assert(sp->size > 0); + assert(!(sp->size % sc->pagesize)); + VTAILQ_REMOVE(&sc->used, sp, status); + sp->alloc = 0; + + sp2 = VTAILQ_NEXT(sp, order); + if (sp2 != NULL && + sp2->alloc == 0 && + (sp2->ptr == sp->ptr + sp->size) && + (sp2->offset == sp->offset + sp->size)) { + sp->size += sp2->size; + VTAILQ_REMOVE(&sc->order, sp2, order); + remfree(sc, sp2); + free(sp2); + sc->stats->g_smf--; + } + + sp2 = VTAILQ_PREV(sp, smfhead, order); + if (sp2 != NULL && + sp2->alloc == 0 && + (sp->ptr == sp2->ptr + sp2->size) && + (sp->offset == sp2->offset + sp2->size)) { + remfree(sc, sp2); + sp2->size += sp->size; + VTAILQ_REMOVE(&sc->order, sp, order); + free(sp); + sc->stats->g_smf--; + sp = sp2; + } + + insfree(sc, sp); +} + +/*-------------------------------------------------------------------- + * Trim the tail of a range. + */ + +static void +trim_smf(struct smf *sp, size_t bytes) +{ + struct smf *sp2; + struct smf_sc *sc = sp->sc; + + assert(sp->alloc != 0); + assert(bytes > 0); + assert(bytes < sp->size); + assert(!(bytes % sc->pagesize)); + assert(!(sp->size % sc->pagesize)); + CHECK_OBJ_NOTNULL(sp, SMF_MAGIC); + sp2 = malloc(sizeof *sp2); + XXXAN(sp2); + sc->stats->g_smf++; + *sp2 = *sp; + + sp2->size -= bytes; + sp->size = bytes; + sp2->ptr += bytes; + sp2->offset += bytes; + VTAILQ_INSERT_AFTER(&sc->order, sp, sp2, order); + VTAILQ_INSERT_TAIL(&sc->used, sp2, status); + free_smf(sp2); +} + +/*-------------------------------------------------------------------- + * Insert a newly created range as busy, then free it to do any collapses + */ + +static void +new_smf(struct smf_sc *sc, unsigned char *ptr, off_t off, size_t len) +{ + struct smf *sp, *sp2; + + assert(!(len % sc->pagesize)); + sp = calloc(sizeof *sp, 1); + XXXAN(sp); + sp->magic = SMF_MAGIC; + sp->s.magic = STORAGE_MAGIC; + sc->stats->g_smf++; + + sp->sc = sc; + sp->size = len; + sp->ptr = ptr; + sp->offset = off; + sp->alloc = 1; + + VTAILQ_FOREACH(sp2, &sc->order, order) { + if (sp->ptr < sp2->ptr) { + VTAILQ_INSERT_BEFORE(sp2, sp, order); + break; + } + } + if (sp2 == NULL) + VTAILQ_INSERT_TAIL(&sc->order, sp, order); + + VTAILQ_INSERT_HEAD(&sc->used, sp, status); + + free_smf(sp); +} + +/*--------------------------------------------------------------------*/ + +/* + * XXX: This may be too aggressive and soak up too much address room. + * XXX: On the other hand, the user, directly or implicitly asked us to + * XXX: use this much storage, so we should make a decent effort. + * XXX: worst case (I think), malloc will fail. + */ + +static void +smf_open_chunk(struct smf_sc *sc, off_t sz, off_t off, off_t *fail, off_t *sum) +{ + void *p; + off_t h; + + assert(sz != 0); + assert(!(sz % sc->pagesize)); + + if (*fail < (uintmax_t)sc->pagesize * MINPAGES) + return; + + if (sz > 0 && sz < *fail && sz < SSIZE_MAX) { + p = mmap(NULL, sz, PROT_READ|PROT_WRITE, + MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, off); + if (p != MAP_FAILED) { + (void) madvise(p, sz, MADV_RANDOM); + (*sum) += sz; + new_smf(sc, p, off, sz); + return; + } + } + + if (sz < *fail) + *fail = sz; + + h = sz / 2; + if (h > SSIZE_MAX) + h = SSIZE_MAX; + h -= (h % sc->pagesize); + + smf_open_chunk(sc, h, off, fail, sum); + smf_open_chunk(sc, sz - h, off + h, fail, sum); +} + +static void +smf_open(const struct stevedore *st) +{ + struct smf_sc *sc; + off_t fail = 1 << 30; /* XXX: where is OFF_T_MAX ? */ + off_t sum = 0; + + CAST_OBJ_NOTNULL(sc, st->priv, SMF_SC_MAGIC); + sc->stats = VSM_Alloc(sizeof *sc->stats, + VSC_CLASS, VSC_TYPE_SMF, st->ident); + Lck_New(&sc->mtx, lck_smf); + Lck_Lock(&sc->mtx); + smf_open_chunk(sc, sc->filesize, 0, &fail, &sum); + Lck_Unlock(&sc->mtx); + printf("SMF.%s mmap'ed %ju bytes of %ju\n", + st->ident, (uintmax_t)sum, sc->filesize); + + /* XXX */ + if (sum < MINPAGES * (off_t)getpagesize()) + exit (2); + + sc->stats->g_space += sc->filesize; +} + +/*--------------------------------------------------------------------*/ + +static struct storage * +smf_alloc(struct stevedore *st, size_t size) +{ + struct smf *smf; + struct smf_sc *sc; + + CAST_OBJ_NOTNULL(sc, st->priv, SMF_SC_MAGIC); + assert(size > 0); + size += (sc->pagesize - 1); + size &= ~(sc->pagesize - 1); + Lck_Lock(&sc->mtx); + sc->stats->c_req++; + smf = alloc_smf(sc, size); + if (smf == NULL) { + sc->stats->c_fail++; + Lck_Unlock(&sc->mtx); + return (NULL); + } + CHECK_OBJ_NOTNULL(smf, SMF_MAGIC); + sc->stats->g_alloc++; + sc->stats->c_bytes += smf->size; + sc->stats->g_bytes += smf->size; + sc->stats->g_space -= smf->size; + Lck_Unlock(&sc->mtx); + CHECK_OBJ_NOTNULL(&smf->s, STORAGE_MAGIC); /*lint !e774 */ + XXXAN(smf); + assert(smf->size == size); + smf->s.space = size; + smf->s.priv = smf; + smf->s.ptr = smf->ptr; + smf->s.len = 0; + smf->s.stevedore = st; +#ifdef SENDFILE_WORKS + smf->s.fd = smf->sc->fd; + smf->s.where = smf->offset; +#endif + return (&smf->s); +} + +/*--------------------------------------------------------------------*/ + +static void +smf_trim(struct storage *s, size_t size) +{ + struct smf *smf; + struct smf_sc *sc; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + assert(size > 0); + assert(size <= s->space); + xxxassert(size > 0); /* XXX: seen */ + CAST_OBJ_NOTNULL(smf, s->priv, SMF_MAGIC); + assert(size <= smf->size); + sc = smf->sc; + size += (sc->pagesize - 1); + size &= ~(sc->pagesize - 1); + if (smf->size > size) { + Lck_Lock(&sc->mtx); + sc->stats->c_freed += (smf->size - size); + sc->stats->g_bytes -= (smf->size - size); + sc->stats->g_space += (smf->size - size); + trim_smf(smf, size); + assert(smf->size == size); + Lck_Unlock(&sc->mtx); + s->space = size; + } +} + +/*--------------------------------------------------------------------*/ + +static void __match_proto__(storage_free_f) +smf_free(struct storage *s) +{ + struct smf *smf; + struct smf_sc *sc; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + CAST_OBJ_NOTNULL(smf, s->priv, SMF_MAGIC); + sc = smf->sc; + Lck_Lock(&sc->mtx); + sc->stats->g_alloc--; + sc->stats->c_freed += smf->size; + sc->stats->g_bytes -= smf->size; + sc->stats->g_space += smf->size; + free_smf(smf); + Lck_Unlock(&sc->mtx); +} + +/*--------------------------------------------------------------------*/ + +const struct stevedore smf_stevedore = { + .magic = STEVEDORE_MAGIC, + .name = "file", + .init = smf_init, + .open = smf_open, + .alloc = smf_alloc, + .trim = smf_trim, + .free = smf_free, +}; + +#ifdef INCLUDE_TEST_DRIVER + +void vca_flush(struct sess *sp) {} + +#define N 100 +#define M (128*1024) + +struct storage *s[N]; + +static void +dumpit(void) +{ + struct smf_sc *sc = smf_stevedore.priv; + struct smf *s; + + return (0); + printf("----------------\n"); + printf("Order:\n"); + VTAILQ_FOREACH(s, &sc->order, order) { + printf("%10p %12ju %12ju %12ju\n", + s, s->offset, s->size, s->offset + s->size); + } + printf("Used:\n"); + VTAILQ_FOREACH(s, &sc->used, status) { + printf("%10p %12ju %12ju %12ju\n", + s, s->offset, s->size, s->offset + s->size); + } + printf("Free:\n"); + VTAILQ_FOREACH(s, &sc->free, status) { + printf("%10p %12ju %12ju %12ju\n", + s, s->offset, s->size, s->offset + s->size); + } + printf("================\n"); +} + +int +main(int argc, char **argv) +{ + int i, j; + + setbuf(stdout, NULL); + smf_init(&smf_stevedore, ""); + smf_open(&smf_stevedore); + while (1) { + dumpit(); + i = random() % N; + do + j = random() % M; + while (j == 0); + if (s[i] == NULL) { + s[i] = smf_alloc(&smf_stevedore, j); + printf("A %10p %12d\n", s[i], j); + } else if (j < s[i]->space) { + smf_trim(s[i], j); + printf("T %10p %12d\n", s[i], j); + } else { + smf_free(s[i]); + printf("D %10p\n", s[i]); + s[i] = NULL; + } + } +} + +#endif /* INCLUDE_TEST_DRIVER */ diff --git a/bin/varnishd/storage/storage_malloc.c b/bin/varnishd/storage/storage_malloc.c new file mode 100644 index 0000000..03d6a55 --- /dev/null +++ b/bin/varnishd/storage/storage_malloc.c @@ -0,0 +1,256 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Storage method based on malloc(3) + */ + +#include "config.h" + +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "vnum.h" + +struct sma_sc { + unsigned magic; +#define SMA_SC_MAGIC 0x1ac8a345 + struct lock sma_mtx; + size_t sma_max; + size_t sma_alloc; + struct VSC_C_sma *stats; +}; + +struct sma { + unsigned magic; +#define SMA_MAGIC 0x69ae9bb9 + struct storage s; + size_t sz; + struct sma_sc *sc; +}; + +static struct storage * +sma_alloc(struct stevedore *st, size_t size) +{ + struct sma_sc *sma_sc; + struct sma *sma = NULL; + void *p; + + CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); + Lck_Lock(&sma_sc->sma_mtx); + sma_sc->stats->c_req++; + if (sma_sc->sma_alloc + size > sma_sc->sma_max) { + sma_sc->stats->c_fail += size; + size = 0; + } else { + sma_sc->sma_alloc += size; + sma_sc->stats->c_bytes += size; + sma_sc->stats->g_alloc++; + sma_sc->stats->g_bytes += size; + if (sma_sc->sma_max != SIZE_MAX) + sma_sc->stats->g_space -= size; + } + Lck_Unlock(&sma_sc->sma_mtx); + + if (size == 0) + return (NULL); + + /* + * Do not collaps the sma allocation with sma->s.ptr: it is not + * a good idea. Not only would it make ->trim impossible, + * performance-wise it would be a catastropy with chunksized + * allocations growing another full page, just to accomodate the sma. + */ + + p = malloc(size); + if (p != NULL) { + ALLOC_OBJ(sma, SMA_MAGIC); + if (sma != NULL) + sma->s.ptr = p; + else + free(p); + } + if (sma == NULL) { + Lck_Lock(&sma_sc->sma_mtx); + /* + * XXX: Not nice to have counters go backwards, but we do + * XXX: Not want to pick up the lock twice just for stats. + */ + sma_sc->stats->c_fail++; + sma_sc->stats->c_bytes -= size; + sma_sc->stats->g_alloc--; + sma_sc->stats->g_bytes -= size; + if (sma_sc->sma_max != SIZE_MAX) + sma_sc->stats->g_space += size; + Lck_Unlock(&sma_sc->sma_mtx); + return (NULL); + } + sma->sc = sma_sc; + sma->sz = size; + sma->s.priv = sma; + sma->s.len = 0; + sma->s.space = size; +#ifdef SENDFILE_WORKS + sma->s.fd = -1; +#endif + sma->s.stevedore = st; + sma->s.magic = STORAGE_MAGIC; + return (&sma->s); +} + +static void __match_proto__(storage_free_f) +sma_free(struct storage *s) +{ + struct sma_sc *sma_sc; + struct sma *sma; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + CAST_OBJ_NOTNULL(sma, s->priv, SMA_MAGIC); + sma_sc = sma->sc; + assert(sma->sz == sma->s.space); + Lck_Lock(&sma_sc->sma_mtx); + sma_sc->sma_alloc -= sma->sz; + sma_sc->stats->g_alloc--; + sma_sc->stats->g_bytes -= sma->sz; + sma_sc->stats->c_freed += sma->sz; + if (sma_sc->sma_max != SIZE_MAX) + sma_sc->stats->g_space += sma->sz; + Lck_Unlock(&sma_sc->sma_mtx); + free(sma->s.ptr); + free(sma); +} + +static void +sma_trim(struct storage *s, size_t size) +{ + struct sma_sc *sma_sc; + struct sma *sma; + void *p; + size_t delta; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + CAST_OBJ_NOTNULL(sma, s->priv, SMA_MAGIC); + sma_sc = sma->sc; + + assert(sma->sz == sma->s.space); + assert(size < sma->sz); + delta = sma->sz - size; + if (delta < 256) + return; + if ((p = realloc(sma->s.ptr, size)) != NULL) { + Lck_Lock(&sma_sc->sma_mtx); + sma_sc->sma_alloc -= delta; + sma_sc->stats->g_bytes -= delta; + sma_sc->stats->c_freed += delta; + if (sma_sc->sma_max != SIZE_MAX) + sma_sc->stats->g_space += delta; + sma->sz = size; + Lck_Unlock(&sma_sc->sma_mtx); + sma->s.ptr = p; + s->space = size; + } +} + +static double +sma_used_space(const struct stevedore *st) +{ + struct sma_sc *sma_sc; + + CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); + return (sma_sc->sma_alloc); +} + +static double +sma_free_space(const struct stevedore *st) +{ + struct sma_sc *sma_sc; + + CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); + return (sma_sc->sma_max - sma_sc->sma_alloc); +} + +static void +sma_init(struct stevedore *parent, int ac, char * const *av) +{ + const char *e; + uintmax_t u; + struct sma_sc *sc; + + ASSERT_MGT(); + ALLOC_OBJ(sc, SMA_SC_MAGIC); + AN(sc); + sc->sma_max = SIZE_MAX; + assert(sc->sma_max == SIZE_MAX); + parent->priv = sc; + + AZ(av[ac]); + if (ac > 1) + ARGV_ERR("(-smalloc) too many arguments\n"); + + if (ac == 0 || *av[0] == '\0') + return; + + e = VNUM_2bytes(av[0], &u, 0); + if (e != NULL) + ARGV_ERR("(-smalloc) size \"%s\": %s\n", av[0], e); + if ((u != (uintmax_t)(size_t)u)) + ARGV_ERR("(-smalloc) size \"%s\": too big\n", av[0]); + if (u < 1024*1024) + ARGV_ERR("(-smalloc) size \"%s\": too small, " + "did you forget to specify M or G?\n", av[0]); + + sc->sma_max = u; +} + +static void +sma_open(const struct stevedore *st) +{ + struct sma_sc *sma_sc; + + CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); + Lck_New(&sma_sc->sma_mtx, lck_sma); + sma_sc->stats = VSM_Alloc(sizeof *sma_sc->stats, + VSC_CLASS, VSC_TYPE_SMA, st->ident); + memset(sma_sc->stats, 0, sizeof *sma_sc->stats); + if (sma_sc->sma_max != SIZE_MAX) + sma_sc->stats->g_space = sma_sc->sma_max; +} + +const struct stevedore sma_stevedore = { + .magic = STEVEDORE_MAGIC, + .name = "malloc", + .init = sma_init, + .open = sma_open, + .alloc = sma_alloc, + .free = sma_free, + .trim = sma_trim, + .var_free_space = sma_free_space, + .var_used_space = sma_used_space, +}; diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c new file mode 100644 index 0000000..84aef5c --- /dev/null +++ b/bin/varnishd/storage/storage_persistent.c @@ -0,0 +1,678 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Persistent storage method + * + * XXX: Before we start the client or maybe after it stops, we should give the + * XXX: stevedores a chance to examine their storage for consistency. + * + * XXX: Do we ever free the LRU-lists ? + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "hash_slinger.h" +#include "vcli.h" +#include "vcli_priv.h" +#include "vend.h" +#include "vsha256.h" + +#include "persistent.h" +#include "storage/storage_persistent.h" + +/*--------------------------------------------------------------------*/ + +/* + * silos is unlocked, it only changes during startup when we are + * single-threaded + */ +static VTAILQ_HEAD(,smp_sc) silos = VTAILQ_HEAD_INITIALIZER(silos); + +/*-------------------------------------------------------------------- + * Add bans to silos + */ + +static void +smp_appendban(struct smp_sc *sc, struct smp_signctx *ctx, + uint32_t len, const uint8_t *ban) +{ + uint8_t *ptr, *ptr2; + + (void)sc; + ptr = ptr2 = SIGN_END(ctx); + + memcpy(ptr, "BAN", 4); + ptr += 4; + + vbe32enc(ptr, len); + ptr += 4; + + memcpy(ptr, ban, len); + ptr += len; + + smp_append_sign(ctx, ptr2, ptr - ptr2); +} + +/* Trust that cache_ban.c takes care of locking */ + +void +SMP_NewBan(const uint8_t *ban, unsigned ln) +{ + struct smp_sc *sc; + + VTAILQ_FOREACH(sc, &silos, list) { + smp_appendban(sc, &sc->ban1, ln, ban); + smp_appendban(sc, &sc->ban2, ln, ban); + } +} + +/*-------------------------------------------------------------------- + * Attempt to open and read in a ban list + */ + +static int +smp_open_bans(struct smp_sc *sc, struct smp_signctx *ctx) +{ + uint8_t *ptr, *pe; + uint32_t length; + int i, retval = 0; + + ASSERT_CLI(); + (void)sc; + i = smp_chk_sign(ctx); + if (i) + return (i); + ptr = SIGN_DATA(ctx); + pe = ptr + ctx->ss->length; + + while (ptr < pe) { + if (memcmp(ptr, "BAN", 4)) { + retval = 1001; + break; + } + ptr += 4; + + length = vbe32dec(ptr); + ptr += 4; + + if (ptr + length > pe) { + retval = 1003; + break; + } + + BAN_Reload(ptr, length); + + ptr += length; + } + assert(ptr <= pe); + return (retval); +} + +/*-------------------------------------------------------------------- + * Attempt to open and read in a segment list + */ + +static int +smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx) +{ + uint64_t length, l; + struct smp_segptr *ss, *se; + struct smp_seg *sg, *sg1, *sg2; + int i, n = 0; + + ASSERT_CLI(); + i = smp_chk_sign(ctx); + if (i) + return (i); + + ss = SIGN_DATA(ctx); + length = ctx->ss->length; + + if (length == 0) { + /* No segments */ + sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; + return (0); + } + se = ss + length / sizeof *ss; + se--; + assert(ss <= se); + + /* + * Locate the free reserve, there are only two basic cases, + * but once we start dropping segments, things gets more complicated. + */ + + sc->free_offset = se->offset + se->length; + l = sc->mediasize - sc->free_offset; + if (se->offset > ss->offset && l >= sc->free_reserve) { + /* + * [__xxxxyyyyzzzz___] + * Plenty of space at tail, do nothing. + */ + } else if (ss->offset > se->offset) { + /* + * [zzzz____xxxxyyyy_] + * (make) space between ends + * We might nuke the entire tail end without getting + * enough space, in which case we fall through to the + * last check. + */ + while (ss < se && ss->offset > se->offset) { + l = ss->offset - (se->offset + se->length); + if (l > sc->free_reserve) + break; + ss++; + n++; + } + } + + if (l < sc->free_reserve) { + /* + * [__xxxxyyyyzzzz___] + * (make) space at front + */ + sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; + while (ss < se) { + l = ss->offset - sc->free_offset; + if (l > sc->free_reserve) + break; + ss++; + n++; + } + } + + assert (l >= sc->free_reserve); + + + sg1 = NULL; + sg2 = NULL; + for(; ss <= se; ss++) { + ALLOC_OBJ(sg, SMP_SEG_MAGIC); + AN(sg); + sg->lru = LRU_Alloc(); + CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); + sg->p = *ss; + + sg->flags |= SMP_SEG_MUSTLOAD; + + /* + * HACK: prevent save_segs from nuking segment until we have + * HACK: loaded it. + */ + sg->nobj = 1; + if (sg1 != NULL) { + assert(sg1->p.offset != sg->p.offset); + if (sg1->p.offset < sg->p.offset) + assert(smp_segend(sg1) <= sg->p.offset); + else + assert(smp_segend(sg) <= sg1->p.offset); + } + if (sg2 != NULL) { + assert(sg2->p.offset != sg->p.offset); + if (sg2->p.offset < sg->p.offset) + assert(smp_segend(sg2) <= sg->p.offset); + else + assert(smp_segend(sg) <= sg2->p.offset); + } + + /* XXX: check that they are inside silo */ + /* XXX: check that they don't overlap */ + /* XXX: check that they are serial */ + sg->sc = sc; + VTAILQ_INSERT_TAIL(&sc->segments, sg, list); + sg2 = sg; + if (sg1 == NULL) + sg1 = sg; + } + printf("Dropped %d segments to make free_reserve\n", n); + return (0); +} + +/*-------------------------------------------------------------------- + * Silo worker thread + */ + +static void * +smp_thread(struct sess *sp, void *priv) +{ + struct smp_sc *sc; + struct smp_seg *sg; + + (void)sp; + CAST_OBJ_NOTNULL(sc, priv, SMP_SC_MAGIC); + + /* First, load all the objects from all segments */ + VTAILQ_FOREACH(sg, &sc->segments, list) + if (sg->flags & SMP_SEG_MUSTLOAD) + smp_load_seg(sp, sc, sg); + + sc->flags |= SMP_SC_LOADED; + BAN_TailDeref(&sc->tailban); + AZ(sc->tailban); + printf("Silo completely loaded\n"); + while (1) { + (void)sleep (1); + sg = VTAILQ_FIRST(&sc->segments); + if (sg != NULL && sg -> sc->cur_seg && + sg->nobj == 0) { + Lck_Lock(&sc->mtx); + smp_save_segs(sc); + Lck_Unlock(&sc->mtx); + } + } + NEEDLESS_RETURN(NULL); +} + +/*-------------------------------------------------------------------- + * Open a silo in the worker process + */ + +static void +smp_open(const struct stevedore *st) +{ + struct smp_sc *sc; + + ASSERT_CLI(); + + CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); + + Lck_New(&sc->mtx, lck_smp); + Lck_Lock(&sc->mtx); + + sc->stevedore = st; + + /* We trust the parent to give us a valid silo, for good measure: */ + AZ(smp_valid_silo(sc)); + + AZ(mprotect(sc->base, 4096, PROT_READ)); + + sc->ident = SIGN_DATA(&sc->idn); + + /* We attempt ban1 first, and if that fails, try ban2 */ + if (smp_open_bans(sc, &sc->ban1)) + AZ(smp_open_bans(sc, &sc->ban2)); + + /* We attempt seg1 first, and if that fails, try seg2 */ + if (smp_open_segs(sc, &sc->seg1)) + AZ(smp_open_segs(sc, &sc->seg2)); + + /* + * Grap a reference to the tail of the ban list, until the thread + * has loaded all objects, so we can be sure that all of our + * proto-bans survive until then. + */ + sc->tailban = BAN_TailRef(); + AN(sc->tailban); + + /* XXX: save segments to ensure consistency between seg1 & seg2 ? */ + + /* XXX: abandon early segments to make sure we have free space ? */ + + /* Open a new segment, so we are ready to write */ + smp_new_seg(sc); + + /* Start the worker silo worker thread, it will load the objects */ + WRK_BgThread(&sc->thread, "persistence", smp_thread, sc); + + VTAILQ_INSERT_TAIL(&silos, sc, list); + Lck_Unlock(&sc->mtx); +} + +/*-------------------------------------------------------------------- + * Close a silo + */ + +static void +smp_close(const struct stevedore *st) +{ + struct smp_sc *sc; + + ASSERT_CLI(); + + CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); + Lck_Lock(&sc->mtx); + smp_close_seg(sc, sc->cur_seg); + Lck_Unlock(&sc->mtx); + + /* XXX: reap thread */ +} + +/*-------------------------------------------------------------------- + * Allocate a bite. + * + * Allocate [min_size...max_size] space from the bottom of the segment, + * as is convenient. + * + * If 'so' + 'idx' is given, also allocate a smp_object from the top + * of the segment. + * + * Return the segment in 'ssg' if given. + */ + +static struct storage * +smp_allocx(struct stevedore *st, size_t min_size, size_t max_size, + struct smp_object **so, unsigned *idx, struct smp_seg **ssg) +{ + struct smp_sc *sc; + struct storage *ss; + struct smp_seg *sg; + unsigned tries; + uint64_t left, extra; + + CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); + assert(min_size <= max_size); + + max_size = IRNUP(sc, max_size); + min_size = IRNUP(sc, min_size); + + extra = IRNUP(sc, sizeof(*ss)); + if (so != NULL) { + extra += sizeof(**so); + AN(idx); + } + + Lck_Lock(&sc->mtx); + sg = NULL; + ss = NULL; + for (tries = 0; tries < 3; tries++) { + left = smp_spaceleft(sc, sc->cur_seg); + if (left >= extra + min_size) + break; + smp_close_seg(sc, sc->cur_seg); + smp_new_seg(sc); + } + if (left >= extra + min_size) { + if (left < extra + max_size) + max_size = IRNDN(sc, left - extra); + + sg = sc->cur_seg; + ss = (void*)(sc->base + sc->next_bot); + sc->next_bot += max_size + IRNUP(sc, sizeof(*ss)); + sg->nalloc++; + if (so != NULL) { + sc->next_top -= sizeof(**so); + *so = (void*)(sc->base + sc->next_top); + /* Render this smp_object mostly harmless */ + (*so)->ttl = 0.; + (*so)->ban = 0.; + (*so)->ptr = 0;; + sg->objs = *so; + *idx = ++sg->p.lobjlist; + } + (void)smp_spaceleft(sc, sg); /* for the assert */ + } + Lck_Unlock(&sc->mtx); + + if (ss == NULL) + return (ss); + AN(sg); + assert(max_size >= min_size); + + /* Fill the storage structure */ + memset(ss, 0, sizeof *ss); + ss->magic = STORAGE_MAGIC; + ss->ptr = PRNUP(sc, ss + 1); + ss->space = max_size; + ss->priv = sc; + ss->stevedore = st; +#ifdef SENDFILE_WORKS + ss->fd = sc->fd; +#endif + if (ssg != NULL) + *ssg = sg; + return (ss); +} + +/*-------------------------------------------------------------------- + * Allocate an object + */ + +static struct object * +smp_allocobj(struct stevedore *stv, struct sess *sp, unsigned ltot, + const struct stv_objsecrets *soc) +{ + struct object *o; + struct storage *st; + struct smp_sc *sc; + struct smp_seg *sg; + struct smp_object *so; + struct objcore *oc; + unsigned objidx; + + if (sp->objcore == NULL) + return (NULL); /* from cnt_error */ + CAST_OBJ_NOTNULL(sc, stv->priv, SMP_SC_MAGIC); + AN(sp->objcore); + AN(sp->wrk->exp.ttl > 0.); + + ltot = IRNUP(sc, ltot); + + st = smp_allocx(stv, ltot, ltot, &so, &objidx, &sg); + if (st == NULL) + return (NULL); + + assert(st->space >= ltot); + ltot = st->len = st->space; + + o = STV_MkObject(sp, st->ptr, ltot, soc); + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + o->objstore = st; + + oc = o->objcore; + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + oc->flags |= OC_F_LRUDONTMOVE; + + Lck_Lock(&sc->mtx); + sg->nfixed++; + sg->nobj++; + + /* We have to do this somewhere, might as well be here... */ + assert(sizeof so->hash == DIGEST_LEN); + memcpy(so->hash, oc->objhead->digest, DIGEST_LEN); + so->ttl = EXP_Grace(NULL, o); + so->ptr = (uint8_t*)o - sc->base; + so->ban = BAN_Time(oc->ban); + + smp_init_oc(oc, sg, objidx); + + Lck_Unlock(&sc->mtx); + return (o); +} + +/*-------------------------------------------------------------------- + * Allocate a bite + */ + +static struct storage * +smp_alloc(struct stevedore *st, size_t size) +{ + + return (smp_allocx(st, + size > 4096 ? 4096 : size, size, NULL, NULL, NULL)); +} + +/*-------------------------------------------------------------------- + * Trim a bite + * XXX: We could trim the last allocation. + */ + +static void +smp_trim(struct storage *ss, size_t size) +{ + + (void)ss; + (void)size; +} + +/*-------------------------------------------------------------------- + * We don't track frees of storage, we track the objects which own the + * storage and when there are no more objects in in the first segment, + * it can be reclaimed. + * XXX: We could free the last allocation, but does that happen ? + */ + +static void __match_proto__(storage_free_f) +smp_free(struct storage *st) +{ + + /* XXX */ + (void)st; +} + + +/*--------------------------------------------------------------------*/ + +const struct stevedore smp_stevedore = { + .magic = STEVEDORE_MAGIC, + .name = "persistent", + .init = smp_mgt_init, + .open = smp_open, + .close = smp_close, + .alloc = smp_alloc, + .allocobj = smp_allocobj, + .free = smp_free, + .trim = smp_trim, +}; + +/*-------------------------------------------------------------------- + * Persistence is a bear to test unadultered, so we cheat by adding + * a cli command we can use to make it do tricks for us. + */ + +static void +debug_report_silo(struct cli *cli, const struct smp_sc *sc, int objs) +{ + struct smp_seg *sg; + struct objcore *oc; + + VCLI_Out(cli, "Silo: %s (%s)\n", + sc->stevedore->ident, sc->filename); + VTAILQ_FOREACH(sg, &sc->segments, list) { + VCLI_Out(cli, " Seg: [0x%jx ... +0x%jx]\n", + (uintmax_t)sg->p.offset, (uintmax_t)sg->p.length); + if (sg == sc->cur_seg) + VCLI_Out(cli, + " Alloc: [0x%jx ... 0x%jx] = 0x%jx free\n", + (uintmax_t)(sc->next_bot), + (uintmax_t)(sc->next_top), + (uintmax_t)(sc->next_top - sc->next_bot)); + VCLI_Out(cli, " %u nobj, %u alloc, %u lobjlist, %u fixed\n", + sg->nobj, sg->nalloc, sg->p.lobjlist, sg->nfixed); + if (objs) { + VTAILQ_FOREACH(oc, &sg->lru->lru_head, lru_list) + VCLI_Out(cli, " OC %p\n", oc); + } + } +} + +static void +debug_persistent(struct cli *cli, const char * const * av, void *priv) +{ + struct smp_sc *sc; + + (void)priv; + + if (av[2] == NULL) { + VTAILQ_FOREACH(sc, &silos, list) + debug_report_silo(cli, sc, 0); + return; + } + VTAILQ_FOREACH(sc, &silos, list) + if (!strcmp(av[2], sc->stevedore->ident)) + break; + if (sc == NULL) { + VCLI_Out(cli, "Silo <%s> not found\n", av[2]); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + if (av[3] == NULL) { + debug_report_silo(cli, sc, 0); + return; + } + Lck_Lock(&sc->mtx); + if (!strcmp(av[3], "sync")) { + smp_close_seg(sc, sc->cur_seg); + smp_new_seg(sc); + } else if (!strcmp(av[3], "dump")) { + debug_report_silo(cli, sc, 1); + } else { + VCLI_Out(cli, "Unknown operation\n"); + VCLI_SetResult(cli, CLIS_PARAM); + } + Lck_Unlock(&sc->mtx); +} + +static struct cli_proto debug_cmds[] = { + { "debug.persistent", "debug.persistent", + "Persistent debugging magic:\n" + "\tdebug.persistent [stevedore [cmd]]\n" + "With no cmd arg, a summary of the silo is returned.\n" + "Possible commands:\n" + "\tsync\tClose current segment, open a new one\n" + "\tdump\tinclude objcores in silo summary\n" + "", + 0, 2, "d", debug_persistent }, + { NULL } +}; + +/*--------------------------------------------------------------------*/ + +void +SMP_Init(void) +{ + CLI_AddFuncs(debug_cmds); +} + +/*-------------------------------------------------------------------- + * Pause until all silos have loaded. + */ + +void +SMP_Ready(void) +{ + struct smp_sc *sc; + + ASSERT_CLI(); + do { + VTAILQ_FOREACH(sc, &silos, list) + if (!(sc->flags & SMP_SC_LOADED)) + break; + if (sc != NULL) + (void)sleep(1); + } while (sc != NULL); +} diff --git a/bin/varnishd/storage/storage_persistent.h b/bin/varnishd/storage/storage_persistent.h new file mode 100644 index 0000000..84f3d21 --- /dev/null +++ b/bin/varnishd/storage/storage_persistent.h @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Persistent storage method + * + * XXX: Before we start the client or maybe after it stops, we should give the + * XXX: stevedores a chance to examine their storage for consistency. + * + * XXX: Do we ever free the LRU-lists ? + */ + +#define ASSERT_SILO_THREAD(sc) \ + do {assert(pthread_self() == (sc)->thread);} while (0) + +#define OC_F_NEEDFIXUP OC_F_PRIV + +/* + * Context for a signature. + * + * A signature is a sequence of bytes in the silo, signed by a SHA256 hash + * which follows the bytes. + * + * The context structure allows us to append to a signature without + * recalculating the entire SHA256 hash. + */ + +struct smp_signctx { + struct smp_sign *ss; + struct SHA256Context ctx; + uint32_t unique; + const char *id; +}; + +struct smp_sc; + +/* XXX: name confusion with on-media version ? */ +struct smp_seg { + unsigned magic; +#define SMP_SEG_MAGIC 0x45c61895 + + struct smp_sc *sc; + struct lru *lru; + + VTAILQ_ENTRY(smp_seg) list; /* on smp_sc.smp_segments */ + + struct smp_segptr p; + + unsigned flags; +#define SMP_SEG_MUSTLOAD (1 << 0) +#define SMP_SEG_LOADED (1 << 1) + + uint32_t nobj; /* Number of objects */ + uint32_t nalloc; /* Allocations */ + uint32_t nfixed; /* How many fixed objects */ + + /* Only for open segment */ + struct smp_object *objs; /* objdesc array */ + struct smp_signctx ctx[1]; +}; + +VTAILQ_HEAD(smp_seghead, smp_seg); + +struct smp_sc { + unsigned magic; +#define SMP_SC_MAGIC 0x7b73af0a + struct stevedore *parent; + + unsigned flags; +#define SMP_SC_LOADED (1 << 0) + + const struct stevedore *stevedore; + int fd; + const char *filename; + off_t mediasize; + uintptr_t align; + uint32_t granularity; + uint32_t unique; + + uint8_t *base; + + struct smp_ident *ident; + + struct smp_seghead segments; + struct smp_seg *cur_seg; + uint64_t next_bot; /* next alloc address bottom */ + uint64_t next_top; /* next alloc address top */ + + uint64_t free_offset; + + pthread_t thread; + + VTAILQ_ENTRY(smp_sc) list; + + struct smp_signctx idn; + struct smp_signctx ban1; + struct smp_signctx ban2; + struct smp_signctx seg1; + struct smp_signctx seg2; + + struct ban *tailban; + + struct lock mtx; + + /* Cleaner metrics */ + + unsigned min_nseg; + unsigned aim_nseg; + unsigned max_nseg; + + uint64_t min_segl; + uint64_t aim_segl; + uint64_t max_segl; + + uint64_t free_reserve; +}; + +/*--------------------------------------------------------------------*/ + +/* Pointer round up/down & assert */ +#define PRNDN(sc, x) ((void*)RDN2((uintptr_t)(x), sc->align)) +#define PRNUP(sc, x) ((void*)RUP2((uintptr_t)(x), sc->align)) +#define PASSERTALIGN(sc, x) assert(PRNDN(sc, x) == (x)) + +/* Integer round up/down & assert */ +#define IRNDN(sc, x) RDN2(x, sc->align) +#define IRNUP(sc, x) RUP2(x, sc->align) +#define IASSERTALIGN(sc, x) assert(IRNDN(sc, x) == (x)) + +/*--------------------------------------------------------------------*/ + +#define ASSERT_PTR_IN_SILO(sc, ptr) \ + assert((const void*)(ptr) >= (const void*)((sc)->base) && \ + (const void*)(ptr) < (const void *)((sc)->base + (sc)->mediasize)) + +/*--------------------------------------------------------------------*/ + +#define SIGN_DATA(ctx) ((void *)((ctx)->ss + 1)) +#define SIGN_END(ctx) ((void *)((int8_t *)SIGN_DATA(ctx) + (ctx)->ss->length)) + +/* storage_persistent_mgt.c */ + +void smp_mgt_init(struct stevedore *parent, int ac, char * const *av); + +/* storage_persistent_silo.c */ + +void smp_load_seg(const struct sess *sp, const struct smp_sc *sc, + struct smp_seg *sg); +void smp_new_seg(struct smp_sc *sc); +void smp_close_seg(struct smp_sc *sc, struct smp_seg *sg); +void smp_init_oc(struct objcore *oc, struct smp_seg *sg, unsigned objidx); +void smp_save_segs(struct smp_sc *sc); + +/* storage_persistent_subr.c */ + +void smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx, + uint64_t off, const char *id); +int smp_chk_sign(struct smp_signctx *ctx); +void smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len); +void smp_reset_sign(struct smp_signctx *ctx); +void smp_sync_sign(const struct smp_signctx *ctx); +void smp_newsilo(struct smp_sc *sc); +int smp_valid_silo(struct smp_sc *sc); + +/*-------------------------------------------------------------------- + * Caculate payload of some stuff + */ + +static inline uint64_t +smp_stuff_len(const struct smp_sc *sc, unsigned stuff) +{ + uint64_t l; + + assert(stuff < SMP_END_STUFF); + l = sc->ident->stuff[stuff + 1] - sc->ident->stuff[stuff]; + l -= SMP_SIGN_SPACE; + return (l); +} + +static inline uint64_t +smp_segend(const struct smp_seg *sg) +{ + + return (sg->p.offset + sg->p.length); +} + +static inline uint64_t +smp_spaceleft(const struct smp_sc *sc, const struct smp_seg *sg) +{ + + IASSERTALIGN(sc, sc->next_bot); + assert(sc->next_bot <= sc->next_top - IRNUP(sc, SMP_SIGN_SPACE)); + assert(sc->next_bot >= sg->p.offset); + assert(sc->next_top < sg->p.offset + sg->p.length); + return ((sc->next_top - sc->next_bot) - IRNUP(sc, SMP_SIGN_SPACE)); +} diff --git a/bin/varnishd/storage/storage_persistent_mgt.c b/bin/varnishd/storage/storage_persistent_mgt.c new file mode 100644 index 0000000..1631ea6 --- /dev/null +++ b/bin/varnishd/storage/storage_persistent_mgt.c @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Persistent storage method + * + * XXX: Before we start the client or maybe after it stops, we should give the + * XXX: stevedores a chance to examine their storage for consistency. + * + * XXX: Do we ever free the LRU-lists ? + */ + +#include "config.h" + +#include + +#include +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "vsha256.h" + +#include "persistent.h" +#include "storage/storage_persistent.h" + +#ifndef MAP_NOCORE +#define MAP_NOCORE 0 /* XXX Linux */ +#endif + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 /* XXX Linux */ +#endif + +/*-------------------------------------------------------------------- + * Calculate cleaner metrics from silo dimensions + */ + +static void +smp_metrics(struct smp_sc *sc) +{ + + /* + * We do not want to loose too big chunks of the silos + * content when we are forced to clean a segment. + * + * For now insist that a segment covers no more than 1% of the silo. + * + * XXX: This should possibly depend on the size of the silo so + * XXX: trivially small silos do not run into trouble along + * XXX: the lines of "one object per segment". + */ + + sc->min_nseg = 10; + sc->max_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->min_nseg; + + fprintf(stderr, "min_nseg = %u, max_segl = %ju\n", + sc->min_nseg, (uintmax_t)sc->max_segl); + + /* + * The number of segments are limited by the size of the segment + * table(s) and from that follows the minimum size of a segmement. + */ + + sc->max_nseg = smp_stuff_len(sc, SMP_SEG1_STUFF) / sc->min_nseg; + sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; + + while (sc->min_segl < sizeof(struct object)) { + sc->max_nseg /= 2; + sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; + } + + fprintf(stderr, "max_nseg = %u, min_segl = %ju\n", + sc->max_nseg, (uintmax_t)sc->min_segl); + + /* + * Set our initial aim point at the exponential average of the + * two extremes. + * + * XXX: This is a pretty arbitrary choice, but having no idea + * XXX: object count, size distribution or ttl pattern at this + * XXX: point, we have to do something. + */ + + sc->aim_nseg = + (unsigned) exp((log(sc->min_nseg) + log(sc->max_nseg))*.5); + sc->aim_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->aim_nseg; + + fprintf(stderr, "aim_nseg = %u, aim_segl = %ju\n", + sc->aim_nseg, (uintmax_t)sc->aim_segl); + + /* + * How much space in the free reserve pool ? + */ + sc->free_reserve = sc->aim_segl * 10; + + fprintf(stderr, "free_reserve = %ju\n", (uintmax_t)sc->free_reserve); +} + +/*-------------------------------------------------------------------- + * Set up persistent storage silo in the master process. + */ + +void +smp_mgt_init(struct stevedore *parent, int ac, char * const *av) +{ + struct smp_sc *sc; + struct smp_sign sgn; + void *target; + int i; + + ASSERT_MGT(); + + AZ(av[ac]); +#define SIZOF(foo) fprintf(stderr, \ + "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); + SIZOF(struct smp_ident); + SIZOF(struct smp_sign); + SIZOF(struct smp_segptr); + SIZOF(struct smp_object); +#undef SIZOF + + /* See comments in persistent.h */ + assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE); + + /* Allocate softc */ + ALLOC_OBJ(sc, SMP_SC_MAGIC); + XXXAN(sc); + sc->parent = parent; + sc->fd = -1; + VTAILQ_INIT(&sc->segments); + + /* Argument processing */ + if (ac != 2) + ARGV_ERR("(-spersistent) wrong number of arguments\n"); + + i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent"); + if (i == 2) + ARGV_ERR("(-spersistent) need filename (not directory)\n"); + + sc->align = sizeof(void*) * 2; + sc->granularity = getpagesize(); + sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity, + "-spersistent"); + + AZ(ftruncate(sc->fd, sc->mediasize)); + + /* Try to determine correct mmap address */ + i = read(sc->fd, &sgn, sizeof sgn); + assert(i == sizeof sgn); + if (!strcmp(sgn.ident, "SILO")) + target = (void*)(uintptr_t)sgn.mapped; + else + target = NULL; + + sc->base = mmap(target, sc->mediasize, PROT_READ|PROT_WRITE, + MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0); + + if (sc->base == MAP_FAILED) + ARGV_ERR("(-spersistent) failed to mmap (%s)\n", + strerror(errno)); + + smp_def_sign(sc, &sc->idn, 0, "SILO"); + sc->ident = SIGN_DATA(&sc->idn); + + i = smp_valid_silo(sc); + if (i) { + printf("Warning SILO (%s) not reloaded (reason=%d)\n", + sc->filename, i); + smp_newsilo(sc); + } + AZ(smp_valid_silo(sc)); + + smp_metrics(sc); + + parent->priv = sc; + + /* XXX: only for sendfile I guess... */ + mgt_child_inherit(sc->fd, "storage_persistent"); +} diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c new file mode 100644 index 0000000..5393546 --- /dev/null +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -0,0 +1,524 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Persistent storage method + * + * XXX: Before we start the client or maybe after it stops, we should give the + * XXX: stevedores a chance to examine their storage for consistency. + * + */ + +#include "config.h" + +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "hash_slinger.h" +#include "vsha256.h" +#include "vtim.h" + +#include "persistent.h" +#include "storage/storage_persistent.h" + +/*-------------------------------------------------------------------- + * Write the segmentlist back to the silo. + * + * We write the first copy, sync it synchronously, then write the + * second copy and sync it synchronously. + * + * Provided the kernel doesn't lie, that means we will always have + * at least one valid copy on in the silo. + */ + +static void +smp_save_seg(const struct smp_sc *sc, struct smp_signctx *ctx) +{ + struct smp_segptr *ss; + struct smp_seg *sg; + uint64_t length; + + Lck_AssertHeld(&sc->mtx); + smp_reset_sign(ctx); + ss = SIGN_DATA(ctx); + length = 0; + VTAILQ_FOREACH(sg, &sc->segments, list) { + assert(sg->p.offset < sc->mediasize); + assert(sg->p.offset + sg->p.length <= sc->mediasize); + *ss = sg->p; + ss++; + length += sizeof *ss; + } + smp_append_sign(ctx, SIGN_DATA(ctx), length); + smp_sync_sign(ctx); +} + +void +smp_save_segs(struct smp_sc *sc) +{ + struct smp_seg *sg, *sg2; + + Lck_AssertHeld(&sc->mtx); + + /* + * Remove empty segments from the front of the list + * before we write the segments to disk. + */ + VTAILQ_FOREACH_SAFE(sg, &sc->segments, list, sg2) { + if (sg->nobj > 0) + break; + if (sg == sc->cur_seg) + continue; + VTAILQ_REMOVE(&sc->segments, sg, list); + LRU_Free(sg->lru); + FREE_OBJ(sg); + } + smp_save_seg(sc, &sc->seg1); + smp_save_seg(sc, &sc->seg2); +} + +/*-------------------------------------------------------------------- + * Load segments + * + * The overall objective is to register the existence of an object, based + * only on the minimally sized struct smp_object, without causing the + * main object to be faulted in. + * + * XXX: We can test this by mprotecting the main body of the segment + * XXX: until the first fixup happens, or even just over this loop, + * XXX: However: the requires that the smp_objects starter further + * XXX: into the segment than a page so that they do not get hit + * XXX: by the protection. + */ + +void +smp_load_seg(const struct sess *sp, const struct smp_sc *sc, + struct smp_seg *sg) +{ + struct smp_object *so; + struct objcore *oc; + uint32_t no; + double t_now = VTIM_real(); + struct smp_signctx ctx[1]; + + ASSERT_SILO_THREAD(sc); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC); + CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); + assert(sg->flags & SMP_SEG_MUSTLOAD); + sg->flags &= ~SMP_SEG_MUSTLOAD; + AN(sg->p.offset); + if (sg->p.objlist == 0) + return; + smp_def_sign(sc, ctx, sg->p.offset, "SEGHEAD"); + if (smp_chk_sign(ctx)) + return; + + /* test SEGTAIL */ + /* test OBJIDX */ + so = (void*)(sc->base + sg->p.objlist); + sg->objs = so; + no = sg->p.lobjlist; + /* Clear the bogus "hold" count */ + sg->nobj = 0; + for (;no > 0; so++,no--) { + if (so->ttl == 0 || so->ttl < t_now) + continue; + HSH_Prealloc(sp); + oc = sp->wrk->nobjcore; + oc->flags |= OC_F_NEEDFIXUP | OC_F_LRUDONTMOVE; + oc->flags &= ~OC_F_BUSY; + smp_init_oc(oc, sg, no); + oc->ban = BAN_RefBan(oc, so->ban, sc->tailban); + memcpy(sp->wrk->nobjhead->digest, so->hash, SHA256_LEN); + (void)HSH_Insert(sp); + AZ(sp->wrk->nobjcore); + EXP_Inject(oc, sg->lru, so->ttl); + sg->nobj++; + } + WRK_SumStat(sp->wrk); + sg->flags |= SMP_SEG_LOADED; +} + +/*-------------------------------------------------------------------- + * Create a new segment + */ + +void +smp_new_seg(struct smp_sc *sc) +{ + struct smp_seg *sg, *sg2; + + Lck_AssertHeld(&sc->mtx); + ALLOC_OBJ(sg, SMP_SEG_MAGIC); + AN(sg); + sg->sc = sc; + sg->lru = LRU_Alloc(); + CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); + + /* XXX: find where it goes in silo */ + + sg->p.offset = sc->free_offset; + // XXX: align */ + assert(sg->p.offset >= sc->ident->stuff[SMP_SPC_STUFF]); + assert(sg->p.offset < sc->mediasize); + + sg->p.length = sc->aim_segl; + sg->p.length &= ~7; + + if (smp_segend(sg) > sc->mediasize) { + sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; + sg->p.offset = sc->free_offset; + sg2 = VTAILQ_FIRST(&sc->segments); + if (smp_segend(sg) > sg2->p.offset) { + printf("Out of space in persistent silo\n"); + printf("Committing suicide, restart will make space\n"); + exit (0); + } + } + + + assert(smp_segend(sg) <= sc->mediasize); + + sg2 = VTAILQ_FIRST(&sc->segments); + if (sg2 != NULL && sg2->p.offset > sc->free_offset) { + if (smp_segend(sg) > sg2->p.offset) { + printf("Out of space in persistent silo\n"); + printf("Committing suicide, restart will make space\n"); + exit (0); + } + assert(smp_segend(sg) <= sg2->p.offset); + } + + sg->p.offset = IRNUP(sc, sg->p.offset); + sg->p.length = IRNDN(sc, sg->p.length); + sc->free_offset = sg->p.offset + sg->p.length; + + VTAILQ_INSERT_TAIL(&sc->segments, sg, list); + + /* Neuter the new segment in case there is an old one there */ + AN(sg->p.offset); + smp_def_sign(sc, sg->ctx, sg->p.offset, "SEGHEAD"); + smp_reset_sign(sg->ctx); + smp_sync_sign(sg->ctx); + + /* Set up our allocation points */ + sc->cur_seg = sg; + sc->next_bot = sg->p.offset + IRNUP(sc, SMP_SIGN_SPACE); + sc->next_top = smp_segend(sg); + sc->next_top -= IRNUP(sc, SMP_SIGN_SPACE); + IASSERTALIGN(sc, sc->next_bot); + IASSERTALIGN(sc, sc->next_top); + sg->objs = (void*)(sc->base + sc->next_top); +} + +/*-------------------------------------------------------------------- + * Close a segment + */ + +void +smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) +{ + uint64_t left, dst, len; + void *dp; + + Lck_AssertHeld(&sc->mtx); + + assert(sg == sc->cur_seg); + AN(sg->p.offset); + sc->cur_seg = NULL; + + if (sg->nalloc == 0) { + /* XXX: if segment is empty, delete instead */ + VTAILQ_REMOVE(&sc->segments, sg, list); + free(sg); + return; + } + + /* + * If there is enough space left, that we can move the smp_objects + * down without overwriting the present copy, we will do so to + * compact the segment. + */ + left = smp_spaceleft(sc, sg); + len = sizeof(struct smp_object) * sg->p.lobjlist; + if (len < left) { + dst = sc->next_bot + IRNUP(sc, SMP_SIGN_SPACE); + dp = sc->base + dst; + assert((uintptr_t)dp + len < (uintptr_t)sg->objs); + memcpy(dp, sg->objs, len); + sc->next_top = dst; + sg->objs = dp; + sg->p.length = (sc->next_top - sg->p.offset) + + len + IRNUP(sc, SMP_SIGN_SPACE); + (void)smp_spaceleft(sc, sg); /* for the asserts */ + + } + + /* Update the segment header */ + sg->p.objlist = sc->next_top; + + /* Write the (empty) OBJIDX signature */ + sc->next_top -= IRNUP(sc, SMP_SIGN_SPACE); + assert(sc->next_top >= sc->next_bot); + smp_def_sign(sc, sg->ctx, sc->next_top, "OBJIDX"); + smp_reset_sign(sg->ctx); + smp_sync_sign(sg->ctx); + + /* Write the (empty) SEGTAIL signature */ + smp_def_sign(sc, sg->ctx, + sg->p.offset + sg->p.length - IRNUP(sc, SMP_SIGN_SPACE), "SEGTAIL"); + smp_reset_sign(sg->ctx); + smp_sync_sign(sg->ctx); + + /* Save segment list */ + smp_save_segs(sc); + sc->free_offset = smp_segend(sg); +} + + +/*--------------------------------------------------------------------- + */ + +static struct smp_object * +smp_find_so(const struct smp_seg *sg, unsigned priv2) +{ + struct smp_object *so; + + assert(priv2 > 0); + assert(priv2 <= sg->p.lobjlist); + so = &sg->objs[sg->p.lobjlist - priv2]; + return (so); +} + +/*--------------------------------------------------------------------- + * Check if a given storage structure is valid to use + */ + +static int +smp_loaded_st(const struct smp_sc *sc, const struct smp_seg *sg, + const struct storage *st) +{ + struct smp_seg *sg2; + const uint8_t *pst; + uint64_t o; + + (void)sg; /* XXX: faster: Start search from here */ + pst = (const void *)st; + + if (pst < (sc->base + sc->ident->stuff[SMP_SPC_STUFF])) + return (0x01); /* Before silo payload start */ + if (pst > (sc->base + sc->ident->stuff[SMP_END_STUFF])) + return (0x02); /* After silo end */ + + o = pst - sc->base; + + /* Find which segment contains the storage structure */ + VTAILQ_FOREACH(sg2, &sc->segments, list) + if (o > sg2->p.offset && (o + sizeof(*st)) < sg2->p.objlist) + break; + if (sg2 == NULL) + return (0x04); /* No claiming segment */ + if (!(sg2->flags & SMP_SEG_LOADED)) + return (0x08); /* Claiming segment not loaded */ + + /* It is now safe to access the storage structure */ + if (st->magic != STORAGE_MAGIC) + return (0x10); /* Not enough magic */ + + if (o + st->space >= sg2->p.objlist) + return (0x20); /* Allocation not inside segment */ + + if (st->len > st->space) + return (0x40); /* Plain bad... */ + + /* + * XXX: We could patch up st->stevedore and st->priv here + * XXX: but if things go right, we will never need them. + */ + return (0); +} + +/*--------------------------------------------------------------------- + * objcore methods for persistent objects + */ + +static struct object * +smp_oc_getobj(struct worker *wrk, struct objcore *oc) +{ + struct object *o; + struct smp_seg *sg; + struct smp_object *so; + struct storage *st; + uint64_t l; + int bad; + + /* Some calls are direct, but they should match anyway */ + assert(oc->methods->getobj == smp_oc_getobj); + + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + if (wrk == NULL) + AZ(oc->flags & OC_F_NEEDFIXUP); + + CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); + so = smp_find_so(sg, oc->priv2); + + o = (void*)(sg->sc->base + so->ptr); + /* + * The object may not be in this segment since we allocate it + * In a separate operation than the smp_object. We could check + * that it is in a later segment, but that would be complicated. + * XXX: For now, be happy if it is inside th silo + */ + ASSERT_PTR_IN_SILO(sg->sc, o); + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + + /* + * If this flag is not set, it will not be, and the lock is not + * needed to test it. + */ + if (!(oc->flags & OC_F_NEEDFIXUP)) + return (o); + + AN(wrk); + Lck_Lock(&sg->sc->mtx); + /* Check again, we might have raced. */ + if (oc->flags & OC_F_NEEDFIXUP) { + /* We trust caller to have a refcnt for us */ + o->objcore = oc; + + bad = 0; + l = 0; + VTAILQ_FOREACH(st, &o->store, list) { + bad |= smp_loaded_st(sg->sc, sg, st); + if (bad) + break; + l += st->len; + } + if (l != o->len) + bad |= 0x100; + + if(bad) { + EXP_Set_ttl(&o->exp, -1); + so->ttl = 0; + } + + sg->nfixed++; + wrk->stats.n_object++; + wrk->stats.n_vampireobject--; + oc->flags &= ~OC_F_NEEDFIXUP; + } + Lck_Unlock(&sg->sc->mtx); + EXP_Rearm(o); + return (o); +} + +static void +smp_oc_updatemeta(struct objcore *oc) +{ + struct object *o; + struct smp_seg *sg; + struct smp_object *so; + double mttl; + + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + o = smp_oc_getobj(NULL, oc); + AN(o); + + CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); + CHECK_OBJ_NOTNULL(sg->sc, SMP_SC_MAGIC); + so = smp_find_so(sg, oc->priv2); + + mttl = EXP_Grace(NULL, o); + + if (sg == sg->sc->cur_seg) { + /* Lock necessary, we might race close_seg */ + Lck_Lock(&sg->sc->mtx); + so->ban = BAN_Time(oc->ban); + so->ttl = mttl; + Lck_Unlock(&sg->sc->mtx); + } else { + so->ban = BAN_Time(oc->ban); + so->ttl = mttl; + } +} + +static void __match_proto__() +smp_oc_freeobj(struct objcore *oc) +{ + struct smp_seg *sg; + struct smp_object *so; + + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + + CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); + so = smp_find_so(sg, oc->priv2); + + Lck_Lock(&sg->sc->mtx); + so->ttl = 0; + so->ptr = 0; + + assert(sg->nobj > 0); + assert(sg->nfixed > 0); + sg->nobj--; + sg->nfixed--; + + Lck_Unlock(&sg->sc->mtx); +} + +/*-------------------------------------------------------------------- + * Find the per-segment lru list for this object + */ + +static struct lru * +smp_oc_getlru(const struct objcore *oc) +{ + struct smp_seg *sg; + + CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); + return (sg->lru); +} + +static struct objcore_methods smp_oc_methods = { + .getobj = smp_oc_getobj, + .updatemeta = smp_oc_updatemeta, + .freeobj = smp_oc_freeobj, + .getlru = smp_oc_getlru, +}; + +/*--------------------------------------------------------------------*/ + +void +smp_init_oc(struct objcore *oc, struct smp_seg *sg, unsigned objidx) +{ + + oc->priv = sg; + oc->priv2 = objidx; + oc->methods = &smp_oc_methods; +} diff --git a/bin/varnishd/storage/storage_persistent_subr.c b/bin/varnishd/storage/storage_persistent_subr.c new file mode 100644 index 0000000..2066e72 --- /dev/null +++ b/bin/varnishd/storage/storage_persistent_subr.c @@ -0,0 +1,302 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Persistent storage method + * + * XXX: Before we start the client or maybe after it stops, we should give the + * XXX: stevedores a chance to examine their storage for consistency. + * + * XXX: Do we ever free the LRU-lists ? + */ + +#include "config.h" + +#include + +#include +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +#include "vsha256.h" + +#include "persistent.h" +#include "storage/storage_persistent.h" + +/*-------------------------------------------------------------------- + * SIGNATURE functions + * The signature is SHA256 over: + * 1. The smp_sign struct up to but not including the length field. + * 2. smp_sign->length bytes, starting after the smp_sign structure + * 3. The smp-sign->length field. + * The signature is stored after the byte-range from step 2. + */ + +/*-------------------------------------------------------------------- + * Define a signature by location and identifier. + */ + +void +smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx, + uint64_t off, const char *id) +{ + + AZ(off & 7); /* Alignment */ + assert(strlen(id) < sizeof ctx->ss->ident); + + memset(ctx, 0, sizeof *ctx); + ctx->ss = (void*)(sc->base + off); + ctx->unique = sc->unique; + ctx->id = id; +} + +/*-------------------------------------------------------------------- + * Check that a signature is good, leave state ready for append + */ +int +smp_chk_sign(struct smp_signctx *ctx) +{ + struct SHA256Context cx; + unsigned char sign[SHA256_LEN]; + int r = 0; + + if (strncmp(ctx->id, ctx->ss->ident, sizeof ctx->ss->ident)) + r = 1; + else if (ctx->unique != ctx->ss->unique) + r = 2; + else if ((uintptr_t)ctx->ss != ctx->ss->mapped) + r = 3; + else { + SHA256_Init(&ctx->ctx); + SHA256_Update(&ctx->ctx, ctx->ss, + offsetof(struct smp_sign, length)); + SHA256_Update(&ctx->ctx, SIGN_DATA(ctx), ctx->ss->length); + cx = ctx->ctx; + SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length)); + SHA256_Final(sign, &cx); + if (memcmp(sign, SIGN_END(ctx), sizeof sign)) + r = 4; + } + if (r) { + fprintf(stderr, "CHK(%p %s %p %s) = %d\n", + ctx, ctx->id, ctx->ss, + r > 1 ? ctx->ss->ident : "", r); + } + return (r); +} + +/*-------------------------------------------------------------------- + * Append data to a signature + */ +void +smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len) +{ + struct SHA256Context cx; + unsigned char sign[SHA256_LEN]; + + if (len != 0) { + SHA256_Update(&ctx->ctx, ptr, len); + ctx->ss->length += len; + } + cx = ctx->ctx; + SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length)); + SHA256_Final(sign, &cx); + memcpy(SIGN_END(ctx), sign, sizeof sign); +XXXAZ(smp_chk_sign(ctx)); +} + +/*-------------------------------------------------------------------- + * Reset a signature to empty, prepare for appending. + */ + +void +smp_reset_sign(struct smp_signctx *ctx) +{ + + memset(ctx->ss, 0, sizeof *ctx->ss); + strcpy(ctx->ss->ident, ctx->id); + ctx->ss->unique = ctx->unique; + ctx->ss->mapped = (uintptr_t)ctx->ss; + SHA256_Init(&ctx->ctx); + SHA256_Update(&ctx->ctx, ctx->ss, + offsetof(struct smp_sign, length)); + smp_append_sign(ctx, NULL, 0); +} + +/*-------------------------------------------------------------------- + * Force a write of a signature block to the backing store. + */ + +void +smp_sync_sign(const struct smp_signctx *ctx) +{ + int i; + + /* XXX: round to pages */ + i = msync((void*)ctx->ss, ctx->ss->length + SHA256_LEN, MS_SYNC); + if (i && 0) + fprintf(stderr, "SyncSign(%p %s) = %d %s\n", + ctx->ss, ctx->id, i, strerror(errno)); +} + +/*-------------------------------------------------------------------- + * Create and force a new signature to backing store + */ + +static void +smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx, + uint64_t off, const char *id) +{ + smp_def_sign(sc, ctx, off, id); + smp_reset_sign(ctx); + smp_sync_sign(ctx); +} + +/*-------------------------------------------------------------------- + * Initialize a Silo with a valid but empty structure. + * + * XXX: more intelligent sizing of things. + */ + +void +smp_newsilo(struct smp_sc *sc) +{ + struct smp_ident *si; + + ASSERT_MGT(); + assert(strlen(SMP_IDENT_STRING) < sizeof si->ident); + + /* Choose a new random number */ + sc->unique = random(); + + smp_reset_sign(&sc->idn); + si = sc->ident; + + memset(si, 0, sizeof *si); + strcpy(si->ident, SMP_IDENT_STRING); + si->byte_order = 0x12345678; + si->size = sizeof *si; + si->major_version = 2; + si->unique = sc->unique; + si->mediasize = sc->mediasize; + si->granularity = sc->granularity; + /* + * Aim for cache-line-width + */ + si->align = sizeof(void*) * 2; + sc->align = si->align; + + si->stuff[SMP_BAN1_STUFF] = sc->granularity; + si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024; + si->stuff[SMP_SEG1_STUFF] = si->stuff[SMP_BAN2_STUFF] + 1024*1024; + si->stuff[SMP_SEG2_STUFF] = si->stuff[SMP_SEG1_STUFF] + 1024*1024; + si->stuff[SMP_SPC_STUFF] = si->stuff[SMP_SEG2_STUFF] + 1024*1024; + si->stuff[SMP_END_STUFF] = si->mediasize; + assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]); + + smp_new_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1"); + smp_new_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2"); + smp_new_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1"); + smp_new_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2"); + + smp_append_sign(&sc->idn, si, sizeof *si); + smp_sync_sign(&sc->idn); +} + +/*-------------------------------------------------------------------- + * Check if a silo is valid. + */ + +int +smp_valid_silo(struct smp_sc *sc) +{ + struct smp_ident *si; + int i, j; + + assert(strlen(SMP_IDENT_STRING) < sizeof si->ident); + + i = smp_chk_sign(&sc->idn); + if (i) + return (i); + + si = sc->ident; + if (strcmp(si->ident, SMP_IDENT_STRING)) + return (12); + if (si->byte_order != 0x12345678) + return (13); + if (si->size != sizeof *si) + return (14); + if (si->major_version != 2) + return (15); + if (si->mediasize != sc->mediasize) + return (17); + if (si->granularity != sc->granularity) + return (18); + if (si->align < sizeof(void*)) + return (19); + if (!PWR2(si->align)) + return (20); + sc->align = si->align; + sc->unique = si->unique; + + /* XXX: Sanity check stuff[6] */ + + assert(si->stuff[SMP_BAN1_STUFF] > sizeof *si + SHA256_LEN); + assert(si->stuff[SMP_BAN2_STUFF] > si->stuff[SMP_BAN1_STUFF]); + assert(si->stuff[SMP_SEG1_STUFF] > si->stuff[SMP_BAN2_STUFF]); + assert(si->stuff[SMP_SEG2_STUFF] > si->stuff[SMP_SEG1_STUFF]); + assert(si->stuff[SMP_SPC_STUFF] > si->stuff[SMP_SEG2_STUFF]); + assert(si->stuff[SMP_END_STUFF] == sc->mediasize); + + assert(smp_stuff_len(sc, SMP_SEG1_STUFF) > 65536); + assert(smp_stuff_len(sc, SMP_SEG1_STUFF) == + smp_stuff_len(sc, SMP_SEG2_STUFF)); + + assert(smp_stuff_len(sc, SMP_BAN1_STUFF) > 65536); + assert(smp_stuff_len(sc, SMP_BAN1_STUFF) == + smp_stuff_len(sc, SMP_BAN2_STUFF)); + + smp_def_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1"); + smp_def_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2"); + smp_def_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1"); + smp_def_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2"); + + /* We must have one valid BAN table */ + i = smp_chk_sign(&sc->ban1); + j = smp_chk_sign(&sc->ban2); + if (i && j) + return (100 + i * 10 + j); + + /* We must have one valid SEG table */ + i = smp_chk_sign(&sc->seg1); + j = smp_chk_sign(&sc->seg2); + if (i && j) + return (200 + i * 10 + j); + return (0); +} diff --git a/bin/varnishd/storage/storage_synth.c b/bin/varnishd/storage/storage_synth.c new file mode 100644 index 0000000..0519738 --- /dev/null +++ b/bin/varnishd/storage/storage_synth.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software 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. + * + * Storage method for synthetic content, based on vsb. + */ + +#include "config.h" + +#include + +#include "cache.h" +#include "storage/storage.h" + + +static struct lock sms_mtx; + +static void +sms_free(struct storage *sto) +{ + + CHECK_OBJ_NOTNULL(sto, STORAGE_MAGIC); + Lck_Lock(&sms_mtx); + VSC_C_main->sms_nobj--; + VSC_C_main->sms_nbytes -= sto->len; + VSC_C_main->sms_bfree += sto->len; + Lck_Unlock(&sms_mtx); + VSB_delete(sto->priv); + free(sto); +} + +void +SMS_Init(void) +{ + + Lck_New(&sms_mtx, lck_sms); +} + +static struct stevedore sms_stevedore = { + .magic = STEVEDORE_MAGIC, + .name = "synth", + .free = sms_free, +}; + +struct vsb * +SMS_Makesynth(struct object *obj) +{ + struct storage *sto; + struct vsb *vsb; + + CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); + STV_Freestore(obj); + obj->len = 0; + + Lck_Lock(&sms_mtx); + VSC_C_main->sms_nreq++; + VSC_C_main->sms_nobj++; + Lck_Unlock(&sms_mtx); + + sto = calloc(sizeof *sto, 1); + XXXAN(sto); + vsb = VSB_new_auto(); + XXXAN(vsb); + sto->priv = vsb; + sto->len = 0; + sto->space = 0; +#ifdef SENDFILE_WORKS + sto->fd = -1; +#endif + sto->stevedore = &sms_stevedore; + sto->magic = STORAGE_MAGIC; + + VTAILQ_INSERT_TAIL(&obj->store, sto, list); + return (vsb); +} + +void +SMS_Finish(struct object *obj) +{ + struct storage *sto; + struct vsb *vsb; + + CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); + sto = VTAILQ_FIRST(&obj->store); + assert(sto->stevedore == &sms_stevedore); + vsb = sto->priv; + AZ(VSB_finish(vsb)); + + sto->ptr = (void*)VSB_data(vsb); + sto->len = VSB_len(vsb); + sto->space = VSB_len(vsb); + obj->len = sto->len; + Lck_Lock(&sms_mtx); + VSC_C_main->sms_nbytes += sto->len; + VSC_C_main->sms_balloc += sto->len; + Lck_Unlock(&sms_mtx); +} diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c new file mode 100644 index 0000000..78110d4 --- /dev/null +++ b/bin/varnishd/storage/storage_umem.c @@ -0,0 +1,166 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Storage method based on umem_alloc(3MALLOC) + */ + +#include "config.h" + +#ifdef HAVE_LIBUMEM + +#include + +#include +#include +#include + +#include "cache.h" +#include "storage/storage.h" + +static size_t smu_max = SIZE_MAX; +static MTX smu_mtx; + +struct smu { + struct storage s; + size_t sz; +}; + +static struct storage * +smu_alloc(struct stevedore *st, size_t size) +{ + struct smu *smu; + + Lck_Lock(&smu_mtx); + VSC_C_main->sma_nreq++; + if (VSC_C_main->sma_nbytes + size > smu_max) + size = 0; + else { + VSC_C_main->sma_nobj++; + VSC_C_main->sma_nbytes += size; + VSC_C_main->sma_balloc += size; + } + Lck_Unlock(&smu_mtx); + + if (size == 0) + return (NULL); + + smu = umem_zalloc(sizeof *smu, UMEM_DEFAULT); + if (smu == NULL) + return (NULL); + smu->sz = size; + smu->s.priv = smu; + smu->s.ptr = umem_alloc(size, UMEM_DEFAULT); + XXXAN(smu->s.ptr); + smu->s.len = 0; + smu->s.space = size; + smu->s.fd = -1; + smu->s.stevedore = st; + smu->s.magic = STORAGE_MAGIC; + return (&smu->s); +} + +static void +smu_free(struct storage *s) +{ + struct smu *smu; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + smu = s->priv; + assert(smu->sz == smu->s.space); + Lck_Lock(&smu_mtx); + VSC_C_main->sma_nobj--; + VSC_C_main->sma_nbytes -= smu->sz; + VSC_C_main->sma_bfree += smu->sz; + Lck_Unlock(&smu_mtx); + umem_free(smu->s.ptr, smu->s.space); + umem_free(smu, sizeof *smu); +} + +static void +smu_trim(const struct storage *s, size_t size) +{ + struct smu *smu; + void *p; + + CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); + smu = s->priv; + assert(smu->sz == smu->s.space); + if ((p = umem_alloc(size, UMEM_DEFAULT)) != NULL) { + memcpy(p, smu->s.ptr, size); + umem_free(smu->s.ptr, smu->s.space); + Lck_Lock(&smu_mtx); + VSC_C_main->sma_nbytes -= (smu->sz - size); + VSC_C_main->sma_bfree += smu->sz - size; + smu->sz = size; + Lck_Unlock(&smu_mtx); + smu->s.ptr = p; + smu->s.space = size; + } +} + +static void +smu_init(struct stevedore *parent, int ac, char * const *av) +{ + const char *e; + uintmax_t u; + + (void)parent; + + AZ(av[ac]); + if (ac > 1) + ARGV_ERR("(-sumem) too many arguments\n"); + + if (ac == 0 || *av[0] == '\0') + return; + + e = VNUM_2bytes(av[0], &u, 0); + if (e != NULL) + ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); + if ((u != (uintmax_t)(size_t)u)) + ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); + smu_max = u; +} + +static void +smu_open(const struct stevedore *st) +{ + (void)st; + AZ(pthread_mutex_init(&smu_mtx, NULL)); +} + +const struct stevedore smu_stevedore = { + .magic = STEVEDORE_MAGIC, + .name = "umem", + .init = smu_init, + .open = smu_open, + .alloc = smu_alloc, + .free = smu_free, + .trim = smu_trim, +}; + +#endif /* HAVE_UMEM_H */ diff --git a/bin/varnishd/storage_file.c b/bin/varnishd/storage_file.c deleted file mode 100644 index ecfc4ff..0000000 --- a/bin/varnishd/storage_file.c +++ /dev/null @@ -1,615 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - * Storage method based on mmap'ed file - */ - -#include "config.h" - -#include - -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "vnum.h" - -#ifndef MAP_NOCORE -#define MAP_NOCORE 0 /* XXX Linux */ -#endif - -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 /* XXX Linux */ -#endif - -#define MINPAGES 128 - -/* - * Number of buckets on free-list. - * - * Last bucket is "larger than" so choose number so that the second - * to last bucket matches the 128k CHUNKSIZE in cache_fetch.c when - * using the a 4K minimal page size - */ -#define NBUCKET (128 / 4 + 1) - -/*--------------------------------------------------------------------*/ - -VTAILQ_HEAD(smfhead, smf); - -struct smf { - unsigned magic; -#define SMF_MAGIC 0x0927a8a0 - struct storage s; - struct smf_sc *sc; - - int alloc; - - off_t size; - off_t offset; - unsigned char *ptr; - - VTAILQ_ENTRY(smf) order; - VTAILQ_ENTRY(smf) status; - struct smfhead *flist; -}; - -struct smf_sc { - unsigned magic; -#define SMF_SC_MAGIC 0x52962ee7 - struct lock mtx; - struct VSC_C_smf *stats; - - const char *filename; - int fd; - unsigned pagesize; - uintmax_t filesize; - struct smfhead order; - struct smfhead free[NBUCKET]; - struct smfhead used; -}; - -/*--------------------------------------------------------------------*/ - -static void -smf_initfile(struct smf_sc *sc, const char *size) -{ - sc->filesize = STV_FileSize(sc->fd, size, &sc->pagesize, "-sfile"); - - AZ(ftruncate(sc->fd, (off_t)sc->filesize)); - - /* XXX: force block allocation here or in open ? */ -} - -static const char default_size[] = "100M"; -static const char default_filename[] = "."; - -static void -smf_init(struct stevedore *parent, int ac, char * const *av) -{ - const char *size, *fn, *r; - struct smf_sc *sc; - unsigned u; - uintmax_t page_size; - - AZ(av[ac]); - - fn = default_filename; - size = default_size; - page_size = getpagesize(); - - if (ac > 3) - ARGV_ERR("(-sfile) too many arguments\n"); - if (ac > 0 && *av[0] != '\0') - fn = av[0]; - if (ac > 1 && *av[1] != '\0') - size = av[1]; - if (ac > 2 && *av[2] != '\0') { - - r = VNUM_2bytes(av[2], &page_size, 0); - if (r != NULL) - ARGV_ERR("(-sfile) granularity \"%s\": %s\n", av[2], r); - } - - AN(fn); - AN(size); - - ALLOC_OBJ(sc, SMF_SC_MAGIC); - XXXAN(sc); - VTAILQ_INIT(&sc->order); - for (u = 0; u < NBUCKET; u++) - VTAILQ_INIT(&sc->free[u]); - VTAILQ_INIT(&sc->used); - sc->pagesize = page_size; - - parent->priv = sc; - - (void)STV_GetFile(fn, &sc->fd, &sc->filename, "-sfile"); - - mgt_child_inherit(sc->fd, "storage_file"); - smf_initfile(sc, size); -} - -/*-------------------------------------------------------------------- - * Insert/Remove from correct freelist - */ - -static void -insfree(struct smf_sc *sc, struct smf *sp) -{ - size_t b; - struct smf *sp2; - size_t ns; - - assert(sp->alloc == 0); - assert(sp->flist == NULL); - Lck_AssertHeld(&sc->mtx); - b = sp->size / sc->pagesize; - if (b >= NBUCKET) { - b = NBUCKET - 1; - sc->stats->g_smf_large++; - } else { - sc->stats->g_smf_frag++; - } - sp->flist = &sc->free[b]; - ns = b * sc->pagesize; - VTAILQ_FOREACH(sp2, sp->flist, status) { - assert(sp2->size >= ns); - assert(sp2->alloc == 0); - assert(sp2->flist == sp->flist); - if (sp->offset < sp2->offset) - break; - } - if (sp2 == NULL) - VTAILQ_INSERT_TAIL(sp->flist, sp, status); - else - VTAILQ_INSERT_BEFORE(sp2, sp, status); -} - -static void -remfree(const struct smf_sc *sc, struct smf *sp) -{ - size_t b; - - assert(sp->alloc == 0); - assert(sp->flist != NULL); - Lck_AssertHeld(&sc->mtx); - b = sp->size / sc->pagesize; - if (b >= NBUCKET) { - b = NBUCKET - 1; - sc->stats->g_smf_large--; - } else { - sc->stats->g_smf_frag--; - } - assert(sp->flist == &sc->free[b]); - VTAILQ_REMOVE(sp->flist, sp, status); - sp->flist = NULL; -} - -/*-------------------------------------------------------------------- - * Allocate a range from the first free range that is large enough. - */ - -static struct smf * -alloc_smf(struct smf_sc *sc, size_t bytes) -{ - struct smf *sp, *sp2; - size_t b; - - assert(!(bytes % sc->pagesize)); - b = bytes / sc->pagesize; - if (b >= NBUCKET) - b = NBUCKET - 1; - for (sp = NULL; b < NBUCKET - 1; b++) { - sp = VTAILQ_FIRST(&sc->free[b]); - if (sp != NULL) - break; - } - if (sp == NULL) { - VTAILQ_FOREACH(sp, &sc->free[NBUCKET -1], status) - if (sp->size >= bytes) - break; - } - if (sp == NULL) - return (sp); - - assert(sp->size >= bytes); - remfree(sc, sp); - - if (sp->size == bytes) { - sp->alloc = 1; - VTAILQ_INSERT_TAIL(&sc->used, sp, status); - return (sp); - } - - /* Split from front */ - sp2 = malloc(sizeof *sp2); - XXXAN(sp2); - sc->stats->g_smf++; - *sp2 = *sp; - - sp->offset += bytes; - sp->ptr += bytes; - sp->size -= bytes; - - sp2->size = bytes; - sp2->alloc = 1; - VTAILQ_INSERT_BEFORE(sp, sp2, order); - VTAILQ_INSERT_TAIL(&sc->used, sp2, status); - insfree(sc, sp); - return (sp2); -} - -/*-------------------------------------------------------------------- - * Free a range. Attempt merge forward and backward, then sort into - * free list according to age. - */ - -static void -free_smf(struct smf *sp) -{ - struct smf *sp2; - struct smf_sc *sc = sp->sc; - - CHECK_OBJ_NOTNULL(sp, SMF_MAGIC); - assert(sp->alloc != 0); - assert(sp->size > 0); - assert(!(sp->size % sc->pagesize)); - VTAILQ_REMOVE(&sc->used, sp, status); - sp->alloc = 0; - - sp2 = VTAILQ_NEXT(sp, order); - if (sp2 != NULL && - sp2->alloc == 0 && - (sp2->ptr == sp->ptr + sp->size) && - (sp2->offset == sp->offset + sp->size)) { - sp->size += sp2->size; - VTAILQ_REMOVE(&sc->order, sp2, order); - remfree(sc, sp2); - free(sp2); - sc->stats->g_smf--; - } - - sp2 = VTAILQ_PREV(sp, smfhead, order); - if (sp2 != NULL && - sp2->alloc == 0 && - (sp->ptr == sp2->ptr + sp2->size) && - (sp->offset == sp2->offset + sp2->size)) { - remfree(sc, sp2); - sp2->size += sp->size; - VTAILQ_REMOVE(&sc->order, sp, order); - free(sp); - sc->stats->g_smf--; - sp = sp2; - } - - insfree(sc, sp); -} - -/*-------------------------------------------------------------------- - * Trim the tail of a range. - */ - -static void -trim_smf(struct smf *sp, size_t bytes) -{ - struct smf *sp2; - struct smf_sc *sc = sp->sc; - - assert(sp->alloc != 0); - assert(bytes > 0); - assert(bytes < sp->size); - assert(!(bytes % sc->pagesize)); - assert(!(sp->size % sc->pagesize)); - CHECK_OBJ_NOTNULL(sp, SMF_MAGIC); - sp2 = malloc(sizeof *sp2); - XXXAN(sp2); - sc->stats->g_smf++; - *sp2 = *sp; - - sp2->size -= bytes; - sp->size = bytes; - sp2->ptr += bytes; - sp2->offset += bytes; - VTAILQ_INSERT_AFTER(&sc->order, sp, sp2, order); - VTAILQ_INSERT_TAIL(&sc->used, sp2, status); - free_smf(sp2); -} - -/*-------------------------------------------------------------------- - * Insert a newly created range as busy, then free it to do any collapses - */ - -static void -new_smf(struct smf_sc *sc, unsigned char *ptr, off_t off, size_t len) -{ - struct smf *sp, *sp2; - - assert(!(len % sc->pagesize)); - sp = calloc(sizeof *sp, 1); - XXXAN(sp); - sp->magic = SMF_MAGIC; - sp->s.magic = STORAGE_MAGIC; - sc->stats->g_smf++; - - sp->sc = sc; - sp->size = len; - sp->ptr = ptr; - sp->offset = off; - sp->alloc = 1; - - VTAILQ_FOREACH(sp2, &sc->order, order) { - if (sp->ptr < sp2->ptr) { - VTAILQ_INSERT_BEFORE(sp2, sp, order); - break; - } - } - if (sp2 == NULL) - VTAILQ_INSERT_TAIL(&sc->order, sp, order); - - VTAILQ_INSERT_HEAD(&sc->used, sp, status); - - free_smf(sp); -} - -/*--------------------------------------------------------------------*/ - -/* - * XXX: This may be too aggressive and soak up too much address room. - * XXX: On the other hand, the user, directly or implicitly asked us to - * XXX: use this much storage, so we should make a decent effort. - * XXX: worst case (I think), malloc will fail. - */ - -static void -smf_open_chunk(struct smf_sc *sc, off_t sz, off_t off, off_t *fail, off_t *sum) -{ - void *p; - off_t h; - - assert(sz != 0); - assert(!(sz % sc->pagesize)); - - if (*fail < (uintmax_t)sc->pagesize * MINPAGES) - return; - - if (sz > 0 && sz < *fail && sz < SSIZE_MAX) { - p = mmap(NULL, sz, PROT_READ|PROT_WRITE, - MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, off); - if (p != MAP_FAILED) { - (void) madvise(p, sz, MADV_RANDOM); - (*sum) += sz; - new_smf(sc, p, off, sz); - return; - } - } - - if (sz < *fail) - *fail = sz; - - h = sz / 2; - if (h > SSIZE_MAX) - h = SSIZE_MAX; - h -= (h % sc->pagesize); - - smf_open_chunk(sc, h, off, fail, sum); - smf_open_chunk(sc, sz - h, off + h, fail, sum); -} - -static void -smf_open(const struct stevedore *st) -{ - struct smf_sc *sc; - off_t fail = 1 << 30; /* XXX: where is OFF_T_MAX ? */ - off_t sum = 0; - - CAST_OBJ_NOTNULL(sc, st->priv, SMF_SC_MAGIC); - sc->stats = VSM_Alloc(sizeof *sc->stats, - VSC_CLASS, VSC_TYPE_SMF, st->ident); - Lck_New(&sc->mtx, lck_smf); - Lck_Lock(&sc->mtx); - smf_open_chunk(sc, sc->filesize, 0, &fail, &sum); - Lck_Unlock(&sc->mtx); - printf("SMF.%s mmap'ed %ju bytes of %ju\n", - st->ident, (uintmax_t)sum, sc->filesize); - - /* XXX */ - if (sum < MINPAGES * (off_t)getpagesize()) - exit (2); - - sc->stats->g_space += sc->filesize; -} - -/*--------------------------------------------------------------------*/ - -static struct storage * -smf_alloc(struct stevedore *st, size_t size) -{ - struct smf *smf; - struct smf_sc *sc; - - CAST_OBJ_NOTNULL(sc, st->priv, SMF_SC_MAGIC); - assert(size > 0); - size += (sc->pagesize - 1); - size &= ~(sc->pagesize - 1); - Lck_Lock(&sc->mtx); - sc->stats->c_req++; - smf = alloc_smf(sc, size); - if (smf == NULL) { - sc->stats->c_fail++; - Lck_Unlock(&sc->mtx); - return (NULL); - } - CHECK_OBJ_NOTNULL(smf, SMF_MAGIC); - sc->stats->g_alloc++; - sc->stats->c_bytes += smf->size; - sc->stats->g_bytes += smf->size; - sc->stats->g_space -= smf->size; - Lck_Unlock(&sc->mtx); - CHECK_OBJ_NOTNULL(&smf->s, STORAGE_MAGIC); /*lint !e774 */ - XXXAN(smf); - assert(smf->size == size); - smf->s.space = size; - smf->s.priv = smf; - smf->s.ptr = smf->ptr; - smf->s.len = 0; - smf->s.stevedore = st; -#ifdef SENDFILE_WORKS - smf->s.fd = smf->sc->fd; - smf->s.where = smf->offset; -#endif - return (&smf->s); -} - -/*--------------------------------------------------------------------*/ - -static void -smf_trim(struct storage *s, size_t size) -{ - struct smf *smf; - struct smf_sc *sc; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - assert(size > 0); - assert(size <= s->space); - xxxassert(size > 0); /* XXX: seen */ - CAST_OBJ_NOTNULL(smf, s->priv, SMF_MAGIC); - assert(size <= smf->size); - sc = smf->sc; - size += (sc->pagesize - 1); - size &= ~(sc->pagesize - 1); - if (smf->size > size) { - Lck_Lock(&sc->mtx); - sc->stats->c_freed += (smf->size - size); - sc->stats->g_bytes -= (smf->size - size); - sc->stats->g_space += (smf->size - size); - trim_smf(smf, size); - assert(smf->size == size); - Lck_Unlock(&sc->mtx); - s->space = size; - } -} - -/*--------------------------------------------------------------------*/ - -static void __match_proto__(storage_free_f) -smf_free(struct storage *s) -{ - struct smf *smf; - struct smf_sc *sc; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - CAST_OBJ_NOTNULL(smf, s->priv, SMF_MAGIC); - sc = smf->sc; - Lck_Lock(&sc->mtx); - sc->stats->g_alloc--; - sc->stats->c_freed += smf->size; - sc->stats->g_bytes -= smf->size; - sc->stats->g_space += smf->size; - free_smf(smf); - Lck_Unlock(&sc->mtx); -} - -/*--------------------------------------------------------------------*/ - -const struct stevedore smf_stevedore = { - .magic = STEVEDORE_MAGIC, - .name = "file", - .init = smf_init, - .open = smf_open, - .alloc = smf_alloc, - .trim = smf_trim, - .free = smf_free, -}; - -#ifdef INCLUDE_TEST_DRIVER - -void vca_flush(struct sess *sp) {} - -#define N 100 -#define M (128*1024) - -struct storage *s[N]; - -static void -dumpit(void) -{ - struct smf_sc *sc = smf_stevedore.priv; - struct smf *s; - - return (0); - printf("----------------\n"); - printf("Order:\n"); - VTAILQ_FOREACH(s, &sc->order, order) { - printf("%10p %12ju %12ju %12ju\n", - s, s->offset, s->size, s->offset + s->size); - } - printf("Used:\n"); - VTAILQ_FOREACH(s, &sc->used, status) { - printf("%10p %12ju %12ju %12ju\n", - s, s->offset, s->size, s->offset + s->size); - } - printf("Free:\n"); - VTAILQ_FOREACH(s, &sc->free, status) { - printf("%10p %12ju %12ju %12ju\n", - s, s->offset, s->size, s->offset + s->size); - } - printf("================\n"); -} - -int -main(int argc, char **argv) -{ - int i, j; - - setbuf(stdout, NULL); - smf_init(&smf_stevedore, ""); - smf_open(&smf_stevedore); - while (1) { - dumpit(); - i = random() % N; - do - j = random() % M; - while (j == 0); - if (s[i] == NULL) { - s[i] = smf_alloc(&smf_stevedore, j); - printf("A %10p %12d\n", s[i], j); - } else if (j < s[i]->space) { - smf_trim(s[i], j); - printf("T %10p %12d\n", s[i], j); - } else { - smf_free(s[i]); - printf("D %10p\n", s[i]); - s[i] = NULL; - } - } -} - -#endif /* INCLUDE_TEST_DRIVER */ diff --git a/bin/varnishd/storage_malloc.c b/bin/varnishd/storage_malloc.c deleted file mode 100644 index 967137c..0000000 --- a/bin/varnishd/storage_malloc.c +++ /dev/null @@ -1,256 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Storage method based on malloc(3) - */ - -#include "config.h" - -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "vnum.h" - -struct sma_sc { - unsigned magic; -#define SMA_SC_MAGIC 0x1ac8a345 - struct lock sma_mtx; - size_t sma_max; - size_t sma_alloc; - struct VSC_C_sma *stats; -}; - -struct sma { - unsigned magic; -#define SMA_MAGIC 0x69ae9bb9 - struct storage s; - size_t sz; - struct sma_sc *sc; -}; - -static struct storage * -sma_alloc(struct stevedore *st, size_t size) -{ - struct sma_sc *sma_sc; - struct sma *sma = NULL; - void *p; - - CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); - Lck_Lock(&sma_sc->sma_mtx); - sma_sc->stats->c_req++; - if (sma_sc->sma_alloc + size > sma_sc->sma_max) { - sma_sc->stats->c_fail += size; - size = 0; - } else { - sma_sc->sma_alloc += size; - sma_sc->stats->c_bytes += size; - sma_sc->stats->g_alloc++; - sma_sc->stats->g_bytes += size; - if (sma_sc->sma_max != SIZE_MAX) - sma_sc->stats->g_space -= size; - } - Lck_Unlock(&sma_sc->sma_mtx); - - if (size == 0) - return (NULL); - - /* - * Do not collaps the sma allocation with sma->s.ptr: it is not - * a good idea. Not only would it make ->trim impossible, - * performance-wise it would be a catastropy with chunksized - * allocations growing another full page, just to accomodate the sma. - */ - - p = malloc(size); - if (p != NULL) { - ALLOC_OBJ(sma, SMA_MAGIC); - if (sma != NULL) - sma->s.ptr = p; - else - free(p); - } - if (sma == NULL) { - Lck_Lock(&sma_sc->sma_mtx); - /* - * XXX: Not nice to have counters go backwards, but we do - * XXX: Not want to pick up the lock twice just for stats. - */ - sma_sc->stats->c_fail++; - sma_sc->stats->c_bytes -= size; - sma_sc->stats->g_alloc--; - sma_sc->stats->g_bytes -= size; - if (sma_sc->sma_max != SIZE_MAX) - sma_sc->stats->g_space += size; - Lck_Unlock(&sma_sc->sma_mtx); - return (NULL); - } - sma->sc = sma_sc; - sma->sz = size; - sma->s.priv = sma; - sma->s.len = 0; - sma->s.space = size; -#ifdef SENDFILE_WORKS - sma->s.fd = -1; -#endif - sma->s.stevedore = st; - sma->s.magic = STORAGE_MAGIC; - return (&sma->s); -} - -static void __match_proto__(storage_free_f) -sma_free(struct storage *s) -{ - struct sma_sc *sma_sc; - struct sma *sma; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - CAST_OBJ_NOTNULL(sma, s->priv, SMA_MAGIC); - sma_sc = sma->sc; - assert(sma->sz == sma->s.space); - Lck_Lock(&sma_sc->sma_mtx); - sma_sc->sma_alloc -= sma->sz; - sma_sc->stats->g_alloc--; - sma_sc->stats->g_bytes -= sma->sz; - sma_sc->stats->c_freed += sma->sz; - if (sma_sc->sma_max != SIZE_MAX) - sma_sc->stats->g_space += sma->sz; - Lck_Unlock(&sma_sc->sma_mtx); - free(sma->s.ptr); - free(sma); -} - -static void -sma_trim(struct storage *s, size_t size) -{ - struct sma_sc *sma_sc; - struct sma *sma; - void *p; - size_t delta; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - CAST_OBJ_NOTNULL(sma, s->priv, SMA_MAGIC); - sma_sc = sma->sc; - - assert(sma->sz == sma->s.space); - assert(size < sma->sz); - delta = sma->sz - size; - if (delta < 256) - return; - if ((p = realloc(sma->s.ptr, size)) != NULL) { - Lck_Lock(&sma_sc->sma_mtx); - sma_sc->sma_alloc -= delta; - sma_sc->stats->g_bytes -= delta; - sma_sc->stats->c_freed += delta; - if (sma_sc->sma_max != SIZE_MAX) - sma_sc->stats->g_space += delta; - sma->sz = size; - Lck_Unlock(&sma_sc->sma_mtx); - sma->s.ptr = p; - s->space = size; - } -} - -static double -sma_used_space(const struct stevedore *st) -{ - struct sma_sc *sma_sc; - - CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); - return (sma_sc->sma_alloc); -} - -static double -sma_free_space(const struct stevedore *st) -{ - struct sma_sc *sma_sc; - - CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); - return (sma_sc->sma_max - sma_sc->sma_alloc); -} - -static void -sma_init(struct stevedore *parent, int ac, char * const *av) -{ - const char *e; - uintmax_t u; - struct sma_sc *sc; - - ASSERT_MGT(); - ALLOC_OBJ(sc, SMA_SC_MAGIC); - AN(sc); - sc->sma_max = SIZE_MAX; - assert(sc->sma_max == SIZE_MAX); - parent->priv = sc; - - AZ(av[ac]); - if (ac > 1) - ARGV_ERR("(-smalloc) too many arguments\n"); - - if (ac == 0 || *av[0] == '\0') - return; - - e = VNUM_2bytes(av[0], &u, 0); - if (e != NULL) - ARGV_ERR("(-smalloc) size \"%s\": %s\n", av[0], e); - if ((u != (uintmax_t)(size_t)u)) - ARGV_ERR("(-smalloc) size \"%s\": too big\n", av[0]); - if (u < 1024*1024) - ARGV_ERR("(-smalloc) size \"%s\": too small, " - "did you forget to specify M or G?\n", av[0]); - - sc->sma_max = u; -} - -static void -sma_open(const struct stevedore *st) -{ - struct sma_sc *sma_sc; - - CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC); - Lck_New(&sma_sc->sma_mtx, lck_sma); - sma_sc->stats = VSM_Alloc(sizeof *sma_sc->stats, - VSC_CLASS, VSC_TYPE_SMA, st->ident); - memset(sma_sc->stats, 0, sizeof *sma_sc->stats); - if (sma_sc->sma_max != SIZE_MAX) - sma_sc->stats->g_space = sma_sc->sma_max; -} - -const struct stevedore sma_stevedore = { - .magic = STEVEDORE_MAGIC, - .name = "malloc", - .init = sma_init, - .open = sma_open, - .alloc = sma_alloc, - .free = sma_free, - .trim = sma_trim, - .var_free_space = sma_free_space, - .var_used_space = sma_used_space, -}; diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c deleted file mode 100644 index abe25f6..0000000 --- a/bin/varnishd/storage_persistent.c +++ /dev/null @@ -1,678 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Persistent storage method - * - * XXX: Before we start the client or maybe after it stops, we should give the - * XXX: stevedores a chance to examine their storage for consistency. - * - * XXX: Do we ever free the LRU-lists ? - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "hash_slinger.h" -#include "vcli.h" -#include "vcli_priv.h" -#include "vend.h" -#include "vsha256.h" - -#include "persistent.h" -#include "storage_persistent.h" - -/*--------------------------------------------------------------------*/ - -/* - * silos is unlocked, it only changes during startup when we are - * single-threaded - */ -static VTAILQ_HEAD(,smp_sc) silos = VTAILQ_HEAD_INITIALIZER(silos); - -/*-------------------------------------------------------------------- - * Add bans to silos - */ - -static void -smp_appendban(struct smp_sc *sc, struct smp_signctx *ctx, - uint32_t len, const uint8_t *ban) -{ - uint8_t *ptr, *ptr2; - - (void)sc; - ptr = ptr2 = SIGN_END(ctx); - - memcpy(ptr, "BAN", 4); - ptr += 4; - - vbe32enc(ptr, len); - ptr += 4; - - memcpy(ptr, ban, len); - ptr += len; - - smp_append_sign(ctx, ptr2, ptr - ptr2); -} - -/* Trust that cache_ban.c takes care of locking */ - -void -SMP_NewBan(const uint8_t *ban, unsigned ln) -{ - struct smp_sc *sc; - - VTAILQ_FOREACH(sc, &silos, list) { - smp_appendban(sc, &sc->ban1, ln, ban); - smp_appendban(sc, &sc->ban2, ln, ban); - } -} - -/*-------------------------------------------------------------------- - * Attempt to open and read in a ban list - */ - -static int -smp_open_bans(struct smp_sc *sc, struct smp_signctx *ctx) -{ - uint8_t *ptr, *pe; - uint32_t length; - int i, retval = 0; - - ASSERT_CLI(); - (void)sc; - i = smp_chk_sign(ctx); - if (i) - return (i); - ptr = SIGN_DATA(ctx); - pe = ptr + ctx->ss->length; - - while (ptr < pe) { - if (memcmp(ptr, "BAN", 4)) { - retval = 1001; - break; - } - ptr += 4; - - length = vbe32dec(ptr); - ptr += 4; - - if (ptr + length > pe) { - retval = 1003; - break; - } - - BAN_Reload(ptr, length); - - ptr += length; - } - assert(ptr <= pe); - return (retval); -} - -/*-------------------------------------------------------------------- - * Attempt to open and read in a segment list - */ - -static int -smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx) -{ - uint64_t length, l; - struct smp_segptr *ss, *se; - struct smp_seg *sg, *sg1, *sg2; - int i, n = 0; - - ASSERT_CLI(); - i = smp_chk_sign(ctx); - if (i) - return (i); - - ss = SIGN_DATA(ctx); - length = ctx->ss->length; - - if (length == 0) { - /* No segments */ - sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; - return (0); - } - se = ss + length / sizeof *ss; - se--; - assert(ss <= se); - - /* - * Locate the free reserve, there are only two basic cases, - * but once we start dropping segments, things gets more complicated. - */ - - sc->free_offset = se->offset + se->length; - l = sc->mediasize - sc->free_offset; - if (se->offset > ss->offset && l >= sc->free_reserve) { - /* - * [__xxxxyyyyzzzz___] - * Plenty of space at tail, do nothing. - */ - } else if (ss->offset > se->offset) { - /* - * [zzzz____xxxxyyyy_] - * (make) space between ends - * We might nuke the entire tail end without getting - * enough space, in which case we fall through to the - * last check. - */ - while (ss < se && ss->offset > se->offset) { - l = ss->offset - (se->offset + se->length); - if (l > sc->free_reserve) - break; - ss++; - n++; - } - } - - if (l < sc->free_reserve) { - /* - * [__xxxxyyyyzzzz___] - * (make) space at front - */ - sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; - while (ss < se) { - l = ss->offset - sc->free_offset; - if (l > sc->free_reserve) - break; - ss++; - n++; - } - } - - assert (l >= sc->free_reserve); - - - sg1 = NULL; - sg2 = NULL; - for(; ss <= se; ss++) { - ALLOC_OBJ(sg, SMP_SEG_MAGIC); - AN(sg); - sg->lru = LRU_Alloc(); - CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); - sg->p = *ss; - - sg->flags |= SMP_SEG_MUSTLOAD; - - /* - * HACK: prevent save_segs from nuking segment until we have - * HACK: loaded it. - */ - sg->nobj = 1; - if (sg1 != NULL) { - assert(sg1->p.offset != sg->p.offset); - if (sg1->p.offset < sg->p.offset) - assert(smp_segend(sg1) <= sg->p.offset); - else - assert(smp_segend(sg) <= sg1->p.offset); - } - if (sg2 != NULL) { - assert(sg2->p.offset != sg->p.offset); - if (sg2->p.offset < sg->p.offset) - assert(smp_segend(sg2) <= sg->p.offset); - else - assert(smp_segend(sg) <= sg2->p.offset); - } - - /* XXX: check that they are inside silo */ - /* XXX: check that they don't overlap */ - /* XXX: check that they are serial */ - sg->sc = sc; - VTAILQ_INSERT_TAIL(&sc->segments, sg, list); - sg2 = sg; - if (sg1 == NULL) - sg1 = sg; - } - printf("Dropped %d segments to make free_reserve\n", n); - return (0); -} - -/*-------------------------------------------------------------------- - * Silo worker thread - */ - -static void * -smp_thread(struct sess *sp, void *priv) -{ - struct smp_sc *sc; - struct smp_seg *sg; - - (void)sp; - CAST_OBJ_NOTNULL(sc, priv, SMP_SC_MAGIC); - - /* First, load all the objects from all segments */ - VTAILQ_FOREACH(sg, &sc->segments, list) - if (sg->flags & SMP_SEG_MUSTLOAD) - smp_load_seg(sp, sc, sg); - - sc->flags |= SMP_SC_LOADED; - BAN_TailDeref(&sc->tailban); - AZ(sc->tailban); - printf("Silo completely loaded\n"); - while (1) { - (void)sleep (1); - sg = VTAILQ_FIRST(&sc->segments); - if (sg != NULL && sg -> sc->cur_seg && - sg->nobj == 0) { - Lck_Lock(&sc->mtx); - smp_save_segs(sc); - Lck_Unlock(&sc->mtx); - } - } - NEEDLESS_RETURN(NULL); -} - -/*-------------------------------------------------------------------- - * Open a silo in the worker process - */ - -static void -smp_open(const struct stevedore *st) -{ - struct smp_sc *sc; - - ASSERT_CLI(); - - CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); - - Lck_New(&sc->mtx, lck_smp); - Lck_Lock(&sc->mtx); - - sc->stevedore = st; - - /* We trust the parent to give us a valid silo, for good measure: */ - AZ(smp_valid_silo(sc)); - - AZ(mprotect(sc->base, 4096, PROT_READ)); - - sc->ident = SIGN_DATA(&sc->idn); - - /* We attempt ban1 first, and if that fails, try ban2 */ - if (smp_open_bans(sc, &sc->ban1)) - AZ(smp_open_bans(sc, &sc->ban2)); - - /* We attempt seg1 first, and if that fails, try seg2 */ - if (smp_open_segs(sc, &sc->seg1)) - AZ(smp_open_segs(sc, &sc->seg2)); - - /* - * Grap a reference to the tail of the ban list, until the thread - * has loaded all objects, so we can be sure that all of our - * proto-bans survive until then. - */ - sc->tailban = BAN_TailRef(); - AN(sc->tailban); - - /* XXX: save segments to ensure consistency between seg1 & seg2 ? */ - - /* XXX: abandon early segments to make sure we have free space ? */ - - /* Open a new segment, so we are ready to write */ - smp_new_seg(sc); - - /* Start the worker silo worker thread, it will load the objects */ - WRK_BgThread(&sc->thread, "persistence", smp_thread, sc); - - VTAILQ_INSERT_TAIL(&silos, sc, list); - Lck_Unlock(&sc->mtx); -} - -/*-------------------------------------------------------------------- - * Close a silo - */ - -static void -smp_close(const struct stevedore *st) -{ - struct smp_sc *sc; - - ASSERT_CLI(); - - CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); - Lck_Lock(&sc->mtx); - smp_close_seg(sc, sc->cur_seg); - Lck_Unlock(&sc->mtx); - - /* XXX: reap thread */ -} - -/*-------------------------------------------------------------------- - * Allocate a bite. - * - * Allocate [min_size...max_size] space from the bottom of the segment, - * as is convenient. - * - * If 'so' + 'idx' is given, also allocate a smp_object from the top - * of the segment. - * - * Return the segment in 'ssg' if given. - */ - -static struct storage * -smp_allocx(struct stevedore *st, size_t min_size, size_t max_size, - struct smp_object **so, unsigned *idx, struct smp_seg **ssg) -{ - struct smp_sc *sc; - struct storage *ss; - struct smp_seg *sg; - unsigned tries; - uint64_t left, extra; - - CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); - assert(min_size <= max_size); - - max_size = IRNUP(sc, max_size); - min_size = IRNUP(sc, min_size); - - extra = IRNUP(sc, sizeof(*ss)); - if (so != NULL) { - extra += sizeof(**so); - AN(idx); - } - - Lck_Lock(&sc->mtx); - sg = NULL; - ss = NULL; - for (tries = 0; tries < 3; tries++) { - left = smp_spaceleft(sc, sc->cur_seg); - if (left >= extra + min_size) - break; - smp_close_seg(sc, sc->cur_seg); - smp_new_seg(sc); - } - if (left >= extra + min_size) { - if (left < extra + max_size) - max_size = IRNDN(sc, left - extra); - - sg = sc->cur_seg; - ss = (void*)(sc->base + sc->next_bot); - sc->next_bot += max_size + IRNUP(sc, sizeof(*ss)); - sg->nalloc++; - if (so != NULL) { - sc->next_top -= sizeof(**so); - *so = (void*)(sc->base + sc->next_top); - /* Render this smp_object mostly harmless */ - (*so)->ttl = 0.; - (*so)->ban = 0.; - (*so)->ptr = 0;; - sg->objs = *so; - *idx = ++sg->p.lobjlist; - } - (void)smp_spaceleft(sc, sg); /* for the assert */ - } - Lck_Unlock(&sc->mtx); - - if (ss == NULL) - return (ss); - AN(sg); - assert(max_size >= min_size); - - /* Fill the storage structure */ - memset(ss, 0, sizeof *ss); - ss->magic = STORAGE_MAGIC; - ss->ptr = PRNUP(sc, ss + 1); - ss->space = max_size; - ss->priv = sc; - ss->stevedore = st; -#ifdef SENDFILE_WORKS - ss->fd = sc->fd; -#endif - if (ssg != NULL) - *ssg = sg; - return (ss); -} - -/*-------------------------------------------------------------------- - * Allocate an object - */ - -static struct object * -smp_allocobj(struct stevedore *stv, struct sess *sp, unsigned ltot, - const struct stv_objsecrets *soc) -{ - struct object *o; - struct storage *st; - struct smp_sc *sc; - struct smp_seg *sg; - struct smp_object *so; - struct objcore *oc; - unsigned objidx; - - if (sp->objcore == NULL) - return (NULL); /* from cnt_error */ - CAST_OBJ_NOTNULL(sc, stv->priv, SMP_SC_MAGIC); - AN(sp->objcore); - AN(sp->wrk->exp.ttl > 0.); - - ltot = IRNUP(sc, ltot); - - st = smp_allocx(stv, ltot, ltot, &so, &objidx, &sg); - if (st == NULL) - return (NULL); - - assert(st->space >= ltot); - ltot = st->len = st->space; - - o = STV_MkObject(sp, st->ptr, ltot, soc); - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - o->objstore = st; - - oc = o->objcore; - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - oc->flags |= OC_F_LRUDONTMOVE; - - Lck_Lock(&sc->mtx); - sg->nfixed++; - sg->nobj++; - - /* We have to do this somewhere, might as well be here... */ - assert(sizeof so->hash == DIGEST_LEN); - memcpy(so->hash, oc->objhead->digest, DIGEST_LEN); - so->ttl = EXP_Grace(NULL, o); - so->ptr = (uint8_t*)o - sc->base; - so->ban = BAN_Time(oc->ban); - - smp_init_oc(oc, sg, objidx); - - Lck_Unlock(&sc->mtx); - return (o); -} - -/*-------------------------------------------------------------------- - * Allocate a bite - */ - -static struct storage * -smp_alloc(struct stevedore *st, size_t size) -{ - - return (smp_allocx(st, - size > 4096 ? 4096 : size, size, NULL, NULL, NULL)); -} - -/*-------------------------------------------------------------------- - * Trim a bite - * XXX: We could trim the last allocation. - */ - -static void -smp_trim(struct storage *ss, size_t size) -{ - - (void)ss; - (void)size; -} - -/*-------------------------------------------------------------------- - * We don't track frees of storage, we track the objects which own the - * storage and when there are no more objects in in the first segment, - * it can be reclaimed. - * XXX: We could free the last allocation, but does that happen ? - */ - -static void __match_proto__(storage_free_f) -smp_free(struct storage *st) -{ - - /* XXX */ - (void)st; -} - - -/*--------------------------------------------------------------------*/ - -const struct stevedore smp_stevedore = { - .magic = STEVEDORE_MAGIC, - .name = "persistent", - .init = smp_mgt_init, - .open = smp_open, - .close = smp_close, - .alloc = smp_alloc, - .allocobj = smp_allocobj, - .free = smp_free, - .trim = smp_trim, -}; - -/*-------------------------------------------------------------------- - * Persistence is a bear to test unadultered, so we cheat by adding - * a cli command we can use to make it do tricks for us. - */ - -static void -debug_report_silo(struct cli *cli, const struct smp_sc *sc, int objs) -{ - struct smp_seg *sg; - struct objcore *oc; - - VCLI_Out(cli, "Silo: %s (%s)\n", - sc->stevedore->ident, sc->filename); - VTAILQ_FOREACH(sg, &sc->segments, list) { - VCLI_Out(cli, " Seg: [0x%jx ... +0x%jx]\n", - (uintmax_t)sg->p.offset, (uintmax_t)sg->p.length); - if (sg == sc->cur_seg) - VCLI_Out(cli, - " Alloc: [0x%jx ... 0x%jx] = 0x%jx free\n", - (uintmax_t)(sc->next_bot), - (uintmax_t)(sc->next_top), - (uintmax_t)(sc->next_top - sc->next_bot)); - VCLI_Out(cli, " %u nobj, %u alloc, %u lobjlist, %u fixed\n", - sg->nobj, sg->nalloc, sg->p.lobjlist, sg->nfixed); - if (objs) { - VTAILQ_FOREACH(oc, &sg->lru->lru_head, lru_list) - VCLI_Out(cli, " OC %p\n", oc); - } - } -} - -static void -debug_persistent(struct cli *cli, const char * const * av, void *priv) -{ - struct smp_sc *sc; - - (void)priv; - - if (av[2] == NULL) { - VTAILQ_FOREACH(sc, &silos, list) - debug_report_silo(cli, sc, 0); - return; - } - VTAILQ_FOREACH(sc, &silos, list) - if (!strcmp(av[2], sc->stevedore->ident)) - break; - if (sc == NULL) { - VCLI_Out(cli, "Silo <%s> not found\n", av[2]); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - if (av[3] == NULL) { - debug_report_silo(cli, sc, 0); - return; - } - Lck_Lock(&sc->mtx); - if (!strcmp(av[3], "sync")) { - smp_close_seg(sc, sc->cur_seg); - smp_new_seg(sc); - } else if (!strcmp(av[3], "dump")) { - debug_report_silo(cli, sc, 1); - } else { - VCLI_Out(cli, "Unknown operation\n"); - VCLI_SetResult(cli, CLIS_PARAM); - } - Lck_Unlock(&sc->mtx); -} - -static struct cli_proto debug_cmds[] = { - { "debug.persistent", "debug.persistent", - "Persistent debugging magic:\n" - "\tdebug.persistent [stevedore [cmd]]\n" - "With no cmd arg, a summary of the silo is returned.\n" - "Possible commands:\n" - "\tsync\tClose current segment, open a new one\n" - "\tdump\tinclude objcores in silo summary\n" - "", - 0, 2, "d", debug_persistent }, - { NULL } -}; - -/*--------------------------------------------------------------------*/ - -void -SMP_Init(void) -{ - CLI_AddFuncs(debug_cmds); -} - -/*-------------------------------------------------------------------- - * Pause until all silos have loaded. - */ - -void -SMP_Ready(void) -{ - struct smp_sc *sc; - - ASSERT_CLI(); - do { - VTAILQ_FOREACH(sc, &silos, list) - if (!(sc->flags & SMP_SC_LOADED)) - break; - if (sc != NULL) - (void)sleep(1); - } while (sc != NULL); -} diff --git a/bin/varnishd/storage_persistent.h b/bin/varnishd/storage_persistent.h deleted file mode 100644 index 84f3d21..0000000 --- a/bin/varnishd/storage_persistent.h +++ /dev/null @@ -1,219 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Persistent storage method - * - * XXX: Before we start the client or maybe after it stops, we should give the - * XXX: stevedores a chance to examine their storage for consistency. - * - * XXX: Do we ever free the LRU-lists ? - */ - -#define ASSERT_SILO_THREAD(sc) \ - do {assert(pthread_self() == (sc)->thread);} while (0) - -#define OC_F_NEEDFIXUP OC_F_PRIV - -/* - * Context for a signature. - * - * A signature is a sequence of bytes in the silo, signed by a SHA256 hash - * which follows the bytes. - * - * The context structure allows us to append to a signature without - * recalculating the entire SHA256 hash. - */ - -struct smp_signctx { - struct smp_sign *ss; - struct SHA256Context ctx; - uint32_t unique; - const char *id; -}; - -struct smp_sc; - -/* XXX: name confusion with on-media version ? */ -struct smp_seg { - unsigned magic; -#define SMP_SEG_MAGIC 0x45c61895 - - struct smp_sc *sc; - struct lru *lru; - - VTAILQ_ENTRY(smp_seg) list; /* on smp_sc.smp_segments */ - - struct smp_segptr p; - - unsigned flags; -#define SMP_SEG_MUSTLOAD (1 << 0) -#define SMP_SEG_LOADED (1 << 1) - - uint32_t nobj; /* Number of objects */ - uint32_t nalloc; /* Allocations */ - uint32_t nfixed; /* How many fixed objects */ - - /* Only for open segment */ - struct smp_object *objs; /* objdesc array */ - struct smp_signctx ctx[1]; -}; - -VTAILQ_HEAD(smp_seghead, smp_seg); - -struct smp_sc { - unsigned magic; -#define SMP_SC_MAGIC 0x7b73af0a - struct stevedore *parent; - - unsigned flags; -#define SMP_SC_LOADED (1 << 0) - - const struct stevedore *stevedore; - int fd; - const char *filename; - off_t mediasize; - uintptr_t align; - uint32_t granularity; - uint32_t unique; - - uint8_t *base; - - struct smp_ident *ident; - - struct smp_seghead segments; - struct smp_seg *cur_seg; - uint64_t next_bot; /* next alloc address bottom */ - uint64_t next_top; /* next alloc address top */ - - uint64_t free_offset; - - pthread_t thread; - - VTAILQ_ENTRY(smp_sc) list; - - struct smp_signctx idn; - struct smp_signctx ban1; - struct smp_signctx ban2; - struct smp_signctx seg1; - struct smp_signctx seg2; - - struct ban *tailban; - - struct lock mtx; - - /* Cleaner metrics */ - - unsigned min_nseg; - unsigned aim_nseg; - unsigned max_nseg; - - uint64_t min_segl; - uint64_t aim_segl; - uint64_t max_segl; - - uint64_t free_reserve; -}; - -/*--------------------------------------------------------------------*/ - -/* Pointer round up/down & assert */ -#define PRNDN(sc, x) ((void*)RDN2((uintptr_t)(x), sc->align)) -#define PRNUP(sc, x) ((void*)RUP2((uintptr_t)(x), sc->align)) -#define PASSERTALIGN(sc, x) assert(PRNDN(sc, x) == (x)) - -/* Integer round up/down & assert */ -#define IRNDN(sc, x) RDN2(x, sc->align) -#define IRNUP(sc, x) RUP2(x, sc->align) -#define IASSERTALIGN(sc, x) assert(IRNDN(sc, x) == (x)) - -/*--------------------------------------------------------------------*/ - -#define ASSERT_PTR_IN_SILO(sc, ptr) \ - assert((const void*)(ptr) >= (const void*)((sc)->base) && \ - (const void*)(ptr) < (const void *)((sc)->base + (sc)->mediasize)) - -/*--------------------------------------------------------------------*/ - -#define SIGN_DATA(ctx) ((void *)((ctx)->ss + 1)) -#define SIGN_END(ctx) ((void *)((int8_t *)SIGN_DATA(ctx) + (ctx)->ss->length)) - -/* storage_persistent_mgt.c */ - -void smp_mgt_init(struct stevedore *parent, int ac, char * const *av); - -/* storage_persistent_silo.c */ - -void smp_load_seg(const struct sess *sp, const struct smp_sc *sc, - struct smp_seg *sg); -void smp_new_seg(struct smp_sc *sc); -void smp_close_seg(struct smp_sc *sc, struct smp_seg *sg); -void smp_init_oc(struct objcore *oc, struct smp_seg *sg, unsigned objidx); -void smp_save_segs(struct smp_sc *sc); - -/* storage_persistent_subr.c */ - -void smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx, - uint64_t off, const char *id); -int smp_chk_sign(struct smp_signctx *ctx); -void smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len); -void smp_reset_sign(struct smp_signctx *ctx); -void smp_sync_sign(const struct smp_signctx *ctx); -void smp_newsilo(struct smp_sc *sc); -int smp_valid_silo(struct smp_sc *sc); - -/*-------------------------------------------------------------------- - * Caculate payload of some stuff - */ - -static inline uint64_t -smp_stuff_len(const struct smp_sc *sc, unsigned stuff) -{ - uint64_t l; - - assert(stuff < SMP_END_STUFF); - l = sc->ident->stuff[stuff + 1] - sc->ident->stuff[stuff]; - l -= SMP_SIGN_SPACE; - return (l); -} - -static inline uint64_t -smp_segend(const struct smp_seg *sg) -{ - - return (sg->p.offset + sg->p.length); -} - -static inline uint64_t -smp_spaceleft(const struct smp_sc *sc, const struct smp_seg *sg) -{ - - IASSERTALIGN(sc, sc->next_bot); - assert(sc->next_bot <= sc->next_top - IRNUP(sc, SMP_SIGN_SPACE)); - assert(sc->next_bot >= sg->p.offset); - assert(sc->next_top < sg->p.offset + sg->p.length); - return ((sc->next_top - sc->next_bot) - IRNUP(sc, SMP_SIGN_SPACE)); -} diff --git a/bin/varnishd/storage_persistent_mgt.c b/bin/varnishd/storage_persistent_mgt.c deleted file mode 100644 index 2cdcc6b..0000000 --- a/bin/varnishd/storage_persistent_mgt.c +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Persistent storage method - * - * XXX: Before we start the client or maybe after it stops, we should give the - * XXX: stevedores a chance to examine their storage for consistency. - * - * XXX: Do we ever free the LRU-lists ? - */ - -#include "config.h" - -#include - -#include -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "vsha256.h" - -#include "persistent.h" -#include "storage_persistent.h" - -#ifndef MAP_NOCORE -#define MAP_NOCORE 0 /* XXX Linux */ -#endif - -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 /* XXX Linux */ -#endif - -/*-------------------------------------------------------------------- - * Calculate cleaner metrics from silo dimensions - */ - -static void -smp_metrics(struct smp_sc *sc) -{ - - /* - * We do not want to loose too big chunks of the silos - * content when we are forced to clean a segment. - * - * For now insist that a segment covers no more than 1% of the silo. - * - * XXX: This should possibly depend on the size of the silo so - * XXX: trivially small silos do not run into trouble along - * XXX: the lines of "one object per segment". - */ - - sc->min_nseg = 10; - sc->max_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->min_nseg; - - fprintf(stderr, "min_nseg = %u, max_segl = %ju\n", - sc->min_nseg, (uintmax_t)sc->max_segl); - - /* - * The number of segments are limited by the size of the segment - * table(s) and from that follows the minimum size of a segmement. - */ - - sc->max_nseg = smp_stuff_len(sc, SMP_SEG1_STUFF) / sc->min_nseg; - sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; - - while (sc->min_segl < sizeof(struct object)) { - sc->max_nseg /= 2; - sc->min_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->max_nseg; - } - - fprintf(stderr, "max_nseg = %u, min_segl = %ju\n", - sc->max_nseg, (uintmax_t)sc->min_segl); - - /* - * Set our initial aim point at the exponential average of the - * two extremes. - * - * XXX: This is a pretty arbitrary choice, but having no idea - * XXX: object count, size distribution or ttl pattern at this - * XXX: point, we have to do something. - */ - - sc->aim_nseg = - (unsigned) exp((log(sc->min_nseg) + log(sc->max_nseg))*.5); - sc->aim_segl = smp_stuff_len(sc, SMP_SPC_STUFF) / sc->aim_nseg; - - fprintf(stderr, "aim_nseg = %u, aim_segl = %ju\n", - sc->aim_nseg, (uintmax_t)sc->aim_segl); - - /* - * How much space in the free reserve pool ? - */ - sc->free_reserve = sc->aim_segl * 10; - - fprintf(stderr, "free_reserve = %ju\n", (uintmax_t)sc->free_reserve); -} - -/*-------------------------------------------------------------------- - * Set up persistent storage silo in the master process. - */ - -void -smp_mgt_init(struct stevedore *parent, int ac, char * const *av) -{ - struct smp_sc *sc; - struct smp_sign sgn; - void *target; - int i; - - ASSERT_MGT(); - - AZ(av[ac]); -#define SIZOF(foo) fprintf(stderr, \ - "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo)); - SIZOF(struct smp_ident); - SIZOF(struct smp_sign); - SIZOF(struct smp_segptr); - SIZOF(struct smp_object); -#undef SIZOF - - /* See comments in persistent.h */ - assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE); - - /* Allocate softc */ - ALLOC_OBJ(sc, SMP_SC_MAGIC); - XXXAN(sc); - sc->parent = parent; - sc->fd = -1; - VTAILQ_INIT(&sc->segments); - - /* Argument processing */ - if (ac != 2) - ARGV_ERR("(-spersistent) wrong number of arguments\n"); - - i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent"); - if (i == 2) - ARGV_ERR("(-spersistent) need filename (not directory)\n"); - - sc->align = sizeof(void*) * 2; - sc->granularity = getpagesize(); - sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity, - "-spersistent"); - - AZ(ftruncate(sc->fd, sc->mediasize)); - - /* Try to determine correct mmap address */ - i = read(sc->fd, &sgn, sizeof sgn); - assert(i == sizeof sgn); - if (!strcmp(sgn.ident, "SILO")) - target = (void*)(uintptr_t)sgn.mapped; - else - target = NULL; - - sc->base = mmap(target, sc->mediasize, PROT_READ|PROT_WRITE, - MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0); - - if (sc->base == MAP_FAILED) - ARGV_ERR("(-spersistent) failed to mmap (%s)\n", - strerror(errno)); - - smp_def_sign(sc, &sc->idn, 0, "SILO"); - sc->ident = SIGN_DATA(&sc->idn); - - i = smp_valid_silo(sc); - if (i) { - printf("Warning SILO (%s) not reloaded (reason=%d)\n", - sc->filename, i); - smp_newsilo(sc); - } - AZ(smp_valid_silo(sc)); - - smp_metrics(sc); - - parent->priv = sc; - - /* XXX: only for sendfile I guess... */ - mgt_child_inherit(sc->fd, "storage_persistent"); -} diff --git a/bin/varnishd/storage_persistent_silo.c b/bin/varnishd/storage_persistent_silo.c deleted file mode 100644 index 8209613..0000000 --- a/bin/varnishd/storage_persistent_silo.c +++ /dev/null @@ -1,524 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Persistent storage method - * - * XXX: Before we start the client or maybe after it stops, we should give the - * XXX: stevedores a chance to examine their storage for consistency. - * - */ - -#include "config.h" - -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "hash_slinger.h" -#include "vsha256.h" -#include "vtim.h" - -#include "persistent.h" -#include "storage_persistent.h" - -/*-------------------------------------------------------------------- - * Write the segmentlist back to the silo. - * - * We write the first copy, sync it synchronously, then write the - * second copy and sync it synchronously. - * - * Provided the kernel doesn't lie, that means we will always have - * at least one valid copy on in the silo. - */ - -static void -smp_save_seg(const struct smp_sc *sc, struct smp_signctx *ctx) -{ - struct smp_segptr *ss; - struct smp_seg *sg; - uint64_t length; - - Lck_AssertHeld(&sc->mtx); - smp_reset_sign(ctx); - ss = SIGN_DATA(ctx); - length = 0; - VTAILQ_FOREACH(sg, &sc->segments, list) { - assert(sg->p.offset < sc->mediasize); - assert(sg->p.offset + sg->p.length <= sc->mediasize); - *ss = sg->p; - ss++; - length += sizeof *ss; - } - smp_append_sign(ctx, SIGN_DATA(ctx), length); - smp_sync_sign(ctx); -} - -void -smp_save_segs(struct smp_sc *sc) -{ - struct smp_seg *sg, *sg2; - - Lck_AssertHeld(&sc->mtx); - - /* - * Remove empty segments from the front of the list - * before we write the segments to disk. - */ - VTAILQ_FOREACH_SAFE(sg, &sc->segments, list, sg2) { - if (sg->nobj > 0) - break; - if (sg == sc->cur_seg) - continue; - VTAILQ_REMOVE(&sc->segments, sg, list); - LRU_Free(sg->lru); - FREE_OBJ(sg); - } - smp_save_seg(sc, &sc->seg1); - smp_save_seg(sc, &sc->seg2); -} - -/*-------------------------------------------------------------------- - * Load segments - * - * The overall objective is to register the existence of an object, based - * only on the minimally sized struct smp_object, without causing the - * main object to be faulted in. - * - * XXX: We can test this by mprotecting the main body of the segment - * XXX: until the first fixup happens, or even just over this loop, - * XXX: However: the requires that the smp_objects starter further - * XXX: into the segment than a page so that they do not get hit - * XXX: by the protection. - */ - -void -smp_load_seg(const struct sess *sp, const struct smp_sc *sc, - struct smp_seg *sg) -{ - struct smp_object *so; - struct objcore *oc; - uint32_t no; - double t_now = VTIM_real(); - struct smp_signctx ctx[1]; - - ASSERT_SILO_THREAD(sc); - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC); - CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); - assert(sg->flags & SMP_SEG_MUSTLOAD); - sg->flags &= ~SMP_SEG_MUSTLOAD; - AN(sg->p.offset); - if (sg->p.objlist == 0) - return; - smp_def_sign(sc, ctx, sg->p.offset, "SEGHEAD"); - if (smp_chk_sign(ctx)) - return; - - /* test SEGTAIL */ - /* test OBJIDX */ - so = (void*)(sc->base + sg->p.objlist); - sg->objs = so; - no = sg->p.lobjlist; - /* Clear the bogus "hold" count */ - sg->nobj = 0; - for (;no > 0; so++,no--) { - if (so->ttl == 0 || so->ttl < t_now) - continue; - HSH_Prealloc(sp); - oc = sp->wrk->nobjcore; - oc->flags |= OC_F_NEEDFIXUP | OC_F_LRUDONTMOVE; - oc->flags &= ~OC_F_BUSY; - smp_init_oc(oc, sg, no); - oc->ban = BAN_RefBan(oc, so->ban, sc->tailban); - memcpy(sp->wrk->nobjhead->digest, so->hash, SHA256_LEN); - (void)HSH_Insert(sp); - AZ(sp->wrk->nobjcore); - EXP_Inject(oc, sg->lru, so->ttl); - sg->nobj++; - } - WRK_SumStat(sp->wrk); - sg->flags |= SMP_SEG_LOADED; -} - -/*-------------------------------------------------------------------- - * Create a new segment - */ - -void -smp_new_seg(struct smp_sc *sc) -{ - struct smp_seg *sg, *sg2; - - Lck_AssertHeld(&sc->mtx); - ALLOC_OBJ(sg, SMP_SEG_MAGIC); - AN(sg); - sg->sc = sc; - sg->lru = LRU_Alloc(); - CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); - - /* XXX: find where it goes in silo */ - - sg->p.offset = sc->free_offset; - // XXX: align */ - assert(sg->p.offset >= sc->ident->stuff[SMP_SPC_STUFF]); - assert(sg->p.offset < sc->mediasize); - - sg->p.length = sc->aim_segl; - sg->p.length &= ~7; - - if (smp_segend(sg) > sc->mediasize) { - sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; - sg->p.offset = sc->free_offset; - sg2 = VTAILQ_FIRST(&sc->segments); - if (smp_segend(sg) > sg2->p.offset) { - printf("Out of space in persistent silo\n"); - printf("Committing suicide, restart will make space\n"); - exit (0); - } - } - - - assert(smp_segend(sg) <= sc->mediasize); - - sg2 = VTAILQ_FIRST(&sc->segments); - if (sg2 != NULL && sg2->p.offset > sc->free_offset) { - if (smp_segend(sg) > sg2->p.offset) { - printf("Out of space in persistent silo\n"); - printf("Committing suicide, restart will make space\n"); - exit (0); - } - assert(smp_segend(sg) <= sg2->p.offset); - } - - sg->p.offset = IRNUP(sc, sg->p.offset); - sg->p.length = IRNDN(sc, sg->p.length); - sc->free_offset = sg->p.offset + sg->p.length; - - VTAILQ_INSERT_TAIL(&sc->segments, sg, list); - - /* Neuter the new segment in case there is an old one there */ - AN(sg->p.offset); - smp_def_sign(sc, sg->ctx, sg->p.offset, "SEGHEAD"); - smp_reset_sign(sg->ctx); - smp_sync_sign(sg->ctx); - - /* Set up our allocation points */ - sc->cur_seg = sg; - sc->next_bot = sg->p.offset + IRNUP(sc, SMP_SIGN_SPACE); - sc->next_top = smp_segend(sg); - sc->next_top -= IRNUP(sc, SMP_SIGN_SPACE); - IASSERTALIGN(sc, sc->next_bot); - IASSERTALIGN(sc, sc->next_top); - sg->objs = (void*)(sc->base + sc->next_top); -} - -/*-------------------------------------------------------------------- - * Close a segment - */ - -void -smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) -{ - uint64_t left, dst, len; - void *dp; - - Lck_AssertHeld(&sc->mtx); - - assert(sg == sc->cur_seg); - AN(sg->p.offset); - sc->cur_seg = NULL; - - if (sg->nalloc == 0) { - /* XXX: if segment is empty, delete instead */ - VTAILQ_REMOVE(&sc->segments, sg, list); - free(sg); - return; - } - - /* - * If there is enough space left, that we can move the smp_objects - * down without overwriting the present copy, we will do so to - * compact the segment. - */ - left = smp_spaceleft(sc, sg); - len = sizeof(struct smp_object) * sg->p.lobjlist; - if (len < left) { - dst = sc->next_bot + IRNUP(sc, SMP_SIGN_SPACE); - dp = sc->base + dst; - assert((uintptr_t)dp + len < (uintptr_t)sg->objs); - memcpy(dp, sg->objs, len); - sc->next_top = dst; - sg->objs = dp; - sg->p.length = (sc->next_top - sg->p.offset) - + len + IRNUP(sc, SMP_SIGN_SPACE); - (void)smp_spaceleft(sc, sg); /* for the asserts */ - - } - - /* Update the segment header */ - sg->p.objlist = sc->next_top; - - /* Write the (empty) OBJIDX signature */ - sc->next_top -= IRNUP(sc, SMP_SIGN_SPACE); - assert(sc->next_top >= sc->next_bot); - smp_def_sign(sc, sg->ctx, sc->next_top, "OBJIDX"); - smp_reset_sign(sg->ctx); - smp_sync_sign(sg->ctx); - - /* Write the (empty) SEGTAIL signature */ - smp_def_sign(sc, sg->ctx, - sg->p.offset + sg->p.length - IRNUP(sc, SMP_SIGN_SPACE), "SEGTAIL"); - smp_reset_sign(sg->ctx); - smp_sync_sign(sg->ctx); - - /* Save segment list */ - smp_save_segs(sc); - sc->free_offset = smp_segend(sg); -} - - -/*--------------------------------------------------------------------- - */ - -static struct smp_object * -smp_find_so(const struct smp_seg *sg, unsigned priv2) -{ - struct smp_object *so; - - assert(priv2 > 0); - assert(priv2 <= sg->p.lobjlist); - so = &sg->objs[sg->p.lobjlist - priv2]; - return (so); -} - -/*--------------------------------------------------------------------- - * Check if a given storage structure is valid to use - */ - -static int -smp_loaded_st(const struct smp_sc *sc, const struct smp_seg *sg, - const struct storage *st) -{ - struct smp_seg *sg2; - const uint8_t *pst; - uint64_t o; - - (void)sg; /* XXX: faster: Start search from here */ - pst = (const void *)st; - - if (pst < (sc->base + sc->ident->stuff[SMP_SPC_STUFF])) - return (0x01); /* Before silo payload start */ - if (pst > (sc->base + sc->ident->stuff[SMP_END_STUFF])) - return (0x02); /* After silo end */ - - o = pst - sc->base; - - /* Find which segment contains the storage structure */ - VTAILQ_FOREACH(sg2, &sc->segments, list) - if (o > sg2->p.offset && (o + sizeof(*st)) < sg2->p.objlist) - break; - if (sg2 == NULL) - return (0x04); /* No claiming segment */ - if (!(sg2->flags & SMP_SEG_LOADED)) - return (0x08); /* Claiming segment not loaded */ - - /* It is now safe to access the storage structure */ - if (st->magic != STORAGE_MAGIC) - return (0x10); /* Not enough magic */ - - if (o + st->space >= sg2->p.objlist) - return (0x20); /* Allocation not inside segment */ - - if (st->len > st->space) - return (0x40); /* Plain bad... */ - - /* - * XXX: We could patch up st->stevedore and st->priv here - * XXX: but if things go right, we will never need them. - */ - return (0); -} - -/*--------------------------------------------------------------------- - * objcore methods for persistent objects - */ - -static struct object * -smp_oc_getobj(struct worker *wrk, struct objcore *oc) -{ - struct object *o; - struct smp_seg *sg; - struct smp_object *so; - struct storage *st; - uint64_t l; - int bad; - - /* Some calls are direct, but they should match anyway */ - assert(oc->methods->getobj == smp_oc_getobj); - - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - if (wrk == NULL) - AZ(oc->flags & OC_F_NEEDFIXUP); - - CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - so = smp_find_so(sg, oc->priv2); - - o = (void*)(sg->sc->base + so->ptr); - /* - * The object may not be in this segment since we allocate it - * In a separate operation than the smp_object. We could check - * that it is in a later segment, but that would be complicated. - * XXX: For now, be happy if it is inside th silo - */ - ASSERT_PTR_IN_SILO(sg->sc, o); - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - - /* - * If this flag is not set, it will not be, and the lock is not - * needed to test it. - */ - if (!(oc->flags & OC_F_NEEDFIXUP)) - return (o); - - AN(wrk); - Lck_Lock(&sg->sc->mtx); - /* Check again, we might have raced. */ - if (oc->flags & OC_F_NEEDFIXUP) { - /* We trust caller to have a refcnt for us */ - o->objcore = oc; - - bad = 0; - l = 0; - VTAILQ_FOREACH(st, &o->store, list) { - bad |= smp_loaded_st(sg->sc, sg, st); - if (bad) - break; - l += st->len; - } - if (l != o->len) - bad |= 0x100; - - if(bad) { - EXP_Set_ttl(&o->exp, -1); - so->ttl = 0; - } - - sg->nfixed++; - wrk->stats.n_object++; - wrk->stats.n_vampireobject--; - oc->flags &= ~OC_F_NEEDFIXUP; - } - Lck_Unlock(&sg->sc->mtx); - EXP_Rearm(o); - return (o); -} - -static void -smp_oc_updatemeta(struct objcore *oc) -{ - struct object *o; - struct smp_seg *sg; - struct smp_object *so; - double mttl; - - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - o = smp_oc_getobj(NULL, oc); - AN(o); - - CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - CHECK_OBJ_NOTNULL(sg->sc, SMP_SC_MAGIC); - so = smp_find_so(sg, oc->priv2); - - mttl = EXP_Grace(NULL, o); - - if (sg == sg->sc->cur_seg) { - /* Lock necessary, we might race close_seg */ - Lck_Lock(&sg->sc->mtx); - so->ban = BAN_Time(oc->ban); - so->ttl = mttl; - Lck_Unlock(&sg->sc->mtx); - } else { - so->ban = BAN_Time(oc->ban); - so->ttl = mttl; - } -} - -static void __match_proto__() -smp_oc_freeobj(struct objcore *oc) -{ - struct smp_seg *sg; - struct smp_object *so; - - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - - CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - so = smp_find_so(sg, oc->priv2); - - Lck_Lock(&sg->sc->mtx); - so->ttl = 0; - so->ptr = 0; - - assert(sg->nobj > 0); - assert(sg->nfixed > 0); - sg->nobj--; - sg->nfixed--; - - Lck_Unlock(&sg->sc->mtx); -} - -/*-------------------------------------------------------------------- - * Find the per-segment lru list for this object - */ - -static struct lru * -smp_oc_getlru(const struct objcore *oc) -{ - struct smp_seg *sg; - - CAST_OBJ_NOTNULL(sg, oc->priv, SMP_SEG_MAGIC); - return (sg->lru); -} - -static struct objcore_methods smp_oc_methods = { - .getobj = smp_oc_getobj, - .updatemeta = smp_oc_updatemeta, - .freeobj = smp_oc_freeobj, - .getlru = smp_oc_getlru, -}; - -/*--------------------------------------------------------------------*/ - -void -smp_init_oc(struct objcore *oc, struct smp_seg *sg, unsigned objidx) -{ - - oc->priv = sg; - oc->priv2 = objidx; - oc->methods = &smp_oc_methods; -} diff --git a/bin/varnishd/storage_persistent_subr.c b/bin/varnishd/storage_persistent_subr.c deleted file mode 100644 index b4bbb3f..0000000 --- a/bin/varnishd/storage_persistent_subr.c +++ /dev/null @@ -1,302 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Persistent storage method - * - * XXX: Before we start the client or maybe after it stops, we should give the - * XXX: stevedores a chance to examine their storage for consistency. - * - * XXX: Do we ever free the LRU-lists ? - */ - -#include "config.h" - -#include - -#include -#include -#include - -#include "cache.h" -#include "storage.h" - -#include "vsha256.h" - -#include "persistent.h" -#include "storage_persistent.h" - -/*-------------------------------------------------------------------- - * SIGNATURE functions - * The signature is SHA256 over: - * 1. The smp_sign struct up to but not including the length field. - * 2. smp_sign->length bytes, starting after the smp_sign structure - * 3. The smp-sign->length field. - * The signature is stored after the byte-range from step 2. - */ - -/*-------------------------------------------------------------------- - * Define a signature by location and identifier. - */ - -void -smp_def_sign(const struct smp_sc *sc, struct smp_signctx *ctx, - uint64_t off, const char *id) -{ - - AZ(off & 7); /* Alignment */ - assert(strlen(id) < sizeof ctx->ss->ident); - - memset(ctx, 0, sizeof *ctx); - ctx->ss = (void*)(sc->base + off); - ctx->unique = sc->unique; - ctx->id = id; -} - -/*-------------------------------------------------------------------- - * Check that a signature is good, leave state ready for append - */ -int -smp_chk_sign(struct smp_signctx *ctx) -{ - struct SHA256Context cx; - unsigned char sign[SHA256_LEN]; - int r = 0; - - if (strncmp(ctx->id, ctx->ss->ident, sizeof ctx->ss->ident)) - r = 1; - else if (ctx->unique != ctx->ss->unique) - r = 2; - else if ((uintptr_t)ctx->ss != ctx->ss->mapped) - r = 3; - else { - SHA256_Init(&ctx->ctx); - SHA256_Update(&ctx->ctx, ctx->ss, - offsetof(struct smp_sign, length)); - SHA256_Update(&ctx->ctx, SIGN_DATA(ctx), ctx->ss->length); - cx = ctx->ctx; - SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length)); - SHA256_Final(sign, &cx); - if (memcmp(sign, SIGN_END(ctx), sizeof sign)) - r = 4; - } - if (r) { - fprintf(stderr, "CHK(%p %s %p %s) = %d\n", - ctx, ctx->id, ctx->ss, - r > 1 ? ctx->ss->ident : "", r); - } - return (r); -} - -/*-------------------------------------------------------------------- - * Append data to a signature - */ -void -smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len) -{ - struct SHA256Context cx; - unsigned char sign[SHA256_LEN]; - - if (len != 0) { - SHA256_Update(&ctx->ctx, ptr, len); - ctx->ss->length += len; - } - cx = ctx->ctx; - SHA256_Update(&cx, &ctx->ss->length, sizeof(ctx->ss->length)); - SHA256_Final(sign, &cx); - memcpy(SIGN_END(ctx), sign, sizeof sign); -XXXAZ(smp_chk_sign(ctx)); -} - -/*-------------------------------------------------------------------- - * Reset a signature to empty, prepare for appending. - */ - -void -smp_reset_sign(struct smp_signctx *ctx) -{ - - memset(ctx->ss, 0, sizeof *ctx->ss); - strcpy(ctx->ss->ident, ctx->id); - ctx->ss->unique = ctx->unique; - ctx->ss->mapped = (uintptr_t)ctx->ss; - SHA256_Init(&ctx->ctx); - SHA256_Update(&ctx->ctx, ctx->ss, - offsetof(struct smp_sign, length)); - smp_append_sign(ctx, NULL, 0); -} - -/*-------------------------------------------------------------------- - * Force a write of a signature block to the backing store. - */ - -void -smp_sync_sign(const struct smp_signctx *ctx) -{ - int i; - - /* XXX: round to pages */ - i = msync((void*)ctx->ss, ctx->ss->length + SHA256_LEN, MS_SYNC); - if (i && 0) - fprintf(stderr, "SyncSign(%p %s) = %d %s\n", - ctx->ss, ctx->id, i, strerror(errno)); -} - -/*-------------------------------------------------------------------- - * Create and force a new signature to backing store - */ - -static void -smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx, - uint64_t off, const char *id) -{ - smp_def_sign(sc, ctx, off, id); - smp_reset_sign(ctx); - smp_sync_sign(ctx); -} - -/*-------------------------------------------------------------------- - * Initialize a Silo with a valid but empty structure. - * - * XXX: more intelligent sizing of things. - */ - -void -smp_newsilo(struct smp_sc *sc) -{ - struct smp_ident *si; - - ASSERT_MGT(); - assert(strlen(SMP_IDENT_STRING) < sizeof si->ident); - - /* Choose a new random number */ - sc->unique = random(); - - smp_reset_sign(&sc->idn); - si = sc->ident; - - memset(si, 0, sizeof *si); - strcpy(si->ident, SMP_IDENT_STRING); - si->byte_order = 0x12345678; - si->size = sizeof *si; - si->major_version = 2; - si->unique = sc->unique; - si->mediasize = sc->mediasize; - si->granularity = sc->granularity; - /* - * Aim for cache-line-width - */ - si->align = sizeof(void*) * 2; - sc->align = si->align; - - si->stuff[SMP_BAN1_STUFF] = sc->granularity; - si->stuff[SMP_BAN2_STUFF] = si->stuff[SMP_BAN1_STUFF] + 1024*1024; - si->stuff[SMP_SEG1_STUFF] = si->stuff[SMP_BAN2_STUFF] + 1024*1024; - si->stuff[SMP_SEG2_STUFF] = si->stuff[SMP_SEG1_STUFF] + 1024*1024; - si->stuff[SMP_SPC_STUFF] = si->stuff[SMP_SEG2_STUFF] + 1024*1024; - si->stuff[SMP_END_STUFF] = si->mediasize; - assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]); - - smp_new_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1"); - smp_new_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2"); - smp_new_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1"); - smp_new_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2"); - - smp_append_sign(&sc->idn, si, sizeof *si); - smp_sync_sign(&sc->idn); -} - -/*-------------------------------------------------------------------- - * Check if a silo is valid. - */ - -int -smp_valid_silo(struct smp_sc *sc) -{ - struct smp_ident *si; - int i, j; - - assert(strlen(SMP_IDENT_STRING) < sizeof si->ident); - - i = smp_chk_sign(&sc->idn); - if (i) - return (i); - - si = sc->ident; - if (strcmp(si->ident, SMP_IDENT_STRING)) - return (12); - if (si->byte_order != 0x12345678) - return (13); - if (si->size != sizeof *si) - return (14); - if (si->major_version != 2) - return (15); - if (si->mediasize != sc->mediasize) - return (17); - if (si->granularity != sc->granularity) - return (18); - if (si->align < sizeof(void*)) - return (19); - if (!PWR2(si->align)) - return (20); - sc->align = si->align; - sc->unique = si->unique; - - /* XXX: Sanity check stuff[6] */ - - assert(si->stuff[SMP_BAN1_STUFF] > sizeof *si + SHA256_LEN); - assert(si->stuff[SMP_BAN2_STUFF] > si->stuff[SMP_BAN1_STUFF]); - assert(si->stuff[SMP_SEG1_STUFF] > si->stuff[SMP_BAN2_STUFF]); - assert(si->stuff[SMP_SEG2_STUFF] > si->stuff[SMP_SEG1_STUFF]); - assert(si->stuff[SMP_SPC_STUFF] > si->stuff[SMP_SEG2_STUFF]); - assert(si->stuff[SMP_END_STUFF] == sc->mediasize); - - assert(smp_stuff_len(sc, SMP_SEG1_STUFF) > 65536); - assert(smp_stuff_len(sc, SMP_SEG1_STUFF) == - smp_stuff_len(sc, SMP_SEG2_STUFF)); - - assert(smp_stuff_len(sc, SMP_BAN1_STUFF) > 65536); - assert(smp_stuff_len(sc, SMP_BAN1_STUFF) == - smp_stuff_len(sc, SMP_BAN2_STUFF)); - - smp_def_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1"); - smp_def_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2"); - smp_def_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1"); - smp_def_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2"); - - /* We must have one valid BAN table */ - i = smp_chk_sign(&sc->ban1); - j = smp_chk_sign(&sc->ban2); - if (i && j) - return (100 + i * 10 + j); - - /* We must have one valid SEG table */ - i = smp_chk_sign(&sc->seg1); - j = smp_chk_sign(&sc->seg2); - if (i && j) - return (200 + i * 10 + j); - return (0); -} diff --git a/bin/varnishd/storage_synth.c b/bin/varnishd/storage_synth.c deleted file mode 100644 index 5df2c08..0000000 --- a/bin/varnishd/storage_synth.c +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * Copyright (c) 2008-2011 Varnish Software 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. - * - * Storage method for synthetic content, based on vsb. - */ - -#include "config.h" - -#include - -#include "cache.h" -#include "storage.h" - - -static struct lock sms_mtx; - -static void -sms_free(struct storage *sto) -{ - - CHECK_OBJ_NOTNULL(sto, STORAGE_MAGIC); - Lck_Lock(&sms_mtx); - VSC_C_main->sms_nobj--; - VSC_C_main->sms_nbytes -= sto->len; - VSC_C_main->sms_bfree += sto->len; - Lck_Unlock(&sms_mtx); - VSB_delete(sto->priv); - free(sto); -} - -void -SMS_Init(void) -{ - - Lck_New(&sms_mtx, lck_sms); -} - -static struct stevedore sms_stevedore = { - .magic = STEVEDORE_MAGIC, - .name = "synth", - .free = sms_free, -}; - -struct vsb * -SMS_Makesynth(struct object *obj) -{ - struct storage *sto; - struct vsb *vsb; - - CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); - STV_Freestore(obj); - obj->len = 0; - - Lck_Lock(&sms_mtx); - VSC_C_main->sms_nreq++; - VSC_C_main->sms_nobj++; - Lck_Unlock(&sms_mtx); - - sto = calloc(sizeof *sto, 1); - XXXAN(sto); - vsb = VSB_new_auto(); - XXXAN(vsb); - sto->priv = vsb; - sto->len = 0; - sto->space = 0; -#ifdef SENDFILE_WORKS - sto->fd = -1; -#endif - sto->stevedore = &sms_stevedore; - sto->magic = STORAGE_MAGIC; - - VTAILQ_INSERT_TAIL(&obj->store, sto, list); - return (vsb); -} - -void -SMS_Finish(struct object *obj) -{ - struct storage *sto; - struct vsb *vsb; - - CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); - sto = VTAILQ_FIRST(&obj->store); - assert(sto->stevedore == &sms_stevedore); - vsb = sto->priv; - AZ(VSB_finish(vsb)); - - sto->ptr = (void*)VSB_data(vsb); - sto->len = VSB_len(vsb); - sto->space = VSB_len(vsb); - obj->len = sto->len; - Lck_Lock(&sms_mtx); - VSC_C_main->sms_nbytes += sto->len; - VSC_C_main->sms_balloc += sto->len; - Lck_Unlock(&sms_mtx); -} diff --git a/bin/varnishd/storage_umem.c b/bin/varnishd/storage_umem.c deleted file mode 100644 index 9198a99..0000000 --- a/bin/varnishd/storage_umem.c +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Storage method based on umem_alloc(3MALLOC) - */ - -#include "config.h" - -#ifdef HAVE_LIBUMEM - -#include - -#include -#include -#include - -#include "cache.h" -#include "storage.h" - -static size_t smu_max = SIZE_MAX; -static MTX smu_mtx; - -struct smu { - struct storage s; - size_t sz; -}; - -static struct storage * -smu_alloc(struct stevedore *st, size_t size) -{ - struct smu *smu; - - Lck_Lock(&smu_mtx); - VSC_C_main->sma_nreq++; - if (VSC_C_main->sma_nbytes + size > smu_max) - size = 0; - else { - VSC_C_main->sma_nobj++; - VSC_C_main->sma_nbytes += size; - VSC_C_main->sma_balloc += size; - } - Lck_Unlock(&smu_mtx); - - if (size == 0) - return (NULL); - - smu = umem_zalloc(sizeof *smu, UMEM_DEFAULT); - if (smu == NULL) - return (NULL); - smu->sz = size; - smu->s.priv = smu; - smu->s.ptr = umem_alloc(size, UMEM_DEFAULT); - XXXAN(smu->s.ptr); - smu->s.len = 0; - smu->s.space = size; - smu->s.fd = -1; - smu->s.stevedore = st; - smu->s.magic = STORAGE_MAGIC; - return (&smu->s); -} - -static void -smu_free(struct storage *s) -{ - struct smu *smu; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - smu = s->priv; - assert(smu->sz == smu->s.space); - Lck_Lock(&smu_mtx); - VSC_C_main->sma_nobj--; - VSC_C_main->sma_nbytes -= smu->sz; - VSC_C_main->sma_bfree += smu->sz; - Lck_Unlock(&smu_mtx); - umem_free(smu->s.ptr, smu->s.space); - umem_free(smu, sizeof *smu); -} - -static void -smu_trim(const struct storage *s, size_t size) -{ - struct smu *smu; - void *p; - - CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC); - smu = s->priv; - assert(smu->sz == smu->s.space); - if ((p = umem_alloc(size, UMEM_DEFAULT)) != NULL) { - memcpy(p, smu->s.ptr, size); - umem_free(smu->s.ptr, smu->s.space); - Lck_Lock(&smu_mtx); - VSC_C_main->sma_nbytes -= (smu->sz - size); - VSC_C_main->sma_bfree += smu->sz - size; - smu->sz = size; - Lck_Unlock(&smu_mtx); - smu->s.ptr = p; - smu->s.space = size; - } -} - -static void -smu_init(struct stevedore *parent, int ac, char * const *av) -{ - const char *e; - uintmax_t u; - - (void)parent; - - AZ(av[ac]); - if (ac > 1) - ARGV_ERR("(-sumem) too many arguments\n"); - - if (ac == 0 || *av[0] == '\0') - return; - - e = VNUM_2bytes(av[0], &u, 0); - if (e != NULL) - ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); - if ((u != (uintmax_t)(size_t)u)) - ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); - smu_max = u; -} - -static void -smu_open(const struct stevedore *st) -{ - (void)st; - AZ(pthread_mutex_init(&smu_mtx, NULL)); -} - -const struct stevedore smu_stevedore = { - .magic = STEVEDORE_MAGIC, - .name = "umem", - .init = smu_init, - .open = smu_open, - .alloc = smu_alloc, - .free = smu_free, - .trim = smu_trim, -}; - -#endif /* HAVE_UMEM_H */ From phk at varnish-cache.org Wed Oct 12 16:03:46 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 18:03:46 +0200 Subject: [master] 552f71c Move the waiters into their own subdirectory where VMODs won't see them. Message-ID: commit 552f71c17ee8fb8d745869d1fce65e8f9521b629 Author: Poul-Henning Kamp Date: Wed Oct 12 16:03:18 2011 +0000 Move the waiters into their own subdirectory where VMODs won't see them. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 5260427..cdec084 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -44,11 +44,11 @@ varnishd_SOURCES = \ cache_vrt_re.c \ cache_vrt_var.c \ cache_vrt_vmod.c \ - cache_waiter.c \ - cache_waiter_epoll.c \ - cache_waiter_kqueue.c \ - cache_waiter_poll.c \ - cache_waiter_ports.c \ + waiter/cache_waiter.c \ + waiter/cache_waiter_epoll.c \ + waiter/cache_waiter_kqueue.c \ + waiter/cache_waiter_poll.c \ + waiter/cache_waiter_ports.c \ cache_wrk.c \ cache_wrw.c \ cache_ws.c \ @@ -81,7 +81,7 @@ noinst_HEADERS = \ cache.h \ cache_backend.h \ cache_esi.h \ - cache_waiter.h \ + waiter/cache_waiter.h \ common.h \ default_vcl.h \ hash_slinger.h \ diff --git a/bin/varnishd/cache_main.c b/bin/varnishd/cache_main.c index 6e62fd2..2d00ee2 100644 --- a/bin/varnishd/cache_main.c +++ b/bin/varnishd/cache_main.c @@ -34,7 +34,7 @@ #include "cache.h" -#include "cache_waiter.h" +#include "waiter/cache_waiter.h" #include "hash_slinger.h" /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index 482708d..76ea866 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -43,7 +43,7 @@ #include "vapi/vsm_int.h" #include "cache_backend.h" -#include "cache_waiter.h" +#include "waiter/cache_waiter.h" #include "libvcl.h" #include "vcl.h" diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 00eaef5..55ad333 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -47,7 +47,7 @@ #include "cache.h" -#include "cache_waiter.h" +#include "waiter/cache_waiter.h" #include "hash_slinger.h" #include "vtcp.h" #include "vtim.h" diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c index d55bae0..5db418c 100644 --- a/bin/varnishd/cache_session.c +++ b/bin/varnishd/cache_session.c @@ -40,7 +40,7 @@ #include "cache.h" -#include "cache_waiter.h" +#include "waiter/cache_waiter.h" /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache_waiter.c b/bin/varnishd/cache_waiter.c deleted file mode 100644 index 9c30edf..0000000 --- a/bin/varnishd/cache_waiter.c +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -#include "config.h" - -#include "cache.h" - -#include "cache_waiter.h" -#include "vcli.h" -#include "vcli_priv.h" - -static const struct waiter * const vca_waiters[] = { - #if defined(HAVE_KQUEUE) - &waiter_kqueue, - #endif - #if defined(HAVE_EPOLL_CTL) - &waiter_epoll, - #endif - #if defined(HAVE_PORT_CREATE) - &waiter_ports, - #endif - &waiter_poll, - NULL, -}; - -struct waiter const * waiter; - -const char * -WAIT_GetName(void) -{ - - if (waiter != NULL) - return (waiter->name); - else - return ("no_waiter"); -} - -void -WAIT_tweak_waiter(struct cli *cli, const char *arg) -{ - int i; - - ASSERT_MGT(); - - if (arg == NULL) { - if (waiter == NULL) - VCLI_Out(cli, "default"); - else - VCLI_Out(cli, "%s", waiter->name); - - VCLI_Out(cli, " ("); - for (i = 0; vca_waiters[i] != NULL; i++) - VCLI_Out(cli, "%s%s", i == 0 ? "" : ", ", - vca_waiters[i]->name); - VCLI_Out(cli, ")"); - return; - } - if (!strcmp(arg, "default")) { - waiter = NULL; - return; - } - for (i = 0; vca_waiters[i]; i++) { - if (!strcmp(arg, vca_waiters[i]->name)) { - waiter = vca_waiters[i]; - return; - } - } - VCLI_Out(cli, "Unknown waiter"); - VCLI_SetResult(cli, CLIS_PARAM); -} - -void -WAIT_Init(void) -{ - - if (waiter == NULL) - waiter = vca_waiters[0]; - - AN(waiter); - AN(waiter->name); - AN(waiter->init); - AN(waiter->pass); -} diff --git a/bin/varnishd/cache_waiter.h b/bin/varnishd/cache_waiter.h deleted file mode 100644 index 28bc39d..0000000 --- a/bin/varnishd/cache_waiter.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - */ - -struct sess; - -typedef void* waiter_init_f(void); -typedef void waiter_pass_f(void *priv, const struct sess *); - -struct waiter { - const char *name; - waiter_init_f *init; - waiter_pass_f *pass; -}; - -extern struct waiter const * waiter; - -#if defined(HAVE_EPOLL_CTL) -extern const struct waiter waiter_epoll; -#endif - -#if defined(HAVE_KQUEUE) -extern const struct waiter waiter_kqueue; -#endif - -#if defined(HAVE_PORT_CREATE) -extern const struct waiter waiter_ports; -#endif - - -/* cache_session.c */ -void SES_Handle(struct sess *sp, int status); - -/* cache_waiter.c */ -extern const struct waiter waiter_poll; -const char *WAIT_GetName(void); -void WAIT_tweak_waiter(struct cli *cli, const char *arg); -void WAIT_Init(void); diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c deleted file mode 100644 index 301fcf2..0000000 --- a/bin/varnishd/cache_waiter_epoll.c +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software AS - * All rights reserved. - * - * Author: Rogerio Carvalho Schneider - * - * 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. - * - * XXX: We need to pass sessions back into the event engine when they are - * reused. Not sure what the most efficient way is for that. For now - * write the session pointer to a pipe which the event engine monitors. - */ - -#include "config.h" - -#if defined(HAVE_EPOLL_CTL) - -#include - -#include -#include - -#include "cache.h" - -#include "cache_waiter.h" -#include "vtim.h" - -#ifndef EPOLLRDHUP -# define EPOLLRDHUP 0 -#endif - -#define NEEV 100 - -struct vwe { - unsigned magic; -#define VWE_MAGIC 0x6bd73424 - - pthread_t epoll_thread; - pthread_t timer_thread; - int epfd; - - VTAILQ_HEAD(,sess) sesshead; - int pipes[2]; - int timer_pipes[2]; -}; - -static void -vwe_modadd(struct vwe *vwe, int fd, void *data, short arm) -{ - - /* XXX: EPOLLET (edge triggered) can cause rather Bad Things to - * XXX: happen: If NEEV+1 threads get stuck in write(), all threads - * XXX: will hang. See #644. - */ - assert(fd >= 0); - if (data == vwe->pipes || data == vwe->timer_pipes) { - struct epoll_event ev = { - EPOLLIN | EPOLLPRI , { data } - }; - AZ(epoll_ctl(vwe->epfd, arm, fd, &ev)); - } else { - struct sess *sp = (struct sess *)data; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - sp->ev.data.ptr = data; - sp->ev.events = EPOLLIN | EPOLLPRI | EPOLLONESHOT | EPOLLRDHUP; - AZ(epoll_ctl(vwe->epfd, arm, fd, &sp->ev)); - } -} - -static void -vwe_cond_modadd(struct vwe *vwe, int fd, void *data) -{ - struct sess *sp = (struct sess *)data; - - assert(fd >= 0); - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - if (sp->ev.data.ptr) - AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_MOD, fd, &sp->ev)); - else { - sp->ev.data.ptr = data; - sp->ev.events = EPOLLIN | EPOLLPRI | EPOLLONESHOT | EPOLLRDHUP; - AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_ADD, fd, &sp->ev)); - } -} - -static void -vwe_eev(struct vwe *vwe, const struct epoll_event *ep) -{ - struct sess *ss[NEEV], *sp; - int i, j; - - AN(ep->data.ptr); - if (ep->data.ptr == vwe->pipes) { - if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { - j = 0; - i = read(vwe->pipes[0], ss, sizeof ss); - if (i == -1 && errno == EAGAIN) - return; - while (i >= sizeof ss[0]) { - CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); - assert(ss[j]->fd >= 0); - AZ(ss[j]->obj); - VTAILQ_INSERT_TAIL(&vwe->sesshead, ss[j], list); - vwe_cond_modadd(vwe, ss[j]->fd, ss[j]); - j++; - i -= sizeof ss[0]; - } - assert(i == 0); - } - } else { - CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC); - if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { - i = HTC_Rx(sp->htc); - if (i == 0) { - vwe_modadd(vwe, sp->fd, sp, EPOLL_CTL_MOD); - return; /* more needed */ - } - VTAILQ_REMOVE(&vwe->sesshead, sp, list); - SES_Handle(sp, i); - } else if (ep->events & EPOLLERR) { - VTAILQ_REMOVE(&vwe->sesshead, sp, list); - SES_Delete(sp, "ERR"); - } else if (ep->events & EPOLLHUP) { - VTAILQ_REMOVE(&vwe->sesshead, sp, list); - SES_Delete(sp, "HUP"); - } else if (ep->events & EPOLLRDHUP) { - VTAILQ_REMOVE(&vwe->sesshead, sp, list); - SES_Delete(sp, "RHUP"); - } - } -} - -/*--------------------------------------------------------------------*/ - -static void * -vwe_thread(void *priv) -{ - struct epoll_event ev[NEEV], *ep; - struct sess *sp; - char junk; - double deadline; - int dotimer, i, n; - struct vwe *vwe; - - CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); - - THR_SetName("cache-epoll"); - - vwe->epfd = epoll_create(1); - assert(vwe->epfd >= 0); - - vwe_modadd(vwe, vwe->pipes[0], vwe->pipes, EPOLL_CTL_ADD); - vwe_modadd(vwe, vwe->timer_pipes[0], vwe->timer_pipes, EPOLL_CTL_ADD); - - while (1) { - dotimer = 0; - n = epoll_wait(vwe->epfd, ev, NEEV, -1); - for (ep = ev, i = 0; i < n; i++, ep++) { - if (ep->data.ptr == vwe->timer_pipes && - (ep->events == EPOLLIN || ep->events == EPOLLPRI)) - { - assert(read(vwe->timer_pipes[0], &junk, 1)); - dotimer = 1; - } else - vwe_eev(vwe, ep); - } - if (!dotimer) - continue; - - /* check for timeouts */ - deadline = VTIM_real() - params->sess_timeout; - for (;;) { - sp = VTAILQ_FIRST(&vwe->sesshead); - if (sp == NULL) - break; - if (sp->t_open > deadline) - break; - VTAILQ_REMOVE(&vwe->sesshead, sp, list); - // XXX: not yet VTCP_linger(sp->fd, 0); - SES_Delete(sp, "timeout"); - } - } - return NULL; -} - -/*--------------------------------------------------------------------*/ - -static void * -vwe_sess_timeout_ticker(void *priv) -{ - char ticker = 'R'; - struct vwe *vwe; - - CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); - THR_SetName("cache-epoll-sess_timeout_ticker"); - - while (1) { - /* ticking */ - assert(write(vwe->timer_pipes[1], &ticker, 1)); - VTIM_sleep(100 * 1e-3); - } - return NULL; -} - -/*--------------------------------------------------------------------*/ - -static void -vwe_pass(void *priv, const struct sess *sp) -{ - struct vwe *vwe; - - CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); - assert(sizeof sp == write(vwe->pipes[1], &sp, sizeof sp)); -} - -/*--------------------------------------------------------------------*/ - -static void * -vwe_init(void) -{ - int i; - struct vwe *vwe; - - ALLOC_OBJ(vwe, VWE_MAGIC); - AN(vwe); - VTAILQ_INIT(&vwe->sesshead); - AZ(pipe(vwe->pipes)); - AZ(pipe(vwe->timer_pipes)); - - i = fcntl(vwe->pipes[0], F_GETFL); - assert(i != -1); - i |= O_NONBLOCK; - i = fcntl(vwe->pipes[0], F_SETFL, i); - assert(i != -1); - - i = fcntl(vwe->timer_pipes[0], F_GETFL); - assert(i != -1); - i |= O_NONBLOCK; - i = fcntl(vwe->timer_pipes[0], F_SETFL, i); - assert(i != -1); - - AZ(pthread_create(&vwe->timer_thread, - NULL, vwe_sess_timeout_ticker, vwe)); - AZ(pthread_create(&vwe->epoll_thread, NULL, vwe_thread, vwe)); - return(vwe); -} - -/*--------------------------------------------------------------------*/ - -const struct waiter waiter_epoll = { - .name = "epoll", - .init = vwe_init, - .pass = vwe_pass, -}; - -#endif /* defined(HAVE_EPOLL_CTL) */ diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c deleted file mode 100644 index 8bee1c9..0000000 --- a/bin/varnishd/cache_waiter_kqueue.c +++ /dev/null @@ -1,246 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - * XXX: We need to pass sessions back into the event engine when they are - * reused. Not sure what the most efficient way is for that. For now - * write the session pointer to a pipe which the event engine monitors. - */ - -#include "config.h" - -#if defined(HAVE_KQUEUE) - -#include -#include - -#include -#include -#include - -#include "cache.h" - -#include "cache_waiter.h" -#include "vtim.h" - -#define NKEV 100 - -struct vwk { - unsigned magic; -#define VWK_MAGIC 0x1cc2acc2 - pthread_t thread; - int pipes[2]; - int kq; - struct kevent ki[NKEV]; - unsigned nki; - VTAILQ_HEAD(,sess) sesshead; -}; - -/*--------------------------------------------------------------------*/ - -static void -vwk_kq_flush(struct vwk *vwk) -{ - int i; - - if (vwk->nki == 0) - return; - i = kevent(vwk->kq, vwk->ki, vwk->nki, NULL, 0, NULL); - assert(i == 0); - vwk->nki = 0; -} - -static void -vwk_kq_sess(struct vwk *vwk, struct sess *sp, short arm) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - assert(sp->fd >= 0); - DSL(0x04, SLT_Debug, sp->vsl_id, "KQ: EV_SET sp %p arm %x", sp, arm); - EV_SET(&vwk->ki[vwk->nki], sp->fd, EVFILT_READ, arm, 0, 0, sp); - if (++vwk->nki == NKEV) - vwk_kq_flush(vwk); -} - -static void -vwk_kev(struct vwk *vwk, const struct kevent *kp) -{ - int i, j; - struct sess *sp; - struct sess *ss[NKEV]; - - AN(kp->udata); - if (kp->udata == vwk->pipes) { - j = 0; - i = read(vwk->pipes[0], ss, sizeof ss); - if (i == -1 && errno == EAGAIN) - return; - while (i >= sizeof ss[0]) { - CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); - assert(ss[j]->fd >= 0); - AZ(ss[j]->obj); - VTAILQ_INSERT_TAIL(&vwk->sesshead, ss[j], list); - vwk_kq_sess(vwk, ss[j], EV_ADD | EV_ONESHOT); - j++; - i -= sizeof ss[0]; - } - assert(i == 0); - return; - } - CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); - DSL(0x04, SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", - sp, (unsigned long)kp->data, kp->flags, - (kp->flags & EV_EOF) ? " EOF" : ""); - - assert((sp->vsl_id & VSL_IDENTMASK) == kp->ident); - assert((sp->vsl_id & VSL_IDENTMASK) == sp->fd); - if (kp->data > 0) { - i = HTC_Rx(sp->htc); - if (i == 0) { - vwk_kq_sess(vwk, sp, EV_ADD | EV_ONESHOT); - return; /* more needed */ - } - VTAILQ_REMOVE(&vwk->sesshead, sp, list); - SES_Handle(sp, i); - return; - } else if (kp->flags & EV_EOF) { - VTAILQ_REMOVE(&vwk->sesshead, sp, list); - SES_Delete(sp, "EOF"); - return; - } else { - VSL(SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", - sp, (unsigned long)kp->data, kp->flags, - (kp->flags & EV_EOF) ? " EOF" : ""); - } -} - -/*--------------------------------------------------------------------*/ - -static void * -vwk_thread(void *priv) -{ - struct vwk *vwk; - struct kevent ke[NKEV], *kp; - int j, n, dotimer; - double deadline; - struct sess *sp; - - CAST_OBJ_NOTNULL(vwk, priv, VWK_MAGIC); - THR_SetName("cache-kqueue"); - - vwk->kq = kqueue(); - assert(vwk->kq >= 0); - - j = 0; - EV_SET(&ke[j], 0, EVFILT_TIMER, EV_ADD, 0, 100, NULL); - j++; - EV_SET(&ke[j], vwk->pipes[0], EVFILT_READ, EV_ADD, 0, 0, vwk->pipes); - j++; - AZ(kevent(vwk->kq, ke, j, NULL, 0, NULL)); - - vwk->nki = 0; - while (1) { - dotimer = 0; - n = kevent(vwk->kq, vwk->ki, vwk->nki, ke, NKEV, NULL); - assert(n >= 1 && n <= NKEV); - vwk->nki = 0; - for (kp = ke, j = 0; j < n; j++, kp++) { - if (kp->filter == EVFILT_TIMER) { - dotimer = 1; - continue; - } - assert(kp->filter == EVFILT_READ); - vwk_kev(vwk, kp); - } - if (!dotimer) - continue; - /* - * Make sure we have no pending changes for the fd's - * we are about to close, in case the accept(2) in the - * other thread creates new fd's betwen our close and - * the kevent(2) at the top of this loop, the kernel - * would not know we meant "the old fd of this number". - */ - vwk_kq_flush(vwk); - deadline = VTIM_real() - params->sess_timeout; - for (;;) { - sp = VTAILQ_FIRST(&vwk->sesshead); - if (sp == NULL) - break; - if (sp->t_open > deadline) - break; - VTAILQ_REMOVE(&vwk->sesshead, sp, list); - // XXX: not yet (void)VTCP_linger(sp->fd, 0); - SES_Delete(sp, "timeout"); - } - } -} - -/*--------------------------------------------------------------------*/ - -static void -vwk_pass(void *priv, const struct sess *sp) -{ - struct vwk *vwk; - - CAST_OBJ_NOTNULL(vwk, priv, VWK_MAGIC); - assert(sizeof sp == write(vwk->pipes[1], &sp, sizeof sp)); -} - -/*--------------------------------------------------------------------*/ - -static void * -vwk_init(void) -{ - int i; - struct vwk *vwk; - - ALLOC_OBJ(vwk, VWK_MAGIC); - AN(vwk); - - VTAILQ_INIT(&vwk->sesshead); - AZ(pipe(vwk->pipes)); - - i = fcntl(vwk->pipes[0], F_GETFL); - assert(i != -1); - i |= O_NONBLOCK; - i = fcntl(vwk->pipes[0], F_SETFL, i); - assert(i != -1); - - AZ(pthread_create(&vwk->thread, NULL, vwk_thread, vwk)); - return (vwk); -} - -/*--------------------------------------------------------------------*/ - -const struct waiter waiter_kqueue = { - .name = "kqueue", - .init = vwk_init, - .pass = vwk_pass, -}; - -#endif /* defined(HAVE_KQUEUE) */ diff --git a/bin/varnishd/cache_waiter_poll.c b/bin/varnishd/cache_waiter_poll.c deleted file mode 100644 index eb48870..0000000 --- a/bin/varnishd/cache_waiter_poll.c +++ /dev/null @@ -1,233 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - */ - -#include "config.h" - -#include -#include - -#include "cache.h" - -#include "cache_waiter.h" -#include "vtim.h" - -#define NEEV 128 - -struct vwp { - unsigned magic; -#define VWP_MAGIC 0x4b2cc735 - int pipes[2]; - pthread_t poll_thread; - struct pollfd *pollfd; - unsigned npoll; - unsigned hpoll; - - VTAILQ_HEAD(,sess) sesshead; -}; - -/*--------------------------------------------------------------------*/ - -static void -vwp_pollspace(struct vwp *vwp, unsigned fd) -{ - struct pollfd *newpollfd = vwp->pollfd; - unsigned newnpoll; - - if (fd < vwp->npoll) - return; - newnpoll = vwp->npoll; - if (newnpoll == 0) - newnpoll = 1; - while (fd >= newnpoll) - newnpoll = newnpoll * 2; - VSL(SLT_Debug, 0, "Acceptor poll space increased to %u", newnpoll); - newpollfd = realloc(newpollfd, newnpoll * sizeof *newpollfd); - XXXAN(newpollfd); - memset(newpollfd + vwp->npoll, 0, - (newnpoll - vwp->npoll) * sizeof *newpollfd); - vwp->pollfd = newpollfd; - while (vwp->npoll < newnpoll) - vwp->pollfd[vwp->npoll++].fd = -1; - assert(fd < vwp->npoll); -} - -/*--------------------------------------------------------------------*/ - -static void -vwp_poll(struct vwp *vwp, int fd) -{ - - assert(fd >= 0); - vwp_pollspace(vwp, (unsigned)fd); - assert(fd < vwp->npoll); - - if (vwp->hpoll < fd) - vwp->hpoll = fd; - - assert(vwp->pollfd[fd].fd == -1); - assert(vwp->pollfd[fd].events == 0); - assert(vwp->pollfd[fd].revents == 0); - - vwp->pollfd[fd].fd = fd; - vwp->pollfd[fd].events = POLLIN; -} - -static void -vwp_unpoll(struct vwp *vwp, int fd) -{ - - assert(fd >= 0); - assert(fd < vwp->npoll); - vwp_pollspace(vwp, (unsigned)fd); - - assert(vwp->pollfd[fd].fd == fd); - assert(vwp->pollfd[fd].events == POLLIN); - assert(vwp->pollfd[fd].revents == 0); - - vwp->pollfd[fd].fd = -1; - vwp->pollfd[fd].events = 0; -} - -/*--------------------------------------------------------------------*/ - -static void * -vwp_main(void *priv) -{ - int v, v2; - struct vwp *vwp; - struct sess *ss[NEEV], *sp, *sp2; - double deadline; - int i, j, fd; - - CAST_OBJ_NOTNULL(vwp, priv, VWP_MAGIC); - THR_SetName("cache-poll"); - - vwp_poll(vwp, vwp->pipes[0]); - - while (1) { - assert(vwp->hpoll < vwp->npoll); - while (vwp->hpoll > 0 && vwp->pollfd[vwp->hpoll].fd == -1) - vwp->hpoll--; - assert(vwp->pipes[0] <= vwp->hpoll); - assert(vwp->pollfd[vwp->pipes[0]].fd == vwp->pipes[0]); - assert(vwp->pollfd[vwp->pipes[1]].fd == -1); - v = poll(vwp->pollfd, vwp->hpoll + 1, 100); - assert(v >= 0); - deadline = VTIM_real() - params->sess_timeout; - v2 = v; - VTAILQ_FOREACH_SAFE(sp, &vwp->sesshead, list, sp2) { - if (v != 0 && v2 == 0) - break; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - fd = sp->fd; - assert(fd >= 0); - assert(fd <= vwp->hpoll); - assert(fd < vwp->npoll); - assert(vwp->pollfd[fd].fd == fd); - if (vwp->pollfd[fd].revents) { - v2--; - i = HTC_Rx(sp->htc); - if (vwp->pollfd[fd].revents != POLLIN) - VSL(SLT_Debug, fd, "Poll: %x / %d", - vwp->pollfd[fd].revents, i); - vwp->pollfd[fd].revents = 0; - VTAILQ_REMOVE(&vwp->sesshead, sp, list); - if (i == 0) { - /* Mov to front of list for speed */ - VTAILQ_INSERT_HEAD(&vwp->sesshead, sp, list); - } else { - vwp_unpoll(vwp, fd); - SES_Handle(sp, i); - } - } else if (sp->t_open <= deadline) { - VTAILQ_REMOVE(&vwp->sesshead, sp, list); - vwp_unpoll(vwp, fd); - // XXX: not yet (void)VTCP_linger(sp->fd, 0); - SES_Delete(sp, "timeout"); - } - } - if (v2 && vwp->pollfd[vwp->pipes[0]].revents) { - - if (vwp->pollfd[vwp->pipes[0]].revents != POLLIN) - VSL(SLT_Debug, 0, "pipe.revents= 0x%x", - vwp->pollfd[vwp->pipes[0]].revents); - assert(vwp->pollfd[vwp->pipes[0]].revents == POLLIN); - vwp->pollfd[vwp->pipes[0]].revents = 0; - v2--; - i = read(vwp->pipes[0], ss, sizeof ss); - assert(i >= 0); - assert(((unsigned)i % sizeof ss[0]) == 0); - for (j = 0; j * sizeof ss[0] < i; j++) { - CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); - assert(ss[j]->fd >= 0); - VTAILQ_INSERT_TAIL(&vwp->sesshead, ss[j], list); - vwp_poll(vwp, ss[j]->fd); - } - } - assert(v2 == 0); - } - NEEDLESS_RETURN(NULL); -} - -/*--------------------------------------------------------------------*/ - -static void -vwp_poll_pass(void *priv, const struct sess *sp) -{ - struct vwp *vwp; - - CAST_OBJ_NOTNULL(vwp, priv, VWP_MAGIC); - - assert(sizeof sp == write(vwp->pipes[1], &sp, sizeof sp)); -} - -/*--------------------------------------------------------------------*/ - -static void * -vwp_poll_init(void) -{ - struct vwp *vwp; - - ALLOC_OBJ(vwp, VWP_MAGIC); - AN(vwp); - VTAILQ_INIT(&vwp->sesshead); - AZ(pipe(vwp->pipes)); - vwp_pollspace(vwp, 256); - AZ(pthread_create(&vwp->poll_thread, NULL, vwp_main, vwp)); - return (vwp); -} - -/*--------------------------------------------------------------------*/ - -const struct waiter waiter_poll = { - .name = "poll", - .init = vwp_poll_init, - .pass = vwp_poll_pass, -}; diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c deleted file mode 100644 index 821ebc3..0000000 --- a/bin/varnishd/cache_waiter_ports.c +++ /dev/null @@ -1,283 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006 Varnish Software AS - * Copyright (c) 2007 OmniTI Computer Consulting, Inc. - * Copyright (c) 2007 Theo Schlossnagle - * Copyright (c) 2010 UPLEX, Nils Goroll - * All rights reserved. - * - * 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 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. - * - */ - -#include "config.h" - -#if defined(HAVE_PORT_CREATE) - -#include - -#include -#include -#include -#include - -#include "cache.h" - -#include "cache_waiter.h" -#include "vtim.h" - -#define MAX_EVENTS 256 - -struct vws { - unsigned magic; -#define VWS_MAGIC 0x0b771473 - pthread_t ports_thread; - int dport; - VTAILQ_HEAD(,sess) sesshead; -}; - -static inline void -vws_add(struct vws *vws, int fd, void *data) -{ - /* - * POLLIN should be all we need here - * - */ - AZ(port_associate(vws->dport, PORT_SOURCE_FD, fd, POLLIN, data)); -} - -static inline void -vws_del(struct vws *vws, int fd) -{ - port_dissociate(vws->dport, PORT_SOURCE_FD, fd); -} - -static inline void -vws_port_ev(struct vws *vws, port_event_t *ev) { - struct sess *sp; - if(ev->portev_source == PORT_SOURCE_USER) { - CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); - assert(sp->fd >= 0); - AZ(sp->obj); - VTAILQ_INSERT_TAIL(&vws->sesshead, sp, list); - vws_add(vws, sp->fd, sp); - } else { - int i; - assert(ev->portev_source == PORT_SOURCE_FD); - CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); - assert(sp->fd >= 0); - if(ev->portev_events & POLLERR) { - vws_del(vws, sp->fd); - VTAILQ_REMOVE(&vws->sesshead, sp, list); - SES_Delete(sp, "EOF"); - return; - } - i = HTC_Rx(sp->htc); - - if (i == 0) { - /* incomplete header, wait for more data */ - vws_add(vws, sp->fd, sp); - return; - } - - /* - * note: the original man page for port_associate(3C) states: - * - * When an event for a PORT_SOURCE_FD object is retrieved, - * the object no longer has an association with the port. - * - * This can be read along the lines of sparing the - * port_dissociate after port_getn(), but in fact, - * port_dissociate should be used - * - * Ref: http://opensolaris.org/jive/thread.jspa?threadID=129476&tstart=0 - */ - vws_del(vws, sp->fd); - VTAILQ_REMOVE(&vws->sesshead, sp, list); - - /* SES_Handle will also handle errors */ - SES_Handle(sp, i); - } - return; -} - -static void * -vws_thread(void *priv) -{ - struct sess *sp; - struct vws *vws; - - CAST_OBJ_NOTNULL(vws, priv, VWS_MAGIC); - /* - * timeouts: - * - * min_ts : Minimum timeout for port_getn - * min_t : ^ equivalent in floating point representation - * - * max_ts : Maximum timeout for port_getn - * max_t : ^ equivalent in floating point representation - * - * with (nevents == 1), we should always choose the correct port_getn - * timeout to check session timeouts, so max is just a safety measure - * (if this implementation is correct, it could be set to an "infinte" - * value) - * - * with (nevents > 1), min and max define the acceptable range for - * - additional latency of keep-alive connections and - * - additional tolerance for handling session timeouts - * - */ - static struct timespec min_ts = {0L, 100L /*ms*/ * 1000L /*us*/ * 1000L /*ns*/}; - static double min_t = 0.1; /* 100 ms*/ - static struct timespec max_ts = {1L, 0L}; /* 1 second */ - static double max_t = 1.0; /* 1 second */ - - /* XXX: These should probably go in vws ? */ - struct timespec ts; - struct timespec *timeout; - - vws->dport = port_create(); - assert(vws->dport >= 0); - - timeout = &max_ts; - - while (1) { - port_event_t ev[MAX_EVENTS]; - int nevents, ei, ret; - double now, deadline; - - /* - * XXX Do we want to scale this up dynamically to increase - * efficiency in high throughput situations? - would need to - * start with one to keep latency low at any rate - * - * Note: when increasing nevents, we must lower min_ts - * and max_ts - */ - nevents = 1; - - /* - * see disucssion in - * - https://issues.apache.org/bugzilla/show_bug.cgi?id=47645 - * - http://mail.opensolaris.org/pipermail/networking-discuss/2009-August/011979.html - * - * comment from apr/poll/unix/port.c : - * - * This confusing API can return an event at the same time - * that it reports EINTR or ETIME. - * - */ - - ret = port_getn(vws->dport, ev, MAX_EVENTS, &nevents, timeout); - - if (ret < 0) - assert((errno == EINTR) || (errno == ETIME)); - - for (ei = 0; ei < nevents; ei++) - vws_port_ev(vws, ev + ei); - - /* check for timeouts */ - now = VTIM_real(); - deadline = now - params->sess_timeout; - - /* - * This loop assumes that the oldest sessions are always at the - * beginning of the list (which is the case if we guarantee to - * enqueue at the tail only - * - */ - - for (;;) { - sp = VTAILQ_FIRST(&vws->sesshead); - if (sp == NULL) - break; - if (sp->t_open > deadline) { - break; - } - VTAILQ_REMOVE(&vws->sesshead, sp, list); - if(sp->fd != -1) { - vws_del(vws, sp->fd); - } - SES_Delete(sp, "timeout"); - } - - /* - * Calculate the timeout for the next get_portn - */ - - if (sp) { - double tmo = (sp->t_open + params->sess_timeout) - now; - - /* we should have removed all sps whose timeout has passed */ - assert(tmo > 0.0); - - if (tmo < min_t) { - timeout = &min_ts; - } else if (tmo > max_t) { - timeout = &max_ts; - } else { - ts = VTIM_timespec(tmo); - timeout = &ts; - } - } else { - timeout = &max_ts; - } - } -} - -/*--------------------------------------------------------------------*/ - -static void -vws_pass(void *priv, const struct sess *sp) -{ - int r; - struct vws *vws; - - CAST_OBJ_NOTNULL(vws, priv, VWS_MAGIC); - while((r = port_send(vws->dport, 0, TRUST_ME(sp))) == -1 && - errno == EAGAIN); - AZ(r); -} - -/*--------------------------------------------------------------------*/ - -static void * -vws_init(void) -{ - struct vws *vws; - - ALLOC_OBJ(vws, VWS_MAGIC); - AN(vws); - VTAILQ_INIT(&vws->sesshead); - AZ(pthread_create(&vws->ports_thread, NULL, vws_thread, vws)); - return (vws); -} - -/*--------------------------------------------------------------------*/ - -const struct waiter waiter_ports = { - .name = "ports", - .init = vws_init, - .pass = vws_pass -}; - -#endif /* defined(HAVE_PORT_CREATE) */ diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index 86d4ad0..357d280 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -17,6 +17,7 @@ flexelint \ -DVARNISH_STATE_DIR=\"foo\" \ *.c \ storage/*.c \ + waiter/*.c \ ../../lib/libvarnish/*.c \ ../../lib/libvarnishcompat/execinfo.c \ ../../lib/libvcl/*.c \ diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c index 9ded195..43749b6 100644 --- a/bin/varnishd/mgt_param.c +++ b/bin/varnishd/mgt_param.c @@ -39,7 +39,7 @@ #include "mgt.h" -#include "cache_waiter.h" +#include "waiter/cache_waiter.h" #include "heritage.h" #include "vav.h" #include "vcli.h" diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c new file mode 100644 index 0000000..e6654fd --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter.c @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#include "config.h" + +#include "cache.h" + +#include "waiter/cache_waiter.h" +#include "vcli.h" +#include "vcli_priv.h" + +static const struct waiter * const vca_waiters[] = { + #if defined(HAVE_KQUEUE) + &waiter_kqueue, + #endif + #if defined(HAVE_EPOLL_CTL) + &waiter_epoll, + #endif + #if defined(HAVE_PORT_CREATE) + &waiter_ports, + #endif + &waiter_poll, + NULL, +}; + +struct waiter const * waiter; + +const char * +WAIT_GetName(void) +{ + + if (waiter != NULL) + return (waiter->name); + else + return ("no_waiter"); +} + +void +WAIT_tweak_waiter(struct cli *cli, const char *arg) +{ + int i; + + ASSERT_MGT(); + + if (arg == NULL) { + if (waiter == NULL) + VCLI_Out(cli, "default"); + else + VCLI_Out(cli, "%s", waiter->name); + + VCLI_Out(cli, " ("); + for (i = 0; vca_waiters[i] != NULL; i++) + VCLI_Out(cli, "%s%s", i == 0 ? "" : ", ", + vca_waiters[i]->name); + VCLI_Out(cli, ")"); + return; + } + if (!strcmp(arg, "default")) { + waiter = NULL; + return; + } + for (i = 0; vca_waiters[i]; i++) { + if (!strcmp(arg, vca_waiters[i]->name)) { + waiter = vca_waiters[i]; + return; + } + } + VCLI_Out(cli, "Unknown waiter"); + VCLI_SetResult(cli, CLIS_PARAM); +} + +void +WAIT_Init(void) +{ + + if (waiter == NULL) + waiter = vca_waiters[0]; + + AN(waiter); + AN(waiter->name); + AN(waiter->init); + AN(waiter->pass); +} diff --git a/bin/varnishd/waiter/cache_waiter.h b/bin/varnishd/waiter/cache_waiter.h new file mode 100644 index 0000000..28bc39d --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + */ + +struct sess; + +typedef void* waiter_init_f(void); +typedef void waiter_pass_f(void *priv, const struct sess *); + +struct waiter { + const char *name; + waiter_init_f *init; + waiter_pass_f *pass; +}; + +extern struct waiter const * waiter; + +#if defined(HAVE_EPOLL_CTL) +extern const struct waiter waiter_epoll; +#endif + +#if defined(HAVE_KQUEUE) +extern const struct waiter waiter_kqueue; +#endif + +#if defined(HAVE_PORT_CREATE) +extern const struct waiter waiter_ports; +#endif + + +/* cache_session.c */ +void SES_Handle(struct sess *sp, int status); + +/* cache_waiter.c */ +extern const struct waiter waiter_poll; +const char *WAIT_GetName(void); +void WAIT_tweak_waiter(struct cli *cli, const char *arg); +void WAIT_Init(void); diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c new file mode 100644 index 0000000..e700676 --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter_epoll.c @@ -0,0 +1,276 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software AS + * All rights reserved. + * + * Author: Rogerio Carvalho Schneider + * + * 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. + * + * XXX: We need to pass sessions back into the event engine when they are + * reused. Not sure what the most efficient way is for that. For now + * write the session pointer to a pipe which the event engine monitors. + */ + +#include "config.h" + +#if defined(HAVE_EPOLL_CTL) + +#include + +#include +#include + +#include "cache.h" + +#include "waiter/cache_waiter.h" +#include "vtim.h" + +#ifndef EPOLLRDHUP +# define EPOLLRDHUP 0 +#endif + +#define NEEV 100 + +struct vwe { + unsigned magic; +#define VWE_MAGIC 0x6bd73424 + + pthread_t epoll_thread; + pthread_t timer_thread; + int epfd; + + VTAILQ_HEAD(,sess) sesshead; + int pipes[2]; + int timer_pipes[2]; +}; + +static void +vwe_modadd(struct vwe *vwe, int fd, void *data, short arm) +{ + + /* XXX: EPOLLET (edge triggered) can cause rather Bad Things to + * XXX: happen: If NEEV+1 threads get stuck in write(), all threads + * XXX: will hang. See #644. + */ + assert(fd >= 0); + if (data == vwe->pipes || data == vwe->timer_pipes) { + struct epoll_event ev = { + EPOLLIN | EPOLLPRI , { data } + }; + AZ(epoll_ctl(vwe->epfd, arm, fd, &ev)); + } else { + struct sess *sp = (struct sess *)data; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + sp->ev.data.ptr = data; + sp->ev.events = EPOLLIN | EPOLLPRI | EPOLLONESHOT | EPOLLRDHUP; + AZ(epoll_ctl(vwe->epfd, arm, fd, &sp->ev)); + } +} + +static void +vwe_cond_modadd(struct vwe *vwe, int fd, void *data) +{ + struct sess *sp = (struct sess *)data; + + assert(fd >= 0); + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + if (sp->ev.data.ptr) + AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_MOD, fd, &sp->ev)); + else { + sp->ev.data.ptr = data; + sp->ev.events = EPOLLIN | EPOLLPRI | EPOLLONESHOT | EPOLLRDHUP; + AZ(epoll_ctl(vwe->epfd, EPOLL_CTL_ADD, fd, &sp->ev)); + } +} + +static void +vwe_eev(struct vwe *vwe, const struct epoll_event *ep) +{ + struct sess *ss[NEEV], *sp; + int i, j; + + AN(ep->data.ptr); + if (ep->data.ptr == vwe->pipes) { + if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { + j = 0; + i = read(vwe->pipes[0], ss, sizeof ss); + if (i == -1 && errno == EAGAIN) + return; + while (i >= sizeof ss[0]) { + CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); + assert(ss[j]->fd >= 0); + AZ(ss[j]->obj); + VTAILQ_INSERT_TAIL(&vwe->sesshead, ss[j], list); + vwe_cond_modadd(vwe, ss[j]->fd, ss[j]); + j++; + i -= sizeof ss[0]; + } + assert(i == 0); + } + } else { + CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC); + if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { + i = HTC_Rx(sp->htc); + if (i == 0) { + vwe_modadd(vwe, sp->fd, sp, EPOLL_CTL_MOD); + return; /* more needed */ + } + VTAILQ_REMOVE(&vwe->sesshead, sp, list); + SES_Handle(sp, i); + } else if (ep->events & EPOLLERR) { + VTAILQ_REMOVE(&vwe->sesshead, sp, list); + SES_Delete(sp, "ERR"); + } else if (ep->events & EPOLLHUP) { + VTAILQ_REMOVE(&vwe->sesshead, sp, list); + SES_Delete(sp, "HUP"); + } else if (ep->events & EPOLLRDHUP) { + VTAILQ_REMOVE(&vwe->sesshead, sp, list); + SES_Delete(sp, "RHUP"); + } + } +} + +/*--------------------------------------------------------------------*/ + +static void * +vwe_thread(void *priv) +{ + struct epoll_event ev[NEEV], *ep; + struct sess *sp; + char junk; + double deadline; + int dotimer, i, n; + struct vwe *vwe; + + CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); + + THR_SetName("cache-epoll"); + + vwe->epfd = epoll_create(1); + assert(vwe->epfd >= 0); + + vwe_modadd(vwe, vwe->pipes[0], vwe->pipes, EPOLL_CTL_ADD); + vwe_modadd(vwe, vwe->timer_pipes[0], vwe->timer_pipes, EPOLL_CTL_ADD); + + while (1) { + dotimer = 0; + n = epoll_wait(vwe->epfd, ev, NEEV, -1); + for (ep = ev, i = 0; i < n; i++, ep++) { + if (ep->data.ptr == vwe->timer_pipes && + (ep->events == EPOLLIN || ep->events == EPOLLPRI)) + { + assert(read(vwe->timer_pipes[0], &junk, 1)); + dotimer = 1; + } else + vwe_eev(vwe, ep); + } + if (!dotimer) + continue; + + /* check for timeouts */ + deadline = VTIM_real() - params->sess_timeout; + for (;;) { + sp = VTAILQ_FIRST(&vwe->sesshead); + if (sp == NULL) + break; + if (sp->t_open > deadline) + break; + VTAILQ_REMOVE(&vwe->sesshead, sp, list); + // XXX: not yet VTCP_linger(sp->fd, 0); + SES_Delete(sp, "timeout"); + } + } + return NULL; +} + +/*--------------------------------------------------------------------*/ + +static void * +vwe_sess_timeout_ticker(void *priv) +{ + char ticker = 'R'; + struct vwe *vwe; + + CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); + THR_SetName("cache-epoll-sess_timeout_ticker"); + + while (1) { + /* ticking */ + assert(write(vwe->timer_pipes[1], &ticker, 1)); + VTIM_sleep(100 * 1e-3); + } + return NULL; +} + +/*--------------------------------------------------------------------*/ + +static void +vwe_pass(void *priv, const struct sess *sp) +{ + struct vwe *vwe; + + CAST_OBJ_NOTNULL(vwe, priv, VWE_MAGIC); + assert(sizeof sp == write(vwe->pipes[1], &sp, sizeof sp)); +} + +/*--------------------------------------------------------------------*/ + +static void * +vwe_init(void) +{ + int i; + struct vwe *vwe; + + ALLOC_OBJ(vwe, VWE_MAGIC); + AN(vwe); + VTAILQ_INIT(&vwe->sesshead); + AZ(pipe(vwe->pipes)); + AZ(pipe(vwe->timer_pipes)); + + i = fcntl(vwe->pipes[0], F_GETFL); + assert(i != -1); + i |= O_NONBLOCK; + i = fcntl(vwe->pipes[0], F_SETFL, i); + assert(i != -1); + + i = fcntl(vwe->timer_pipes[0], F_GETFL); + assert(i != -1); + i |= O_NONBLOCK; + i = fcntl(vwe->timer_pipes[0], F_SETFL, i); + assert(i != -1); + + AZ(pthread_create(&vwe->timer_thread, + NULL, vwe_sess_timeout_ticker, vwe)); + AZ(pthread_create(&vwe->epoll_thread, NULL, vwe_thread, vwe)); + return(vwe); +} + +/*--------------------------------------------------------------------*/ + +const struct waiter waiter_epoll = { + .name = "epoll", + .init = vwe_init, + .pass = vwe_pass, +}; + +#endif /* defined(HAVE_EPOLL_CTL) */ diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c new file mode 100644 index 0000000..b300fae --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter_kqueue.c @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + * XXX: We need to pass sessions back into the event engine when they are + * reused. Not sure what the most efficient way is for that. For now + * write the session pointer to a pipe which the event engine monitors. + */ + +#include "config.h" + +#if defined(HAVE_KQUEUE) + +#include +#include + +#include +#include +#include + +#include "cache.h" + +#include "waiter/cache_waiter.h" +#include "vtim.h" + +#define NKEV 100 + +struct vwk { + unsigned magic; +#define VWK_MAGIC 0x1cc2acc2 + pthread_t thread; + int pipes[2]; + int kq; + struct kevent ki[NKEV]; + unsigned nki; + VTAILQ_HEAD(,sess) sesshead; +}; + +/*--------------------------------------------------------------------*/ + +static void +vwk_kq_flush(struct vwk *vwk) +{ + int i; + + if (vwk->nki == 0) + return; + i = kevent(vwk->kq, vwk->ki, vwk->nki, NULL, 0, NULL); + assert(i == 0); + vwk->nki = 0; +} + +static void +vwk_kq_sess(struct vwk *vwk, struct sess *sp, short arm) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + assert(sp->fd >= 0); + DSL(0x04, SLT_Debug, sp->vsl_id, "KQ: EV_SET sp %p arm %x", sp, arm); + EV_SET(&vwk->ki[vwk->nki], sp->fd, EVFILT_READ, arm, 0, 0, sp); + if (++vwk->nki == NKEV) + vwk_kq_flush(vwk); +} + +static void +vwk_kev(struct vwk *vwk, const struct kevent *kp) +{ + int i, j; + struct sess *sp; + struct sess *ss[NKEV]; + + AN(kp->udata); + if (kp->udata == vwk->pipes) { + j = 0; + i = read(vwk->pipes[0], ss, sizeof ss); + if (i == -1 && errno == EAGAIN) + return; + while (i >= sizeof ss[0]) { + CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); + assert(ss[j]->fd >= 0); + AZ(ss[j]->obj); + VTAILQ_INSERT_TAIL(&vwk->sesshead, ss[j], list); + vwk_kq_sess(vwk, ss[j], EV_ADD | EV_ONESHOT); + j++; + i -= sizeof ss[0]; + } + assert(i == 0); + return; + } + CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); + DSL(0x04, SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", + sp, (unsigned long)kp->data, kp->flags, + (kp->flags & EV_EOF) ? " EOF" : ""); + + assert((sp->vsl_id & VSL_IDENTMASK) == kp->ident); + assert((sp->vsl_id & VSL_IDENTMASK) == sp->fd); + if (kp->data > 0) { + i = HTC_Rx(sp->htc); + if (i == 0) { + vwk_kq_sess(vwk, sp, EV_ADD | EV_ONESHOT); + return; /* more needed */ + } + VTAILQ_REMOVE(&vwk->sesshead, sp, list); + SES_Handle(sp, i); + return; + } else if (kp->flags & EV_EOF) { + VTAILQ_REMOVE(&vwk->sesshead, sp, list); + SES_Delete(sp, "EOF"); + return; + } else { + VSL(SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", + sp, (unsigned long)kp->data, kp->flags, + (kp->flags & EV_EOF) ? " EOF" : ""); + } +} + +/*--------------------------------------------------------------------*/ + +static void * +vwk_thread(void *priv) +{ + struct vwk *vwk; + struct kevent ke[NKEV], *kp; + int j, n, dotimer; + double deadline; + struct sess *sp; + + CAST_OBJ_NOTNULL(vwk, priv, VWK_MAGIC); + THR_SetName("cache-kqueue"); + + vwk->kq = kqueue(); + assert(vwk->kq >= 0); + + j = 0; + EV_SET(&ke[j], 0, EVFILT_TIMER, EV_ADD, 0, 100, NULL); + j++; + EV_SET(&ke[j], vwk->pipes[0], EVFILT_READ, EV_ADD, 0, 0, vwk->pipes); + j++; + AZ(kevent(vwk->kq, ke, j, NULL, 0, NULL)); + + vwk->nki = 0; + while (1) { + dotimer = 0; + n = kevent(vwk->kq, vwk->ki, vwk->nki, ke, NKEV, NULL); + assert(n >= 1 && n <= NKEV); + vwk->nki = 0; + for (kp = ke, j = 0; j < n; j++, kp++) { + if (kp->filter == EVFILT_TIMER) { + dotimer = 1; + continue; + } + assert(kp->filter == EVFILT_READ); + vwk_kev(vwk, kp); + } + if (!dotimer) + continue; + /* + * Make sure we have no pending changes for the fd's + * we are about to close, in case the accept(2) in the + * other thread creates new fd's betwen our close and + * the kevent(2) at the top of this loop, the kernel + * would not know we meant "the old fd of this number". + */ + vwk_kq_flush(vwk); + deadline = VTIM_real() - params->sess_timeout; + for (;;) { + sp = VTAILQ_FIRST(&vwk->sesshead); + if (sp == NULL) + break; + if (sp->t_open > deadline) + break; + VTAILQ_REMOVE(&vwk->sesshead, sp, list); + // XXX: not yet (void)VTCP_linger(sp->fd, 0); + SES_Delete(sp, "timeout"); + } + } +} + +/*--------------------------------------------------------------------*/ + +static void +vwk_pass(void *priv, const struct sess *sp) +{ + struct vwk *vwk; + + CAST_OBJ_NOTNULL(vwk, priv, VWK_MAGIC); + assert(sizeof sp == write(vwk->pipes[1], &sp, sizeof sp)); +} + +/*--------------------------------------------------------------------*/ + +static void * +vwk_init(void) +{ + int i; + struct vwk *vwk; + + ALLOC_OBJ(vwk, VWK_MAGIC); + AN(vwk); + + VTAILQ_INIT(&vwk->sesshead); + AZ(pipe(vwk->pipes)); + + i = fcntl(vwk->pipes[0], F_GETFL); + assert(i != -1); + i |= O_NONBLOCK; + i = fcntl(vwk->pipes[0], F_SETFL, i); + assert(i != -1); + + AZ(pthread_create(&vwk->thread, NULL, vwk_thread, vwk)); + return (vwk); +} + +/*--------------------------------------------------------------------*/ + +const struct waiter waiter_kqueue = { + .name = "kqueue", + .init = vwk_init, + .pass = vwk_pass, +}; + +#endif /* defined(HAVE_KQUEUE) */ diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c new file mode 100644 index 0000000..2617365 --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter_poll.c @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + */ + +#include "config.h" + +#include +#include + +#include "cache.h" + +#include "waiter/cache_waiter.h" +#include "vtim.h" + +#define NEEV 128 + +struct vwp { + unsigned magic; +#define VWP_MAGIC 0x4b2cc735 + int pipes[2]; + pthread_t poll_thread; + struct pollfd *pollfd; + unsigned npoll; + unsigned hpoll; + + VTAILQ_HEAD(,sess) sesshead; +}; + +/*--------------------------------------------------------------------*/ + +static void +vwp_pollspace(struct vwp *vwp, unsigned fd) +{ + struct pollfd *newpollfd = vwp->pollfd; + unsigned newnpoll; + + if (fd < vwp->npoll) + return; + newnpoll = vwp->npoll; + if (newnpoll == 0) + newnpoll = 1; + while (fd >= newnpoll) + newnpoll = newnpoll * 2; + VSL(SLT_Debug, 0, "Acceptor poll space increased to %u", newnpoll); + newpollfd = realloc(newpollfd, newnpoll * sizeof *newpollfd); + XXXAN(newpollfd); + memset(newpollfd + vwp->npoll, 0, + (newnpoll - vwp->npoll) * sizeof *newpollfd); + vwp->pollfd = newpollfd; + while (vwp->npoll < newnpoll) + vwp->pollfd[vwp->npoll++].fd = -1; + assert(fd < vwp->npoll); +} + +/*--------------------------------------------------------------------*/ + +static void +vwp_poll(struct vwp *vwp, int fd) +{ + + assert(fd >= 0); + vwp_pollspace(vwp, (unsigned)fd); + assert(fd < vwp->npoll); + + if (vwp->hpoll < fd) + vwp->hpoll = fd; + + assert(vwp->pollfd[fd].fd == -1); + assert(vwp->pollfd[fd].events == 0); + assert(vwp->pollfd[fd].revents == 0); + + vwp->pollfd[fd].fd = fd; + vwp->pollfd[fd].events = POLLIN; +} + +static void +vwp_unpoll(struct vwp *vwp, int fd) +{ + + assert(fd >= 0); + assert(fd < vwp->npoll); + vwp_pollspace(vwp, (unsigned)fd); + + assert(vwp->pollfd[fd].fd == fd); + assert(vwp->pollfd[fd].events == POLLIN); + assert(vwp->pollfd[fd].revents == 0); + + vwp->pollfd[fd].fd = -1; + vwp->pollfd[fd].events = 0; +} + +/*--------------------------------------------------------------------*/ + +static void * +vwp_main(void *priv) +{ + int v, v2; + struct vwp *vwp; + struct sess *ss[NEEV], *sp, *sp2; + double deadline; + int i, j, fd; + + CAST_OBJ_NOTNULL(vwp, priv, VWP_MAGIC); + THR_SetName("cache-poll"); + + vwp_poll(vwp, vwp->pipes[0]); + + while (1) { + assert(vwp->hpoll < vwp->npoll); + while (vwp->hpoll > 0 && vwp->pollfd[vwp->hpoll].fd == -1) + vwp->hpoll--; + assert(vwp->pipes[0] <= vwp->hpoll); + assert(vwp->pollfd[vwp->pipes[0]].fd == vwp->pipes[0]); + assert(vwp->pollfd[vwp->pipes[1]].fd == -1); + v = poll(vwp->pollfd, vwp->hpoll + 1, 100); + assert(v >= 0); + deadline = VTIM_real() - params->sess_timeout; + v2 = v; + VTAILQ_FOREACH_SAFE(sp, &vwp->sesshead, list, sp2) { + if (v != 0 && v2 == 0) + break; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + fd = sp->fd; + assert(fd >= 0); + assert(fd <= vwp->hpoll); + assert(fd < vwp->npoll); + assert(vwp->pollfd[fd].fd == fd); + if (vwp->pollfd[fd].revents) { + v2--; + i = HTC_Rx(sp->htc); + if (vwp->pollfd[fd].revents != POLLIN) + VSL(SLT_Debug, fd, "Poll: %x / %d", + vwp->pollfd[fd].revents, i); + vwp->pollfd[fd].revents = 0; + VTAILQ_REMOVE(&vwp->sesshead, sp, list); + if (i == 0) { + /* Mov to front of list for speed */ + VTAILQ_INSERT_HEAD(&vwp->sesshead, sp, list); + } else { + vwp_unpoll(vwp, fd); + SES_Handle(sp, i); + } + } else if (sp->t_open <= deadline) { + VTAILQ_REMOVE(&vwp->sesshead, sp, list); + vwp_unpoll(vwp, fd); + // XXX: not yet (void)VTCP_linger(sp->fd, 0); + SES_Delete(sp, "timeout"); + } + } + if (v2 && vwp->pollfd[vwp->pipes[0]].revents) { + + if (vwp->pollfd[vwp->pipes[0]].revents != POLLIN) + VSL(SLT_Debug, 0, "pipe.revents= 0x%x", + vwp->pollfd[vwp->pipes[0]].revents); + assert(vwp->pollfd[vwp->pipes[0]].revents == POLLIN); + vwp->pollfd[vwp->pipes[0]].revents = 0; + v2--; + i = read(vwp->pipes[0], ss, sizeof ss); + assert(i >= 0); + assert(((unsigned)i % sizeof ss[0]) == 0); + for (j = 0; j * sizeof ss[0] < i; j++) { + CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); + assert(ss[j]->fd >= 0); + VTAILQ_INSERT_TAIL(&vwp->sesshead, ss[j], list); + vwp_poll(vwp, ss[j]->fd); + } + } + assert(v2 == 0); + } + NEEDLESS_RETURN(NULL); +} + +/*--------------------------------------------------------------------*/ + +static void +vwp_poll_pass(void *priv, const struct sess *sp) +{ + struct vwp *vwp; + + CAST_OBJ_NOTNULL(vwp, priv, VWP_MAGIC); + + assert(sizeof sp == write(vwp->pipes[1], &sp, sizeof sp)); +} + +/*--------------------------------------------------------------------*/ + +static void * +vwp_poll_init(void) +{ + struct vwp *vwp; + + ALLOC_OBJ(vwp, VWP_MAGIC); + AN(vwp); + VTAILQ_INIT(&vwp->sesshead); + AZ(pipe(vwp->pipes)); + vwp_pollspace(vwp, 256); + AZ(pthread_create(&vwp->poll_thread, NULL, vwp_main, vwp)); + return (vwp); +} + +/*--------------------------------------------------------------------*/ + +const struct waiter waiter_poll = { + .name = "poll", + .init = vwp_poll_init, + .pass = vwp_poll_pass, +}; diff --git a/bin/varnishd/waiter/cache_waiter_ports.c b/bin/varnishd/waiter/cache_waiter_ports.c new file mode 100644 index 0000000..022131b --- /dev/null +++ b/bin/varnishd/waiter/cache_waiter_ports.c @@ -0,0 +1,283 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006 Varnish Software AS + * Copyright (c) 2007 OmniTI Computer Consulting, Inc. + * Copyright (c) 2007 Theo Schlossnagle + * Copyright (c) 2010 UPLEX, Nils Goroll + * All rights reserved. + * + * 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 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. + * + */ + +#include "config.h" + +#if defined(HAVE_PORT_CREATE) + +#include + +#include +#include +#include +#include + +#include "cache.h" + +#include "waiter/cache_waiter.h" +#include "vtim.h" + +#define MAX_EVENTS 256 + +struct vws { + unsigned magic; +#define VWS_MAGIC 0x0b771473 + pthread_t ports_thread; + int dport; + VTAILQ_HEAD(,sess) sesshead; +}; + +static inline void +vws_add(struct vws *vws, int fd, void *data) +{ + /* + * POLLIN should be all we need here + * + */ + AZ(port_associate(vws->dport, PORT_SOURCE_FD, fd, POLLIN, data)); +} + +static inline void +vws_del(struct vws *vws, int fd) +{ + port_dissociate(vws->dport, PORT_SOURCE_FD, fd); +} + +static inline void +vws_port_ev(struct vws *vws, port_event_t *ev) { + struct sess *sp; + if(ev->portev_source == PORT_SOURCE_USER) { + CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); + assert(sp->fd >= 0); + AZ(sp->obj); + VTAILQ_INSERT_TAIL(&vws->sesshead, sp, list); + vws_add(vws, sp->fd, sp); + } else { + int i; + assert(ev->portev_source == PORT_SOURCE_FD); + CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); + assert(sp->fd >= 0); + if(ev->portev_events & POLLERR) { + vws_del(vws, sp->fd); + VTAILQ_REMOVE(&vws->sesshead, sp, list); + SES_Delete(sp, "EOF"); + return; + } + i = HTC_Rx(sp->htc); + + if (i == 0) { + /* incomplete header, wait for more data */ + vws_add(vws, sp->fd, sp); + return; + } + + /* + * note: the original man page for port_associate(3C) states: + * + * When an event for a PORT_SOURCE_FD object is retrieved, + * the object no longer has an association with the port. + * + * This can be read along the lines of sparing the + * port_dissociate after port_getn(), but in fact, + * port_dissociate should be used + * + * Ref: http://opensolaris.org/jive/thread.jspa?threadID=129476&tstart=0 + */ + vws_del(vws, sp->fd); + VTAILQ_REMOVE(&vws->sesshead, sp, list); + + /* SES_Handle will also handle errors */ + SES_Handle(sp, i); + } + return; +} + +static void * +vws_thread(void *priv) +{ + struct sess *sp; + struct vws *vws; + + CAST_OBJ_NOTNULL(vws, priv, VWS_MAGIC); + /* + * timeouts: + * + * min_ts : Minimum timeout for port_getn + * min_t : ^ equivalent in floating point representation + * + * max_ts : Maximum timeout for port_getn + * max_t : ^ equivalent in floating point representation + * + * with (nevents == 1), we should always choose the correct port_getn + * timeout to check session timeouts, so max is just a safety measure + * (if this implementation is correct, it could be set to an "infinte" + * value) + * + * with (nevents > 1), min and max define the acceptable range for + * - additional latency of keep-alive connections and + * - additional tolerance for handling session timeouts + * + */ + static struct timespec min_ts = {0L, 100L /*ms*/ * 1000L /*us*/ * 1000L /*ns*/}; + static double min_t = 0.1; /* 100 ms*/ + static struct timespec max_ts = {1L, 0L}; /* 1 second */ + static double max_t = 1.0; /* 1 second */ + + /* XXX: These should probably go in vws ? */ + struct timespec ts; + struct timespec *timeout; + + vws->dport = port_create(); + assert(vws->dport >= 0); + + timeout = &max_ts; + + while (1) { + port_event_t ev[MAX_EVENTS]; + int nevents, ei, ret; + double now, deadline; + + /* + * XXX Do we want to scale this up dynamically to increase + * efficiency in high throughput situations? - would need to + * start with one to keep latency low at any rate + * + * Note: when increasing nevents, we must lower min_ts + * and max_ts + */ + nevents = 1; + + /* + * see disucssion in + * - https://issues.apache.org/bugzilla/show_bug.cgi?id=47645 + * - http://mail.opensolaris.org/pipermail/networking-discuss/2009-August/011979.html + * + * comment from apr/poll/unix/port.c : + * + * This confusing API can return an event at the same time + * that it reports EINTR or ETIME. + * + */ + + ret = port_getn(vws->dport, ev, MAX_EVENTS, &nevents, timeout); + + if (ret < 0) + assert((errno == EINTR) || (errno == ETIME)); + + for (ei = 0; ei < nevents; ei++) + vws_port_ev(vws, ev + ei); + + /* check for timeouts */ + now = VTIM_real(); + deadline = now - params->sess_timeout; + + /* + * This loop assumes that the oldest sessions are always at the + * beginning of the list (which is the case if we guarantee to + * enqueue at the tail only + * + */ + + for (;;) { + sp = VTAILQ_FIRST(&vws->sesshead); + if (sp == NULL) + break; + if (sp->t_open > deadline) { + break; + } + VTAILQ_REMOVE(&vws->sesshead, sp, list); + if(sp->fd != -1) { + vws_del(vws, sp->fd); + } + SES_Delete(sp, "timeout"); + } + + /* + * Calculate the timeout for the next get_portn + */ + + if (sp) { + double tmo = (sp->t_open + params->sess_timeout) - now; + + /* we should have removed all sps whose timeout has passed */ + assert(tmo > 0.0); + + if (tmo < min_t) { + timeout = &min_ts; + } else if (tmo > max_t) { + timeout = &max_ts; + } else { + ts = VTIM_timespec(tmo); + timeout = &ts; + } + } else { + timeout = &max_ts; + } + } +} + +/*--------------------------------------------------------------------*/ + +static void +vws_pass(void *priv, const struct sess *sp) +{ + int r; + struct vws *vws; + + CAST_OBJ_NOTNULL(vws, priv, VWS_MAGIC); + while((r = port_send(vws->dport, 0, TRUST_ME(sp))) == -1 && + errno == EAGAIN); + AZ(r); +} + +/*--------------------------------------------------------------------*/ + +static void * +vws_init(void) +{ + struct vws *vws; + + ALLOC_OBJ(vws, VWS_MAGIC); + AN(vws); + VTAILQ_INIT(&vws->sesshead); + AZ(pthread_create(&vws->ports_thread, NULL, vws_thread, vws)); + return (vws); +} + +/*--------------------------------------------------------------------*/ + +const struct waiter waiter_ports = { + .name = "ports", + .init = vws_init, + .pass = vws_pass +}; + +#endif /* defined(HAVE_PORT_CREATE) */ From phk at varnish-cache.org Wed Oct 12 17:09:25 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 12 Oct 2011 19:09:25 +0200 Subject: [master] 18edda6 Move the hashing implementations into a subdirectory where VMODs won't see them. Message-ID: commit 18edda6b2925d86115bd5e2488190f0f91a39d41 Author: Poul-Henning Kamp Date: Wed Oct 12 17:08:56 2011 +0000 Move the hashing implementations into a subdirectory where VMODs won't see them. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index cdec084..499cb6c 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -52,9 +52,9 @@ varnishd_SOURCES = \ cache_wrk.c \ cache_wrw.c \ cache_ws.c \ - hash_classic.c \ - hash_critbit.c \ - hash_simple_list.c \ + hash/hash_classic.c \ + hash/hash_critbit.c \ + hash/hash_simple_list.c \ mgt_child.c \ mgt_cli.c \ mgt_param.c \ @@ -84,7 +84,7 @@ noinst_HEADERS = \ waiter/cache_waiter.h \ common.h \ default_vcl.h \ - hash_slinger.h \ + hash/hash_slinger.h \ heritage.h \ mgt.h \ mgt_cli.h \ diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index d556ace..736cbf7 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -67,7 +67,7 @@ #include "cache.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vcli.h" #include "vcli_priv.h" #include "vend.h" diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 1eb249e..0a81925 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -64,7 +64,7 @@ DOT acceptor -> start [style=bold,color=green] #include "cache.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vcl.h" #include "vcli_priv.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_cli.c b/bin/varnishd/cache_cli.c index 01da3f2..30a12e3 100644 --- a/bin/varnishd/cache_cli.c +++ b/bin/varnishd/cache_cli.c @@ -41,7 +41,7 @@ #include "cache.h" #include "cache_backend.h" // struct vbc -#include "hash_slinger.h" // objhead +#include "hash/hash_slinger.h" // struct objhead #include "vcli.h" #include "vcli_common.h" #include "vcli_priv.h" diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index f9dcdd1..601025c 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -56,7 +56,7 @@ #include "cache.h" #include "binary_heap.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vtim.h" static pthread_t exp_thread; diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c index 14c5e7c..ecce40d 100644 --- a/bin/varnishd/cache_hash.c +++ b/bin/varnishd/cache_hash.c @@ -58,7 +58,7 @@ #include "cache.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vav.h" #include "vsha256.h" diff --git a/bin/varnishd/cache_main.c b/bin/varnishd/cache_main.c index 2d00ee2..8293d38 100644 --- a/bin/varnishd/cache_main.c +++ b/bin/varnishd/cache_main.c @@ -35,7 +35,7 @@ #include "cache.h" #include "waiter/cache_waiter.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" /*-------------------------------------------------------------------- * Per thread storage for the session currently being processed by diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 55ad333..141a0c7 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -48,7 +48,6 @@ #include "cache.h" #include "waiter/cache_waiter.h" -#include "hash_slinger.h" #include "vtcp.h" #include "vtim.h" @@ -262,9 +261,7 @@ Pool_Work_Thread(void *priv, struct worker *w) AZ(w->sp->wrk); THR_SetSession(w->sp); w->sp->wrk = w; - CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); CNT_Session(w->sp); - CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); THR_SetSession(NULL); w->sp = NULL; diff --git a/bin/varnishd/cache_vrt.c b/bin/varnishd/cache_vrt.c index 2302b86..16258ec 100644 --- a/bin/varnishd/cache_vrt.c +++ b/bin/varnishd/cache_vrt.c @@ -40,7 +40,7 @@ #include "cache.h" #include "cache_backend.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vav.h" #include "vcl.h" #include "vrt.h" diff --git a/bin/varnishd/cache_wrk.c b/bin/varnishd/cache_wrk.c index 1032691..e416eb9 100644 --- a/bin/varnishd/cache_wrk.c +++ b/bin/varnishd/cache_wrk.c @@ -36,7 +36,7 @@ #include "cache.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vsha256.h" static struct lock wstat_mtx; diff --git a/bin/varnishd/hash/hash_classic.c b/bin/varnishd/hash/hash_classic.c new file mode 100644 index 0000000..6b1d589 --- /dev/null +++ b/bin/varnishd/hash/hash_classic.c @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + * A classic bucketed hash + */ + +#include "config.h" + +#include +#include + +#include "cache.h" + +#include "hash/hash_slinger.h" + +/*--------------------------------------------------------------------*/ + +struct hcl_hd { + unsigned magic; +#define HCL_HEAD_MAGIC 0x0f327016 + VTAILQ_HEAD(, objhead) head; + struct lock mtx; +}; + +static unsigned hcl_nhash = 16383; +static struct hcl_hd *hcl_head; + +/*-------------------------------------------------------------------- + * The ->init method allows the management process to pass arguments + */ + +static void +hcl_init(int ac, char * const *av) +{ + int i; + unsigned u; + + if (ac == 0) + return; + if (ac > 1) + ARGV_ERR("(-hclassic) too many arguments\n"); + i = sscanf(av[0], "%u", &u); + if (i <= 0 || u == 0) + return; + if (u > 2 && !(u & (u - 1))) { + fprintf(stderr, + "NOTE:\n" + "\tA power of two number of hash buckets is " + "marginally less efficient\n" + "\twith systematic URLs. Reducing by one" + " hash bucket.\n"); + u--; + } + hcl_nhash = u; + fprintf(stderr, "Classic hash: %u buckets\n", hcl_nhash); + return; +} + +/*-------------------------------------------------------------------- + * The ->start method is called during cache process start and allows + * initialization to happen before the first lookup. + */ + +static void +hcl_start(void) +{ + unsigned u; + + hcl_head = calloc(sizeof *hcl_head, hcl_nhash); + XXXAN(hcl_head); + + for (u = 0; u < hcl_nhash; u++) { + VTAILQ_INIT(&hcl_head[u].head); + Lck_New(&hcl_head[u].mtx, lck_hcl); + hcl_head[u].magic = HCL_HEAD_MAGIC; + } +} + +/*-------------------------------------------------------------------- + * Lookup and possibly insert element. + * If nobj != NULL and the lookup does not find key, nobj is inserted. + * If nobj == NULL and the lookup does not find key, NULL is returned. + * A reference to the returned object is held. + * We use a two-pass algorithm to handle inserts as they are quite + * rare and collisions even rarer. + */ + +static struct objhead * +hcl_lookup(const struct sess *sp, struct objhead *noh) +{ + struct objhead *oh; + struct hcl_hd *hp; + unsigned u1, digest; + int i; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); + + assert(sizeof noh->digest > sizeof digest); + memcpy(&digest, noh->digest, sizeof digest); + u1 = digest % hcl_nhash; + hp = &hcl_head[u1]; + + Lck_Lock(&hp->mtx); + VTAILQ_FOREACH(oh, &hp->head, hoh_list) { + i = memcmp(oh->digest, noh->digest, sizeof oh->digest); + if (i < 0) + continue; + if (i > 0) + break; + oh->refcnt++; + Lck_Unlock(&hp->mtx); + return (oh); + } + + if (oh != NULL) + VTAILQ_INSERT_BEFORE(oh, noh, hoh_list); + else + VTAILQ_INSERT_TAIL(&hp->head, noh, hoh_list); + + noh->hoh_head = hp; + + Lck_Unlock(&hp->mtx); + return (noh); +} + +/*-------------------------------------------------------------------- + * Dereference and if no references are left, free. + */ + +static int +hcl_deref(struct objhead *oh) +{ + struct hcl_hd *hp; + int ret; + + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + CAST_OBJ_NOTNULL(hp, oh->hoh_head, HCL_HEAD_MAGIC); + assert(oh->refcnt > 0); + Lck_Lock(&hp->mtx); + if (--oh->refcnt == 0) { + VTAILQ_REMOVE(&hp->head, oh, hoh_list); + ret = 0; + } else + ret = 1; + Lck_Unlock(&hp->mtx); + return (ret); +} + +/*--------------------------------------------------------------------*/ + +const struct hash_slinger hcl_slinger = { + .magic = SLINGER_MAGIC, + .name = "classic", + .init = hcl_init, + .start = hcl_start, + .lookup = hcl_lookup, + .deref = hcl_deref, +}; diff --git a/bin/varnishd/hash/hash_critbit.c b/bin/varnishd/hash/hash_critbit.c new file mode 100644 index 0000000..56cc5c0 --- /dev/null +++ b/bin/varnishd/hash/hash_critbit.c @@ -0,0 +1,492 @@ +/*- + * Copyright (c) 2008-2010 Varnish Software 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. + * + * A Crit Bit tree based hash + */ + +// #define PHK + +#include "config.h" + +#include + +#include "cache.h" + +#include "hash/hash_slinger.h" +#include "vcli_priv.h" +#include "vmb.h" +#include "vtim.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 char x; + unsigned 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 magic; +#define HCB_Y_MAGIC 0x125c4bd2 + unsigned short critbit; + unsigned char ptr; + unsigned char bitmask; + volatile uintptr_t leaf[2]; + VSTAILQ_ENTRY(hcb_y) list; +}; + +#define HCB_BIT_NODE (1<<0) +#define HCB_BIT_Y (1<<1) + +struct hcb_root { + volatile uintptr_t origo; +}; + +static struct hcb_root hcb_root; + +static VSTAILQ_HEAD(, hcb_y) cool_y = VSTAILQ_HEAD_INITIALIZER(cool_y); +static VSTAILQ_HEAD(, hcb_y) dead_y = VSTAILQ_HEAD_INITIALIZER(dead_y); +static VTAILQ_HEAD(, objhead) cool_h = VTAILQ_HEAD_INITIALIZER(cool_h); +static VTAILQ_HEAD(, objhead) dead_h = VTAILQ_HEAD_INITIALIZER(dead_h); + +/*--------------------------------------------------------------------- + * 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) +{ + + CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); + 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)); +} + +/*--------------------------------------------------------------------- + * Find the "critical" bit that separates these two digests + */ + +static unsigned +hcb_crit_bit(const struct objhead *oh1, const struct objhead *oh2, + struct hcb_y *y) +{ + unsigned char u, r; + + CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); + 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; + y->critbit = u * 8 + r; + return (y->critbit); +} + +/*--------------------------------------------------------------------- + * Unless we have the lock, we need to be very careful about pointer + * references into the tree, we cannot trust things to be the same + * in two consequtive memory accesses. + */ + +static struct objhead * +hcb_insert(struct worker *wrk, struct hcb_root *root, struct objhead *oh, int has_lock) +{ + volatile uintptr_t *p; + uintptr_t pp; + struct hcb_y *y, *y2; + struct objhead *oh2; + unsigned s, s2; + + p = &root->origo; + pp = *p; + if (pp == 0) { + if (!has_lock) + return (NULL); + *p = hcb_r_node(oh); + return (oh); + } + + while(hcb_is_y(pp)) { + y = hcb_l_y(pp); + CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); + assert(y->ptr < DIGEST_LEN); + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + p = &y->leaf[s]; + pp = *p; + } + + if (pp == 0) { + /* We raced hcb_delete and got a NULL pointer */ + assert(!has_lock); + return (NULL); + } + + assert(hcb_is_node(pp)); + + /* We found a node, does it match ? */ + oh2 = hcb_l_node(pp); + CHECK_OBJ_NOTNULL(oh2, OBJHEAD_MAGIC); + if (!memcmp(oh2->digest, oh->digest, DIGEST_LEN)) + return (oh2); + + if (!has_lock) + return (NULL); + + /* Insert */ + + CAST_OBJ_NOTNULL(y2, wrk->nhashpriv, HCB_Y_MAGIC); + wrk->nhashpriv = NULL; + (void)hcb_crit_bit(oh, oh2, 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); + CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); + assert(y->critbit != y2->critbit); + if (y->critbit > y2->critbit) + break; + assert(y->ptr < DIGEST_LEN); + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + p = &y->leaf[s]; + } + y2->leaf[s2] = *p; + VWMB(); + *p = hcb_r_y(y2); + return(oh); +} + +/*--------------------------------------------------------------------*/ + +static void +hcb_delete(struct hcb_root *r, struct objhead *oh) +{ + struct hcb_y *y; + volatile 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(1) { + assert(hcb_is_y(*p)); + y = hcb_l_y(*p); + assert(y->ptr < DIGEST_LEN); + s = (oh->digest[y->ptr] & y->bitmask) != 0; + assert(s < 2); + if (y->leaf[s] == hcb_r_node(oh)) { + *p = y->leaf[1 - s]; + VSTAILQ_INSERT_TAIL(&cool_y, y, list); + return; + } + p = &y->leaf[s]; + } +} + +/*--------------------------------------------------------------------*/ + +static void +dumptree(struct cli *cli, uintptr_t p, int indent) +{ + 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); + VCLI_Out(cli, "%*.*sN %d r%u <%02x%02x%02x...>\n", + indent, indent, "", indent / 2, oh->refcnt, + oh->digest[0], oh->digest[1], oh->digest[2]); + return; + } + assert(hcb_is_y(p)); + y = hcb_l_y(p); + VCLI_Out(cli, "%*.*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(cli, y->leaf[i], indent); +} + +static void +hcb_dump(struct cli *cli, const char * const *av, void *priv) +{ + + (void)priv; + (void)av; + VCLI_Out(cli, "HCB dump:\n"); + dumptree(cli, hcb_root.origo, 0); + VCLI_Out(cli, "Coollist:\n"); +} + +static struct cli_proto hcb_cmds[] = { + { "hcb.dump", "hcb.dump", "dump HCB tree\n", 0, 0, "d", hcb_dump }, + { NULL } +}; + +/*--------------------------------------------------------------------*/ + +static void * +hcb_cleaner(void *priv) +{ + struct hcb_y *y, *y2; + struct worker ww; + struct objhead *oh, *oh2; + + memset(&ww, 0, sizeof ww); + ww.magic = WORKER_MAGIC; + + THR_SetName("hcb_cleaner"); + (void)priv; + while (1) { + VSTAILQ_FOREACH_SAFE(y, &dead_y, list, y2) { + VSTAILQ_REMOVE_HEAD(&dead_y, list); + FREE_OBJ(y); + } + VTAILQ_FOREACH_SAFE(oh, &dead_h, hoh_list, oh2) { + VTAILQ_REMOVE(&dead_h, oh, hoh_list); + HSH_DeleteObjHead(&ww, oh); + } + Lck_Lock(&hcb_mtx); + VSTAILQ_CONCAT(&dead_y, &cool_y); + VTAILQ_CONCAT(&dead_h, &cool_h, hoh_list); + Lck_Unlock(&hcb_mtx); + WRK_SumStat(&ww); + VTIM_sleep(params->critbit_cooloff); + } + NEEDLESS_RETURN(NULL); +} + +/*--------------------------------------------------------------------*/ + +static void +hcb_start(void) +{ + struct objhead *oh = NULL; + pthread_t tp; + + (void)oh; + CLI_AddFuncs(hcb_cmds); + Lck_New(&hcb_mtx, lck_hcb); + AZ(pthread_create(&tp, NULL, hcb_cleaner, NULL)); + memset(&hcb_root, 0, sizeof hcb_root); + hcb_build_bittbl(); +} + +static int +hcb_deref(struct objhead *oh) +{ + int r; + + r = 1; + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + Lck_Lock(&oh->mtx); + assert(oh->refcnt > 0); + oh->refcnt--; + if (oh->refcnt == 0) { + Lck_Lock(&hcb_mtx); + hcb_delete(&hcb_root, oh); + VTAILQ_INSERT_TAIL(&cool_h, oh, hoh_list); + Lck_Unlock(&hcb_mtx); + assert(VTAILQ_EMPTY(&oh->objcs)); + AZ(oh->waitinglist); + } + Lck_Unlock(&oh->mtx); +#ifdef PHK + fprintf(stderr, "hcb_defef %d %d <%s>\n", __LINE__, r, oh->hash); +#endif + return (r); +} + +static struct objhead * +hcb_lookup(const struct sess *sp, struct objhead *noh) +{ + struct objhead *oh; + struct hcb_y *y; + unsigned u; + unsigned with_lock; + + (void)sp; + + with_lock = 0; + while (1) { + if (with_lock) { + CAST_OBJ_NOTNULL(y, sp->wrk->nhashpriv, HCB_Y_MAGIC); + Lck_Lock(&hcb_mtx); + VSC_C_main->hcb_lock++; + assert(noh->refcnt == 1); + oh = hcb_insert(sp->wrk, &hcb_root, noh, 1); + Lck_Unlock(&hcb_mtx); + } else { + VSC_C_main->hcb_nolock++; + oh = hcb_insert(sp->wrk, &hcb_root, noh, 0); + } + + if (oh != NULL && oh == noh) { + /* Assert that we only muck with the tree with a lock */ + assert(with_lock); + VSC_C_main->hcb_insert++; + assert(oh->refcnt > 0); + return (oh); + } + + if (oh == NULL) { + assert(!with_lock); + /* Try again, with lock */ + with_lock = 1; + continue; + } + + CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); + Lck_Lock(&oh->mtx); + /* + * A refcount of zero indicates that the tree changed + * under us, so fall through and try with the lock held. + */ + u = oh->refcnt; + if (u > 0) + oh->refcnt++; + else + with_lock = 1; + Lck_Unlock(&oh->mtx); + if (u > 0) + return (oh); + } +} + +static void +hcb_prep(const struct sess *sp) +{ + struct hcb_y *y; + + if (sp->wrk->nhashpriv == NULL) { + ALLOC_OBJ(y, HCB_Y_MAGIC); + sp->wrk->nhashpriv = y; + } +} + +const struct hash_slinger hcb_slinger = { + .magic = SLINGER_MAGIC, + .name = "critbit", + .start = hcb_start, + .lookup = hcb_lookup, + .prep = hcb_prep, + .deref = hcb_deref, +}; diff --git a/bin/varnishd/hash/hash_simple_list.c b/bin/varnishd/hash/hash_simple_list.c new file mode 100644 index 0000000..1a0cae5 --- /dev/null +++ b/bin/varnishd/hash/hash_simple_list.c @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + * This is the reference hash(/lookup) implementation + */ + +#include "config.h" + +#include "cache.h" + +#include "hash/hash_slinger.h" + +/*--------------------------------------------------------------------*/ + +static VTAILQ_HEAD(, objhead) hsl_head = VTAILQ_HEAD_INITIALIZER(hsl_head); +static struct lock hsl_mtx; + +/*-------------------------------------------------------------------- + * The ->init method is called during process start and allows + * initialization to happen before the first lookup. + */ + +static void +hsl_start(void) +{ + + Lck_New(&hsl_mtx, lck_hsl); +} + +/*-------------------------------------------------------------------- + * Lookup and possibly insert element. + * If nobj != NULL and the lookup does not find key, nobj is inserted. + * If nobj == NULL and the lookup does not find key, NULL is returned. + * A reference to the returned object is held. + */ + +static struct objhead * +hsl_lookup(const struct sess *sp, struct objhead *noh) +{ + 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 = memcmp(oh->digest, noh->digest, sizeof oh->digest); + if (i < 0) + continue; + if (i > 0) + break; + oh->refcnt++; + Lck_Unlock(&hsl_mtx); + return (oh); + } + + if (oh != NULL) + VTAILQ_INSERT_BEFORE(oh, noh, hoh_list); + else + VTAILQ_INSERT_TAIL(&hsl_head, noh, hoh_list); + + Lck_Unlock(&hsl_mtx); + return (noh); +} + +/*-------------------------------------------------------------------- + * Dereference and if no references are left, free. + */ + +static int +hsl_deref(struct objhead *oh) +{ + int ret; + + Lck_Lock(&hsl_mtx); + if (--oh->refcnt == 0) { + VTAILQ_REMOVE(&hsl_head, oh, hoh_list); + ret = 0; + } else + ret = 1; + Lck_Unlock(&hsl_mtx); + return (ret); +} + +/*--------------------------------------------------------------------*/ + +const struct hash_slinger hsl_slinger = { + .magic = SLINGER_MAGIC, + .name = "simple", + .start = hsl_start, + .lookup = hsl_lookup, + .deref = hsl_deref, +}; diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h new file mode 100644 index 0000000..2c142cf --- /dev/null +++ b/bin/varnishd/hash/hash_slinger.h @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2010 Varnish Software 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. + * + */ + +struct sess; +struct worker; +struct object; + +typedef void hash_init_f(int ac, char * const *av); +typedef void hash_start_f(void); +typedef void hash_prep_f(const struct sess *sp); +typedef struct objhead * + hash_lookup_f(const struct sess *sp, struct objhead *nobj); +typedef int hash_deref_f(struct objhead *obj); + +struct hash_slinger { + unsigned magic; +#define SLINGER_MAGIC 0x1b720cba + const char *name; + hash_init_f *init; + hash_start_f *start; + hash_prep_f *prep; + hash_lookup_f *lookup; + hash_deref_f *deref; +}; + +/* cache_hash.c */ +void HSH_Prealloc(const struct sess *sp); +void HSH_Cleanup(struct worker *w); +struct objcore *HSH_Lookup(struct sess *sp, struct objhead **poh); +void HSH_Unbusy(const struct sess *sp); +void HSH_Ref(struct objcore *o); +void HSH_Drop(struct sess *sp); +void HSH_Init(void); +void HSH_AddString(const struct sess *sp, const char *str); +struct objcore *HSH_Insert(const struct sess *sp); +void HSH_Purge(const struct sess *, struct objhead *, double ttl, double grace); +void HSH_config(const char *h_arg); + +#ifdef VARNISH_CACHE_CHILD + +struct waitinglist { + unsigned magic; +#define WAITINGLIST_MAGIC 0x063a477a + VTAILQ_HEAD(, sess) list; +}; + +struct objhead { + unsigned magic; +#define OBJHEAD_MAGIC 0x1b96615d + + int refcnt; + struct lock mtx; + VTAILQ_HEAD(,objcore) objcs; + unsigned char digest[DIGEST_LEN]; + struct waitinglist *waitinglist; + + /*---------------------------------------------------- + * The fields below are for the sole private use of + * the hash implementation(s). + */ + union { + struct { + VTAILQ_ENTRY(objhead) u_n_hoh_list; + void *u_n_hoh_head; + } n; + } _u; +#define hoh_list _u.n.u_n_hoh_list +#define hoh_head _u.n.u_n_hoh_head +}; + +void HSH_DeleteObjHead(struct worker *w, struct objhead *oh); +int HSH_Deref(struct worker *w, struct objcore *oc, struct object **o); +#endif /* VARNISH_CACHE_CHILD */ + +extern const struct hash_slinger hsl_slinger; +extern const struct hash_slinger hcl_slinger; +extern const struct hash_slinger hcb_slinger; diff --git a/bin/varnishd/hash_classic.c b/bin/varnishd/hash_classic.c deleted file mode 100644 index fc88757..0000000 --- a/bin/varnishd/hash_classic.c +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - * A classic bucketed hash - */ - -#include "config.h" - -#include -#include - -#include "cache.h" - -#include "hash_slinger.h" - -/*--------------------------------------------------------------------*/ - -struct hcl_hd { - unsigned magic; -#define HCL_HEAD_MAGIC 0x0f327016 - VTAILQ_HEAD(, objhead) head; - struct lock mtx; -}; - -static unsigned hcl_nhash = 16383; -static struct hcl_hd *hcl_head; - -/*-------------------------------------------------------------------- - * The ->init method allows the management process to pass arguments - */ - -static void -hcl_init(int ac, char * const *av) -{ - int i; - unsigned u; - - if (ac == 0) - return; - if (ac > 1) - ARGV_ERR("(-hclassic) too many arguments\n"); - i = sscanf(av[0], "%u", &u); - if (i <= 0 || u == 0) - return; - if (u > 2 && !(u & (u - 1))) { - fprintf(stderr, - "NOTE:\n" - "\tA power of two number of hash buckets is " - "marginally less efficient\n" - "\twith systematic URLs. Reducing by one" - " hash bucket.\n"); - u--; - } - hcl_nhash = u; - fprintf(stderr, "Classic hash: %u buckets\n", hcl_nhash); - return; -} - -/*-------------------------------------------------------------------- - * The ->start method is called during cache process start and allows - * initialization to happen before the first lookup. - */ - -static void -hcl_start(void) -{ - unsigned u; - - hcl_head = calloc(sizeof *hcl_head, hcl_nhash); - XXXAN(hcl_head); - - for (u = 0; u < hcl_nhash; u++) { - VTAILQ_INIT(&hcl_head[u].head); - Lck_New(&hcl_head[u].mtx, lck_hcl); - hcl_head[u].magic = HCL_HEAD_MAGIC; - } -} - -/*-------------------------------------------------------------------- - * Lookup and possibly insert element. - * If nobj != NULL and the lookup does not find key, nobj is inserted. - * If nobj == NULL and the lookup does not find key, NULL is returned. - * A reference to the returned object is held. - * We use a two-pass algorithm to handle inserts as they are quite - * rare and collisions even rarer. - */ - -static struct objhead * -hcl_lookup(const struct sess *sp, struct objhead *noh) -{ - struct objhead *oh; - struct hcl_hd *hp; - unsigned u1, digest; - int i; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); - - assert(sizeof noh->digest > sizeof digest); - memcpy(&digest, noh->digest, sizeof digest); - u1 = digest % hcl_nhash; - hp = &hcl_head[u1]; - - Lck_Lock(&hp->mtx); - VTAILQ_FOREACH(oh, &hp->head, hoh_list) { - i = memcmp(oh->digest, noh->digest, sizeof oh->digest); - if (i < 0) - continue; - if (i > 0) - break; - oh->refcnt++; - Lck_Unlock(&hp->mtx); - return (oh); - } - - if (oh != NULL) - VTAILQ_INSERT_BEFORE(oh, noh, hoh_list); - else - VTAILQ_INSERT_TAIL(&hp->head, noh, hoh_list); - - noh->hoh_head = hp; - - Lck_Unlock(&hp->mtx); - return (noh); -} - -/*-------------------------------------------------------------------- - * Dereference and if no references are left, free. - */ - -static int -hcl_deref(struct objhead *oh) -{ - struct hcl_hd *hp; - int ret; - - CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - CAST_OBJ_NOTNULL(hp, oh->hoh_head, HCL_HEAD_MAGIC); - assert(oh->refcnt > 0); - Lck_Lock(&hp->mtx); - if (--oh->refcnt == 0) { - VTAILQ_REMOVE(&hp->head, oh, hoh_list); - ret = 0; - } else - ret = 1; - Lck_Unlock(&hp->mtx); - return (ret); -} - -/*--------------------------------------------------------------------*/ - -const struct hash_slinger hcl_slinger = { - .magic = SLINGER_MAGIC, - .name = "classic", - .init = hcl_init, - .start = hcl_start, - .lookup = hcl_lookup, - .deref = hcl_deref, -}; diff --git a/bin/varnishd/hash_critbit.c b/bin/varnishd/hash_critbit.c deleted file mode 100644 index 78bda7a..0000000 --- a/bin/varnishd/hash_critbit.c +++ /dev/null @@ -1,492 +0,0 @@ -/*- - * Copyright (c) 2008-2010 Varnish Software 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. - * - * A Crit Bit tree based hash - */ - -// #define PHK - -#include "config.h" - -#include - -#include "cache.h" - -#include "hash_slinger.h" -#include "vcli_priv.h" -#include "vmb.h" -#include "vtim.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 char x; - unsigned 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 magic; -#define HCB_Y_MAGIC 0x125c4bd2 - unsigned short critbit; - unsigned char ptr; - unsigned char bitmask; - volatile uintptr_t leaf[2]; - VSTAILQ_ENTRY(hcb_y) list; -}; - -#define HCB_BIT_NODE (1<<0) -#define HCB_BIT_Y (1<<1) - -struct hcb_root { - volatile uintptr_t origo; -}; - -static struct hcb_root hcb_root; - -static VSTAILQ_HEAD(, hcb_y) cool_y = VSTAILQ_HEAD_INITIALIZER(cool_y); -static VSTAILQ_HEAD(, hcb_y) dead_y = VSTAILQ_HEAD_INITIALIZER(dead_y); -static VTAILQ_HEAD(, objhead) cool_h = VTAILQ_HEAD_INITIALIZER(cool_h); -static VTAILQ_HEAD(, objhead) dead_h = VTAILQ_HEAD_INITIALIZER(dead_h); - -/*--------------------------------------------------------------------- - * 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) -{ - - CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); - 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)); -} - -/*--------------------------------------------------------------------- - * Find the "critical" bit that separates these two digests - */ - -static unsigned -hcb_crit_bit(const struct objhead *oh1, const struct objhead *oh2, - struct hcb_y *y) -{ - unsigned char u, r; - - CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); - 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; - y->critbit = u * 8 + r; - return (y->critbit); -} - -/*--------------------------------------------------------------------- - * Unless we have the lock, we need to be very careful about pointer - * references into the tree, we cannot trust things to be the same - * in two consequtive memory accesses. - */ - -static struct objhead * -hcb_insert(struct worker *wrk, struct hcb_root *root, struct objhead *oh, int has_lock) -{ - volatile uintptr_t *p; - uintptr_t pp; - struct hcb_y *y, *y2; - struct objhead *oh2; - unsigned s, s2; - - p = &root->origo; - pp = *p; - if (pp == 0) { - if (!has_lock) - return (NULL); - *p = hcb_r_node(oh); - return (oh); - } - - while(hcb_is_y(pp)) { - y = hcb_l_y(pp); - CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); - assert(y->ptr < DIGEST_LEN); - s = (oh->digest[y->ptr] & y->bitmask) != 0; - assert(s < 2); - p = &y->leaf[s]; - pp = *p; - } - - if (pp == 0) { - /* We raced hcb_delete and got a NULL pointer */ - assert(!has_lock); - return (NULL); - } - - assert(hcb_is_node(pp)); - - /* We found a node, does it match ? */ - oh2 = hcb_l_node(pp); - CHECK_OBJ_NOTNULL(oh2, OBJHEAD_MAGIC); - if (!memcmp(oh2->digest, oh->digest, DIGEST_LEN)) - return (oh2); - - if (!has_lock) - return (NULL); - - /* Insert */ - - CAST_OBJ_NOTNULL(y2, wrk->nhashpriv, HCB_Y_MAGIC); - wrk->nhashpriv = NULL; - (void)hcb_crit_bit(oh, oh2, 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); - CHECK_OBJ_NOTNULL(y, HCB_Y_MAGIC); - assert(y->critbit != y2->critbit); - if (y->critbit > y2->critbit) - break; - assert(y->ptr < DIGEST_LEN); - s = (oh->digest[y->ptr] & y->bitmask) != 0; - assert(s < 2); - p = &y->leaf[s]; - } - y2->leaf[s2] = *p; - VWMB(); - *p = hcb_r_y(y2); - return(oh); -} - -/*--------------------------------------------------------------------*/ - -static void -hcb_delete(struct hcb_root *r, struct objhead *oh) -{ - struct hcb_y *y; - volatile 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(1) { - assert(hcb_is_y(*p)); - y = hcb_l_y(*p); - assert(y->ptr < DIGEST_LEN); - s = (oh->digest[y->ptr] & y->bitmask) != 0; - assert(s < 2); - if (y->leaf[s] == hcb_r_node(oh)) { - *p = y->leaf[1 - s]; - VSTAILQ_INSERT_TAIL(&cool_y, y, list); - return; - } - p = &y->leaf[s]; - } -} - -/*--------------------------------------------------------------------*/ - -static void -dumptree(struct cli *cli, uintptr_t p, int indent) -{ - 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); - VCLI_Out(cli, "%*.*sN %d r%u <%02x%02x%02x...>\n", - indent, indent, "", indent / 2, oh->refcnt, - oh->digest[0], oh->digest[1], oh->digest[2]); - return; - } - assert(hcb_is_y(p)); - y = hcb_l_y(p); - VCLI_Out(cli, "%*.*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(cli, y->leaf[i], indent); -} - -static void -hcb_dump(struct cli *cli, const char * const *av, void *priv) -{ - - (void)priv; - (void)av; - VCLI_Out(cli, "HCB dump:\n"); - dumptree(cli, hcb_root.origo, 0); - VCLI_Out(cli, "Coollist:\n"); -} - -static struct cli_proto hcb_cmds[] = { - { "hcb.dump", "hcb.dump", "dump HCB tree\n", 0, 0, "d", hcb_dump }, - { NULL } -}; - -/*--------------------------------------------------------------------*/ - -static void * -hcb_cleaner(void *priv) -{ - struct hcb_y *y, *y2; - struct worker ww; - struct objhead *oh, *oh2; - - memset(&ww, 0, sizeof ww); - ww.magic = WORKER_MAGIC; - - THR_SetName("hcb_cleaner"); - (void)priv; - while (1) { - VSTAILQ_FOREACH_SAFE(y, &dead_y, list, y2) { - VSTAILQ_REMOVE_HEAD(&dead_y, list); - FREE_OBJ(y); - } - VTAILQ_FOREACH_SAFE(oh, &dead_h, hoh_list, oh2) { - VTAILQ_REMOVE(&dead_h, oh, hoh_list); - HSH_DeleteObjHead(&ww, oh); - } - Lck_Lock(&hcb_mtx); - VSTAILQ_CONCAT(&dead_y, &cool_y); - VTAILQ_CONCAT(&dead_h, &cool_h, hoh_list); - Lck_Unlock(&hcb_mtx); - WRK_SumStat(&ww); - VTIM_sleep(params->critbit_cooloff); - } - NEEDLESS_RETURN(NULL); -} - -/*--------------------------------------------------------------------*/ - -static void -hcb_start(void) -{ - struct objhead *oh = NULL; - pthread_t tp; - - (void)oh; - CLI_AddFuncs(hcb_cmds); - Lck_New(&hcb_mtx, lck_hcb); - AZ(pthread_create(&tp, NULL, hcb_cleaner, NULL)); - memset(&hcb_root, 0, sizeof hcb_root); - hcb_build_bittbl(); -} - -static int -hcb_deref(struct objhead *oh) -{ - int r; - - r = 1; - CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - Lck_Lock(&oh->mtx); - assert(oh->refcnt > 0); - oh->refcnt--; - if (oh->refcnt == 0) { - Lck_Lock(&hcb_mtx); - hcb_delete(&hcb_root, oh); - VTAILQ_INSERT_TAIL(&cool_h, oh, hoh_list); - Lck_Unlock(&hcb_mtx); - assert(VTAILQ_EMPTY(&oh->objcs)); - AZ(oh->waitinglist); - } - Lck_Unlock(&oh->mtx); -#ifdef PHK - fprintf(stderr, "hcb_defef %d %d <%s>\n", __LINE__, r, oh->hash); -#endif - return (r); -} - -static struct objhead * -hcb_lookup(const struct sess *sp, struct objhead *noh) -{ - struct objhead *oh; - struct hcb_y *y; - unsigned u; - unsigned with_lock; - - (void)sp; - - with_lock = 0; - while (1) { - if (with_lock) { - CAST_OBJ_NOTNULL(y, sp->wrk->nhashpriv, HCB_Y_MAGIC); - Lck_Lock(&hcb_mtx); - VSC_C_main->hcb_lock++; - assert(noh->refcnt == 1); - oh = hcb_insert(sp->wrk, &hcb_root, noh, 1); - Lck_Unlock(&hcb_mtx); - } else { - VSC_C_main->hcb_nolock++; - oh = hcb_insert(sp->wrk, &hcb_root, noh, 0); - } - - if (oh != NULL && oh == noh) { - /* Assert that we only muck with the tree with a lock */ - assert(with_lock); - VSC_C_main->hcb_insert++; - assert(oh->refcnt > 0); - return (oh); - } - - if (oh == NULL) { - assert(!with_lock); - /* Try again, with lock */ - with_lock = 1; - continue; - } - - CHECK_OBJ_NOTNULL(noh, OBJHEAD_MAGIC); - Lck_Lock(&oh->mtx); - /* - * A refcount of zero indicates that the tree changed - * under us, so fall through and try with the lock held. - */ - u = oh->refcnt; - if (u > 0) - oh->refcnt++; - else - with_lock = 1; - Lck_Unlock(&oh->mtx); - if (u > 0) - return (oh); - } -} - -static void -hcb_prep(const struct sess *sp) -{ - struct hcb_y *y; - - if (sp->wrk->nhashpriv == NULL) { - ALLOC_OBJ(y, HCB_Y_MAGIC); - sp->wrk->nhashpriv = y; - } -} - -const struct hash_slinger hcb_slinger = { - .magic = SLINGER_MAGIC, - .name = "critbit", - .start = hcb_start, - .lookup = hcb_lookup, - .prep = hcb_prep, - .deref = hcb_deref, -}; diff --git a/bin/varnishd/hash_simple_list.c b/bin/varnishd/hash_simple_list.c deleted file mode 100644 index c1c17da..0000000 --- a/bin/varnishd/hash_simple_list.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - * This is the reference hash(/lookup) implementation - */ - -#include "config.h" - -#include "cache.h" - -#include "hash_slinger.h" - -/*--------------------------------------------------------------------*/ - -static VTAILQ_HEAD(, objhead) hsl_head = VTAILQ_HEAD_INITIALIZER(hsl_head); -static struct lock hsl_mtx; - -/*-------------------------------------------------------------------- - * The ->init method is called during process start and allows - * initialization to happen before the first lookup. - */ - -static void -hsl_start(void) -{ - - Lck_New(&hsl_mtx, lck_hsl); -} - -/*-------------------------------------------------------------------- - * Lookup and possibly insert element. - * If nobj != NULL and the lookup does not find key, nobj is inserted. - * If nobj == NULL and the lookup does not find key, NULL is returned. - * A reference to the returned object is held. - */ - -static struct objhead * -hsl_lookup(const struct sess *sp, struct objhead *noh) -{ - 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 = memcmp(oh->digest, noh->digest, sizeof oh->digest); - if (i < 0) - continue; - if (i > 0) - break; - oh->refcnt++; - Lck_Unlock(&hsl_mtx); - return (oh); - } - - if (oh != NULL) - VTAILQ_INSERT_BEFORE(oh, noh, hoh_list); - else - VTAILQ_INSERT_TAIL(&hsl_head, noh, hoh_list); - - Lck_Unlock(&hsl_mtx); - return (noh); -} - -/*-------------------------------------------------------------------- - * Dereference and if no references are left, free. - */ - -static int -hsl_deref(struct objhead *oh) -{ - int ret; - - Lck_Lock(&hsl_mtx); - if (--oh->refcnt == 0) { - VTAILQ_REMOVE(&hsl_head, oh, hoh_list); - ret = 0; - } else - ret = 1; - Lck_Unlock(&hsl_mtx); - return (ret); -} - -/*--------------------------------------------------------------------*/ - -const struct hash_slinger hsl_slinger = { - .magic = SLINGER_MAGIC, - .name = "simple", - .start = hsl_start, - .lookup = hsl_lookup, - .deref = hsl_deref, -}; diff --git a/bin/varnishd/hash_slinger.h b/bin/varnishd/hash_slinger.h deleted file mode 100644 index 2c142cf..0000000 --- a/bin/varnishd/hash_slinger.h +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2010 Varnish Software 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. - * - */ - -struct sess; -struct worker; -struct object; - -typedef void hash_init_f(int ac, char * const *av); -typedef void hash_start_f(void); -typedef void hash_prep_f(const struct sess *sp); -typedef struct objhead * - hash_lookup_f(const struct sess *sp, struct objhead *nobj); -typedef int hash_deref_f(struct objhead *obj); - -struct hash_slinger { - unsigned magic; -#define SLINGER_MAGIC 0x1b720cba - const char *name; - hash_init_f *init; - hash_start_f *start; - hash_prep_f *prep; - hash_lookup_f *lookup; - hash_deref_f *deref; -}; - -/* cache_hash.c */ -void HSH_Prealloc(const struct sess *sp); -void HSH_Cleanup(struct worker *w); -struct objcore *HSH_Lookup(struct sess *sp, struct objhead **poh); -void HSH_Unbusy(const struct sess *sp); -void HSH_Ref(struct objcore *o); -void HSH_Drop(struct sess *sp); -void HSH_Init(void); -void HSH_AddString(const struct sess *sp, const char *str); -struct objcore *HSH_Insert(const struct sess *sp); -void HSH_Purge(const struct sess *, struct objhead *, double ttl, double grace); -void HSH_config(const char *h_arg); - -#ifdef VARNISH_CACHE_CHILD - -struct waitinglist { - unsigned magic; -#define WAITINGLIST_MAGIC 0x063a477a - VTAILQ_HEAD(, sess) list; -}; - -struct objhead { - unsigned magic; -#define OBJHEAD_MAGIC 0x1b96615d - - int refcnt; - struct lock mtx; - VTAILQ_HEAD(,objcore) objcs; - unsigned char digest[DIGEST_LEN]; - struct waitinglist *waitinglist; - - /*---------------------------------------------------- - * The fields below are for the sole private use of - * the hash implementation(s). - */ - union { - struct { - VTAILQ_ENTRY(objhead) u_n_hoh_list; - void *u_n_hoh_head; - } n; - } _u; -#define hoh_list _u.n.u_n_hoh_list -#define hoh_head _u.n.u_n_hoh_head -}; - -void HSH_DeleteObjHead(struct worker *w, struct objhead *oh); -int HSH_Deref(struct worker *w, struct objcore *oc, struct object **o); -#endif /* VARNISH_CACHE_CHILD */ - -extern const struct hash_slinger hsl_slinger; -extern const struct hash_slinger hcl_slinger; -extern const struct hash_slinger hcb_slinger; diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index 84aef5c..02d244e 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -46,7 +46,7 @@ #include "cache.h" #include "storage/storage.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vcli.h" #include "vcli_priv.h" #include "vend.h" diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c index 5393546..27f0c98 100644 --- a/bin/varnishd/storage/storage_persistent_silo.c +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -40,7 +40,7 @@ #include "cache.h" #include "storage/storage.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "vsha256.h" #include "vtim.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index 7fe72aa..e0654a3 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -45,7 +45,7 @@ #include "mgt.h" -#include "hash_slinger.h" +#include "hash/hash_slinger.h" #include "heritage.h" #include "vav.h" #include "vcli.h" From tfheen at varnish-cache.org Thu Oct 13 06:15:49 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 13 Oct 2011 08:15:49 +0200 Subject: [master] 4620b27 Grammar Message-ID: commit 4620b2702c1ee13d51c1a9ec77465426388c7aab Author: Tollef Fog Heen Date: Fri Oct 7 08:59:08 2011 +0200 Grammar diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 019fd3b..2558413 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -5,8 +5,8 @@ Welcome to Varnish's documentation! =================================== Varnish is a state of the art web accelerator. Its mission is to sit -in front of a web server and to cache the content. It makes your web site -go fast. +in front of a web server and cache content. It makes your web site +go faster. We suggest you start by reading the installation guide :ref:`install-index`. Once you have Varnish up and running go through From tfheen at varnish-cache.org Thu Oct 13 06:15:49 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 13 Oct 2011 08:15:49 +0200 Subject: [master] 91734c4 WRK_Flush was renamed to WRW_Flush a long time ago; update some ifdefed code and comments to match Message-ID: commit 91734c47393d6bba8cca4eed265ee78a1b5f92c8 Author: Tollef Fog Heen Date: Mon Oct 10 08:14:31 2011 +0200 WRK_Flush was renamed to WRW_Flush a long time ago; update some ifdefed code and comments to match diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 33ccc8b..22e61ae 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -255,7 +255,7 @@ struct exp { struct wrw { int *wfd; - unsigned werr; /* valid after WRK_Flush() */ + unsigned werr; /* valid after WRW_Flush() */ struct iovec *iov; unsigned siov; unsigned niov; diff --git a/bin/varnishd/cache_wrw.c b/bin/varnishd/cache_wrw.c index 4fef1aa..0790ab2 100644 --- a/bin/varnishd/cache_wrw.c +++ b/bin/varnishd/cache_wrw.c @@ -264,7 +264,7 @@ WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len) } while (0); #elif defined(__linux__) do { - if (WRK_Flush(w) == 0 && + if (WRW_Flush(w) == 0 && sendfile(*wrw->wfd, fd, &off, len) != len) wrw->werr++; } while (0); @@ -293,7 +293,7 @@ WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len) } while (0); #elif defined(__sun) && defined(HAVE_SENDFILE) do { - if (WRK_Flush(w) == 0 && + if (WRW_Flush(w) == 0 && sendfile(*wrw->wfd, fd, &off, len) != len) wrw->werr++; } while (0); From tfheen at varnish-cache.org Thu Oct 13 06:33:52 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 13 Oct 2011 08:33:52 +0200 Subject: [master] 2bcbc00 Use = rather than := in Makefile to make solaris make stop whining on distcheck Message-ID: commit 2bcbc0032e76cd037e47887bc5d40628128818e6 Author: Tollef Fog Heen Date: Thu Oct 13 08:33:36 2011 +0200 Use = rather than := in Makefile to make solaris make stop whining on distcheck diff --git a/lib/libjemalloc/Makefile.am b/lib/libjemalloc/Makefile.am index 32b3462..63f5c7a 100644 --- a/lib/libjemalloc/Makefile.am +++ b/lib/libjemalloc/Makefile.am @@ -1,6 +1,6 @@ # See source code comments to avoid memory leaks when enabling MALLOC_MAG. -#CPPFLAGS := -DMALLOC_PRODUCTION -DMALLOC_MAG -AM_CPPFLAGS := -DMALLOC_PRODUCTION +#CPPFLAGS = -DMALLOC_PRODUCTION -DMALLOC_MAG +AM_CPPFLAGS = -DMALLOC_PRODUCTION #all: libjemalloc.so.0 libjemalloc_mt.so.0 From apj at varnish-cache.org Thu Oct 13 07:30:59 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Thu, 13 Oct 2011 09:30:59 +0200 Subject: [master] 28e866b Update docs for 3.0 Fixes #1032 Message-ID: commit 28e866b59ba0e9c95bdf314965d5895698616136 Author: Andreas Plesner Jacobsen Date: Thu Oct 13 09:30:27 2011 +0200 Update docs for 3.0 Fixes #1032 diff --git a/doc/sphinx/tutorial/esi.rst b/doc/sphinx/tutorial/esi.rst index ef79f3e..1d01cb8 100644 --- a/doc/sphinx/tutorial/esi.rst +++ b/doc/sphinx/tutorial/esi.rst @@ -48,9 +48,9 @@ For ESI to work you need to activate ESI processing in VCL, like this::: sub vcl_fetch { if (req.url == "/test.html") { set beresp.do_esi = true; /* Do ESI processing */ - set obj.ttl = 24 h; /* Sets the TTL on the HTML above */ + set beresp.ttl = 24 h; /* Sets the TTL on the HTML above */ } elseif (req.url == "/cgi-bin/date.cgi") { - set obj.ttl = 1m; /* Sets a one minute TTL on */ + set beresp.ttl = 1m; /* Sets a one minute TTL on */ /* the included object */ } } From phk at varnish-cache.org Thu Oct 13 09:56:56 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 13 Oct 2011 11:56:56 +0200 Subject: [master] 69e59af Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 69e59af21e03867ca4c92aa8a29bfb41383401b4 Merge: a641a46 28e866b Author: Poul-Henning Kamp Date: Thu Oct 13 09:56:51 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From phk at varnish-cache.org Thu Oct 13 09:56:56 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 13 Oct 2011 11:56:56 +0200 Subject: [master] a641a46 Move the manager process sources into a subdirectory, away from the gaze of prying VMODs. Message-ID: commit a641a46cfe0e00e7104db050f459faeaa324a046 Author: Poul-Henning Kamp Date: Thu Oct 13 09:42:36 2011 +0000 Move the manager process sources into a subdirectory, away from the gaze of prying VMODs. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 499cb6c..f2e9d04 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -55,14 +55,14 @@ varnishd_SOURCES = \ hash/hash_classic.c \ hash/hash_critbit.c \ hash/hash_simple_list.c \ - mgt_child.c \ - mgt_cli.c \ - mgt_param.c \ - mgt_pool.c \ - mgt_sandbox.c \ - mgt_sandbox_solaris.c \ - mgt_shmem.c \ - mgt_vcc.c \ + mgt/mgt_child.c \ + mgt/mgt_cli.c \ + mgt/mgt_param.c \ + mgt/mgt_pool.c \ + mgt/mgt_sandbox.c \ + mgt/mgt_sandbox_solaris.c \ + mgt/mgt_shmem.c \ + mgt/mgt_vcc.c \ rfc2616.c \ storage/stevedore.c \ storage/stevedore_utils.c \ @@ -86,8 +86,8 @@ noinst_HEADERS = \ default_vcl.h \ hash/hash_slinger.h \ heritage.h \ - mgt.h \ - mgt_cli.h \ + mgt/mgt.h \ + mgt/mgt_cli.h \ storage/storage.h \ storage/storage_persistent.h \ vparam.h @@ -128,7 +128,7 @@ default_vcl.h: default.vcl Makefile -e 's/^/ "/' $(srcdir)/default.vcl >> $@ # Explicitly record dependency -mgt_vcc.c: default_vcl.h +mgt/mgt_vcc.c: default_vcl.h varnishd.1: $(top_srcdir)/doc/sphinx/reference/varnishd.rst if HAVE_RST2MAN diff --git a/bin/varnishd/flint.sh b/bin/varnishd/flint.sh index 357d280..4beb9d5 100755 --- a/bin/varnishd/flint.sh +++ b/bin/varnishd/flint.sh @@ -18,6 +18,8 @@ flexelint \ *.c \ storage/*.c \ waiter/*.c \ + hash/*.c \ + mgt/*.c \ ../../lib/libvarnish/*.c \ ../../lib/libvarnishcompat/execinfo.c \ ../../lib/libvcl/*.c \ diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h deleted file mode 100644 index 1656af8..0000000 --- a/bin/varnishd/mgt.h +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - */ - -#include - -#include "common.h" - -struct cli; - -extern struct vev_base *mgt_evb; -extern unsigned d_flag; -extern int exit_status; - -/* mgt_child.c */ -extern pid_t child_pid; -void MGT_Run(void); -void mgt_stop_child(void); -void mgt_got_fd(int fd); -void MGT_Child_Cli_Fail(void); - -/* mgt_cli.c */ - -typedef void mgt_cli_close_f(void *priv); -void mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident, mgt_cli_close_f *close_func, void *priv); -int mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...); -void mgt_cli_start_child(int fdi, int fdo); -void mgt_cli_stop_child(void); -void mgt_cli_telnet(const char *T_arg); -void mgt_cli_master(const char *M_arg); -void mgt_cli_secret(const char *S_arg); -void mgt_cli_close_all(void); - -/* mgt_param.c */ -void MCF_ParamSync(void); -void MCF_ParamInit(struct cli *); -void MCF_ParamSet(struct cli *, const char *param, const char *val); -void MCF_DumpRst(void); - -/* mgt_sandbox.c */ -void mgt_sandbox(void); - -/* mgt_sandbox_solaris.c */ -#ifdef HAVE_SETPPRIV -void mgt_sandbox_solaris_init(void); -void mgt_sandbox_solaris_fini(void); -void mgt_sandbox_solaris_privsep(void); -#endif - -/* mgt_shmem.c */ -void mgt_SHM_Init(const char *arg); -void mgt_SHM_Pid(void); - -/* mgt_vcc.c */ -void mgt_vcc_init(void); -int mgt_vcc_default(const char *bflag, const char *f_arg, char *vcl, int Cflag); -int mgt_push_vcls_and_start(unsigned *status, char **p); -int mgt_has_vcl(void); -extern char *mgt_cc_cmd; -extern const char *mgt_vcl_dir; -extern const char *mgt_vmod_dir; -extern unsigned mgt_vcc_err_unref; - - -#define REPORT0(pri, fmt) \ - do { \ - fprintf(stderr, fmt "\n"); \ - syslog(pri, fmt); \ - } while (0) - -#define REPORT(pri, fmt, ...) \ - do { \ - fprintf(stderr, fmt "\n", __VA_ARGS__); \ - syslog(pri, fmt, __VA_ARGS__); \ - } while (0) - -#define VSM_Alloc(a, b, c, d) VSM__Alloc(a,b,c,d) -#define VSM_Free(a) VSM__Free(a) -#define VSM_Clean() VSM__Clean() - - -#if defined(PTHREAD_CANCELED) || defined(PTHREAD_MUTEX_DEFAULT) -#error "Keep pthreads out of in manager process" -#endif diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h new file mode 100644 index 0000000..1656af8 --- /dev/null +++ b/bin/varnishd/mgt/mgt.h @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + */ + +#include + +#include "common.h" + +struct cli; + +extern struct vev_base *mgt_evb; +extern unsigned d_flag; +extern int exit_status; + +/* mgt_child.c */ +extern pid_t child_pid; +void MGT_Run(void); +void mgt_stop_child(void); +void mgt_got_fd(int fd); +void MGT_Child_Cli_Fail(void); + +/* mgt_cli.c */ + +typedef void mgt_cli_close_f(void *priv); +void mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident, mgt_cli_close_f *close_func, void *priv); +int mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...); +void mgt_cli_start_child(int fdi, int fdo); +void mgt_cli_stop_child(void); +void mgt_cli_telnet(const char *T_arg); +void mgt_cli_master(const char *M_arg); +void mgt_cli_secret(const char *S_arg); +void mgt_cli_close_all(void); + +/* mgt_param.c */ +void MCF_ParamSync(void); +void MCF_ParamInit(struct cli *); +void MCF_ParamSet(struct cli *, const char *param, const char *val); +void MCF_DumpRst(void); + +/* mgt_sandbox.c */ +void mgt_sandbox(void); + +/* mgt_sandbox_solaris.c */ +#ifdef HAVE_SETPPRIV +void mgt_sandbox_solaris_init(void); +void mgt_sandbox_solaris_fini(void); +void mgt_sandbox_solaris_privsep(void); +#endif + +/* mgt_shmem.c */ +void mgt_SHM_Init(const char *arg); +void mgt_SHM_Pid(void); + +/* mgt_vcc.c */ +void mgt_vcc_init(void); +int mgt_vcc_default(const char *bflag, const char *f_arg, char *vcl, int Cflag); +int mgt_push_vcls_and_start(unsigned *status, char **p); +int mgt_has_vcl(void); +extern char *mgt_cc_cmd; +extern const char *mgt_vcl_dir; +extern const char *mgt_vmod_dir; +extern unsigned mgt_vcc_err_unref; + + +#define REPORT0(pri, fmt) \ + do { \ + fprintf(stderr, fmt "\n"); \ + syslog(pri, fmt); \ + } while (0) + +#define REPORT(pri, fmt, ...) \ + do { \ + fprintf(stderr, fmt "\n", __VA_ARGS__); \ + syslog(pri, fmt, __VA_ARGS__); \ + } while (0) + +#define VSM_Alloc(a, b, c, d) VSM__Alloc(a,b,c,d) +#define VSM_Free(a) VSM__Free(a) +#define VSM_Clean() VSM__Clean() + + +#if defined(PTHREAD_CANCELED) || defined(PTHREAD_MUTEX_DEFAULT) +#error "Keep pthreads out of in manager process" +#endif diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c new file mode 100644 index 0000000..ff8a776 --- /dev/null +++ b/bin/varnishd/mgt/mgt_child.c @@ -0,0 +1,673 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * The mechanics of handling the child process + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "heritage.h" +#include "vapi/vsm_int.h" +#include "vbm.h" +#include "vcli.h" +#include "vcli_priv.h" +#include "vev.h" +#include "vlu.h" +#include "vss.h" +#include "vtcp.h" +#include "vtim.h" + +#include "mgt_cli.h" + +pid_t child_pid = -1; + + +static struct vbitmap *fd_map; + +static int child_cli_in = -1; +static int child_VCLI_Out = -1; +static int child_output = -1; + +static enum { + CH_STOPPED = 0, + CH_STARTING = 1, + CH_RUNNING = 2, + CH_STOPPING = 3, + CH_DIED = 4 +} child_state = CH_STOPPED; + +static const char * const ch_state[] = { + [CH_STOPPED] = "stopped", + [CH_STARTING] = "starting", + [CH_RUNNING] = "running", + [CH_STOPPING] = "stopping", + [CH_DIED] = "died, (restarting)", +}; + +static struct vev *ev_poker; +static struct vev *ev_listen; +static struct vlu *vlu; + +static struct vsb *child_panic = NULL; + +/*-------------------------------------------------------------------- + * Track the highest file descriptor the parent knows is being used. + * + * This allows the child process to clean/close only a small fraction + * of the possible file descriptors after exec(2). + * + * This is likely to a bit on the low side, as libc and other libraries + * has a tendency to cache file descriptors (syslog, resolver, etc.) + * so we add a margin of 100 fds. + */ + +static int mgt_max_fd; + +#define CLOSE_FD_UP_TO (mgt_max_fd + 100) + +void +mgt_got_fd(int fd) +{ + /* + * Assert > 0, to catch bogus opens, we know where stdin goes + * in the master process. + */ + assert(fd > 0); + if (fd > mgt_max_fd) + mgt_max_fd = fd; +} + +/*-------------------------------------------------------------------- + * A handy little function + */ + +static inline void +closex(int *fd) +{ + + assert(*fd >= 0); + AZ(close(*fd)); + *fd = -1; +} + +/*-------------------------------------------------------------------- + * Keep track of which filedescriptors the child should inherit and + * which should be closed after fork() + */ + +void +mgt_child_inherit(int fd, const char *what) +{ + + assert(fd >= 0); + if (fd_map == NULL) + fd_map = vbit_init(128); + AN(fd_map); + if (what != NULL) + vbit_set(fd_map, fd); + else + vbit_clr(fd_map, fd); +} + +/*--------------------------------------------------------------------*/ + +static int +child_line(void *priv, const char *p) +{ + (void)priv; + + REPORT(LOG_NOTICE, "Child (%jd) said %s", (intmax_t)child_pid, p); + return (0); +} + +/*--------------------------------------------------------------------*/ + +static int +child_listener(const struct vev *e, int what) +{ + + (void)e; + if ((what & ~EV_RD)) { + ev_listen = NULL; + return (1); + } + if (VLU_Fd(child_output, vlu)) { + ev_listen = NULL; + return (1); + } + return (0); +} + +/*--------------------------------------------------------------------*/ + +static int +child_poker(const struct vev *e, int what) +{ + + (void)e; + (void)what; + if (child_state != CH_RUNNING) + return (1); + if (child_pid < 0) + return (0); + if (!mgt_cli_askchild(NULL, NULL, "ping\n")) + return (0); + return (0); +} + +/*-------------------------------------------------------------------- + * If CLI communications with the child process fails, there is nothing + * for us to do but to drag it behind the barn and get it over with. + * + * The typical case is where the child process fails to return a reply + * before the cli_timeout expires. This invalidates the CLI pipes for + * all future use, as we don't know if the child was just slow and the + * result gets piped later on, or if the child is catatonic. + */ + +void +MGT_Child_Cli_Fail(void) +{ + + if (child_state != CH_RUNNING) + return; + if (child_pid < 0) + return; + REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", + (intmax_t)child_pid); + if (params->diag_bitmap & 0x1000) + (void)kill(child_pid, SIGKILL); + else + (void)kill(child_pid, SIGQUIT); +} + +/*--------------------------------------------------------------------*/ + +static int +open_sockets(void) +{ + struct listen_sock *ls, *ls2; + int good = 0; + + VTAILQ_FOREACH_SAFE(ls, &heritage.socks, list, ls2) { + if (ls->sock >= 0) { + good++; + continue; + } + ls->sock = VSS_bind(ls->addr); + if (ls->sock < 0) + continue; + + mgt_child_inherit(ls->sock, "sock"); + + /* + * Set nonblocking mode to avoid a race where a client + * closes before we call accept(2) and nobody else are in + * the listen queue to release us. + */ + (void)VTCP_filter_http(ls->sock); + good++; + } + if (!good) + return (1); + return (0); +} + +/*--------------------------------------------------------------------*/ + +static void +close_sockets(void) +{ + struct listen_sock *ls; + + VTAILQ_FOREACH(ls, &heritage.socks, list) { + if (ls->sock < 0) + continue; + mgt_child_inherit(ls->sock, NULL); + closex(&ls->sock); + } +} + +/*--------------------------------------------------------------------*/ + +static void +start_child(struct cli *cli) +{ + pid_t pid; + unsigned u; + char *p; + struct vev *e; + int i, cp[2]; + + if (child_state != CH_STOPPED && child_state != CH_DIED) + return; + + if (open_sockets() != 0) { + child_state = CH_STOPPED; + if (cli != NULL) { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "Could not open sockets"); + return; + } + REPORT0(LOG_ERR, + "Child start failed: could not open sockets"); + return; + } + + child_state = CH_STARTING; + + /* Open pipe for mgr->child CLI */ + AZ(pipe(cp)); + heritage.cli_in = cp[0]; + mgt_child_inherit(heritage.cli_in, "cli_in"); + child_VCLI_Out = cp[1]; + + /* Open pipe for child->mgr CLI */ + AZ(pipe(cp)); + heritage.VCLI_Out = cp[1]; + mgt_child_inherit(heritage.VCLI_Out, "VCLI_Out"); + child_cli_in = cp[0]; + + /* + * Open pipe for child stdout/err + * NB: not inherited, because we dup2() it to stdout/stderr in child + */ + AZ(pipe(cp)); + heritage.std_fd = cp[1]; + child_output = cp[0]; + + MCF_ParamSync(); + if ((pid = fork()) < 0) { + perror("Could not fork child"); + exit(1); + } + if (pid == 0) { + + /* Redirect stdin/out/err */ + AZ(close(STDIN_FILENO)); + assert(open("/dev/null", O_RDONLY) == STDIN_FILENO); + assert(dup2(heritage.std_fd, STDOUT_FILENO) == STDOUT_FILENO); + assert(dup2(heritage.std_fd, STDERR_FILENO) == STDERR_FILENO); + + /* Close anything we shouldn't know about */ + closelog(); + for (i = STDERR_FILENO + 1; i < CLOSE_FD_UP_TO; i++) { + if (vbit_test(fd_map, i)) + continue; + (void)(close(i) == 0); + } +#ifdef HAVE_SETPROCTITLE + setproctitle("Varnish-Chld %s", heritage.name); +#endif + + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGTERM, SIG_DFL); + + mgt_sandbox(); + + child_main(); + + exit(1); + } + REPORT(LOG_NOTICE, "child (%jd) Started", (intmax_t)pid); + + /* Close stuff the child got */ + closex(&heritage.std_fd); + + mgt_child_inherit(heritage.cli_in, NULL); + closex(&heritage.cli_in); + + mgt_child_inherit(heritage.VCLI_Out, NULL); + closex(&heritage.VCLI_Out); + + close_sockets(); + + vlu = VLU_New(NULL, child_line, 0); + AN(vlu); + + AZ(ev_listen); + e = vev_new(); + XXXAN(e); + e->fd = child_output; + e->fd_flags = EV_RD; + e->name = "Child listener"; + e->callback = child_listener; + AZ(vev_add(mgt_evb, e)); + ev_listen = e; + AZ(ev_poker); + if (params->ping_interval > 0) { + e = vev_new(); + XXXAN(e); + e->timeout = params->ping_interval; + e->callback = child_poker; + e->name = "child poker"; + AZ(vev_add(mgt_evb, e)); + ev_poker = e; + } + + mgt_cli_start_child(child_cli_in, child_VCLI_Out); + child_pid = pid; + if (mgt_push_vcls_and_start(&u, &p)) { + REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p); + free(p); + child_state = CH_RUNNING; + mgt_stop_child(); + } else + child_state = CH_RUNNING; +} + +/*--------------------------------------------------------------------*/ + +void +mgt_stop_child(void) +{ + + if (child_state != CH_RUNNING) + return; + + child_state = CH_STOPPING; + + REPORT0(LOG_DEBUG, "Stopping Child"); + if (ev_poker != NULL) { + vev_del(mgt_evb, ev_poker); + free(ev_poker); + } + ev_poker = NULL; + + mgt_cli_stop_child(); + + /* We tell the child to die gracefully by closing the CLI */ + closex(&child_VCLI_Out); + closex(&child_cli_in); +} + +/*--------------------------------------------------------------------*/ + +static void +mgt_report_panic(pid_t r) +{ + + if (VSM_head->panicstr[0] == '\0') + return; + REPORT(LOG_ERR, "Child (%jd) Panic message: %s", + (intmax_t)r, VSM_head->panicstr); +} + +static void +mgt_save_panic(void) +{ + char time_str[30]; + if (VSM_head->panicstr[0] == '\0') + return; + + if (child_panic) + VSB_delete(child_panic); + child_panic = VSB_new_auto(); + XXXAN(child_panic); + VTIM_format(VTIM_real(), time_str); + VSB_printf(child_panic, "Last panic at: %s\n", time_str); + VSB_cat(child_panic, VSM_head->panicstr); + AZ(VSB_finish(child_panic)); +} + +static void +mgt_clear_panic(void) +{ + VSB_delete(child_panic); + child_panic = NULL; +} + +/*--------------------------------------------------------------------*/ + +static int +mgt_sigchld(const struct vev *e, int what) +{ + int status; + struct vsb *vsb; + pid_t r; + + (void)e; + (void)what; + + if (ev_poker != NULL) { + vev_del(mgt_evb, ev_poker); + free(ev_poker); + } + ev_poker = NULL; + + r = waitpid(child_pid, &status, WNOHANG); + if (r == 0 || (r == -1 && errno == ECHILD)) + return (0); + assert(r == child_pid); + vsb = VSB_new_auto(); + XXXAN(vsb); + VSB_printf(vsb, "Child (%d) %s", r, status ? "died" : "ended"); + if (WIFEXITED(status) && WEXITSTATUS(status)) { + VSB_printf(vsb, " status=%d", WEXITSTATUS(status)); + exit_status |= 0x20; + } + if (WIFSIGNALED(status)) { + VSB_printf(vsb, " signal=%d", WTERMSIG(status)); + exit_status |= 0x40; + } +#ifdef WCOREDUMP + if (WCOREDUMP(status)) { + VSB_printf(vsb, " (core dumped)"); + exit_status |= 0x80; + } +#endif + AZ(VSB_finish(vsb)); + REPORT(LOG_INFO, "%s", VSB_data(vsb)); + VSB_delete(vsb); + + mgt_report_panic(r); + mgt_save_panic(); + + child_pid = -1; + + if (child_state == CH_RUNNING) { + child_state = CH_DIED; + mgt_cli_stop_child(); + closex(&child_VCLI_Out); + closex(&child_cli_in); + } + + if (ev_listen != NULL) { + vev_del(mgt_evb, ev_listen); + free(ev_listen); + ev_listen = NULL; + } + /* Pick up any stuff lingering on stdout/stderr */ + (void)child_listener(NULL, EV_RD); + closex(&child_output); + + REPORT0(LOG_DEBUG, "Child cleanup complete"); + + if (child_state == CH_DIED && params->auto_restart) + start_child(NULL); + else if (child_state == CH_DIED) { + child_state = CH_STOPPED; + } else if (child_state == CH_STOPPING) + child_state = CH_STOPPED; + + return (0); +} + +/*--------------------------------------------------------------------*/ + +static int +mgt_sigint(const struct vev *e, int what) +{ + + (void)e; + (void)what; + REPORT0(LOG_ERR, "Manager got SIGINT"); + (void)fflush(stdout); + if (child_pid >= 0) + mgt_stop_child(); + exit (2); +} + +/*-------------------------------------------------------------------- + * This thread is the master thread in the management process. + * The relatively simple task is to start and stop the child process + * and to reincarnate it in case of trouble. + */ + +void +MGT_Run(void) +{ + struct sigaction sac; + struct vev *e; + int i; + + e = vev_new(); + XXXAN(e); + e->sig = SIGTERM; + e->callback = mgt_sigint; + e->name = "mgt_sigterm"; + AZ(vev_add(mgt_evb, e)); + + e = vev_new(); + XXXAN(e); + e->sig = SIGINT; + e->callback = mgt_sigint; + e->name = "mgt_sigint"; + AZ(vev_add(mgt_evb, e)); + + e = vev_new(); + XXXAN(e); + e->sig = SIGCHLD; + e->sig_flags = SA_NOCLDSTOP; + e->callback = mgt_sigchld; + e->name = "mgt_sigchild"; + AZ(vev_add(mgt_evb, e)); + +#ifdef HAVE_SETPROCTITLE + setproctitle("Varnish-Mgr %s", heritage.name); +#endif + + memset(&sac, 0, sizeof sac); + sac.sa_handler = SIG_IGN; + sac.sa_flags = SA_RESTART; + + AZ(sigaction(SIGPIPE, &sac, NULL)); + AZ(sigaction(SIGHUP, &sac, NULL)); + + if (!d_flag && !mgt_has_vcl()) + REPORT0(LOG_ERR, "No VCL loaded yet"); + else if (!d_flag) { + start_child(NULL); + if (child_state == CH_STOPPED) { + exit_status = 2; + return; + } + } + + i = vev_schedule(mgt_evb); + if (i != 0) + REPORT(LOG_ERR, "vev_schedule() = %d", i); + + REPORT0(LOG_ERR, "manager dies"); +} + +/*--------------------------------------------------------------------*/ + +void __match_proto__(cli_func_t) +mcf_server_startstop(struct cli *cli, const char * const *av, void *priv) +{ + + (void)av; + if (priv != NULL && child_state == CH_RUNNING) + mgt_stop_child(); + else if (priv == NULL && child_state == CH_STOPPED) { + if (mgt_has_vcl()) { + start_child(cli); + } else { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "No VCL available"); + } + } else { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "Child in state %s", ch_state[child_state]); + } +} + +/*--------------------------------------------------------------------*/ + +void +mcf_server_status(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + VCLI_Out(cli, "Child in state %s", ch_state[child_state]); +} + +void +mcf_panic_show(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + + if (!child_panic) { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "Child has not panicked or panic has been cleared"); + return; + } + + VCLI_Out(cli, "%s\n", VSB_data(child_panic)); +} + +void +mcf_panic_clear(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + + if (!child_panic) { + VCLI_SetResult(cli, CLIS_CANT); + VCLI_Out(cli, "No panic to clear"); + return; + } + + mgt_clear_panic(); +} diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c new file mode 100644 index 0000000..c8f22c3 --- /dev/null +++ b/bin/varnishd/mgt/mgt_cli.c @@ -0,0 +1,663 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * The management process' CLI handling + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "heritage.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" +#include "vcli_serve.h" +#include "vev.h" +#include "vlu.h" +#include "vss.h" +#include "vtcp.h" + +#include "mgt_cli.h" + +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif + +static int cli_i = -1, cli_o = -1; +static struct VCLS *cls; +static const char *secret_file; + +#define MCF_NOAUTH 0 /* NB: zero disables here-documents */ +#define MCF_AUTH 16 + +/*--------------------------------------------------------------------*/ + +static void +mcf_banner(struct cli *cli, const char *const *av, void *priv) +{ + + (void)av; + (void)priv; + VCLI_Out(cli, "-----------------------------\n"); + VCLI_Out(cli, "Varnish Cache CLI 1.0\n"); + VCLI_Out(cli, "-----------------------------\n"); + VCLI_Out(cli, "%s\n", VSB_data(vident) + 1); + VCLI_Out(cli, "\n"); + VCLI_Out(cli, "Type 'help' for command list.\n"); + VCLI_Out(cli, "Type 'quit' to close CLI session.\n"); + if (child_pid < 0) + VCLI_Out(cli, "Type 'start' to launch worker process.\n"); + VCLI_SetResult(cli, CLIS_OK); +} + +/*--------------------------------------------------------------------*/ + +/* XXX: what order should this list be in ? */ +static struct cli_proto cli_proto[] = { + { CLI_BANNER, "", mcf_banner, NULL }, + { CLI_SERVER_STATUS, "", mcf_server_status, NULL }, + { CLI_SERVER_START, "", mcf_server_startstop, NULL }, + { CLI_SERVER_STOP, "", mcf_server_startstop, cli_proto }, + { CLI_VCL_LOAD, "", mcf_config_load, NULL }, + { CLI_VCL_INLINE, "", mcf_config_inline, NULL }, + { CLI_VCL_USE, "", mcf_config_use, NULL }, + { CLI_VCL_DISCARD, "", mcf_config_discard, NULL }, + { CLI_VCL_LIST, "", mcf_config_list, NULL }, + { CLI_VCL_SHOW, "", mcf_config_show, NULL }, + { CLI_PARAM_SHOW, "", mcf_param_show, NULL }, + { CLI_PARAM_SET, "", mcf_param_set, NULL }, + { CLI_PANIC_SHOW, "", mcf_panic_show, NULL }, + { CLI_PANIC_CLEAR, "", mcf_panic_clear, NULL }, + { NULL } +}; + +/*--------------------------------------------------------------------*/ + +static void +mcf_panic(struct cli *cli, const char * const *av, void *priv) +{ + + (void)cli; + (void)av; + (void)priv; + assert(!strcmp("", "You asked for it")); +} + +static struct cli_proto cli_debug[] = { + { "debug.panic.master", "debug.panic.master", + "\tPanic the master process.\n", + 0, 0, "d", mcf_panic, NULL}, + { NULL } +}; + +/*--------------------------------------------------------------------*/ + +static void +mcf_askchild(struct cli *cli, const char * const *av, void *priv) +{ + int i; + char *q; + unsigned u; + struct vsb *vsb; + + (void)priv; + /* + * Command not recognized in master, try cacher if it is + * running. + */ + if (cli_o <= 0) { + if (!strcmp(av[1], "help")) { + VCLI_Out(cli, "No help from child, (not running).\n"); + return; + } + VCLI_SetResult(cli, CLIS_UNKNOWN); + VCLI_Out(cli, + "Unknown request in manager process " + "(child not running).\n" + "Type 'help' for more info."); + return; + } + vsb = VSB_new_auto(); + for (i = 1; av[i] != NULL; i++) { + VSB_quote(vsb, av[i], strlen(av[i]), 0); + VSB_putc(vsb, ' '); + } + VSB_putc(vsb, '\n'); + AZ(VSB_finish(vsb)); + i = write(cli_o, VSB_data(vsb), VSB_len(vsb)); + if (i != VSB_len(vsb)) { + VSB_delete(vsb); + VCLI_SetResult(cli, CLIS_COMMS); + VCLI_Out(cli, "CLI communication error"); + MGT_Child_Cli_Fail(); + return; + } + VSB_delete(vsb); + (void)VCLI_ReadResult(cli_i, &u, &q, params->cli_timeout); + VCLI_SetResult(cli, u); + VCLI_Out(cli, "%s", q); + free(q); +} + +static struct cli_proto cli_askchild[] = { + { "*", "", "\t\n", + 0, 9999, "h*", mcf_askchild, NULL}, + { NULL } +}; + +/*-------------------------------------------------------------------- + * Ask the child something over CLI, return zero only if everything is + * happy happy. + */ + +int +mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) { + int i, j; + va_list ap; + unsigned u; + char buf[params->cli_buffer], *p; + + if (resp != NULL) + *resp = NULL; + if (status != NULL) + *status = 0; + if (cli_i < 0|| cli_o < 0) { + if (status != NULL) + *status = CLIS_CANT; + return (CLIS_CANT); + } + va_start(ap, fmt); + vbprintf(buf, fmt, ap); + va_end(ap); + p = strchr(buf, '\0'); + assert(p != NULL && p > buf && p[-1] == '\n'); + i = p - buf; + j = write(cli_o, buf, i); + if (j != i) { + if (status != NULL) + *status = CLIS_COMMS; + if (resp != NULL) + *resp = strdup("CLI communication error"); + MGT_Child_Cli_Fail(); + return (CLIS_COMMS); + } + + (void)VCLI_ReadResult(cli_i, &u, resp, params->cli_timeout); + if (status != NULL) + *status = u; + if (u == CLIS_COMMS) + MGT_Child_Cli_Fail(); + return (u == CLIS_OK ? 0 : u); +} + +/*--------------------------------------------------------------------*/ + +void +mgt_cli_start_child(int fdi, int fdo) +{ + + cli_i = fdi; + cli_o = fdo; +} + +/*--------------------------------------------------------------------*/ + +void +mgt_cli_stop_child(void) +{ + + cli_i = -1; + cli_o = -1; + /* XXX: kick any users */ +} + +/*-------------------------------------------------------------------- + * Generate a random challenge + */ + +static void +mgt_cli_challenge(struct cli *cli) +{ + int i; + + for (i = 0; i + 2L < sizeof cli->challenge; i++) + cli->challenge[i] = (random() % 26) + 'a'; + cli->challenge[i++] = '\n'; + cli->challenge[i] = '\0'; + VCLI_Out(cli, "%s", cli->challenge); + VCLI_Out(cli, "\nAuthentication required.\n"); + VCLI_SetResult(cli, CLIS_AUTH); +} + +/*-------------------------------------------------------------------- + * Validate the authentication + */ + +static void +mcf_auth(struct cli *cli, const char *const *av, void *priv) +{ + int fd; + char buf[CLI_AUTH_RESPONSE_LEN + 1]; + + AN(av[2]); + (void)priv; + if (secret_file == NULL) { + VCLI_Out(cli, "Secret file not configured\n"); + VCLI_SetResult(cli, CLIS_CANT); + return; + } + fd = open(secret_file, O_RDONLY); + if (fd < 0) { + VCLI_Out(cli, "Cannot open secret file (%s)\n", + strerror(errno)); + VCLI_SetResult(cli, CLIS_CANT); + return; + } + mgt_got_fd(fd); + VCLI_AuthResponse(fd, cli->challenge, buf); + AZ(close(fd)); + if (strcasecmp(buf, av[2])) { + mgt_cli_challenge(cli); + return; + } + cli->auth = MCF_AUTH; + memset(cli->challenge, 0, sizeof cli->challenge); + VCLI_SetResult(cli, CLIS_OK); + mcf_banner(cli, av, priv); +} + +static struct cli_proto cli_auth[] = { + { CLI_HELP, "", VCLS_func_help, NULL }, + { CLI_PING, "", VCLS_func_ping }, + { CLI_AUTH, "", mcf_auth, NULL }, + { CLI_QUIT, "", VCLS_func_close, NULL}, + { NULL } +}; + +/*--------------------------------------------------------------------*/ +static void +mgt_cli_cb_before(const struct cli *cli) +{ + + if (params->syslog_cli_traffic) + syslog(LOG_NOTICE, "CLI %s Rd %s", cli->ident, cli->cmd); +} + +static void +mgt_cli_cb_after(const struct cli *cli) +{ + + if (params->syslog_cli_traffic) + syslog(LOG_NOTICE, "CLI %s Wr %03u %s", + cli->ident, cli->result, VSB_data(cli->sb)); +} + +/*--------------------------------------------------------------------*/ + +static void +mgt_cli_init_cls(void) +{ + + cls = VCLS_New(mgt_cli_cb_before, mgt_cli_cb_after, params->cli_buffer); + AN(cls); + AZ(VCLS_AddFunc(cls, MCF_NOAUTH, cli_auth)); + AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_proto)); + AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_debug)); + AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_stv)); + AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_askchild)); +} + +/*-------------------------------------------------------------------- + * Get rid of all CLI sessions + */ + +void +mgt_cli_close_all(void) +{ + + VCLS_Destroy(&cls); +} + +/*-------------------------------------------------------------------- + * Callback whenever something happens to the input fd of the session. + */ + +static int +mgt_cli_callback2(const struct vev *e, int what) +{ + int i; + + (void)e; + (void)what; + i = VCLS_PollFd(cls, e->fd, 0); + return (i); +} + +/*--------------------------------------------------------------------*/ + +void +mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident, mgt_cli_close_f *closefunc, void *priv) +{ + struct cli *cli; + struct vev *ev; + + (void)ident; + (void)verbose; + if (cls == NULL) + mgt_cli_init_cls(); + + cli = VCLS_AddFd(cls, fdi, fdo, closefunc, priv); + + cli->ident = strdup(ident); + + /* Deal with TELNET options */ + if (fdi != 0) + VLU_SetTelnet(cli->vlu, fdo); + + if (fdi != 0 && secret_file != NULL) { + cli->auth = MCF_NOAUTH; + mgt_cli_challenge(cli); + } else { + cli->auth = MCF_AUTH; + mcf_banner(cli, NULL, NULL); + } + AZ(VSB_finish(cli->sb)); + (void)VCLI_WriteResult(fdo, cli->result, VSB_data(cli->sb)); + + + ev = vev_new(); + AN(ev); + ev->name = cli->ident; + ev->fd = fdi; + ev->fd_flags = EV_RD; + ev->callback = mgt_cli_callback2; + ev->priv = cli; + AZ(vev_add(mgt_evb, ev)); +} + +/*--------------------------------------------------------------------*/ + +static struct vsb * +sock_id(const char *pfx, int fd) +{ + struct vsb *vsb; + + char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; + char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; + + vsb = VSB_new_auto(); + AN(vsb); + VTCP_myname(fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); + VTCP_hisname(fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); + VSB_printf(vsb, "%s %s %s %s %s", pfx, abuf2, pbuf2, abuf1, pbuf1); + AZ(VSB_finish(vsb)); + return (vsb); +} + +/*--------------------------------------------------------------------*/ + +struct telnet { + unsigned magic; +#define TELNET_MAGIC 0x53ec3ac0 + int fd; + struct vev *ev; +}; + +static void +telnet_close(void *priv) +{ + struct telnet *tn; + + CAST_OBJ_NOTNULL(tn, priv, TELNET_MAGIC); + (void)close(tn->fd); + FREE_OBJ(tn); +} + +static struct telnet * +telnet_new(int fd) +{ + struct telnet *tn; + + ALLOC_OBJ(tn, TELNET_MAGIC); + AN(tn); + tn->fd = fd; + return (tn); +} + +static int +telnet_accept(const struct vev *ev, int what) +{ + struct vsb *vsb; + struct sockaddr_storage addr; + socklen_t addrlen; + struct telnet *tn; + int i; + + (void)what; + addrlen = sizeof addr; + i = accept(ev->fd, (void *)&addr, &addrlen); + if (i < 0 && errno == EBADF) + return (1); + if (i < 0) + return (0); + + mgt_got_fd(i); + tn = telnet_new(i); + vsb = sock_id("telnet", i); + mgt_cli_setup(i, i, 0, VSB_data(vsb), telnet_close, tn); + VSB_delete(vsb); + return (0); +} + +void +mgt_cli_secret(const char *S_arg) +{ + int i, fd; + char buf[BUFSIZ]; + char *p; + + /* Save in shmem */ + i = strlen(S_arg); + p = VSM_Alloc(i + 1, "Arg", "-S", ""); + AN(p); + strcpy(p, S_arg); + + srandomdev(); + fd = open(S_arg, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Can not open secret-file \"%s\"\n", S_arg); + exit (2); + } + mgt_got_fd(fd); + i = read(fd, buf, sizeof buf); + if (i == 0) { + fprintf(stderr, "Empty secret-file \"%s\"\n", S_arg); + exit (2); + } + if (i < 0) { + fprintf(stderr, "Can not read secret-file \"%s\"\n", S_arg); + exit (2); + } + AZ(close(fd)); + secret_file = S_arg; +} + +void +mgt_cli_telnet(const char *T_arg) +{ + struct vss_addr **ta; + int i, n, sock, good; + struct telnet *tn; + char *p; + struct vsb *vsb; + char abuf[VTCP_ADDRBUFSIZE]; + char pbuf[VTCP_PORTBUFSIZE]; + + n = VSS_resolve(T_arg, NULL, &ta); + if (n == 0) { + REPORT(LOG_ERR, "-T %s Could not be resolved\n", T_arg); + exit(2); + } + good = 0; + vsb = VSB_new_auto(); + XXXAN(vsb); + for (i = 0; i < n; ++i) { + sock = VSS_listen(ta[i], 10); + if (sock < 0) + continue; + VTCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf); + VSB_printf(vsb, "%s %s\n", abuf, pbuf); + good++; + tn = telnet_new(sock); + tn->ev = vev_new(); + XXXAN(tn->ev); + tn->ev->fd = sock; + tn->ev->fd_flags = POLLIN; + tn->ev->callback = telnet_accept; + AZ(vev_add(mgt_evb, tn->ev)); + free(ta[i]); + ta[i] = NULL; + } + free(ta); + if (good == 0) { + REPORT(LOG_ERR, "-T %s could not be listened on.", T_arg); + exit(2); + } + AZ(VSB_finish(vsb)); + /* Save in shmem */ + p = VSM_Alloc(VSB_len(vsb) + 1, "Arg", "-T", ""); + AN(p); + strcpy(p, VSB_data(vsb)); + VSB_delete(vsb); +} + +/* Reverse CLI ("Master") connections --------------------------------*/ + +static int M_fd = -1; +static struct vev *M_poker, *M_conn; +static struct vss_addr **M_ta; +static int M_nta, M_nxt; +static double M_poll = 0.1; + +static void +Marg_closer(void *priv) +{ + + (void)priv; + (void)close(M_fd); + M_fd = -1; +} + +static int +Marg_poker(const struct vev *e, int what) +{ + struct vsb *vsb; + int s, k; + socklen_t l; + + (void)what; /* XXX: ??? */ + + if (e == M_conn) { + /* Our connect(2) returned, check result */ + l = sizeof k; + AZ(getsockopt(M_fd, SOL_SOCKET, SO_ERROR, &k, &l)); + if (k) { + errno = k; + syslog(LOG_INFO, "Could not connect to CLI-master: %m"); + (void)close(M_fd); + M_fd = -1; + /* Try next address */ + if (++M_nxt >= M_nta) { + M_nxt = 0; + if (M_poll < 10) + M_poll *= 2; + } + return (1); + } + vsb = sock_id("master", M_fd); + mgt_cli_setup(M_fd, M_fd, 0, VSB_data(vsb), Marg_closer, NULL); + VSB_delete(vsb); + M_poll = 1; + return (1); + } + + assert(e == M_poker); + + M_poker->timeout = M_poll; /* XXX nasty ? */ + if (M_fd >= 0) + return (0); + + /* Try to connect asynchronously */ + s = VSS_connect(M_ta[M_nxt], 1); + if (s < 0) + return (0); + + mgt_got_fd(s); + + M_conn = vev_new(); + AN(M_conn); + M_conn->callback = Marg_poker; + M_conn->name = "-M connector"; + M_conn->fd_flags = EV_WR; + M_conn->fd = s; + M_fd = s; + AZ(vev_add(mgt_evb, M_conn)); + return (0); +} + +void +mgt_cli_master(const char *M_arg) +{ + (void)M_arg; + + M_nta = VSS_resolve(M_arg, NULL, &M_ta); + if (M_nta <= 0) { + fprintf(stderr, "Could resolve -M argument to address\n"); + exit (1); + } + M_nxt = 0; + AZ(M_poker); + M_poker = vev_new(); + AN(M_poker); + M_poker->timeout = M_poll; + M_poker->callback = Marg_poker; + M_poker->name = "-M poker"; + AZ(vev_add(mgt_evb, M_poker)); +} diff --git a/bin/varnishd/mgt/mgt_cli.h b/bin/varnishd/mgt/mgt_cli.h new file mode 100644 index 0000000..8c49abb --- /dev/null +++ b/bin/varnishd/mgt/mgt_cli.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2009 Varnish Software 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. + * + */ + +/* mgt_child.c */ +cli_func_t mcf_server_startstop; +cli_func_t mcf_server_status; +cli_func_t mcf_panic_show; +cli_func_t mcf_panic_clear; + +/* mgt_param.c */ +cli_func_t mcf_param_show; +cli_func_t mcf_param_set; + +/* mgt_vcc.c */ +cli_func_t mcf_config_load; +cli_func_t mcf_config_inline; +cli_func_t mcf_config_use; +cli_func_t mcf_config_discard; +cli_func_t mcf_config_list; +cli_func_t mcf_config_show; + +/* stevedore.c */ +extern struct cli_proto cli_stv[]; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c new file mode 100644 index 0000000..1ca6a74 --- /dev/null +++ b/bin/varnishd/mgt/mgt_param.c @@ -0,0 +1,1237 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "waiter/cache_waiter.h" +#include "heritage.h" +#include "vav.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" +#include "vparam.h" +#include "vss.h" + +#include "mgt_cli.h" + +#define MAGIC_INIT_STRING "\001" +struct params master; +static int nparspec; +static struct parspec const ** parspec; +static int margin; + +/*--------------------------------------------------------------------*/ + +static const struct parspec * +mcf_findpar(const char *name) +{ + int i; + + for (i = 0; i < nparspec; i++) + if (!strcmp(parspec[i]->name, name)) + return (parspec[i]); + return (NULL); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_generic_timeout(struct cli *cli, volatile unsigned *dst, const char *arg) +{ + unsigned u; + + if (arg != NULL) { + u = strtoul(arg, NULL, 0); + if (u == 0) { + VCLI_Out(cli, "Timeout must be greater than zero\n"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + *dst = u; + } else + VCLI_Out(cli, "%u", *dst); +} + +/*--------------------------------------------------------------------*/ + +void +tweak_timeout(struct cli *cli, const struct parspec *par, const char *arg) +{ + volatile unsigned *dest; + + dest = par->priv; + tweak_generic_timeout(cli, dest, arg); +} + +static void +tweak_timeout_double(struct cli *cli, const struct parspec *par, + const char *arg) +{ + volatile double *dest; + double u; + + dest = par->priv; + if (arg != NULL) { + u = strtod(arg, NULL); + if (u < par->min) { + VCLI_Out(cli, + "Timeout must be greater or equal to %.g\n", + par->min); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + if (u > par->max) { + VCLI_Out(cli, + "Timeout must be less than or equal to %.g\n", + par->max); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + *dest = u; + } else + VCLI_Out(cli, "%.6f", *dest); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_generic_double(struct cli *cli, const struct parspec *par, + const char *arg) +{ + volatile double *dest; + double u; + + dest = par->priv; + if (arg != NULL) { + u = strtod(arg, NULL); + if (u < par->min) { + VCLI_Out(cli, + "Must be greater or equal to %.g\n", + par->min); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + if (u > par->max) { + VCLI_Out(cli, + "Must be less than or equal to %.g\n", + par->max); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + *dest = u; + } else + VCLI_Out(cli, "%f", *dest); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_generic_bool(struct cli *cli, volatile unsigned *dest, const char *arg) +{ + if (arg != NULL) { + if (!strcasecmp(arg, "off")) + *dest = 0; + else if (!strcasecmp(arg, "disable")) + *dest = 0; + else if (!strcasecmp(arg, "no")) + *dest = 0; + else if (!strcasecmp(arg, "false")) + *dest = 0; + else if (!strcasecmp(arg, "on")) + *dest = 1; + else if (!strcasecmp(arg, "enable")) + *dest = 1; + else if (!strcasecmp(arg, "yes")) + *dest = 1; + else if (!strcasecmp(arg, "true")) + *dest = 1; + else { + VCLI_Out(cli, "use \"on\" or \"off\"\n"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + } else + VCLI_Out(cli, *dest ? "on" : "off"); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) +{ + volatile unsigned *dest; + + dest = par->priv; + tweak_generic_bool(cli, dest, arg); +} + +/*--------------------------------------------------------------------*/ + +void +tweak_generic_uint(struct cli *cli, volatile unsigned *dest, const char *arg, + unsigned min, unsigned max) +{ + unsigned u; + + if (arg != NULL) { + if (!strcasecmp(arg, "unlimited")) + u = UINT_MAX; + else + u = strtoul(arg, NULL, 0); + if (u < min) { + VCLI_Out(cli, "Must be at least %u\n", min); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + if (u > max) { + VCLI_Out(cli, "Must be no more than %u\n", max); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + *dest = u; + } else if (*dest == UINT_MAX) { + VCLI_Out(cli, "unlimited", *dest); + } else { + VCLI_Out(cli, "%u", *dest); + } +} + +/*--------------------------------------------------------------------*/ + +void +tweak_uint(struct cli *cli, const struct parspec *par, const char *arg) +{ + volatile unsigned *dest; + + dest = par->priv; + tweak_generic_uint(cli, dest, arg, (uint)par->min, (uint)par->max); +} + +/*-------------------------------------------------------------------- + * XXX: slightly magic. We want to initialize to "nobody" (XXX: shouldn't + * XXX: that be something autocrap found for us ?) but we don't want to + * XXX: fail initialization if that user doesn't exists, even though we + * XXX: do want to fail it, in subsequent sets. + * XXX: The magic init string is a hack for this. + */ + +static void +tweak_user(struct cli *cli, const struct parspec *par, const char *arg) +{ + struct passwd *pw; + struct group *gr; + + (void)par; + if (arg != NULL) { + if (!strcmp(arg, MAGIC_INIT_STRING)) { + pw = getpwnam("nobody"); + if (pw == NULL) { + master.uid = getuid(); + return; + } + } else + pw = getpwnam(arg); + if (pw == NULL) { + VCLI_Out(cli, "Unknown user"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + REPLACE(master.user, pw->pw_name); + master.uid = pw->pw_uid; + master.gid = pw->pw_gid; + + /* set group to user's primary group */ + if ((gr = getgrgid(pw->pw_gid)) != NULL && + (gr = getgrnam(gr->gr_name)) != NULL && + gr->gr_gid == pw->pw_gid) + REPLACE(master.group, gr->gr_name); + } else if (master.user) { + VCLI_Out(cli, "%s (%d)", master.user, (int)master.uid); + } else { + VCLI_Out(cli, "%d", (int)master.uid); + } +} + +/*-------------------------------------------------------------------- + * XXX: see comment for tweak_user, same thing here. + */ + +static void +tweak_group(struct cli *cli, const struct parspec *par, const char *arg) +{ + struct group *gr; + + (void)par; + if (arg != NULL) { + if (!strcmp(arg, MAGIC_INIT_STRING)) { + gr = getgrnam("nogroup"); + if (gr == NULL) { + /* Only replace if tweak_user didn't */ + if (master.gid == 0) + master.gid = getgid(); + return; + } + } else + gr = getgrnam(arg); + if (gr == NULL) { + VCLI_Out(cli, "Unknown group"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + REPLACE(master.group, gr->gr_name); + master.gid = gr->gr_gid; + } else if (master.group) { + VCLI_Out(cli, "%s (%d)", master.group, (int)master.gid); + } else { + VCLI_Out(cli, "%d", (int)master.gid); + } +} + +/*--------------------------------------------------------------------*/ + +static void +clean_listen_sock_head(struct listen_sock_head *lsh) +{ + struct listen_sock *ls, *ls2; + + VTAILQ_FOREACH_SAFE(ls, lsh, list, ls2) { + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + VTAILQ_REMOVE(lsh, ls, list); + free(ls->name); + free(ls->addr); + FREE_OBJ(ls); + } +} + +static void +tweak_listen_address(struct cli *cli, const struct parspec *par, + const char *arg) +{ + char **av; + int i; + struct listen_sock *ls; + struct listen_sock_head lsh; + + (void)par; + if (arg == NULL) { + VCLI_Quote(cli, master.listen_address); + return; + } + + av = VAV_Parse(arg, NULL, ARGV_COMMA); + if (av == NULL) { + VCLI_Out(cli, "Parse error: out of memory"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + if (av[0] != NULL) { + VCLI_Out(cli, "Parse error: %s", av[0]); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + if (av[1] == NULL) { + VCLI_Out(cli, "Empty listen address"); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + VTAILQ_INIT(&lsh); + for (i = 1; av[i] != NULL; i++) { + struct vss_addr **ta; + int j, n; + + n = VSS_resolve(av[i], "http", &ta); + if (n == 0) { + VCLI_Out(cli, "Invalid listen address "); + VCLI_Quote(cli, av[i]); + VCLI_SetResult(cli, CLIS_PARAM); + break; + } + for (j = 0; j < n; ++j) { + ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC); + AN(ls); + ls->sock = -1; + ls->addr = ta[j]; + ls->name = strdup(av[i]); + AN(ls->name); + VTAILQ_INSERT_TAIL(&lsh, ls, list); + } + free(ta); + } + VAV_Free(av); + if (cli != NULL && cli->result != CLIS_OK) { + clean_listen_sock_head(&lsh); + return; + } + + REPLACE(master.listen_address, arg); + + clean_listen_sock_head(&heritage.socks); + heritage.nsocks = 0; + + while (!VTAILQ_EMPTY(&lsh)) { + ls = VTAILQ_FIRST(&lsh); + VTAILQ_REMOVE(&lsh, ls, list); + CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); + VTAILQ_INSERT_TAIL(&heritage.socks, ls, list); + heritage.nsocks++; + } +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_string(struct cli *cli, const struct parspec *par, const char *arg) +{ + char **p = TRUST_ME(par->priv); + + AN(p); + /* XXX should have tweak_generic_string */ + if (arg == NULL) { + VCLI_Quote(cli, *p); + } else { + REPLACE(*p, arg); + } +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_waiter(struct cli *cli, const struct parspec *par, const char *arg) +{ + + /* XXX should have tweak_generic_string */ + (void)par; + WAIT_tweak_waiter(cli, arg); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_diag_bitmap(struct cli *cli, const struct parspec *par, const char *arg) +{ + unsigned u; + + (void)par; + if (arg != NULL) { + u = strtoul(arg, NULL, 0); + master.diag_bitmap = u; + } else { + VCLI_Out(cli, "0x%x", master.diag_bitmap); + } +} + +/*--------------------------------------------------------------------*/ + +/* + * Make sure to end all lines with either a space or newline of the + * formatting will go haywire. + */ + +#define DELAYED_EFFECT_TEXT \ + "\nNB: This parameter may take quite some time to take (full) effect." + +#define MUST_RESTART_TEXT \ + "\nNB: This parameter will not take any effect until the " \ + "child process has been restarted." + +#define MUST_RELOAD_TEXT \ + "\nNB: This parameter will not take any effect until the " \ + "VCL programs have been reloaded." + +#define EXPERIMENTAL_TEXT \ + "\nNB: We do not know yet if it is a good idea to change " \ + "this parameter, or if the default value is even sensible. " \ + "Caution is advised, and feedback is most welcome." + +#define WIZARD_TEXT \ + "\nNB: Do not change this parameter, unless a developer tell " \ + "you to do so." + +/* + * Remember to update varnishd.1 whenever you add / remove a parameter or + * change its default value. + * XXX: we should generate the relevant section of varnishd.1 from here. + */ +static const struct parspec input_parspec[] = { + { "user", tweak_user, NULL, 0, 0, + "The unprivileged user to run as. Setting this will " + "also set \"group\" to the specified user's primary group.", + MUST_RESTART, + MAGIC_INIT_STRING }, + { "group", tweak_group, NULL, 0, 0, + "The unprivileged group to run as.", + MUST_RESTART, + MAGIC_INIT_STRING }, + { "default_ttl", tweak_timeout_double, &master.default_ttl, + 0, UINT_MAX, + "The TTL assigned to objects if neither the backend nor " + "the VCL code assigns one.\n" + "Objects already cached will not be affected by changes " + "made until they are fetched from the backend again.\n" + "To force an immediate effect at the expense of a total " + "flush of the cache use \"ban.url .\"", + 0, + "120", "seconds" }, + { "sess_workspace", tweak_uint, &master.sess_workspace, 1024, UINT_MAX, + "Bytes of HTTP protocol workspace allocated for sessions. " + "This space must be big enough for the entire HTTP protocol " + "header and any edits done to it in the VCL code.\n" + "Minimum is 1024 bytes.", + DELAYED_EFFECT, + "65536", + "bytes" }, + { "http_req_hdr_len", tweak_uint, &master.http_req_hdr_len, + 40, UINT_MAX, + "Maximum length of any HTTP client request header we will " + "allow. The limit is inclusive its continuation lines.\n", + 0, + "8192", "bytes" }, + { "http_req_size", tweak_uint, &master.http_req_size, + 256, UINT_MAX, + "Maximum number of bytes of HTTP client request we will deal " + "with. This is a limit on all bytes up to the double blank " + "line which ends the HTTP request.\n" + "The memory for the request is allocated from the session " + "workspace (param: sess_workspace) and this parameter limits " + "how much of that the request is allowed to take up.", + 0, + "32768", "bytes" }, + { "http_resp_hdr_len", tweak_uint, &master.http_resp_hdr_len, + 40, UINT_MAX, + "Maximum length of any HTTP backend response header we will " + "allow. The limit is inclusive its continuation lines.\n", + 0, + "8192", "bytes" }, + { "http_resp_size", tweak_uint, &master.http_resp_size, + 256, UINT_MAX, + "Maximum number of bytes of HTTP backend resonse we will deal " + "with. This is a limit on all bytes up to the double blank " + "line which ends the HTTP request.\n" + "The memory for the request is allocated from the worker " + "workspace (param: sess_workspace) and this parameter limits " + "how much of that the request is allowed to take up.", + 0, + "32768", "bytes" }, + { "http_max_hdr", tweak_uint, &master.http_max_hdr, 32, 65535, + "Maximum number of HTTP headers we will deal with in " + "client request or backend reponses. " + "Note that the first line occupies five header fields.\n" + "This paramter does not influence storage consumption, " + "objects allocate exact space for the headers they store.\n", + 0, + "64", "header lines" }, + { "shm_workspace", tweak_uint, &master.shm_workspace, 4096, UINT_MAX, + "Bytes of shmlog workspace allocated for worker threads. " + "If too big, it wastes some ram, if too small it causes " + "needless flushes of the SHM workspace.\n" + "These flushes show up in stats as " + "\"SHM flushes due to overflow\".\n" + "Minimum is 4096 bytes.", + DELAYED_EFFECT, + "8192", "bytes" }, + { "shm_reclen", tweak_uint, &master.shm_reclen, 16, 65535, + "Maximum number of bytes in SHM log record.\n" + "Maximum is 65535 bytes.", + 0, + "255", "bytes" }, + { "default_grace", tweak_timeout_double, &master.default_grace, + 0, UINT_MAX, + "Default grace period. We will deliver an object " + "this long after it has expired, provided another thread " + "is attempting to get a new copy.\n" + "Objects already cached will not be affected by changes " + "made until they are fetched from the backend again.\n", + DELAYED_EFFECT, + "10", "seconds" }, + { "default_keep", tweak_timeout_double, &master.default_keep, + 0, UINT_MAX, + "Default keep period. We will keep a useless object " + "around this long, making it available for conditional " + "backend fetches. " + "That means that the object will be removed from the " + "cache at the end of ttl+grace+keep.", + DELAYED_EFFECT, + "0", "seconds" }, + { "sess_timeout", tweak_timeout, &master.sess_timeout, 0, 0, + "Idle timeout for persistent sessions. " + "If a HTTP request has not been received in this many " + "seconds, the session is closed.", + 0, + "5", "seconds" }, + { "expiry_sleep", tweak_timeout_double, &master.expiry_sleep, 0, 60, + "How long the expiry thread sleeps when there is nothing " + "for it to do.\n", + 0, + "1", "seconds" }, + { "pipe_timeout", tweak_timeout, &master.pipe_timeout, 0, 0, + "Idle timeout for PIPE sessions. " + "If nothing have been received in either direction for " + "this many seconds, the session is closed.\n", + 0, + "60", "seconds" }, + { "send_timeout", tweak_timeout, &master.send_timeout, 0, 0, + "Send timeout for client connections. " + "If the HTTP response hasn't been transmitted in this many\n" + "seconds the session is closed. \n" + "See setsockopt(2) under SO_SNDTIMEO for more information.", + DELAYED_EFFECT, + "60", "seconds" }, + { "auto_restart", tweak_bool, &master.auto_restart, 0, 0, + "Restart child process automatically if it dies.\n", + 0, + "on", "bool" }, + { "nuke_limit", + tweak_uint, &master.nuke_limit, 0, UINT_MAX, + "Maximum number of objects we attempt to nuke in order" + "to make space for a object body.", + EXPERIMENTAL, + "50", "allocations" }, + { "fetch_chunksize", + tweak_uint, &master.fetch_chunksize, 4, UINT_MAX / 1024., + "The default chunksize used by fetcher. " + "This should be bigger than the majority of objects with " + "short TTLs.\n" + "Internal limits in the storage_file module makes increases " + "above 128kb a dubious idea.", + EXPERIMENTAL, + "128", "kilobytes" }, + { "fetch_maxchunksize", + tweak_uint, &master.fetch_maxchunksize, 64, UINT_MAX / 1024., + "The maximum chunksize we attempt to allocate from storage. " + "Making this too large may cause delays and storage " + "fragmentation.\n", + EXPERIMENTAL, + "262144", "kilobytes" }, +#ifdef SENDFILE_WORKS + { "sendfile_threshold", + tweak_uint, &master.sendfile_threshold, 0, UINT_MAX, + "The minimum size of objects transmitted with sendfile.", + EXPERIMENTAL, + "-1", "bytes" }, +#endif /* SENDFILE_WORKS */ + { "vcl_trace", tweak_bool, &master.vcl_trace, 0, 0, + "Trace VCL execution in the shmlog.\n" + "Enabling this will allow you to see the path each " + "request has taken through the VCL program.\n" + "This generates a lot of logrecords so it is off by " + "default.", + 0, + "off", "bool" }, + { "listen_address", tweak_listen_address, NULL, 0, 0, + "Whitespace separated list of network endpoints where " + "Varnish will accept requests.\n" + "Possible formats: host, host:port, :port", + MUST_RESTART, + ":80" }, + { "listen_depth", tweak_uint, &master.listen_depth, 0, UINT_MAX, + "Listen queue depth.", + MUST_RESTART, + "1024", "connections" }, + { "cli_timeout", tweak_timeout, &master.cli_timeout, 0, 0, + "Timeout for the childs replies to CLI requests from " + "the master.", + 0, + "10", "seconds" }, + { "ping_interval", tweak_uint, &master.ping_interval, 0, UINT_MAX, + "Interval between pings from parent to child.\n" + "Zero will disable pinging entirely, which makes " + "it possible to attach a debugger to the child.", + MUST_RESTART, + "3", "seconds" }, + { "lru_interval", tweak_timeout, &master.lru_timeout, 0, 0, + "Grace period before object moves on LRU list.\n" + "Objects are only moved to the front of the LRU " + "list if they have not been moved there already inside " + "this timeout period. This reduces the amount of lock " + "operations necessary for LRU list access.", + EXPERIMENTAL, + "2", "seconds" }, + { "cc_command", tweak_string, &mgt_cc_cmd, 0, 0, + "Command used for compiling the C source code to a " + "dlopen(3) loadable object. Any occurrence of %s in " + "the string will be replaced with the source file name, " + "and %o will be replaced with the output file name.", + MUST_RELOAD, + VCC_CC , NULL }, + { "max_restarts", tweak_uint, &master.max_restarts, 0, UINT_MAX, + "Upper limit on how many times a request can restart." + "\nBe aware that restarts are likely to cause a hit against " + "the backend, so don't increase thoughtlessly.\n", + 0, + "4", "restarts" }, + { "esi_syntax", + tweak_uint, &master.esi_syntax, 0, UINT_MAX, + "Bitmap controlling ESI parsing code:\n" + " 0x00000001 - Don't check if it looks like XML\n" + " 0x00000002 - Ignore non-esi elements\n" + " 0x00000004 - Emit parsing debug records\n" + " 0x00000008 - Force-split parser input (debugging)\n" + "Use 0x notation and do the bitor in your head :-)\n", + 0, + "0", "bitmap" }, + { "max_esi_depth", + tweak_uint, &master.max_esi_depth, 0, UINT_MAX, + "Maximum depth of esi:include processing.\n", + 0, + "5", "levels" }, + { "connect_timeout", tweak_timeout_double, + &master.connect_timeout,0, UINT_MAX, + "Default connection timeout for backend connections. " + "We only try to connect to the backend for this many " + "seconds before giving up. " + "VCL can override this default value for each backend and " + "backend request.", + 0, + "0.7", "s" }, + { "first_byte_timeout", tweak_timeout_double, + &master.first_byte_timeout,0, UINT_MAX, + "Default timeout for receiving first byte from backend. " + "We only wait for this many seconds for the first " + "byte before giving up. A value of 0 means it will never time " + "out. " + "VCL can override this default value for each backend and " + "backend request. This parameter does not apply to pipe.", + 0, + "60", "s" }, + { "between_bytes_timeout", tweak_timeout_double, + &master.between_bytes_timeout,0, UINT_MAX, + "Default timeout between bytes when receiving data from " + "backend. " + "We only wait for this many seconds between bytes " + "before giving up. A value of 0 means it will never time out. " + "VCL can override this default value for each backend request " + "and backend request. This parameter does not apply to pipe.", + 0, + "60", "s" }, + { "acceptor_sleep_max", tweak_timeout_double, + &master.acceptor_sleep_max, 0, 10, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter limits how long it can sleep between " + "attempts to accept new connections.", + EXPERIMENTAL, + "0.050", "s" }, + { "acceptor_sleep_incr", tweak_timeout_double, + &master.acceptor_sleep_incr, 0, 1, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter control how much longer we sleep, each time " + "we fail to accept a new connection.", + EXPERIMENTAL, + "0.001", "s" }, + { "acceptor_sleep_decay", tweak_generic_double, + &master.acceptor_sleep_decay, 0, 1, + "If we run out of resources, such as file descriptors or " + "worker threads, the acceptor will sleep between accepts.\n" + "This parameter (multiplicatively) reduce the sleep duration " + "for each succesfull accept. (ie: 0.9 = reduce by 10%)", + EXPERIMENTAL, + "0.900", "" }, + { "clock_skew", tweak_uint, &master.clock_skew, 0, UINT_MAX, + "How much clockskew we are willing to accept between the " + "backend and our own clock.", + 0, + "10", "s" }, + { "prefer_ipv6", tweak_bool, &master.prefer_ipv6, 0, 0, + "Prefer IPv6 address when connecting to backends which " + "have both IPv4 and IPv6 addresses.", + 0, + "off", "bool" }, + { "session_max", tweak_uint, + &master.max_sess, 1000, UINT_MAX, + "Maximum number of sessions we will allocate from one pool " + "before just dropping connections.\n" + "This is mostly an anti-DoS measure, and setting it plenty " + "high should not hurt, as long as you have the memory for " + "it.\n", + 0, + "100000", "sessions" }, + { "session_linger", tweak_uint, + &master.session_linger,0, UINT_MAX, + "How long time the workerthread lingers on the session " + "to see if a new request appears right away.\n" + "If sessions are reused, as much as half of all reuses " + "happen within the first 100 msec of the previous request " + "completing.\n" + "Setting this too high results in worker threads not doing " + "anything for their keep, setting it too low just means that " + "more sessions take a detour around the waiter.", + EXPERIMENTAL, + "50", "ms" }, + { "cli_buffer", tweak_uint, &master.cli_buffer, 4096, UINT_MAX, + "Size of buffer for CLI input." + "\nYou may need to increase this if you have big VCL files " + "and use the vcl.inline CLI command.\n" + "NB: Must be specified with -p to have effect.\n", + 0, + "8192", "bytes" }, + { "log_hashstring", tweak_bool, &master.log_hash, 0, 0, + "Log the hash string components to shared memory log.\n", + 0, + "on", "bool" }, + { "log_local_address", tweak_bool, &master.log_local_addr, 0, 0, + "Log the local address on the TCP connection in the " + "SessionOpen shared memory record.\n", + 0, + "off", "bool" }, + { "waiter", tweak_waiter, NULL, 0, 0, + "Select the waiter kernel interface.\n", + EXPERIMENTAL | MUST_RESTART, + "default", NULL }, + { "diag_bitmap", tweak_diag_bitmap, 0, 0, 0, + "Bitmap controlling diagnostics code:\n" + " 0x00000001 - CNT_Session states.\n" + " 0x00000002 - workspace debugging.\n" + " 0x00000004 - kqueue debugging.\n" + " 0x00000008 - mutex logging.\n" + " 0x00000010 - mutex contests.\n" + " 0x00000020 - waiting list.\n" + " 0x00000040 - object workspace.\n" + " 0x00001000 - do not core-dump child process.\n" + " 0x00002000 - only short panic message.\n" + " 0x00004000 - panic to stderr.\n" +#ifdef HAVE_ABORT2 + " 0x00008000 - panic to abort2().\n" +#endif + " 0x00010000 - synchronize shmlog.\n" + " 0x00020000 - synchronous start of persistence.\n" + " 0x00040000 - release VCL early.\n" + " 0x80000000 - do edge-detection on digest.\n" + "Use 0x notation and do the bitor in your head :-)\n", + 0, + "0", "bitmap" }, + { "ban_dups", tweak_bool, &master.ban_dups, 0, 0, + "Detect and eliminate duplicate bans.\n", + 0, + "on", "bool" }, + { "syslog_cli_traffic", tweak_bool, &master.syslog_cli_traffic, 0, 0, + "Log all CLI traffic to syslog(LOG_INFO).\n", + 0, + "on", "bool" }, + { "ban_lurker_sleep", tweak_timeout_double, + &master.ban_lurker_sleep, 0, UINT_MAX, + "How long time does the ban lurker thread sleeps between " + "successful attempts to push the last item up the ban " + " list. It always sleeps a second when nothing can be done.\n" + "A value of zero disables the ban lurker.", + 0, + "0.01", "s" }, + { "saintmode_threshold", tweak_uint, + &master.saintmode_threshold, 0, UINT_MAX, + "The maximum number of objects held off by saint mode before " + "no further will be made to the backend until one times out. " + "A value of 0 disables saintmode.", + EXPERIMENTAL, + "10", "objects" }, + { "http_range_support", tweak_bool, &master.http_range_support, 0, 0, + "Enable support for HTTP Range headers.\n", + EXPERIMENTAL, + "on", "bool" }, + { "http_gzip_support", tweak_bool, &master.http_gzip_support, 0, 0, + "Enable gzip support. When enabled Varnish will compress " + "uncompressed objects before they are stored in the cache. " + "If a client does not support gzip encoding Varnish will " + "uncompress compressed objects on demand. Varnish will also " + "rewrite the Accept-Encoding header of clients indicating " + "support for gzip to:\n" + "Accept-Encoding: gzip\n\n" + "Clients that do not support gzip will have their " + "Accept-Encoding header removed. For more information on how " + "gzip is implemented please see the chapter on gzip in the " + "Varnish reference.", + EXPERIMENTAL, + "on", "bool" }, + { "gzip_tmp_space", tweak_uint, &master.gzip_tmp_space, 0, 2, + "Where temporary space for gzip/gunzip is allocated:\n" + " 0 - malloc\n" + " 1 - session workspace\n" + " 2 - thread workspace\n" + "If you have much gzip/gunzip activity, it may be an" + " advantage to use workspace for these allocations to reduce" + " malloc activity. Be aware that gzip needs 256+KB and gunzip" + " needs 32+KB of workspace (64+KB if ESI processing).", + EXPERIMENTAL, + "0", "" }, + { "gzip_level", tweak_uint, &master.gzip_level, 0, 9, + "Gzip compression level: 0=debug, 1=fast, 9=best", + 0, + "6", ""}, + { "gzip_window", tweak_uint, &master.gzip_window, 8, 15, + "Gzip window size 8=least, 15=most compression.\n" + "Memory impact is 8=1k, 9=2k, ... 15=128k.", + 0, + "15", ""}, + { "gzip_memlevel", tweak_uint, &master.gzip_memlevel, 1, 9, + "Gzip memory level 1=slow/least, 9=fast/most compression.\n" + "Memory impact is 1=1k, 2=2k, ... 9=256k.", + 0, + "8", ""}, + { "gzip_stack_buffer", tweak_uint, &master.gzip_stack_buffer, + 2048, UINT_MAX, + "Size of stack buffer used for gzip processing.\n" + "The stack buffers are used for in-transit data," + " for instance gunzip'ed data being sent to a client." + "Making this space to small results in more overhead," + " writes to sockets etc, making it too big is probably" + " just a waste of memory.", + EXPERIMENTAL, + "32768", "Bytes" }, + { "shortlived", tweak_timeout_double, + &master.shortlived, 0, UINT_MAX, + "Objects created with TTL shorter than this are always " + "put in transient storage.\n", + 0, + "10.0", "s" }, + { "critbit_cooloff", tweak_timeout_double, + &master.critbit_cooloff, 60, 254, + "How long time the critbit hasher keeps deleted objheads " + "on the cooloff list.\n", + WIZARD, + "180.0", "s" }, + { "vcl_dir", tweak_string, &mgt_vcl_dir, 0, 0, + "Directory from which relative VCL filenames (vcl.load and " + "include) are opened.", + 0, +#ifdef VARNISH_VCL_DIR + VARNISH_VCL_DIR, +#else + ".", +#endif + NULL }, + { "vmod_dir", tweak_string, &mgt_vmod_dir, 0, 0, + "Directory where VCL modules are to be found.", + 0, +#ifdef VARNISH_VMOD_DIR + VARNISH_VMOD_DIR, +#else + ".", +#endif + NULL }, + { "vcc_err_unref", tweak_bool, &mgt_vcc_err_unref, 0, 0, + "Unreferenced VCL objects result in error.\n", + 0, + "on", "bool" }, + + + { "pcre_match_limit", tweak_uint, + &master.vre_limits.match, + 1, UINT_MAX, + "The limit for the number of internal matching function" + " calls in a pcre_exec() execution.", + 0, + "10000", ""}, + + { "pcre_match_limit_recursion", tweak_uint, + &master.vre_limits.match_recursion, + 1, UINT_MAX, + "The limit for the number of internal matching function" + " recursions in a pcre_exec() execution.", + 0, + "10000", ""}, + + { NULL, NULL, NULL } +}; + +/*--------------------------------------------------------------------*/ + +#define WIDTH 76 + +static void +mcf_wrap(struct cli *cli, const char *text) +{ + const char *p, *q; + + /* Format text to COLUMNS width */ + for (p = text; *p != '\0'; ) { + q = strchr(p, '\n'); + if (q == NULL) + q = strchr(p, '\0'); + if (q > p + WIDTH - margin) { + q = p + WIDTH - margin; + while (q > p && *q != ' ') + q--; + AN(q); + } + VCLI_Out(cli, "%*s %.*s\n", margin, "", (int)(q - p), p); + p = q; + if (*p == ' ' || *p == '\n') + p++; + } +} + +void +mcf_param_show(struct cli *cli, const char * const *av, void *priv) +{ + int i; + const struct parspec *pp; + int lfmt; + + (void)priv; + if (av[2] == NULL || strcmp(av[2], "-l")) + lfmt = 0; + else + lfmt = 1; + for (i = 0; i < nparspec; i++) { + pp = parspec[i]; + if (av[2] != NULL && !lfmt && strcmp(pp->name, av[2])) + continue; + VCLI_Out(cli, "%-*s ", margin, pp->name); + if (pp->func == NULL) { + VCLI_Out(cli, "Not implemented.\n"); + if (av[2] != NULL && !lfmt) + return; + else + continue; + } + pp->func(cli, pp, NULL); + if (pp->units != NULL) + VCLI_Out(cli, " [%s]\n", pp->units); + else + VCLI_Out(cli, "\n"); + if (av[2] != NULL) { + VCLI_Out(cli, "%-*s Default is %s\n", + margin, "", pp->def); + mcf_wrap(cli, pp->descr); + if (pp->flags & DELAYED_EFFECT) + mcf_wrap(cli, DELAYED_EFFECT_TEXT); + if (pp->flags & EXPERIMENTAL) + mcf_wrap(cli, EXPERIMENTAL_TEXT); + if (pp->flags & MUST_RELOAD) + mcf_wrap(cli, MUST_RELOAD_TEXT); + if (pp->flags & MUST_RESTART) + mcf_wrap(cli, MUST_RESTART_TEXT); + if (pp->flags & WIZARD) + mcf_wrap(cli, WIZARD_TEXT); + if (!lfmt) + return; + else + VCLI_Out(cli, "\n"); + } + } + if (av[2] != NULL && !lfmt) { + VCLI_SetResult(cli, CLIS_PARAM); + VCLI_Out(cli, "Unknown parameter \"%s\".", av[2]); + } +} + +/*--------------------------------------------------------------------*/ + +void +MCF_ParamSync(void) +{ + if (params != &master) + *params = master; +} + +/*--------------------------------------------------------------------*/ + +void +MCF_ParamSet(struct cli *cli, const char *param, const char *val) +{ + const struct parspec *pp; + + pp = mcf_findpar(param); + if (pp != NULL) { + pp->func(cli, pp, val); + if (cli->result != CLIS_OK) { + VCLI_Out(cli, "(attempting to set param %s to %s)\n", + pp->name, val); + } else if (child_pid >= 0 && pp->flags & MUST_RESTART) { + VCLI_Out(cli, "Change will take effect" + " when child is restarted"); + } else if (pp->flags & MUST_RELOAD) { + VCLI_Out(cli, "Change will take effect" + " when VCL script is reloaded"); + } + MCF_ParamSync(); + return; + } + VCLI_SetResult(cli, CLIS_PARAM); + VCLI_Out(cli, "Unknown parameter \"%s\".", param); +} + + +/*--------------------------------------------------------------------*/ + +void +mcf_param_set(struct cli *cli, const char * const *av, void *priv) +{ + + (void)priv; + MCF_ParamSet(cli, av[2], av[3]); +} + +/*-------------------------------------------------------------------- + * Add a group of parameters to the global set and sort by name. + */ + +static int +parspec_cmp(const void *a, const void *b) +{ + struct parspec * const * pa = a; + struct parspec * const * pb = b; + return (strcmp((*pa)->name, (*pb)->name)); +} + +static void +MCF_AddParams(const struct parspec *ps) +{ + const struct parspec *pp; + int n; + + n = 0; + for (pp = ps; pp->name != NULL; pp++) { + if (mcf_findpar(pp->name) != NULL) + fprintf(stderr, "Duplicate param: %s\n", pp->name); + if (strlen(pp->name) + 1 > margin) + margin = strlen(pp->name) + 1; + n++; + } + parspec = realloc(parspec, (1L + nparspec + n) * sizeof *parspec); + XXXAN(parspec); + for (pp = ps; pp->name != NULL; pp++) + parspec[nparspec++] = pp; + parspec[nparspec] = NULL; + qsort (parspec, nparspec, sizeof parspec[0], parspec_cmp); +} + +/*-------------------------------------------------------------------- + * Set defaults for all parameters + */ + +static void +MCF_SetDefaults(struct cli *cli) +{ + const struct parspec *pp; + int i; + + for (i = 0; i < nparspec; i++) { + pp = parspec[i]; + if (cli != NULL) + VCLI_Out(cli, + "Set Default for %s = %s\n", pp->name, pp->def); + pp->func(cli, pp, pp->def); + if (cli != NULL && cli->result != CLIS_OK) + return; + } +} + +/*--------------------------------------------------------------------*/ + +void +MCF_ParamInit(struct cli *cli) +{ + + MCF_AddParams(input_parspec); + MCF_AddParams(WRK_parspec); + + /* XXX: We do this twice, to get past any interdependencies */ + MCF_SetDefaults(NULL); + MCF_SetDefaults(cli); + + params = &master; +} + +/*--------------------------------------------------------------------*/ + +void +MCF_DumpRst(void) +{ + const struct parspec *pp; + const char *p, *q; + int i; + + for (i = 0; i < nparspec; i++) { + pp = parspec[i]; + printf("%s\n", pp->name); + if (pp->units != NULL && *pp->units != '\0') + printf("\t- Units: %s\n", pp->units); + printf("\t- Default: %s\n", + strcmp(pp->def,MAGIC_INIT_STRING) == 0 ? "magic" : pp->def); + /* + * XXX: we should mark the params with one/two flags + * XXX: that say if ->min/->max are valid, so we + * XXX: can emit those also in help texts. + */ + if (pp->flags) { + printf("\t- Flags: "); + q = ""; + if (pp->flags & DELAYED_EFFECT) { + printf("%sdelayed", q); + q = ", "; + } + if (pp->flags & MUST_RESTART) { + printf("%smust_restart", q); + q = ", "; + } + if (pp->flags & MUST_RELOAD) { + printf("%smust_reload", q); + q = ", "; + } + if (pp->flags & EXPERIMENTAL) { + printf("%sexperimental", q); + q = ", "; + } + printf("\n"); + } + printf("\n\t"); + for (p = pp->descr; *p; p++) { + if (*p == '\n' && p[1] =='\0') + break; + if (*p == '\n' && p[1] =='\n') { + printf("\n\n\t"); + p++; + } else if (*p == '\n') { + printf("\n\t"); + } else if (*p == ':' && p[1] == '\n') { + /* + * Start of definition list, + * use RSTs code mode for this + */ + printf("::\n"); + } else { + printf("%c", *p); + } + } + printf("\n\n"); + } + printf("\n"); +} diff --git a/bin/varnishd/mgt/mgt_pool.c b/bin/varnishd/mgt/mgt_pool.c new file mode 100644 index 0000000..978e60a --- /dev/null +++ b/bin/varnishd/mgt/mgt_pool.c @@ -0,0 +1,238 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * We maintain a number of worker thread pools, to spread lock contention. + * + * Pools can be added on the fly, as a means to mitigate lock contention, + * but can only be removed again by a restart. (XXX: we could fix that) + * + * Two threads herd the pools, one eliminates idle threads and aggregates + * statistics for all the pools, the other thread creates new threads + * on demand, subject to various numerical constraints. + * + * The algorithm for when to create threads needs to be reactive enough + * to handle startup spikes, but sufficiently attenuated to not cause + * thread pileups. This remains subject for improvement. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "heritage.h" +#include "vparam.h" + +/*--------------------------------------------------------------------*/ + +static void +tweak_thread_pool_min(struct cli *cli, const struct parspec *par, + const char *arg) +{ + + tweak_generic_uint(cli, &master.wthread_min, arg, + (unsigned)par->min, master.wthread_max); +} + +/*-------------------------------------------------------------------- + * This is utterly ridiculous: POSIX does not guarantee that the + * minimum thread stack size is a compile time constant. + * XXX: "32" is a magic marker for 32bit systems. + */ + +static void +tweak_stack_size(struct cli *cli, const struct parspec *par, + const char *arg) +{ + unsigned low, u; + char buf[12]; + + low = sysconf(_SC_THREAD_STACK_MIN); + + if (arg != NULL && !strcmp(arg, "32bit")) { + u = 65536; + if (u < low) + u = low; + sprintf(buf, "%u", u); + arg = buf; + } + + tweak_generic_uint(cli, &master.wthread_stacksize, arg, + low, (uint)par->max); +} + +/*--------------------------------------------------------------------*/ + +static void +tweak_thread_pool_max(struct cli *cli, const struct parspec *par, + const char *arg) +{ + + (void)par; + tweak_generic_uint(cli, &master.wthread_max, arg, + master.wthread_min, UINT_MAX); +} + +/*--------------------------------------------------------------------*/ + +const struct parspec WRK_parspec[] = { + { "thread_pools", tweak_uint, &master.wthread_pools, 1, UINT_MAX, + "Number of worker thread pools.\n" + "\n" + "Increasing number of worker pools decreases lock " + "contention.\n" + "\n" + "Too many pools waste CPU and RAM resources, and more than " + "one pool for each CPU is probably detrimal to performance.\n" + "\n" + "Can be increased on the fly, but decreases require a " + "restart to take effect.", + EXPERIMENTAL | DELAYED_EFFECT, + "2", "pools" }, + { "thread_pool_max", tweak_thread_pool_max, NULL, 1, 0, + "The maximum number of worker threads in each pool.\n" + "\n" + "Do not set this higher than you have to, since excess " + "worker threads soak up RAM and CPU and generally just get " + "in the way of getting work done.\n", + EXPERIMENTAL | DELAYED_EFFECT, + "500", "threads" }, + { "thread_pool_min", tweak_thread_pool_min, NULL, 2, 0, + "The minimum number of worker threads in each pool.\n" + "\n" + "Increasing this may help ramp up faster from low load " + "situations where threads have expired.\n" + "\n" + "Minimum is 2 threads.", + EXPERIMENTAL | DELAYED_EFFECT, + "5", "threads" }, + { "thread_pool_timeout", tweak_timeout, &master.wthread_timeout, 1, 0, + "Thread idle threshold.\n" + "\n" + "Threads in excess of thread_pool_min, which have been idle " + "for at least this long are candidates for purging.\n" + "\n" + "Minimum is 1 second.", + EXPERIMENTAL | DELAYED_EFFECT, + "300", "seconds" }, + { "thread_pool_purge_delay", + tweak_timeout, &master.wthread_purge_delay, 100, 0, + "Wait this long between purging threads.\n" + "\n" + "This controls the decay of thread pools when idle(-ish).\n" + "\n" + "Minimum is 100 milliseconds.", + EXPERIMENTAL | DELAYED_EFFECT, + "1000", "milliseconds" }, + { "thread_pool_add_threshold", + tweak_uint, &master.wthread_add_threshold, 0, UINT_MAX, + "Overflow threshold for worker thread creation.\n" + "\n" + "Setting this too low, will result in excess worker threads, " + "which is generally a bad idea.\n" + "\n" + "Setting it too high results in insuffient worker threads.\n", + EXPERIMENTAL, + "2", "requests" }, + { "thread_pool_add_delay", + tweak_timeout, &master.wthread_add_delay, 0, UINT_MAX, + "Wait at least this long between creating threads.\n" + "\n" + "Setting this too long results in insuffient worker threads.\n" + "\n" + "Setting this too short increases the risk of worker " + "thread pile-up.\n", + 0, + "2", "milliseconds" }, + { "thread_pool_fail_delay", + tweak_timeout, &master.wthread_fail_delay, 100, UINT_MAX, + "Wait at least this long after a failed thread creation " + "before trying to create another thread.\n" + "\n" + "Failure to create a worker thread is often a sign that " + " the end is near, because the process is running out of " + "RAM resources for thread stacks.\n" + "This delay tries to not rush it on needlessly.\n" + "\n" + "If thread creation failures are a problem, check that " + "thread_pool_max is not too high.\n" + "\n" + "It may also help to increase thread_pool_timeout and " + "thread_pool_min, to reduce the rate at which treads are " + "destroyed and later recreated.\n", + EXPERIMENTAL, + "200", "milliseconds" }, + { "thread_stats_rate", + tweak_uint, &master.wthread_stats_rate, 0, UINT_MAX, + "Worker threads accumulate statistics, and dump these into " + "the global stats counters if the lock is free when they " + "finish a request.\n" + "This parameters defines the maximum number of requests " + "a worker thread may handle, before it is forced to dump " + "its accumulated stats into the global counters.\n", + EXPERIMENTAL, + "10", "requests" }, + { "queue_max", tweak_uint, &master.queue_max, 0, UINT_MAX, + "Percentage permitted queue length.\n" + "\n" + "This sets the ratio of queued requests to worker threads, " + "above which sessions will be dropped instead of queued.\n", + EXPERIMENTAL, + "100", "%" }, + { "rush_exponent", tweak_uint, &master.rush_exponent, 2, UINT_MAX, + "How many parked request we start for each completed " + "request on the object.\n" + "NB: Even with the implict delay of delivery, " + "this parameter controls an exponential increase in " + "number of worker threads.", + EXPERIMENTAL, + "3", "requests per request" }, + { "thread_pool_stack", + tweak_stack_size, &master.wthread_stacksize, 0, UINT_MAX, + "Worker thread stack size.\n" + "On 32bit systems you may need to tweak this down to fit " + "many threads into the limited address space.\n", + EXPERIMENTAL, + "-1", "bytes" }, + { "thread_pool_workspace", tweak_uint, &master.wthread_workspace, + 1024, UINT_MAX, + "Bytes of HTTP protocol workspace allocated for worker " + "threads. " + "This space must be big enough for the backend request " + "and responses, and response to the client plus any other " + "memory needs in the VCL code." + "Minimum is 1024 bytes.", + DELAYED_EFFECT, + "65536", + "bytes" }, + { NULL, NULL, NULL } +}; diff --git a/bin/varnishd/mgt/mgt_sandbox.c b/bin/varnishd/mgt/mgt_sandbox.c new file mode 100644 index 0000000..b01d243 --- /dev/null +++ b/bin/varnishd/mgt/mgt_sandbox.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2006-2011 Varnish Software 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. + * + * Sandboxing child processes + * + * The worker/manager process border is one of the major security barriers + * in Varnish, and therefore subject to whatever restrictions we have access + * to under the given operating system. + * + * Unfortunately there is no consensus on APIs for this purpose, so each + * operating system will require its own methods. + * + * This sourcefile tries to encapsulate the resulting mess on place. + * + * TODO: + * Unix: chroot + * FreeBSD: jail + * FreeBSD: capsicum + */ + +#include "config.h" + +#ifdef __linux__ +#include +#endif + +#include +#include +#include + +#include "mgt/mgt.h" + +#include "heritage.h" + +/*--------------------------------------------------------------------*/ + +/* Waive all privileges in the child, it does not need any */ + +void +mgt_sandbox(void) +{ +#ifdef HAVE_SETPPRIV + mgt_sandbox_solaris_init(); + mgt_sandbox_solaris_privsep(); +#else + if (geteuid() == 0) { + XXXAZ(setgid(params->gid)); + XXXAZ(setuid(params->uid)); + } else { + REPORT0(LOG_INFO, "Not running as root, no priv-sep"); + } +#endif + + /* On Linux >= 2.4, you need to set the dumpable flag + to get core dumps after you have done a setuid. */ + +#ifdef __linux__ + if (prctl(PR_SET_DUMPABLE, 1) != 0) + REPORT0(LOG_INFO, + "Could not set dumpable bit. Core dumps turned off\n"); +#endif + +#ifdef HAVE_SETPPRIV + mgt_sandbox_solaris_fini(); +#endif + +} diff --git a/bin/varnishd/mgt/mgt_sandbox_solaris.c b/bin/varnishd/mgt/mgt_sandbox_solaris.c new file mode 100644 index 0000000..715408e --- /dev/null +++ b/bin/varnishd/mgt/mgt_sandbox_solaris.c @@ -0,0 +1,233 @@ +/*- + * Copyright (c) 2006-2011 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * Nils Goroll + * + * 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. + * + * Sandboxing child processes on Solaris + * + */ + +#include "config.h" + +#ifdef HAVE_SETPPRIV + +#ifdef HAVE_PRIV_H +#include +#endif +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "heritage.h" + +/*-------------------------------------------------------------------- + * SOLARIS PRIVILEGES: Note on use of symbolic PRIV_* constants + * + * For privileges which existed in Solaris 10 FCS, we may use the constants from + * sys/priv_names.h + * + * For privileges which have been added later, we need to use strings in order + * not to break builds of varnish on these platforms. To remain binary + * compatible, we need to silently ignore errors from priv_addset when using + * these strings. + * + * For optimal build and binary forward comatibility, we could use subtractive + * set specs like + * + * basic,!file_link_any,!proc_exec,!proc_fork,!proc_info,!proc_session + * + * but I (Nils) have a preference for making an informed decision about which + * privileges the varnish child should have and which it shouldn't. + * + * Newly introduced privileges should be annotated with their PSARC / commit ID + * (as long as Oracle reveils these :/ ) + * + * SOLARIS PRIVILEGES: Note on accidentally setting the SNOCD flag + * + * When setting privileges, we need to take care not to accidentally set the + * SNOCD flag which will disable core dumps unnecessarily. (see + * https://www.varnish-cache.org/trac/ticket/671 ) + * + * When changing the logic herein, always check with mdb -k. Replace _PID_ with + * the pid of your varnish child, the result should be 0, otherwise a regression + * has been introduced. + * + * > 0t_PID_::pid2proc | ::print proc_t p_flag | >a + * > (gid) + XXXAZ(setgid(params->gid)); + if (getuid() != params->uid) + XXXAZ(setuid(params->uid)); + } else { + REPORT(LOG_INFO, "Privilege %s missing, will not change uid/gid", + PRIV_PROC_SETID); + } +} + +/* + * Waive most privileges in the child + * + * as of onnv_151a, we should end up with: + * + * > ppriv -v #pid of varnish child + * PID: .../varnishd ... + * flags = PRIV_AWARE + * E: file_read,file_write,net_access + * I: none + * P: file_read,file_write,net_access,sys_resource + * L: file_read,file_write,net_access,sys_resource + * + * We should keep sys_resource in P in order to adjust our limits if we need to + */ + +void +mgt_sandbox_solaris_fini(void) +{ + priv_set_t *effective, *inheritable, *permitted; + + if (!(effective = priv_allocset()) || + !(inheritable = priv_allocset()) || + !(permitted = priv_allocset())) { + REPORT(LOG_ERR, + "Child start warning: mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)", + errno, strerror(errno)); + return; + } + + priv_emptyset(inheritable); + + priv_emptyset(effective); + mgt_sandbox_solaris_add_effective(effective); + + priv_copyset(effective, permitted); + mgt_sandbox_solaris_add_permitted(permitted); + + /* + * invert the sets and clear privileges such that setppriv will always + * succeed + */ + priv_inverse(inheritable); + priv_inverse(effective); + priv_inverse(permitted); + +#define SETPPRIV(which, set) \ + if (setppriv(PRIV_OFF, which, set)) \ + REPORT(LOG_ERR, \ + "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \ + #which, errno, strerror(errno)); + + SETPPRIV(PRIV_INHERITABLE, inheritable); + SETPPRIV(PRIV_EFFECTIVE, effective); + SETPPRIV(PRIV_PERMITTED, permitted); + SETPPRIV(PRIV_LIMIT, permitted); +#undef SETPPRIV + + priv_freeset(inheritable); + priv_freeset(effective); +} + +#endif /* HAVE_SETPPRIV */ diff --git a/bin/varnishd/mgt/mgt_shmem.c b/bin/varnishd/mgt/mgt_shmem.c new file mode 100644 index 0000000..630865d --- /dev/null +++ b/bin/varnishd/mgt/mgt_shmem.c @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * + * TODO: + * + * There is a risk that the child process might corrupt the VSM segment + * and we should capture that event and recover gracefully. + * + * A possible state diagram could be: + * + * [manager start] + * | + * v + * Open old VSM, + * check pid --------> exit/fail (-n message) + * | + * +<----------------------+ + * | ^ + * v | + * Create new VSM | + * | | + * v | + * Init header | + * Alloc VSL | + * Alloc VSC:Main | + * Alloc Args etc. | + * | | + * +<--------------+ | + * | ^ | + * v | | + * start worker | | + * | | | + * | | +<---- worker crash + * v | ^ + * Reset VSL ptr. | | + * Reset VSC counters | | + * | | | + * +<------+ | | + * | ^ | | + * v | | | + * alloc dynamics | | | + * free dynamics | | | + * | | | | + * v | | | + * +------>+ | | + * | | | + * v | | + * stop worker | | + * | | | + * v | | + * Check consist---------- | ----->+ + * | | + * v | + * Free dynamics | + * | | + * v | + * +-------------->+ + * + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "flopen.h" +#include "heritage.h" +#include "vapi/vsc_int.h" +#include "vapi/vsl_int.h" +#include "vapi/vsm_int.h" +#include "vav.h" +#include "vmb.h" +#include "vnum.h" + +#ifndef MAP_HASSEMAPHORE +#define MAP_HASSEMAPHORE 0 /* XXX Linux */ +#endif + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 /* XXX Linux */ +#endif + +struct VSC_C_main *VSC_C_main; + +static int vsl_fd = -1; + +/*-------------------------------------------------------------------- + * Check that we are not started with the same -n argument as an already + * running varnishd + */ + +static void +vsl_n_check(int fd) +{ + struct VSM_head slh; + int i; + struct stat st; + pid_t pid; + + AZ(fstat(fd, &st)); + if (!S_ISREG(st.st_mode)) + ARGV_ERR("\tshmlog: Not a file\n"); + + /* Test if the SHMFILE is locked by other Varnish */ + if (fltest(fd, &pid) > 0) { + fprintf(stderr, + "SHMFILE locked by running varnishd master (pid=%jd)\n", + (intmax_t)pid); + fprintf(stderr, + "(Use unique -n arguments if you want multiple " + "instances)\n"); + exit(2); + } + + /* Read owning pid from SHMFILE */ + memset(&slh, 0, sizeof slh); /* XXX: for flexelint */ + i = read(fd, &slh, sizeof slh); + if (i != sizeof slh) + return; + if (slh.magic != VSM_HEAD_MAGIC) + return; + if (slh.hdrsize != sizeof slh) + return; + if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) { + fprintf(stderr, + "WARNING: Taking over SHMFILE marked as owned by " + "running process (pid=%jd)\n", + (intmax_t)slh.master_pid); + } +} + +/*-------------------------------------------------------------------- + * Build a new shmlog file + */ + +static void +vsl_buildnew(const char *fn, unsigned size, int fill) +{ + struct VSM_head slh; + int i; + unsigned u; + char buf[64*1024]; + int flags; + + (void)unlink(fn); + vsl_fd = flopen(fn, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0644); + if (vsl_fd < 0) { + fprintf(stderr, "Could not create %s: %s\n", + fn, strerror(errno)); + exit (1); + } + flags = fcntl(vsl_fd, F_GETFL); + assert(flags != -1); + flags &= ~O_NONBLOCK; + AZ(fcntl(vsl_fd, F_SETFL, flags)); + + memset(&slh, 0, sizeof slh); + slh.magic = VSM_HEAD_MAGIC; + slh.hdrsize = sizeof slh; + slh.shm_size = size; + i = write(vsl_fd, &slh, sizeof slh); + xxxassert(i == sizeof slh); + + if (fill) { + memset(buf, 0, sizeof buf); + for (u = sizeof slh; u < size; ) { + i = write(vsl_fd, buf, sizeof buf); + if (i <= 0) { + fprintf(stderr, "Write error %s: %s\n", + fn, strerror(errno)); + exit (1); + } + u += i; + } + } + + AZ(ftruncate(vsl_fd, (off_t)size)); +} + +/*-------------------------------------------------------------------- + * Exit handler that clears the owning pid from the SHMLOG + */ + +static +void +mgt_shm_atexit(void) +{ + if (getpid() == VSM_head->master_pid) + VSM_head->master_pid = 0; +} + +void +mgt_SHM_Init(const char *l_arg) +{ + int i, fill; + struct params *pp; + const char *q; + uintmax_t size, s1, s2, ps; + char **av, **ap; + uint32_t *vsl_log_start; + + if (l_arg == NULL) + l_arg = ""; + + av = VAV_Parse(l_arg, NULL, ARGV_COMMA); + AN(av); + if (av[0] != NULL) + ARGV_ERR("\t-l ...: %s", av[0]); + + ap = av + 1; + + /* Size of SHMLOG */ + if (*ap != NULL && **ap != '\0') { + q = VNUM_2bytes(*ap, &s1, 0); + if (q != NULL) + ARGV_ERR("\t-l[1] ...: %s\n", q); + } else { + s1 = 80 * 1024 * 1024; + } + if (*ap != NULL) + ap++; + + /* Size of space for other stuff */ + if (*ap != NULL && **ap != '\0') { + q = VNUM_2bytes(*ap, &s2, 0); + if (q != NULL) + ARGV_ERR("\t-l[2] ...: %s\n", q); + } else { + s2 = 1024 * 1024; + } + if (*ap != NULL) + ap++; + + /* Fill or not ? */ + if (*ap != NULL) { + if (**ap == '\0') + fill = 1; + else if (!strcmp(*ap, "-")) + fill = 0; + else if (!strcmp(*ap, "+")) + fill = 1; + else + ARGV_ERR("\t-l[3] ...: Must be \"-\" or \"+\"\n"); + ap++; + } else { + fill = 1; + } + + if (*ap != NULL) + ARGV_ERR("\t-l ...: Too many sub-args\n"); + + VAV_Free(av); + + size = s1 + s2; + ps = getpagesize(); + size += ps - 1; + size &= ~(ps - 1); + + i = open(VSM_FILENAME, O_RDWR, 0644); + if (i >= 0) { + vsl_n_check(i); + (void)close(i); + } + vsl_buildnew(VSM_FILENAME, size, fill); + + VSM_head = (void *)mmap(NULL, size, + PROT_READ|PROT_WRITE, + MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED, + vsl_fd, 0); + VSM_head->master_pid = getpid(); + AZ(atexit(mgt_shm_atexit)); + xxxassert(VSM_head != MAP_FAILED); + (void)mlock((void*)VSM_head, size); + + memset(&VSM_head->head, 0, sizeof VSM_head->head); + VSM_head->head.magic = VSM_CHUNK_MAGIC; + VSM_head->head.len = + (uint8_t*)(VSM_head) + size - (uint8_t*)&VSM_head->head; + bprintf(VSM_head->head.class, "%s", VSM_CLASS_FREE); + VWMB(); + + vsm_end = (void*)((uint8_t*)VSM_head + size); + + VSC_C_main = VSM_Alloc(sizeof *VSC_C_main, + VSC_CLASS, VSC_TYPE_MAIN, ""); + AN(VSC_C_main); + + pp = VSM_Alloc(sizeof *pp, VSM_CLASS_PARAM, "", ""); + AN(pp); + *pp = *params; + params = pp; + + vsl_log_start = VSM_Alloc(s1, VSL_CLASS, "", ""); + AN(vsl_log_start); + vsl_log_start[1] = VSL_ENDMARKER; + VWMB(); + + do + *vsl_log_start = random() & 0xffff; + while (*vsl_log_start == 0); + + VWMB(); + + do + VSM_head->alloc_seq = random(); + while (VSM_head->alloc_seq == 0); + +} + +void +mgt_SHM_Pid(void) +{ + + VSM_head->master_pid = getpid(); +} diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c new file mode 100644 index 0000000..ec117db --- /dev/null +++ b/bin/varnishd/mgt/mgt_vcc.c @@ -0,0 +1,676 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2011 Varnish Software 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. + * + * VCL compiler stuff + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "mgt/mgt.h" + +#include "libvcl.h" +#include "vcl.h" +#include "vcli.h" +#include "vcli_priv.h" +#include "vfil.h" +#include "vsub.h" + +#include "mgt_cli.h" + +struct vclprog { + VTAILQ_ENTRY(vclprog) list; + char *name; + char *fname; + int active; +}; + +static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead); + +char *mgt_cc_cmd; +const char *mgt_vcl_dir; +const char *mgt_vmod_dir; +unsigned mgt_vcc_err_unref; + +static struct vcc *vcc; + +/*--------------------------------------------------------------------*/ + +static const char * const default_vcl = +#include "default_vcl.h" + "" ; + +/*-------------------------------------------------------------------- + * Prepare the compiler command line + */ +static struct vsb * +mgt_make_cc_cmd(const char *sf, const char *of) +{ + struct vsb *sb; + int pct; + char *p; + + sb = VSB_new_auto(); + XXXAN(sb); + for (p = mgt_cc_cmd, pct = 0; *p; ++p) { + if (pct) { + switch (*p) { + case 's': + VSB_cat(sb, sf); + break; + case 'o': + VSB_cat(sb, of); + break; + case '%': + VSB_putc(sb, '%'); + break; + default: + VSB_putc(sb, '%'); + VSB_putc(sb, *p); + break; + } + pct = 0; + } else if (*p == '%') { + pct = 1; + } else { + VSB_putc(sb, *p); + } + } + if (pct) + VSB_putc(sb, '%'); + AZ(VSB_finish(sb)); + return (sb); +} + +/*-------------------------------------------------------------------- + * Invoke system VCC compiler in a sub-process + */ + +struct vcc_priv { + unsigned magic; +#define VCC_PRIV_MAGIC 0x70080cb8 + char *sf; + const char *vcl; +}; + +static void +run_vcc(void *priv) +{ + char *csrc; + struct vsb *sb; + struct vcc_priv *vp; + int fd, i, l; + + CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC); + sb = VSB_new_auto(); + XXXAN(sb); + VCC_VCL_dir(vcc, mgt_vcl_dir); + VCC_VMOD_dir(vcc, mgt_vmod_dir); + VCC_Err_Unref(vcc, mgt_vcc_err_unref); + csrc = VCC_Compile(vcc, sb, vp->vcl); + AZ(VSB_finish(sb)); + if (VSB_len(sb)) + printf("%s", VSB_data(sb)); + VSB_delete(sb); + if (csrc == NULL) + exit (1); + + fd = open(vp->sf, O_WRONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open %s", vp->sf); + exit (1); + } + l = strlen(csrc); + i = write(fd, csrc, l); + if (i != l) { + fprintf(stderr, "Cannot write %s", vp->sf); + exit (1); + } + AZ(close(fd)); + free(csrc); + exit (0); +} + +/*-------------------------------------------------------------------- + * Invoke system C compiler in a sub-process + */ + +static void +run_cc(void *priv) +{ + (void)execl("/bin/sh", "/bin/sh", "-c", priv, NULL); +} + +/*-------------------------------------------------------------------- + * Attempt to open compiled VCL in a sub-process + */ + +static void __match_proto__(sub_func_f) +run_dlopen(void *priv) +{ + const char *of; + void *dlh; + struct VCL_conf const *cnf; + + of = priv; + + /* Try to load the object into the management process */ + if ((dlh = dlopen(of, RTLD_NOW | RTLD_LOCAL)) == NULL) { + fprintf(stderr, + "Compiled VCL program failed to load:\n %s\n", + dlerror()); + exit(1); + } + + cnf = dlsym(dlh, "VCL_conf"); + if (cnf == NULL) { + fprintf(stderr, "Compiled VCL program, metadata not found\n"); + exit(1); + } + + if (cnf->magic != VCL_CONF_MAGIC) { + fprintf(stderr, "Compiled VCL program, mangled metadata\n"); + exit(1); + } + + if (dlclose(dlh)) { + fprintf(stderr, + "Compiled VCL program failed to unload:\n %s\n", + dlerror()); + exit(1); + } + exit(0); +} + +/*-------------------------------------------------------------------- + * Compile a VCL program, return shared object, errors in sb. + */ + +static char * +mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) +{ + char *csrc; + struct vsb *cmdsb; + char sf[] = "./vcl.########.c"; + char of[sizeof sf + 1]; + char *retval; + int sfd, i; + struct vcc_priv vp; + + /* Create temporary C source file */ + sfd = VFIL_tmpfile(sf); + if (sfd < 0) { + VSB_printf(sb, "Failed to create %s: %s", sf, strerror(errno)); + return (NULL); + } + AZ(close(sfd)); + + /* Run the VCC compiler in a sub-process */ + memset(&vp, 0, sizeof vp); + vp.magic = VCC_PRIV_MAGIC; + vp.sf = sf; + vp.vcl = vcl; + if (VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1)) { + (void)unlink(sf); + return (NULL); + } + + if (C_flag) { + csrc = VFIL_readfile(NULL, sf, NULL); + XXXAN(csrc); + (void)fputs(csrc, stdout); + free(csrc); + } + + /* Name the output shared library by "s/[.]c$/[.]so/" */ + memcpy(of, sf, sizeof sf); + assert(sf[sizeof sf - 2] == 'c'); + of[sizeof sf - 2] = 's'; + of[sizeof sf - 1] = 'o'; + of[sizeof sf] = '\0'; + + /* Build the C-compiler command line */ + cmdsb = mgt_make_cc_cmd(sf, of); + + /* Run the C-compiler in a sub-shell */ + i = VSUB_run(sb, run_cc, VSB_data(cmdsb), "C-compiler", 10); + + (void)unlink(sf); + VSB_delete(cmdsb); + + if (!i) + i = VSUB_run(sb, run_dlopen, of, "dlopen", 10); + + if (i) { + (void)unlink(of); + return (NULL); + } + + retval = strdup(of); + XXXAN(retval); + return (retval); +} + +/*--------------------------------------------------------------------*/ + +static char * +mgt_VccCompile(struct vsb **sb, const char *b, int C_flag) +{ + char *vf; + + *sb = VSB_new_auto(); + XXXAN(*sb); + vf = mgt_run_cc(b, *sb, C_flag); + AZ(VSB_finish(*sb)); + return (vf); +} + +/*--------------------------------------------------------------------*/ + +static struct vclprog * +mgt_vcc_add(const char *name, char *file) +{ + struct vclprog *vp; + + vp = calloc(sizeof *vp, 1); + XXXAN(vp); + vp->name = strdup(name); + XXXAN(vp->name); + vp->fname = file; + VTAILQ_INSERT_TAIL(&vclhead, vp, list); + return (vp); +} + +static void +mgt_vcc_del(struct vclprog *vp) +{ + VTAILQ_REMOVE(&vclhead, vp, list); + printf("unlink %s\n", vp->fname); + XXXAZ(unlink(vp->fname)); + free(vp->fname); + free(vp->name); + free(vp); +} + +static struct vclprog * +mgt_vcc_byname(const char *name) +{ + struct vclprog *vp; + + VTAILQ_FOREACH(vp, &vclhead, list) + if (!strcmp(name, vp->name)) + return (vp); + return (NULL); +} + + +static int +mgt_vcc_delbyname(const char *name) +{ + struct vclprog *vp; + + vp = mgt_vcc_byname(name); + if (vp != NULL) { + mgt_vcc_del(vp); + return (0); + } + return (1); +} + +/*--------------------------------------------------------------------*/ + +int +mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag) +{ + char *vf; + struct vsb *sb; + struct vclprog *vp; + char buf[BUFSIZ]; + + /* XXX: annotate vcl with -b/-f arg so people know where it came from */ + (void)f_arg; + + if (b_arg != NULL) { + AZ(vcl); + /* + * XXX: should do a "HEAD /" on the -b argument to see that + * XXX: it even works. On the other hand, we should do that + * XXX: for all backends in the cache process whenever we + * XXX: change config, but for a complex VCL, it might not be + * XXX: a bug for a backend to not reply at that time, so then + * XXX: again: we should check it here in the "trivial" case. + */ + bprintf(buf, + "backend default {\n" + " .host = \"%s\";\n" + "}\n", b_arg); + vcl = strdup(buf); + AN(vcl); + } + strcpy(buf, "boot"); + + vf = mgt_VccCompile(&sb, vcl, C_flag); + free(vcl); + if (VSB_len(sb) > 0) + fprintf(stderr, "%s", VSB_data(sb)); + VSB_delete(sb); + if (C_flag) { + if (vf != NULL) + AZ(unlink(vf)); + return (0); + } + if (vf == NULL) { + fprintf(stderr, "\nVCL compilation failed\n"); + return (1); + } + vp = mgt_vcc_add(buf, vf); + vp->active = 1; + return (0); +} + +/*--------------------------------------------------------------------*/ + +int +mgt_has_vcl() +{ + + return (!VTAILQ_EMPTY(&vclhead)); +} + +/*--------------------------------------------------------------------*/ + +int +mgt_push_vcls_and_start(unsigned *status, char **p) +{ + struct vclprog *vp; + + VTAILQ_FOREACH(vp, &vclhead, list) { + if (mgt_cli_askchild(status, p, + "vcl.load \"%s\" %s\n", vp->name, vp->fname)) + return (1); + free(*p); + if (!vp->active) + continue; + if (mgt_cli_askchild(status, p, + "vcl.use \"%s\"\n", vp->name)) + return (1); + free(*p); + } + if (mgt_cli_askchild(status, p, "start\n")) + return (1); + free(*p); + *p = NULL; + return (0); +} + +/*--------------------------------------------------------------------*/ + +static +void +mgt_vcc_atexit(void) +{ + struct vclprog *vp; + + if (getpid() != mgt_pid) + return; + while (1) { + vp = VTAILQ_FIRST(&vclhead); + if (vp == NULL) + break; + (void)unlink(vp->fname); + VTAILQ_REMOVE(&vclhead, vp, list); + } +} + +void +mgt_vcc_init(void) +{ + + vcc = VCC_New(); + AN(vcc); + VCC_Default_VCL(vcc, default_vcl); + AZ(atexit(mgt_vcc_atexit)); +} + +/*--------------------------------------------------------------------*/ + +void +mcf_config_inline(struct cli *cli, const char * const *av, void *priv) +{ + char *vf, *p = NULL; + struct vsb *sb; + unsigned status; + struct vclprog *vp; + + (void)priv; + + vp = mgt_vcc_byname(av[2]); + if (vp != NULL) { + VCLI_Out(cli, "Already a VCL program named %s", av[2]); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + + vf = mgt_VccCompile(&sb, av[3], 0); + if (VSB_len(sb) > 0) + VCLI_Out(cli, "%s\n", VSB_data(sb)); + VSB_delete(sb); + if (vf == NULL) { + VCLI_Out(cli, "VCL compilation failed"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + VCLI_Out(cli, "VCL compiled."); + if (child_pid >= 0 && + mgt_cli_askchild(&status, &p, "vcl.load %s %s\n", av[2], vf)) { + VCLI_SetResult(cli, status); + VCLI_Out(cli, "%s", p); + } else { + (void)mgt_vcc_add(av[2], vf); + } + free(p); +} + +void +mcf_config_load(struct cli *cli, const char * const *av, void *priv) +{ + char *vf, *vcl; + struct vsb *sb; + unsigned status; + char *p = NULL; + struct vclprog *vp; + + (void)priv; + vp = mgt_vcc_byname(av[2]); + if (vp != NULL) { + VCLI_Out(cli, "Already a VCL program named %s", av[2]); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + + vcl = VFIL_readfile(mgt_vcl_dir, av[3], NULL); + if (vcl == NULL) { + VCLI_Out(cli, "Cannot open '%s'", av[3]); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + + vf = mgt_VccCompile(&sb, vcl, 0); + free(vcl); + + if (VSB_len(sb) > 0) + VCLI_Out(cli, "%s", VSB_data(sb)); + VSB_delete(sb); + if (vf == NULL) { + VCLI_Out(cli, "VCL compilation failed"); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + VCLI_Out(cli, "VCL compiled."); + if (child_pid >= 0 && + mgt_cli_askchild(&status, &p, "vcl.load %s %s\n", av[2], vf)) { + VCLI_SetResult(cli, status); + VCLI_Out(cli, "%s", p); + } else { + (void)mgt_vcc_add(av[2], vf); + } + free(p); +} + +static struct vclprog * +mcf_find_vcl(struct cli *cli, const char *name) +{ + struct vclprog *vp; + + vp = mgt_vcc_byname(name); + if (vp != NULL) + return (vp); + VCLI_SetResult(cli, CLIS_PARAM); + VCLI_Out(cli, "No configuration named %s known.", name); + return (NULL); +} + +void +mcf_config_use(struct cli *cli, const char * const *av, void *priv) +{ + unsigned status; + char *p = NULL; + struct vclprog *vp; + + (void)priv; + vp = mcf_find_vcl(cli, av[2]); + if (vp == NULL) + return; + if (vp->active != 0) + return; + if (child_pid >= 0 && + mgt_cli_askchild(&status, &p, "vcl.use %s\n", av[2])) { + VCLI_SetResult(cli, status); + VCLI_Out(cli, "%s", p); + } else { + vp->active = 2; + VTAILQ_FOREACH(vp, &vclhead, list) { + if (vp->active == 1) + vp->active = 0; + else if (vp->active == 2) + vp->active = 1; + } + } + free(p); +} + +void +mcf_config_discard(struct cli *cli, const char * const *av, void *priv) +{ + unsigned status; + char *p = NULL; + struct vclprog *vp; + + (void)priv; + vp = mcf_find_vcl(cli, av[2]); + if (vp != NULL && vp->active) { + VCLI_SetResult(cli, CLIS_PARAM); + VCLI_Out(cli, "Cannot discard active VCL program\n"); + } else if (vp != NULL) { + if (child_pid >= 0 && + mgt_cli_askchild(&status, &p, + "vcl.discard %s\n", av[2])) { + VCLI_SetResult(cli, status); + VCLI_Out(cli, "%s", p); + } else { + AZ(mgt_vcc_delbyname(av[2])); + } + } + free(p); +} + +void +mcf_config_list(struct cli *cli, const char * const *av, void *priv) +{ + unsigned status; + char *p; + const char *flg; + struct vclprog *vp; + + (void)av; + (void)priv; + if (child_pid >= 0) { + if (!mgt_cli_askchild(&status, &p, "vcl.list\n")) { + VCLI_SetResult(cli, status); + VCLI_Out(cli, "%s", p); + } + free(p); + } else { + VTAILQ_FOREACH(vp, &vclhead, list) { + if (vp->active) { + flg = "active"; + } else + flg = "available"; + VCLI_Out(cli, "%-10s %6s %s\n", + flg, "N/A", vp->name); + } + } +} + +/* + * XXX: This should take an option argument to show all (include) files + * XXX: This violates the principle of not loading VCL's in the master + * XXX: process. + */ +void +mcf_config_show(struct cli *cli, const char * const *av, void *priv) +{ + struct vclprog *vp; + void *dlh, *sym; + const char **src; + + (void)priv; + if ((vp = mcf_find_vcl(cli, av[2])) != NULL) { + if ((dlh = dlopen(vp->fname, RTLD_NOW | RTLD_LOCAL)) == NULL) { + VCLI_Out(cli, "failed to load %s: %s\n", + vp->name, dlerror()); + VCLI_SetResult(cli, CLIS_CANT); + } else if ((sym = dlsym(dlh, "srcbody")) == NULL) { + VCLI_Out(cli, "failed to locate source for %s: %s\n", + vp->name, dlerror()); + VCLI_SetResult(cli, CLIS_CANT); + AZ(dlclose(dlh)); + } else { + src = sym; + VCLI_Out(cli, "%s", src[0]); + /* VCLI_Out(cli, src[1]); */ + AZ(dlclose(dlh)); + } + } +} diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c deleted file mode 100644 index 2108230..0000000 --- a/bin/varnishd/mgt_child.c +++ /dev/null @@ -1,673 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * The mechanics of handling the child process - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "heritage.h" -#include "vapi/vsm_int.h" -#include "vbm.h" -#include "vcli.h" -#include "vcli_priv.h" -#include "vev.h" -#include "vlu.h" -#include "vss.h" -#include "vtcp.h" -#include "vtim.h" - -#include "mgt_cli.h" - -pid_t child_pid = -1; - - -static struct vbitmap *fd_map; - -static int child_cli_in = -1; -static int child_VCLI_Out = -1; -static int child_output = -1; - -static enum { - CH_STOPPED = 0, - CH_STARTING = 1, - CH_RUNNING = 2, - CH_STOPPING = 3, - CH_DIED = 4 -} child_state = CH_STOPPED; - -static const char * const ch_state[] = { - [CH_STOPPED] = "stopped", - [CH_STARTING] = "starting", - [CH_RUNNING] = "running", - [CH_STOPPING] = "stopping", - [CH_DIED] = "died, (restarting)", -}; - -static struct vev *ev_poker; -static struct vev *ev_listen; -static struct vlu *vlu; - -static struct vsb *child_panic = NULL; - -/*-------------------------------------------------------------------- - * Track the highest file descriptor the parent knows is being used. - * - * This allows the child process to clean/close only a small fraction - * of the possible file descriptors after exec(2). - * - * This is likely to a bit on the low side, as libc and other libraries - * has a tendency to cache file descriptors (syslog, resolver, etc.) - * so we add a margin of 100 fds. - */ - -static int mgt_max_fd; - -#define CLOSE_FD_UP_TO (mgt_max_fd + 100) - -void -mgt_got_fd(int fd) -{ - /* - * Assert > 0, to catch bogus opens, we know where stdin goes - * in the master process. - */ - assert(fd > 0); - if (fd > mgt_max_fd) - mgt_max_fd = fd; -} - -/*-------------------------------------------------------------------- - * A handy little function - */ - -static inline void -closex(int *fd) -{ - - assert(*fd >= 0); - AZ(close(*fd)); - *fd = -1; -} - -/*-------------------------------------------------------------------- - * Keep track of which filedescriptors the child should inherit and - * which should be closed after fork() - */ - -void -mgt_child_inherit(int fd, const char *what) -{ - - assert(fd >= 0); - if (fd_map == NULL) - fd_map = vbit_init(128); - AN(fd_map); - if (what != NULL) - vbit_set(fd_map, fd); - else - vbit_clr(fd_map, fd); -} - -/*--------------------------------------------------------------------*/ - -static int -child_line(void *priv, const char *p) -{ - (void)priv; - - REPORT(LOG_NOTICE, "Child (%jd) said %s", (intmax_t)child_pid, p); - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int -child_listener(const struct vev *e, int what) -{ - - (void)e; - if ((what & ~EV_RD)) { - ev_listen = NULL; - return (1); - } - if (VLU_Fd(child_output, vlu)) { - ev_listen = NULL; - return (1); - } - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int -child_poker(const struct vev *e, int what) -{ - - (void)e; - (void)what; - if (child_state != CH_RUNNING) - return (1); - if (child_pid < 0) - return (0); - if (!mgt_cli_askchild(NULL, NULL, "ping\n")) - return (0); - return (0); -} - -/*-------------------------------------------------------------------- - * If CLI communications with the child process fails, there is nothing - * for us to do but to drag it behind the barn and get it over with. - * - * The typical case is where the child process fails to return a reply - * before the cli_timeout expires. This invalidates the CLI pipes for - * all future use, as we don't know if the child was just slow and the - * result gets piped later on, or if the child is catatonic. - */ - -void -MGT_Child_Cli_Fail(void) -{ - - if (child_state != CH_RUNNING) - return; - if (child_pid < 0) - return; - REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", - (intmax_t)child_pid); - if (params->diag_bitmap & 0x1000) - (void)kill(child_pid, SIGKILL); - else - (void)kill(child_pid, SIGQUIT); -} - -/*--------------------------------------------------------------------*/ - -static int -open_sockets(void) -{ - struct listen_sock *ls, *ls2; - int good = 0; - - VTAILQ_FOREACH_SAFE(ls, &heritage.socks, list, ls2) { - if (ls->sock >= 0) { - good++; - continue; - } - ls->sock = VSS_bind(ls->addr); - if (ls->sock < 0) - continue; - - mgt_child_inherit(ls->sock, "sock"); - - /* - * Set nonblocking mode to avoid a race where a client - * closes before we call accept(2) and nobody else are in - * the listen queue to release us. - */ - (void)VTCP_filter_http(ls->sock); - good++; - } - if (!good) - return (1); - return (0); -} - -/*--------------------------------------------------------------------*/ - -static void -close_sockets(void) -{ - struct listen_sock *ls; - - VTAILQ_FOREACH(ls, &heritage.socks, list) { - if (ls->sock < 0) - continue; - mgt_child_inherit(ls->sock, NULL); - closex(&ls->sock); - } -} - -/*--------------------------------------------------------------------*/ - -static void -start_child(struct cli *cli) -{ - pid_t pid; - unsigned u; - char *p; - struct vev *e; - int i, cp[2]; - - if (child_state != CH_STOPPED && child_state != CH_DIED) - return; - - if (open_sockets() != 0) { - child_state = CH_STOPPED; - if (cli != NULL) { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "Could not open sockets"); - return; - } - REPORT0(LOG_ERR, - "Child start failed: could not open sockets"); - return; - } - - child_state = CH_STARTING; - - /* Open pipe for mgr->child CLI */ - AZ(pipe(cp)); - heritage.cli_in = cp[0]; - mgt_child_inherit(heritage.cli_in, "cli_in"); - child_VCLI_Out = cp[1]; - - /* Open pipe for child->mgr CLI */ - AZ(pipe(cp)); - heritage.VCLI_Out = cp[1]; - mgt_child_inherit(heritage.VCLI_Out, "VCLI_Out"); - child_cli_in = cp[0]; - - /* - * Open pipe for child stdout/err - * NB: not inherited, because we dup2() it to stdout/stderr in child - */ - AZ(pipe(cp)); - heritage.std_fd = cp[1]; - child_output = cp[0]; - - MCF_ParamSync(); - if ((pid = fork()) < 0) { - perror("Could not fork child"); - exit(1); - } - if (pid == 0) { - - /* Redirect stdin/out/err */ - AZ(close(STDIN_FILENO)); - assert(open("/dev/null", O_RDONLY) == STDIN_FILENO); - assert(dup2(heritage.std_fd, STDOUT_FILENO) == STDOUT_FILENO); - assert(dup2(heritage.std_fd, STDERR_FILENO) == STDERR_FILENO); - - /* Close anything we shouldn't know about */ - closelog(); - for (i = STDERR_FILENO + 1; i < CLOSE_FD_UP_TO; i++) { - if (vbit_test(fd_map, i)) - continue; - (void)(close(i) == 0); - } -#ifdef HAVE_SETPROCTITLE - setproctitle("Varnish-Chld %s", heritage.name); -#endif - - (void)signal(SIGINT, SIG_DFL); - (void)signal(SIGTERM, SIG_DFL); - - mgt_sandbox(); - - child_main(); - - exit(1); - } - REPORT(LOG_NOTICE, "child (%jd) Started", (intmax_t)pid); - - /* Close stuff the child got */ - closex(&heritage.std_fd); - - mgt_child_inherit(heritage.cli_in, NULL); - closex(&heritage.cli_in); - - mgt_child_inherit(heritage.VCLI_Out, NULL); - closex(&heritage.VCLI_Out); - - close_sockets(); - - vlu = VLU_New(NULL, child_line, 0); - AN(vlu); - - AZ(ev_listen); - e = vev_new(); - XXXAN(e); - e->fd = child_output; - e->fd_flags = EV_RD; - e->name = "Child listener"; - e->callback = child_listener; - AZ(vev_add(mgt_evb, e)); - ev_listen = e; - AZ(ev_poker); - if (params->ping_interval > 0) { - e = vev_new(); - XXXAN(e); - e->timeout = params->ping_interval; - e->callback = child_poker; - e->name = "child poker"; - AZ(vev_add(mgt_evb, e)); - ev_poker = e; - } - - mgt_cli_start_child(child_cli_in, child_VCLI_Out); - child_pid = pid; - if (mgt_push_vcls_and_start(&u, &p)) { - REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p); - free(p); - child_state = CH_RUNNING; - mgt_stop_child(); - } else - child_state = CH_RUNNING; -} - -/*--------------------------------------------------------------------*/ - -void -mgt_stop_child(void) -{ - - if (child_state != CH_RUNNING) - return; - - child_state = CH_STOPPING; - - REPORT0(LOG_DEBUG, "Stopping Child"); - if (ev_poker != NULL) { - vev_del(mgt_evb, ev_poker); - free(ev_poker); - } - ev_poker = NULL; - - mgt_cli_stop_child(); - - /* We tell the child to die gracefully by closing the CLI */ - closex(&child_VCLI_Out); - closex(&child_cli_in); -} - -/*--------------------------------------------------------------------*/ - -static void -mgt_report_panic(pid_t r) -{ - - if (VSM_head->panicstr[0] == '\0') - return; - REPORT(LOG_ERR, "Child (%jd) Panic message: %s", - (intmax_t)r, VSM_head->panicstr); -} - -static void -mgt_save_panic(void) -{ - char time_str[30]; - if (VSM_head->panicstr[0] == '\0') - return; - - if (child_panic) - VSB_delete(child_panic); - child_panic = VSB_new_auto(); - XXXAN(child_panic); - VTIM_format(VTIM_real(), time_str); - VSB_printf(child_panic, "Last panic at: %s\n", time_str); - VSB_cat(child_panic, VSM_head->panicstr); - AZ(VSB_finish(child_panic)); -} - -static void -mgt_clear_panic(void) -{ - VSB_delete(child_panic); - child_panic = NULL; -} - -/*--------------------------------------------------------------------*/ - -static int -mgt_sigchld(const struct vev *e, int what) -{ - int status; - struct vsb *vsb; - pid_t r; - - (void)e; - (void)what; - - if (ev_poker != NULL) { - vev_del(mgt_evb, ev_poker); - free(ev_poker); - } - ev_poker = NULL; - - r = waitpid(child_pid, &status, WNOHANG); - if (r == 0 || (r == -1 && errno == ECHILD)) - return (0); - assert(r == child_pid); - vsb = VSB_new_auto(); - XXXAN(vsb); - VSB_printf(vsb, "Child (%d) %s", r, status ? "died" : "ended"); - if (WIFEXITED(status) && WEXITSTATUS(status)) { - VSB_printf(vsb, " status=%d", WEXITSTATUS(status)); - exit_status |= 0x20; - } - if (WIFSIGNALED(status)) { - VSB_printf(vsb, " signal=%d", WTERMSIG(status)); - exit_status |= 0x40; - } -#ifdef WCOREDUMP - if (WCOREDUMP(status)) { - VSB_printf(vsb, " (core dumped)"); - exit_status |= 0x80; - } -#endif - AZ(VSB_finish(vsb)); - REPORT(LOG_INFO, "%s", VSB_data(vsb)); - VSB_delete(vsb); - - mgt_report_panic(r); - mgt_save_panic(); - - child_pid = -1; - - if (child_state == CH_RUNNING) { - child_state = CH_DIED; - mgt_cli_stop_child(); - closex(&child_VCLI_Out); - closex(&child_cli_in); - } - - if (ev_listen != NULL) { - vev_del(mgt_evb, ev_listen); - free(ev_listen); - ev_listen = NULL; - } - /* Pick up any stuff lingering on stdout/stderr */ - (void)child_listener(NULL, EV_RD); - closex(&child_output); - - REPORT0(LOG_DEBUG, "Child cleanup complete"); - - if (child_state == CH_DIED && params->auto_restart) - start_child(NULL); - else if (child_state == CH_DIED) { - child_state = CH_STOPPED; - } else if (child_state == CH_STOPPING) - child_state = CH_STOPPED; - - return (0); -} - -/*--------------------------------------------------------------------*/ - -static int -mgt_sigint(const struct vev *e, int what) -{ - - (void)e; - (void)what; - REPORT0(LOG_ERR, "Manager got SIGINT"); - (void)fflush(stdout); - if (child_pid >= 0) - mgt_stop_child(); - exit (2); -} - -/*-------------------------------------------------------------------- - * This thread is the master thread in the management process. - * The relatively simple task is to start and stop the child process - * and to reincarnate it in case of trouble. - */ - -void -MGT_Run(void) -{ - struct sigaction sac; - struct vev *e; - int i; - - e = vev_new(); - XXXAN(e); - e->sig = SIGTERM; - e->callback = mgt_sigint; - e->name = "mgt_sigterm"; - AZ(vev_add(mgt_evb, e)); - - e = vev_new(); - XXXAN(e); - e->sig = SIGINT; - e->callback = mgt_sigint; - e->name = "mgt_sigint"; - AZ(vev_add(mgt_evb, e)); - - e = vev_new(); - XXXAN(e); - e->sig = SIGCHLD; - e->sig_flags = SA_NOCLDSTOP; - e->callback = mgt_sigchld; - e->name = "mgt_sigchild"; - AZ(vev_add(mgt_evb, e)); - -#ifdef HAVE_SETPROCTITLE - setproctitle("Varnish-Mgr %s", heritage.name); -#endif - - memset(&sac, 0, sizeof sac); - sac.sa_handler = SIG_IGN; - sac.sa_flags = SA_RESTART; - - AZ(sigaction(SIGPIPE, &sac, NULL)); - AZ(sigaction(SIGHUP, &sac, NULL)); - - if (!d_flag && !mgt_has_vcl()) - REPORT0(LOG_ERR, "No VCL loaded yet"); - else if (!d_flag) { - start_child(NULL); - if (child_state == CH_STOPPED) { - exit_status = 2; - return; - } - } - - i = vev_schedule(mgt_evb); - if (i != 0) - REPORT(LOG_ERR, "vev_schedule() = %d", i); - - REPORT0(LOG_ERR, "manager dies"); -} - -/*--------------------------------------------------------------------*/ - -void __match_proto__(cli_func_t) -mcf_server_startstop(struct cli *cli, const char * const *av, void *priv) -{ - - (void)av; - if (priv != NULL && child_state == CH_RUNNING) - mgt_stop_child(); - else if (priv == NULL && child_state == CH_STOPPED) { - if (mgt_has_vcl()) { - start_child(cli); - } else { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No VCL available"); - } - } else { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "Child in state %s", ch_state[child_state]); - } -} - -/*--------------------------------------------------------------------*/ - -void -mcf_server_status(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - VCLI_Out(cli, "Child in state %s", ch_state[child_state]); -} - -void -mcf_panic_show(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - - if (!child_panic) { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "Child has not panicked or panic has been cleared"); - return; - } - - VCLI_Out(cli, "%s\n", VSB_data(child_panic)); -} - -void -mcf_panic_clear(struct cli *cli, const char * const *av, void *priv) -{ - (void)av; - (void)priv; - - if (!child_panic) { - VCLI_SetResult(cli, CLIS_CANT); - VCLI_Out(cli, "No panic to clear"); - return; - } - - mgt_clear_panic(); -} diff --git a/bin/varnishd/mgt_cli.c b/bin/varnishd/mgt_cli.c deleted file mode 100644 index dea5e7f..0000000 --- a/bin/varnishd/mgt_cli.c +++ /dev/null @@ -1,663 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * The management process' CLI handling - */ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "heritage.h" -#include "vcli.h" -#include "vcli_common.h" -#include "vcli_priv.h" -#include "vcli_serve.h" -#include "vev.h" -#include "vlu.h" -#include "vss.h" -#include "vtcp.h" - -#include "mgt_cli.h" - -#ifndef HAVE_SRANDOMDEV -#include "compat/srandomdev.h" -#endif - -static int cli_i = -1, cli_o = -1; -static struct VCLS *cls; -static const char *secret_file; - -#define MCF_NOAUTH 0 /* NB: zero disables here-documents */ -#define MCF_AUTH 16 - -/*--------------------------------------------------------------------*/ - -static void -mcf_banner(struct cli *cli, const char *const *av, void *priv) -{ - - (void)av; - (void)priv; - VCLI_Out(cli, "-----------------------------\n"); - VCLI_Out(cli, "Varnish Cache CLI 1.0\n"); - VCLI_Out(cli, "-----------------------------\n"); - VCLI_Out(cli, "%s\n", VSB_data(vident) + 1); - VCLI_Out(cli, "\n"); - VCLI_Out(cli, "Type 'help' for command list.\n"); - VCLI_Out(cli, "Type 'quit' to close CLI session.\n"); - if (child_pid < 0) - VCLI_Out(cli, "Type 'start' to launch worker process.\n"); - VCLI_SetResult(cli, CLIS_OK); -} - -/*--------------------------------------------------------------------*/ - -/* XXX: what order should this list be in ? */ -static struct cli_proto cli_proto[] = { - { CLI_BANNER, "", mcf_banner, NULL }, - { CLI_SERVER_STATUS, "", mcf_server_status, NULL }, - { CLI_SERVER_START, "", mcf_server_startstop, NULL }, - { CLI_SERVER_STOP, "", mcf_server_startstop, cli_proto }, - { CLI_VCL_LOAD, "", mcf_config_load, NULL }, - { CLI_VCL_INLINE, "", mcf_config_inline, NULL }, - { CLI_VCL_USE, "", mcf_config_use, NULL }, - { CLI_VCL_DISCARD, "", mcf_config_discard, NULL }, - { CLI_VCL_LIST, "", mcf_config_list, NULL }, - { CLI_VCL_SHOW, "", mcf_config_show, NULL }, - { CLI_PARAM_SHOW, "", mcf_param_show, NULL }, - { CLI_PARAM_SET, "", mcf_param_set, NULL }, - { CLI_PANIC_SHOW, "", mcf_panic_show, NULL }, - { CLI_PANIC_CLEAR, "", mcf_panic_clear, NULL }, - { NULL } -}; - -/*--------------------------------------------------------------------*/ - -static void -mcf_panic(struct cli *cli, const char * const *av, void *priv) -{ - - (void)cli; - (void)av; - (void)priv; - assert(!strcmp("", "You asked for it")); -} - -static struct cli_proto cli_debug[] = { - { "debug.panic.master", "debug.panic.master", - "\tPanic the master process.\n", - 0, 0, "d", mcf_panic, NULL}, - { NULL } -}; - -/*--------------------------------------------------------------------*/ - -static void -mcf_askchild(struct cli *cli, const char * const *av, void *priv) -{ - int i; - char *q; - unsigned u; - struct vsb *vsb; - - (void)priv; - /* - * Command not recognized in master, try cacher if it is - * running. - */ - if (cli_o <= 0) { - if (!strcmp(av[1], "help")) { - VCLI_Out(cli, "No help from child, (not running).\n"); - return; - } - VCLI_SetResult(cli, CLIS_UNKNOWN); - VCLI_Out(cli, - "Unknown request in manager process " - "(child not running).\n" - "Type 'help' for more info."); - return; - } - vsb = VSB_new_auto(); - for (i = 1; av[i] != NULL; i++) { - VSB_quote(vsb, av[i], strlen(av[i]), 0); - VSB_putc(vsb, ' '); - } - VSB_putc(vsb, '\n'); - AZ(VSB_finish(vsb)); - i = write(cli_o, VSB_data(vsb), VSB_len(vsb)); - if (i != VSB_len(vsb)) { - VSB_delete(vsb); - VCLI_SetResult(cli, CLIS_COMMS); - VCLI_Out(cli, "CLI communication error"); - MGT_Child_Cli_Fail(); - return; - } - VSB_delete(vsb); - (void)VCLI_ReadResult(cli_i, &u, &q, params->cli_timeout); - VCLI_SetResult(cli, u); - VCLI_Out(cli, "%s", q); - free(q); -} - -static struct cli_proto cli_askchild[] = { - { "*", "", "\t\n", - 0, 9999, "h*", mcf_askchild, NULL}, - { NULL } -}; - -/*-------------------------------------------------------------------- - * Ask the child something over CLI, return zero only if everything is - * happy happy. - */ - -int -mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) { - int i, j; - va_list ap; - unsigned u; - char buf[params->cli_buffer], *p; - - if (resp != NULL) - *resp = NULL; - if (status != NULL) - *status = 0; - if (cli_i < 0|| cli_o < 0) { - if (status != NULL) - *status = CLIS_CANT; - return (CLIS_CANT); - } - va_start(ap, fmt); - vbprintf(buf, fmt, ap); - va_end(ap); - p = strchr(buf, '\0'); - assert(p != NULL && p > buf && p[-1] == '\n'); - i = p - buf; - j = write(cli_o, buf, i); - if (j != i) { - if (status != NULL) - *status = CLIS_COMMS; - if (resp != NULL) - *resp = strdup("CLI communication error"); - MGT_Child_Cli_Fail(); - return (CLIS_COMMS); - } - - (void)VCLI_ReadResult(cli_i, &u, resp, params->cli_timeout); - if (status != NULL) - *status = u; - if (u == CLIS_COMMS) - MGT_Child_Cli_Fail(); - return (u == CLIS_OK ? 0 : u); -} - -/*--------------------------------------------------------------------*/ - -void -mgt_cli_start_child(int fdi, int fdo) -{ - - cli_i = fdi; - cli_o = fdo; -} - -/*--------------------------------------------------------------------*/ - -void -mgt_cli_stop_child(void) -{ - - cli_i = -1; - cli_o = -1; - /* XXX: kick any users */ -} - -/*-------------------------------------------------------------------- - * Generate a random challenge - */ - -static void -mgt_cli_challenge(struct cli *cli) -{ - int i; - - for (i = 0; i + 2L < sizeof cli->challenge; i++) - cli->challenge[i] = (random() % 26) + 'a'; - cli->challenge[i++] = '\n'; - cli->challenge[i] = '\0'; - VCLI_Out(cli, "%s", cli->challenge); - VCLI_Out(cli, "\nAuthentication required.\n"); - VCLI_SetResult(cli, CLIS_AUTH); -} - -/*-------------------------------------------------------------------- - * Validate the authentication - */ - -static void -mcf_auth(struct cli *cli, const char *const *av, void *priv) -{ - int fd; - char buf[CLI_AUTH_RESPONSE_LEN + 1]; - - AN(av[2]); - (void)priv; - if (secret_file == NULL) { - VCLI_Out(cli, "Secret file not configured\n"); - VCLI_SetResult(cli, CLIS_CANT); - return; - } - fd = open(secret_file, O_RDONLY); - if (fd < 0) { - VCLI_Out(cli, "Cannot open secret file (%s)\n", - strerror(errno)); - VCLI_SetResult(cli, CLIS_CANT); - return; - } - mgt_got_fd(fd); - VCLI_AuthResponse(fd, cli->challenge, buf); - AZ(close(fd)); - if (strcasecmp(buf, av[2])) { - mgt_cli_challenge(cli); - return; - } - cli->auth = MCF_AUTH; - memset(cli->challenge, 0, sizeof cli->challenge); - VCLI_SetResult(cli, CLIS_OK); - mcf_banner(cli, av, priv); -} - -static struct cli_proto cli_auth[] = { - { CLI_HELP, "", VCLS_func_help, NULL }, - { CLI_PING, "", VCLS_func_ping }, - { CLI_AUTH, "", mcf_auth, NULL }, - { CLI_QUIT, "", VCLS_func_close, NULL}, - { NULL } -}; - -/*--------------------------------------------------------------------*/ -static void -mgt_cli_cb_before(const struct cli *cli) -{ - - if (params->syslog_cli_traffic) - syslog(LOG_NOTICE, "CLI %s Rd %s", cli->ident, cli->cmd); -} - -static void -mgt_cli_cb_after(const struct cli *cli) -{ - - if (params->syslog_cli_traffic) - syslog(LOG_NOTICE, "CLI %s Wr %03u %s", - cli->ident, cli->result, VSB_data(cli->sb)); -} - -/*--------------------------------------------------------------------*/ - -static void -mgt_cli_init_cls(void) -{ - - cls = VCLS_New(mgt_cli_cb_before, mgt_cli_cb_after, params->cli_buffer); - AN(cls); - AZ(VCLS_AddFunc(cls, MCF_NOAUTH, cli_auth)); - AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_proto)); - AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_debug)); - AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_stv)); - AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_askchild)); -} - -/*-------------------------------------------------------------------- - * Get rid of all CLI sessions - */ - -void -mgt_cli_close_all(void) -{ - - VCLS_Destroy(&cls); -} - -/*-------------------------------------------------------------------- - * Callback whenever something happens to the input fd of the session. - */ - -static int -mgt_cli_callback2(const struct vev *e, int what) -{ - int i; - - (void)e; - (void)what; - i = VCLS_PollFd(cls, e->fd, 0); - return (i); -} - -/*--------------------------------------------------------------------*/ - -void -mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident, mgt_cli_close_f *closefunc, void *priv) -{ - struct cli *cli; - struct vev *ev; - - (void)ident; - (void)verbose; - if (cls == NULL) - mgt_cli_init_cls(); - - cli = VCLS_AddFd(cls, fdi, fdo, closefunc, priv); - - cli->ident = strdup(ident); - - /* Deal with TELNET options */ - if (fdi != 0) - VLU_SetTelnet(cli->vlu, fdo); - - if (fdi != 0 && secret_file != NULL) { - cli->auth = MCF_NOAUTH; - mgt_cli_challenge(cli); - } else { - cli->auth = MCF_AUTH; - mcf_banner(cli, NULL, NULL); - } - AZ(VSB_finish(cli->sb)); - (void)VCLI_WriteResult(fdo, cli->result, VSB_data(cli->sb)); - - - ev = vev_new(); - AN(ev); - ev->name = cli->ident; - ev->fd = fdi; - ev->fd_flags = EV_RD; - ev->callback = mgt_cli_callback2; - ev->priv = cli; - AZ(vev_add(mgt_evb, ev)); -} - -/*--------------------------------------------------------------------*/ - -static struct vsb * -sock_id(const char *pfx, int fd) -{ - struct vsb *vsb; - - char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; - char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; - - vsb = VSB_new_auto(); - AN(vsb); - VTCP_myname(fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); - VTCP_hisname(fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); - VSB_printf(vsb, "%s %s %s %s %s", pfx, abuf2, pbuf2, abuf1, pbuf1); - AZ(VSB_finish(vsb)); - return (vsb); -} - -/*--------------------------------------------------------------------*/ - -struct telnet { - unsigned magic; -#define TELNET_MAGIC 0x53ec3ac0 - int fd; - struct vev *ev; -}; - -static void -telnet_close(void *priv) -{ - struct telnet *tn; - - CAST_OBJ_NOTNULL(tn, priv, TELNET_MAGIC); - (void)close(tn->fd); - FREE_OBJ(tn); -} - -static struct telnet * -telnet_new(int fd) -{ - struct telnet *tn; - - ALLOC_OBJ(tn, TELNET_MAGIC); - AN(tn); - tn->fd = fd; - return (tn); -} - -static int -telnet_accept(const struct vev *ev, int what) -{ - struct vsb *vsb; - struct sockaddr_storage addr; - socklen_t addrlen; - struct telnet *tn; - int i; - - (void)what; - addrlen = sizeof addr; - i = accept(ev->fd, (void *)&addr, &addrlen); - if (i < 0 && errno == EBADF) - return (1); - if (i < 0) - return (0); - - mgt_got_fd(i); - tn = telnet_new(i); - vsb = sock_id("telnet", i); - mgt_cli_setup(i, i, 0, VSB_data(vsb), telnet_close, tn); - VSB_delete(vsb); - return (0); -} - -void -mgt_cli_secret(const char *S_arg) -{ - int i, fd; - char buf[BUFSIZ]; - char *p; - - /* Save in shmem */ - i = strlen(S_arg); - p = VSM_Alloc(i + 1, "Arg", "-S", ""); - AN(p); - strcpy(p, S_arg); - - srandomdev(); - fd = open(S_arg, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Can not open secret-file \"%s\"\n", S_arg); - exit (2); - } - mgt_got_fd(fd); - i = read(fd, buf, sizeof buf); - if (i == 0) { - fprintf(stderr, "Empty secret-file \"%s\"\n", S_arg); - exit (2); - } - if (i < 0) { - fprintf(stderr, "Can not read secret-file \"%s\"\n", S_arg); - exit (2); - } - AZ(close(fd)); - secret_file = S_arg; -} - -void -mgt_cli_telnet(const char *T_arg) -{ - struct vss_addr **ta; - int i, n, sock, good; - struct telnet *tn; - char *p; - struct vsb *vsb; - char abuf[VTCP_ADDRBUFSIZE]; - char pbuf[VTCP_PORTBUFSIZE]; - - n = VSS_resolve(T_arg, NULL, &ta); - if (n == 0) { - REPORT(LOG_ERR, "-T %s Could not be resolved\n", T_arg); - exit(2); - } - good = 0; - vsb = VSB_new_auto(); - XXXAN(vsb); - for (i = 0; i < n; ++i) { - sock = VSS_listen(ta[i], 10); - if (sock < 0) - continue; - VTCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf); - VSB_printf(vsb, "%s %s\n", abuf, pbuf); - good++; - tn = telnet_new(sock); - tn->ev = vev_new(); - XXXAN(tn->ev); - tn->ev->fd = sock; - tn->ev->fd_flags = POLLIN; - tn->ev->callback = telnet_accept; - AZ(vev_add(mgt_evb, tn->ev)); - free(ta[i]); - ta[i] = NULL; - } - free(ta); - if (good == 0) { - REPORT(LOG_ERR, "-T %s could not be listened on.", T_arg); - exit(2); - } - AZ(VSB_finish(vsb)); - /* Save in shmem */ - p = VSM_Alloc(VSB_len(vsb) + 1, "Arg", "-T", ""); - AN(p); - strcpy(p, VSB_data(vsb)); - VSB_delete(vsb); -} - -/* Reverse CLI ("Master") connections --------------------------------*/ - -static int M_fd = -1; -static struct vev *M_poker, *M_conn; -static struct vss_addr **M_ta; -static int M_nta, M_nxt; -static double M_poll = 0.1; - -static void -Marg_closer(void *priv) -{ - - (void)priv; - (void)close(M_fd); - M_fd = -1; -} - -static int -Marg_poker(const struct vev *e, int what) -{ - struct vsb *vsb; - int s, k; - socklen_t l; - - (void)what; /* XXX: ??? */ - - if (e == M_conn) { - /* Our connect(2) returned, check result */ - l = sizeof k; - AZ(getsockopt(M_fd, SOL_SOCKET, SO_ERROR, &k, &l)); - if (k) { - errno = k; - syslog(LOG_INFO, "Could not connect to CLI-master: %m"); - (void)close(M_fd); - M_fd = -1; - /* Try next address */ - if (++M_nxt >= M_nta) { - M_nxt = 0; - if (M_poll < 10) - M_poll *= 2; - } - return (1); - } - vsb = sock_id("master", M_fd); - mgt_cli_setup(M_fd, M_fd, 0, VSB_data(vsb), Marg_closer, NULL); - VSB_delete(vsb); - M_poll = 1; - return (1); - } - - assert(e == M_poker); - - M_poker->timeout = M_poll; /* XXX nasty ? */ - if (M_fd >= 0) - return (0); - - /* Try to connect asynchronously */ - s = VSS_connect(M_ta[M_nxt], 1); - if (s < 0) - return (0); - - mgt_got_fd(s); - - M_conn = vev_new(); - AN(M_conn); - M_conn->callback = Marg_poker; - M_conn->name = "-M connector"; - M_conn->fd_flags = EV_WR; - M_conn->fd = s; - M_fd = s; - AZ(vev_add(mgt_evb, M_conn)); - return (0); -} - -void -mgt_cli_master(const char *M_arg) -{ - (void)M_arg; - - M_nta = VSS_resolve(M_arg, NULL, &M_ta); - if (M_nta <= 0) { - fprintf(stderr, "Could resolve -M argument to address\n"); - exit (1); - } - M_nxt = 0; - AZ(M_poker); - M_poker = vev_new(); - AN(M_poker); - M_poker->timeout = M_poll; - M_poker->callback = Marg_poker; - M_poker->name = "-M poker"; - AZ(vev_add(mgt_evb, M_poker)); -} diff --git a/bin/varnishd/mgt_cli.h b/bin/varnishd/mgt_cli.h deleted file mode 100644 index 8c49abb..0000000 --- a/bin/varnishd/mgt_cli.h +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2009 Varnish Software 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. - * - */ - -/* mgt_child.c */ -cli_func_t mcf_server_startstop; -cli_func_t mcf_server_status; -cli_func_t mcf_panic_show; -cli_func_t mcf_panic_clear; - -/* mgt_param.c */ -cli_func_t mcf_param_show; -cli_func_t mcf_param_set; - -/* mgt_vcc.c */ -cli_func_t mcf_config_load; -cli_func_t mcf_config_inline; -cli_func_t mcf_config_use; -cli_func_t mcf_config_discard; -cli_func_t mcf_config_list; -cli_func_t mcf_config_show; - -/* stevedore.c */ -extern struct cli_proto cli_stv[]; diff --git a/bin/varnishd/mgt_param.c b/bin/varnishd/mgt_param.c deleted file mode 100644 index 43749b6..0000000 --- a/bin/varnishd/mgt_param.c +++ /dev/null @@ -1,1237 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "waiter/cache_waiter.h" -#include "heritage.h" -#include "vav.h" -#include "vcli.h" -#include "vcli_common.h" -#include "vcli_priv.h" -#include "vparam.h" -#include "vss.h" - -#include "mgt_cli.h" - -#define MAGIC_INIT_STRING "\001" -struct params master; -static int nparspec; -static struct parspec const ** parspec; -static int margin; - -/*--------------------------------------------------------------------*/ - -static const struct parspec * -mcf_findpar(const char *name) -{ - int i; - - for (i = 0; i < nparspec; i++) - if (!strcmp(parspec[i]->name, name)) - return (parspec[i]); - return (NULL); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_generic_timeout(struct cli *cli, volatile unsigned *dst, const char *arg) -{ - unsigned u; - - if (arg != NULL) { - u = strtoul(arg, NULL, 0); - if (u == 0) { - VCLI_Out(cli, "Timeout must be greater than zero\n"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - *dst = u; - } else - VCLI_Out(cli, "%u", *dst); -} - -/*--------------------------------------------------------------------*/ - -void -tweak_timeout(struct cli *cli, const struct parspec *par, const char *arg) -{ - volatile unsigned *dest; - - dest = par->priv; - tweak_generic_timeout(cli, dest, arg); -} - -static void -tweak_timeout_double(struct cli *cli, const struct parspec *par, - const char *arg) -{ - volatile double *dest; - double u; - - dest = par->priv; - if (arg != NULL) { - u = strtod(arg, NULL); - if (u < par->min) { - VCLI_Out(cli, - "Timeout must be greater or equal to %.g\n", - par->min); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - if (u > par->max) { - VCLI_Out(cli, - "Timeout must be less than or equal to %.g\n", - par->max); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - *dest = u; - } else - VCLI_Out(cli, "%.6f", *dest); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_generic_double(struct cli *cli, const struct parspec *par, - const char *arg) -{ - volatile double *dest; - double u; - - dest = par->priv; - if (arg != NULL) { - u = strtod(arg, NULL); - if (u < par->min) { - VCLI_Out(cli, - "Must be greater or equal to %.g\n", - par->min); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - if (u > par->max) { - VCLI_Out(cli, - "Must be less than or equal to %.g\n", - par->max); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - *dest = u; - } else - VCLI_Out(cli, "%f", *dest); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_generic_bool(struct cli *cli, volatile unsigned *dest, const char *arg) -{ - if (arg != NULL) { - if (!strcasecmp(arg, "off")) - *dest = 0; - else if (!strcasecmp(arg, "disable")) - *dest = 0; - else if (!strcasecmp(arg, "no")) - *dest = 0; - else if (!strcasecmp(arg, "false")) - *dest = 0; - else if (!strcasecmp(arg, "on")) - *dest = 1; - else if (!strcasecmp(arg, "enable")) - *dest = 1; - else if (!strcasecmp(arg, "yes")) - *dest = 1; - else if (!strcasecmp(arg, "true")) - *dest = 1; - else { - VCLI_Out(cli, "use \"on\" or \"off\"\n"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - } else - VCLI_Out(cli, *dest ? "on" : "off"); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_bool(struct cli *cli, const struct parspec *par, const char *arg) -{ - volatile unsigned *dest; - - dest = par->priv; - tweak_generic_bool(cli, dest, arg); -} - -/*--------------------------------------------------------------------*/ - -void -tweak_generic_uint(struct cli *cli, volatile unsigned *dest, const char *arg, - unsigned min, unsigned max) -{ - unsigned u; - - if (arg != NULL) { - if (!strcasecmp(arg, "unlimited")) - u = UINT_MAX; - else - u = strtoul(arg, NULL, 0); - if (u < min) { - VCLI_Out(cli, "Must be at least %u\n", min); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - if (u > max) { - VCLI_Out(cli, "Must be no more than %u\n", max); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - *dest = u; - } else if (*dest == UINT_MAX) { - VCLI_Out(cli, "unlimited", *dest); - } else { - VCLI_Out(cli, "%u", *dest); - } -} - -/*--------------------------------------------------------------------*/ - -void -tweak_uint(struct cli *cli, const struct parspec *par, const char *arg) -{ - volatile unsigned *dest; - - dest = par->priv; - tweak_generic_uint(cli, dest, arg, (uint)par->min, (uint)par->max); -} - -/*-------------------------------------------------------------------- - * XXX: slightly magic. We want to initialize to "nobody" (XXX: shouldn't - * XXX: that be something autocrap found for us ?) but we don't want to - * XXX: fail initialization if that user doesn't exists, even though we - * XXX: do want to fail it, in subsequent sets. - * XXX: The magic init string is a hack for this. - */ - -static void -tweak_user(struct cli *cli, const struct parspec *par, const char *arg) -{ - struct passwd *pw; - struct group *gr; - - (void)par; - if (arg != NULL) { - if (!strcmp(arg, MAGIC_INIT_STRING)) { - pw = getpwnam("nobody"); - if (pw == NULL) { - master.uid = getuid(); - return; - } - } else - pw = getpwnam(arg); - if (pw == NULL) { - VCLI_Out(cli, "Unknown user"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - REPLACE(master.user, pw->pw_name); - master.uid = pw->pw_uid; - master.gid = pw->pw_gid; - - /* set group to user's primary group */ - if ((gr = getgrgid(pw->pw_gid)) != NULL && - (gr = getgrnam(gr->gr_name)) != NULL && - gr->gr_gid == pw->pw_gid) - REPLACE(master.group, gr->gr_name); - } else if (master.user) { - VCLI_Out(cli, "%s (%d)", master.user, (int)master.uid); - } else { - VCLI_Out(cli, "%d", (int)master.uid); - } -} - -/*-------------------------------------------------------------------- - * XXX: see comment for tweak_user, same thing here. - */ - -static void -tweak_group(struct cli *cli, const struct parspec *par, const char *arg) -{ - struct group *gr; - - (void)par; - if (arg != NULL) { - if (!strcmp(arg, MAGIC_INIT_STRING)) { - gr = getgrnam("nogroup"); - if (gr == NULL) { - /* Only replace if tweak_user didn't */ - if (master.gid == 0) - master.gid = getgid(); - return; - } - } else - gr = getgrnam(arg); - if (gr == NULL) { - VCLI_Out(cli, "Unknown group"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - REPLACE(master.group, gr->gr_name); - master.gid = gr->gr_gid; - } else if (master.group) { - VCLI_Out(cli, "%s (%d)", master.group, (int)master.gid); - } else { - VCLI_Out(cli, "%d", (int)master.gid); - } -} - -/*--------------------------------------------------------------------*/ - -static void -clean_listen_sock_head(struct listen_sock_head *lsh) -{ - struct listen_sock *ls, *ls2; - - VTAILQ_FOREACH_SAFE(ls, lsh, list, ls2) { - CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - VTAILQ_REMOVE(lsh, ls, list); - free(ls->name); - free(ls->addr); - FREE_OBJ(ls); - } -} - -static void -tweak_listen_address(struct cli *cli, const struct parspec *par, - const char *arg) -{ - char **av; - int i; - struct listen_sock *ls; - struct listen_sock_head lsh; - - (void)par; - if (arg == NULL) { - VCLI_Quote(cli, master.listen_address); - return; - } - - av = VAV_Parse(arg, NULL, ARGV_COMMA); - if (av == NULL) { - VCLI_Out(cli, "Parse error: out of memory"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - if (av[0] != NULL) { - VCLI_Out(cli, "Parse error: %s", av[0]); - VCLI_SetResult(cli, CLIS_PARAM); - VAV_Free(av); - return; - } - if (av[1] == NULL) { - VCLI_Out(cli, "Empty listen address"); - VCLI_SetResult(cli, CLIS_PARAM); - VAV_Free(av); - return; - } - VTAILQ_INIT(&lsh); - for (i = 1; av[i] != NULL; i++) { - struct vss_addr **ta; - int j, n; - - n = VSS_resolve(av[i], "http", &ta); - if (n == 0) { - VCLI_Out(cli, "Invalid listen address "); - VCLI_Quote(cli, av[i]); - VCLI_SetResult(cli, CLIS_PARAM); - break; - } - for (j = 0; j < n; ++j) { - ALLOC_OBJ(ls, LISTEN_SOCK_MAGIC); - AN(ls); - ls->sock = -1; - ls->addr = ta[j]; - ls->name = strdup(av[i]); - AN(ls->name); - VTAILQ_INSERT_TAIL(&lsh, ls, list); - } - free(ta); - } - VAV_Free(av); - if (cli != NULL && cli->result != CLIS_OK) { - clean_listen_sock_head(&lsh); - return; - } - - REPLACE(master.listen_address, arg); - - clean_listen_sock_head(&heritage.socks); - heritage.nsocks = 0; - - while (!VTAILQ_EMPTY(&lsh)) { - ls = VTAILQ_FIRST(&lsh); - VTAILQ_REMOVE(&lsh, ls, list); - CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC); - VTAILQ_INSERT_TAIL(&heritage.socks, ls, list); - heritage.nsocks++; - } -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_string(struct cli *cli, const struct parspec *par, const char *arg) -{ - char **p = TRUST_ME(par->priv); - - AN(p); - /* XXX should have tweak_generic_string */ - if (arg == NULL) { - VCLI_Quote(cli, *p); - } else { - REPLACE(*p, arg); - } -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_waiter(struct cli *cli, const struct parspec *par, const char *arg) -{ - - /* XXX should have tweak_generic_string */ - (void)par; - WAIT_tweak_waiter(cli, arg); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_diag_bitmap(struct cli *cli, const struct parspec *par, const char *arg) -{ - unsigned u; - - (void)par; - if (arg != NULL) { - u = strtoul(arg, NULL, 0); - master.diag_bitmap = u; - } else { - VCLI_Out(cli, "0x%x", master.diag_bitmap); - } -} - -/*--------------------------------------------------------------------*/ - -/* - * Make sure to end all lines with either a space or newline of the - * formatting will go haywire. - */ - -#define DELAYED_EFFECT_TEXT \ - "\nNB: This parameter may take quite some time to take (full) effect." - -#define MUST_RESTART_TEXT \ - "\nNB: This parameter will not take any effect until the " \ - "child process has been restarted." - -#define MUST_RELOAD_TEXT \ - "\nNB: This parameter will not take any effect until the " \ - "VCL programs have been reloaded." - -#define EXPERIMENTAL_TEXT \ - "\nNB: We do not know yet if it is a good idea to change " \ - "this parameter, or if the default value is even sensible. " \ - "Caution is advised, and feedback is most welcome." - -#define WIZARD_TEXT \ - "\nNB: Do not change this parameter, unless a developer tell " \ - "you to do so." - -/* - * Remember to update varnishd.1 whenever you add / remove a parameter or - * change its default value. - * XXX: we should generate the relevant section of varnishd.1 from here. - */ -static const struct parspec input_parspec[] = { - { "user", tweak_user, NULL, 0, 0, - "The unprivileged user to run as. Setting this will " - "also set \"group\" to the specified user's primary group.", - MUST_RESTART, - MAGIC_INIT_STRING }, - { "group", tweak_group, NULL, 0, 0, - "The unprivileged group to run as.", - MUST_RESTART, - MAGIC_INIT_STRING }, - { "default_ttl", tweak_timeout_double, &master.default_ttl, - 0, UINT_MAX, - "The TTL assigned to objects if neither the backend nor " - "the VCL code assigns one.\n" - "Objects already cached will not be affected by changes " - "made until they are fetched from the backend again.\n" - "To force an immediate effect at the expense of a total " - "flush of the cache use \"ban.url .\"", - 0, - "120", "seconds" }, - { "sess_workspace", tweak_uint, &master.sess_workspace, 1024, UINT_MAX, - "Bytes of HTTP protocol workspace allocated for sessions. " - "This space must be big enough for the entire HTTP protocol " - "header and any edits done to it in the VCL code.\n" - "Minimum is 1024 bytes.", - DELAYED_EFFECT, - "65536", - "bytes" }, - { "http_req_hdr_len", tweak_uint, &master.http_req_hdr_len, - 40, UINT_MAX, - "Maximum length of any HTTP client request header we will " - "allow. The limit is inclusive its continuation lines.\n", - 0, - "8192", "bytes" }, - { "http_req_size", tweak_uint, &master.http_req_size, - 256, UINT_MAX, - "Maximum number of bytes of HTTP client request we will deal " - "with. This is a limit on all bytes up to the double blank " - "line which ends the HTTP request.\n" - "The memory for the request is allocated from the session " - "workspace (param: sess_workspace) and this parameter limits " - "how much of that the request is allowed to take up.", - 0, - "32768", "bytes" }, - { "http_resp_hdr_len", tweak_uint, &master.http_resp_hdr_len, - 40, UINT_MAX, - "Maximum length of any HTTP backend response header we will " - "allow. The limit is inclusive its continuation lines.\n", - 0, - "8192", "bytes" }, - { "http_resp_size", tweak_uint, &master.http_resp_size, - 256, UINT_MAX, - "Maximum number of bytes of HTTP backend resonse we will deal " - "with. This is a limit on all bytes up to the double blank " - "line which ends the HTTP request.\n" - "The memory for the request is allocated from the worker " - "workspace (param: sess_workspace) and this parameter limits " - "how much of that the request is allowed to take up.", - 0, - "32768", "bytes" }, - { "http_max_hdr", tweak_uint, &master.http_max_hdr, 32, 65535, - "Maximum number of HTTP headers we will deal with in " - "client request or backend reponses. " - "Note that the first line occupies five header fields.\n" - "This paramter does not influence storage consumption, " - "objects allocate exact space for the headers they store.\n", - 0, - "64", "header lines" }, - { "shm_workspace", tweak_uint, &master.shm_workspace, 4096, UINT_MAX, - "Bytes of shmlog workspace allocated for worker threads. " - "If too big, it wastes some ram, if too small it causes " - "needless flushes of the SHM workspace.\n" - "These flushes show up in stats as " - "\"SHM flushes due to overflow\".\n" - "Minimum is 4096 bytes.", - DELAYED_EFFECT, - "8192", "bytes" }, - { "shm_reclen", tweak_uint, &master.shm_reclen, 16, 65535, - "Maximum number of bytes in SHM log record.\n" - "Maximum is 65535 bytes.", - 0, - "255", "bytes" }, - { "default_grace", tweak_timeout_double, &master.default_grace, - 0, UINT_MAX, - "Default grace period. We will deliver an object " - "this long after it has expired, provided another thread " - "is attempting to get a new copy.\n" - "Objects already cached will not be affected by changes " - "made until they are fetched from the backend again.\n", - DELAYED_EFFECT, - "10", "seconds" }, - { "default_keep", tweak_timeout_double, &master.default_keep, - 0, UINT_MAX, - "Default keep period. We will keep a useless object " - "around this long, making it available for conditional " - "backend fetches. " - "That means that the object will be removed from the " - "cache at the end of ttl+grace+keep.", - DELAYED_EFFECT, - "0", "seconds" }, - { "sess_timeout", tweak_timeout, &master.sess_timeout, 0, 0, - "Idle timeout for persistent sessions. " - "If a HTTP request has not been received in this many " - "seconds, the session is closed.", - 0, - "5", "seconds" }, - { "expiry_sleep", tweak_timeout_double, &master.expiry_sleep, 0, 60, - "How long the expiry thread sleeps when there is nothing " - "for it to do.\n", - 0, - "1", "seconds" }, - { "pipe_timeout", tweak_timeout, &master.pipe_timeout, 0, 0, - "Idle timeout for PIPE sessions. " - "If nothing have been received in either direction for " - "this many seconds, the session is closed.\n", - 0, - "60", "seconds" }, - { "send_timeout", tweak_timeout, &master.send_timeout, 0, 0, - "Send timeout for client connections. " - "If the HTTP response hasn't been transmitted in this many\n" - "seconds the session is closed. \n" - "See setsockopt(2) under SO_SNDTIMEO for more information.", - DELAYED_EFFECT, - "60", "seconds" }, - { "auto_restart", tweak_bool, &master.auto_restart, 0, 0, - "Restart child process automatically if it dies.\n", - 0, - "on", "bool" }, - { "nuke_limit", - tweak_uint, &master.nuke_limit, 0, UINT_MAX, - "Maximum number of objects we attempt to nuke in order" - "to make space for a object body.", - EXPERIMENTAL, - "50", "allocations" }, - { "fetch_chunksize", - tweak_uint, &master.fetch_chunksize, 4, UINT_MAX / 1024., - "The default chunksize used by fetcher. " - "This should be bigger than the majority of objects with " - "short TTLs.\n" - "Internal limits in the storage_file module makes increases " - "above 128kb a dubious idea.", - EXPERIMENTAL, - "128", "kilobytes" }, - { "fetch_maxchunksize", - tweak_uint, &master.fetch_maxchunksize, 64, UINT_MAX / 1024., - "The maximum chunksize we attempt to allocate from storage. " - "Making this too large may cause delays and storage " - "fragmentation.\n", - EXPERIMENTAL, - "262144", "kilobytes" }, -#ifdef SENDFILE_WORKS - { "sendfile_threshold", - tweak_uint, &master.sendfile_threshold, 0, UINT_MAX, - "The minimum size of objects transmitted with sendfile.", - EXPERIMENTAL, - "-1", "bytes" }, -#endif /* SENDFILE_WORKS */ - { "vcl_trace", tweak_bool, &master.vcl_trace, 0, 0, - "Trace VCL execution in the shmlog.\n" - "Enabling this will allow you to see the path each " - "request has taken through the VCL program.\n" - "This generates a lot of logrecords so it is off by " - "default.", - 0, - "off", "bool" }, - { "listen_address", tweak_listen_address, NULL, 0, 0, - "Whitespace separated list of network endpoints where " - "Varnish will accept requests.\n" - "Possible formats: host, host:port, :port", - MUST_RESTART, - ":80" }, - { "listen_depth", tweak_uint, &master.listen_depth, 0, UINT_MAX, - "Listen queue depth.", - MUST_RESTART, - "1024", "connections" }, - { "cli_timeout", tweak_timeout, &master.cli_timeout, 0, 0, - "Timeout for the childs replies to CLI requests from " - "the master.", - 0, - "10", "seconds" }, - { "ping_interval", tweak_uint, &master.ping_interval, 0, UINT_MAX, - "Interval between pings from parent to child.\n" - "Zero will disable pinging entirely, which makes " - "it possible to attach a debugger to the child.", - MUST_RESTART, - "3", "seconds" }, - { "lru_interval", tweak_timeout, &master.lru_timeout, 0, 0, - "Grace period before object moves on LRU list.\n" - "Objects are only moved to the front of the LRU " - "list if they have not been moved there already inside " - "this timeout period. This reduces the amount of lock " - "operations necessary for LRU list access.", - EXPERIMENTAL, - "2", "seconds" }, - { "cc_command", tweak_string, &mgt_cc_cmd, 0, 0, - "Command used for compiling the C source code to a " - "dlopen(3) loadable object. Any occurrence of %s in " - "the string will be replaced with the source file name, " - "and %o will be replaced with the output file name.", - MUST_RELOAD, - VCC_CC , NULL }, - { "max_restarts", tweak_uint, &master.max_restarts, 0, UINT_MAX, - "Upper limit on how many times a request can restart." - "\nBe aware that restarts are likely to cause a hit against " - "the backend, so don't increase thoughtlessly.\n", - 0, - "4", "restarts" }, - { "esi_syntax", - tweak_uint, &master.esi_syntax, 0, UINT_MAX, - "Bitmap controlling ESI parsing code:\n" - " 0x00000001 - Don't check if it looks like XML\n" - " 0x00000002 - Ignore non-esi elements\n" - " 0x00000004 - Emit parsing debug records\n" - " 0x00000008 - Force-split parser input (debugging)\n" - "Use 0x notation and do the bitor in your head :-)\n", - 0, - "0", "bitmap" }, - { "max_esi_depth", - tweak_uint, &master.max_esi_depth, 0, UINT_MAX, - "Maximum depth of esi:include processing.\n", - 0, - "5", "levels" }, - { "connect_timeout", tweak_timeout_double, - &master.connect_timeout,0, UINT_MAX, - "Default connection timeout for backend connections. " - "We only try to connect to the backend for this many " - "seconds before giving up. " - "VCL can override this default value for each backend and " - "backend request.", - 0, - "0.7", "s" }, - { "first_byte_timeout", tweak_timeout_double, - &master.first_byte_timeout,0, UINT_MAX, - "Default timeout for receiving first byte from backend. " - "We only wait for this many seconds for the first " - "byte before giving up. A value of 0 means it will never time " - "out. " - "VCL can override this default value for each backend and " - "backend request. This parameter does not apply to pipe.", - 0, - "60", "s" }, - { "between_bytes_timeout", tweak_timeout_double, - &master.between_bytes_timeout,0, UINT_MAX, - "Default timeout between bytes when receiving data from " - "backend. " - "We only wait for this many seconds between bytes " - "before giving up. A value of 0 means it will never time out. " - "VCL can override this default value for each backend request " - "and backend request. This parameter does not apply to pipe.", - 0, - "60", "s" }, - { "acceptor_sleep_max", tweak_timeout_double, - &master.acceptor_sleep_max, 0, 10, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter limits how long it can sleep between " - "attempts to accept new connections.", - EXPERIMENTAL, - "0.050", "s" }, - { "acceptor_sleep_incr", tweak_timeout_double, - &master.acceptor_sleep_incr, 0, 1, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter control how much longer we sleep, each time " - "we fail to accept a new connection.", - EXPERIMENTAL, - "0.001", "s" }, - { "acceptor_sleep_decay", tweak_generic_double, - &master.acceptor_sleep_decay, 0, 1, - "If we run out of resources, such as file descriptors or " - "worker threads, the acceptor will sleep between accepts.\n" - "This parameter (multiplicatively) reduce the sleep duration " - "for each succesfull accept. (ie: 0.9 = reduce by 10%)", - EXPERIMENTAL, - "0.900", "" }, - { "clock_skew", tweak_uint, &master.clock_skew, 0, UINT_MAX, - "How much clockskew we are willing to accept between the " - "backend and our own clock.", - 0, - "10", "s" }, - { "prefer_ipv6", tweak_bool, &master.prefer_ipv6, 0, 0, - "Prefer IPv6 address when connecting to backends which " - "have both IPv4 and IPv6 addresses.", - 0, - "off", "bool" }, - { "session_max", tweak_uint, - &master.max_sess, 1000, UINT_MAX, - "Maximum number of sessions we will allocate from one pool " - "before just dropping connections.\n" - "This is mostly an anti-DoS measure, and setting it plenty " - "high should not hurt, as long as you have the memory for " - "it.\n", - 0, - "100000", "sessions" }, - { "session_linger", tweak_uint, - &master.session_linger,0, UINT_MAX, - "How long time the workerthread lingers on the session " - "to see if a new request appears right away.\n" - "If sessions are reused, as much as half of all reuses " - "happen within the first 100 msec of the previous request " - "completing.\n" - "Setting this too high results in worker threads not doing " - "anything for their keep, setting it too low just means that " - "more sessions take a detour around the waiter.", - EXPERIMENTAL, - "50", "ms" }, - { "cli_buffer", tweak_uint, &master.cli_buffer, 4096, UINT_MAX, - "Size of buffer for CLI input." - "\nYou may need to increase this if you have big VCL files " - "and use the vcl.inline CLI command.\n" - "NB: Must be specified with -p to have effect.\n", - 0, - "8192", "bytes" }, - { "log_hashstring", tweak_bool, &master.log_hash, 0, 0, - "Log the hash string components to shared memory log.\n", - 0, - "on", "bool" }, - { "log_local_address", tweak_bool, &master.log_local_addr, 0, 0, - "Log the local address on the TCP connection in the " - "SessionOpen shared memory record.\n", - 0, - "off", "bool" }, - { "waiter", tweak_waiter, NULL, 0, 0, - "Select the waiter kernel interface.\n", - EXPERIMENTAL | MUST_RESTART, - "default", NULL }, - { "diag_bitmap", tweak_diag_bitmap, 0, 0, 0, - "Bitmap controlling diagnostics code:\n" - " 0x00000001 - CNT_Session states.\n" - " 0x00000002 - workspace debugging.\n" - " 0x00000004 - kqueue debugging.\n" - " 0x00000008 - mutex logging.\n" - " 0x00000010 - mutex contests.\n" - " 0x00000020 - waiting list.\n" - " 0x00000040 - object workspace.\n" - " 0x00001000 - do not core-dump child process.\n" - " 0x00002000 - only short panic message.\n" - " 0x00004000 - panic to stderr.\n" -#ifdef HAVE_ABORT2 - " 0x00008000 - panic to abort2().\n" -#endif - " 0x00010000 - synchronize shmlog.\n" - " 0x00020000 - synchronous start of persistence.\n" - " 0x00040000 - release VCL early.\n" - " 0x80000000 - do edge-detection on digest.\n" - "Use 0x notation and do the bitor in your head :-)\n", - 0, - "0", "bitmap" }, - { "ban_dups", tweak_bool, &master.ban_dups, 0, 0, - "Detect and eliminate duplicate bans.\n", - 0, - "on", "bool" }, - { "syslog_cli_traffic", tweak_bool, &master.syslog_cli_traffic, 0, 0, - "Log all CLI traffic to syslog(LOG_INFO).\n", - 0, - "on", "bool" }, - { "ban_lurker_sleep", tweak_timeout_double, - &master.ban_lurker_sleep, 0, UINT_MAX, - "How long time does the ban lurker thread sleeps between " - "successful attempts to push the last item up the ban " - " list. It always sleeps a second when nothing can be done.\n" - "A value of zero disables the ban lurker.", - 0, - "0.01", "s" }, - { "saintmode_threshold", tweak_uint, - &master.saintmode_threshold, 0, UINT_MAX, - "The maximum number of objects held off by saint mode before " - "no further will be made to the backend until one times out. " - "A value of 0 disables saintmode.", - EXPERIMENTAL, - "10", "objects" }, - { "http_range_support", tweak_bool, &master.http_range_support, 0, 0, - "Enable support for HTTP Range headers.\n", - EXPERIMENTAL, - "on", "bool" }, - { "http_gzip_support", tweak_bool, &master.http_gzip_support, 0, 0, - "Enable gzip support. When enabled Varnish will compress " - "uncompressed objects before they are stored in the cache. " - "If a client does not support gzip encoding Varnish will " - "uncompress compressed objects on demand. Varnish will also " - "rewrite the Accept-Encoding header of clients indicating " - "support for gzip to:\n" - "Accept-Encoding: gzip\n\n" - "Clients that do not support gzip will have their " - "Accept-Encoding header removed. For more information on how " - "gzip is implemented please see the chapter on gzip in the " - "Varnish reference.", - EXPERIMENTAL, - "on", "bool" }, - { "gzip_tmp_space", tweak_uint, &master.gzip_tmp_space, 0, 2, - "Where temporary space for gzip/gunzip is allocated:\n" - " 0 - malloc\n" - " 1 - session workspace\n" - " 2 - thread workspace\n" - "If you have much gzip/gunzip activity, it may be an" - " advantage to use workspace for these allocations to reduce" - " malloc activity. Be aware that gzip needs 256+KB and gunzip" - " needs 32+KB of workspace (64+KB if ESI processing).", - EXPERIMENTAL, - "0", "" }, - { "gzip_level", tweak_uint, &master.gzip_level, 0, 9, - "Gzip compression level: 0=debug, 1=fast, 9=best", - 0, - "6", ""}, - { "gzip_window", tweak_uint, &master.gzip_window, 8, 15, - "Gzip window size 8=least, 15=most compression.\n" - "Memory impact is 8=1k, 9=2k, ... 15=128k.", - 0, - "15", ""}, - { "gzip_memlevel", tweak_uint, &master.gzip_memlevel, 1, 9, - "Gzip memory level 1=slow/least, 9=fast/most compression.\n" - "Memory impact is 1=1k, 2=2k, ... 9=256k.", - 0, - "8", ""}, - { "gzip_stack_buffer", tweak_uint, &master.gzip_stack_buffer, - 2048, UINT_MAX, - "Size of stack buffer used for gzip processing.\n" - "The stack buffers are used for in-transit data," - " for instance gunzip'ed data being sent to a client." - "Making this space to small results in more overhead," - " writes to sockets etc, making it too big is probably" - " just a waste of memory.", - EXPERIMENTAL, - "32768", "Bytes" }, - { "shortlived", tweak_timeout_double, - &master.shortlived, 0, UINT_MAX, - "Objects created with TTL shorter than this are always " - "put in transient storage.\n", - 0, - "10.0", "s" }, - { "critbit_cooloff", tweak_timeout_double, - &master.critbit_cooloff, 60, 254, - "How long time the critbit hasher keeps deleted objheads " - "on the cooloff list.\n", - WIZARD, - "180.0", "s" }, - { "vcl_dir", tweak_string, &mgt_vcl_dir, 0, 0, - "Directory from which relative VCL filenames (vcl.load and " - "include) are opened.", - 0, -#ifdef VARNISH_VCL_DIR - VARNISH_VCL_DIR, -#else - ".", -#endif - NULL }, - { "vmod_dir", tweak_string, &mgt_vmod_dir, 0, 0, - "Directory where VCL modules are to be found.", - 0, -#ifdef VARNISH_VMOD_DIR - VARNISH_VMOD_DIR, -#else - ".", -#endif - NULL }, - { "vcc_err_unref", tweak_bool, &mgt_vcc_err_unref, 0, 0, - "Unreferenced VCL objects result in error.\n", - 0, - "on", "bool" }, - - - { "pcre_match_limit", tweak_uint, - &master.vre_limits.match, - 1, UINT_MAX, - "The limit for the number of internal matching function" - " calls in a pcre_exec() execution.", - 0, - "10000", ""}, - - { "pcre_match_limit_recursion", tweak_uint, - &master.vre_limits.match_recursion, - 1, UINT_MAX, - "The limit for the number of internal matching function" - " recursions in a pcre_exec() execution.", - 0, - "10000", ""}, - - { NULL, NULL, NULL } -}; - -/*--------------------------------------------------------------------*/ - -#define WIDTH 76 - -static void -mcf_wrap(struct cli *cli, const char *text) -{ - const char *p, *q; - - /* Format text to COLUMNS width */ - for (p = text; *p != '\0'; ) { - q = strchr(p, '\n'); - if (q == NULL) - q = strchr(p, '\0'); - if (q > p + WIDTH - margin) { - q = p + WIDTH - margin; - while (q > p && *q != ' ') - q--; - AN(q); - } - VCLI_Out(cli, "%*s %.*s\n", margin, "", (int)(q - p), p); - p = q; - if (*p == ' ' || *p == '\n') - p++; - } -} - -void -mcf_param_show(struct cli *cli, const char * const *av, void *priv) -{ - int i; - const struct parspec *pp; - int lfmt; - - (void)priv; - if (av[2] == NULL || strcmp(av[2], "-l")) - lfmt = 0; - else - lfmt = 1; - for (i = 0; i < nparspec; i++) { - pp = parspec[i]; - if (av[2] != NULL && !lfmt && strcmp(pp->name, av[2])) - continue; - VCLI_Out(cli, "%-*s ", margin, pp->name); - if (pp->func == NULL) { - VCLI_Out(cli, "Not implemented.\n"); - if (av[2] != NULL && !lfmt) - return; - else - continue; - } - pp->func(cli, pp, NULL); - if (pp->units != NULL) - VCLI_Out(cli, " [%s]\n", pp->units); - else - VCLI_Out(cli, "\n"); - if (av[2] != NULL) { - VCLI_Out(cli, "%-*s Default is %s\n", - margin, "", pp->def); - mcf_wrap(cli, pp->descr); - if (pp->flags & DELAYED_EFFECT) - mcf_wrap(cli, DELAYED_EFFECT_TEXT); - if (pp->flags & EXPERIMENTAL) - mcf_wrap(cli, EXPERIMENTAL_TEXT); - if (pp->flags & MUST_RELOAD) - mcf_wrap(cli, MUST_RELOAD_TEXT); - if (pp->flags & MUST_RESTART) - mcf_wrap(cli, MUST_RESTART_TEXT); - if (pp->flags & WIZARD) - mcf_wrap(cli, WIZARD_TEXT); - if (!lfmt) - return; - else - VCLI_Out(cli, "\n"); - } - } - if (av[2] != NULL && !lfmt) { - VCLI_SetResult(cli, CLIS_PARAM); - VCLI_Out(cli, "Unknown parameter \"%s\".", av[2]); - } -} - -/*--------------------------------------------------------------------*/ - -void -MCF_ParamSync(void) -{ - if (params != &master) - *params = master; -} - -/*--------------------------------------------------------------------*/ - -void -MCF_ParamSet(struct cli *cli, const char *param, const char *val) -{ - const struct parspec *pp; - - pp = mcf_findpar(param); - if (pp != NULL) { - pp->func(cli, pp, val); - if (cli->result != CLIS_OK) { - VCLI_Out(cli, "(attempting to set param %s to %s)\n", - pp->name, val); - } else if (child_pid >= 0 && pp->flags & MUST_RESTART) { - VCLI_Out(cli, "Change will take effect" - " when child is restarted"); - } else if (pp->flags & MUST_RELOAD) { - VCLI_Out(cli, "Change will take effect" - " when VCL script is reloaded"); - } - MCF_ParamSync(); - return; - } - VCLI_SetResult(cli, CLIS_PARAM); - VCLI_Out(cli, "Unknown parameter \"%s\".", param); -} - - -/*--------------------------------------------------------------------*/ - -void -mcf_param_set(struct cli *cli, const char * const *av, void *priv) -{ - - (void)priv; - MCF_ParamSet(cli, av[2], av[3]); -} - -/*-------------------------------------------------------------------- - * Add a group of parameters to the global set and sort by name. - */ - -static int -parspec_cmp(const void *a, const void *b) -{ - struct parspec * const * pa = a; - struct parspec * const * pb = b; - return (strcmp((*pa)->name, (*pb)->name)); -} - -static void -MCF_AddParams(const struct parspec *ps) -{ - const struct parspec *pp; - int n; - - n = 0; - for (pp = ps; pp->name != NULL; pp++) { - if (mcf_findpar(pp->name) != NULL) - fprintf(stderr, "Duplicate param: %s\n", pp->name); - if (strlen(pp->name) + 1 > margin) - margin = strlen(pp->name) + 1; - n++; - } - parspec = realloc(parspec, (1L + nparspec + n) * sizeof *parspec); - XXXAN(parspec); - for (pp = ps; pp->name != NULL; pp++) - parspec[nparspec++] = pp; - parspec[nparspec] = NULL; - qsort (parspec, nparspec, sizeof parspec[0], parspec_cmp); -} - -/*-------------------------------------------------------------------- - * Set defaults for all parameters - */ - -static void -MCF_SetDefaults(struct cli *cli) -{ - const struct parspec *pp; - int i; - - for (i = 0; i < nparspec; i++) { - pp = parspec[i]; - if (cli != NULL) - VCLI_Out(cli, - "Set Default for %s = %s\n", pp->name, pp->def); - pp->func(cli, pp, pp->def); - if (cli != NULL && cli->result != CLIS_OK) - return; - } -} - -/*--------------------------------------------------------------------*/ - -void -MCF_ParamInit(struct cli *cli) -{ - - MCF_AddParams(input_parspec); - MCF_AddParams(WRK_parspec); - - /* XXX: We do this twice, to get past any interdependencies */ - MCF_SetDefaults(NULL); - MCF_SetDefaults(cli); - - params = &master; -} - -/*--------------------------------------------------------------------*/ - -void -MCF_DumpRst(void) -{ - const struct parspec *pp; - const char *p, *q; - int i; - - for (i = 0; i < nparspec; i++) { - pp = parspec[i]; - printf("%s\n", pp->name); - if (pp->units != NULL && *pp->units != '\0') - printf("\t- Units: %s\n", pp->units); - printf("\t- Default: %s\n", - strcmp(pp->def,MAGIC_INIT_STRING) == 0 ? "magic" : pp->def); - /* - * XXX: we should mark the params with one/two flags - * XXX: that say if ->min/->max are valid, so we - * XXX: can emit those also in help texts. - */ - if (pp->flags) { - printf("\t- Flags: "); - q = ""; - if (pp->flags & DELAYED_EFFECT) { - printf("%sdelayed", q); - q = ", "; - } - if (pp->flags & MUST_RESTART) { - printf("%smust_restart", q); - q = ", "; - } - if (pp->flags & MUST_RELOAD) { - printf("%smust_reload", q); - q = ", "; - } - if (pp->flags & EXPERIMENTAL) { - printf("%sexperimental", q); - q = ", "; - } - printf("\n"); - } - printf("\n\t"); - for (p = pp->descr; *p; p++) { - if (*p == '\n' && p[1] =='\0') - break; - if (*p == '\n' && p[1] =='\n') { - printf("\n\n\t"); - p++; - } else if (*p == '\n') { - printf("\n\t"); - } else if (*p == ':' && p[1] == '\n') { - /* - * Start of definition list, - * use RSTs code mode for this - */ - printf("::\n"); - } else { - printf("%c", *p); - } - } - printf("\n\n"); - } - printf("\n"); -} diff --git a/bin/varnishd/mgt_pool.c b/bin/varnishd/mgt_pool.c deleted file mode 100644 index 489fab8..0000000 --- a/bin/varnishd/mgt_pool.c +++ /dev/null @@ -1,238 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * We maintain a number of worker thread pools, to spread lock contention. - * - * Pools can be added on the fly, as a means to mitigate lock contention, - * but can only be removed again by a restart. (XXX: we could fix that) - * - * Two threads herd the pools, one eliminates idle threads and aggregates - * statistics for all the pools, the other thread creates new threads - * on demand, subject to various numerical constraints. - * - * The algorithm for when to create threads needs to be reactive enough - * to handle startup spikes, but sufficiently attenuated to not cause - * thread pileups. This remains subject for improvement. - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "mgt.h" - -#include "heritage.h" -#include "vparam.h" - -/*--------------------------------------------------------------------*/ - -static void -tweak_thread_pool_min(struct cli *cli, const struct parspec *par, - const char *arg) -{ - - tweak_generic_uint(cli, &master.wthread_min, arg, - (unsigned)par->min, master.wthread_max); -} - -/*-------------------------------------------------------------------- - * This is utterly ridiculous: POSIX does not guarantee that the - * minimum thread stack size is a compile time constant. - * XXX: "32" is a magic marker for 32bit systems. - */ - -static void -tweak_stack_size(struct cli *cli, const struct parspec *par, - const char *arg) -{ - unsigned low, u; - char buf[12]; - - low = sysconf(_SC_THREAD_STACK_MIN); - - if (arg != NULL && !strcmp(arg, "32bit")) { - u = 65536; - if (u < low) - u = low; - sprintf(buf, "%u", u); - arg = buf; - } - - tweak_generic_uint(cli, &master.wthread_stacksize, arg, - low, (uint)par->max); -} - -/*--------------------------------------------------------------------*/ - -static void -tweak_thread_pool_max(struct cli *cli, const struct parspec *par, - const char *arg) -{ - - (void)par; - tweak_generic_uint(cli, &master.wthread_max, arg, - master.wthread_min, UINT_MAX); -} - -/*--------------------------------------------------------------------*/ - -const struct parspec WRK_parspec[] = { - { "thread_pools", tweak_uint, &master.wthread_pools, 1, UINT_MAX, - "Number of worker thread pools.\n" - "\n" - "Increasing number of worker pools decreases lock " - "contention.\n" - "\n" - "Too many pools waste CPU and RAM resources, and more than " - "one pool for each CPU is probably detrimal to performance.\n" - "\n" - "Can be increased on the fly, but decreases require a " - "restart to take effect.", - EXPERIMENTAL | DELAYED_EFFECT, - "2", "pools" }, - { "thread_pool_max", tweak_thread_pool_max, NULL, 1, 0, - "The maximum number of worker threads in each pool.\n" - "\n" - "Do not set this higher than you have to, since excess " - "worker threads soak up RAM and CPU and generally just get " - "in the way of getting work done.\n", - EXPERIMENTAL | DELAYED_EFFECT, - "500", "threads" }, - { "thread_pool_min", tweak_thread_pool_min, NULL, 2, 0, - "The minimum number of worker threads in each pool.\n" - "\n" - "Increasing this may help ramp up faster from low load " - "situations where threads have expired.\n" - "\n" - "Minimum is 2 threads.", - EXPERIMENTAL | DELAYED_EFFECT, - "5", "threads" }, - { "thread_pool_timeout", tweak_timeout, &master.wthread_timeout, 1, 0, - "Thread idle threshold.\n" - "\n" - "Threads in excess of thread_pool_min, which have been idle " - "for at least this long are candidates for purging.\n" - "\n" - "Minimum is 1 second.", - EXPERIMENTAL | DELAYED_EFFECT, - "300", "seconds" }, - { "thread_pool_purge_delay", - tweak_timeout, &master.wthread_purge_delay, 100, 0, - "Wait this long between purging threads.\n" - "\n" - "This controls the decay of thread pools when idle(-ish).\n" - "\n" - "Minimum is 100 milliseconds.", - EXPERIMENTAL | DELAYED_EFFECT, - "1000", "milliseconds" }, - { "thread_pool_add_threshold", - tweak_uint, &master.wthread_add_threshold, 0, UINT_MAX, - "Overflow threshold for worker thread creation.\n" - "\n" - "Setting this too low, will result in excess worker threads, " - "which is generally a bad idea.\n" - "\n" - "Setting it too high results in insuffient worker threads.\n", - EXPERIMENTAL, - "2", "requests" }, - { "thread_pool_add_delay", - tweak_timeout, &master.wthread_add_delay, 0, UINT_MAX, - "Wait at least this long between creating threads.\n" - "\n" - "Setting this too long results in insuffient worker threads.\n" - "\n" - "Setting this too short increases the risk of worker " - "thread pile-up.\n", - 0, - "2", "milliseconds" }, - { "thread_pool_fail_delay", - tweak_timeout, &master.wthread_fail_delay, 100, UINT_MAX, - "Wait at least this long after a failed thread creation " - "before trying to create another thread.\n" - "\n" - "Failure to create a worker thread is often a sign that " - " the end is near, because the process is running out of " - "RAM resources for thread stacks.\n" - "This delay tries to not rush it on needlessly.\n" - "\n" - "If thread creation failures are a problem, check that " - "thread_pool_max is not too high.\n" - "\n" - "It may also help to increase thread_pool_timeout and " - "thread_pool_min, to reduce the rate at which treads are " - "destroyed and later recreated.\n", - EXPERIMENTAL, - "200", "milliseconds" }, - { "thread_stats_rate", - tweak_uint, &master.wthread_stats_rate, 0, UINT_MAX, - "Worker threads accumulate statistics, and dump these into " - "the global stats counters if the lock is free when they " - "finish a request.\n" - "This parameters defines the maximum number of requests " - "a worker thread may handle, before it is forced to dump " - "its accumulated stats into the global counters.\n", - EXPERIMENTAL, - "10", "requests" }, - { "queue_max", tweak_uint, &master.queue_max, 0, UINT_MAX, - "Percentage permitted queue length.\n" - "\n" - "This sets the ratio of queued requests to worker threads, " - "above which sessions will be dropped instead of queued.\n", - EXPERIMENTAL, - "100", "%" }, - { "rush_exponent", tweak_uint, &master.rush_exponent, 2, UINT_MAX, - "How many parked request we start for each completed " - "request on the object.\n" - "NB: Even with the implict delay of delivery, " - "this parameter controls an exponential increase in " - "number of worker threads.", - EXPERIMENTAL, - "3", "requests per request" }, - { "thread_pool_stack", - tweak_stack_size, &master.wthread_stacksize, 0, UINT_MAX, - "Worker thread stack size.\n" - "On 32bit systems you may need to tweak this down to fit " - "many threads into the limited address space.\n", - EXPERIMENTAL, - "-1", "bytes" }, - { "thread_pool_workspace", tweak_uint, &master.wthread_workspace, - 1024, UINT_MAX, - "Bytes of HTTP protocol workspace allocated for worker " - "threads. " - "This space must be big enough for the backend request " - "and responses, and response to the client plus any other " - "memory needs in the VCL code." - "Minimum is 1024 bytes.", - DELAYED_EFFECT, - "65536", - "bytes" }, - { NULL, NULL, NULL } -}; diff --git a/bin/varnishd/mgt_sandbox.c b/bin/varnishd/mgt_sandbox.c deleted file mode 100644 index 8ac827d..0000000 --- a/bin/varnishd/mgt_sandbox.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 2006-2011 Varnish Software 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. - * - * Sandboxing child processes - * - * The worker/manager process border is one of the major security barriers - * in Varnish, and therefore subject to whatever restrictions we have access - * to under the given operating system. - * - * Unfortunately there is no consensus on APIs for this purpose, so each - * operating system will require its own methods. - * - * This sourcefile tries to encapsulate the resulting mess on place. - * - * TODO: - * Unix: chroot - * FreeBSD: jail - * FreeBSD: capsicum - */ - -#include "config.h" - -#ifdef __linux__ -#include -#endif - -#include -#include -#include - -#include "mgt.h" - -#include "heritage.h" - -/*--------------------------------------------------------------------*/ - -/* Waive all privileges in the child, it does not need any */ - -void -mgt_sandbox(void) -{ -#ifdef HAVE_SETPPRIV - mgt_sandbox_solaris_init(); - mgt_sandbox_solaris_privsep(); -#else - if (geteuid() == 0) { - XXXAZ(setgid(params->gid)); - XXXAZ(setuid(params->uid)); - } else { - REPORT0(LOG_INFO, "Not running as root, no priv-sep"); - } -#endif - - /* On Linux >= 2.4, you need to set the dumpable flag - to get core dumps after you have done a setuid. */ - -#ifdef __linux__ - if (prctl(PR_SET_DUMPABLE, 1) != 0) - REPORT0(LOG_INFO, - "Could not set dumpable bit. Core dumps turned off\n"); -#endif - -#ifdef HAVE_SETPPRIV - mgt_sandbox_solaris_fini(); -#endif - -} diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c deleted file mode 100644 index 534f609..0000000 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ /dev/null @@ -1,233 +0,0 @@ -/*- - * Copyright (c) 2006-2011 Varnish Software AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * Nils Goroll - * - * 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. - * - * Sandboxing child processes on Solaris - * - */ - -#include "config.h" - -#ifdef HAVE_SETPPRIV - -#ifdef HAVE_PRIV_H -#include -#endif -#include -#include -#include -#include - -#include "mgt.h" - -#include "heritage.h" - -/*-------------------------------------------------------------------- - * SOLARIS PRIVILEGES: Note on use of symbolic PRIV_* constants - * - * For privileges which existed in Solaris 10 FCS, we may use the constants from - * sys/priv_names.h - * - * For privileges which have been added later, we need to use strings in order - * not to break builds of varnish on these platforms. To remain binary - * compatible, we need to silently ignore errors from priv_addset when using - * these strings. - * - * For optimal build and binary forward comatibility, we could use subtractive - * set specs like - * - * basic,!file_link_any,!proc_exec,!proc_fork,!proc_info,!proc_session - * - * but I (Nils) have a preference for making an informed decision about which - * privileges the varnish child should have and which it shouldn't. - * - * Newly introduced privileges should be annotated with their PSARC / commit ID - * (as long as Oracle reveils these :/ ) - * - * SOLARIS PRIVILEGES: Note on accidentally setting the SNOCD flag - * - * When setting privileges, we need to take care not to accidentally set the - * SNOCD flag which will disable core dumps unnecessarily. (see - * https://www.varnish-cache.org/trac/ticket/671 ) - * - * When changing the logic herein, always check with mdb -k. Replace _PID_ with - * the pid of your varnish child, the result should be 0, otherwise a regression - * has been introduced. - * - * > 0t_PID_::pid2proc | ::print proc_t p_flag | >a - * > (gid) - XXXAZ(setgid(params->gid)); - if (getuid() != params->uid) - XXXAZ(setuid(params->uid)); - } else { - REPORT(LOG_INFO, "Privilege %s missing, will not change uid/gid", - PRIV_PROC_SETID); - } -} - -/* - * Waive most privileges in the child - * - * as of onnv_151a, we should end up with: - * - * > ppriv -v #pid of varnish child - * PID: .../varnishd ... - * flags = PRIV_AWARE - * E: file_read,file_write,net_access - * I: none - * P: file_read,file_write,net_access,sys_resource - * L: file_read,file_write,net_access,sys_resource - * - * We should keep sys_resource in P in order to adjust our limits if we need to - */ - -void -mgt_sandbox_solaris_fini(void) -{ - priv_set_t *effective, *inheritable, *permitted; - - if (!(effective = priv_allocset()) || - !(inheritable = priv_allocset()) || - !(permitted = priv_allocset())) { - REPORT(LOG_ERR, - "Child start warning: mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)", - errno, strerror(errno)); - return; - } - - priv_emptyset(inheritable); - - priv_emptyset(effective); - mgt_sandbox_solaris_add_effective(effective); - - priv_copyset(effective, permitted); - mgt_sandbox_solaris_add_permitted(permitted); - - /* - * invert the sets and clear privileges such that setppriv will always - * succeed - */ - priv_inverse(inheritable); - priv_inverse(effective); - priv_inverse(permitted); - -#define SETPPRIV(which, set) \ - if (setppriv(PRIV_OFF, which, set)) \ - REPORT(LOG_ERR, \ - "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \ - #which, errno, strerror(errno)); - - SETPPRIV(PRIV_INHERITABLE, inheritable); - SETPPRIV(PRIV_EFFECTIVE, effective); - SETPPRIV(PRIV_PERMITTED, permitted); - SETPPRIV(PRIV_LIMIT, permitted); -#undef SETPPRIV - - priv_freeset(inheritable); - priv_freeset(effective); -} - -#endif /* HAVE_SETPPRIV */ diff --git a/bin/varnishd/mgt_shmem.c b/bin/varnishd/mgt_shmem.c deleted file mode 100644 index ae0a50d..0000000 --- a/bin/varnishd/mgt_shmem.c +++ /dev/null @@ -1,351 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * - * TODO: - * - * There is a risk that the child process might corrupt the VSM segment - * and we should capture that event and recover gracefully. - * - * A possible state diagram could be: - * - * [manager start] - * | - * v - * Open old VSM, - * check pid --------> exit/fail (-n message) - * | - * +<----------------------+ - * | ^ - * v | - * Create new VSM | - * | | - * v | - * Init header | - * Alloc VSL | - * Alloc VSC:Main | - * Alloc Args etc. | - * | | - * +<--------------+ | - * | ^ | - * v | | - * start worker | | - * | | | - * | | +<---- worker crash - * v | ^ - * Reset VSL ptr. | | - * Reset VSC counters | | - * | | | - * +<------+ | | - * | ^ | | - * v | | | - * alloc dynamics | | | - * free dynamics | | | - * | | | | - * v | | | - * +------>+ | | - * | | | - * v | | - * stop worker | | - * | | | - * v | | - * Check consist---------- | ----->+ - * | | - * v | - * Free dynamics | - * | | - * v | - * +-------------->+ - * - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "flopen.h" -#include "heritage.h" -#include "vapi/vsc_int.h" -#include "vapi/vsl_int.h" -#include "vapi/vsm_int.h" -#include "vav.h" -#include "vmb.h" -#include "vnum.h" - -#ifndef MAP_HASSEMAPHORE -#define MAP_HASSEMAPHORE 0 /* XXX Linux */ -#endif - -#ifndef MAP_NOSYNC -#define MAP_NOSYNC 0 /* XXX Linux */ -#endif - -struct VSC_C_main *VSC_C_main; - -static int vsl_fd = -1; - -/*-------------------------------------------------------------------- - * Check that we are not started with the same -n argument as an already - * running varnishd - */ - -static void -vsl_n_check(int fd) -{ - struct VSM_head slh; - int i; - struct stat st; - pid_t pid; - - AZ(fstat(fd, &st)); - if (!S_ISREG(st.st_mode)) - ARGV_ERR("\tshmlog: Not a file\n"); - - /* Test if the SHMFILE is locked by other Varnish */ - if (fltest(fd, &pid) > 0) { - fprintf(stderr, - "SHMFILE locked by running varnishd master (pid=%jd)\n", - (intmax_t)pid); - fprintf(stderr, - "(Use unique -n arguments if you want multiple " - "instances)\n"); - exit(2); - } - - /* Read owning pid from SHMFILE */ - memset(&slh, 0, sizeof slh); /* XXX: for flexelint */ - i = read(fd, &slh, sizeof slh); - if (i != sizeof slh) - return; - if (slh.magic != VSM_HEAD_MAGIC) - return; - if (slh.hdrsize != sizeof slh) - return; - if (slh.master_pid != 0 && !kill(slh.master_pid, 0)) { - fprintf(stderr, - "WARNING: Taking over SHMFILE marked as owned by " - "running process (pid=%jd)\n", - (intmax_t)slh.master_pid); - } -} - -/*-------------------------------------------------------------------- - * Build a new shmlog file - */ - -static void -vsl_buildnew(const char *fn, unsigned size, int fill) -{ - struct VSM_head slh; - int i; - unsigned u; - char buf[64*1024]; - int flags; - - (void)unlink(fn); - vsl_fd = flopen(fn, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0644); - if (vsl_fd < 0) { - fprintf(stderr, "Could not create %s: %s\n", - fn, strerror(errno)); - exit (1); - } - flags = fcntl(vsl_fd, F_GETFL); - assert(flags != -1); - flags &= ~O_NONBLOCK; - AZ(fcntl(vsl_fd, F_SETFL, flags)); - - memset(&slh, 0, sizeof slh); - slh.magic = VSM_HEAD_MAGIC; - slh.hdrsize = sizeof slh; - slh.shm_size = size; - i = write(vsl_fd, &slh, sizeof slh); - xxxassert(i == sizeof slh); - - if (fill) { - memset(buf, 0, sizeof buf); - for (u = sizeof slh; u < size; ) { - i = write(vsl_fd, buf, sizeof buf); - if (i <= 0) { - fprintf(stderr, "Write error %s: %s\n", - fn, strerror(errno)); - exit (1); - } - u += i; - } - } - - AZ(ftruncate(vsl_fd, (off_t)size)); -} - -/*-------------------------------------------------------------------- - * Exit handler that clears the owning pid from the SHMLOG - */ - -static -void -mgt_shm_atexit(void) -{ - if (getpid() == VSM_head->master_pid) - VSM_head->master_pid = 0; -} - -void -mgt_SHM_Init(const char *l_arg) -{ - int i, fill; - struct params *pp; - const char *q; - uintmax_t size, s1, s2, ps; - char **av, **ap; - uint32_t *vsl_log_start; - - if (l_arg == NULL) - l_arg = ""; - - av = VAV_Parse(l_arg, NULL, ARGV_COMMA); - AN(av); - if (av[0] != NULL) - ARGV_ERR("\t-l ...: %s", av[0]); - - ap = av + 1; - - /* Size of SHMLOG */ - if (*ap != NULL && **ap != '\0') { - q = VNUM_2bytes(*ap, &s1, 0); - if (q != NULL) - ARGV_ERR("\t-l[1] ...: %s\n", q); - } else { - s1 = 80 * 1024 * 1024; - } - if (*ap != NULL) - ap++; - - /* Size of space for other stuff */ - if (*ap != NULL && **ap != '\0') { - q = VNUM_2bytes(*ap, &s2, 0); - if (q != NULL) - ARGV_ERR("\t-l[2] ...: %s\n", q); - } else { - s2 = 1024 * 1024; - } - if (*ap != NULL) - ap++; - - /* Fill or not ? */ - if (*ap != NULL) { - if (**ap == '\0') - fill = 1; - else if (!strcmp(*ap, "-")) - fill = 0; - else if (!strcmp(*ap, "+")) - fill = 1; - else - ARGV_ERR("\t-l[3] ...: Must be \"-\" or \"+\"\n"); - ap++; - } else { - fill = 1; - } - - if (*ap != NULL) - ARGV_ERR("\t-l ...: Too many sub-args\n"); - - VAV_Free(av); - - size = s1 + s2; - ps = getpagesize(); - size += ps - 1; - size &= ~(ps - 1); - - i = open(VSM_FILENAME, O_RDWR, 0644); - if (i >= 0) { - vsl_n_check(i); - (void)close(i); - } - vsl_buildnew(VSM_FILENAME, size, fill); - - VSM_head = (void *)mmap(NULL, size, - PROT_READ|PROT_WRITE, - MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED, - vsl_fd, 0); - VSM_head->master_pid = getpid(); - AZ(atexit(mgt_shm_atexit)); - xxxassert(VSM_head != MAP_FAILED); - (void)mlock((void*)VSM_head, size); - - memset(&VSM_head->head, 0, sizeof VSM_head->head); - VSM_head->head.magic = VSM_CHUNK_MAGIC; - VSM_head->head.len = - (uint8_t*)(VSM_head) + size - (uint8_t*)&VSM_head->head; - bprintf(VSM_head->head.class, "%s", VSM_CLASS_FREE); - VWMB(); - - vsm_end = (void*)((uint8_t*)VSM_head + size); - - VSC_C_main = VSM_Alloc(sizeof *VSC_C_main, - VSC_CLASS, VSC_TYPE_MAIN, ""); - AN(VSC_C_main); - - pp = VSM_Alloc(sizeof *pp, VSM_CLASS_PARAM, "", ""); - AN(pp); - *pp = *params; - params = pp; - - vsl_log_start = VSM_Alloc(s1, VSL_CLASS, "", ""); - AN(vsl_log_start); - vsl_log_start[1] = VSL_ENDMARKER; - VWMB(); - - do - *vsl_log_start = random() & 0xffff; - while (*vsl_log_start == 0); - - VWMB(); - - do - VSM_head->alloc_seq = random(); - while (VSM_head->alloc_seq == 0); - -} - -void -mgt_SHM_Pid(void) -{ - - VSM_head->master_pid = getpid(); -} diff --git a/bin/varnishd/mgt_vcc.c b/bin/varnishd/mgt_vcc.c deleted file mode 100644 index 5901408..0000000 --- a/bin/varnishd/mgt_vcc.c +++ /dev/null @@ -1,676 +0,0 @@ -/*- - * Copyright (c) 2006 Verdens Gang AS - * Copyright (c) 2006-2011 Varnish Software 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. - * - * VCL compiler stuff - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#include "mgt.h" - -#include "libvcl.h" -#include "vcl.h" -#include "vcli.h" -#include "vcli_priv.h" -#include "vfil.h" -#include "vsub.h" - -#include "mgt_cli.h" - -struct vclprog { - VTAILQ_ENTRY(vclprog) list; - char *name; - char *fname; - int active; -}; - -static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead); - -char *mgt_cc_cmd; -const char *mgt_vcl_dir; -const char *mgt_vmod_dir; -unsigned mgt_vcc_err_unref; - -static struct vcc *vcc; - -/*--------------------------------------------------------------------*/ - -static const char * const default_vcl = -#include "default_vcl.h" - "" ; - -/*-------------------------------------------------------------------- - * Prepare the compiler command line - */ -static struct vsb * -mgt_make_cc_cmd(const char *sf, const char *of) -{ - struct vsb *sb; - int pct; - char *p; - - sb = VSB_new_auto(); - XXXAN(sb); - for (p = mgt_cc_cmd, pct = 0; *p; ++p) { - if (pct) { - switch (*p) { - case 's': - VSB_cat(sb, sf); - break; - case 'o': - VSB_cat(sb, of); - break; - case '%': - VSB_putc(sb, '%'); - break; - default: - VSB_putc(sb, '%'); - VSB_putc(sb, *p); - break; - } - pct = 0; - } else if (*p == '%') { - pct = 1; - } else { - VSB_putc(sb, *p); - } - } - if (pct) - VSB_putc(sb, '%'); - AZ(VSB_finish(sb)); - return (sb); -} - -/*-------------------------------------------------------------------- - * Invoke system VCC compiler in a sub-process - */ - -struct vcc_priv { - unsigned magic; -#define VCC_PRIV_MAGIC 0x70080cb8 - char *sf; - const char *vcl; -}; - -static void -run_vcc(void *priv) -{ - char *csrc; - struct vsb *sb; - struct vcc_priv *vp; - int fd, i, l; - - CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC); - sb = VSB_new_auto(); - XXXAN(sb); - VCC_VCL_dir(vcc, mgt_vcl_dir); - VCC_VMOD_dir(vcc, mgt_vmod_dir); - VCC_Err_Unref(vcc, mgt_vcc_err_unref); - csrc = VCC_Compile(vcc, sb, vp->vcl); - AZ(VSB_finish(sb)); - if (VSB_len(sb)) - printf("%s", VSB_data(sb)); - VSB_delete(sb); - if (csrc == NULL) - exit (1); - - fd = open(vp->sf, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open %s", vp->sf); - exit (1); - } - l = strlen(csrc); - i = write(fd, csrc, l); - if (i != l) { - fprintf(stderr, "Cannot write %s", vp->sf); - exit (1); - } - AZ(close(fd)); - free(csrc); - exit (0); -} - -/*-------------------------------------------------------------------- - * Invoke system C compiler in a sub-process - */ - -static void -run_cc(void *priv) -{ - (void)execl("/bin/sh", "/bin/sh", "-c", priv, NULL); -} - -/*-------------------------------------------------------------------- - * Attempt to open compiled VCL in a sub-process - */ - -static void __match_proto__(sub_func_f) -run_dlopen(void *priv) -{ - const char *of; - void *dlh; - struct VCL_conf const *cnf; - - of = priv; - - /* Try to load the object into the management process */ - if ((dlh = dlopen(of, RTLD_NOW | RTLD_LOCAL)) == NULL) { - fprintf(stderr, - "Compiled VCL program failed to load:\n %s\n", - dlerror()); - exit(1); - } - - cnf = dlsym(dlh, "VCL_conf"); - if (cnf == NULL) { - fprintf(stderr, "Compiled VCL program, metadata not found\n"); - exit(1); - } - - if (cnf->magic != VCL_CONF_MAGIC) { - fprintf(stderr, "Compiled VCL program, mangled metadata\n"); - exit(1); - } - - if (dlclose(dlh)) { - fprintf(stderr, - "Compiled VCL program failed to unload:\n %s\n", - dlerror()); - exit(1); - } - exit(0); -} - -/*-------------------------------------------------------------------- - * Compile a VCL program, return shared object, errors in sb. - */ - -static char * -mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag) -{ - char *csrc; - struct vsb *cmdsb; - char sf[] = "./vcl.########.c"; - char of[sizeof sf + 1]; - char *retval; - int sfd, i; - struct vcc_priv vp; - - /* Create temporary C source file */ - sfd = VFIL_tmpfile(sf); - if (sfd < 0) { - VSB_printf(sb, "Failed to create %s: %s", sf, strerror(errno)); - return (NULL); - } - AZ(close(sfd)); - - /* Run the VCC compiler in a sub-process */ - memset(&vp, 0, sizeof vp); - vp.magic = VCC_PRIV_MAGIC; - vp.sf = sf; - vp.vcl = vcl; - if (VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1)) { - (void)unlink(sf); - return (NULL); - } - - if (C_flag) { - csrc = VFIL_readfile(NULL, sf, NULL); - XXXAN(csrc); - (void)fputs(csrc, stdout); - free(csrc); - } - - /* Name the output shared library by "s/[.]c$/[.]so/" */ - memcpy(of, sf, sizeof sf); - assert(sf[sizeof sf - 2] == 'c'); - of[sizeof sf - 2] = 's'; - of[sizeof sf - 1] = 'o'; - of[sizeof sf] = '\0'; - - /* Build the C-compiler command line */ - cmdsb = mgt_make_cc_cmd(sf, of); - - /* Run the C-compiler in a sub-shell */ - i = VSUB_run(sb, run_cc, VSB_data(cmdsb), "C-compiler", 10); - - (void)unlink(sf); - VSB_delete(cmdsb); - - if (!i) - i = VSUB_run(sb, run_dlopen, of, "dlopen", 10); - - if (i) { - (void)unlink(of); - return (NULL); - } - - retval = strdup(of); - XXXAN(retval); - return (retval); -} - -/*--------------------------------------------------------------------*/ - -static char * -mgt_VccCompile(struct vsb **sb, const char *b, int C_flag) -{ - char *vf; - - *sb = VSB_new_auto(); - XXXAN(*sb); - vf = mgt_run_cc(b, *sb, C_flag); - AZ(VSB_finish(*sb)); - return (vf); -} - -/*--------------------------------------------------------------------*/ - -static struct vclprog * -mgt_vcc_add(const char *name, char *file) -{ - struct vclprog *vp; - - vp = calloc(sizeof *vp, 1); - XXXAN(vp); - vp->name = strdup(name); - XXXAN(vp->name); - vp->fname = file; - VTAILQ_INSERT_TAIL(&vclhead, vp, list); - return (vp); -} - -static void -mgt_vcc_del(struct vclprog *vp) -{ - VTAILQ_REMOVE(&vclhead, vp, list); - printf("unlink %s\n", vp->fname); - XXXAZ(unlink(vp->fname)); - free(vp->fname); - free(vp->name); - free(vp); -} - -static struct vclprog * -mgt_vcc_byname(const char *name) -{ - struct vclprog *vp; - - VTAILQ_FOREACH(vp, &vclhead, list) - if (!strcmp(name, vp->name)) - return (vp); - return (NULL); -} - - -static int -mgt_vcc_delbyname(const char *name) -{ - struct vclprog *vp; - - vp = mgt_vcc_byname(name); - if (vp != NULL) { - mgt_vcc_del(vp); - return (0); - } - return (1); -} - -/*--------------------------------------------------------------------*/ - -int -mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag) -{ - char *vf; - struct vsb *sb; - struct vclprog *vp; - char buf[BUFSIZ]; - - /* XXX: annotate vcl with -b/-f arg so people know where it came from */ - (void)f_arg; - - if (b_arg != NULL) { - AZ(vcl); - /* - * XXX: should do a "HEAD /" on the -b argument to see that - * XXX: it even works. On the other hand, we should do that - * XXX: for all backends in the cache process whenever we - * XXX: change config, but for a complex VCL, it might not be - * XXX: a bug for a backend to not reply at that time, so then - * XXX: again: we should check it here in the "trivial" case. - */ - bprintf(buf, - "backend default {\n" - " .host = \"%s\";\n" - "}\n", b_arg); - vcl = strdup(buf); - AN(vcl); - } - strcpy(buf, "boot"); - - vf = mgt_VccCompile(&sb, vcl, C_flag); - free(vcl); - if (VSB_len(sb) > 0) - fprintf(stderr, "%s", VSB_data(sb)); - VSB_delete(sb); - if (C_flag) { - if (vf != NULL) - AZ(unlink(vf)); - return (0); - } - if (vf == NULL) { - fprintf(stderr, "\nVCL compilation failed\n"); - return (1); - } - vp = mgt_vcc_add(buf, vf); - vp->active = 1; - return (0); -} - -/*--------------------------------------------------------------------*/ - -int -mgt_has_vcl() -{ - - return (!VTAILQ_EMPTY(&vclhead)); -} - -/*--------------------------------------------------------------------*/ - -int -mgt_push_vcls_and_start(unsigned *status, char **p) -{ - struct vclprog *vp; - - VTAILQ_FOREACH(vp, &vclhead, list) { - if (mgt_cli_askchild(status, p, - "vcl.load \"%s\" %s\n", vp->name, vp->fname)) - return (1); - free(*p); - if (!vp->active) - continue; - if (mgt_cli_askchild(status, p, - "vcl.use \"%s\"\n", vp->name)) - return (1); - free(*p); - } - if (mgt_cli_askchild(status, p, "start\n")) - return (1); - free(*p); - *p = NULL; - return (0); -} - -/*--------------------------------------------------------------------*/ - -static -void -mgt_vcc_atexit(void) -{ - struct vclprog *vp; - - if (getpid() != mgt_pid) - return; - while (1) { - vp = VTAILQ_FIRST(&vclhead); - if (vp == NULL) - break; - (void)unlink(vp->fname); - VTAILQ_REMOVE(&vclhead, vp, list); - } -} - -void -mgt_vcc_init(void) -{ - - vcc = VCC_New(); - AN(vcc); - VCC_Default_VCL(vcc, default_vcl); - AZ(atexit(mgt_vcc_atexit)); -} - -/*--------------------------------------------------------------------*/ - -void -mcf_config_inline(struct cli *cli, const char * const *av, void *priv) -{ - char *vf, *p = NULL; - struct vsb *sb; - unsigned status; - struct vclprog *vp; - - (void)priv; - - vp = mgt_vcc_byname(av[2]); - if (vp != NULL) { - VCLI_Out(cli, "Already a VCL program named %s", av[2]); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - - vf = mgt_VccCompile(&sb, av[3], 0); - if (VSB_len(sb) > 0) - VCLI_Out(cli, "%s\n", VSB_data(sb)); - VSB_delete(sb); - if (vf == NULL) { - VCLI_Out(cli, "VCL compilation failed"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - VCLI_Out(cli, "VCL compiled."); - if (child_pid >= 0 && - mgt_cli_askchild(&status, &p, "vcl.load %s %s\n", av[2], vf)) { - VCLI_SetResult(cli, status); - VCLI_Out(cli, "%s", p); - } else { - (void)mgt_vcc_add(av[2], vf); - } - free(p); -} - -void -mcf_config_load(struct cli *cli, const char * const *av, void *priv) -{ - char *vf, *vcl; - struct vsb *sb; - unsigned status; - char *p = NULL; - struct vclprog *vp; - - (void)priv; - vp = mgt_vcc_byname(av[2]); - if (vp != NULL) { - VCLI_Out(cli, "Already a VCL program named %s", av[2]); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - - vcl = VFIL_readfile(mgt_vcl_dir, av[3], NULL); - if (vcl == NULL) { - VCLI_Out(cli, "Cannot open '%s'", av[3]); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - - vf = mgt_VccCompile(&sb, vcl, 0); - free(vcl); - - if (VSB_len(sb) > 0) - VCLI_Out(cli, "%s", VSB_data(sb)); - VSB_delete(sb); - if (vf == NULL) { - VCLI_Out(cli, "VCL compilation failed"); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - VCLI_Out(cli, "VCL compiled."); - if (child_pid >= 0 && - mgt_cli_askchild(&status, &p, "vcl.load %s %s\n", av[2], vf)) { - VCLI_SetResult(cli, status); - VCLI_Out(cli, "%s", p); - } else { - (void)mgt_vcc_add(av[2], vf); - } - free(p); -} - -static struct vclprog * -mcf_find_vcl(struct cli *cli, const char *name) -{ - struct vclprog *vp; - - vp = mgt_vcc_byname(name); - if (vp != NULL) - return (vp); - VCLI_SetResult(cli, CLIS_PARAM); - VCLI_Out(cli, "No configuration named %s known.", name); - return (NULL); -} - -void -mcf_config_use(struct cli *cli, const char * const *av, void *priv) -{ - unsigned status; - char *p = NULL; - struct vclprog *vp; - - (void)priv; - vp = mcf_find_vcl(cli, av[2]); - if (vp == NULL) - return; - if (vp->active != 0) - return; - if (child_pid >= 0 && - mgt_cli_askchild(&status, &p, "vcl.use %s\n", av[2])) { - VCLI_SetResult(cli, status); - VCLI_Out(cli, "%s", p); - } else { - vp->active = 2; - VTAILQ_FOREACH(vp, &vclhead, list) { - if (vp->active == 1) - vp->active = 0; - else if (vp->active == 2) - vp->active = 1; - } - } - free(p); -} - -void -mcf_config_discard(struct cli *cli, const char * const *av, void *priv) -{ - unsigned status; - char *p = NULL; - struct vclprog *vp; - - (void)priv; - vp = mcf_find_vcl(cli, av[2]); - if (vp != NULL && vp->active) { - VCLI_SetResult(cli, CLIS_PARAM); - VCLI_Out(cli, "Cannot discard active VCL program\n"); - } else if (vp != NULL) { - if (child_pid >= 0 && - mgt_cli_askchild(&status, &p, - "vcl.discard %s\n", av[2])) { - VCLI_SetResult(cli, status); - VCLI_Out(cli, "%s", p); - } else { - AZ(mgt_vcc_delbyname(av[2])); - } - } - free(p); -} - -void -mcf_config_list(struct cli *cli, const char * const *av, void *priv) -{ - unsigned status; - char *p; - const char *flg; - struct vclprog *vp; - - (void)av; - (void)priv; - if (child_pid >= 0) { - if (!mgt_cli_askchild(&status, &p, "vcl.list\n")) { - VCLI_SetResult(cli, status); - VCLI_Out(cli, "%s", p); - } - free(p); - } else { - VTAILQ_FOREACH(vp, &vclhead, list) { - if (vp->active) { - flg = "active"; - } else - flg = "available"; - VCLI_Out(cli, "%-10s %6s %s\n", - flg, "N/A", vp->name); - } - } -} - -/* - * XXX: This should take an option argument to show all (include) files - * XXX: This violates the principle of not loading VCL's in the master - * XXX: process. - */ -void -mcf_config_show(struct cli *cli, const char * const *av, void *priv) -{ - struct vclprog *vp; - void *dlh, *sym; - const char **src; - - (void)priv; - if ((vp = mcf_find_vcl(cli, av[2])) != NULL) { - if ((dlh = dlopen(vp->fname, RTLD_NOW | RTLD_LOCAL)) == NULL) { - VCLI_Out(cli, "failed to load %s: %s\n", - vp->name, dlerror()); - VCLI_SetResult(cli, CLIS_CANT); - } else if ((sym = dlsym(dlh, "srcbody")) == NULL) { - VCLI_Out(cli, "failed to locate source for %s: %s\n", - vp->name, dlerror()); - VCLI_SetResult(cli, CLIS_CANT); - AZ(dlclose(dlh)); - } else { - src = sym; - VCLI_Out(cli, "%s", src[0]); - /* VCLI_Out(cli, src[1]); */ - AZ(dlclose(dlh)); - } - } -} diff --git a/bin/varnishd/storage/stevedore_utils.c b/bin/varnishd/storage/stevedore_utils.c index 3daebf8..7e9c7d5 100644 --- a/bin/varnishd/storage/stevedore_utils.c +++ b/bin/varnishd/storage/stevedore_utils.c @@ -49,7 +49,7 @@ #include #include -#include "mgt.h" +#include "mgt/mgt.h" #include "storage/storage.h" #include "vnum.h" diff --git a/bin/varnishd/varnishd.c b/bin/varnishd/varnishd.c index e0654a3..e0ba759 100644 --- a/bin/varnishd/varnishd.c +++ b/bin/varnishd/varnishd.c @@ -43,7 +43,7 @@ #include #include -#include "mgt.h" +#include "mgt/mgt.h" #include "hash/hash_slinger.h" #include "heritage.h" From phk at varnish-cache.org Thu Oct 13 09:59:27 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 13 Oct 2011 11:59:27 +0200 Subject: [master] e600a75 Work around a Solaris bug. Message-ID: commit e600a75ed5d35db87b36bf64d45940e50c0d25c7 Author: Poul-Henning Kamp Date: Thu Oct 13 09:59:03 2011 +0000 Work around a Solaris bug. Submitted by: Nils Goroll diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index 10c3664..c0f7a95 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -265,7 +265,13 @@ VTCP_set_read_timeout(int s, double seconds) timeout.tv_sec = (int)floor(seconds); timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec)); #ifdef SO_RCVTIMEO_WORKS - AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); + /* + * Solaris bug (present at least in snv_151 and older): If this fails + * with EINVAL, the socket is half-closed (SS_CANTSENDMORE) and the + * timeout does not get set. Needs to be fixed in Solaris, there is + * nothing we can do about this. + */ + VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); #else (void)s; #endif From phk at varnish-cache.org Thu Oct 13 10:01:17 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 13 Oct 2011 12:01:17 +0200 Subject: [master] 9988408 Adjustments to solaris sandbox. Message-ID: commit 99884082bdc3c50e586b2826b9ac7d4e46eb8dcf Author: Poul-Henning Kamp Date: Thu Oct 13 10:00:56 2011 +0000 Adjustments to solaris sandbox. Submitted by: Nils Goroll diff --git a/bin/varnishd/mgt/mgt_sandbox_solaris.c b/bin/varnishd/mgt/mgt_sandbox_solaris.c index 715408e..f243938 100644 --- a/bin/varnishd/mgt/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt/mgt_sandbox_solaris.c @@ -220,10 +220,10 @@ mgt_sandbox_solaris_fini(void) "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \ #which, errno, strerror(errno)); - SETPPRIV(PRIV_INHERITABLE, inheritable); - SETPPRIV(PRIV_EFFECTIVE, effective); - SETPPRIV(PRIV_PERMITTED, permitted); SETPPRIV(PRIV_LIMIT, permitted); + SETPPRIV(PRIV_PERMITTED, permitted); + SETPPRIV(PRIV_EFFECTIVE, effective); + SETPPRIV(PRIV_INHERITABLE, inheritable); #undef SETPPRIV priv_freeset(inheritable); From phk at varnish-cache.org Thu Oct 13 10:12:13 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 13 Oct 2011 12:12:13 +0200 Subject: [master] ac66673 Quit early if setting blocking mode fails. Message-ID: commit ac666733b7985436b77f10f5276909e7e65933c9 Author: Poul-Henning Kamp Date: Thu Oct 13 10:11:42 2011 +0000 Quit early if setting blocking mode fails. Submitted by: Nils Goroll diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 0a81925..47139c7 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -1573,14 +1573,21 @@ CNT_Session(struct sess *sp) AZ(w->do_esi); /* - * Whenever we come in from the acceptor we need to set blocking - * mode, but there is no point in setting it when we come from + * Whenever we come in from the acceptor or waiter, we need to set + * blocking mode, but there is no point in setting it when we come from * ESI or when a parked sessions returns. - * It would be simpler to do this in the acceptor, but we'd rather - * do the syscall in the worker thread. + * It would be simpler to do this in the acceptor or waiter, but we'd + * rather do the syscall in the worker thread. + * On systems which return errors for ioctl, we close early */ - if (sp->step == STP_FIRST || sp->step == STP_START) - (void)VTCP_blocking(sp->fd); + if ((sp->step == STP_FIRST || sp->step == STP_START) && + VTCP_blocking(sp->fd)) { + if (errno == ECONNRESET) + SES_Close(sp, "remote closed"); + else + SES_Close(sp, "error"); + sp->step = STP_DONE; + } /* * NB: Once done is set, we can no longer touch sp! From tfheen at varnish-cache.org Thu Oct 13 11:09:33 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 13 Oct 2011 13:09:33 +0200 Subject: [master] ce54514 Solaris: Test for SO_{RCV,SND}TIMEO needs NET_LIBS Message-ID: commit ce5451435bf3ffe64d9113222777e035b3d52bda Author: Nils Goroll Date: Fri Mar 11 17:36:54 2011 +0100 Solaris: Test for SO_{RCV,SND}TIMEO needs NET_LIBS diff --git a/configure.ac b/configure.ac index cf1f566..8295fbb 100644 --- a/configure.ac +++ b/configure.ac @@ -375,11 +375,20 @@ fi AM_MISSING_HAS_RUN AC_CHECK_PROGS(PYTHON, [python3 python3.1 python3.2 python2.7 python2.6 python2.5 python2 python], [AC_MSG_ERROR([Python is needed to build Varnish, please install python.])]) -# Solaris defines SO_{RCV,SND}TIMEO, but does not implement them. +# Older Solaris versions define SO_{RCV,SND}TIMEO, but do not +# implement them. +# # Varnish will build and run without these, but connections will not # time out, which may leave Varnish vulnerable to denail-of-service # attacks which would not be possible on other platforms. +# +# Newer Solaris releases with the Volo framework (Solaris 11, +# Opensolaris starting with onnv_106) do support SO_{RCV,SND}TIMEO +# (see PSARC 2007/587, initially committed into onnv-gate / +# OpenSolaris 8348:4137e18bfaf0 Thu Dec 11 20:04:13 2008) +save_LIBS="${LIBS}" +LIBS="${LIBS} ${NET_LIBS}" AC_CACHE_CHECK([whether SO_RCVTIMEO works], [ac_cv_so_rcvtimeo_works], [AC_RUN_IFELSE( @@ -404,7 +413,10 @@ return 1; if test "$ac_cv_so_rcvtimeo_works" = yes; then AC_DEFINE([SO_RCVTIMEO_WORKS], [1], [Define if SO_RCVTIMEO works]) fi +LIBS="${save_LIBS}" +save_LIBS="${LIBS}" +LIBS="${LIBS} ${NET_LIBS}" AC_CACHE_CHECK([whether SO_SNDTIMEO works], [ac_cv_so_sndtimeo_works], [AC_RUN_IFELSE( @@ -434,6 +446,7 @@ if test "$ac_cv_so_rcvtimeo_works" = no || test "$ac_cv_so_sndtimeo_works" = no; then AC_MSG_WARN([connection timeouts will not work]) fi +LIBS="${save_LIBS}" # Run-time directory VARNISH_STATE_DIR='${localstatedir}/varnish' From ingvar at varnish-cache.org Thu Oct 13 22:30:16 2011 From: ingvar at varnish-cache.org (Ingvar) Date: Fri, 14 Oct 2011 00:30:16 +0200 Subject: [master] bebf42d Just small typofixes Message-ID: commit bebf42d62aac3e9013c70ba5e489bcd4b6e8c232 Author: Ingvar Hagelund Date: Fri Oct 14 00:30:02 2011 +0200 Just small typofixes diff --git a/redhat/varnish.spec b/redhat/varnish.spec index e8ea8c7..0e3f1e6 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -373,7 +373,7 @@ fi - Whitespace changes to make rpmlint more happy * Fri Sep 12 2008 Ingvar Hagelund - 2.0-0.9.20080912svn3184 -- Added varnisnsca init script (Colin Hill) +- Added varnisncsa init script (Colin Hill) - Corrected varnishlog init script (Colin Hill) * Tue Sep 09 2008 Ingvar Hagelund - 2.0-0.8.beta1 diff --git a/redhat/varnishncsa.initrc b/redhat/varnishncsa.initrc index ee26376..b23fa48 100644 --- a/redhat/varnishncsa.initrc +++ b/redhat/varnishncsa.initrc @@ -1,6 +1,6 @@ #! /bin/sh # -# varnishncsa Control the Varnish NSCA logging daemon +# varnishncsa Control the Varnish NCSA logging daemon # # chkconfig: - 90 10 # description: Varnish Cache logging daemon @@ -15,7 +15,7 @@ # Default-Start: # Default-Stop: # Short-Description: start and stop varnishncsa -# Description: Varnish Cache NSCA logging daemon +# Description: Varnish Cache NCSA logging daemon ### END INIT INFO # Source function library. From phk at varnish-cache.org Fri Oct 14 08:42:23 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 14 Oct 2011 10:42:23 +0200 Subject: [master] 31636e6 Even more strange error returns on Solaris Message-ID: commit 31636e68029195142aee28b5fefb00841b3990a2 Author: Poul-Henning Kamp Date: Fri Oct 14 08:42:04 2011 +0000 Even more strange error returns on Solaris diff --git a/include/vtcp.h b/include/vtcp.h index 022f101..6ad260e 100644 --- a/include/vtcp.h +++ b/include/vtcp.h @@ -33,16 +33,24 @@ #define VTCP_ADDRBUFSIZE 64 #define VTCP_PORTBUFSIZE 16 +static inline int +VTCP_Check(int a) +{ + if (a == 0) + return (1); + if (errno == ECONNRESET || errno == ENOTCONN) + return (1); #if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__) -/* - * Solaris returns EINVAL if the other end unexepectedly reset the - * connection. This is a bug in Solaris and documented behaviour on NetBSD. - */ -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN \ - || errno == EINVAL) -#else -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN) + /* + * Solaris returns EINVAL if the other end unexepectedly reset the + * connection. + * This is a bug in Solaris and documented behaviour on NetBSD. + */ + if (errno == EINVAL || errno == ETIMEDOUT) + return (1); #endif + return (0); +} #define VTCP_Assert(a) assert(VTCP_Check(a)) From tfheen at varnish-cache.org Fri Oct 14 10:51:18 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Fri, 14 Oct 2011 12:51:18 +0200 Subject: [master] b06654b Drop explicit dependeny on Makefile for default_vcl.h to avoid spurious rebuilds Message-ID: commit b06654b978c59181f53c19a66b1468b0f11acc0f Author: Tollef Fog Heen Date: Fri Oct 14 12:39:57 2011 +0200 Drop explicit dependeny on Makefile for default_vcl.h to avoid spurious rebuilds diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index f2e9d04..c95b09a 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -115,7 +115,7 @@ DISTCLEANFILES = default_vcl.h # # Turn the default.vcl file into a C-string we can include in the program. # -default_vcl.h: default.vcl Makefile +default_vcl.h: default.vcl echo '/*' > $@ echo ' * NB: This file is machine generated, DO NOT EDIT!' >> $@ echo ' *' >> $@ From kristian at varnish-cache.org Mon Oct 17 11:35:30 2011 From: kristian at varnish-cache.org (=?UTF-8?Q?Kristian_Lyngst=C3=B8l?=) Date: Mon, 17 Oct 2011 13:35:30 +0200 Subject: [master] 601ee74 Ensure obj->response is set sensibly for errors Message-ID: commit 601ee74203b8d0088251c43c5e5de380dabdcba0 Author: Kristian Lyngstol Date: Mon Oct 17 13:30:29 2011 +0200 Ensure obj->response is set sensibly for errors The http_PutProtocol() and http_PutResponse() would in the case of workspace overflow leave the headers as NULL and log a SLT_LostHeader. This would make Varnish assert correctly later when writing to the wire, as these are mandated by HTTP. This commit changes them to set the fields to static strings instead ("HTTP/1.1" and "Lost Response") when failing to write them to the workspace. This leaves enough information to complete the protocol in the case of overflow. The patch also increases the synthetic object's workspace from static 1024 to param->http_resp_size. This leaves more (and configurable) room for manipulating the headers of the synthetic object in vcl_error. This whole thing has been a collaboration between Martin and myself. I'll leave it a mystery who wrote what line of code, which part of the comment and contributed what to the test-case. In all fairness, it's not a prefect solution, but a far step closer to one. So it sort of, kinda, more or less, for now, until we get a better solution: Fixes: #1031 diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 47139c7..6bf0b0c 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -435,13 +435,13 @@ cnt_error(struct sess *sp) w = sp->wrk; if (sp->obj == NULL) { HSH_Prealloc(sp); - /* XXX: 1024 is a pure guess */ EXP_Clr(&w->exp); - sp->obj = STV_NewObject(sp, NULL, 1024, &w->exp, - (uint16_t)params->http_max_hdr); + sp->obj = STV_NewObject(sp, NULL, params->http_resp_size, + &w->exp, (uint16_t)params->http_max_hdr); if (sp->obj == NULL) sp->obj = STV_NewObject(sp, TRANSIENT_STORAGE, - 1024, &w->exp, (uint16_t)params->http_max_hdr); + params->http_resp_size , &w->exp, + (uint16_t)params->http_max_hdr); if (sp->obj == NULL) { sp->doclose = "Out of objects"; sp->director = NULL; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index dd55990..aaa8212 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -979,6 +979,9 @@ http_PutProtocol(struct worker *w, unsigned vsl_id, const struct http *to, { http_PutField(w, vsl_id, to, HTTP_HDR_PROTO, protocol); + if (to->hd[HTTP_HDR_PROTO].b == NULL) + http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1"); + Tcheck(to->hd[HTTP_HDR_PROTO]); } void @@ -995,6 +998,10 @@ http_PutResponse(struct worker *w, unsigned vsl_id, const struct http *to, { http_PutField(w, vsl_id, to, HTTP_HDR_RESPONSE, response); + if (to->hd[HTTP_HDR_RESPONSE].b == NULL) + http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response"); + Tcheck(to->hd[HTTP_HDR_RESPONSE]); + } void diff --git a/bin/varnishtest/tests/r01031.vtc b/bin/varnishtest/tests/r01031.vtc new file mode 100644 index 0000000..435f973 --- /dev/null +++ b/bin/varnishtest/tests/r01031.vtc @@ -0,0 +1,30 @@ +varnishtest "Test overflowing the response through sp->err_reason" + +varnish v1 -vcl { + backend blatti { + .host = "127.0.0.1"; + } + + sub vcl_recv { + error 200 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + } + sub vcl_error { + return(deliver); + } +} -start + +client c1 { + txreq -req GET + rxresp + expect resp.status == 200 + expect resp.msg == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +} -run + +varnish v1 -cliok "param.set http_resp_size 256" + +client c2 { + txreq -req GET + rxresp + expect resp.status == 200 + expect resp.msg == "Lost Response" +} -run From kristian at varnish-cache.org Mon Oct 17 12:11:48 2011 From: kristian at varnish-cache.org (=?UTF-8?Q?Kristian_Lyngst=C3=B8l?=) Date: Mon, 17 Oct 2011 14:11:48 +0200 Subject: [master] fa3b136 Ensure ban lurker sleeps 1.0s on failure Message-ID: commit fa3b136f2169a71b63603835c69441ca37913507 Author: Kristian Lyngstol Date: Mon Oct 17 14:09:11 2011 +0200 Ensure ban lurker sleeps 1.0s on failure As per documentation, the ban lurker sleeps ban_lurker_sleep when it is successful, but on failure it should only sleep 1.0s. No point hammering the ban list every 0.01s if bans aren't even used. Fixes #1030 diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index 736cbf7..5b7d457 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -754,7 +754,7 @@ BAN_CheckObject(struct object *o, const struct sess *sp) * Ban tail lurker thread */ -static void +static int ban_lurker_work(const struct sess *sp) { struct ban *b, *bf; @@ -773,21 +773,21 @@ ban_lurker_work(const struct sess *sp) if (bf != NULL) { Lck_Unlock(&ban_mtx); BAN_Free(bf); - return; + return (0); } /* Find the last ban give up, if we have only one */ b = VTAILQ_LAST(&ban_head, banhead_s); if (b == ban_start) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* Find the first object on it, if any */ oc = VTAILQ_FIRST(&b->objcore); if (oc == NULL) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* Try to lock the objhead */ @@ -795,7 +795,7 @@ ban_lurker_work(const struct sess *sp) CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); if (Lck_Trylock(&oh->mtx)) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* @@ -808,7 +808,7 @@ ban_lurker_work(const struct sess *sp) if (oc2 == NULL) { Lck_Unlock(&oh->mtx); Lck_Unlock(&ban_mtx); - return; + return (0); } /* * Grab a reference to the OC and we can let go of the BAN mutex @@ -825,12 +825,13 @@ ban_lurker_work(const struct sess *sp) Lck_Unlock(&oh->mtx); WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->exp.ttl, i); (void)HSH_Deref(sp->wrk, NULL, &o); + return (i); } static void * __match_proto__(bgthread_t) ban_lurker(struct sess *sp, void *priv) { - + int i = 0; (void)priv; while (1) { if (params->ban_lurker_sleep == 0.0) { @@ -838,8 +839,11 @@ ban_lurker(struct sess *sp, void *priv) VTIM_sleep(1.0); continue; } - VTIM_sleep(params->ban_lurker_sleep); - ban_lurker_work(sp); + if (i != 0) + VTIM_sleep(params->ban_lurker_sleep); + else + VTIM_sleep(1.0); + i = ban_lurker_work(sp); WSL_Flush(sp->wrk, 0); WRK_SumStat(sp->wrk); } diff --git a/bin/varnishtest/tests/r01030.vtc b/bin/varnishtest/tests/r01030.vtc new file mode 100644 index 0000000..97ef3d7 --- /dev/null +++ b/bin/varnishtest/tests/r01030.vtc @@ -0,0 +1,64 @@ +varnishtest "Test ban_lurker_sleep vs failed ban lurker" + +# The idea here is that the ban lurker should always wait 1 second when it +# can't proceed, as per documentation and original intent. The +# ban_lurker_sleep should not affect sleep-times when the lurker fails. + +server s1 { + rxreq + txresp -status 200 + + rxreq + txresp -status 200 +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.request == "BAN") { + ban("obj.http.url ~ /"); + error 201 "banned"; + } + return (lookup); + } + sub vcl_fetch { + set beresp.http.url = req.url; + } +} -start + +varnish v1 -cliok "param.set ban_lurker_sleep 0.01" +varnish v1 -expect n_ban_obj_test == 0 + +delay 0.01 +client c1 { + txreq -req GET + rxresp + expect resp.status == 200 + + txreq -req BAN + rxresp + expect resp.status == 201 +} -run + +delay 0.1 +varnish v1 -expect n_ban_obj_test == 0 + +delay 1.0 +varnish v1 -expect n_ban_obj_test == 1 + +varnish v1 -cliok "param.set ban_lurker_sleep 5.01" + +client c2 { + txreq -req GET + rxresp + expect resp.status == 200 + + txreq -req BAN + rxresp + expect resp.status == 201 +} -run + +delay 0.1 +varnish v1 -expect n_ban_obj_test == 1 + +delay 1.1 +varnish v1 -expect n_ban_obj_test == 2 From kristian at varnish-cache.org Mon Oct 17 12:57:59 2011 From: kristian at varnish-cache.org (=?UTF-8?Q?Kristian_Lyngst=C3=B8l?=) Date: Mon, 17 Oct 2011 14:57:59 +0200 Subject: [master] e18a6ab Formally remove error from vcl_deliver VCC Message-ID: commit e18a6ab53fbae30b633fbe5f040b5686bec6ea4d Author: Kristian Lyngstol Date: Mon Oct 17 14:46:54 2011 +0200 Formally remove error from vcl_deliver VCC Note that error wasn't actually working in vcl_deliver, and this just puts VCC in line with the rest of Varnish. Syntax errors are better than assert errors. Re #1027 I'll leave it for later discussion to see if we close #1027, which is technically a feature request now, though a request for a feature we used to have (not sure how well it worked). diff --git a/bin/varnishtest/tests/r01027.vtc b/bin/varnishtest/tests/r01027.vtc new file mode 100644 index 0000000..6c20b00 --- /dev/null +++ b/bin/varnishtest/tests/r01027.vtc @@ -0,0 +1,8 @@ +varnishtest "Test if you can error in vcl_deliver" + +varnish v1 -badvcl { + sub vcl_deliver { + error 201 "ok"; + } +} + diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 9d72b51..044d12d 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -320,7 +320,7 @@ static struct action_table { } action_table[] = { { "error", parse_error, VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | - VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER + VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH }, #define VCL_RET_MAC(l, U, B) \ From apj at varnish-cache.org Wed Oct 19 20:44:17 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Wed, 19 Oct 2011 22:44:17 +0200 Subject: [master] da68c3a Attempt to document the different options for invalidating cached content Message-ID: commit da68c3aa1e84a923a1d95566aa21b86d9ef9cfe0 Author: Andreas Plesner Jacobsen Date: Wed Oct 19 22:43:25 2011 +0200 Attempt to document the different options for invalidating cached content diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst index 84449da..9e41430 100644 --- a/doc/sphinx/reference/index.rst +++ b/doc/sphinx/reference/index.rst @@ -21,6 +21,7 @@ The Varnish Reference Manual shmem.rst vmod.rst vmod_std.rst + purging_banning.rst vsl.rst .. todo:: diff --git a/doc/sphinx/reference/purging_banning.rst b/doc/sphinx/reference/purging_banning.rst new file mode 100644 index 0000000..4d63d8a --- /dev/null +++ b/doc/sphinx/reference/purging_banning.rst @@ -0,0 +1,140 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%% +Purging and banning content +%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Varnish has three ways to invalidate content in varnish. You can either purge an object and all the variants of it from the cache, or you can prevent past versions of an object from being served by banning it. Finally, you can force a cache miss to force a backend fetch and override an object in the cache. + +Purging +======= + +To purge an object, you need to access that object explicitly, which is why the purge method is only available in VCL in the methods `vcl_hit` and `vcl_miss`. Purging is available in `vcl_miss` to allow for purging of all other variants of this object, even when this is particular request didn't hit a variant. Purging explicitly evicts that object and all variants from the cache immediately. An example implementation of the HTTP PURGE method in VCL:: + + acl purgers { + "localhost"; + "192.0.2.1"/24; + } + + sub vcl_recv { + if (req.request == "PURGE") { + if (!client.ip ~ purgers) { + error 405 "Not allowed."; + } + return(lookup); + } + } + + sub vcl_hit { + if (req.request == "PURGE") { + purge; + error 200 "Purged."; + } + } + + sub vcl_miss { + if (req.request == "PURGE") { + purge; + error 200 "Purged."; + } + } + +Banning +======= + +Banning prevents varnish from serving all matching objects in the cache at the time of the ban. Banning is not a permanent operation, it is only used to invalidate and evict content already in the cache. It does not immediately evict objects from the cache, but will compare all future hits to this ban, and evict the objects if they match. When a ban has been matched against all objects in the cache, or when all objects in the cache is newer than the ban, it is deleted. + +Bans are added to the ban list using the `ban` CLI command or the `ban()` VCL method. They both take a ban expression that matches the objects that should be banned. + +Varnish also does duplicate ban detection if `ban_dups` is enabled. + +Ban Expressions +--------------- + +A ban expression is a list of conditions that needs to be fulfilled to invalidate content. You can match the content of the following variables using equality comparison or regular expressions: + + * req.url + * req.http.* + * obj.http.* + +Conditions are combined using logical and: && + +To ban any content served from an Apache backend, you could use this expression:: + + obj.http.Server ~ Apache + +To ban a particular URL and hostname:: + + req.url == /this/url && req.http.Host == example.com + +Banning From CLI +---------------- + +To ban from CLI, use the ban or the ban.url commands:: + + ban obj.http.Server ~ Apache + ban.url /images/.* + +ban.url is equivelant to "ban req.url ~" + +Banning From VCL +---------------- + +To ban from VCL, use the ban() or ban_url() functions. You can use the full arsenal of varnish string manipulation functions to build your ban expression. For example to let users execute requests that purge based on regular expressions:: + + sub vcl_recv { + if (req.url ~ "^/purgere/") { + if (!client.ip ~ purge) { + error 405 "Not allowed."; + } + set req.url = regsub(req.url, "^/purgere/", "/"); + ban("obj.http.x-url ~ " req.url); + error 200 "Banned."; + } + } + +The Ban List +------------ + +The ban list can be inspected via the CLI command ban.list. + +Example output:: + + 0xb75096d0 1318329475.377475 10 obj.http.x-url ~ test + 0xb7509610 1318329470.785875 20G obj.http.x-url ~ test + +The ban list contains the ID of the ban, the timestamp when the ban entered the ban list. A count of the objects that has reached this point in the ban list, optionally postfixed with a 'G' for "Gone", if the ban is no longer valid. Finally, the ban expression is listed. The ban can be marked as Gone if it is a duplicate ban, but is still kept in the list for optimization purposes. + +The Ban Lurker +-------------- + +Since a ban needs to be be matched against all objects in the cache, one way to speed up the eviction process is to enable the ban lurker. The ban lurker will walk the cache and match all objects to the bans in the ban list, and evict matching objects. The ban lurker is enabled by setting `ban_lurker_sleep` to a value above 0. + +Since Varnish 3.0, the ban lurker is enabled by default. + +Writing Ban Lurker Friendly Bans +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To fully utilize the ban lurker, bans need to be written without the use of any req.* parameters, since there is no request to match against when the ban lurker walks the cache. + +A simple mode to avoid req.* in bans is to add headers to the cached object containing the parts of the request on which you want to ban, e.g.:: + + sub vcl_fetch { + set obj.http.x-url = req.url; + } + + sub vcl_deliver { + unset resp.http.x-url; # Optional + } + + sub vcl_recv { + if (req.request == "PURGE") { + if (client.ip !~ purgers) { + error 401 "Not allowed"; + } + purge("obj.http.x-url ~ " req.url); # Assumes req.url is a regex. This might be a bit too simple + } + } + +req.hash_always_miss +==================== + +The final way to invalidate an object is a method that allows you to refresh an object by forcing a hash miss for a single request. If you set `req.hash_always_miss` to true, varnish will miss the current object in the cache, thus forcing a fetch from the backend. This can in turn add the freshly fetched object to the cache, thus overriding the current one. The old object will stay in the cache until ttl expires or it is evicted by some other means. From phk at varnish-cache.org Fri Oct 21 12:19:41 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Fri, 21 Oct 2011 14:19:41 +0200 Subject: [master] 30046dc Make EXP_NukeOne() make do with a struct worker arg instead of sess. Message-ID: commit 30046dce5fda7281b67169a1ad24484c0765c391 Author: Poul-Henning Kamp Date: Fri Oct 21 12:19:16 2011 +0000 Make EXP_NukeOne() make do with a struct worker arg instead of sess. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 22e61ae..e94180a 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -697,7 +697,7 @@ void EXP_Inject(struct objcore *oc, struct lru *lru, double when); void EXP_Init(void); void EXP_Rearm(const struct object *o); int EXP_Touch(struct objcore *oc); -int EXP_NukeOne(const struct sess *sp, struct lru *lru); +int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ struct storage *FetchStorage(const struct sess *sp, ssize_t sz); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 6bf0b0c..fd3238d 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -440,8 +440,8 @@ cnt_error(struct sess *sp) &w->exp, (uint16_t)params->http_max_hdr); if (sp->obj == NULL) sp->obj = STV_NewObject(sp, TRANSIENT_STORAGE, - params->http_resp_size , &w->exp, - (uint16_t)params->http_max_hdr); + params->http_resp_size, &w->exp, + (uint16_t)params->http_max_hdr); if (sp->obj == NULL) { sp->doclose = "Out of objects"; sp->director = NULL; diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c index 601025c..f7f779d 100644 --- a/bin/varnishd/cache_expire.c +++ b/bin/varnishd/cache_expire.c @@ -414,7 +414,7 @@ exp_timer(struct sess *sp, void *priv) */ int -EXP_NukeOne(const struct sess *sp, struct lru *lru) +EXP_NukeOne(struct worker *w, struct lru *lru) { struct objcore *oc; struct object *o; @@ -446,9 +446,9 @@ EXP_NukeOne(const struct sess *sp, struct lru *lru) return (-1); /* XXX: bad idea for -spersistent */ - o = oc_getobj(sp->wrk, oc); - WSL(sp->wrk, SLT_ExpKill, 0, "%u LRU", o->xid); - (void)HSH_Deref(sp->wrk, NULL, &o); + o = oc_getobj(w, oc); + WSL(w, SLT_ExpKill, 0, "%u LRU", o->xid); + (void)HSH_Deref(w, NULL, &o); return (1); } diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index aaa8212..784eb28 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -1001,7 +1001,6 @@ http_PutResponse(struct worker *w, unsigned vsl_id, const struct http *to, if (to->hd[HTTP_HDR_RESPONSE].b == NULL) http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response"); Tcheck(to->hd[HTTP_HDR_RESPONSE]); - } void diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 65f9f49..bd42e54 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -184,7 +184,7 @@ stv_alloc(const struct sess *sp, size_t size) } /* no luck; try to free some space and keep trying */ - if (EXP_NukeOne(sp, stv->lru) == -1) + if (EXP_NukeOne(sp->wrk, stv->lru) == -1) break; /* Enough is enough: try another if we have one */ @@ -336,7 +336,7 @@ STV_NewObject(struct sess *sp, const char *hint, unsigned wsl, struct exp *ep, if (o == NULL) { /* no luck; try to free some space and keep trying */ for (i = 0; o == NULL && i < params->nuke_limit; i++) { - if (EXP_NukeOne(sp, stv->lru) == -1) + if (EXP_NukeOne(sp->wrk, stv->lru) == -1) break; o = stv->allocobj(stv, sp, ltot, &soc); } From apj at varnish-cache.org Sat Oct 22 08:59:12 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Sat, 22 Oct 2011 10:59:12 +0200 Subject: [master] 5e4a502 Merge new material from reference/purging_banning, and do a little house keeping Message-ID: commit 5e4a502fcc72a0bfef4269d06e08fcd9d8625f0f Author: Andreas Plesner Jacobsen Date: Sat Oct 22 10:58:22 2011 +0200 Merge new material from reference/purging_banning, and do a little house keeping Remove reference/purging_banning, since all info is now in tutorial/purging diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst index 9e41430..84449da 100644 --- a/doc/sphinx/reference/index.rst +++ b/doc/sphinx/reference/index.rst @@ -21,7 +21,6 @@ The Varnish Reference Manual shmem.rst vmod.rst vmod_std.rst - purging_banning.rst vsl.rst .. todo:: diff --git a/doc/sphinx/reference/purging_banning.rst b/doc/sphinx/reference/purging_banning.rst deleted file mode 100644 index 4d63d8a..0000000 --- a/doc/sphinx/reference/purging_banning.rst +++ /dev/null @@ -1,140 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%% -Purging and banning content -%%%%%%%%%%%%%%%%%%%%%%%%%%% - -Varnish has three ways to invalidate content in varnish. You can either purge an object and all the variants of it from the cache, or you can prevent past versions of an object from being served by banning it. Finally, you can force a cache miss to force a backend fetch and override an object in the cache. - -Purging -======= - -To purge an object, you need to access that object explicitly, which is why the purge method is only available in VCL in the methods `vcl_hit` and `vcl_miss`. Purging is available in `vcl_miss` to allow for purging of all other variants of this object, even when this is particular request didn't hit a variant. Purging explicitly evicts that object and all variants from the cache immediately. An example implementation of the HTTP PURGE method in VCL:: - - acl purgers { - "localhost"; - "192.0.2.1"/24; - } - - sub vcl_recv { - if (req.request == "PURGE") { - if (!client.ip ~ purgers) { - error 405 "Not allowed."; - } - return(lookup); - } - } - - sub vcl_hit { - if (req.request == "PURGE") { - purge; - error 200 "Purged."; - } - } - - sub vcl_miss { - if (req.request == "PURGE") { - purge; - error 200 "Purged."; - } - } - -Banning -======= - -Banning prevents varnish from serving all matching objects in the cache at the time of the ban. Banning is not a permanent operation, it is only used to invalidate and evict content already in the cache. It does not immediately evict objects from the cache, but will compare all future hits to this ban, and evict the objects if they match. When a ban has been matched against all objects in the cache, or when all objects in the cache is newer than the ban, it is deleted. - -Bans are added to the ban list using the `ban` CLI command or the `ban()` VCL method. They both take a ban expression that matches the objects that should be banned. - -Varnish also does duplicate ban detection if `ban_dups` is enabled. - -Ban Expressions ---------------- - -A ban expression is a list of conditions that needs to be fulfilled to invalidate content. You can match the content of the following variables using equality comparison or regular expressions: - - * req.url - * req.http.* - * obj.http.* - -Conditions are combined using logical and: && - -To ban any content served from an Apache backend, you could use this expression:: - - obj.http.Server ~ Apache - -To ban a particular URL and hostname:: - - req.url == /this/url && req.http.Host == example.com - -Banning From CLI ----------------- - -To ban from CLI, use the ban or the ban.url commands:: - - ban obj.http.Server ~ Apache - ban.url /images/.* - -ban.url is equivelant to "ban req.url ~" - -Banning From VCL ----------------- - -To ban from VCL, use the ban() or ban_url() functions. You can use the full arsenal of varnish string manipulation functions to build your ban expression. For example to let users execute requests that purge based on regular expressions:: - - sub vcl_recv { - if (req.url ~ "^/purgere/") { - if (!client.ip ~ purge) { - error 405 "Not allowed."; - } - set req.url = regsub(req.url, "^/purgere/", "/"); - ban("obj.http.x-url ~ " req.url); - error 200 "Banned."; - } - } - -The Ban List ------------- - -The ban list can be inspected via the CLI command ban.list. - -Example output:: - - 0xb75096d0 1318329475.377475 10 obj.http.x-url ~ test - 0xb7509610 1318329470.785875 20G obj.http.x-url ~ test - -The ban list contains the ID of the ban, the timestamp when the ban entered the ban list. A count of the objects that has reached this point in the ban list, optionally postfixed with a 'G' for "Gone", if the ban is no longer valid. Finally, the ban expression is listed. The ban can be marked as Gone if it is a duplicate ban, but is still kept in the list for optimization purposes. - -The Ban Lurker --------------- - -Since a ban needs to be be matched against all objects in the cache, one way to speed up the eviction process is to enable the ban lurker. The ban lurker will walk the cache and match all objects to the bans in the ban list, and evict matching objects. The ban lurker is enabled by setting `ban_lurker_sleep` to a value above 0. - -Since Varnish 3.0, the ban lurker is enabled by default. - -Writing Ban Lurker Friendly Bans -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To fully utilize the ban lurker, bans need to be written without the use of any req.* parameters, since there is no request to match against when the ban lurker walks the cache. - -A simple mode to avoid req.* in bans is to add headers to the cached object containing the parts of the request on which you want to ban, e.g.:: - - sub vcl_fetch { - set obj.http.x-url = req.url; - } - - sub vcl_deliver { - unset resp.http.x-url; # Optional - } - - sub vcl_recv { - if (req.request == "PURGE") { - if (client.ip !~ purgers) { - error 401 "Not allowed"; - } - purge("obj.http.x-url ~ " req.url); # Assumes req.url is a regex. This might be a bit too simple - } - } - -req.hash_always_miss -==================== - -The final way to invalidate an object is a method that allows you to refresh an object by forcing a hash miss for a single request. If you set `req.hash_always_miss` to true, varnish will miss the current object in the cache, thus forcing a fetch from the backend. This can in turn add the freshly fetched object to the cache, thus overriding the current one. The old object will stay in the cache until ttl expires or it is evicted by some other means. diff --git a/doc/sphinx/tutorial/purging.rst b/doc/sphinx/tutorial/purging.rst index ce1d945..e5da595 100644 --- a/doc/sphinx/tutorial/purging.rst +++ b/doc/sphinx/tutorial/purging.rst @@ -10,8 +10,8 @@ of, in this twitterific day of age serving content that is outdated is bad for business. The solution is to notify Varnish when there is fresh content -available. This can be done through two mechanisms. HTTP purging and -bans. First, let me explain the HTTP purges. +available. This can be done through three mechanisms. HTTP purging, +banning and forced cache misses. First, let me explain the HTTP purges. HTTP Purges @@ -61,7 +61,9 @@ As you can see we have used to new VCL subroutines, vcl_hit and vcl_miss. When we call lookup Varnish will try to lookup the object in its cache. It will either hit an object or miss it and so the corresponding subroutine is called. In vcl_hit the object that is -stored in cache is available and we can set the TTL. +stored in cache is available and we can set the TTL. The purge in +vcl_miss is necessary to purge all variants in the cases where you hit an +object, but miss a particular variant. So for example.com to invalidate their front page they would call out to Varnish like this:: @@ -75,14 +77,16 @@ variants as defined by Vary. Bans ==== -There is another way to invalidate content. Bans. You can think of -bans as a sort of a filter. You *ban* certain content from being -served from your cache. You can ban content based on any metadata we -have. +There is another way to invalidate content: Bans. You can think of +bans as a sort of a filter on objects already in the cache. You *ban* +certain content from being served from your cache. You can ban +content based on any metadata we have. +A ban will only work on objects already in the cache, it does not +prevent new content from entering the cache or being served. Support for bans is built into Varnish and available in the CLI -interface. For VG to ban every png object belonging on example.com -they could issue:: +interface. To ban every png object belonging on example.com, issue +the following command:: ban req.http.host == "example.com" && req.http.url ~ "\.png$" @@ -91,13 +95,14 @@ Quite powerful, really. Bans are checked when we hit an object in the cache, but before we deliver it. *An object is only checked against newer bans*. -Bans that only match against beresp.* are also processed by a -background worker threads called the *ban lurker*. The ban lurker will -walk the heap and try to match objects and will evict the matching -objects. How aggressive the ban lurker is can be controlled by the -parameter ban_lurker_sleep. +Bans that only match against obj.* are also processed by a background +worker threads called the *ban lurker*. The ban lurker will walk the +heap and try to match objects and will evict the matching objects. How +aggressive the ban lurker is can be controlled by the parameter +ban_lurker_sleep. The ban lurker can be disabled by setting +ban_lurker_sleep to 0. -Bans that are older then the oldest objects in the cache are discarded +Bans that are older than the oldest objects in the cache are discarded without evaluation. If you have a lot of objects with long TTL, that are seldom accessed you might accumulate a lot of bans. This might impact CPU usage and thereby performance. @@ -122,3 +127,49 @@ You can also add bans to Varnish via HTTP. Doing so requires a bit of VCL:: This VCL sniplet enables Varnish to handle an HTTP BAN method, adding a ban on the URL, including the host part. +The ban lurker can help you keep the ban list at a manageable size, so +we recommend that you avoid using req.* in your bans, as the request +object is not available in the ban lurker thread. + +You can use the following template to write ban lurker friendly bans:: + + sub vcl_fetch { + set obj.http.x-url = req.url; + } + + sub vcl_deliver { + unset resp.http.x-url; # Optional + } + + sub vcl_recv { + if (req.request == "PURGE") { + if (client.ip !~ purge) { + error 401 "Not allowed"; + } + ban("obj.http.x-url ~ " req.url); # Assumes req.url is a regex. This might be a bit too simple + } + } + +To inspect the current ban list, issue the ban.list command in CLI. This +will produce a status of all current bans:: + + 0xb75096d0 1318329475.377475 10 obj.http.x-url ~ test + 0xb7509610 1318329470.785875 20G obj.http.x-url ~ test + +The ban list contains the ID of the ban, the timestamp when the ban +entered the ban list. A count of the objects that has reached this point +in the ban list, optionally postfixed with a 'G' for "Gone", if the ban +is no longer valid. Finally, the ban expression is listed. The ban can +be marked as Gone if it is a duplicate ban, but is still kept in the list +for optimization purposes. + +Forcing a cache miss +==================== + +The final way to invalidate an object is a method that allows you to +refresh an object by forcing a hash miss for a single request. If you set +req.hash_always_miss to true, varnish will miss the current object in the +cache, thus forcing a fetch from the backend. This can in turn add the +freshly fetched object to the cache, thus overriding the current one. The +old object will stay in the cache until ttl expires or it is evicted by +some other means. From phk at varnish-cache.org Mon Oct 24 09:51:07 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 11:51:07 +0200 Subject: [master] 5e673e1 Start to push struct sess out of the "fetch non-esi body from backend" code path, to pave the road for Martins streaming code. Message-ID: commit 5e673e14c020a4cf3ce2f246268a0fbfd0de7bfb Author: Poul-Henning Kamp Date: Mon Oct 24 09:50:18 2011 +0000 Start to push struct sess out of the "fetch non-esi body from backend" code path, to pave the road for Martins streaming code. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index e94180a..018355e 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -710,8 +710,8 @@ void Fetch_Init(void); struct vgz; enum vgz_flag { VGZ_NORMAL, VGZ_ALIGN, VGZ_RESET, VGZ_FINISH }; -struct vgz *VGZ_NewUngzip(struct sess *sp, const char *id); -struct vgz *VGZ_NewGzip(struct sess *sp, const char *id); +struct vgz *VGZ_NewUngzip(struct worker *wrk, int vsl_id, const char *id); +struct vgz *VGZ_NewGzip(struct worker *wrk, int vsl_id, const char *id); void VGZ_Ibuf(struct vgz *, const void *, ssize_t len); int VGZ_IbufEmpty(const struct vgz *vg); void VGZ_Obuf(struct vgz *, void *, ssize_t len); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index fd3238d..d60f17e 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -901,7 +901,7 @@ cnt_streambody(struct sess *sp) sp->wrk->sctx = &sctx; if (sp->wrk->res_mode & RES_GUNZIP) { - sctx.vgz = VGZ_NewUngzip(sp, "U S -"); + sctx.vgz = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U S -"); sctx.obuf = obuf; sctx.obuf_len = sizeof (obuf); } diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index f7daeeb..aaf5f7a 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -267,7 +267,7 @@ ESI_Deliver(struct sess *sp) } if (isgzip && !sp->wrk->gzip_resp) { - vgz = VGZ_NewUngzip(sp, "U D E"); + vgz = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U D E"); /* Feed a gzip header to gunzip to make it happy */ VGZ_Ibuf(vgz, gzip_hdr, sizeof gzip_hdr); diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 1db5259..f69e900 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -301,7 +301,7 @@ vfp_esi_begin(struct sess *sp, size_t estimate) AZ(sp->wrk->vgz_rx); if (sp->wrk->is_gzip && sp->wrk->do_gunzip) { - sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "U F E"); + sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); VEP_Init(sp, NULL); } else if (sp->wrk->is_gunzip && sp->wrk->do_gzip) { ALLOC_OBJ(vef, VEF_MAGIC); @@ -309,18 +309,18 @@ vfp_esi_begin(struct sess *sp, size_t estimate) //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(sp, "G F E"); + vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); AZ(sp->wrk->vef_priv); sp->wrk->vef_priv = vef; VEP_Init(sp, vfp_vep_callback); } else if (sp->wrk->is_gzip) { - sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "U F E"); + sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(sp, "G F E"); + vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); AZ(sp->wrk->vef_priv); sp->wrk->vef_priv = vef; VEP_Init(sp, vfp_vep_callback); diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 156ac52..787ff16 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -77,7 +77,8 @@ struct vgz { unsigned magic; #define VGZ_MAGIC 0x162df0cb enum {VGZ_GZ,VGZ_UN} dir; - struct sess *sess; + struct worker *wrk; + int vsl_id; const char *id; struct ws *tmp; char *tmp_snapshot; @@ -113,11 +114,13 @@ vgz_free(voidpf opaque, voidpf address) */ static struct vgz * -vgz_alloc_vgz(struct sess *sp, const char *id) +vgz_alloc_vgz(struct worker *wrk, int vsl_id, const char *id) { struct vgz *vg; - struct ws *ws = sp->wrk->ws; + struct ws *ws; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + ws = wrk->ws; WS_Assert(ws); // XXX: we restore workspace in esi:include // vg = (void*)WS_Alloc(ws, sizeof *vg); @@ -125,22 +128,17 @@ vgz_alloc_vgz(struct sess *sp, const char *id) AN(vg); memset(vg, 0, sizeof *vg); vg->magic = VGZ_MAGIC; - vg->sess = sp; + vg->wrk = wrk; + vg->vsl_id = vsl_id; vg->id = id; switch (params->gzip_tmp_space) { case 0: - /* malloc, the default */ - break; case 1: - vg->tmp = sp->ws; - vg->tmp_snapshot = WS_Snapshot(vg->tmp); - vg->vz.zalloc = vgz_alloc; - vg->vz.zfree = vgz_free; - vg->vz.opaque = vg; + /* malloc, the default */ break; case 2: - vg->tmp = sp->wrk->ws; + vg->tmp = wrk->ws; vg->tmp_snapshot = WS_Snapshot(vg->tmp); vg->vz.zalloc = vgz_alloc; vg->vz.zfree = vgz_free; @@ -153,12 +151,12 @@ vgz_alloc_vgz(struct sess *sp, const char *id) } struct vgz * -VGZ_NewUngzip(struct sess *sp, const char *id) +VGZ_NewUngzip(struct worker *wrk, int vsl_id, const char *id) { struct vgz *vg; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vg = vgz_alloc_vgz(sp, id); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + vg = vgz_alloc_vgz(wrk, vsl_id, id); vg->dir = VGZ_UN; VSC_C_main->n_gunzip++; @@ -173,13 +171,13 @@ VGZ_NewUngzip(struct sess *sp, const char *id) } struct vgz * -VGZ_NewGzip(struct sess *sp, const char *id) +VGZ_NewGzip(struct worker *wrk, int vsl_id, const char *id) { struct vgz *vg; int i; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vg = vgz_alloc_vgz(sp, id); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + vg = vgz_alloc_vgz(wrk, vsl_id, id); vg->dir = VGZ_GZ; VSC_C_main->n_gzip++; @@ -413,7 +411,7 @@ VGZ_Destroy(struct vgz **vgp) CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); *vgp = NULL; - WSP(vg->sess, SLT_Gzip, "%s %jd %jd %jd %jd %jd", + WSL(vg->wrk, SLT_Gzip, vg->vsl_id, "%s %jd %jd %jd %jd %jd", vg->id, (intmax_t)vg->vz.total_in, (intmax_t)vg->vz.total_out, @@ -440,7 +438,7 @@ vfp_gunzip_begin(struct sess *sp, size_t estimate) { (void)estimate; AZ(sp->wrk->vgz_rx); - sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "U F -"); + sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F -"); } static int __match_proto__() @@ -516,7 +514,7 @@ vfp_gzip_begin(struct sess *sp, size_t estimate) (void)estimate; AZ(sp->wrk->vgz_rx); - sp->wrk->vgz_rx = VGZ_NewGzip(sp, "G F -"); + sp->wrk->vgz_rx = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F -"); } static int __match_proto__() @@ -598,7 +596,7 @@ static void __match_proto__() vfp_testgzip_begin(struct sess *sp, size_t estimate) { (void)estimate; - sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "u F -"); + sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "u F -"); CHECK_OBJ_NOTNULL(sp->wrk->vgz_rx, VGZ_MAGIC); } diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 4f0334b..5521bc0 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -151,7 +151,7 @@ RES_BuildHttp(const struct sess *sp) */ static void -res_WriteGunzipObj(struct sess *sp) +res_WriteGunzipObj(const struct sess *sp) { struct storage *st; unsigned u = 0; @@ -162,7 +162,7 @@ res_WriteGunzipObj(struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vg = VGZ_NewUngzip(sp, "U D -"); + vg = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U D -"); VGZ_Obuf(vg, obuf, sizeof obuf); VTAILQ_FOREACH(st, &sp->obj->store, list) { diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 1ca6a74..8665ff5 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -882,7 +882,6 @@ static const struct parspec input_parspec[] = { { "gzip_tmp_space", tweak_uint, &master.gzip_tmp_space, 0, 2, "Where temporary space for gzip/gunzip is allocated:\n" " 0 - malloc\n" - " 1 - session workspace\n" " 2 - thread workspace\n" "If you have much gzip/gunzip activity, it may be an" " advantage to use workspace for these allocations to reduce" From phk at varnish-cache.org Mon Oct 24 12:08:56 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 14:08:56 +0200 Subject: [master] 8c80f86 Move the vbc structure from session to worker Message-ID: commit 8c80f8649476d9226e68a3b4ffa28310bc280c94 Author: Poul-Henning Kamp Date: Mon Oct 24 12:08:37 2011 +0000 Move the vbc structure from session to worker diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 018355e..59d5fa8 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -338,6 +338,7 @@ struct worker { const char *storage_hint; /* Fetch stuff */ + struct vbc *vbc; enum body_status body_status; struct vfp *vfp; struct vgz *vgz_rx; @@ -606,7 +607,6 @@ struct sess { VTAILQ_ENTRY(sess) list; struct director *director; - struct vbc *vbc; struct object *obj; struct objcore *objcore; struct VCL_conf *vcl; @@ -641,8 +641,8 @@ void VBE_UseHealth(const struct director *vdi); struct vbc *VDI_GetFd(const struct director *, struct sess *sp); int VDI_Healthy(const struct director *, const struct sess *sp); -void VDI_CloseFd(struct sess *sp); -void VDI_RecycleFd(struct sess *sp); +void VDI_CloseFd(struct worker *wrk); +void VDI_RecycleFd(struct worker *wrk); void VDI_AddHostHeader(const struct sess *sp); void VBE_Poll(void); diff --git a/bin/varnishd/cache_backend.c b/bin/varnishd/cache_backend.c index 0026259..7bacd26 100644 --- a/bin/varnishd/cache_backend.c +++ b/bin/varnishd/cache_backend.c @@ -64,10 +64,10 @@ VDI_AddHostHeader(const struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->vdis, VDI_SIMPLE_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(sp->wrk->vbc->vdis, VDI_SIMPLE_MAGIC); http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->bereq, - "Host: %s", sp->vbc->vdis->vrt->hosthdr); + "Host: %s", sp->wrk->vbc->vdis->vrt->hosthdr); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index d60f17e..243123d 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -227,7 +227,7 @@ cnt_prepresp(struct sess *sp) if (sp->restarts >= params->max_restarts) break; if (sp->wrk->do_stream) { - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); HSH_Drop(sp); } else { (void)HSH_Deref(sp->wrk, NULL, &sp->obj); @@ -305,7 +305,7 @@ cnt_done(struct sess *sp) CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC); AZ(sp->obj); - AZ(sp->vbc); + AZ(sp->wrk->vbc); sp->director = NULL; sp->restarts = 0; @@ -537,7 +537,7 @@ cnt_fetch(struct sess *sp) CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); AN(sp->director); - AZ(sp->vbc); + AZ(sp->wrk->vbc); AZ(sp->wrk->h_content_length); AZ(sp->wrk->do_close); AZ(sp->wrk->storage_hint); @@ -606,11 +606,11 @@ cnt_fetch(struct sess *sp) } /* We are not going to fetch the body, Close the connection */ - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); } /* Clean up partial fetch */ - AZ(sp->vbc); + AZ(sp->wrk->vbc); if (sp->objcore != NULL) { CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); @@ -788,7 +788,7 @@ cnt_fetchbody(struct sess *sp) if (sp->obj == NULL) { sp->err_code = 503; sp->step = STP_ERROR; - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); return (0); } CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); @@ -854,7 +854,7 @@ cnt_fetchbody(struct sess *sp) http_Setup(sp->wrk->beresp, NULL); sp->wrk->vfp = NULL; assert(WRW_IsReleased(sp->wrk)); - AZ(sp->vbc); + AZ(sp->wrk->vbc); AN(sp->director); if (i) { @@ -917,7 +917,7 @@ cnt_streambody(struct sess *sp) http_Setup(sp->wrk->bereq, NULL); http_Setup(sp->wrk->beresp, NULL); sp->wrk->vfp = NULL; - AZ(sp->vbc); + AZ(sp->wrk->vbc); AN(sp->director); if (!i && sp->obj->objcore != NULL) { diff --git a/bin/varnishd/cache_dir.c b/bin/varnishd/cache_dir.c index 3fd0475..e95b015 100644 --- a/bin/varnishd/cache_dir.c +++ b/bin/varnishd/cache_dir.c @@ -40,54 +40,54 @@ /* Close a connection ------------------------------------------------*/ void -VDI_CloseFd(struct sess *sp) +VDI_CloseFd(struct worker *wrk) { struct backend *bp; - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - assert(sp->vbc->fd >= 0); + CHECK_OBJ_NOTNULL(wrk->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(wrk->vbc->backend, BACKEND_MAGIC); + assert(wrk->vbc->fd >= 0); - bp = sp->vbc->backend; + bp = wrk->vbc->backend; - WSL(sp->wrk, SLT_BackendClose, sp->vbc->vsl_id, "%s", bp->vcl_name); + WSL(wrk, SLT_BackendClose, wrk->vbc->vsl_id, "%s", bp->vcl_name); /* Checkpoint log to flush all info related to this connection before the OS reuses the FD */ - WSL_Flush(sp->wrk, 0); + WSL_Flush(wrk, 0); - VTCP_close(&sp->vbc->fd); + VTCP_close(&wrk->vbc->fd); VBE_DropRefConn(bp); - sp->vbc->backend = NULL; - VBE_ReleaseConn(sp->vbc); - sp->vbc = NULL; - sp->wrk->do_close = 0; + wrk->vbc->backend = NULL; + VBE_ReleaseConn(wrk->vbc); + wrk->vbc = NULL; + wrk->do_close = 0; } /* Recycle a connection ----------------------------------------------*/ void -VDI_RecycleFd(struct sess *sp) +VDI_RecycleFd(struct worker *wrk) { struct backend *bp; - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); - assert(sp->vbc->fd >= 0); - AZ(sp->wrk->do_close); + CHECK_OBJ_NOTNULL(wrk->vbc, VBC_MAGIC); + CHECK_OBJ_NOTNULL(wrk->vbc->backend, BACKEND_MAGIC); + assert(wrk->vbc->fd >= 0); + AZ(wrk->do_close); - bp = sp->vbc->backend; + bp = wrk->vbc->backend; - WSL(sp->wrk, SLT_BackendReuse, sp->vbc->vsl_id, "%s", bp->vcl_name); + WSL(wrk, SLT_BackendReuse, wrk->vbc->vsl_id, "%s", bp->vcl_name); /* * Flush the shmlog, so that another session reusing this backend * will log chronologically later than our use of it. */ - WSL_Flush(sp->wrk, 0); + WSL_Flush(wrk, 0); Lck_Lock(&bp->mtx); VSC_C_main->backend_recycle++; - VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbc, list); - sp->vbc = NULL; + VTAILQ_INSERT_HEAD(&bp->connlist, wrk->vbc, list); + wrk->vbc = NULL; VBE_DropRefLocked(bp); } diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 71fc8e2..ba91720 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -394,12 +394,12 @@ FetchHdr(struct sess *sp) hp = w->bereq; - sp->vbc = VDI_GetFd(NULL, sp); - if (sp->vbc == NULL) { + sp->wrk->vbc = VDI_GetFd(NULL, sp); + if (sp->wrk->vbc == NULL) { WSP(sp, SLT_FetchError, "no backend connection"); return (-1); } - vc = sp->vbc; + vc = sp->wrk->vbc; if (vc->recycled) retry = 1; @@ -420,7 +420,7 @@ FetchHdr(struct sess *sp) if (WRW_FlushRelease(w) || i > 0) { WSP(sp, SLT_FetchError, "backend write error: %d (%s)", errno, strerror(errno)); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ return (retry); } @@ -443,7 +443,7 @@ FetchHdr(struct sess *sp) if (i < 0) { WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)", i, errno, w->htc->error); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ /* Retryable if we never received anything */ return (i == -1 ? retry : -1); @@ -457,7 +457,7 @@ FetchHdr(struct sess *sp) WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)", i, errno, w->htc->error); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ return (-1); } @@ -467,7 +467,7 @@ FetchHdr(struct sess *sp) if (http_DissectResponse(w, w->htc, hp)) { WSP(sp, SLT_FetchError, "http format error"); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ return (-1); } @@ -541,12 +541,12 @@ FetchBody(struct sess *sp) */ AZ(vfp_nop_end(sp)); - WSL(w, SLT_Fetch_Body, sp->vbc->vsl_id, "%u(%s) cls %d mklen %u", + WSL(w, SLT_Fetch_Body, sp->wrk->vbc->vsl_id, "%u(%s) cls %d mklen %u", w->body_status, body_status(w->body_status), cls, mklen); if (w->body_status == BS_ERROR) { - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); return (__LINE__); } @@ -558,7 +558,7 @@ FetchBody(struct sess *sp) VTAILQ_REMOVE(&sp->obj->store, st, list); STV_free(st); } - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); sp->obj->len = 0; return (__LINE__); } @@ -566,7 +566,7 @@ FetchBody(struct sess *sp) if (cls == 0 && w->do_close) cls = 1; - WSL(w, SLT_Length, sp->vbc->vsl_id, "%u", sp->obj->len); + WSL(w, SLT_Length, sp->wrk->vbc->vsl_id, "%u", sp->obj->len); { /* Sanity check fetch methods accounting */ @@ -589,9 +589,9 @@ FetchBody(struct sess *sp) } if (cls) - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); else - VDI_RecycleFd(sp); + VDI_RecycleFd(sp->wrk); return (0); } diff --git a/bin/varnishd/cache_panic.c b/bin/varnishd/cache_panic.c index 76ea866..231adf1 100644 --- a/bin/varnishd/cache_panic.c +++ b/bin/varnishd/cache_panic.c @@ -263,8 +263,8 @@ pan_sess(const struct sess *sp) if (VALID_OBJ(sp->vcl, VCL_CONF_MAGIC)) pan_vcl(sp->vcl); - if (VALID_OBJ(sp->vbc, BACKEND_MAGIC)) - pan_vbc(sp->vbc); + if (VALID_OBJ(sp->wrk->vbc, BACKEND_MAGIC)) + pan_vbc(sp->wrk->vbc); if (VALID_OBJ(sp->obj, OBJECT_MAGIC)) pan_object(sp->obj); diff --git a/bin/varnishd/cache_pipe.c b/bin/varnishd/cache_pipe.c index 8f109a5..31dcf1a 100644 --- a/bin/varnishd/cache_pipe.c +++ b/bin/varnishd/cache_pipe.c @@ -71,10 +71,10 @@ PipeSession(struct sess *sp) CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; - sp->vbc = VDI_GetFd(NULL, sp); - if (sp->vbc == NULL) + sp->wrk->vbc = VDI_GetFd(NULL, sp); + if (sp->wrk->vbc == NULL) return; - vc = sp->vbc; + vc = sp->wrk->vbc; (void)VTCP_blocking(vc->fd); WRW_Reserve(w, &vc->fd); @@ -89,7 +89,7 @@ PipeSession(struct sess *sp) if (i) { SES_Close(sp, "pipe"); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); return; } @@ -129,5 +129,5 @@ PipeSession(struct sess *sp) } } SES_Close(sp, "pipe"); - VDI_CloseFd(sp); + VDI_CloseFd(sp->wrk); } diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c index 1a16e16..92d8451 100644 --- a/bin/varnishd/cache_vrt_var.c +++ b/bin/varnishd/cache_vrt_var.c @@ -130,14 +130,16 @@ VRT_l_beresp_saintmode(const struct sess *sp, double a) struct trouble *new; struct trouble *tr; struct trouble *tr2; + struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - if (!sp->vbc) + wrk = sp->wrk; + if (!wrk->vbc) return; - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - if (!sp->vbc->backend) + CHECK_OBJ_NOTNULL(wrk->vbc, VBC_MAGIC); + if (!wrk->vbc->backend) return; - CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC); + CHECK_OBJ_NOTNULL(wrk->vbc->backend, BACKEND_MAGIC); if (!sp->objcore) return; CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC); @@ -156,8 +158,8 @@ VRT_l_beresp_saintmode(const struct sess *sp, double a) * timeout at a later date (ie: sort by which entry will time out * from the list */ - Lck_Lock(&sp->vbc->backend->mtx); - VTAILQ_FOREACH_SAFE(tr, &sp->vbc->backend->troublelist, list, tr2) { + Lck_Lock(&wrk->vbc->backend->mtx); + VTAILQ_FOREACH_SAFE(tr, &wrk->vbc->backend->troublelist, list, tr2) { if (tr->timeout < new->timeout) { VTAILQ_INSERT_BEFORE(tr, new, list); new = NULL; @@ -169,9 +171,9 @@ VRT_l_beresp_saintmode(const struct sess *sp, double a) * items have a longer timeout. */ if (new) - VTAILQ_INSERT_TAIL(&sp->vbc->backend->troublelist, new, list); + VTAILQ_INSERT_TAIL(&wrk->vbc->backend->troublelist, new, list); - Lck_Unlock(&sp->vbc->backend->mtx); + Lck_Unlock(&wrk->vbc->backend->mtx); } /*--------------------------------------------------------------------*/ @@ -250,8 +252,8 @@ VRT_r_beresp_backend_name(const struct sess *sp) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - return(sp->vbc->backend->vcl_name); + CHECK_OBJ_NOTNULL(sp->wrk->vbc, VBC_MAGIC); + return(sp->wrk->vbc->backend->vcl_name); } struct sockaddr_storage * @@ -259,8 +261,8 @@ VRT_r_beresp_backend_ip(const struct sess *sp) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - return(sp->vbc->addr); + CHECK_OBJ_NOTNULL(sp->wrk->vbc, VBC_MAGIC); + return(sp->wrk->vbc->addr); } int @@ -268,8 +270,8 @@ VRT_r_beresp_backend_port(const struct sess *sp) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC); - return (VTCP_port(sp->vbc->addr)); + CHECK_OBJ_NOTNULL(sp->wrk->vbc, VBC_MAGIC); + return (VTCP_port(sp->wrk->vbc->addr)); } const char * __match_proto__() From phk at varnish-cache.org Mon Oct 24 12:19:44 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 14:19:44 +0200 Subject: [master] 3999568 Shave some session from FetchBody Message-ID: commit 3999568c2dc6be3f801484cea7cfa614535a9508 Author: Poul-Henning Kamp Date: Mon Oct 24 12:19:26 2011 +0000 Shave some session from FetchBody diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 59d5fa8..71cc776 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -702,7 +702,7 @@ int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ struct storage *FetchStorage(const struct sess *sp, ssize_t sz); int FetchHdr(struct sess *sp); -int FetchBody(struct sess *sp); +int FetchBody(struct sess *sp, struct object *obj); int FetchReqBody(struct sess *sp); void Fetch_Init(void); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 243123d..13d8083 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -846,7 +846,7 @@ cnt_fetchbody(struct sess *sp) } /* Use unmodified headers*/ - i = FetchBody(sp); + i = FetchBody(sp, sp->obj); sp->wrk->h_content_length = NULL; @@ -910,7 +910,7 @@ cnt_streambody(struct sess *sp) AssertObjCorePassOrBusy(sp->obj->objcore); - i = FetchBody(sp); + i = FetchBody(sp, sp->obj); sp->wrk->h_content_length = NULL; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index ba91720..eae583d 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -477,7 +477,7 @@ FetchHdr(struct sess *sp) /*--------------------------------------------------------------------*/ int -FetchBody(struct sess *sp) +FetchBody(struct sess *sp, struct object *obj) { int cls; struct storage *st; @@ -487,17 +487,17 @@ FetchBody(struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - CHECK_OBJ_NOTNULL(sp->obj->http, HTTP_MAGIC); + CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(obj->http, HTTP_MAGIC); if (w->vfp == NULL) w->vfp = &vfp_nop; AN(sp->director); - AssertObjCorePassOrBusy(sp->obj->objcore); + AssertObjCorePassOrBusy(obj->objcore); AZ(w->vgz_rx); - AZ(VTAILQ_FIRST(&sp->obj->store)); + AZ(VTAILQ_FIRST(&obj->store)); switch (w->body_status) { case BS_NONE: cls = 0; @@ -541,57 +541,57 @@ FetchBody(struct sess *sp) */ AZ(vfp_nop_end(sp)); - WSL(w, SLT_Fetch_Body, sp->wrk->vbc->vsl_id, "%u(%s) cls %d mklen %u", + WSL(w, SLT_Fetch_Body, w->vbc->vsl_id, "%u(%s) cls %d mklen %u", w->body_status, body_status(w->body_status), cls, mklen); if (w->body_status == BS_ERROR) { - VDI_CloseFd(sp->wrk); + VDI_CloseFd(w); return (__LINE__); } if (cls < 0) { w->stats.fetch_failed++; /* XXX: Wouldn't this store automatically be released ? */ - while (!VTAILQ_EMPTY(&sp->obj->store)) { - st = VTAILQ_FIRST(&sp->obj->store); - VTAILQ_REMOVE(&sp->obj->store, st, list); + while (!VTAILQ_EMPTY(&obj->store)) { + st = VTAILQ_FIRST(&obj->store); + VTAILQ_REMOVE(&obj->store, st, list); STV_free(st); } - VDI_CloseFd(sp->wrk); - sp->obj->len = 0; + VDI_CloseFd(w); + obj->len = 0; return (__LINE__); } if (cls == 0 && w->do_close) cls = 1; - WSL(w, SLT_Length, sp->wrk->vbc->vsl_id, "%u", sp->obj->len); + WSL(w, SLT_Length, w->vbc->vsl_id, "%u", obj->len); { /* Sanity check fetch methods accounting */ ssize_t uu; uu = 0; - VTAILQ_FOREACH(st, &sp->obj->store, list) + VTAILQ_FOREACH(st, &obj->store, list) uu += st->len; if (sp->objcore == NULL || (sp->objcore->flags & OC_F_PASS)) /* Streaming might have started freeing stuff */ - assert (uu <= sp->obj->len); + assert (uu <= obj->len); else - assert(uu == sp->obj->len); + assert(uu == obj->len); } if (mklen > 0) { - http_Unset(sp->obj->http, H_Content_Length); - http_PrintfHeader(w, sp->vsl_id, sp->obj->http, - "Content-Length: %jd", (intmax_t)sp->obj->len); + http_Unset(obj->http, H_Content_Length); + http_PrintfHeader(w, sp->vsl_id, obj->http, + "Content-Length: %jd", (intmax_t)obj->len); } if (cls) - VDI_CloseFd(sp->wrk); + VDI_CloseFd(w); else - VDI_RecycleFd(sp->wrk); + VDI_RecycleFd(w); return (0); } From phk at varnish-cache.org Mon Oct 24 12:36:57 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 14:36:57 +0200 Subject: [master] 57240f5 Decontaminate STV_alloc() to not need session Message-ID: commit 57240f5a3e76cbd968518e0325de97bf09d293ea Author: Poul-Henning Kamp Date: Mon Oct 24 12:36:22 2011 +0000 Decontaminate STV_alloc() to not need session diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 71cc776..a8dff7b 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -950,7 +950,8 @@ int RFC2616_Do_Cond(const struct sess *sp); /* stevedore.c */ struct object *STV_NewObject(struct sess *sp, const char *hint, unsigned len, struct exp *, uint16_t nhttp); -struct storage *STV_alloc(const struct sess *sp, size_t size); +struct storage *STV_alloc(struct worker *w, const struct object *obj, + size_t size); void STV_trim(struct storage *st, size_t size); void STV_free(struct storage *st); void STV_open(void); diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index f69e900..5d8f8dc 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -368,7 +368,7 @@ vfp_esi_end(struct sess *sp) l = VSB_len(vsb); assert(l > 0); /* XXX: This is a huge waste of storage... */ - sp->obj->esidata = STV_alloc(sp, l); + sp->obj->esidata = STV_alloc(sp->wrk, sp->obj, l); XXXAN(sp->obj->esidata); memcpy(sp->obj->esidata->ptr, VSB_data(vsb), l); sp->obj->esidata->len = l; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index eae583d..ccc2ec3 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -159,7 +159,7 @@ FetchStorage(const struct sess *sp, ssize_t sz) l = sz; if (l == 0) l = params->fetch_chunksize * 1024LL; - st = STV_alloc(sp, l); + st = STV_alloc(sp->wrk, sp->obj, l); if (st == NULL) { errno = ENOMEM; return (NULL); diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index bd42e54..93e2bf8 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -154,7 +154,7 @@ stv_pick_stevedore(const struct sess *sp, const char **hint) /*-------------------------------------------------------------------*/ static struct storage * -stv_alloc(const struct sess *sp, size_t size) +stv_alloc(struct worker *w, const struct object *obj, size_t size) { struct storage *st; struct stevedore *stv; @@ -164,8 +164,9 @@ stv_alloc(const struct sess *sp, size_t size) * Always use the stevedore which allocated the object in order to * keep an object inside the same stevedore. */ - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - stv = sp->obj->objstore->stevedore; + CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + stv = obj->objstore->stevedore; CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC); if (size > (size_t)(params->fetch_maxchunksize) << 10) @@ -184,7 +185,7 @@ stv_alloc(const struct sess *sp, size_t size) } /* no luck; try to free some space and keep trying */ - if (EXP_NukeOne(sp->wrk, stv->lru) == -1) + if (EXP_NukeOne(w, stv->lru) == -1) break; /* Enough is enough: try another if we have one */ @@ -370,10 +371,10 @@ STV_Freestore(struct object *o) /*-------------------------------------------------------------------*/ struct storage * -STV_alloc(const struct sess *sp, size_t size) +STV_alloc(struct worker *w, const struct object *obj, size_t size) { - return (stv_alloc(sp, size)); + return (stv_alloc(w, obj, size)); } void From phk at varnish-cache.org Mon Oct 24 12:55:56 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 14:55:56 +0200 Subject: [master] 78f18e8 Give the worker a "fetch_obj" to avoid passing it around as a separate parameter all the time. Message-ID: commit 78f18e855bf04ddc1cef31405bdc6f8e3e58b6cc Author: Poul-Henning Kamp Date: Mon Oct 24 12:54:55 2011 +0000 Give the worker a "fetch_obj" to avoid passing it around as a separate parameter all the time. Also decontaminate FetchStorage to not need session diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index a8dff7b..46d4067 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -339,6 +339,7 @@ struct worker { /* Fetch stuff */ struct vbc *vbc; + struct object *fetch_obj; enum body_status body_status; struct vfp *vfp; struct vgz *vgz_rx; @@ -700,7 +701,7 @@ int EXP_Touch(struct objcore *oc); int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ -struct storage *FetchStorage(const struct sess *sp, ssize_t sz); +struct storage *FetchStorage(struct worker *w, ssize_t sz); int FetchHdr(struct sess *sp); int FetchBody(struct sess *sp, struct object *obj); int FetchReqBody(struct sess *sp); @@ -950,8 +951,7 @@ int RFC2616_Do_Cond(const struct sess *sp); /* stevedore.c */ struct object *STV_NewObject(struct sess *sp, const char *hint, unsigned len, struct exp *, uint16_t nhttp); -struct storage *STV_alloc(struct worker *w, const struct object *obj, - size_t size); +struct storage *STV_alloc(struct worker *w, size_t size); void STV_trim(struct storage *st, size_t size); void STV_free(struct storage *st); void STV_open(void); diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 5d8f8dc..00c7432 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -71,7 +71,7 @@ vfp_esi_bytes_uu(struct sess *sp, struct http_conn *htc, ssize_t bytes) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); while (bytes > 0) { - st = FetchStorage(sp, 0); + st = FetchStorage(sp->wrk, 0); if (st == NULL) return (-1); w = vef_read(htc, @@ -368,7 +368,7 @@ vfp_esi_end(struct sess *sp) l = VSB_len(vsb); assert(l > 0); /* XXX: This is a huge waste of storage... */ - sp->obj->esidata = STV_alloc(sp->wrk, sp->obj, l); + sp->obj->esidata = STV_alloc(sp->wrk, l); XXXAN(sp->obj->esidata); memcpy(sp->obj->esidata->ptr, VSB_data(vsb), l); sp->obj->esidata->len = l; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index ccc2ec3..d71b2ec 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -66,7 +66,7 @@ vfp_nop_begin(struct sess *sp, size_t estimate) WSP(sp, SLT_Debug, "Fetch %d byte segments:", fetchfrag); } if (estimate > 0) - (void)FetchStorage(sp, estimate); + (void)FetchStorage(sp->wrk, estimate); } /*-------------------------------------------------------------------- @@ -86,7 +86,7 @@ vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) struct storage *st; while (bytes > 0) { - st = FetchStorage(sp, 0); + st = FetchStorage(sp->wrk, 0); if (st == NULL) { htc->error = "Could not get storage"; return (-1); @@ -145,12 +145,15 @@ static struct vfp vfp_nop = { */ struct storage * -FetchStorage(const struct sess *sp, ssize_t sz) +FetchStorage(struct worker *w, ssize_t sz) { ssize_t l; struct storage *st; + struct object *obj; - st = VTAILQ_LAST(&sp->obj->store, storagehead); + obj = w->fetch_obj; + CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); + st = VTAILQ_LAST(&obj->store, storagehead); if (st != NULL && st->len < st->space) return (st); @@ -159,13 +162,13 @@ FetchStorage(const struct sess *sp, ssize_t sz) l = sz; if (l == 0) l = params->fetch_chunksize * 1024LL; - st = STV_alloc(sp->wrk, sp->obj, l); + st = STV_alloc(w, l); if (st == NULL) { errno = ENOMEM; return (NULL); } AZ(st->len); - VTAILQ_INSERT_TAIL(&sp->obj->store, st, list); + VTAILQ_INSERT_TAIL(&obj->store, st, list); return (st); } @@ -487,6 +490,7 @@ FetchBody(struct sess *sp, struct object *obj) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); w = sp->wrk; + AZ(w->fetch_obj); CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(obj->http, HTTP_MAGIC); @@ -498,6 +502,9 @@ FetchBody(struct sess *sp, struct object *obj) AZ(w->vgz_rx); AZ(VTAILQ_FIRST(&obj->store)); + + w->fetch_obj = obj; + switch (w->body_status) { case BS_NONE: cls = 0; @@ -541,6 +548,8 @@ FetchBody(struct sess *sp, struct object *obj) */ AZ(vfp_nop_end(sp)); + w->fetch_obj = NULL; + WSL(w, SLT_Fetch_Body, w->vbc->vsl_id, "%u(%s) cls %d mklen %u", w->body_status, body_status(w->body_status), cls, mklen); diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 787ff16..e40676c 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -259,7 +259,7 @@ VGZ_ObufStorage(const struct sess *sp, struct vgz *vg) { struct storage *st; - st = FetchStorage(sp, 0); + st = FetchStorage(sp->wrk, 0); if (st == NULL) return (-1); @@ -615,7 +615,7 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0) { - st = FetchStorage(sp, 0); + st = FetchStorage(sp->wrk, 0); if (st == NULL) { htc->error = "Could not get storage"; return (-1); diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 93e2bf8..4048836 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -371,10 +371,10 @@ STV_Freestore(struct object *o) /*-------------------------------------------------------------------*/ struct storage * -STV_alloc(struct worker *w, const struct object *obj, size_t size) +STV_alloc(struct worker *w, size_t size) { - return (stv_alloc(w, obj, size)); + return (stv_alloc(w, w->fetch_obj, size)); } void From phk at varnish-cache.org Mon Oct 24 13:41:32 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 15:41:32 +0200 Subject: [master] 9765f1a Downgrade ESI parse from using struct sess to struct worker. Message-ID: commit 9765f1a846461820e8bcc628c1d1a1f843f4cf39 Author: Poul-Henning Kamp Date: Mon Oct 24 13:41:06 2011 +0000 Downgrade ESI parse from using struct sess to struct worker. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 46d4067..298f820 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -717,7 +717,7 @@ void VGZ_Ibuf(struct vgz *, const void *, ssize_t len); int VGZ_IbufEmpty(const struct vgz *vg); void VGZ_Obuf(struct vgz *, void *, ssize_t len); int VGZ_ObufFull(const struct vgz *vg); -int VGZ_ObufStorage(const struct sess *sp, struct vgz *vg); +int VGZ_ObufStorage(struct worker *w, struct vgz *vg); int VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag); int VGZ_Gunzip(struct vgz *, const void **, size_t *len); void VGZ_Destroy(struct vgz **); @@ -863,6 +863,13 @@ void VSM_Free(const void *ptr); void VSL(enum VSL_tag_e tag, int id, const char *fmt, ...); void WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t); void WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...); +#define WSLB(w, tag, ...) \ + do { \ + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); \ + CHECK_OBJ_NOTNULL(w->vbc, VBC_MAGIC); \ + WSL(w, tag, (w)->vbc->vsl_id, __VA_ARGS__); \ + } while (0) + void WSL_Flush(struct worker *w, int overflow); #define DSL(flag, tag, id, ...) \ diff --git a/bin/varnishd/cache_esi.h b/bin/varnishd/cache_esi.h index 4110687..ff84d41 100644 --- a/bin/varnishd/cache_esi.h +++ b/bin/varnishd/cache_esi.h @@ -39,11 +39,10 @@ #define VEC_S8 (0x60 + 8) #define VEC_INCL 'I' -typedef ssize_t vep_callback_t(const struct sess *sp, - ssize_t l, enum vgz_flag flg); +typedef ssize_t vep_callback_t(struct worker *w, ssize_t l, enum vgz_flag flg); -void VEP_Init(const struct sess *sp, vep_callback_t *cb); -void VEP_parse(const struct sess *sp, const char *p, size_t l); -struct vsb *VEP_Finish(const struct sess *sp); +void VEP_Init(struct worker *w, vep_callback_t *cb); +void VEP_Parse(const struct worker *w, const char *p, size_t l); +struct vsb *VEP_Finish(struct worker *w); diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 00c7432..fab6513 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -78,7 +78,7 @@ vfp_esi_bytes_uu(struct sess *sp, struct http_conn *htc, ssize_t bytes) st->ptr + st->len, st->space - st->len, bytes); if (w <= 0) return (w); - VEP_parse(sp, (const char *)st->ptr + st->len, w); + VEP_Parse(sp->wrk, (const char *)st->ptr + st->len, w); st->len += w; sp->obj->len += w; bytes -= w; @@ -111,11 +111,11 @@ vfp_esi_bytes_gu(struct sess *sp, struct http_conn *htc, ssize_t bytes) VGZ_Ibuf(vg, ibuf, w); bytes -= w; } - if (VGZ_ObufStorage(sp, vg)) + if (VGZ_ObufStorage(sp->wrk, vg)) return (-1); i = VGZ_Gunzip(vg, &dp, &dl); xxxassert(i == VGZ_OK || i == VGZ_END); - VEP_parse(sp, dp, dl); + VEP_Parse(sp->wrk, dp, dl); sp->obj->len += dl; } return (1); @@ -141,15 +141,15 @@ struct vef_priv { */ static ssize_t -vfp_vep_callback(const struct sess *sp, ssize_t l, enum vgz_flag flg) +vfp_vep_callback(struct worker *w, ssize_t l, enum vgz_flag flg) { struct vef_priv *vef; size_t dl, px; const void *dp; int i; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vef = sp->wrk->vef_priv; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); assert(l >= 0); @@ -179,14 +179,14 @@ vfp_vep_callback(const struct sess *sp, ssize_t l, enum vgz_flag flg) l = 0; } do { - if (VGZ_ObufStorage(sp, vef->vgz)) { + if (VGZ_ObufStorage(w, vef->vgz)) { vef->error = errno; vef->tot += l; return (vef->tot); } i = VGZ_Gzip(vef->vgz, &dp, &dl, flg); vef->tot += dl; - sp->obj->len += dl; + w->fetch_obj->len += dl; } while (!VGZ_IbufEmpty(vef->vgz) || (flg != VGZ_NORMAL && VGZ_ObufFull(vef->vgz))); if (px != 0) { @@ -219,7 +219,7 @@ vfp_esi_bytes_ug(struct sess *sp, struct http_conn *htc, ssize_t bytes) return (w); bytes -= w; vef->bufp = ibuf; - VEP_parse(sp, ibuf, w); + VEP_Parse(sp->wrk, ibuf, w); assert(vef->bufp >= ibuf && vef->bufp <= ibuf + w); if (vef->error) { errno = vef->error; @@ -271,7 +271,7 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) assert(i >= VGZ_OK); vef->bufp = ibuf2; if (dl > 0) - VEP_parse(sp, ibuf2, dl); + VEP_Parse(sp->wrk, ibuf2, dl); if (vef->error) { errno = vef->error; return (-1); @@ -302,7 +302,7 @@ vfp_esi_begin(struct sess *sp, size_t estimate) AZ(sp->wrk->vgz_rx); if (sp->wrk->is_gzip && sp->wrk->do_gunzip) { sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); - VEP_Init(sp, NULL); + VEP_Init(sp->wrk, NULL); } else if (sp->wrk->is_gunzip && sp->wrk->do_gzip) { ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); @@ -312,7 +312,7 @@ vfp_esi_begin(struct sess *sp, size_t estimate) vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); AZ(sp->wrk->vef_priv); sp->wrk->vef_priv = vef; - VEP_Init(sp, vfp_vep_callback); + VEP_Init(sp->wrk, vfp_vep_callback); } else if (sp->wrk->is_gzip) { sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); ALLOC_OBJ(vef, VEF_MAGIC); @@ -323,10 +323,10 @@ vfp_esi_begin(struct sess *sp, size_t estimate) vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); AZ(sp->wrk->vef_priv); sp->wrk->vef_priv = vef; - VEP_Init(sp, vfp_vep_callback); + VEP_Init(sp->wrk, vfp_vep_callback); } else { AZ(sp->wrk->vef_priv); - VEP_Init(sp, NULL); + VEP_Init(sp->wrk, NULL); } (void)estimate; @@ -362,7 +362,7 @@ vfp_esi_end(struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); AN(sp->wrk->vep); - vsb = VEP_Finish(sp); + vsb = VEP_Finish(sp->wrk); if (vsb != NULL) { l = VSB_len(vsb); diff --git a/bin/varnishd/cache_esi_parse.c b/bin/varnishd/cache_esi_parse.c index 37c20e7..24fbe8b 100644 --- a/bin/varnishd/cache_esi_parse.c +++ b/bin/varnishd/cache_esi_parse.c @@ -35,6 +35,7 @@ #include "cache.h" +#include "cache_backend.h" // XXX: w->vbc for WSLB #include "cache_esi.h" #include "vct.h" #include "vend.h" @@ -60,7 +61,7 @@ struct vep_state { #define VEP_MAGIC 0x55cb9b82 struct vsb *vsb; - const struct sess *sp; + struct worker *wrk; int dogzip; vep_callback_t *cb; @@ -186,7 +187,7 @@ vep_error(const struct vep_state *vep, const char *p) VSC_C_main->esi_errors++; l = (intmax_t)(vep->ver_p - vep->hack_p); - WSP(vep->sp, SLT_ESI_xmlerror, "ERR at %jd %s", l, p); + WSLB(vep->wrk, SLT_ESI_xmlerror, "ERR at %jd %s", l, p); } @@ -202,7 +203,7 @@ vep_warn(const struct vep_state *vep, const char *p) VSC_C_main->esi_warnings++; l = (intmax_t)(vep->ver_p - vep->hack_p); printf("WARNING at %jd %s\n", l, p); - WSP(vep->sp, SLT_ESI_xmlerror, "WARN at %jd %s", l, p); + WSLB(vep->wrk, SLT_ESI_xmlerror, "WARN at %jd %s", l, p); } @@ -328,7 +329,7 @@ vep_mark_common(struct vep_state *vep, const char *p, enum vep_mark mark) */ if (vep->last_mark != mark && (vep->o_wait > 0 || vep->startup)) { - lcb = vep->cb(vep->sp, 0, + lcb = vep->cb(vep->wrk, 0, mark == VERBATIM ? VGZ_RESET : VGZ_ALIGN); if (lcb - vep->o_last > 0) vep_emit_common(vep, lcb - vep->o_last, vep->last_mark); @@ -338,7 +339,7 @@ vep_mark_common(struct vep_state *vep, const char *p, enum vep_mark mark) /* Transfer pending bytes CRC into active mode CRC */ if (vep->o_pending) { - (void)vep->cb(vep->sp, vep->o_pending, VGZ_NORMAL); + (void)vep->cb(vep->wrk, vep->o_pending, VGZ_NORMAL); if (vep->o_crc == 0) { vep->crc = vep->crcp; vep->o_crc = vep->o_pending; @@ -362,7 +363,7 @@ vep_mark_common(struct vep_state *vep, const char *p, enum vep_mark mark) vep->o_wait += l; vep->last_mark = mark; - (void)vep->cb(vep->sp, l, VGZ_NORMAL); + (void)vep->cb(vep->wrk, l, VGZ_NORMAL); } static void @@ -499,7 +500,7 @@ vep_do_include(struct vep_state *vep, enum dowhat what) VSB_printf(vep->vsb, "%c", 0); } else { VSB_printf(vep->vsb, "%c", 0); - url = vep->sp->wrk->bereq->hd[HTTP_HDR_URL]; + url = vep->wrk->bereq->hd[HTTP_HDR_URL]; /* Look for the last / before a '?' */ h = NULL; for (q = url.b; q < url.e && *q != '?'; q++) @@ -548,15 +549,15 @@ vep_do_include(struct vep_state *vep, enum dowhat what) */ void -VEP_parse(const struct sess *sp, const char *p, size_t l) +VEP_Parse(const struct worker *w, const char *p, size_t l) { struct vep_state *vep; const char *e; struct vep_match *vm; int i; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vep = sp->wrk->vep; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vep = w->vep; CHECK_OBJ_NOTNULL(vep, VEP_MAGIC); assert(l > 0); @@ -601,7 +602,7 @@ VEP_parse(const struct sess *sp, const char *p, size_t l) p++; vep->state = VEP_STARTTAG; } else if (p < e) { - WSP(vep->sp, SLT_ESI_xmlerror, + WSLB(vep->wrk, SLT_ESI_xmlerror, "No ESI processing, first char not '<'"); vep->state = VEP_NOTXML; } @@ -978,33 +979,34 @@ VEP_parse(const struct sess *sp, const char *p, size_t l) /*--------------------------------------------------------------------- */ -static ssize_t -vep_default_cb(const struct sess *sp, ssize_t l, enum vgz_flag flg) +static ssize_t __match_proto__() +vep_default_cb(struct worker *w, ssize_t l, enum vgz_flag flg) { (void)flg; - AN(sp->wrk->vep); - sp->wrk->vep->cb_x += l; -Debug("CB(%jd,%d) = %jd\n", (intmax_t)l, flg, (intmax_t)sp->wrk->vep->cb_x); - return (sp->wrk->vep->cb_x); + AN(w->vep); + w->vep->cb_x += l; +Debug("CB(%jd,%d) = %jd\n", (intmax_t)l, flg, (intmax_t)w->vep->cb_x); + return (w->vep->cb_x); } /*--------------------------------------------------------------------- */ void -VEP_Init(const struct sess *sp, vep_callback_t *cb) +VEP_Init(struct worker *w, vep_callback_t *cb) { struct vep_state *vep; - AZ(sp->wrk->vep); - sp->wrk->vep = (void*)WS_Alloc(sp->wrk->ws, sizeof *vep); - AN(sp->wrk->vep); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + AZ(w->vep); + w->vep = (void*)WS_Alloc(w->ws, sizeof *vep); + AN(w->vep); - vep = sp->wrk->vep; + vep = w->vep; memset(vep, 0, sizeof *vep); vep->magic = VEP_MAGIC; - vep->sp = sp; + vep->wrk = w; vep->vsb = VSB_new_auto(); AN(vep->vsb); @@ -1037,24 +1039,24 @@ VEP_Init(const struct sess *sp, vep_callback_t *cb) */ struct vsb * -VEP_Finish(const struct sess *sp) +VEP_Finish(struct worker *w) { struct vep_state *vep; ssize_t l, lcb; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vep = sp->wrk->vep; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vep = w->vep; CHECK_OBJ_NOTNULL(vep, VEP_MAGIC); if (vep->o_pending) vep_mark_common(vep, vep->ver_p, vep->last_mark); if (vep->o_wait > 0) { - lcb = vep->cb(vep->sp, 0, VGZ_ALIGN); + lcb = vep->cb(vep->wrk, 0, VGZ_ALIGN); vep_emit_common(vep, lcb - vep->o_last, vep->last_mark); } - (void)vep->cb(vep->sp, 0, VGZ_FINISH); + (void)vep->cb(vep->wrk, 0, VGZ_FINISH); - sp->wrk->vep = NULL; + w->vep = NULL; AZ(VSB_finish(vep->vsb)); l = VSB_len(vep->vsb); diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index e40676c..68dc04b 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -255,11 +255,11 @@ VGZ_ObufFull(const struct vgz *vg) */ int -VGZ_ObufStorage(const struct sess *sp, struct vgz *vg) +VGZ_ObufStorage(struct worker *w, struct vgz *vg) { struct storage *st; - st = FetchStorage(sp->wrk, 0); + st = FetchStorage(w, 0); if (st == NULL) return (-1); @@ -466,7 +466,7 @@ vfp_gunzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) bytes -= w; } - if (VGZ_ObufStorage(sp, vg)) { + if (VGZ_ObufStorage(sp->wrk, vg)) { htc->error = "Could not get storage"; return (-1); } @@ -541,7 +541,7 @@ vfp_gzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) VGZ_Ibuf(vg, ibuf, w); bytes -= w; } - if (VGZ_ObufStorage(sp, vg)) { + if (VGZ_ObufStorage(sp->wrk, vg)) { htc->error = "Could not get storage"; return (-1); } @@ -567,7 +567,7 @@ vfp_gzip_end(struct sess *sp) CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); do { VGZ_Ibuf(vg, "", 0); - if (VGZ_ObufStorage(sp, vg)) + if (VGZ_ObufStorage(sp->wrk, vg)) return (-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); sp->obj->len += dl; From phk at varnish-cache.org Mon Oct 24 14:26:16 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 16:26:16 +0200 Subject: [master] 4133b27 Push sess out of the stream-polling operation. Message-ID: commit 4133b274b11c980b302f4c79716b8083efaf3d83 Author: Poul-Henning Kamp Date: Mon Oct 24 14:01:25 2011 +0000 Push sess out of the stream-polling operation. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 298f820..08ba997 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -722,7 +722,7 @@ int VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag); int VGZ_Gunzip(struct vgz *, const void **, size_t *len); void VGZ_Destroy(struct vgz **); void VGZ_UpdateObj(const struct vgz*, struct object *); -int VGZ_WrwGunzip(const struct sess *, struct vgz *, const void *ibuf, +int VGZ_WrwGunzip(struct worker *w, struct vgz *, const void *ibuf, ssize_t ibufl, char *obuf, ssize_t obufl, ssize_t *obufp); /* Return values */ @@ -898,7 +898,7 @@ void RES_BuildHttp(const struct sess *sp); void RES_WriteObj(struct sess *sp); void RES_StreamStart(struct sess *sp); void RES_StreamEnd(struct sess *sp); -void RES_StreamPoll(const struct sess *sp); +void RES_StreamPoll(struct worker *); /* cache_vary.c */ struct vsb *VRY_Create(const struct sess *sp, const struct http *hp); diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index aaf5f7a..c79da64 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -330,7 +330,7 @@ ESI_Deliver(struct sess *sp) * response */ AN(vgz); - i = VGZ_WrwGunzip(sp, vgz, + i = VGZ_WrwGunzip(sp->wrk, vgz, st->ptr + off, l2, obuf, sizeof obuf, &obufl); if (WRW_Error(sp->wrk)) { diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index d71b2ec..08dd99c 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -101,7 +101,7 @@ vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) sp->obj->len += w; bytes -= w; if (sp->wrk->do_stream) - RES_StreamPoll(sp); + RES_StreamPoll(sp->wrk); } return (1); } diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 68dc04b..81c2475 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -350,7 +350,7 @@ VGZ_Gzip(struct vgz *vg, const void **pptr, size_t *plen, enum vgz_flag flags) */ int -VGZ_WrwGunzip(const struct sess *sp, struct vgz *vg, const void *ibuf, +VGZ_WrwGunzip(struct worker *w, struct vgz *vg, const void *ibuf, ssize_t ibufl, char *obuf, ssize_t obufl, ssize_t *obufp) { int i; @@ -375,9 +375,9 @@ VGZ_WrwGunzip(const struct sess *sp, struct vgz *vg, const void *ibuf, return (-1); } if (obufl == *obufp || i == VGZ_STUCK) { - sp->wrk->acct_tmp.bodybytes += *obufp; - (void)WRW_Write(sp->wrk, obuf, *obufp); - (void)WRW_Flush(sp->wrk); + w->acct_tmp.bodybytes += *obufp; + (void)WRW_Write(w, obuf, *obufp); + (void)WRW_Flush(w); *obufp = 0; VGZ_Obuf(vg, obuf + *obufp, obufl - *obufp); } @@ -474,7 +474,7 @@ vfp_gunzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) assert(i == VGZ_OK || i == VGZ_END); sp->obj->len += dl; if (sp->wrk->do_stream) - RES_StreamPoll(sp); + RES_StreamPoll(sp->wrk); } if (i == Z_OK || i == Z_STREAM_END) return (1); @@ -549,7 +549,7 @@ vfp_gzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) assert(i == Z_OK); sp->obj->len += dl; if (sp->wrk->do_stream) - RES_StreamPoll(sp); + RES_StreamPoll(sp->wrk); } return (1); } @@ -573,7 +573,7 @@ vfp_gzip_end(struct sess *sp) sp->obj->len += dl; } while (i != Z_STREAM_END); if (sp->wrk->do_stream) - RES_StreamPoll(sp); + RES_StreamPoll(sp->wrk); VGZ_UpdateObj(vg, sp->obj); VGZ_Destroy(&vg); return (0); @@ -631,7 +631,7 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) st->len += w; sp->obj->len += w; if (sp->wrk->do_stream) - RES_StreamPoll(sp); + RES_StreamPoll(sp->wrk); while (!VGZ_IbufEmpty(vg)) { VGZ_Obuf(vg, obuf, sizeof obuf); diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 5521bc0..ecc9839 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -172,7 +172,7 @@ res_WriteGunzipObj(const struct sess *sp) VSC_C_main->n_objwrite++; - i = VGZ_WrwGunzip(sp, vg, + i = VGZ_WrwGunzip(sp->wrk, vg, st->ptr, st->len, obuf, sizeof obuf, &obufl); /* XXX: error check */ @@ -354,50 +354,52 @@ RES_StreamStart(struct sess *sp) } void -RES_StreamPoll(const struct sess *sp) +RES_StreamPoll(struct worker *w) { struct stream_ctx *sctx; struct storage *st; ssize_t l, l2; void *ptr; - sctx = sp->wrk->sctx; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(w->fetch_obj, OBJECT_MAGIC); + sctx = w->sctx; CHECK_OBJ_NOTNULL(sctx, STREAM_CTX_MAGIC); - if (sp->obj->len == sctx->stream_next) + if (w->fetch_obj->len == sctx->stream_next) return; - assert(sp->obj->len > sctx->stream_next); + assert(w->fetch_obj->len > sctx->stream_next); l = sctx->stream_front; - VTAILQ_FOREACH(st, &sp->obj->store, list) { + VTAILQ_FOREACH(st, &w->fetch_obj->store, list) { if (st->len + l <= sctx->stream_next) { l += st->len; continue; } l2 = st->len + l - sctx->stream_next; ptr = st->ptr + (sctx->stream_next - l); - if (sp->wrk->res_mode & RES_GUNZIP) { - (void)VGZ_WrwGunzip(sp, sctx->vgz, ptr, l2, + if (w->res_mode & RES_GUNZIP) { + (void)VGZ_WrwGunzip(w, sctx->vgz, ptr, l2, sctx->obuf, sctx->obuf_len, &sctx->obuf_ptr); } else { - (void)WRW_Write(sp->wrk, ptr, l2); + (void)WRW_Write(w, ptr, l2); } l += st->len; sctx->stream_next += l2; } - if (!(sp->wrk->res_mode & RES_GUNZIP)) - (void)WRW_Flush(sp->wrk); + if (!(w->res_mode & RES_GUNZIP)) + (void)WRW_Flush(w); - if (sp->obj->objcore == NULL || - (sp->obj->objcore->flags & OC_F_PASS)) { + if (w->fetch_obj->objcore == NULL || + (w->fetch_obj->objcore->flags & OC_F_PASS)) { /* * This is a pass object, release storage as soon as we * have delivered it. */ while (1) { - st = VTAILQ_FIRST(&sp->obj->store); + st = VTAILQ_FIRST(&w->fetch_obj->store); if (st == NULL || sctx->stream_front + st->len > sctx->stream_next) break; - VTAILQ_REMOVE(&sp->obj->store, st, list); + VTAILQ_REMOVE(&w->fetch_obj->store, st, list); sctx->stream_front += st->len; STV_free(st); } From phk at varnish-cache.org Mon Oct 24 14:26:18 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 16:26:18 +0200 Subject: [master] 3e4b829 Push struct session out of all the vfp's in one go. Message-ID: commit 3e4b82917f6c17672dbfd192dd0bc41c04180b31 Author: Poul-Henning Kamp Date: Mon Oct 24 14:25:52 2011 +0000 Push struct session out of all the vfp's in one go. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 08ba997..85f5d5f 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -110,6 +110,7 @@ struct vef_priv; struct vrt_backend; struct vsb; struct waitinglist; +struct worker; #define DIGEST_LEN 32 @@ -226,9 +227,9 @@ struct dstat { /* Fetch processors --------------------------------------------------*/ -typedef void vfp_begin_f(struct sess *, size_t ); -typedef int vfp_bytes_f(struct sess *, struct http_conn *, ssize_t); -typedef int vfp_end_f(struct sess *sp); +typedef void vfp_begin_f(struct worker *, size_t ); +typedef int vfp_bytes_f(struct worker *, struct http_conn *, ssize_t); +typedef int vfp_end_f(struct worker *); struct vfp { vfp_begin_f *begin; @@ -703,7 +704,7 @@ int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ struct storage *FetchStorage(struct worker *w, ssize_t sz); int FetchHdr(struct sess *sp); -int FetchBody(struct sess *sp, struct object *obj); +int FetchBody(const struct sess *sp, struct object *obj); int FetchReqBody(struct sess *sp); void Fetch_Init(void); diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index fab6513..1713004 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -34,6 +34,7 @@ #include "cache.h" +#include "cache_backend.h" // for w->vbc #include "cache_esi.h" /*--------------------------------------------------------------------- @@ -62,26 +63,26 @@ vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes) * We receive a ungzip'ed object, and want to store it ungzip'ed. */ -static int __match_proto__() -vfp_esi_bytes_uu(struct sess *sp, struct http_conn *htc, ssize_t bytes) +static int +vfp_esi_bytes_uu(struct worker *w, struct http_conn *htc, ssize_t bytes) { - ssize_t w; + ssize_t wl; struct storage *st; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); while (bytes > 0) { - st = FetchStorage(sp->wrk, 0); + st = FetchStorage(w, 0); if (st == NULL) return (-1); - w = vef_read(htc, + wl = vef_read(htc, st->ptr + st->len, st->space - st->len, bytes); - if (w <= 0) - return (w); - VEP_Parse(sp->wrk, (const char *)st->ptr + st->len, w); - st->len += w; - sp->obj->len += w; - bytes -= w; + if (wl <= 0) + return (wl); + VEP_Parse(w, (const char *)st->ptr + st->len, wl); + st->len += wl; + w->fetch_obj->len += wl; + bytes -= wl; } return (1); } @@ -90,33 +91,33 @@ vfp_esi_bytes_uu(struct sess *sp, struct http_conn *htc, ssize_t bytes) * We receive a gzip'ed object, and want to store it ungzip'ed. */ -static int __match_proto__() -vfp_esi_bytes_gu(struct sess *sp, struct http_conn *htc, ssize_t bytes) +static int +vfp_esi_bytes_gu(struct worker *w, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; - ssize_t w; + ssize_t wl; uint8_t ibuf[params->gzip_stack_buffer]; int i; size_t dl; const void *dp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vg = sp->wrk->vgz_rx; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vg = w->vgz_rx; while (bytes > 0) { if (VGZ_IbufEmpty(vg) && bytes > 0) { - w = vef_read(htc, ibuf, sizeof ibuf, bytes); - if (w <= 0) - return (w); - VGZ_Ibuf(vg, ibuf, w); - bytes -= w; + wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + if (wl <= 0) + return (wl); + VGZ_Ibuf(vg, ibuf, wl); + bytes -= wl; } - if (VGZ_ObufStorage(sp->wrk, vg)) + if (VGZ_ObufStorage(w, vg)) return (-1); i = VGZ_Gunzip(vg, &dp, &dl); xxxassert(i == VGZ_OK || i == VGZ_END); - VEP_Parse(sp->wrk, dp, dl); - sp->obj->len += dl; + VEP_Parse(w, dp, dl); + w->fetch_obj->len += dl; } return (1); } @@ -202,34 +203,34 @@ vfp_vep_callback(struct worker *w, ssize_t l, enum vgz_flag flg) return (vef->tot); } -static int __match_proto__() -vfp_esi_bytes_ug(struct sess *sp, struct http_conn *htc, ssize_t bytes) +static int +vfp_esi_bytes_ug(const struct worker *w, struct http_conn *htc, ssize_t bytes) { - ssize_t w; + ssize_t wl; char ibuf[params->gzip_stack_buffer]; struct vef_priv *vef; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vef = sp->wrk->vef_priv; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); while (bytes > 0) { - w = vef_read(htc, ibuf, sizeof ibuf, bytes); - if (w <= 0) - return (w); - bytes -= w; + wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + if (wl <= 0) + return (wl); + bytes -= wl; vef->bufp = ibuf; - VEP_Parse(sp->wrk, ibuf, w); - assert(vef->bufp >= ibuf && vef->bufp <= ibuf + w); + VEP_Parse(w, ibuf, wl); + assert(vef->bufp >= ibuf && vef->bufp <= ibuf + wl); if (vef->error) { errno = vef->error; return (-1); } - if (vef->bufp < ibuf + w) { - w = (ibuf + w) - vef->bufp; - assert(w + vef->npend < sizeof vef->pending); - memmove(vef->pending + vef->npend, vef->bufp, w); - vef->npend += w; + if (vef->bufp < ibuf + wl) { + wl = (ibuf + wl) - vef->bufp; + assert(wl + vef->npend < sizeof vef->pending); + memmove(vef->pending + vef->npend, vef->bufp, wl); + vef->npend += wl; } } return (1); @@ -239,10 +240,10 @@ vfp_esi_bytes_ug(struct sess *sp, struct http_conn *htc, ssize_t bytes) * We receive a gzip'ed object, and want to store it gzip'ed. */ -static int __match_proto__() -vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) +static int +vfp_esi_bytes_gg(const struct worker *w, struct http_conn *htc, size_t bytes) { - ssize_t w; + ssize_t wl; char ibuf[params->gzip_stack_buffer]; char ibuf2[params->gzip_stack_buffer]; struct vef_priv *vef; @@ -250,28 +251,28 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) const void *dp; int i; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vef = sp->wrk->vef_priv; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); assert(sizeof ibuf >= 1024); ibuf2[0] = 0; /* For Flexelint */ while (bytes > 0) { - w = vef_read(htc, ibuf, sizeof ibuf, bytes); - if (w <= 0) - return (w); - bytes -= w; + wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + if (wl <= 0) + return (wl); + bytes -= wl; vef->bufp = ibuf; - VGZ_Ibuf(sp->wrk->vgz_rx, ibuf, w); + VGZ_Ibuf(w->vgz_rx, ibuf, wl); do { - VGZ_Obuf(sp->wrk->vgz_rx, ibuf2, sizeof ibuf2); - i = VGZ_Gunzip(sp->wrk->vgz_rx, &dp, &dl); + VGZ_Obuf(w->vgz_rx, ibuf2, sizeof ibuf2); + i = VGZ_Gunzip(w->vgz_rx, &dp, &dl); /* XXX: check i */ assert(i >= VGZ_OK); vef->bufp = ibuf2; if (dl > 0) - VEP_Parse(sp->wrk, ibuf2, dl); + VEP_Parse(w, ibuf2, dl); if (vef->error) { errno = vef->error; return (-1); @@ -283,7 +284,7 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) vef->bufp, dl); vef->npend += dl; } - } while (!VGZ_IbufEmpty(sp->wrk->vgz_rx)); + } while (!VGZ_IbufEmpty(w->vgz_rx)); } return (1); } @@ -292,96 +293,96 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) /*---------------------------------------------------------------------*/ static void __match_proto__() -vfp_esi_begin(struct sess *sp, size_t estimate) +vfp_esi_begin(struct worker *w, size_t estimate) { struct vef_priv *vef; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); /* XXX: snapshot WS's ? We'll need the space */ - AZ(sp->wrk->vgz_rx); - if (sp->wrk->is_gzip && sp->wrk->do_gunzip) { - sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); - VEP_Init(sp->wrk, NULL); - } else if (sp->wrk->is_gunzip && sp->wrk->do_gzip) { + AZ(w->vgz_rx); + if (w->is_gzip && w->do_gunzip) { + w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F E"); + VEP_Init(w, NULL); + } else if (w->is_gunzip && w->do_gzip) { ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); - AZ(sp->wrk->vef_priv); - sp->wrk->vef_priv = vef; - VEP_Init(sp->wrk, vfp_vep_callback); - } else if (sp->wrk->is_gzip) { - sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F E"); + vef->vgz = VGZ_NewGzip(w, w->vbc->vsl_id, "G F E"); + AZ(w->vef_priv); + w->vef_priv = vef; + VEP_Init(w, vfp_vep_callback); + } else if (w->is_gzip) { + w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F E"); ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F E"); - AZ(sp->wrk->vef_priv); - sp->wrk->vef_priv = vef; - VEP_Init(sp->wrk, vfp_vep_callback); + vef->vgz = VGZ_NewGzip(w, w->vbc->vsl_id, "G F E"); + AZ(w->vef_priv); + w->vef_priv = vef; + VEP_Init(w, vfp_vep_callback); } else { - AZ(sp->wrk->vef_priv); - VEP_Init(sp->wrk, NULL); + AZ(w->vef_priv); + VEP_Init(w, NULL); } (void)estimate; - AN(sp->wrk->vep); + AN(w->vep); } static int __match_proto__() -vfp_esi_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) +vfp_esi_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) { int i; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - AN(sp->wrk->vep); - if (sp->wrk->is_gzip && sp->wrk->do_gunzip) - i = vfp_esi_bytes_gu(sp, htc, bytes); - else if (sp->wrk->is_gunzip && sp->wrk->do_gzip) - i = vfp_esi_bytes_ug(sp, htc, bytes); - else if (sp->wrk->is_gzip) - i = vfp_esi_bytes_gg(sp, htc, bytes); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + AN(w->vep); + if (w->is_gzip && w->do_gunzip) + i = vfp_esi_bytes_gu(w, htc, bytes); + else if (w->is_gunzip && w->do_gzip) + i = vfp_esi_bytes_ug(w, htc, bytes); + else if (w->is_gzip) + i = vfp_esi_bytes_gg(w, htc, bytes); else - i = vfp_esi_bytes_uu(sp, htc, bytes); - AN(sp->wrk->vep); + i = vfp_esi_bytes_uu(w, htc, bytes); + AN(w->vep); return (i); } static int __match_proto__() -vfp_esi_end(struct sess *sp) +vfp_esi_end(struct worker *w) { struct vsb *vsb; struct vef_priv *vef; ssize_t l; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - AN(sp->wrk->vep); + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + AN(w->vep); - vsb = VEP_Finish(sp->wrk); + vsb = VEP_Finish(w); if (vsb != NULL) { l = VSB_len(vsb); assert(l > 0); /* XXX: This is a huge waste of storage... */ - sp->obj->esidata = STV_alloc(sp->wrk, l); - XXXAN(sp->obj->esidata); - memcpy(sp->obj->esidata->ptr, VSB_data(vsb), l); - sp->obj->esidata->len = l; + w->fetch_obj->esidata = STV_alloc(w, l); + XXXAN(w->fetch_obj->esidata); + memcpy(w->fetch_obj->esidata->ptr, VSB_data(vsb), l); + w->fetch_obj->esidata->len = l; VSB_delete(vsb); } - if (sp->wrk->vgz_rx != NULL) - VGZ_Destroy(&sp->wrk->vgz_rx); + if (w->vgz_rx != NULL) + VGZ_Destroy(&w->vgz_rx); - if (sp->wrk->vef_priv != NULL) { - vef = sp->wrk->vef_priv; + if (w->vef_priv != NULL) { + vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); - sp->wrk->vef_priv = NULL; - VGZ_UpdateObj(vef->vgz, sp->obj); + w->vef_priv = NULL; + VGZ_UpdateObj(vef->vgz, w->fetch_obj); VGZ_Destroy(&vef->vgz); XXXAZ(vef->error); FREE_OBJ(vef); diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 08dd99c..1769d3a 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -58,15 +58,15 @@ static unsigned fetchfrag; * as seen on the socket, or zero if unknown. */ static void __match_proto__() -vfp_nop_begin(struct sess *sp, size_t estimate) +vfp_nop_begin(struct worker *w, size_t estimate) { if (fetchfrag > 0) { estimate = fetchfrag; - WSP(sp, SLT_Debug, "Fetch %d byte segments:", fetchfrag); + WSLB(w, SLT_Debug, "Fetch %d byte segments:", fetchfrag); } if (estimate > 0) - (void)FetchStorage(sp->wrk, estimate); + (void)FetchStorage(w, estimate); } /*-------------------------------------------------------------------- @@ -80,13 +80,13 @@ vfp_nop_begin(struct sess *sp, size_t estimate) */ static int __match_proto__() -vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) +vfp_nop_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) { - ssize_t l, w; + ssize_t l, wl; struct storage *st; while (bytes > 0) { - st = FetchStorage(sp->wrk, 0); + st = FetchStorage(w, 0); if (st == NULL) { htc->error = "Could not get storage"; return (-1); @@ -94,14 +94,14 @@ vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) l = st->space - st->len; if (l > bytes) l = bytes; - w = HTC_Read(htc, st->ptr + st->len, l); - if (w <= 0) - return (w); - st->len += w; - sp->obj->len += w; - bytes -= w; - if (sp->wrk->do_stream) - RES_StreamPoll(sp->wrk); + wl = HTC_Read(htc, st->ptr + st->len, l); + if (wl <= 0) + return (wl); + st->len += wl; + w->fetch_obj->len += wl; + bytes -= wl; + if (w->do_stream) + RES_StreamPoll(w); } return (1); } @@ -116,16 +116,16 @@ vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) */ static int __match_proto__() -vfp_nop_end(struct sess *sp) +vfp_nop_end(struct worker *w) { struct storage *st; - st = VTAILQ_LAST(&sp->obj->store, storagehead); + st = VTAILQ_LAST(&w->fetch_obj->store, storagehead); if (st == NULL) return (0); if (st->len == 0) { - VTAILQ_REMOVE(&sp->obj->store, st, list); + VTAILQ_REMOVE(&w->fetch_obj->store, st, list); STV_free(st); return (0); } @@ -198,7 +198,7 @@ fetch_number(const char *nbr, int radix) /*--------------------------------------------------------------------*/ static int -fetch_straight(struct sess *sp, struct http_conn *htc, const char *b) +fetch_straight(const struct sess *sp, struct http_conn *htc, const char *b) { int i; ssize_t cl; @@ -206,14 +206,14 @@ fetch_straight(struct sess *sp, struct http_conn *htc, const char *b) assert(sp->wrk->body_status == BS_LENGTH); cl = fetch_number(b, 10); - sp->wrk->vfp->begin(sp, cl > 0 ? cl : 0); + sp->wrk->vfp->begin(sp->wrk, cl > 0 ? cl : 0); if (cl < 0) { WSP(sp, SLT_FetchError, "straight length field bogus"); return (-1); } else if (cl == 0) return (0); - i = sp->wrk->vfp->bytes(sp, htc, cl); + i = sp->wrk->vfp->bytes(sp->wrk, htc, cl); if (i <= 0) { WSP(sp, SLT_FetchError, "straight read_error: %d %d (%s)", i, errno, htc->error); @@ -235,14 +235,14 @@ fetch_straight(struct sess *sp, struct http_conn *htc, const char *b) } while (0) static int -fetch_chunked(struct sess *sp, struct http_conn *htc) +fetch_chunked(const struct sess *sp, struct http_conn *htc) { int i; char buf[20]; /* XXX: 20 is arbitrary */ unsigned u; ssize_t cl; - sp->wrk->vfp->begin(sp, 0); + sp->wrk->vfp->begin(sp->wrk, 0); assert(sp->wrk->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ @@ -283,7 +283,7 @@ fetch_chunked(struct sess *sp, struct http_conn *htc) WSP(sp, SLT_FetchError, "chunked header nbr syntax"); return (-1); } else if (cl > 0) { - i = sp->wrk->vfp->bytes(sp, htc, cl); + i = sp->wrk->vfp->bytes(sp->wrk, htc, cl); CERR(); } i = HTC_Read(htc, buf, 1); @@ -305,13 +305,13 @@ fetch_chunked(struct sess *sp, struct http_conn *htc) /*--------------------------------------------------------------------*/ static int -fetch_eof(struct sess *sp, struct http_conn *htc) +fetch_eof(const struct sess *sp, struct http_conn *htc) { int i; assert(sp->wrk->body_status == BS_EOF); - sp->wrk->vfp->begin(sp, 0); - i = sp->wrk->vfp->bytes(sp, htc, SSIZE_MAX); + sp->wrk->vfp->begin(sp->wrk, 0); + i = sp->wrk->vfp->bytes(sp->wrk, htc, SSIZE_MAX); if (i < 0) { WSP(sp, SLT_FetchError, "eof read_error: %d (%s)", errno, htc->error); @@ -480,7 +480,7 @@ FetchHdr(struct sess *sp) /*--------------------------------------------------------------------*/ int -FetchBody(struct sess *sp, struct object *obj) +FetchBody(const struct sess *sp, struct object *obj) { int cls; struct storage *st; @@ -518,17 +518,17 @@ FetchBody(struct sess *sp, struct object *obj) cls = fetch_straight(sp, w->htc, w->h_content_length); mklen = 1; - XXXAZ(w->vfp->end(sp)); + XXXAZ(w->vfp->end(sp->wrk)); break; case BS_CHUNKED: cls = fetch_chunked(sp, w->htc); mklen = 1; - XXXAZ(w->vfp->end(sp)); + XXXAZ(w->vfp->end(sp->wrk)); break; case BS_EOF: cls = fetch_eof(sp, w->htc); mklen = 1; - XXXAZ(w->vfp->end(sp)); + XXXAZ(w->vfp->end(sp->wrk)); break; case BS_ERROR: cls = 1; @@ -546,7 +546,7 @@ FetchBody(struct sess *sp, struct object *obj) * sitting on w->storage, we will always call vfp_nop_end() * to get it trimmed or thrown out if empty. */ - AZ(vfp_nop_end(sp)); + AZ(vfp_nop_end(sp->wrk)); w->fetch_obj = NULL; diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 81c2475..541d30e 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -71,6 +71,7 @@ #include "cache.h" +#include "cache_backend.h" // for w->vbc #include "vgz.h" struct vgz { @@ -434,24 +435,24 @@ VGZ_Destroy(struct vgz **vgp) */ static void __match_proto__() -vfp_gunzip_begin(struct sess *sp, size_t estimate) +vfp_gunzip_begin(struct worker *w, size_t estimate) { (void)estimate; - AZ(sp->wrk->vgz_rx); - sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U F -"); + AZ(w->vgz_rx); + w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F -"); } static int __match_proto__() -vfp_gunzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) +vfp_gunzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; - ssize_t l, w; + ssize_t l, wl; int i = -100; uint8_t ibuf[params->gzip_stack_buffer]; size_t dl; const void *dp; - vg = sp->wrk->vgz_rx; + vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0 || vg->vz.avail_in > 0) { @@ -459,37 +460,37 @@ vfp_gunzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) l = sizeof ibuf; if (l > bytes) l = bytes; - w = HTC_Read(htc, ibuf, l); - if (w <= 0) - return (w); - VGZ_Ibuf(vg, ibuf, w); - bytes -= w; + wl = HTC_Read(htc, ibuf, l); + if (wl <= 0) + return (wl); + VGZ_Ibuf(vg, ibuf, wl); + bytes -= wl; } - if (VGZ_ObufStorage(sp->wrk, vg)) { + if (VGZ_ObufStorage(w, vg)) { htc->error = "Could not get storage"; return (-1); } i = VGZ_Gunzip(vg, &dp, &dl); assert(i == VGZ_OK || i == VGZ_END); - sp->obj->len += dl; - if (sp->wrk->do_stream) - RES_StreamPoll(sp->wrk); + w->fetch_obj->len += dl; + if (w->do_stream) + RES_StreamPoll(w); } if (i == Z_OK || i == Z_STREAM_END) return (1); htc->error = "See other message"; - WSP(sp, SLT_FetchError, "Gunzip trouble (%d)", i); + WSLB(w, SLT_FetchError, "Gunzip trouble (%d)", i); return (-1); } static int __match_proto__() -vfp_gunzip_end(struct sess *sp) +vfp_gunzip_end(struct worker *w) { struct vgz *vg; - vg = sp->wrk->vgz_rx; - sp->wrk->vgz_rx = NULL; + vg = w->vgz_rx; + w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); VGZ_Destroy(&vg); return (0); @@ -509,25 +510,25 @@ struct vfp vfp_gunzip = { */ static void __match_proto__() -vfp_gzip_begin(struct sess *sp, size_t estimate) +vfp_gzip_begin(struct worker *w, size_t estimate) { (void)estimate; - AZ(sp->wrk->vgz_rx); - sp->wrk->vgz_rx = VGZ_NewGzip(sp->wrk, sp->vsl_id, "G F -"); + AZ(w->vgz_rx); + w->vgz_rx = VGZ_NewGzip(w, w->vbc->vsl_id, "G F -"); } static int __match_proto__() -vfp_gzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) +vfp_gzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; - ssize_t l, w; + ssize_t l, wl; int i = -100; uint8_t ibuf[params->gzip_stack_buffer]; size_t dl; const void *dp; - vg = sp->wrk->vgz_rx; + vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0 || !VGZ_IbufEmpty(vg)) { @@ -535,46 +536,46 @@ vfp_gzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) l = sizeof ibuf; if (l > bytes) l = bytes; - w = HTC_Read(htc, ibuf, l); - if (w <= 0) - return (w); - VGZ_Ibuf(vg, ibuf, w); - bytes -= w; + wl = HTC_Read(htc, ibuf, l); + if (wl <= 0) + return (wl); + VGZ_Ibuf(vg, ibuf, wl); + bytes -= wl; } - if (VGZ_ObufStorage(sp->wrk, vg)) { + if (VGZ_ObufStorage(w, vg)) { htc->error = "Could not get storage"; return (-1); } i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL); assert(i == Z_OK); - sp->obj->len += dl; - if (sp->wrk->do_stream) - RES_StreamPoll(sp->wrk); + w->fetch_obj->len += dl; + if (w->do_stream) + RES_StreamPoll(w); } return (1); } static int __match_proto__() -vfp_gzip_end(struct sess *sp) +vfp_gzip_end(struct worker *w) { struct vgz *vg; size_t dl; const void *dp; int i; - vg = sp->wrk->vgz_rx; - sp->wrk->vgz_rx = NULL; + vg = w->vgz_rx; + w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); do { VGZ_Ibuf(vg, "", 0); - if (VGZ_ObufStorage(sp->wrk, vg)) + if (VGZ_ObufStorage(w, vg)) return (-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); - sp->obj->len += dl; + w->fetch_obj->len += dl; } while (i != Z_STREAM_END); - if (sp->wrk->do_stream) - RES_StreamPoll(sp->wrk); - VGZ_UpdateObj(vg, sp->obj); + if (w->do_stream) + RES_StreamPoll(w); + VGZ_UpdateObj(vg, w->fetch_obj); VGZ_Destroy(&vg); return (0); } @@ -593,29 +594,29 @@ struct vfp vfp_gzip = { */ static void __match_proto__() -vfp_testgzip_begin(struct sess *sp, size_t estimate) +vfp_testgzip_begin(struct worker *w, size_t estimate) { (void)estimate; - sp->wrk->vgz_rx = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "u F -"); - CHECK_OBJ_NOTNULL(sp->wrk->vgz_rx, VGZ_MAGIC); + w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "u F -"); + CHECK_OBJ_NOTNULL(w->vgz_rx, VGZ_MAGIC); } static int __match_proto__() -vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) +vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; - ssize_t l, w; + ssize_t l, wl; int i = -100; uint8_t obuf[params->gzip_stack_buffer]; size_t dl; const void *dp; struct storage *st; - vg = sp->wrk->vgz_rx; + vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0) { - st = FetchStorage(sp->wrk, 0); + st = FetchStorage(w, 0); if (st == NULL) { htc->error = "Could not get storage"; return (-1); @@ -623,15 +624,15 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) l = st->space - st->len; if (l > bytes) l = bytes; - w = HTC_Read(htc, st->ptr + st->len, l); - if (w <= 0) - return (w); - bytes -= w; - VGZ_Ibuf(vg, st->ptr + st->len, w); - st->len += w; - sp->obj->len += w; - if (sp->wrk->do_stream) - RES_StreamPoll(sp->wrk); + wl = HTC_Read(htc, st->ptr + st->len, l); + if (wl <= 0) + return (wl); + bytes -= wl; + VGZ_Ibuf(vg, st->ptr + st->len, wl); + st->len += wl; + w->fetch_obj->len += wl; + if (w->do_stream) + RES_StreamPoll(w); while (!VGZ_IbufEmpty(vg)) { VGZ_Obuf(vg, obuf, sizeof obuf); @@ -642,7 +643,7 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) } if (i != VGZ_OK && i != VGZ_END) { htc->error = "See other message"; - WSP(sp, SLT_FetchError, + WSLB(w, SLT_FetchError, "Invalid Gzip data: %s", vg->vz.msg); return (-1); } @@ -651,19 +652,19 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) if (i == VGZ_OK || i == VGZ_END) return (1); htc->error = "See other message"; - WSP(sp, SLT_FetchError, "Gunzip trouble (%d)", i); + WSLB(w, SLT_FetchError, "Gunzip trouble (%d)", i); return (-1); } static int __match_proto__() -vfp_testgzip_end(struct sess *sp) +vfp_testgzip_end(struct worker *w) { struct vgz *vg; - vg = sp->wrk->vgz_rx; - sp->wrk->vgz_rx = NULL; + vg = w->vgz_rx; + w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - VGZ_UpdateObj(vg, sp->obj); + VGZ_UpdateObj(vg, w->fetch_obj); VGZ_Destroy(&vg); return (0); } From phk at varnish-cache.org Mon Oct 24 14:40:53 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 24 Oct 2011 16:40:53 +0200 Subject: [master] 71fe293 Push struct session entirely out of FetchBody(). Message-ID: commit 71fe2939a4435a1c5765de17708ecb22b3ddd66e Author: Poul-Henning Kamp Date: Mon Oct 24 14:39:45 2011 +0000 Push struct session entirely out of FetchBody(). This should make it possible to get a different worker thread to pull the body in from the backend, without cloning the session structure, with all the trouble that would cause. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 85f5d5f..b92fd60 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -704,7 +704,7 @@ int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ struct storage *FetchStorage(struct worker *w, ssize_t sz); int FetchHdr(struct sess *sp); -int FetchBody(const struct sess *sp, struct object *obj); +int FetchBody(struct worker *w, struct object *obj); int FetchReqBody(struct sess *sp); void Fetch_Init(void); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 13d8083..418fbe9 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -846,7 +846,7 @@ cnt_fetchbody(struct sess *sp) } /* Use unmodified headers*/ - i = FetchBody(sp, sp->obj); + i = FetchBody(sp->wrk, sp->obj); sp->wrk->h_content_length = NULL; @@ -910,7 +910,7 @@ cnt_streambody(struct sess *sp) AssertObjCorePassOrBusy(sp->obj->objcore); - i = FetchBody(sp, sp->obj); + i = FetchBody(sp->wrk, sp->obj); sp->wrk->h_content_length = NULL; diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 1769d3a..acef94b 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -198,24 +198,24 @@ fetch_number(const char *nbr, int radix) /*--------------------------------------------------------------------*/ static int -fetch_straight(const struct sess *sp, struct http_conn *htc, const char *b) +fetch_straight(struct worker *w, struct http_conn *htc, const char *b) { int i; ssize_t cl; - assert(sp->wrk->body_status == BS_LENGTH); + assert(w->body_status == BS_LENGTH); cl = fetch_number(b, 10); - sp->wrk->vfp->begin(sp->wrk, cl > 0 ? cl : 0); + w->vfp->begin(w, cl > 0 ? cl : 0); if (cl < 0) { - WSP(sp, SLT_FetchError, "straight length field bogus"); + WSLB(w, SLT_FetchError, "straight length field bogus"); return (-1); } else if (cl == 0) return (0); - i = sp->wrk->vfp->bytes(sp->wrk, htc, cl); + i = w->vfp->bytes(w, htc, cl); if (i <= 0) { - WSP(sp, SLT_FetchError, "straight read_error: %d %d (%s)", + WSLB(w, SLT_FetchError, "straight read_error: %d %d (%s)", i, errno, htc->error); return (-1); } @@ -227,7 +227,7 @@ fetch_straight(const struct sess *sp, struct http_conn *htc, const char *b) #define CERR() do { \ if (i != 1) { \ - WSP(sp, SLT_FetchError, \ + WSLB(w, SLT_FetchError, \ "chunked read_error: %d (%s)", \ errno, htc->error); \ return (-1); \ @@ -235,15 +235,15 @@ fetch_straight(const struct sess *sp, struct http_conn *htc, const char *b) } while (0) static int -fetch_chunked(const struct sess *sp, struct http_conn *htc) +fetch_chunked(struct worker *w, struct http_conn *htc) { int i; char buf[20]; /* XXX: 20 is arbitrary */ unsigned u; ssize_t cl; - sp->wrk->vfp->begin(sp->wrk, 0); - assert(sp->wrk->body_status == BS_CHUNKED); + w->vfp->begin(w, 0); + assert(w->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ do { @@ -262,7 +262,7 @@ fetch_chunked(const struct sess *sp, struct http_conn *htc) } if (u >= sizeof buf) { - WSP(sp, SLT_FetchError, "chunked header too long"); + WSLB(w, SLT_FetchError, "chunked header too long"); return (-1); } @@ -273,17 +273,17 @@ fetch_chunked(const struct sess *sp, struct http_conn *htc) } if (buf[u] != '\n') { - WSP(sp, SLT_FetchError, "chunked header char syntax"); + WSLB(w, SLT_FetchError, "chunked header char syntax"); return (-1); } buf[u] = '\0'; cl = fetch_number(buf, 16); if (cl < 0) { - WSP(sp, SLT_FetchError, "chunked header nbr syntax"); + WSLB(w, SLT_FetchError, "chunked header nbr syntax"); return (-1); } else if (cl > 0) { - i = sp->wrk->vfp->bytes(sp->wrk, htc, cl); + i = w->vfp->bytes(w, htc, cl); CERR(); } i = HTC_Read(htc, buf, 1); @@ -293,7 +293,7 @@ fetch_chunked(const struct sess *sp, struct http_conn *htc) CERR(); } if (buf[0] != '\n') { - WSP(sp, SLT_FetchError, "chunked tail syntax"); + WSLB(w, SLT_FetchError, "chunked tail syntax"); return (-1); } } while (cl > 0); @@ -305,15 +305,15 @@ fetch_chunked(const struct sess *sp, struct http_conn *htc) /*--------------------------------------------------------------------*/ static int -fetch_eof(const struct sess *sp, struct http_conn *htc) +fetch_eof(struct worker *w, struct http_conn *htc) { int i; - assert(sp->wrk->body_status == BS_EOF); - sp->wrk->vfp->begin(sp->wrk, 0); - i = sp->wrk->vfp->bytes(sp->wrk, htc, SSIZE_MAX); + assert(w->body_status == BS_EOF); + w->vfp->begin(w, 0); + i = w->vfp->bytes(w, htc, SSIZE_MAX); if (i < 0) { - WSP(sp, SLT_FetchError, "eof read_error: %d (%s)", + WSLB(w, SLT_FetchError, "eof read_error: %d (%s)", errno, htc->error); return (-1); } @@ -480,24 +480,21 @@ FetchHdr(struct sess *sp) /*--------------------------------------------------------------------*/ int -FetchBody(const struct sess *sp, struct object *obj) +FetchBody(struct worker *w, struct object *obj) { int cls; struct storage *st; - struct worker *w; int mklen; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); - w = sp->wrk; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); AZ(w->fetch_obj); + CHECK_OBJ_NOTNULL(w->vbc, VBC_MAGIC); CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(obj->http, HTTP_MAGIC); if (w->vfp == NULL) w->vfp = &vfp_nop; - AN(sp->director); AssertObjCorePassOrBusy(obj->objcore); AZ(w->vgz_rx); @@ -515,20 +512,20 @@ FetchBody(const struct sess *sp, struct object *obj) mklen = 1; break; case BS_LENGTH: - cls = fetch_straight(sp, w->htc, + cls = fetch_straight(w, w->htc, w->h_content_length); mklen = 1; - XXXAZ(w->vfp->end(sp->wrk)); + XXXAZ(w->vfp->end(w)); break; case BS_CHUNKED: - cls = fetch_chunked(sp, w->htc); + cls = fetch_chunked(w, w->htc); mklen = 1; - XXXAZ(w->vfp->end(sp->wrk)); + XXXAZ(w->vfp->end(w)); break; case BS_EOF: - cls = fetch_eof(sp, w->htc); + cls = fetch_eof(w, w->htc); mklen = 1; - XXXAZ(w->vfp->end(sp->wrk)); + XXXAZ(w->vfp->end(w)); break; case BS_ERROR: cls = 1; @@ -546,11 +543,11 @@ FetchBody(const struct sess *sp, struct object *obj) * sitting on w->storage, we will always call vfp_nop_end() * to get it trimmed or thrown out if empty. */ - AZ(vfp_nop_end(sp->wrk)); + AZ(vfp_nop_end(w)); w->fetch_obj = NULL; - WSL(w, SLT_Fetch_Body, w->vbc->vsl_id, "%u(%s) cls %d mklen %u", + WSLB(w, SLT_Fetch_Body, "%u(%s) cls %d mklen %u", w->body_status, body_status(w->body_status), cls, mklen); @@ -575,7 +572,7 @@ FetchBody(const struct sess *sp, struct object *obj) if (cls == 0 && w->do_close) cls = 1; - WSL(w, SLT_Length, w->vbc->vsl_id, "%u", obj->len); + WSLB(w, SLT_Length, "%u", obj->len); { /* Sanity check fetch methods accounting */ @@ -584,7 +581,7 @@ FetchBody(const struct sess *sp, struct object *obj) uu = 0; VTAILQ_FOREACH(st, &obj->store, list) uu += st->len; - if (sp->objcore == NULL || (sp->objcore->flags & OC_F_PASS)) + if (w->do_stream) /* Streaming might have started freeing stuff */ assert (uu <= obj->len); else @@ -593,7 +590,7 @@ FetchBody(const struct sess *sp, struct object *obj) if (mklen > 0) { http_Unset(obj->http, H_Content_Length); - http_PrintfHeader(w, sp->vsl_id, obj->http, + http_PrintfHeader(w, w->vbc->vsl_id, obj->http, "Content-Length: %jd", (intmax_t)obj->len); } From apj at varnish-cache.org Mon Oct 24 20:39:03 2011 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Mon, 24 Oct 2011 22:39:03 +0200 Subject: [master] 0b3ec32 Update to 3.0 syntax Message-ID: commit 0b3ec32c049af7102c6d8dfbb38e1fcd06f300a9 Author: Andreas Plesner Jacobsen Date: Mon Oct 24 22:38:48 2011 +0200 Update to 3.0 syntax diff --git a/doc/sphinx/tutorial/purging.rst b/doc/sphinx/tutorial/purging.rst index e5da595..cea1ccd 100644 --- a/doc/sphinx/tutorial/purging.rst +++ b/doc/sphinx/tutorial/purging.rst @@ -134,7 +134,7 @@ object is not available in the ban lurker thread. You can use the following template to write ban lurker friendly bans:: sub vcl_fetch { - set obj.http.x-url = req.url; + set beresp.http.x-url = req.url; } sub vcl_deliver { From phk at varnish-cache.org Tue Oct 25 07:53:13 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 09:53:13 +0200 Subject: [master] f6baebc Also snapshot the worker thread workspace around esi:include processing. Message-ID: commit f6baebcc2931036353356b16662e70de0363a1fe Author: Poul-Henning Kamp Date: Tue Oct 25 07:52:09 2011 +0000 Also snapshot the worker thread workspace around esi:include processing. Convert a few http_PrintfHeader() to http_SetHeader() for good measure: There is no reason to waste workspace on compiled in strings. Fixes #1038 diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 418fbe9..91ee652 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -467,7 +467,7 @@ cnt_error(struct sess *sp) http_PutStatus(h, sp->err_code); VTIM_format(VTIM_real(), date); http_PrintfHeader(w, sp->vsl_id, h, "Date: %s", date); - http_PrintfHeader(w, sp->vsl_id, h, "Server: Varnish"); + http_SetHeader(w, sp->vsl_id, h, "Server: Varnish"); if (sp->err_reason != NULL) http_PutResponse(w, sp->vsl_id, h, sp->err_reason); @@ -727,8 +727,8 @@ cnt_fetchbody(struct sess *sp) /* If we do gzip, add the C-E header */ if (sp->wrk->do_gzip) - http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->beresp, - "Content-Encoding: %s", "gzip"); + http_SetHeader(sp->wrk, sp->vsl_id, sp->wrk->beresp, + "Content-Encoding: gzip"); /* But we can't do both at the same time */ assert(sp->wrk->do_gzip == 0 || sp->wrk->do_gunzip == 0); @@ -1193,7 +1193,7 @@ cnt_miss(struct sess *sp) * the minority of clients which don't. */ http_Unset(sp->wrk->bereq, H_Accept_Encoding); - http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->bereq, + http_SetHeader(sp->wrk, sp->vsl_id, sp->wrk->bereq, "Accept-Encoding: gzip"); } sp->wrk->connect_timeout = 0; @@ -1397,7 +1397,7 @@ cnt_recv(struct sess *sp) (recv_handling != VCL_RET_PASS)) { if (RFC2616_Req_Gzip(sp)) { http_Unset(sp->http, H_Accept_Encoding); - http_PrintfHeader(sp->wrk, sp->vsl_id, sp->http, + http_SetHeader(sp->wrk, sp->vsl_id, sp->http, "Accept-Encoding: gzip"); } else { http_Unset(sp->http, H_Accept_Encoding); diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index c79da64..c10452e 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -46,7 +46,8 @@ ved_include(struct sess *sp, const char *src, const char *host) { struct object *obj; struct worker *w; - char *ws_wm; + char *sp_ws_wm; + char *wrk_ws_wm; unsigned sxid, res_mode; w = sp->wrk; @@ -65,7 +66,8 @@ ved_include(struct sess *sp, const char *src, const char *host) HTTP_Copy(sp->http, sp->http0); /* Take a workspace snapshot */ - ws_wm = WS_Snapshot(sp->ws); + sp_ws_wm = WS_Snapshot(sp->ws); + wrk_ws_wm = WS_Snapshot(w->ws); http_SetH(sp->http, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { @@ -115,7 +117,8 @@ ved_include(struct sess *sp, const char *src, const char *host) sp->wrk->res_mode = res_mode; /* Reset the workspace */ - WS_Reset(sp->ws, ws_wm); + WS_Reset(sp->ws, sp_ws_wm); + WS_Reset(w->ws, wrk_ws_wm); WRW_Reserve(sp->wrk, &sp->fd); if (sp->wrk->res_mode & RES_CHUNKED) diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index ecc9839..569f24f 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -125,7 +125,7 @@ RES_BuildHttp(const struct sess *sp) } if (sp->wrk->res_mode & RES_CHUNKED) - http_PrintfHeader(sp->wrk, sp->vsl_id, sp->wrk->resp, + http_SetHeader(sp->wrk, sp->vsl_id, sp->wrk->resp, "Transfer-Encoding: chunked"); VTIM_format(VTIM_real(), time_str); diff --git a/bin/varnishtest/tests/r01038.vtc b/bin/varnishtest/tests/r01038.vtc new file mode 100644 index 0000000..a4173b4 --- /dev/null +++ b/bin/varnishtest/tests/r01038.vtc @@ -0,0 +1,62 @@ +varnishtest "ticket 1038 regression test" + +server s1 { + rxreq + txresp -nolen -hdr "Transfer-encoding: chunked" + chunked {} + + + chunked {} + chunked {} + chunked {} + chunked {} + chunked {} + chunked {} + chunked {} + chunked {} + chunked {} + chunkedlen 0 + rxreq + expect req.url == "/xxx0.htm" + txresp -body "foo0" + rxreq + expect req.url == "/xxx1.htm" + txresp -body "foo1" + rxreq + expect req.url == "/xxx2.htm" + txresp -body "foo2" + rxreq + expect req.url == "/xxx3.htm" + txresp -body "foo3" + rxreq + expect req.url == "/xxx4.htm" + txresp -body "foo4" + rxreq + expect req.url == "/xxx5.htm" + txresp -body "foo5" + rxreq + expect req.url == "/xxx6.htm" + txresp -body "foo6" + rxreq + expect req.url == "/xxx7.htm" + txresp -body "foo7" + rxreq + expect req.url == "/xxx8.htm" + txresp -body "foo8" +} -start + +varnish v1 -arg "-p thread_pool_workspace=1024" -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq + rxresp + txreq + rxresp +} -run + +varnish v1 -expect losthdr == 0 + From phk at varnish-cache.org Tue Oct 25 09:45:09 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 11:45:09 +0200 Subject: [master] adf381c Ignore SIGPIPE, it causes the test-executing subprocess to bail out before all diagnostics have been gathered. Message-ID: commit adf381c8a1159580a8635bfb1de0e259eff9e81e Author: Poul-Henning Kamp Date: Tue Oct 25 08:15:35 2011 +0000 Ignore SIGPIPE, it causes the test-executing subprocess to bail out before all diagnostics have been gathered. diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index b496f9e..9581b3c 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -526,6 +527,8 @@ exec_file(const char *fn, const char *script, const char *tmpdir, FILE *f; struct extmacro *m; + signal(SIGPIPE, SIG_IGN); + vtc_loginit(logbuf, loglen); vltop = vtc_logopen("top"); AN(vltop); From phk at varnish-cache.org Tue Oct 25 09:45:10 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 11:45:10 +0200 Subject: [master] 1ff8836 Make it possible to mark http stuff "non-fatal". Message-ID: commit 1ff88369bf3690020975f2250ebad4ada39d1e0d Author: Poul-Henning Kamp Date: Tue Oct 25 09:33:57 2011 +0000 Make it possible to mark http stuff "non-fatal". The thread (s%d/c%d) still dies, but it does not mark this as fatal with respect to the test as such. This is useful where varnishd shuts the connection on a backend prematurely, as part of the correct execution of a test. Fix a undue recursion problem with asserts in the vtc_log code. diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index a1b6cbd..ee5308a 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -77,10 +77,10 @@ void cmd_server_genvcl(struct vsb *vsb); void vtc_loginit(char *buf, unsigned buflen); struct vtclog *vtc_logopen(const char *id); void vtc_logclose(struct vtclog *vl); -void vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...); -void vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, +void vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...); +void vtc_dump(struct vtclog *vl, int lvl, const char *pfx, const char *str, int len); -void vtc_hexdump(struct vtclog *vl, unsigned lvl, const char *pfx, +void vtc_hexdump(struct vtclog *vl, int lvl, const char *pfx, const unsigned char *str, int len); int exec_file(const char *fn, const char *script, const char *tmpdir, diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 698ffb0..69485cc 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -67,6 +67,8 @@ struct http { int gziplevel; int gzipresidual; + + int fatal; }; #define ONLY_CLIENT(hp, av) \ @@ -137,7 +139,7 @@ http_write(const struct http *hp, int lvl, const char *pfx) vtc_dump(hp->vl, lvl, pfx, VSB_data(hp->vsb), VSB_len(hp->vsb)); l = write(hp->fd, VSB_data(hp->vsb), VSB_len(hp->vsb)); if (l != VSB_len(hp->vsb)) - vtc_log(hp->vl, 0, "Write failed: (%d vs %d) %s", + vtc_log(hp->vl, hp->fatal, "Write failed: (%d vs %d) %s", l, VSB_len(hp->vsb), strerror(errno)); } @@ -339,10 +341,12 @@ http_rxchar(struct http *hp, int n, int eof) pfd[0].revents = 0; i = poll(pfd, 1, hp->timeout); if (i == 0) - vtc_log(hp->vl, 0, "HTTP rx timeout (fd:%d %u ms)", + vtc_log(hp->vl, hp->fatal, + "HTTP rx timeout (fd:%d %u ms)", hp->fd, hp->timeout); if (i < 0) - vtc_log(hp->vl, 0, "HTTP rx failed (fd:%d poll: %s)", + vtc_log(hp->vl, hp->fatal, + "HTTP rx failed (fd:%d poll: %s)", hp->fd, strerror(errno)); assert(i > 0); assert(hp->prxbuf + n < hp->nrxbuf); @@ -354,10 +358,12 @@ http_rxchar(struct http *hp, int n, int eof) if (i == 0 && eof) return (i); if (i == 0) - vtc_log(hp->vl, 0, "HTTP rx EOF (fd:%d read: %s)", + vtc_log(hp->vl, hp->fatal, + "HTTP rx EOF (fd:%d read: %s)", hp->fd, strerror(errno)); if (i < 0) - vtc_log(hp->vl, 0, "HTTP rx failed (fd:%d read: %s)", + vtc_log(hp->vl, hp->fatal, + "HTTP rx failed (fd:%d read: %s)", hp->fd, strerror(errno)); hp->prxbuf += i; hp->rxbuf[hp->prxbuf] = '\0'; @@ -381,7 +387,7 @@ http_rxchunk(struct http *hp) bprintf(hp->chunklen, "%d", i); if ((q == hp->rxbuf + l) || (*q != '\0' && !vct_islws(*q))) { - vtc_log(hp->vl, 0, "chunked fail %02x @ %d", + vtc_log(hp->vl, hp->fatal, "chunked fail %02x @ %d", *q, q - (hp->rxbuf + l)); } assert(q != hp->rxbuf + l); @@ -395,11 +401,11 @@ http_rxchunk(struct http *hp) l = hp->prxbuf; (void)http_rxchar(hp, 2, 0); if(!vct_iscrlf(hp->rxbuf[l])) - vtc_log(hp->vl, 0, + vtc_log(hp->vl, hp->fatal, "Wrong chunk tail[0] = %02x", hp->rxbuf[l] & 0xff); if(!vct_iscrlf(hp->rxbuf[l + 1])) - vtc_log(hp->vl, 0, + vtc_log(hp->vl, hp->fatal, "Wrong chunk tail[1] = %02x", hp->rxbuf[l + 1] & 0xff); hp->prxbuf = l; @@ -541,7 +547,8 @@ cmd_http_gunzip_body(CMD_ARGS) memset(&vz, 0, sizeof vz); if (hp->body[0] != (char)0x1f || hp->body[1] != (char)0x8b) - vtc_log(hp->vl, 0, "Gunzip error: Body lacks gzip magics"); + vtc_log(hp->vl, hp->fatal, + "Gunzip error: Body lacks gzip magics"); vz.next_in = TRUST_ME(hp->body); vz.avail_in = hp->bodyl; @@ -570,7 +577,8 @@ cmd_http_gunzip_body(CMD_ARGS) (uintmax_t)vz.stop_bit, (uintmax_t)vz.stop_bit >> 3, (uintmax_t)vz.stop_bit & 7); if (i != Z_STREAM_END) - vtc_log(hp->vl, 0, "Gunzip error = %d (%s) in:%jd out:%jd", + vtc_log(hp->vl, hp->fatal, + "Gunzip error = %d (%s) in:%jd out:%jd", i, vz.msg, (intmax_t)vz.total_in, (intmax_t)vz.total_out); assert(Z_OK == inflateEnd(&vz)); } @@ -602,7 +610,8 @@ gzip_body(const struct http *hp, const char *txt, char **body, int *bodylen) assert(Z_STREAM_END == deflate(&vz, Z_FINISH)); i = vz.stop_bit & 7; if (hp->gzipresidual >= 0 && hp->gzipresidual != i) - vtc_log(hp->vl, 0, "Wrong gzip residual got %d wanted %d", + vtc_log(hp->vl, hp->fatal, + "Wrong gzip residual got %d wanted %d", i, hp->gzipresidual); *bodylen = vz.total_out; vtc_log(hp->vl, 4, "startbit = %ju %ju/%ju", @@ -894,7 +903,7 @@ cmd_http_send(CMD_ARGS) vtc_dump(hp->vl, 4, "send", av[1], -1); i = write(hp->fd, av[1], strlen(av[1])); if (i != strlen(av[1])) - vtc_log(hp->vl, 0, "Write error in http_send(): %s", + vtc_log(hp->vl, hp->fatal, "Write error in http_send(): %s", strerror(errno)); } @@ -1036,9 +1045,9 @@ cmd_http_expect_close(CMD_ARGS) fds[0].revents = 0; i = poll(fds, 1, 1000); if (i == 0) - vtc_log(vl, 0, "Expected close: timeout"); + vtc_log(vl, hp->fatal, "Expected close: timeout"); if (i != 1 || !(fds[0].revents & POLLIN)) - vtc_log(vl, 0, + vtc_log(vl, hp->fatal, "Expected close: poll = %d, revents = 0x%x", i, fds[0].revents); i = read(hp->fd, &c, 1); @@ -1046,7 +1055,7 @@ cmd_http_expect_close(CMD_ARGS) break; if (i == 1 && vct_islws(c)) continue; - vtc_log(vl, 0, + vtc_log(vl, hp->fatal, "Expecting close: read = %d, c = 0x%02x", i, c); } vtc_log(vl, 4, "fd=%d EOF, as expected", hp->fd); @@ -1091,7 +1100,7 @@ cmd_http_accept(CMD_ARGS) vtc_log(vl, 4, "Accepting"); hp->fd = accept(*hp->sfd, NULL, NULL); if (hp->fd < 0) - vtc_log(vl, 0, "Accepted failed: %s", strerror(errno)); + vtc_log(vl, hp->fatal, "Accepted failed: %s", strerror(errno)); vtc_log(vl, 3, "Accepted socket fd is %d", hp->fd); } @@ -1120,6 +1129,26 @@ cmd_http_loop(CMD_ARGS) } /********************************************************************** + * Control fatality + */ + +static void +cmd_http_fatal(CMD_ARGS) +{ + struct http *hp; + CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC); + + AZ(av[1]); + if (!strcmp(av[0], "fatal")) + hp->fatal = 0; + else if (!strcmp(av[0], "non-fatal")) + hp->fatal = -1; + else { + vtc_log(vl, 0, "XXX: fatal %s", cmd->name); + } +} + +/********************************************************************** * Execute HTTP specifications */ @@ -1146,6 +1175,8 @@ static const struct cmds http_cmds[] = { { "close", cmd_http_close }, { "accept", cmd_http_accept }, { "loop", cmd_http_loop }, + { "fatal", cmd_http_fatal }, + { "non-fatal", cmd_http_fatal }, { NULL, NULL } }; diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index d6d15c1..313d3ab 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -47,6 +47,7 @@ struct vtclog { const char *id; struct vsb *vsb; pthread_mutex_t mtx; + int act; }; static pthread_key_t log_key; @@ -103,10 +104,12 @@ static const char * const lead[] = { #define NLEAD (sizeof(lead)/sizeof(lead[0])) static void -vtc_log_emit(const struct vtclog *vl, unsigned lvl) +vtc_log_emit(const struct vtclog *vl, int lvl) { int l; + if (lvl < 0) + lvl = 0; if (vtc_stop && lvl == 0) return; l = VSB_len(vl->vsb); @@ -121,16 +124,18 @@ vtc_log_emit(const struct vtclog *vl, unsigned lvl) //lint -e{818} void -vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...) +vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...) { double tx; CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); tx = VTIM_mono() - t0; AZ(pthread_mutex_lock(&vl->mtx)); + vl->act = 1; assert(lvl < NLEAD); VSB_clear(vl->vsb); - VSB_printf(vl->vsb, "%s %-4s %4.1f ", lead[lvl], vl->id, tx); + VSB_printf(vl->vsb, "%s %-4s %4.1f ", + lead[lvl < 0 ? 1: lvl], vl->id, tx); va_list ap; va_start(ap, fmt); (void)VSB_vprintf(vl->vsb, fmt, ap); @@ -141,12 +146,14 @@ vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...) vtc_log_emit(vl, lvl); VSB_clear(vl->vsb); + vl->act = 0; AZ(pthread_mutex_unlock(&vl->mtx)); - if (lvl == 0) { + if (lvl > 0) + return; + if (lvl == 0) vtc_error = 1; - if (pthread_self() != vtc_thread) - pthread_exit(NULL); - } + if (pthread_self() != vtc_thread) + pthread_exit(NULL); } /********************************************************************** @@ -155,7 +162,7 @@ vtc_log(struct vtclog *vl, unsigned lvl, const char *fmt, ...) //lint -e{818} void -vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, const char *str, int len) +vtc_dump(struct vtclog *vl, int lvl, const char *pfx, const char *str, int len) { int nl = 1; unsigned l; @@ -164,7 +171,9 @@ vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, const char *str, int CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); tx = VTIM_mono() - t0; assert(lvl < NLEAD); + assert(lvl >= 0); AZ(pthread_mutex_lock(&vl->mtx)); + vl->act = 1; VSB_clear(vl->vsb); if (pfx == NULL) pfx = ""; @@ -204,6 +213,7 @@ vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, const char *str, int vtc_log_emit(vl, lvl); VSB_clear(vl->vsb); + vl->act = 0; AZ(pthread_mutex_unlock(&vl->mtx)); if (lvl == 0) { vtc_error = 1; @@ -218,7 +228,7 @@ vtc_dump(struct vtclog *vl, unsigned lvl, const char *pfx, const char *str, int //lint -e{818} void -vtc_hexdump(struct vtclog *vl, unsigned lvl, const char *pfx, const unsigned char *str, int len) +vtc_hexdump(struct vtclog *vl, int lvl, const char *pfx, const unsigned char *str, int len) { int nl = 1; unsigned l; @@ -228,7 +238,9 @@ vtc_hexdump(struct vtclog *vl, unsigned lvl, const char *pfx, const unsigned cha tx = VTIM_mono() - t0; assert(len >= 0); assert(lvl < NLEAD); + assert(lvl >= 0); AZ(pthread_mutex_lock(&vl->mtx)); + vl->act = 1; VSB_clear(vl->vsb); if (pfx == NULL) pfx = ""; @@ -260,6 +272,7 @@ vtc_hexdump(struct vtclog *vl, unsigned lvl, const char *pfx, const unsigned cha vtc_log_emit(vl, lvl); VSB_clear(vl->vsb); + vl->act = 0; AZ(pthread_mutex_unlock(&vl->mtx)); if (lvl == 0) { vtc_error = 1; @@ -279,7 +292,7 @@ vtc_log_VAS_Fail(const char *func, const char *file, int line, (void)err; (void)xxx; vl = pthread_getspecific(log_key); - if (vl == NULL) { + if (vl == NULL || vl->act) { fprintf(stderr, "Assert error in %s(), %s line %d:\n" " Condition(%s) not true.\n", From phk at varnish-cache.org Tue Oct 25 09:45:10 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 11:45:10 +0200 Subject: [master] 6460036 Minor adjustment to asserts Message-ID: commit 6460036898caf29c6be27e5bec9722f27b5edf44 Author: Poul-Henning Kamp Date: Tue Oct 25 09:39:12 2011 +0000 Minor adjustment to asserts diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 313d3ab..651bd89 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -132,7 +132,7 @@ vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...) tx = VTIM_mono() - t0; AZ(pthread_mutex_lock(&vl->mtx)); vl->act = 1; - assert(lvl < NLEAD); + assert(lvl < (int)NLEAD); VSB_clear(vl->vsb); VSB_printf(vl->vsb, "%s %-4s %4.1f ", lead[lvl < 0 ? 1: lvl], vl->id, tx); @@ -170,8 +170,8 @@ vtc_dump(struct vtclog *vl, int lvl, const char *pfx, const char *str, int len) CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); tx = VTIM_mono() - t0; - assert(lvl < NLEAD); assert(lvl >= 0); + assert(lvl < NLEAD); AZ(pthread_mutex_lock(&vl->mtx)); vl->act = 1; VSB_clear(vl->vsb); @@ -237,8 +237,8 @@ vtc_hexdump(struct vtclog *vl, int lvl, const char *pfx, const unsigned char *st CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); tx = VTIM_mono() - t0; assert(len >= 0); - assert(lvl < NLEAD); assert(lvl >= 0); + assert(lvl < NLEAD); AZ(pthread_mutex_lock(&vl->mtx)); vl->act = 1; VSB_clear(vl->vsb); From phk at varnish-cache.org Tue Oct 25 09:45:10 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 11:45:10 +0200 Subject: [master] a2f873f Register buffer allocation failuers on vgz's and make failure to clean those up non-fatal. Message-ID: commit a2f873f20f4ee3b05ada950b168a25523550c99c Author: Poul-Henning Kamp Date: Tue Oct 25 09:44:39 2011 +0000 Register buffer allocation failuers on vgz's and make failure to clean those up non-fatal. Fixes #1036 diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 541d30e..08d298e 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -83,6 +83,7 @@ struct vgz { const char *id; struct ws *tmp; char *tmp_snapshot; + const char *error; struct storage *obuf; @@ -261,8 +262,10 @@ VGZ_ObufStorage(struct worker *w, struct vgz *vg) struct storage *st; st = FetchStorage(w, 0); - if (st == NULL) + if (st == NULL) { + vg->error = "Could not get ObufStorage"; return (-1); + } vg->obuf = st; VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len); @@ -407,6 +410,7 @@ void VGZ_Destroy(struct vgz **vgp) { struct vgz *vg; + const char *err; vg = *vgp; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); @@ -419,12 +423,13 @@ VGZ_Destroy(struct vgz **vgp) (intmax_t)vg->vz.start_bit, (intmax_t)vg->vz.last_bit, (intmax_t)vg->vz.stop_bit); + err = vg->error; if (vg->tmp != NULL) WS_Reset(vg->tmp, vg->tmp_snapshot); if (vg->dir == VGZ_GZ) - AZ(deflateEnd(&vg->vz)); + assert(deflateEnd(&vg->vz) == 0 || err != NULL); else - AZ(inflateEnd(&vg->vz)); + assert(inflateEnd(&vg->vz) == 0 || err != NULL); FREE_OBJ(vg); } @@ -564,18 +569,20 @@ vfp_gzip_end(struct worker *w) int i; vg = w->vgz_rx; - w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - do { - VGZ_Ibuf(vg, "", 0); - if (VGZ_ObufStorage(w, vg)) - return (-1); - i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); + w->vgz_rx = NULL; + if (vg->error == NULL) { + do { + VGZ_Ibuf(vg, "", 0); + if (VGZ_ObufStorage(w, vg)) + return (-1); + i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); w->fetch_obj->len += dl; - } while (i != Z_STREAM_END); - if (w->do_stream) - RES_StreamPoll(w); - VGZ_UpdateObj(vg, w->fetch_obj); + } while (i != Z_STREAM_END); + if (w->do_stream) + RES_StreamPoll(w); + VGZ_UpdateObj(vg, w->fetch_obj); + } VGZ_Destroy(&vg); return (0); } @@ -619,6 +626,7 @@ vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) st = FetchStorage(w, 0); if (st == NULL) { htc->error = "Could not get storage"; + vg->error = htc->error; return (-1); } l = st->space - st->len; diff --git a/bin/varnishtest/tests/r01036.vtc b/bin/varnishtest/tests/r01036.vtc new file mode 100644 index 0000000..8fb7600 --- /dev/null +++ b/bin/varnishtest/tests/r01036.vtc @@ -0,0 +1,22 @@ +varnishtest "Test case for #1036" + +server s1 { + rxreq + # Send a bodylen of 1,5M, which will exceed cache space of 1M + non-fatal + txresp -bodylen 1572864 +} -start + +varnish v1 -arg "-smalloc,1M" -arg "-pgzip_level=0" -vcl+backend { + sub vcl_fetch { + set beresp.do_gzip = true; + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == "503" +} -run + + From phk at varnish-cache.org Tue Oct 25 10:00:49 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 12:00:49 +0200 Subject: [master] 5068897 Fix indentation typo Message-ID: commit 5068897dbb6cb902fdb95b8050cfb66fc6a30ae8 Author: Poul-Henning Kamp Date: Tue Oct 25 10:00:32 2011 +0000 Fix indentation typo diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 08d298e..01ccebc 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -577,7 +577,7 @@ vfp_gzip_end(struct worker *w) if (VGZ_ObufStorage(w, vg)) return (-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); - w->fetch_obj->len += dl; + w->fetch_obj->len += dl; } while (i != Z_STREAM_END); if (w->do_stream) RES_StreamPoll(w); From phk at varnish-cache.org Tue Oct 25 20:05:12 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 25 Oct 2011 22:05:12 +0200 Subject: [master] 15c82a6 Clean up the cache_backend.h pollution caused by recent changes to FetchBody. Message-ID: commit 15c82a60ab3962d2b8291173d4b8fb10f3ab3215 Author: Poul-Henning Kamp Date: Tue Oct 25 20:04:42 2011 +0000 Clean up the cache_backend.h pollution caused by recent changes to FetchBody. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index b92fd60..bce7377 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -712,8 +712,8 @@ void Fetch_Init(void); struct vgz; enum vgz_flag { VGZ_NORMAL, VGZ_ALIGN, VGZ_RESET, VGZ_FINISH }; -struct vgz *VGZ_NewUngzip(struct worker *wrk, int vsl_id, const char *id); -struct vgz *VGZ_NewGzip(struct worker *wrk, int vsl_id, const char *id); +struct vgz *VGZ_NewUngzip(struct worker *wrk, const char *id); +struct vgz *VGZ_NewGzip(struct worker *wrk, const char *id); void VGZ_Ibuf(struct vgz *, const void *, ssize_t len); int VGZ_IbufEmpty(const struct vgz *vg); void VGZ_Obuf(struct vgz *, void *, ssize_t len); @@ -721,7 +721,7 @@ int VGZ_ObufFull(const struct vgz *vg); int VGZ_ObufStorage(struct worker *w, struct vgz *vg); int VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag); int VGZ_Gunzip(struct vgz *, const void **, size_t *len); -void VGZ_Destroy(struct vgz **); +void VGZ_Destroy(struct vgz **, int vsl_id); void VGZ_UpdateObj(const struct vgz*, struct object *); int VGZ_WrwGunzip(struct worker *w, struct vgz *, const void *ibuf, ssize_t ibufl, char *obuf, ssize_t obufl, ssize_t *obufp); @@ -864,12 +864,7 @@ void VSM_Free(const void *ptr); void VSL(enum VSL_tag_e tag, int id, const char *fmt, ...); void WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t); void WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...); -#define WSLB(w, tag, ...) \ - do { \ - CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); \ - CHECK_OBJ_NOTNULL(w->vbc, VBC_MAGIC); \ - WSL(w, tag, (w)->vbc->vsl_id, __VA_ARGS__); \ - } while (0) +void WSLB(struct worker *w, enum VSL_tag_e tag, const char *fmt, ...); void WSL_Flush(struct worker *w, int overflow); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 91ee652..fe7dae6 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -901,7 +901,7 @@ cnt_streambody(struct sess *sp) sp->wrk->sctx = &sctx; if (sp->wrk->res_mode & RES_GUNZIP) { - sctx.vgz = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U S -"); + sctx.vgz = VGZ_NewUngzip(sp->wrk, "U S -"); sctx.obuf = obuf; sctx.obuf_len = sizeof (obuf); } @@ -934,7 +934,7 @@ cnt_streambody(struct sess *sp) RES_StreamEnd(sp); if (sp->wrk->res_mode & RES_GUNZIP) - VGZ_Destroy(&sctx.vgz); + VGZ_Destroy(&sctx.vgz, sp->vsl_id); sp->wrk->sctx = NULL; assert(WRW_IsReleased(sp->wrk)); diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index c10452e..a06bbb8 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -270,7 +270,7 @@ ESI_Deliver(struct sess *sp) } if (isgzip && !sp->wrk->gzip_resp) { - vgz = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U D E"); + vgz = VGZ_NewUngzip(sp->wrk, "U D E"); /* Feed a gzip header to gunzip to make it happy */ VGZ_Ibuf(vgz, gzip_hdr, sizeof gzip_hdr); @@ -406,7 +406,7 @@ ESI_Deliver(struct sess *sp) if (vgz != NULL) { if (obufl > 0) (void)WRW_Write(sp->wrk, obuf, obufl); - VGZ_Destroy(&vgz); + VGZ_Destroy(&vgz, sp->vsl_id); } if (sp->wrk->gzip_resp && sp->esi_level == 0) { /* Emit a gzip literal block with finish bit set */ diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 1713004..69896aa 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -34,7 +34,6 @@ #include "cache.h" -#include "cache_backend.h" // for w->vbc #include "cache_esi.h" /*--------------------------------------------------------------------- @@ -302,7 +301,7 @@ vfp_esi_begin(struct worker *w, size_t estimate) AZ(w->vgz_rx); if (w->is_gzip && w->do_gunzip) { - w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F E"); + w->vgz_rx = VGZ_NewUngzip(w, "U F E"); VEP_Init(w, NULL); } else if (w->is_gunzip && w->do_gzip) { ALLOC_OBJ(vef, VEF_MAGIC); @@ -310,18 +309,18 @@ vfp_esi_begin(struct worker *w, size_t estimate) //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(w, w->vbc->vsl_id, "G F E"); + vef->vgz = VGZ_NewGzip(w, "G F E"); AZ(w->vef_priv); w->vef_priv = vef; VEP_Init(w, vfp_vep_callback); } else if (w->is_gzip) { - w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F E"); + w->vgz_rx = VGZ_NewUngzip(w, "U F E"); ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); //memset(vef, 0, sizeof *vef); //vef->magic = VEF_MAGIC; - vef->vgz = VGZ_NewGzip(w, w->vbc->vsl_id, "G F E"); + vef->vgz = VGZ_NewGzip(w, "G F E"); AZ(w->vef_priv); w->vef_priv = vef; VEP_Init(w, vfp_vep_callback); @@ -376,14 +375,14 @@ vfp_esi_end(struct worker *w) VSB_delete(vsb); } if (w->vgz_rx != NULL) - VGZ_Destroy(&w->vgz_rx); + VGZ_Destroy(&w->vgz_rx, -1); if (w->vef_priv != NULL) { vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); w->vef_priv = NULL; VGZ_UpdateObj(vef->vgz, w->fetch_obj); - VGZ_Destroy(&vef->vgz); + VGZ_Destroy(&vef->vgz, -1); XXXAZ(vef->error); FREE_OBJ(vef); } diff --git a/bin/varnishd/cache_esi_parse.c b/bin/varnishd/cache_esi_parse.c index 24fbe8b..663894a 100644 --- a/bin/varnishd/cache_esi_parse.c +++ b/bin/varnishd/cache_esi_parse.c @@ -35,7 +35,6 @@ #include "cache.h" -#include "cache_backend.h" // XXX: w->vbc for WSLB #include "cache_esi.h" #include "vct.h" #include "vend.h" diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 01ccebc..7df69cd 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -71,7 +71,6 @@ #include "cache.h" -#include "cache_backend.h" // for w->vbc #include "vgz.h" struct vgz { @@ -79,7 +78,6 @@ struct vgz { #define VGZ_MAGIC 0x162df0cb enum {VGZ_GZ,VGZ_UN} dir; struct worker *wrk; - int vsl_id; const char *id; struct ws *tmp; char *tmp_snapshot; @@ -116,7 +114,7 @@ vgz_free(voidpf opaque, voidpf address) */ static struct vgz * -vgz_alloc_vgz(struct worker *wrk, int vsl_id, const char *id) +vgz_alloc_vgz(struct worker *wrk, const char *id) { struct vgz *vg; struct ws *ws; @@ -131,7 +129,6 @@ vgz_alloc_vgz(struct worker *wrk, int vsl_id, const char *id) memset(vg, 0, sizeof *vg); vg->magic = VGZ_MAGIC; vg->wrk = wrk; - vg->vsl_id = vsl_id; vg->id = id; switch (params->gzip_tmp_space) { @@ -153,12 +150,12 @@ vgz_alloc_vgz(struct worker *wrk, int vsl_id, const char *id) } struct vgz * -VGZ_NewUngzip(struct worker *wrk, int vsl_id, const char *id) +VGZ_NewUngzip(struct worker *wrk, const char *id) { struct vgz *vg; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - vg = vgz_alloc_vgz(wrk, vsl_id, id); + vg = vgz_alloc_vgz(wrk, id); vg->dir = VGZ_UN; VSC_C_main->n_gunzip++; @@ -173,13 +170,13 @@ VGZ_NewUngzip(struct worker *wrk, int vsl_id, const char *id) } struct vgz * -VGZ_NewGzip(struct worker *wrk, int vsl_id, const char *id) +VGZ_NewGzip(struct worker *wrk, const char *id) { struct vgz *vg; int i; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - vg = vgz_alloc_vgz(wrk, vsl_id, id); + vg = vgz_alloc_vgz(wrk, id); vg->dir = VGZ_GZ; VSC_C_main->n_gzip++; @@ -404,10 +401,12 @@ VGZ_UpdateObj(const struct vgz *vg, struct object *obj) obj->gzip_stop = vg->vz.stop_bit; } -/*--------------------------------------------------------------------*/ +/*-------------------------------------------------------------------- + * Passing a vsl_id of -1 means "use w->vbc->vsl_id" + */ void -VGZ_Destroy(struct vgz **vgp) +VGZ_Destroy(struct vgz **vgp, int vsl_id) { struct vgz *vg; const char *err; @@ -416,13 +415,22 @@ VGZ_Destroy(struct vgz **vgp) CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); *vgp = NULL; - WSL(vg->wrk, SLT_Gzip, vg->vsl_id, "%s %jd %jd %jd %jd %jd", - vg->id, - (intmax_t)vg->vz.total_in, - (intmax_t)vg->vz.total_out, - (intmax_t)vg->vz.start_bit, - (intmax_t)vg->vz.last_bit, - (intmax_t)vg->vz.stop_bit); + if (vsl_id < 0) + WSLB(vg->wrk, SLT_Gzip, "%s %jd %jd %jd %jd %jd", + vg->id, + (intmax_t)vg->vz.total_in, + (intmax_t)vg->vz.total_out, + (intmax_t)vg->vz.start_bit, + (intmax_t)vg->vz.last_bit, + (intmax_t)vg->vz.stop_bit); + else + WSL(vg->wrk, SLT_Gzip, vsl_id, "%s %jd %jd %jd %jd %jd", + vg->id, + (intmax_t)vg->vz.total_in, + (intmax_t)vg->vz.total_out, + (intmax_t)vg->vz.start_bit, + (intmax_t)vg->vz.last_bit, + (intmax_t)vg->vz.stop_bit); err = vg->error; if (vg->tmp != NULL) WS_Reset(vg->tmp, vg->tmp_snapshot); @@ -444,7 +452,7 @@ vfp_gunzip_begin(struct worker *w, size_t estimate) { (void)estimate; AZ(w->vgz_rx); - w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "U F -"); + w->vgz_rx = VGZ_NewUngzip(w, "U F -"); } static int __match_proto__() @@ -497,7 +505,7 @@ vfp_gunzip_end(struct worker *w) vg = w->vgz_rx; w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - VGZ_Destroy(&vg); + VGZ_Destroy(&vg, -1); return (0); } @@ -520,7 +528,7 @@ vfp_gzip_begin(struct worker *w, size_t estimate) (void)estimate; AZ(w->vgz_rx); - w->vgz_rx = VGZ_NewGzip(w, w->vbc->vsl_id, "G F -"); + w->vgz_rx = VGZ_NewGzip(w, "G F -"); } static int __match_proto__() @@ -583,7 +591,7 @@ vfp_gzip_end(struct worker *w) RES_StreamPoll(w); VGZ_UpdateObj(vg, w->fetch_obj); } - VGZ_Destroy(&vg); + VGZ_Destroy(&vg, -1); return (0); } @@ -604,7 +612,7 @@ static void __match_proto__() vfp_testgzip_begin(struct worker *w, size_t estimate) { (void)estimate; - w->vgz_rx = VGZ_NewUngzip(w, w->vbc->vsl_id, "u F -"); + w->vgz_rx = VGZ_NewUngzip(w, "u F -"); CHECK_OBJ_NOTNULL(w->vgz_rx, VGZ_MAGIC); } @@ -673,7 +681,7 @@ vfp_testgzip_end(struct worker *w) w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); VGZ_UpdateObj(vg, w->fetch_obj); - VGZ_Destroy(&vg); + VGZ_Destroy(&vg, -1); return (0); } diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 569f24f..84606b6 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -162,7 +162,7 @@ res_WriteGunzipObj(const struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - vg = VGZ_NewUngzip(sp->wrk, sp->vsl_id, "U D -"); + vg = VGZ_NewUngzip(sp->wrk, "U D -"); VGZ_Obuf(vg, obuf, sizeof obuf); VTAILQ_FOREACH(st, &sp->obj->store, list) { @@ -182,7 +182,7 @@ res_WriteGunzipObj(const struct sess *sp) (void)WRW_Write(sp->wrk, obuf, obufl); (void)WRW_Flush(sp->wrk); } - VGZ_Destroy(&vg); + VGZ_Destroy(&vg, sp->vsl_id); assert(u == sp->obj->len); } diff --git a/bin/varnishd/cache_shmlog.c b/bin/varnishd/cache_shmlog.c index da39e2d..5601463 100644 --- a/bin/varnishd/cache_shmlog.c +++ b/bin/varnishd/cache_shmlog.c @@ -33,6 +33,8 @@ #include "cache.h" +#include "cache_backend.h" // For w->vbc + #include "vapi/vsm_int.h" #include "vmb.h" #include "vtim.h" @@ -229,16 +231,14 @@ WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t) /*--------------------------------------------------------------------*/ -void -WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...) +static void +wsl(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, va_list ap) { - va_list ap; char *p; unsigned n, mlen; txt t; AN(fmt); - va_start(ap, fmt); mlen = params->shm_reclen; if (strchr(fmt, '%') == NULL) { @@ -261,7 +261,6 @@ WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...) assert(w->wlp < w->wle); w->wlr++; } - va_end(ap); if (params->diag_bitmap & 0x10000) WSL_Flush(w, 0); } @@ -269,6 +268,36 @@ WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...) /*--------------------------------------------------------------------*/ void +WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...) +{ + va_list ap; + + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + AN(fmt); + va_start(ap, fmt); + wsl(w, tag, id, fmt, ap); + va_end(ap); +} + + +/*--------------------------------------------------------------------*/ + +void +WSLB(struct worker *w, enum VSL_tag_e tag, const char *fmt, ...) +{ + va_list ap; + + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(w->vbc, VBC_MAGIC); + AN(fmt); + va_start(ap, fmt); + wsl(w, tag, w->vbc->vsl_id, fmt, ap); + va_end(ap); +} + +/*--------------------------------------------------------------------*/ + +void VSL_Init(void) { struct VSM_chunk *vsc; From tfheen at varnish-cache.org Wed Oct 26 12:58:52 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:52 +0200 Subject: [3.0] e422c76 Sense of exit-code test was wrong. Message-ID: commit e422c7671149a76b69523aa3450dbc317b5573d7 Author: Poul-Henning Kamp Date: Thu Oct 6 08:43:22 2011 +0000 Sense of exit-code test was wrong. diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c index 9d6966a..ee74452 100644 --- a/bin/varnishd/mgt_child.c +++ b/bin/varnishd/mgt_child.c @@ -479,7 +479,7 @@ mgt_sigchld(const struct vev *e, int what) vsb = VSB_new_auto(); XXXAN(vsb); VSB_printf(vsb, "Child (%d) %s", r, status ? "died" : "ended"); - if (!WIFEXITED(status) && WEXITSTATUS(status)) { + if (WIFEXITED(status) && WEXITSTATUS(status)) { VSB_printf(vsb, " status=%d", WEXITSTATUS(status)); exit_status |= 0x20; } From tfheen at varnish-cache.org Wed Oct 26 12:58:52 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:52 +0200 Subject: [3.0] d18336e Add default values for some fields when logging imcomplete records. Allow %r format to log incomplete records too. Update docs to reflect new defaults Message-ID: commit d18336e59ed66512f5af2f2d26bb0a7261d012c8 Author: Andreas Plesner Jacobsen Date: Mon Oct 10 14:55:55 2011 +0200 Add default values for some fields when logging imcomplete records. Allow %r format to log incomplete records too. Update docs to reflect new defaults Fixes #1028 diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 7c35c3e..ad9249d 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -600,7 +600,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'H': - VSB_cat(os, lp->df_H); + VSB_cat(os, lp->df_H ? lp->df_H : "HTTP/1.0"); break; case 'h': @@ -614,7 +614,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'm': - VSB_cat(os, lp->df_m); + VSB_cat(os, lp->df_m ? lp->df_m : "-"); break; case 'q': @@ -626,24 +626,19 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, * Fake "%r". This would be a lot easier if Varnish * normalized the request URL. */ - if (!lp->df_m || - !req_header(lp, "Host") || - !lp->df_U || - !lp->df_H) { - clean_logline(lp); - return (reopen); - } - VSB_cat(os, lp->df_m); + VSB_cat(os, lp->df_m ? lp->df_m : "-"); VSB_putc(os, ' '); if (req_header(lp, "Host")) { if (strncmp(req_header(lp, "Host"), "http://", 7) != 0) VSB_cat(os, "http://"); VSB_cat(os, req_header(lp, "Host")); + } else { + VSB_cat(os, "http://localhost"); } - VSB_cat(os, lp->df_U); + VSB_cat(os, lp->df_U ? lp->df_U : "-"); VSB_cat(os, lp->df_q ? lp->df_q : ""); VSB_putc(os, ' '); - VSB_cat(os, lp->df_H); + VSB_cat(os, lp->df_H ? lp->df_H : "HTTP/1.0"); break; case 's': @@ -658,7 +653,7 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, break; case 'U': - VSB_cat(os, lp->df_U); + VSB_cat(os, lp->df_U ? lp->df_U : "-"); break; case 'u': diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index a4bac0a..e654e37 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -62,10 +62,12 @@ The following options are available: bytes are sent. %H - The request protocol + The request protocol. Defaults to HTTP/1.0 if not + known. %h - Remote host + Remote host. Defaults to '-' if not known. + Defaults to 127.0.0.1 for backend requests. %{X}i The contents of request header line X. @@ -74,16 +76,18 @@ The following options are available: Remote logname (always '-') %m - Request method + Request method. Defaults to '-' if not known. %q - The query string, if no query string exists, an empty string. + The query string, if no query string exists, an + empty string. %{X}o The contents of response header line X. %r - The first line of the request + The first line of the request. Synthesized from other + fields, so it may not be the request verbatim. %s Status sent to the client @@ -93,7 +97,8 @@ The following options are available: format. %U - The request URL without any query string. + The request URL without any query string. Defaults to + '-' if not known. %u Remote user from auth From tfheen at varnish-cache.org Wed Oct 26 12:58:52 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:52 +0200 Subject: [3.0] 3b8835a Smartypants is bad for code. People couldn't copy/paste from the reference pages Message-ID: commit 3b8835af3c70bc23035189edf0bccdfe63bfd00a Author: Andreas Plesner Jacobsen Date: Mon Oct 10 22:56:34 2011 +0200 Smartypants is bad for code. People couldn't copy/paste from the reference pages diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in index 0b07a2b..5cef666 100644 --- a/doc/sphinx/conf.py.in +++ b/doc/sphinx/conf.py.in @@ -155,7 +155,7 @@ html_title = "Varnish version @VERSION@ documentation" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +html_use_smartypants = False # Custom sidebar templates, maps document names to template names. #html_sidebars = {} From tfheen at varnish-cache.org Wed Oct 26 12:58:52 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:52 +0200 Subject: [3.0] 09dbe8e Add short segment on VMs / OpenVZ Message-ID: commit 09dbe8ef0e64d25fd42e164efa63923259ac0a3a Author: Lasse Karstensen Date: Tue Oct 11 09:59:00 2011 +0200 Add short segment on VMs / OpenVZ diff --git a/doc/sphinx/tutorial/index.rst b/doc/sphinx/tutorial/index.rst index e0e5023..59fd94e 100644 --- a/doc/sphinx/tutorial/index.rst +++ b/doc/sphinx/tutorial/index.rst @@ -26,6 +26,7 @@ separate topic. Good luck. vary purging esi + virtualised advanced_backend_servers handling_misbehaving_servers advanced_topics diff --git a/doc/sphinx/tutorial/virtualised.rst b/doc/sphinx/tutorial/virtualised.rst new file mode 100644 index 0000000..ce4b9ad --- /dev/null +++ b/doc/sphinx/tutorial/virtualised.rst @@ -0,0 +1,20 @@ + +Running inside a virtual machine (VM) +------------------------------------- + +It is possible, but not recommended for high performance, to run Varnish on virtualised +hardware. + +OpenVZ +'''''' + +If you are running on 64bit OpenVZ (or Parallels VPS), you must reduce the +maximum stack size before starting Varnish. The default allocates to much memory per thread, +which will make varnish fail as soon as the number of threads (==traffic) increases. + +Reduce the maximum stack size by running:: + + ulimit -s 256 + +in the startup script. + From tfheen at varnish-cache.org Wed Oct 26 12:58:53 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:53 +0200 Subject: [3.0] b49a87f Split solaris sandboxing out to a separate source file, and apply patch received from Nils Goroll Message-ID: commit b49a87fea435721d1834d2925dd6b59d40161848 Author: Poul-Henning Kamp Date: Fri Sep 30 13:30:43 2011 +0000 Split solaris sandboxing out to a separate source file, and apply patch received from Nils Goroll - [e0ee2a2e69654a9df74aaf3dcadc9639659cf42b] adds the file_read privilege needed for onnv_140 and newer (see #912), but we also need the file_write privilege for stevedore access. - If available, keep sys_resource in the permitted/limited set to allow cache_waiter_ports to raise the process.max-port-events resource control (feature to be added later). - When starting varnish with euid 0 on Solaris, privilege seperation prohibited preserving additional privileges (in excess of the basic set) in the child, because, for a non privilege aware process, setuid() resets the effective, inheritable and permitted sets to the basic set. To achieve interoperability between solaris privileges and setuid()/setgid(), we now make the varnish child privilege aware before calling setuid() by trying to add all privileges we will need plus proc_setid. - On solaris, check for proc_setid rather than checking the euid as a prerequisite for changing the uid/gid and only change the uid/gid if we need to (for a privilege aware process, [ers]uid 0 loose their magic powers). Note that setuid() will always set SNOCD on Solaris, which will prevent core dumps from being written, unless setuid core dumps are explicitly enabled using coreadm(1M). To avoid setuid() (and the SNOCD flag, consequently), start varnish as the user you intend to run the child as, but with additional privileges, e.g. using ppriv -e -s A=basic,net_privaddr,sys_resource varnishd ... - setppriv(PRIV_SET, ...) failed when the privileges to be applied were not available in the permitted set. We change the logic to only clear the privileges which are not needed by inverting the sets and removing all unneeded privileges using setppriv(PRIV_OFF, ...). So the child might end up with less privileges than given initially, diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 7d21fcd..00dc716 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -58,6 +58,7 @@ varnishd_SOURCES = \ mgt_param.c \ mgt_pool.c \ mgt_sandbox.c \ + mgt_sandbox_solaris.c \ mgt_shmem.c \ mgt_vcc.c \ rfc2616.c \ diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 485de26..b6dac01 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -71,6 +71,12 @@ void MCF_DumpRst(void); /* mgt_sandbox.c */ void mgt_sandbox(void); +/* mgt_sandbox_solaris.c */ +#ifdef HAVE_SETPPRIV +void mgt_sandbox_solaris_init(void) +void mgt_sandbox_solaris_fini(void) +#endif + /* mgt_shmem.c */ void mgt_SHM_Init(const char *arg); void mgt_SHM_Pid(void); diff --git a/bin/varnishd/mgt_sandbox.c b/bin/varnishd/mgt_sandbox.c index a5eee2f..94f9f4d 100644 --- a/bin/varnishd/mgt_sandbox.c +++ b/bin/varnishd/mgt_sandbox.c @@ -48,10 +48,6 @@ #include #include -#ifdef HAVE_PRIV_H -#include -#endif - #ifdef __linux__ #include #endif @@ -67,6 +63,10 @@ void mgt_sandbox(void) { +#ifdef HAVE_SETPPRIV + mgt_sandbox_solaris_init(); +#endif + if (geteuid() == 0) { XXXAZ(setgid(params->gid)); XXXAZ(setuid(params->uid)); @@ -84,35 +84,7 @@ mgt_sandbox(void) #endif #ifdef HAVE_SETPPRIV - priv_set_t *empty, *minimal; - - if (!(empty = priv_allocset()) || - !(minimal = priv_allocset())) { - REPORT0(LOG_ERR, "priv_allocset_failed"); - } else { - priv_emptyset(empty); - priv_emptyset(minimal); - - /* - * new privilege, - * silently ignore any errors if it doesn't exist - */ - priv_addset(minimal, "net_access"); - priv_addset(minimal, "file_read"); - -#define SETPPRIV(which, set) \ - if (setppriv(PRIV_SET, which, set)) \ - REPORT0(LOG_ERR, \ - "Waiving privileges failed on " #which) - - /* need to set I after P to avoid SNOCD being set */ - SETPPRIV(PRIV_LIMIT, minimal); - SETPPRIV(PRIV_PERMITTED, minimal); /* implies PRIV_EFFECTIVE */ - SETPPRIV(PRIV_INHERITABLE, empty); - - priv_freeset(empty); - priv_freeset(minimal); - } + mgt_sandbox_solaris_fini(); #endif } diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c new file mode 100644 index 0000000..15b7c95 --- /dev/null +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 2006-2011 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * Nils Goroll + * + * 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. + * + * Sandboxing child processes on Solaris + * + */ + +#include "config.h" + +#ifdef HAVE_SETPPRIV + +#include +#include +#include +#include + +#ifdef HAVE_PRIV_H +#include +#endif + +#include "mgt.h" +#include "heritage.h" + +/*-------------------------------------------------------------------- + * SOLARIS PRIVILEGES: Note on use of symbolic PRIV_* constants + * + * For privileges which existed in Solaris 10 FCS, we may use the constants from + * sys/priv_names.h + * + * For privileges which have been added later, we need to use strings in order + * not to break builds of varnish on these platforms. To remain binary + * compatible, we need to silently ignore errors from priv_addset when using + * these strings. + * + * For optimal build and binary forward comatibility, we could use subtractive + * set specs like + * + * basic,!file_link_any,!proc_exec,!proc_fork,!proc_info,!proc_session + * + * but I (Nils) have a preference for making an informed decision about which + * privileges the varnish child should have and which it shouldn't. + * + * Newly introduced privileges should be annotated with their PSARC / commit ID + * (as long as Oracle reveils these :/ ) + * + * SOLARIS PRIVILEGES: Note on accidentally setting the SNOCD flag + * + * When setting privileges, we need to take care not to accidentally set the + * SNOCD flag which will disable core dumps unnecessarily. (see + * https://www.varnish-cache.org/trac/ticket/671 ) + * + * When changing the logic herein, always check with mdb -k. Replace _PID_ with + * the pid of your varnish child, the result should be 0, otherwise a regression + * has been introduced. + * + * > 0t_PID_::pid2proc | ::print proc_t p_flag | >a + * > ( ppriv -v #pid of varnish child + * PID: .../varnishd ... + * flags = PRIV_AWARE + * E: file_read,file_write,net_access + * I: none + * P: file_read,file_write,net_access,sys_resource + * L: file_read,file_write,net_access,sys_resource + * + * We should keep sys_resource in P in order to adjust our limits if we need to + */ + +void +mgt_sandbox_solaris_fini(void) +{ + priv_set_t *effective, *inheritable, *permitted; + + if (!(effective = priv_allocset()) || + !(inheritable = priv_allocset()) || + !(permitted = priv_allocset())) { + REPORT(LOG_ERR, + "Child start warning: mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)", + errno, strerror(errno)); + return; + } + + priv_emptyset(inheritable); + + priv_emptyset(effective); + mgt_sandbox_solaris_add_effective(effective); + + priv_copyset(effective, permitted); + mgt_sandbox_solaris_add_permitted(permitted); + + /* + * invert the sets and clear privileges such that setppriv will always + * succeed + */ + priv_inverse(inheritable); + priv_inverse(effective); + priv_inverse(permitted); + +#define SETPPRIV(which, set) \ + if (setppriv(PRIV_OFF, which, set)) \ + REPORT(LOG_ERR, \ + "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \ + #which, errno, strerror(errno)); + + SETPPRIV(PRIV_INHERITABLE, inheritable); + SETPPRIV(PRIV_EFFECTIVE, effective); + SETPPRIV(PRIV_PERMITTED, permitted); + SETPPRIV(PRIV_LIMIT, permitted); +#undef SETPPRIV + + priv_freeset(inheritable); + priv_freeset(effective); +} + +#endif /* HAVE_SETPPRIV */ From tfheen at varnish-cache.org Wed Oct 26 12:58:53 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:53 +0200 Subject: [3.0] 66ba62e Add mising ;'s Message-ID: commit 66ba62ef10b04aacebe1b49a84f747d416ad5b4a Author: Poul-Henning Kamp Date: Fri Sep 30 15:39:55 2011 +0000 Add mising ;'s diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index b6dac01..24293c2 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -73,8 +73,8 @@ void mgt_sandbox(void); /* mgt_sandbox_solaris.c */ #ifdef HAVE_SETPPRIV -void mgt_sandbox_solaris_init(void) -void mgt_sandbox_solaris_fini(void) +void mgt_sandbox_solaris_init(void); +void mgt_sandbox_solaris_fini(void); #endif /* mgt_shmem.c */ From tfheen at varnish-cache.org Wed Oct 26 12:58:53 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:53 +0200 Subject: [3.0] 5cc9462 Solaris sandbox changes. Message-ID: commit 5cc94622da8df18349a47d259d6ac7b80c86648b Author: Poul-Henning Kamp Date: Wed Oct 12 08:29:41 2011 +0000 Solaris sandbox changes. Submitted by: Nils Goroll Conflicts: bin/varnishd/mgt_sandbox_solaris.c diff --git a/bin/varnishd/mgt.h b/bin/varnishd/mgt.h index 24293c2..578fcad 100644 --- a/bin/varnishd/mgt.h +++ b/bin/varnishd/mgt.h @@ -75,6 +75,7 @@ void mgt_sandbox(void); #ifdef HAVE_SETPPRIV void mgt_sandbox_solaris_init(void); void mgt_sandbox_solaris_fini(void); +void mgt_sandbox_solaris_privsep(void); #endif /* mgt_shmem.c */ diff --git a/bin/varnishd/mgt_sandbox.c b/bin/varnishd/mgt_sandbox.c index 94f9f4d..f092bf2 100644 --- a/bin/varnishd/mgt_sandbox.c +++ b/bin/varnishd/mgt_sandbox.c @@ -62,17 +62,17 @@ void mgt_sandbox(void) { - #ifdef HAVE_SETPPRIV mgt_sandbox_solaris_init(); -#endif - + mgt_sandbox_solaris_privsep(); +#else if (geteuid() == 0) { XXXAZ(setgid(params->gid)); XXXAZ(setuid(params->uid)); } else { REPORT0(LOG_INFO, "Not running as root, no priv-sep"); } +#endif /* On Linux >= 2.4, you need to set the dumpable flag to get core dumps after you have done a setuid. */ diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 15b7c95..5da880a 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -42,6 +42,10 @@ #ifdef HAVE_PRIV_H #include #endif +#include +#include +#include +#include #include "mgt.h" #include "heritage.h" @@ -154,6 +158,20 @@ mgt_sandbox_solaris_init(void) priv_freeset(priv_all); } +void +mgt_sandbox_solaris_privsep(void) +{ + if (priv_ineffect(PRIV_PROC_SETID)) { + if (getgid() != params->gid) + XXXAZ(setgid(params->gid)); + if (getuid() != params->uid) + XXXAZ(setuid(params->uid)); + } else { + REPORT(LOG_INFO, "Privilege %s missing, will not change uid/gid", + PRIV_PROC_SETID); + } +} + /* * Waive most privileges in the child * From tfheen at varnish-cache.org Wed Oct 26 12:58:53 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:53 +0200 Subject: [3.0] c14a4cd strange wording. typo Message-ID: commit c14a4cdbec4db8938b89fe576a70b8cc272fce57 Author: Per Buer Date: Thu Oct 6 11:03:43 2011 +0200 strange wording. typo diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 6ba912a..019fd3b 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -5,7 +5,7 @@ Welcome to Varnish's documentation! =================================== Varnish is a state of the art web accelerator. Its mission is to sit -in front of a web server an cache the content. It makes your web site +in front of a web server and to cache the content. It makes your web site go fast. We suggest you start by reading the installation guide From tfheen at varnish-cache.org Wed Oct 26 12:58:54 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:54 +0200 Subject: [3.0] 0924503 Grammar Message-ID: commit 092450397ade557a2f286f241bc49ec4655d79f5 Author: Tollef Fog Heen Date: Fri Oct 7 08:59:08 2011 +0200 Grammar diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 019fd3b..2558413 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -5,8 +5,8 @@ Welcome to Varnish's documentation! =================================== Varnish is a state of the art web accelerator. Its mission is to sit -in front of a web server and to cache the content. It makes your web site -go fast. +in front of a web server and cache content. It makes your web site +go faster. We suggest you start by reading the installation guide :ref:`install-index`. Once you have Varnish up and running go through From tfheen at varnish-cache.org Wed Oct 26 12:58:54 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:54 +0200 Subject: [3.0] 2cd4ec2 Update docs for 3.0 Fixes #1032 Message-ID: commit 2cd4ec22ce9846d32fcced777eccddc57ab0a07f Author: Andreas Plesner Jacobsen Date: Thu Oct 13 09:30:27 2011 +0200 Update docs for 3.0 Fixes #1032 diff --git a/doc/sphinx/tutorial/esi.rst b/doc/sphinx/tutorial/esi.rst index ef79f3e..1d01cb8 100644 --- a/doc/sphinx/tutorial/esi.rst +++ b/doc/sphinx/tutorial/esi.rst @@ -48,9 +48,9 @@ For ESI to work you need to activate ESI processing in VCL, like this::: sub vcl_fetch { if (req.url == "/test.html") { set beresp.do_esi = true; /* Do ESI processing */ - set obj.ttl = 24 h; /* Sets the TTL on the HTML above */ + set beresp.ttl = 24 h; /* Sets the TTL on the HTML above */ } elseif (req.url == "/cgi-bin/date.cgi") { - set obj.ttl = 1m; /* Sets a one minute TTL on */ + set beresp.ttl = 1m; /* Sets a one minute TTL on */ /* the included object */ } } From tfheen at varnish-cache.org Wed Oct 26 12:58:54 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:54 +0200 Subject: [3.0] 601d7d3 Work around a Solaris bug. Message-ID: commit 601d7d3ff87b917ea1d2ba595a3c98c9a7e18e4e Author: Poul-Henning Kamp Date: Thu Oct 13 09:59:03 2011 +0000 Work around a Solaris bug. Submitted by: Nils Goroll diff --git a/lib/libvarnish/tcp.c b/lib/libvarnish/tcp.c index c612e97..f544bdc 100644 --- a/lib/libvarnish/tcp.c +++ b/lib/libvarnish/tcp.c @@ -267,7 +267,13 @@ VTCP_set_read_timeout(int s, double seconds) timeout.tv_sec = (int)floor(seconds); timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec)); #ifdef SO_RCVTIMEO_WORKS - AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); + /* + * Solaris bug (present at least in snv_151 and older): If this fails + * with EINVAL, the socket is half-closed (SS_CANTSENDMORE) and the + * timeout does not get set. Needs to be fixed in Solaris, there is + * nothing we can do about this. + */ + VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); #else (void)s; #endif From tfheen at varnish-cache.org Wed Oct 26 12:58:55 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:55 +0200 Subject: [3.0] f46350c Adjustments to solaris sandbox. Message-ID: commit f46350c3b6e1b7ee1ba44ad3261a730a9de0c316 Author: Poul-Henning Kamp Date: Thu Oct 13 10:00:56 2011 +0000 Adjustments to solaris sandbox. Submitted by: Nils Goroll diff --git a/bin/varnishd/mgt_sandbox_solaris.c b/bin/varnishd/mgt_sandbox_solaris.c index 5da880a..82c4380 100644 --- a/bin/varnishd/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt_sandbox_solaris.c @@ -224,10 +224,10 @@ mgt_sandbox_solaris_fini(void) "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \ #which, errno, strerror(errno)); - SETPPRIV(PRIV_INHERITABLE, inheritable); - SETPPRIV(PRIV_EFFECTIVE, effective); - SETPPRIV(PRIV_PERMITTED, permitted); SETPPRIV(PRIV_LIMIT, permitted); + SETPPRIV(PRIV_PERMITTED, permitted); + SETPPRIV(PRIV_EFFECTIVE, effective); + SETPPRIV(PRIV_INHERITABLE, inheritable); #undef SETPPRIV priv_freeset(inheritable); From tfheen at varnish-cache.org Wed Oct 26 12:58:55 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:55 +0200 Subject: [3.0] 5046158 Solaris: Test for SO_{RCV,SND}TIMEO needs NET_LIBS Message-ID: commit 504615812ef346309e01071d173848b687eef608 Author: Nils Goroll Date: Fri Mar 11 17:36:54 2011 +0100 Solaris: Test for SO_{RCV,SND}TIMEO needs NET_LIBS diff --git a/configure.ac b/configure.ac index 7e86ed8..34279bb 100644 --- a/configure.ac +++ b/configure.ac @@ -375,11 +375,20 @@ fi AM_MISSING_HAS_RUN AC_CHECK_PROGS(PYTHON, [python3 python3.1 python3.2 python2.7 python2.6 python2.5 python2 python], [AC_MSG_ERROR([Python is needed to build Varnish, please install python.])]) -# Solaris defines SO_{RCV,SND}TIMEO, but does not implement them. +# Older Solaris versions define SO_{RCV,SND}TIMEO, but do not +# implement them. +# # Varnish will build and run without these, but connections will not # time out, which may leave Varnish vulnerable to denail-of-service # attacks which would not be possible on other platforms. +# +# Newer Solaris releases with the Volo framework (Solaris 11, +# Opensolaris starting with onnv_106) do support SO_{RCV,SND}TIMEO +# (see PSARC 2007/587, initially committed into onnv-gate / +# OpenSolaris 8348:4137e18bfaf0 Thu Dec 11 20:04:13 2008) +save_LIBS="${LIBS}" +LIBS="${LIBS} ${NET_LIBS}" AC_CACHE_CHECK([whether SO_RCVTIMEO works], [ac_cv_so_rcvtimeo_works], [AC_RUN_IFELSE( @@ -404,7 +413,10 @@ return 1; if test "$ac_cv_so_rcvtimeo_works" = yes; then AC_DEFINE([SO_RCVTIMEO_WORKS], [1], [Define if SO_RCVTIMEO works]) fi +LIBS="${save_LIBS}" +save_LIBS="${LIBS}" +LIBS="${LIBS} ${NET_LIBS}" AC_CACHE_CHECK([whether SO_SNDTIMEO works], [ac_cv_so_sndtimeo_works], [AC_RUN_IFELSE( @@ -434,6 +446,7 @@ if test "$ac_cv_so_rcvtimeo_works" = no || test "$ac_cv_so_sndtimeo_works" = no; then AC_MSG_WARN([connection timeouts will not work]) fi +LIBS="${save_LIBS}" # Run-time directory VARNISH_STATE_DIR='${localstatedir}/varnish' From tfheen at varnish-cache.org Wed Oct 26 12:58:55 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:55 +0200 Subject: [3.0] 8436484 Just small typofixes Message-ID: commit 8436484ed101991d88de22602d98b79b3b490a21 Author: Ingvar Hagelund Date: Fri Oct 14 00:30:02 2011 +0200 Just small typofixes diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 20c613e..bb019f8 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -372,7 +372,7 @@ fi - Whitespace changes to make rpmlint more happy * Fri Sep 12 2008 Ingvar Hagelund - 2.0-0.9.20080912svn3184 -- Added varnisnsca init script (Colin Hill) +- Added varnisncsa init script (Colin Hill) - Corrected varnishlog init script (Colin Hill) * Tue Sep 09 2008 Ingvar Hagelund - 2.0-0.8.beta1 diff --git a/redhat/varnishncsa.initrc b/redhat/varnishncsa.initrc index ee26376..b23fa48 100644 --- a/redhat/varnishncsa.initrc +++ b/redhat/varnishncsa.initrc @@ -1,6 +1,6 @@ #! /bin/sh # -# varnishncsa Control the Varnish NSCA logging daemon +# varnishncsa Control the Varnish NCSA logging daemon # # chkconfig: - 90 10 # description: Varnish Cache logging daemon @@ -15,7 +15,7 @@ # Default-Start: # Default-Stop: # Short-Description: start and stop varnishncsa -# Description: Varnish Cache NSCA logging daemon +# Description: Varnish Cache NCSA logging daemon ### END INIT INFO # Source function library. From tfheen at varnish-cache.org Wed Oct 26 12:58:56 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:56 +0200 Subject: [3.0] 2f53298 Even more strange error returns on Solaris Message-ID: commit 2f53298df0271815649ea010fdd1a6795b4cad5d Author: Poul-Henning Kamp Date: Fri Oct 14 08:42:04 2011 +0000 Even more strange error returns on Solaris diff --git a/include/libvarnish.h b/include/libvarnish.h index 157a64e..a4fd542 100644 --- a/include/libvarnish.h +++ b/include/libvarnish.h @@ -56,16 +56,24 @@ int SUB_run(struct vsb *sb, sub_func_f *func, void *priv, const char *name, #define VTCP_ADDRBUFSIZE 64 #define VTCP_PORTBUFSIZE 16 +static inline int +VTCP_Check(int a) +{ + if (a == 0) + return (1); + if (errno == ECONNRESET || errno == ENOTCONN) + return (1); #if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__) -/* - * Solaris returns EINVAL if the other end unexepectedly reset the - * connection. This is a bug in Solaris and documented behaviour on NetBSD. - */ -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN \ - || errno == EINVAL) -#else -#define VTCP_Check(a) ((a) == 0 || errno == ECONNRESET || errno == ENOTCONN) + /* + * Solaris returns EINVAL if the other end unexepectedly reset the + * connection. + * This is a bug in Solaris and documented behaviour on NetBSD. + */ + if (errno == EINVAL || errno == ETIMEDOUT) + return (1); #endif + return (0); +} #define VTCP_Assert(a) assert(VTCP_Check(a)) From tfheen at varnish-cache.org Wed Oct 26 12:58:57 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:57 +0200 Subject: [3.0] 0e3fd5b Ensure obj->response is set sensibly for errors Message-ID: commit 0e3fd5b2db1e4ef5503e1a6d498284ca080f697a Author: Kristian Lyngstol Date: Mon Oct 17 13:30:29 2011 +0200 Ensure obj->response is set sensibly for errors The http_PutProtocol() and http_PutResponse() would in the case of workspace overflow leave the headers as NULL and log a SLT_LostHeader. This would make Varnish assert correctly later when writing to the wire, as these are mandated by HTTP. This commit changes them to set the fields to static strings instead ("HTTP/1.1" and "Lost Response") when failing to write them to the workspace. This leaves enough information to complete the protocol in the case of overflow. The patch also increases the synthetic object's workspace from static 1024 to param->http_resp_size. This leaves more (and configurable) room for manipulating the headers of the synthetic object in vcl_error. This whole thing has been a collaboration between Martin and myself. I'll leave it a mystery who wrote what line of code, which part of the comment and contributed what to the test-case. In all fairness, it's not a prefect solution, but a far step closer to one. So it sort of, kinda, more or less, for now, until we get a better solution: Fixes: #1031 Conflicts: bin/varnishd/cache_http.c diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index 39a2104..4d94d88 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -436,13 +436,13 @@ cnt_error(struct sess *sp) w = sp->wrk; if (sp->obj == NULL) { HSH_Prealloc(sp); - /* XXX: 1024 is a pure guess */ EXP_Clr(&w->exp); - sp->obj = STV_NewObject(sp, NULL, 1024, &w->exp, - (uint16_t)params->http_max_hdr); + sp->obj = STV_NewObject(sp, NULL, params->http_resp_size, + &w->exp, (uint16_t)params->http_max_hdr); if (sp->obj == NULL) sp->obj = STV_NewObject(sp, TRANSIENT_STORAGE, - 1024, &w->exp, (uint16_t)params->http_max_hdr); + params->http_resp_size , &w->exp, + (uint16_t)params->http_max_hdr); if (sp->obj == NULL) { sp->doclose = "Out of objects"; sp->director = NULL; diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c index f77ab74..844e71b 100644 --- a/bin/varnishd/cache_http.c +++ b/bin/varnishd/cache_http.c @@ -981,6 +981,9 @@ http_PutProtocol(struct worker *w, int fd, const struct http *to, { http_PutField(w, fd, to, HTTP_HDR_PROTO, protocol); + if (to->hd[HTTP_HDR_PROTO].b == NULL) + http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1"); + Tcheck(to->hd[HTTP_HDR_PROTO]); } void @@ -997,6 +1000,10 @@ http_PutResponse(struct worker *w, int fd, const struct http *to, { http_PutField(w, fd, to, HTTP_HDR_RESPONSE, response); + if (to->hd[HTTP_HDR_RESPONSE].b == NULL) + http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response"); + Tcheck(to->hd[HTTP_HDR_RESPONSE]); + } void diff --git a/bin/varnishtest/tests/r01031.vtc b/bin/varnishtest/tests/r01031.vtc new file mode 100644 index 0000000..435f973 --- /dev/null +++ b/bin/varnishtest/tests/r01031.vtc @@ -0,0 +1,30 @@ +varnishtest "Test overflowing the response through sp->err_reason" + +varnish v1 -vcl { + backend blatti { + .host = "127.0.0.1"; + } + + sub vcl_recv { + error 200 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + } + sub vcl_error { + return(deliver); + } +} -start + +client c1 { + txreq -req GET + rxresp + expect resp.status == 200 + expect resp.msg == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +} -run + +varnish v1 -cliok "param.set http_resp_size 256" + +client c2 { + txreq -req GET + rxresp + expect resp.status == 200 + expect resp.msg == "Lost Response" +} -run From tfheen at varnish-cache.org Wed Oct 26 12:58:57 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:57 +0200 Subject: [3.0] 1369592 Ensure ban lurker sleeps 1.0s on failure Message-ID: commit 1369592ded40e4a0982fe6ba9c50a0bb10992a39 Author: Kristian Lyngstol Date: Mon Oct 17 14:09:11 2011 +0200 Ensure ban lurker sleeps 1.0s on failure As per documentation, the ban lurker sleeps ban_lurker_sleep when it is successful, but on failure it should only sleep 1.0s. No point hammering the ban list every 0.01s if bans aren't even used. Fixes #1030 Conflicts: bin/varnishd/cache_ban.c diff --git a/bin/varnishd/cache_ban.c b/bin/varnishd/cache_ban.c index 4c95592..7fbeffd 100644 --- a/bin/varnishd/cache_ban.c +++ b/bin/varnishd/cache_ban.c @@ -738,7 +738,7 @@ BAN_CheckObject(struct object *o, const struct sess *sp) * Ban tail lurker thread */ -static void +static int ban_lurker_work(const struct sess *sp) { struct ban *b, *bf; @@ -757,21 +757,21 @@ ban_lurker_work(const struct sess *sp) if (bf != NULL) { Lck_Unlock(&ban_mtx); BAN_Free(bf); - return; + return (0); } /* Find the last ban give up, if we have only one */ b = VTAILQ_LAST(&ban_head, banhead_s); if (b == ban_start) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* Find the first object on it, if any */ oc = VTAILQ_FIRST(&b->objcore); if (oc == NULL) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* Try to lock the objhead */ @@ -779,7 +779,7 @@ ban_lurker_work(const struct sess *sp) CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); if (Lck_Trylock(&oh->mtx)) { Lck_Unlock(&ban_mtx); - return; + return (0); } /* @@ -792,7 +792,7 @@ ban_lurker_work(const struct sess *sp) if (oc2 == NULL) { Lck_Unlock(&oh->mtx); Lck_Unlock(&ban_mtx); - return; + return (0); } /* * Grab a reference to the OC and we can let go of the BAN mutex @@ -809,12 +809,13 @@ ban_lurker_work(const struct sess *sp) Lck_Unlock(&oh->mtx); WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->exp.ttl, i); (void)HSH_Deref(sp->wrk, NULL, &o); + return (i); } static void * __match_proto__(bgthread_t) ban_lurker(struct sess *sp, void *priv) { - + int i = 0; (void)priv; while (1) { if (params->ban_lurker_sleep == 0.0) { @@ -822,8 +823,11 @@ ban_lurker(struct sess *sp, void *priv) TIM_sleep(1.0); continue; } - TIM_sleep(params->ban_lurker_sleep); - ban_lurker_work(sp); + if (i != 0) + TIM_sleep(params->ban_lurker_sleep); + else + TIM_sleep(1.0); + i = ban_lurker_work(sp); WSL_Flush(sp->wrk, 0); WRK_SumStat(sp->wrk); } diff --git a/bin/varnishtest/tests/r01030.vtc b/bin/varnishtest/tests/r01030.vtc new file mode 100644 index 0000000..97ef3d7 --- /dev/null +++ b/bin/varnishtest/tests/r01030.vtc @@ -0,0 +1,64 @@ +varnishtest "Test ban_lurker_sleep vs failed ban lurker" + +# The idea here is that the ban lurker should always wait 1 second when it +# can't proceed, as per documentation and original intent. The +# ban_lurker_sleep should not affect sleep-times when the lurker fails. + +server s1 { + rxreq + txresp -status 200 + + rxreq + txresp -status 200 +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.request == "BAN") { + ban("obj.http.url ~ /"); + error 201 "banned"; + } + return (lookup); + } + sub vcl_fetch { + set beresp.http.url = req.url; + } +} -start + +varnish v1 -cliok "param.set ban_lurker_sleep 0.01" +varnish v1 -expect n_ban_obj_test == 0 + +delay 0.01 +client c1 { + txreq -req GET + rxresp + expect resp.status == 200 + + txreq -req BAN + rxresp + expect resp.status == 201 +} -run + +delay 0.1 +varnish v1 -expect n_ban_obj_test == 0 + +delay 1.0 +varnish v1 -expect n_ban_obj_test == 1 + +varnish v1 -cliok "param.set ban_lurker_sleep 5.01" + +client c2 { + txreq -req GET + rxresp + expect resp.status == 200 + + txreq -req BAN + rxresp + expect resp.status == 201 +} -run + +delay 0.1 +varnish v1 -expect n_ban_obj_test == 1 + +delay 1.1 +varnish v1 -expect n_ban_obj_test == 2 From tfheen at varnish-cache.org Wed Oct 26 12:58:58 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:58 +0200 Subject: [3.0] 6d26305 Formally remove error from vcl_deliver VCC Message-ID: commit 6d263051a9ea9bd624401610867f0bd0d006b646 Author: Kristian Lyngstol Date: Mon Oct 17 14:46:54 2011 +0200 Formally remove error from vcl_deliver VCC Note that error wasn't actually working in vcl_deliver, and this just puts VCC in line with the rest of Varnish. Syntax errors are better than assert errors. Re #1027 I'll leave it for later discussion to see if we close #1027, which is technically a feature request now, though a request for a feature we used to have (not sure how well it worked). diff --git a/bin/varnishtest/tests/r01027.vtc b/bin/varnishtest/tests/r01027.vtc new file mode 100644 index 0000000..6c20b00 --- /dev/null +++ b/bin/varnishtest/tests/r01027.vtc @@ -0,0 +1,8 @@ +varnishtest "Test if you can error in vcl_deliver" + +varnish v1 -badvcl { + sub vcl_deliver { + error 201 "ok"; + } +} + diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c index 353a40b..033149b 100644 --- a/lib/libvcl/vcc_action.c +++ b/lib/libvcl/vcc_action.c @@ -327,7 +327,7 @@ static struct action_table { } action_table[] = { { "error", parse_error, VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | - VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER + VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH }, #define VCL_RET_MAC(l, U, B) \ From tfheen at varnish-cache.org Wed Oct 26 12:58:58 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:58 +0200 Subject: [3.0] a97637e Update parameters for 3.0.2 Message-ID: commit a97637e3c8dd8c2a5fc0cc09a775129374858122 Author: Tollef Fog Heen Date: Fri Oct 21 10:47:52 2011 +0200 Update parameters for 3.0.2 diff --git a/doc/sphinx/reference/params.rst b/doc/sphinx/reference/params.rst index f161596..71a938e 100644 --- a/doc/sphinx/reference/params.rst +++ b/doc/sphinx/reference/params.rst @@ -128,7 +128,6 @@ diag_bitmap 0x00020000 - synchronous start of persistence. 0x00040000 - release VCL early. 0x80000000 - do edge-detection on digest. - Use 0x notation and do the bitor in your head :-) esi_syntax @@ -141,7 +140,6 @@ esi_syntax 0x00000002 - Ignore non-esi elements 0x00000004 - Emit parsing debug records 0x00000008 - Force-split parser input (debugging) - Use 0x notation and do the bitor in your head :-) expiry_sleep @@ -205,7 +203,6 @@ gzip_tmp_space 0 - malloc 1 - session workspace 2 - thread workspace - If you have much gzip/gunzip activity, it may be an advantage to use workspace for these allocations to reduce malloc activity. Be aware that gzip needs 256+KB and gunzip needs 32+KB of workspace (64+KB if ESI processing). gzip_window @@ -219,7 +216,7 @@ http_gzip_support - Default: on - Flags: experimental - Enable gzip support. When enabled Varnish will compress uncompressed objects before they are stored in the cache. If a client does not support gzip encoding Varnish will uncompress compressed objects on demand. Varnish will also rewrite the Accept-Encoding header of clients indicating support for gzip to: + Enable gzip support. When enabled Varnish will compress uncompressed objects before they are stored in the cache. If a client does not support gzip encoding Varnish will uncompress compressed objects on demand. Varnish will also rewrite the Accept-Encoding header of clients indicating support for gzip to:: Accept-Encoding: gzip @@ -241,7 +238,7 @@ http_range_support http_req_hdr_len - Units: bytes - - Default: 4096 + - Default: 8192 Maximum length of any HTTP client request header we will allow. The limit is inclusive its continuation lines. @@ -254,7 +251,7 @@ http_req_size http_resp_hdr_len - Units: bytes - - Default: 4096 + - Default: 8192 Maximum length of any HTTP backend response header we will allow. The limit is inclusive its continuation lines. @@ -314,7 +311,7 @@ max_restarts nuke_limit - Units: allocations - - Default: 10 + - Default: 50 - Flags: experimental Maximum number of objects we attempt to nuke in orderto make space for a object body. From tfheen at varnish-cache.org Wed Oct 26 12:58:58 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:58 +0200 Subject: [3.0] 8d1ed24 Document 3.0.2 changes Message-ID: commit 8d1ed24b1cd901eff38159e7832f10a81876c433 Author: Tollef Fog Heen Date: Fri Oct 21 10:48:09 2011 +0200 Document 3.0.2 changes diff --git a/doc/changes.rst b/doc/changes.rst index c3603df..8659f2e 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,4 +1,34 @@ ================================ +Changes from 3.0.2 rc 1 to 3.0.2 +================================ + +Varnishd +-------- + +- Make the size of the synthetic object workspace equal to + `http_resp_size` and add workaround to avoid a crash when setting + too long response strings for synthetic objects. + +- Ensure the ban lurker always sleeps the advertised 1 second when it + does not have anything to do. + +- Remove error from `vcl_deliver`. Previously this would assert while + it will now give a syntax error. + +varnishncsa +----------- + +- Add default values for some fields when logging incomplete records + and document the default values. + +Other +----- + +- Documentation updates + +- Some Solaris portability updates. + +================================ Changes from 3.0.1 to 3.0.2 rc 1 ================================ From tfheen at varnish-cache.org Wed Oct 26 12:58:59 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:59 +0200 Subject: [3.0] 670f56f Build without rst2man and rst2html Message-ID: commit 670f56f3dadf7ae6d086302e63d834fbd9056129 Author: Tollef Fog Heen Date: Wed Oct 26 14:11:39 2011 +0200 Build without rst2man and rst2html diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 94088d4..5ecb85f 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -88,9 +88,9 @@ cp bin/varnishd/default.vcl etc/zope-plone.vcl examples # Remove "--disable static" if you want to build static libraries # jemalloc is not compatible with Red Hat's ppc64 RHEL kernel :-( %ifarch ppc64 ppc - %configure --disable-static --localstatedir=/var/lib --without-jemalloc + %configure --disable-static --localstatedir=/var/lib --without-jemalloc --without-rst2man --without-rst2html %else - %configure --disable-static --localstatedir=/var/lib + %configure --disable-static --localstatedir=/var/lib --without-rst2man --without-rst2html %endif # We have to remove rpath - not allowed in Fedora From tfheen at varnish-cache.org Wed Oct 26 12:58:58 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:58 +0200 Subject: [3.0] 55e70a4 Make it possible to disable checks for rst2man and rst2html Message-ID: commit 55e70a4a651d061f50b030888b3c677b4bdb97df Author: Tollef Fog Heen Date: Mon Oct 24 09:24:36 2011 +0200 Make it possible to disable checks for rst2man and rst2html diff --git a/configure.ac b/configure.ac index 46df5ad..1f58e00 100644 --- a/configure.ac +++ b/configure.ac @@ -50,16 +50,24 @@ if test "x$XSLTPROC" = "xno"; then AC_MSG_WARN([xsltproc not found ? not building documentation]) fi AM_CONDITIONAL(HAVE_XSLTPROC,[test "x$XSLTPROC" != "xno"]) -AC_CHECK_PROGS(RST2MAN, [rst2man rst2man.py], "no") -if test "x$RST2MAN" = "xno"; then - AC_MSG_WARN([rst2man not found ? not building man pages]) -fi +AC_ARG_WITH([rst2man], + AS_HELP_STRING([--with-rst2man=PATH], + [Location of rst2man (auto)]), + [RST2MAN="$withval"], + [AC_CHECK_PROGS(RST2MAN, [rst2man rst2man.py], "no") + if test "x$RST2MAN" = "xno"; then + AC_MSG_WARN([rst2man not found ? not building man pages]) + fi]) AM_CONDITIONAL(HAVE_RST2MAN,[test "x$RST2MAN" != "xno"]) -AC_CHECK_PROGS(RST2HTML, [rst2html rst2html.py], "no") -if test "x$RST2HTML" = "xno"; then - AC_MSG_WARN([rst2html not found ? not building changelog]) -fi +AC_ARG_WITH([rst2html], + AS_HELP_STRING([--with-rst2html=PATH], + [Location of rst2html (auto)]), + [RST2HTML="$withval"], + [AC_CHECK_PROGS(RST2HTML, [rst2html rst2html.py], "no") + if test "x$RST2HTML" = "xno"; then + AC_MSG_WARN([rst2html not found ? not building changelog]) + fi]) AM_CONDITIONAL(HAVE_RST2HTML,[test "x$RST2HTML" != "xno"]) # Checks for libraries. From tfheen at varnish-cache.org Wed Oct 26 12:58:58 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Wed, 26 Oct 2011 14:58:58 +0200 Subject: [3.0] 3942f5e Update version numbers Message-ID: commit 3942f5e1d2539574ef66ca2fb7e6730c5e38a548 Author: Tollef Fog Heen Date: Fri Oct 21 10:48:25 2011 +0200 Update version numbers diff --git a/configure.ac b/configure.ac index 34279bb..46df5ad 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2011 Varnish Software AS]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [3.0.2-rc1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [3.0.2], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/varnishapi.h) AM_CONFIG_HEADER(config.h) diff --git a/redhat/varnish.spec b/redhat/varnish.spec index bb019f8..94088d4 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,15 +1,13 @@ -%define v_rc rc1 -%define vd_rc %{?v_rc:-%{?v_rc}} - +#% define v_rc "" Summary: High-performance HTTP accelerator Name: varnish Version: 3.0.2 -Release: 0.%{?v_rc}%{?dist} +Release: 1%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ #Source0: http://repo.varnish-cache.org/source/%{name}-%{version}.tar.gz -Source0: %{name}-%{version}%{?vd_rc}.tar.gz +Source0: %{name}-%{version}%{?v_rc:-%{v_rc}}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # To build from git, start with a make dist, see redhat/README.redhat # You will need at least automake autoconf libtool python-docutils @@ -75,7 +73,7 @@ Documentation files for %name %prep #%setup -q -%setup -q -n varnish-%{version}%{?vd_rc} +%setup -q -n varnish-%{version}%{?v_rc:-%{?v_rc}} mkdir examples cp bin/varnishd/default.vcl etc/zope-plone.vcl examples From tfheen at varnish-cache.org Mon Oct 31 07:59:21 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 31 Oct 2011 08:59:21 +0100 Subject: [master] 10c81c1 Move XML changes files into changes.rst Message-ID: commit 10c81c11a60e13dbf6da32e0f7f8ba9c82f94499 Author: Tollef Fog Heen Date: Mon Oct 31 08:58:24 2011 +0100 Move XML changes files into changes.rst Convert all the old changelogs to restructured text, drop xsltproc from the build system and adjust documentation appropriately. diff --git a/configure.ac b/configure.ac index 4591148..ebea42b 100644 --- a/configure.ac +++ b/configure.ac @@ -45,11 +45,6 @@ CC="$PTHREAD_CC" AC_PROG_INSTALL AC_PROG_LIBTOOL AC_PROG_MAKE_SET -AC_CHECK_PROGS(XSLTPROC, [xsltproc], "no") -if test "x$XSLTPROC" = "xno"; then - AC_MSG_WARN([xsltproc not found ? not building documentation]) -fi -AM_CONDITIONAL(HAVE_XSLTPROC,[test "x$XSLTPROC" != "xno"]) AC_ARG_WITH([rst2man], AS_HELP_STRING([--with-rst2man=PATH], [Location of rst2man (auto)]), diff --git a/doc/Makefile.am b/doc/Makefile.am index 58d9dc7..cfd0fb5 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,64 +1,6 @@ # -CHANGELOGS = \ - changes-2.1.5.html \ - changes-2.1.4.html \ - changes-2.1.3.html \ - changes-2.1.2.html \ - changes-2.1.1.html \ - changes-2.1.0.html \ - changes-2.0.6.html \ - changes-2.0.5.html \ - changes-2.0.4.html \ - changes-2.0.3.html \ - changes-2.0.2.html \ - changes-2.0.1.html \ - changes-2.0.html \ - changes-1.1.2.html \ - changes-1.1.1.html \ - changes-1.1.html \ - changes-1.0.4.html - -XML = \ - changes-2.1.4-2.1.5.xml \ - changes-2.1.3-2.1.4.xml \ - changes-2.1.2-2.1.3.xml \ - changes-2.1.1-2.1.2.xml \ - changes-2.1.0-2.1.1.xml \ - changes-2.0.6-2.1.0.xml \ - changes-2.0.5-2.0.6.xml \ - changes-2.0.4-2.0.5.xml \ - changes-2.0.3-2.0.4.xml \ - changes-2.0.2-2.0.3.xml \ - changes-2.0.1-2.0.2.xml \ - changes-2.0-2.0.1.xml \ - changes-1.1.2-2.0.xml \ - changes-1.1.1-1.1.2.xml \ - changes-1.1-1.1.1.xml \ - changes-1.0.4-1.1.xml \ - changes-1.0.3-1.0.4.xml \ - ${CHANGELOGS:.html=.xml} - -if HAVE_XSLTPROC -all: ${CHANGELOGS} -endif - -EXTRA_DIST = ${CHANGELOGS} ${XML} \ - changes.css changes-html.xsl \ - changes.rst changes.html - -CLEANFILES = ${CHANGELOGS} -SUFFIXES = .xml .html - -.xml.html: -if HAVE_XSLTPROC - ${XSLTPROC} --xinclude -o $@ $< -else - @echo "========================================" - @echo "You need xsltproc installed to make dist" - @echo "========================================" - @false -endif +EXTRA_DIST = changes.rst changes.html changes.html: changes.rst if HAVE_RST2HTML @@ -70,7 +12,4 @@ else @false endif - -${CHANGELOGS}: changes-html.xsl - SUBDIRS = sphinx diff --git a/doc/changes-1.0.3-1.0.4.xml b/doc/changes-1.0.3-1.0.4.xml deleted file mode 100644 index 8cd010e..0000000 --- a/doc/changes-1.0.3-1.0.4.xml +++ /dev/null @@ -1,218 +0,0 @@ - - -]> - - - - varnishd - - - The request workflow has been redesigned to simplify - request processing and eliminate code duplication. All - codepaths which need to speak HTTP now share a single - implementation of the protocol. Some new VCL hooks have been - added, though they aren't much use yet. The only real - user-visible change should be that Varnish now handles - persistent backend connections correctly (see ). - - - - Support for multiple listen addresses has been - added. - - - - An "include" facility has been added to VCL, allowing - VCL code to pull in code fragments from multiple files. - - - - Multiple definitions of the same VCL function are now - concatenated into one in the order in which they appear in the - source. This simplifies the mechanism for falling back to the - built-in default for cases which aren't handled in custom - code, and facilitates modularization. - - - - The code used to format management command arguments - before passing them on to the child process would - underestimate the amount of space needed to hold each argument - once quotes and special characters were properly escaped, - resulting in a buffer overflow. This has been - corrected. - - - - The VCL compiler has been overhauled. Several memory - leaks have been plugged, and error detection and reporting has - been improved throughout. Parts of the compiler have been - refactored to simplify future extension of the - language. - - - - A bug in the VCL compiler which resulted in incorrect - parsing of the decrement (-=) operator has been - fixed. - - - - A new -C command-line option has been added - which causes varnishd to compile the VCL code - (either from a file specified with -f or the - built-in default), print the resulting C code and exit. - - - - When processing a backend response using chunked - encoding, if a chunk header crosses a read buffer boundary, - read additional bytes from the backend connection until the - chunk header is complete. - - - - A new ping_interval run-time parameter - controls how often the management process checks that the - worker process is alive. - - - - A bug which would cause the worker process to - dereference a NULL pointer and crash if the - backend did not respond has been fixed. - - - - In some cases, such as when they are used by AJAX - applications to circumvent Internet Explorer's over-eager disk - cache, it may be desirable to cache POST - requests. However, the code path responsible for delivering - objects from cache would only transmit the response body when - replying to a GET request. This has been - extended to also apply to POST. - - This should be revisited at a later date to allow VCL - code to control whether the body is delivered. - - - - Varnish now respects Cache-control: - s-maxage, and prefers it to Cache-control: - max-age if both are present. - - This should be revisited at a later date to allow VCL - code to control which headers are used and how they are - interpreted. - - - - When loading a new VCL script, the management process - will now load the compiled object to verify that it links - correctly before instructing the worker process to load - it. - - - - A new -P command-line options has been - added which causes varnishd to create a PID - file. - - - - The sendfile_threshold run-time parameter's - default value has been set to infinity after a variety of - sendfile()-related bugs were discovered on - several platforms. - - - - - varnishlog - - - When grouping log entries by request, - varnishlog attempts to collapse the log entry for - a call to a VCL function with the log entry for the - corresponding return from VCL. When two VCL calls were made - in succession, varnishlog would incorrectly omit - the newline between the two calls (see ). - - - - New -D and -P command-line - options have been added to daemonize and create a pidfile, - respectively. - - - - The flag that is raised upon reception of a - SIGHUP has been marked volatile so it - will not be optimized away by the compiler. - - - - - varnishncsa - - - The formatting callback has been largely rewritten for - clarity, robustness and efficiency. - - If a request included a Host: header, - construct and output an absolute URL. This makes - varnishncsa output from servers which handle - multiple virtual hosts far more useful. - - - - The flag that is raised upon reception of a - SIGHUP has been marked volatile so it - will not be optimized away by the compiler. - - - - - Documentation - - - The documentation—especially the VCL - documentation—has been greatly extended and improved. - - - - - Build system - - - The name and location of the curses or - ncurses library is now correctly detected by the - configure script instead of being hardcoded into - affected Makefiles. This allows Varnish to build correctly on - a wider range of platforms. - - - - Compatibility shims for clock_gettime() are - now correctly applied where needed, allowing Varnish to build - on MacOS X. - - - - The autogen.sh script will now correctly - detect and warn about automake versions which are - known not to work correctly. - - - - - diff --git a/doc/changes-1.0.4-1.1.xml b/doc/changes-1.0.4-1.1.xml deleted file mode 100644 index 7bbfc47..0000000 --- a/doc/changes-1.0.4-1.1.xml +++ /dev/null @@ -1,267 +0,0 @@ - - -]> - - - - varnishd - - - Readability of the C source code generated from VCL code - has been improved. - - - - Equality (==) and inequality - (!=) operators have been implemented for IP - addresses (which previously could only be compared using - ACLs). - - - - The address of the listening socket on which the client - connection was received is now available to VCL as the - server.ip variable. - - - - Each object's hash key is now computed based on a string - which is available to VCL as req.hash. A VCL hook - named vcl_hash has been added to allow VCL scripts - to control hash generation (for instance, whether or not to - include the value of the Host: header in the - hash). - - - - The setup code for listening sockets has been modified to - detect and handle situations where a host name resolves to - multiple IP addresses. It will now attempt to bind to each IP - address separately, and report a failure only if none of them - worked. - - - - Network or protocol errors that occur while retrieving an - object from a backend server now result in a synthetic error - page being inserted into the cache with a 30-second TTL. This - should help avoid driving an overburdened backend server into - the ground by repeatedly requesting the same object. - - - - The child process will now drop root privileges - immediately upon startup. The user and group to use are - specified with the user and group - run-time parameters, which default to nobody and - nogroup, respectively. Other changes have been - made in an effort to increase the isolation between parent and - child, and reduce the impact of a compromise of the child - process. - - - - Objects which are received from the backend with a - Vary: header are now stored separately according to - the values of the headers specified in Vary:. This - allows Varnish to correctly cache e.g. compressed and - uncompressed versions of the same object. - - - - Each Varnish instance now has a name, which by default is - the host name of the machine it runs on, but can be any string - that would be valid as a relative or absolute directory name. - It is used to construct the name of a directory in which the - server state as well as all temporary files are stored. This - makes it possible to run multiple Varnish instances on the same - machine without conflict. - - - - When invoked with the -C option, - varnishd will now not just translate the VCL code - to C, but also compile the C code and attempt to load the - resulting shared object. - - - - Attempts by VCL code to reference a variable outside its - scope or to assign a value to a read-only variable will now - result in compile-time rather than run-time errors. - - - - The new command-line option -F will make - varnishd run in the foreground, without enabling - debugging. - - - - New VCL variables have been introduced to allow inspection - and manipulation of the request sent to the backend - (bereq.request, bereq.url, - bereq.proto and bereq.http) and the - response to the client (resp.proto, - resp.status, resp.response and - resp.http). - - - - Statistics from the storage code (including the amount of - data and free space in the cache) are now available to - varnishstat and other statistics-gathering - tools. - - - - Objects are now kept on an LRU list which is kept loosely - up-to-date (to within a few seconds). When cache runs out, the - objects at the tail end of the LRU list are discarded one by one - until there is enough space for the freshly requested object(s). - A VCL hook, vcl_discard, is allowed to inspect each - object and determine its fate by returning either - keep or discard. - - - - A new VCL hook, vcl_deliver, provides a - chance to adjust the response before it is sent to the - client. - - - - A new management command, vcl.show, displays - the VCL source code of any loaded configuration. - - - - A new VCL variable, now, provides VCL scripts - with the current time in seconds since the epoch. - - - - A new VCL variable, obj.lastuse, reflects the - time in seconds since the object in question was last - used. - - - - VCL scripts can now add an HTTP header (or modify the - value of an existing one) by assigning a value to the - corresponding variable, and strip an HTTP header by using the - remove keyword. - - - - VCL scripts can now modify the HTTP status code of cached - objects (obj.status) and responses - (resp.status) - - - - Numeric and other non-textual variables in VCL can now be - assigned to textual variables; they will be converted as - needed. - - - - VCL scripts can now apply regular expression substitutions - to textual variables using the regsub - function. - - - - A new management command, status, returns the - state of the child. - - - - Varnish will now build and run on Mac OS X. - - - - - varnishadm - - - This is a new utility which sends a single command to a - Varnish server's management port and prints the result to - stdout, greatly simplifying the use of the - management port from scripts. - - - - - varnishhist - - - The user interface has been greatly improved; the - histogram will be automatically rescaled and redrawn when the - window size changes, and it is updated regularly rather than at - a rate dependent on the amount of log data gathered. In - addition, the name of the Varnish instance being watched is - displayed in the upper right corner. - - - - - varnishncsa - - - In addition to client traffic, varnishncsa - can now also process log data from backend traffic. - - - - A bug that would cause varnishncsa to - segfault when it encountered an empty HTTP header in the log - file has been fixed. - - - - - varnishreplay - - - This new utility will attempt to recreate the HTTP traffic - which resulted in the raw Varnish log data which it is - fed. - - - - - varnishstat - - - Don't print lifetime averages when it doesn't make any - sense—for instance, there is no point in dividing the - amount in bytes of free cache space by the lifetime in seconds - of the varnishd process. - - - - The user interface has been greatly improved; - varnishstat will no longer print more than fits in - the terminal, and will respond correctly to window resize - events. The output produced in one-shot mode has been modified - to include symbolic names for each entry. In addition, the name - of the Varnish instance being watched is displayed in the upper - right corner in curses mode. - - - - - varnishtop - - - The user interface has been greatly improved; - varnishtop will now respond correctly to window - resize events, and one-shot mode (-1) actually - works. In addition, the name of the Varnish instance being - watched is displayed in the upper right corner in curses - mode. - - - diff --git a/doc/changes-1.0.4.xml b/doc/changes-1.0.4.xml deleted file mode 100644 index 739b1bd..0000000 --- a/doc/changes-1.0.4.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - -]> - - - Varnish - 1.0.4 - - - - - - - diff --git a/doc/changes-1.1-1.1.1.xml b/doc/changes-1.1-1.1.1.xml deleted file mode 100644 index 78d6648..0000000 --- a/doc/changes-1.1-1.1.1.xml +++ /dev/null @@ -1,136 +0,0 @@ - - -]> - - - - varnishd - - - The code required to allow VCL to read - obj.status, which had accidentally been left out, - has now been added. - - - - Varnish will now always include a Connection: - header in its reply to the client, to avoid possible - misunderstandings. - - - - A bug that triggered an assertion failure when generating - synthetic error documents has been corrected. - - - - A new VCL function, purge_url, provides the - same functionality as the url.purge management - command. - - - - Previously, Varnish assumed that the response body should - be sent only if the request method was GET. This - was a problem for custom request methods (such as - PURGE), so the logic has been changed to always - send the response body except in the specific case of a - HEAD request. - - - - Changes to run-time parameters are now correctly - propagated to the child process. - - - - Due to the way run-time parameters are initialized at - startup, varnishd previously required the - nobody user and the nogroup group to - exist even if a different user and group were specified on the - command line. This has been corrected. - - - - Under certain conditions, the VCL compiler would carry on - after a syntax error instead of exiting after reporting the - error. This has been corrected. - - - - The manner in which the hash string is assembled has been - modified to reduce memory usage and memory-to-memory - copying. - - - - Before calling vcl_miss, Varnish assembles a - tentative request object for the backend request which will - usually follow. This object would be leaked if - vcl_miss returned anything else than - fetch. This has been corrected. - - - - The code necessary to handle an error return - from vcl_fetch and vcl_deliver had - inadvertantly been left out. This has been corrected. - - - - Varnish no longer prints a spurious "child died" message - (the result of reaping the compiler process) after compiling a - new VCL configuration. - - - - Under some circumstances, due to an error in the workspace - management code, Varnish would lose the "tail" of a request, - i.e. the part of the request that has been received from the - client but not yet processed. The most obvious symptom of this - was that POST requests would work with some browsers but not - others, depending on details of the browser's HTTP - implementation. This has been corrected. - - - - On some platforms, due to incorrect assumptions in the CLI - code, the management process would crash while processing - commands received over the management port. This has been - corrected. - - - - - Build system - - - The top-level Makefile will now honor - $DESTDIR when creating the state directory. - - - - The Debian and RedHat packages are now split into three - (main / lib / devel) as is customary. - - - - A number of compile-time and run-time portability issues - have been addressed. - - - - The autogen.sh script had workarounds for - problems with the GNU autotools on FreeBSD; these are no longer - needed and have been removed. - - - - The libcompat library has been renamed to - libvarnishcompat and is now dynamic rather than - static. This simplifies the build process and resolves an issue - with the Mac OS X linker. - - - diff --git a/doc/changes-1.1.1-1.1.2.xml b/doc/changes-1.1.1-1.1.2.xml deleted file mode 100644 index 5f59902..0000000 --- a/doc/changes-1.1.1-1.1.2.xml +++ /dev/null @@ -1,157 +0,0 @@ - - -]> - - - - varnishd - - - When switching to a new VCL configuration, a race - condition exists which may cause Varnish to reference a backend - which no longer exists (see ). This race - condition has not been entirely eliminated, but it should occur - less frequently. - - - - When dropping a TCP session before any requests were - processed, an assertion would be triggered due to an - uninitialized timestamp (see ). The - timestamp is now correctly initialized. - - - - Varnish will now correctly generate a Date: - header for every response instead of copying the one it got from - the backend (see ). - - - - Comparisons in VCL which involve a non-existent string - (usually a header which is not present in the request or object - being processed) would cause a NULL pointer dereference; now the - comparison will simply fail. - - - - A bug in the VCL compiler which would cause a double-free - when processing include directives has been - fixed. - - - - A resource leak in the worker thread management code has - been fixed. - - - - When connecting to a backend, Varnish will usually get the - address from a cache. When the cache is refreshed, existing - connections may end up with a reference to an address structure - which no longer exists, resulting in a crash. This race - condition has been somewhat mitigated, but not entirely - eliminated (see .) - - - - Varnish will now pass the correct protocol version in pipe - mode: the backend will get what the client sent, and vice - versa. - - - - The core of the pipe mode code has been rewritten to - increase robustness and eliminate spurious error messages when - either end closes the connection in a manner Varnish did not - anticipate. - - - - A memory leak in the backend code has been plugged. - - - - When using the kqueue acceptor, if a client - shuts down the request side of the connection (as many clients - do after sending their final request), it was possible for the - acceptor code to receive the EOF event and recycle - the session while the last request was still being serviced, - resulting in a assertion failure and a crash when the worker - thread later tried to delete the session. This should no longer - happen (see .) - - - - A mismatch between the recorded length of a cached object - and the amount of data actually present in cache for that object - can occasionally occur (see .) This has been - partially fixed, but may still occur for error pages generated - by Varnish when a problem arises while retrieving an object from - the backend. - - - - Some socket-related system calls may return unexpected - error codes when operating on a TCP connection that has been - shut down at the other end. These error codes would previously - cause assertion failures, but are now recognized as harmless - conditions. - - - - - varnishhist - - - Pressing 0 though 9 while - varnishhist is running will change the refresh - interval to the corresponding power of two, in seconds. - - - - - varnishncsa - - - The varnishncsa tool can now daemonize and - write a PID file like varnishlog, using the same - command-line options. It will also reopen its output upon receipt - of a SIGHUP if invoked with -w. - - - - - varnishstat - - - Pressing 0 though 9 while - varnishstat is running will change the refresh - interval to the corresponding power of two, in seconds. - - - - - Build system - - - Varnish's <queue.h> has been modified - to avoid conflicts with <sys/queue.h> on - platforms where the latter is included indirectly through system - headers. - - - - Several steps have been taken towards Solaris - support, but this is not yet complete. - - - - When configure was run without an explicit - prefix, Varnish's idea of the default state directory would be - garbage and a state directory would have to be specified - manually with -n. This has been corrected. - - - diff --git a/doc/changes-1.1.1.xml b/doc/changes-1.1.1.xml deleted file mode 100644 index 784249e..0000000 --- a/doc/changes-1.1.1.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 1.1.1 - - - diff --git a/doc/changes-1.1.2-2.0.xml b/doc/changes-1.1.2-2.0.xml deleted file mode 100644 index 1b56acb..0000000 --- a/doc/changes-1.1.2-2.0.xml +++ /dev/null @@ -1,199 +0,0 @@ - - -]> - - - - varnishd - - - Only look for sendfile on platforms where we know how to - use it, which is FreeBSD for now. - - - - Make it possible to adjust the shared memory log size and - bump the size from 8MB to 80MB. - - - - Fix up the handling of request bodies to better match - what RFC2616 mandates. This makes PUT, DELETE, OPTIONS and - TRACE work in addition to POST. - - - - Change how backends are defined, to a constant structural - defintion style. See - http://varnish.projects.linpro.no/wiki/VclSyntaxChanges for the - details. - - - - Add directors, which wrap backends. Currently, there's a - random director and a round-robin director. - - - - Add "grace", which is for how long and object will be - served, even after it has expired. To use this, both the - object's and the request's grace parameter need - to be set. - - - - Manual pages have been updated for new VCL syntax and - varnishd options. - - - - Man pages and other docs have been updated. - - - - The shared memory log file is now locked in memory, so it - should not be paged out to disk. - - - - We now handle Vary correctly, as well as Expect. - - - - ESI include support is implemented. - - - - Make it possible to limit how much memory the malloc uses. - - - - Solaris is now supported. - - - - There is now a regsuball function, which - works like regsub except it replaces all - occurences of the regex, not just the first. - - - - Backend and director declarations can have - a .connect_timeout parameter, which tells us how - long to wait for a successful connection. - - - - It is now possible to select the acceptor to use by - changing the acceptor parameter. - - - - Backends can have probes associated with them, which can - be checked with req.backend.health in VCL as well as - being handled by directors which do load-balancing. - - - - Support larger-than-2GB files also on 32 bit hosts. - Please note that this does not mean we can support caches - bigger than 2GB, it just means logfiles and similar can be - bigger. - - - - In some cases, we would remove the wrong header when we - were stripping Content-Transfer-Encoding headers from a - request. This has been fixed. - - - - Backends can have a .max_connections - associated with them. - - - - On Linux, we need to set the dumpable bit on the child if - we want core dumps. Make sure it's set. - - - - Doing purge.hash() with an empty string - would cause us to dump core. Fixed so we don't do that any - more. - - - - We ran into a problem with glibc's malloc on Linux where - it seemed like it failed to ever give memory back to the OS, - causing the system to swap. We have now switched to jemalloc - which appears not to have this problem. - - - - max_restarts was never checked, so we always - ended up running out of workspace. Now, vcl_error - is called when we reach max_restarts. - - - - varnishtest - - - varnishtest is a tool to do correctness tests - of varnishd. The test suite is run by using make - check. - - - - - varnishtop - - - We now set the field widths dynamically based on the size - of the terminal and the name of the longest field. - - - - - varnishstat - - - varnishstat -1 now displays the uptime too. - - - - - varnishncsa - - - varnishncsa now does fflush after each - write. This makes tail -f work correctly, as well - as avoiding broken lines in the log file. - - - - It is possible to get varnishncsa to output - the X-Forwarded-For instead of the client IP by - passing -f to it. - - - - - Build system - - - Various sanity checks have been added - to configure, it now complains about no ncurses or - if SO_RCVTIMEO or SO_SNDTIMEO are non-functional. It also - aborts if there's no working acceptor mechanism - - - - The C compiler invocation is decided by the configure - script and can now be overridden by passing VCC_CC - when running configure. - - - diff --git a/doc/changes-1.1.2.xml b/doc/changes-1.1.2.xml deleted file mode 100644 index e629003..0000000 --- a/doc/changes-1.1.2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 1.1.2 - - - diff --git a/doc/changes-1.1.xml b/doc/changes-1.1.xml deleted file mode 100644 index a1b1c38..0000000 --- a/doc/changes-1.1.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 1.1 - - - diff --git a/doc/changes-2.0-2.0.1.xml b/doc/changes-2.0-2.0.1.xml deleted file mode 100644 index 39422ab..0000000 --- a/doc/changes-2.0-2.0.1.xml +++ /dev/null @@ -1,29 +0,0 @@ - - -]> - - - - varnishd - - - When receiving a garbled HTTP - request, varnishd would sometimes crash. This has - been fixed. - - - - There was an off-by-one error in the ACL compilation. - Now fixed. - - - - - Red Hat spec file - - - A typo in the spec file made the .rpm file names wrong. - - - diff --git a/doc/changes-2.0.1-2.0.2.xml b/doc/changes-2.0.1-2.0.2.xml deleted file mode 100644 index 51e5627..0000000 --- a/doc/changes-2.0.1-2.0.2.xml +++ /dev/null @@ -1,25 +0,0 @@ - - -]> - - - - varnishd - - - In high-load situations, when using - ESI, varnishd would sometimes mishandle objects and - crash. This has been worked around. - - - - - varnishreplay - - - varnishreplay did not work correctly on - Linux, due to a too small stack. This has now been fixed. - - - diff --git a/doc/changes-2.0.1.xml b/doc/changes-2.0.1.xml deleted file mode 100644 index 9d84398..0000000 --- a/doc/changes-2.0.1.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.1 - - - diff --git a/doc/changes-2.0.2-2.0.3.xml b/doc/changes-2.0.2-2.0.3.xml deleted file mode 100644 index 1c0737a..0000000 --- a/doc/changes-2.0.2-2.0.3.xml +++ /dev/null @@ -1,225 +0,0 @@ - - -]> - - - - varnishd - - - Handle If-Modified-Since and ESI sub-objects better, - fixing a problem where we sometimes neglected to insert - included objects. - - - - restart in vcl_hit is now supported. - - - - Setting the TTL of an object to 0 seconds would sometimes - cause it to be delivered for up to one second - epsilon. This - has been corrected and we should now never deliver those - objects to other clients. - - - - The malloc storage backend now prints the maximum storage - size, just like the file backend. - - - - Various small documentation bugs have been fixed. - - - - Varnish did not set a default interval for backend - probes, causing it to poll the backend continuously. This has - been corrected. - - - - Allow "true" and "false" when setting boolean parameters, - in addition to on/off, enable/disable and yes/no. - - - - Default to always talking HTTP 1.1 with the backend. - - - - Varnish did not make sure the file it was loading was a - regular file. This could cause Varnish to crash if it was - asked to load a directory or other non-regular file. We now - check that the file is a regular file before loading it. - - - - The binary heap used for expiry processing had - scalability problems. Work around this by using stripes of a - fixed size, which should make this scale better, particularly - when starting up and having lots of objects. - - - - When we imported the jemalloc library into - the Varnish tree, it did not compile without warnings. This - has now been fixed. - - - - Varnish took a very long time to detect that the backend - did not respond. To remedy this, we now have read timeouts in - addition to the connect timeout. Both - the first_byte_timeout and - the between_bytes_timeout defaults to 60 seconds. - The connect timeout is no longer in milliseconds, but rather in - seconds. - - - - Previously, the VCL to C conversion as well as the - invocation of the C compiler was done in the management - process. This is now done in a separate sub-process. This - prevents any bugs in the VCL compiler from affecting the - management process. - - - - Chunked encoding headers were counted in the statistics - for header bytes. They no longer are. - - - - ESI processed objects were not counted in the statistics - for body bytes. They now are. - - - - It is now possible to adjust the maximum record length of - log entries in the shmlog by tuning the shm_reclen - parameter. - - - - The management parameters listed in the CLI were not - sorted, which made it hard to find the parameter you were - looking for. They are now sorted, which should make this - easier. - - - - Add a new hashing type, "critbit", which uses a lock-less - tree based lookup algorithm. This is experimental and should - not be enabled in production environments without proper - testing. - - - - The session workspace had a default size of 8k. It is - now 16k, which should make VCLs where many headers are - processed less prone to panics. - - - - We have seen that people seem to be confused as to which - actions in the different VCL functions return and which ones - don't. Add a new syntax return(action) to make - this more explicit. The old syntax is still supported. - - - - Varnish would return an error if any of the management - IPs listed in the -T parameter could not be - listened to. We now only return an error if none of them can - be listened to. - - - - In the case of the backend or client giving us too many - parameters, we used to just ignore the overflowing headers. - This is problematic if you end up ignoreing Content-Length, - Transfer-Encoding and similar headers. We now give out a 400 - error to the client if it sends us too many and 503 if we get - too many from the backend. - - - - We used panic if we got a too large chunked header. - This behaviour has been changed into just failing the - transaction. - - - - Varnish now supports an extended purge method where it is - possible to do purge req.http.host ~ "web1.com" && req.url ~ "\.png" - and similar. See the documentation for details. - - - - Under heavy load, Varnish would sometimes crash when - trying to update the per-request statistics. This has now been - fixed. - - - - It is now possible to not save the hash string in the - session and object workspace. This will save a lot of memory - on sites with many small objects. Disabling - the purge_hash parameter also disables - the purge.hash facility. - - - - Varnish now supports !~ as a "no match" - regular expression matcher. - - - - In some cases, you could get serialised access to "pass" - objects. We now make it default to the default_ttl value; this - can be overridden in vcl_fetch. - - - - Varnish did not check the syntax of regsub - calls properly. More checking has been added. - - - - If the client closed the connection while Varnish was - processing ESI elements, Varnish would crash while trying to - write the object to the client. We now check if the client has - closed the connection. - - - - The ESI parser had a bug where it would crash if an XML - comment would span storage segments. This has been - fixed. - - - - - VCL Manual page - - - The documentation on how capturing parentheses work was - wrong. This has been corrected. - - - - Grace has now been documented. - - - - - varnishreplay - - - varnishreplay did not work correctly on - Linux, due to a too small stack. This has now been fixed. - - - diff --git a/doc/changes-2.0.2.xml b/doc/changes-2.0.2.xml deleted file mode 100644 index c56ca46..0000000 --- a/doc/changes-2.0.2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.2 - - - diff --git a/doc/changes-2.0.3-2.0.4.xml b/doc/changes-2.0.3-2.0.4.xml deleted file mode 100644 index d7bb0b8..0000000 --- a/doc/changes-2.0.3-2.0.4.xml +++ /dev/null @@ -1,98 +0,0 @@ - - -]> - - - - varnishd - - - Make Varnish more portable by pulling in fixes for - Solaris and NetBSD. - - - - Correct description of -a in the manual page. - - - - Ensure we are compiling in C99 mode. - - - - If error was called with a null reason, we would crash on - Solaris. Make sure this no longer happens. - - - - Varnish used to crash if you asked it to use a - non-existent waiter. This has now been fixed. - - - - Add documentation to the default VCL explaining that - using Connection: close in vcl_close - is generally a good idea. - - - - Add minimal facility for dealing with TELNET option - negotiation by returning WONT to DO and DONT requests. - - - - If the backend is unhealthy, use a graced object if one is - available. - - - - Make server.hostname - and server.identity available to VCL. The latter - can be set with the -i parameter - to varnishd. - - - - Make restart available - from vcl_error. - - - - Previously, only the TTL of an object was considered in - whether it would be marked as cacheable. This has been changed - to take the grace into consideration as well. - - - - Previously, if an included ESI fragment had a zero size, - we would send out a zero-sized chunk which signifies - end-of-transmission. We now ignore zero-sized chunks. - - - - We accidentially slept for far too long when we reached - the maximum number of open file descriptors. This has been - corrected and accept_fd_holdoff now works - correctly. - - - Previously, when ESI processing, we did not look at the - full length, but stopped at the first NULL byte. We no longer - do that, enabling ESI processing of binary data. - - - - - varnishtest - - Make sure system "..." returns successfully to ensure - test failures do not go unnoticed. - - - - Make it possible to send NULL bytes through the testing - framework. - - - diff --git a/doc/changes-2.0.3.xml b/doc/changes-2.0.3.xml deleted file mode 100644 index 69dd9fd..0000000 --- a/doc/changes-2.0.3.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.3 - - - diff --git a/doc/changes-2.0.4-2.0.5.xml b/doc/changes-2.0.4-2.0.5.xml deleted file mode 100644 index ff5e15d..0000000 --- a/doc/changes-2.0.4-2.0.5.xml +++ /dev/null @@ -1,161 +0,0 @@ - - -]> - - - - varnishd - - - Handle object workspace overruns better. - - - - Allow turning off ESI processing per request by using - set req.esi = off. - - - - Tell the kernel that we expect to use the mmap-ed file in - a random fashion. On Linux, this turns off/down readahead and - increases performance. - - - - Make it possible to change the maximum number of HTTP - headers we allow by - passing --with-max-header-fields=NUM rather than - changing the code. - - - - Implement support for HTTP continuation lines. - - - - Change how connections are closed and only use SO_LINGER - for orderly connection closure. This should hopefully make - worker threads less prone to hangups on network problems. - - - - Handle multi-element purges correctly. Previously we - ended up with parse errors when this was done from VCL. - - - - Handle illegal responses from the backend better by - serving a 503 page rather than panic-ing. - - - - When we run into an assertion that is not true, Varnish - would previously dump a little bit of information about itself. - Extend that information with a backtrace. Note that this relies - on the varnish binary being unstripped. - - - - Add a session_max parameter that limits the maximum - number of sessions we keep open before we start dropping new - connections summarily. - - - - Try to consume less memory when doing ESI processing by - properly rolling back used workspace after processing an - object. This should make it possible to - turn sess_workspace quite a bit for users with - ESI-heavy pages. - - - - Turn on session_linger by default. Tests - have shown that session_linger helps a fair bit - with performance. - - - - Rewrite the epoll acceptor for better performance. This - should lead to both higher processing rates and maximum number - of connections on Linux. - - - - Add If-None-Match support, this gives significant - bandwidth savings for users with compliant browsers. - - - - RFC2616 specifies - that ETag, Content-Location, Expires, Cache-Control - and Vary should be emitted when delivering a - response with the 304 response code. - - - - Various fixes which makes Varnish compile and work on AIX. - - - - Turn on TCP_DEFER_ACCEPT on Linux. This should make us - less suspecible to denial of service attacks as well as give us - slightly better performance. - - - - Add an .initial property to the backend - probe specification. This is the number of good probes we - pretend to have seen. The default is one less than .threshold, - which means the first probe will decide if we consider the - backend healthy. - - - - Make it possible to compare strings against other - string-like objects, not just plain strings. This allows you to - compare two headers, for instance. - - - - When support for restart - in vcl_error was added, there was no check to - prevent infinte recursion. This has now been fixed. - - - - - Turn on purge_dups by default. This should make us - consume less memory when there are many bans for the same - pattern added. - - - - Add a new log tag called FetchError which - tries to explain why we could not fetch an object from the - backend. - - - - Change the default srcaddr_ttl to 0. It is - not used by anything and has been removed in the development - version. This will increase performance somewhat. - - - - - - varnishtop - - varnishtop did not handle variable-length log fields - correctly. This is now fixed. - - - - varnishtop previously did not print the name of the tag, - which made it very hard to understand. We now print out the - tag name. - - - diff --git a/doc/changes-2.0.4.xml b/doc/changes-2.0.4.xml deleted file mode 100644 index bf08056..0000000 --- a/doc/changes-2.0.4.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.4 - - - diff --git a/doc/changes-2.0.5-2.0.6.xml b/doc/changes-2.0.5-2.0.6.xml deleted file mode 100644 index 257bd0e..0000000 --- a/doc/changes-2.0.5-2.0.6.xml +++ /dev/null @@ -1,53 +0,0 @@ - - -]> - - - - varnishd - - - 2.0.5 had an off-by-one error in the ESI handling causing - includes to fail a large part of the time. This has now been - fixed. - - - - Try harder to not confuse backends when sending them - backend probes. We half-closed the connection, something some - backends thought meant we had dropped the connection. Stop - doing so, and add the capability for specifying the expected - response code. - - - - In 2.0.5, session lingering was turned on. This caused - statistics to not be counted often enough in some cases. This - has now been fixed. - - - - Avoid triggering an assert if the other end closes the - connection while we are lingering and waiting for another - request from them. - - - - When generating backtraces, prefer the built-in backtrace - function if such exists. This fixes a problem compiling 2.0.5 - on Solaris. - - - - Make it possible to specify the per-thread stack size. - This might be useful on 32 bit systems with their limited - address space. - - - - Document the -C option - to varnishd. - - - diff --git a/doc/changes-2.0.5.xml b/doc/changes-2.0.5.xml deleted file mode 100644 index 5c6c47a..0000000 --- a/doc/changes-2.0.5.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.5 - - - diff --git a/doc/changes-2.0.6-2.1.0.xml b/doc/changes-2.0.6-2.1.0.xml deleted file mode 100644 index 7ecbd59..0000000 --- a/doc/changes-2.0.6-2.1.0.xml +++ /dev/null @@ -1,316 +0,0 @@ - - -]> - - - - varnishd - - - Persistent storage is now experimentally supported using - the persistent stevedore. It has the same command - line arguments as the file stevedore. - - - - obj.* is now called beresp.* - in vcl_fetch, and obj.* is now - read-only. - - - - The regular expression engine is now PCRE instead of POSIX - regular expressions. - - - - req.* is now available - in vcl_deliver. - - - - Add saint mode where we can attempt to grace an object if - we don't like the backend response for some reason. - - Related, add saintmode_threshold which is the - threshold for the number of objects to be added to the trouble - list before the backend is considered sick. - - - - Add a new hashing method called critbit. This autoscales - and should work better on large object workloads than the - classic hash. Critbit has been made the default hash algorithm. - - - - When closing connections, we experimented with sending RST - to free up load balancers and free up threads more quickly. - This caused some problems with NAT routers and so has been - reverted for now. - - - - Add thread that checks objects against ban list in order - to prevent ban list from growing forever. Note that this - needs purges to be written so they don't depend - on req.*. Enabled by - setting ban_lurker_sleep to a nonzero - value. - - - - The shared memory log file format was limited to maximum - 64k simultaneous connections. This is now a 32 bit field which - removes this limitation. - - - - Remove obj_workspace, this is now sized automatically. - - - - - Rename acceptors to waiters - - - - vcl_prefetch has been removed. It was never - fully implemented. - - - - Add support for authenticating CLI connections. - - - - Add hash director that chooses which backend to use - depending on req.hash. - - - - Add client director that chooses which backend to use - depending on the client's IP address. Note that this ignores - the X-Forwarded-For header. - - - - varnishd now displays a banner by default - when you connect to the CLI. - - - - Increase performance somewhat by moving statistics - gathering into a per-worker structure that is regularly - flushed to the global stats. - - - - Make sure we store the header and body of object together. - This may in some cases improve performance and is needed for - persistence. - - - - Remove client-side address accounting. It was never used - for anything and presented a performance problem. - - - - Add a timestamp to bans, so you can know how old they are. - - - - Quite a few people got confused over the warning about not - being able to lock the shared memory log into RAM, so stop - warning about that. - - - - Change the default CLI timeout to 10 seconds. - - - - We previously forced all inserts into the cache to be GET - requests. This has been changed to allow POST as well in - order to be able to implement purge-on-POST semantics. - - - - The CLI command stats now only lists non-zero - values. - - - - The CLI command stats now only lists non-zero - values. - - - - Use daemon(3) from libcompat on - Darwin. - - - - Remove vcl_discard as it causes too much - complexity and never actually worked particularly well. - - - - Remove vcl_timeout as it causes too much - complexity and never actually worked particularly well. - - - - Update the documentation so it refers - to sess_workspace, not http_workspace. - - - - Document the -i switch - to varnishd as well as - the server.identity - and server.hostname VCL variables. - - - - purge.hash is now deprecated and no longer - shown in help listings. - - - - When processing ESI, replace the five mandatory XML - entities when we encounter them. - - - - Add string representations of time and relative - time. - - - - Add locking for n_vbe_conn to make it stop - underflowing. - - - - When ESI-processing content, check for illegal XML - character entities. - - - - Varnish can now connect its CLI to a remote instance when - starting up, rather than just being connected to. - - - - It is no longer needed to specify the maximum number of - HTTP headers to allow from backends. This is now a run-time - parameter. - - - - The X-Forwarded-For header is now generated - by vcl_recv rather than the C code. - - - - It is now possible to not send all CLI traffic to - syslog. - - - - It is now possible to not send all CLI traffic to - syslog. - - - - In the case of varnish crashing, it now outputs a - identifying string with the OS, OS revision, architecture and - storage parameters together with the backtrace. - - - - Use exponential backoff when we run out of file - descriptors or sessions. - - - - Allow setting backend timeouts to zero. - - - - Count uptime in the shared memory log. - - - - Try to detect the case of two running varnishes with the - same shmlog and storage by writing the master and child process - ids to the shmlog and refusing to start if they are still - running. - - - - Make sure to use EOF mode when serving ESI content to - HTTP/1.0 clients. - - - - Make sure we close the connection if it either - sends Connection: close or it is a HTTP/1.0 - backend that does not send Connection: - keep-alive. - - - - Increase the default session workspace to 64k on 64-bit - systems. - - - - Make the epoll waiter use level triggering, - not edge triggering as edge triggering caused problems on very - busy servers. - - - - Handle unforeseen client disconnections better on Solaris. - - - - Make session lingering apply to new sessions, not just - reused sessions. - - - - varnishstat - - - Make use of the new uptime field in the shared memory log - rather than synthesizing it from the start time. - - - - varnishlog - - - Exit at the end of the file when started - with -d. - - - - - varnishadm - - - varnishadm can now have a timeout when trying - to connect to the running varnishd. - - - - varnishadm now knows how to respond to the - secret from a secured varnishd - - - diff --git a/doc/changes-2.0.6.xml b/doc/changes-2.0.6.xml deleted file mode 100644 index bf742f0..0000000 --- a/doc/changes-2.0.6.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0.6 - - - diff --git a/doc/changes-2.0.xml b/doc/changes-2.0.xml deleted file mode 100644 index a510d76..0000000 --- a/doc/changes-2.0.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.0 - - - diff --git a/doc/changes-2.1.0-2.1.1.xml b/doc/changes-2.1.0-2.1.1.xml deleted file mode 100644 index 3c3a7c9..0000000 --- a/doc/changes-2.1.0-2.1.1.xml +++ /dev/null @@ -1,93 +0,0 @@ - - -]> - - - - varnishd - - - The changelog in 2.1.0 included syntax errors, causing - the generated changelog to be empty. - - - - The help text for default_grace was wrongly - formatted and included a syntax error. This has now been fixed. - - - - varnishd now closes the file descriptor used - to read the management secret file (from the -S - parameter). - - - - The child would previously try to close every valid file - descriptor, something which could cause problems if the file - descriptor ulimit was set too high. We now keep track of all - the file descriptors we open and only close up to that number. - - - - - ESI was partially broken in 2.1.0 due to a bug in the - rollback of session workspace. This has been fixed. - - - - Reject the authcommand rather than crash if - there is no -S parameter given. - - - - Align pointers in allocated objects. This will in theory - make Varnish a tiny bit faster at the expense of slightly more - memory usage. - - - - Ensure the master process process id is updated in the - shared memory log file after we go into the background. - - - - HEAD requests would be converted to GET - requests too early, which affected pass - and pipe. This has been fixed. - - - - Update the documentation to point out that the TTL is no - longer taken into account to decide whether an object is - cacheable or not. - - - - Add support for completely obliterating an object and all - variants of it. Currently, this has to be done using inline C. - - - - Add experimental support for the Range - header. This has to be enabled using the parameter - http_range_support. - - - - The critbit hasher could get into a deadlock - and had a race condition. Both those have now been fixed. - - - - - varnishsizes - - - varnishsizes, which is - like varnishhost, but for the length of objects, - has been added.. - - - diff --git a/doc/changes-2.1.0.xml b/doc/changes-2.1.0.xml deleted file mode 100644 index 73305c5..0000000 --- a/doc/changes-2.1.0.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.1 - - - diff --git a/doc/changes-2.1.1-2.1.2.xml b/doc/changes-2.1.1-2.1.2.xml deleted file mode 100644 index 486d530..0000000 --- a/doc/changes-2.1.1-2.1.2.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -]> - - - - varnishd - - - When adding Range support for 2.1.1, we - accidentially introduced a bug which would append garbage to - objects larger than the chunk size, by default 128k. Browsers - would do the right thing due to Content-Length, but some load - balancers would get very confused. - - - - diff --git a/doc/changes-2.1.1.xml b/doc/changes-2.1.1.xml deleted file mode 100644 index f5a91ba..0000000 --- a/doc/changes-2.1.1.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.1 - - - diff --git a/doc/changes-2.1.2-2.1.3.xml b/doc/changes-2.1.2-2.1.3.xml deleted file mode 100644 index 638bbf4..0000000 --- a/doc/changes-2.1.2-2.1.3.xml +++ /dev/null @@ -1,75 +0,0 @@ - - -]> - - - - varnishd - - - Improve scalability of critbit. - - - - The critbit hash algorithm has now been tightened to make - sure the tree is in a consistent state at all points, and the - time we wait for an object to cool off after it is eligible for - garbage collection has been tweaked. - - - - Add log command to VCL. This emits - a VCL_log entry into the shared memory log. - - - - Only emit Length and ReqEnd log entries if we actually - have an XID. This should get rid of some empty log lines in - varnishncsa. - - - - Destroy directors in a predictable fashion, namely reverse - of creation order. - - - - Fix bug when ESI elements spanned storage elements causing - a panic. - - - - In some cases, the VCL compiler would panic instead of - giving sensible messages. This has now been fixed. - - - - Correct an off-by-one error when the requested range - exceeds the size of an object. - - - - Handle requests for the end of an object correctly. - - - - Allow tabulator characters in the third field of the - first line of HTTP requests - - - - On Solaris, if the remote end sends us an RST, all system - calls related to that socket will return EINVAL. We now handle - this better. - - - - libvarnishapi - - The -X parameter didn't work correctly. This - has been fixed. - - - - diff --git a/doc/changes-2.1.2.xml b/doc/changes-2.1.2.xml deleted file mode 100644 index c34aae6..0000000 --- a/doc/changes-2.1.2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.1.2 - - - diff --git a/doc/changes-2.1.3-2.1.4.xml b/doc/changes-2.1.3-2.1.4.xml deleted file mode 100644 index 775b6bd..0000000 --- a/doc/changes-2.1.3-2.1.4.xml +++ /dev/null @@ -1,170 +0,0 @@ - - -]> - - - varnishd - - An embarrasing typo in the new binary heap layout caused - inflated obj/objcore/objhdr counts and could cause odd problems - when the LRU expunge mechanism was invoked. This has been - fixed. - - - - We now have updated documentation in the reStructuredText - format. Manual pages and reference documentation are both built - from this. - - - - We now include a DNS director which uses DNS for choosing - which backend to route requests to. Please see the - documentation for more details. - - - - If you restarted a request, the HTTP header - X-Forwarded-For would be updated multiple times. - This has been fixed. - - - - If a VCL contained a % sign, and the vcl.show - CLI command was used, varnishd would crash. This has been - fixed. - - - - When doing a pass operation, we would remove the - Content-Length, Age and - Proxy-Auth headers. We are no longer doing - this. - - - - now has a string representation, making it - easier to construct Expires headers in VCL. - - - - In a high traffic environment, we would sometimes reuse a - file descriptor before flushing the logs from a worker thread to - the shared log buffer. This would cause confusion in some of - the tools. This has been fixed by explicitly flushing the log - when a backend connection is closed. - - - - If the communication between the management and the child - process gets out of sync, we have no way to recover. - Previously, varnishd would be confused, but we now - just kill the child and restart it. - - - - If the backend closes the connection on us just as we sent - a request to it, we retry the request. This should solve some - interoperability problems with Apache and the mpm-itk multi - processing module. - - - - varnishd now only provides help output the - current CLI session is authenticated for. - - - - If the backend does not tell us which length indication it - is using, we now assume the resource ends EOF at. - - - - The client director now has a variable - client.identity which is used to choose which - backend should receive a given request. - - - - The Solaris port waiter has been updated, and - other portability fixes for Solaris. - - - - There was a corner case in the close-down processing of pipes, this has now been fixed. - - - - Previously, if we stopped polling a backend which was - sick, it never got marked as healthy. This has now been - changed. - - - - It is now possible to specify ports as part of the .host field in VCL. - - - - The synthetic counters were not locked properly, and so - the sms_ counters could underflow. This has now - been fixed. - - - - The value of obj.status as a string in vcl_error would not be correct in all cases. This has been fixed. - - - - Varnish would try to trim storage segments completely - filled when using the malloc stevedore and the object was - received chunked encoding. This has been fixed. - - - - If a buggy backend sends us a Vary header - with two colons, we would previously abort. We now rather fix - this up and ignore the extra colon. - - - - req.hash_always_miss and - req.hash_ignore_busy has been added, to make - preloading or periodically refreshing content work better. - - - - - varnishncsa - - varnishncsa would in some cases be confused - by ESI requests and output invalid lines. This has now been - fixed. - - - - - varnishlog - - varnishlog now allows -o and -u together. - - - - - varnishtop - - varnishtop would crash on 32 bit - architectures. This has been fixed. - - - - - libvarnishapi - - Regex inclusion and exclusion had problems with matching - particular parts of the string being matched. This has been - fixed. - - - - diff --git a/doc/changes-2.1.3.xml b/doc/changes-2.1.3.xml deleted file mode 100644 index 6cfe24d..0000000 --- a/doc/changes-2.1.3.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.1.3 - - - diff --git a/doc/changes-2.1.4-2.1.5.xml b/doc/changes-2.1.4-2.1.5.xml deleted file mode 100644 index 9b7e8ae..0000000 --- a/doc/changes-2.1.4-2.1.5.xml +++ /dev/null @@ -1,132 +0,0 @@ - - -]> - - - varnishd - - On pass from vcl_recv, we did not remove the backends Content-Length - header before adding our own. This could cause confusion for - browsers and has been fixed. - - - - Make pass with content-length work again. An issue with regards - to 304, Content-Length and pass has been resolved. - - - - An issue relating to passed requests with If-Modified-Since - headers has been fixed. Varnish did not recognize that the - 304-response did not have a body. - - - - A potential lock-inversion with the ban lurker thread has been - resolved. - - - - Several build-dependency issues relating to rst2man have been - fixed. Varnish should now build from source without rst2man if you - are using tar-balls. - - - - Ensure Varnish reads the expected last CRLF after chunked data - from the backend. This allows re-use of the connection. - - - - Remove a GNU Make-ism during make dist to make BSD - happier. - - - - Document the log, set, unset, return and restart statements in - the VCL documentation. - - - - Fix an embarrassingly old bug where Varnish would run out of - workspace when requests come in fast over a single connection, - typically during synthetic benchmarks. - - - - Varnish will now allow If-Modified-Since requests - to objects without a Last-Modified-header, and instead - use the time the object was cached instead. - - - - Do not filter out Content-Range headers in - pass. - - - - Require -d, -b, -f, -S or -T when starting Varnishd. In human - terms, this means that it is legal to start varnishd without a Vcl or - backend, but only if you have a CLI channel of some kind. - - - - Don't suppress Cache-Control headers in pass - responses. - - - - Merge multi-line Cache-Control and Vary header fields. Until - now, no browsers have needed this, but Chromium seems to find it - necessary to spread its Cache-Control across two lines, and we get to - deal with it. - - - - Make new-purge not touch busy objects. This fixes a potential - crash when calling VRT_purge. - - - - If there are everal grace-able objects, pick the least expired - one. - - - - Fix an issue with varnishadm -T :6082 - shorthand. - - - - Add bourn-shell like "here" documents on the CLI. Typical - usage: - - vcl.inline vcl_new << 42 - backend foo {...} - sub vcl_recv {...} - 42 - - - - - Add CLI version to the CLI-banner, starting with version 1.0 to - mark here-documents. - - - - Fix a problem with the expiry thread slacking off during high - load. - - - - - - varnishtest - - Remove no longer existing -L option. - - - - - diff --git a/doc/changes-2.1.4.xml b/doc/changes-2.1.4.xml deleted file mode 100644 index c9211d8..0000000 --- a/doc/changes-2.1.4.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - -]> - - - Varnish - 2.1.4 - - - diff --git a/doc/changes-2.1.5.xml b/doc/changes-2.1.5.xml deleted file mode 100644 index 7e37731..0000000 --- a/doc/changes-2.1.5.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -]> - - Varnish - 2.1.5 - - - diff --git a/doc/changes-html.xsl b/doc/changes-html.xsl deleted file mode 100644 index eeaa1a4..0000000 --- a/doc/changes-html.xsl +++ /dev/null @@ -1,92 +0,0 @@ - - - -]> - - - - - - - - - - <xsl:call-template name="title"/> - - - -

- - - -
- - - Change log for&space; - - &space; - - - - -

- Changes between&space; - - &space;and&space; - -

- -
- - -

- -

-
    - -
-
- - -
  • - -
  • -
    - - -

    - -

    -
    - - -
    - - http://varnish.projects.linpro.no/ticket/ - - - ticket # - - - - - - - - - - - - - - - Warning: no template for element - - - - - diff --git a/doc/changes-wiki.xsl b/doc/changes-wiki.xsl deleted file mode 100644 index 9ff0d11..0000000 --- a/doc/changes-wiki.xsl +++ /dev/null @@ -1,76 +0,0 @@ - - -]> - - - - - - - - == - - ==&lf; - - - - - Change log for - - - - - - - === - Changes between - - and - - ===&lf; - - - - - ==== - - ====&lf; - - - - - * - - - - - - &lf; - - - - # - - - - - {{{ - - }}} - - - - - - - - Warning: no template for element - - - - - diff --git a/doc/changes.css b/doc/changes.css deleted file mode 100644 index f3d5c71..0000000 --- a/doc/changes.css +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id$ */ - -body { - background-color: white; - color: black; - font-family: sans-serif; - max-width: 40em; - margin: 1in auto 1in auto; -} - -h1 { - font-size: 200%; - font-weight: bold; - color: maroon; -} - -h2 { - font-size: 160%; - font-weight: bold; - color: maroon; -} - -h3 { - font-size: 120%; - font-weight: bold; - color: maroon; -} - -.code { - font-family: monospace; -} diff --git a/doc/changes.rst b/doc/changes.rst index 06540bf..cbf4834 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -425,3 +425,1416 @@ Other version. - The documentation has been improved all over and should now be in much better shape than before + +=========================== +Changes from 2.1.4 to 2.1.5 +=========================== + +varnishd +-------- + +- On pass from vcl\_recv, we did not remove the backends Content-Length + header before adding our own. This could cause confusion for browsers + and has been fixed. + +- Make pass with content-length work again. An issue with regards to + 304, Content-Length and pass has been resolved. + +- An issue relating to passed requests with If-Modified-Since headers + has been fixed. Varnish did not recognize that the 304-response did + not have a body. + +- A potential lock-inversion with the ban lurker thread has been + resolved. + +- Several build-dependency issues relating to rst2man have been fixed. + Varnish should now build from source without rst2man if you are using + tar-balls. + +- Ensure Varnish reads the expected last CRLF after chunked data from + the backend. This allows re-use of the connection. + +- Remove a GNU Make-ism during make dist to make BSD happier. + +- Document the log, set, unset, return and restart statements in the + VCL documentation. + +- Fix an embarrassingly old bug where Varnish would run out of + workspace when requests come in fast over a single connection, + typically during synthetic benchmarks. + +- Varnish will now allow If-Modified-Since requests to objects without + a Last-Modified-header, and instead use the time the object was + cached instead. + +- Do not filter out Content-Range headers in pass. + +- Require -d, -b, -f, -S or -T when starting Varnishd. In human terms, + this means that it is legal to start varnishd without a Vcl or + backend, but only if you have a CLI channel of some kind. + +- Don't suppress Cache-Control headers in pass responses. + +- Merge multi-line Cache-Control and Vary header fields. Until now, no + browsers have needed this, but Chromium seems to find it necessary to + spread its Cache-Control across two lines, and we get to deal with + it. + +- Make new-purge not touch busy objects. This fixes a potential crash + when calling VRT\_purge. + +- If there are everal grace-able objects, pick the least expired one. + +- Fix an issue with varnishadm -T :6082 shorthand. + +- Add bourn-shell like "here" documents on the CLI. Typical usage: + vcl.inline vcl\_new << 42 backend foo {...} sub vcl\_recv {...} 42 + +- Add CLI version to the CLI-banner, starting with version 1.0 to mark + here-documents. + +- Fix a problem with the expiry thread slacking off during high load. + +varnishtest +----------- + +- Remove no longer existing -L option. + +=========================== +Changes from 2.1.3 to 2.1.4 +=========================== + +varnishd +-------- + +- An embarrasing typo in the new binary heap layout caused inflated + obj/objcore/objhdr counts and could cause odd problems when the LRU + expunge mechanism was invoked. This has been fixed. + +- We now have updated documentation in the reStructuredText format. + Manual pages and reference documentation are both built from this. + +- We now include a DNS director which uses DNS for choosing which + backend to route requests to. Please see the documentation for more + details. + +- If you restarted a request, the HTTP header X-Forwarded-For would be + updated multiple times. This has been fixed. + +- If a VCL contained a % sign, and the vcl.show CLI command was used, + varnishd would crash. This has been fixed. + +- When doing a pass operation, we would remove the Content-Length, Age + and Proxy-Auth headers. We are no longer doing this. + +- now has a string representation, making it easier to construct + Expires headers in VCL. + +- In a high traffic environment, we would sometimes reuse a file + descriptor before flushing the logs from a worker thread to the + shared log buffer. This would cause confusion in some of the tools. + This has been fixed by explicitly flushing the log when a backend + connection is closed. + +- If the communication between the management and the child process + gets out of sync, we have no way to recover. Previously, varnishd + would be confused, but we now just kill the child and restart it. + +- If the backend closes the connection on us just as we sent a request + to it, we retry the request. This should solve some interoperability + problems with Apache and the mpm-itk multi processing module. + +- varnishd now only provides help output the current CLI session is + authenticated for. + +- If the backend does not tell us which length indication it is using, + we now assume the resource ends EOF at. + +- The client director now has a variable client.identity which is used + to choose which backend should receive a given request. + +- The Solaris port waiter has been updated, and other portability fixes + for Solaris. + +- There was a corner case in the close-down processing of pipes, this + has now been fixed. + +- Previously, if we stopped polling a backend which was sick, it never + got marked as healthy. This has now been changed. + +- It is now possible to specify ports as part of the .host field in + VCL. + +- The synthetic counters were not locked properly, and so the sms\_ + counters could underflow. This has now been fixed. + +- The value of obj.status as a string in vcl\_error would not be + correct in all cases. This has been fixed. + +- Varnish would try to trim storage segments completely filled when + using the malloc stevedore and the object was received chunked + encoding. This has been fixed. + +- If a buggy backend sends us a Vary header with two colons, we would + previously abort. We now rather fix this up and ignore the extra + colon. + +- req.hash\_always\_miss and req.hash\_ignore\_busy has been added, to + make preloading or periodically refreshing content work better. + +varnishncsa +----------- + +- varnishncsa would in some cases be confused by ESI requests and + output invalid lines. This has now been fixed. + +varnishlog +---------- + +- varnishlog now allows -o and -u together. + +varnishtop +---------- + +- varnishtop would crash on 32 bit architectures. This has been fixed. + +libvarnishapi +------------- + +- Regex inclusion and exclusion had problems with matching particular + parts of the string being matched. This has been fixed. + + +=========================== +Changes from 2.1.2 to 2.1.3 +=========================== + +varnishd +-------- + +- Improve scalability of critbit. + +- The critbit hash algorithm has now been tightened to make sure the + tree is in a consistent state at all points, and the time we wait for + an object to cool off after it is eligible for garbage collection has + been tweaked. + +- Add log command to VCL. This emits a VCL\_log entry into the shared + memory log. + +- Only emit Length and ReqEnd log entries if we actually have an XID. + This should get rid of some empty log lines in varnishncsa. + +- Destroy directors in a predictable fashion, namely reverse of + creation order. + +- Fix bug when ESI elements spanned storage elements causing a panic. + +- In some cases, the VCL compiler would panic instead of giving + sensible messages. This has now been fixed. + +- Correct an off-by-one error when the requested range exceeds the size + of an object. + +- Handle requests for the end of an object correctly. + +- Allow tabulator characters in the third field of the first line of + HTTP requests + +- On Solaris, if the remote end sends us an RST, all system calls + related to that socket will return EINVAL. We now handle this better. + +libvarnishapi +------------- + +- The -X parameter didn't work correctly. This has been fixed. + +=========================== +Changes from 2.1.1 to 2.1.2 +=========================== + +varnishd +-------- + +- When adding Range support for 2.1.1, we accidentially introduced a + bug which would append garbage to objects larger than the chunk size, + by default 128k. Browsers would do the right thing due to + Content-Length, but some load balancers would get very confused. + +=========================== +Changes from 2.1.1 to 2.1.1 +=========================== + +varnishd +-------- + +- The changelog in 2.1.0 included syntax errors, causing the generated + changelog to be empty. + +- The help text for default\_grace was wrongly formatted and included a + syntax error. This has now been fixed. + +- varnishd now closes the file descriptor used to read the management + secret file (from the -S parameter). + +- The child would previously try to close every valid file descriptor, + something which could cause problems if the file descriptor ulimit + was set too high. We now keep track of all the file descriptors we + open and only close up to that number. + +- ESI was partially broken in 2.1.0 due to a bug in the rollback of + session workspace. This has been fixed. + +- Reject the authcommand rather than crash if there is no -S parameter + given. + +- Align pointers in allocated objects. This will in theory make Varnish + a tiny bit faster at the expense of slightly more memory usage. + +- Ensure the master process process id is updated in the shared memory + log file after we go into the background. + +- HEAD requests would be converted to GET requests too early, which + affected pass and pipe. This has been fixed. + +- Update the documentation to point out that the TTL is no longer taken + into account to decide whether an object is cacheable or not. + +- Add support for completely obliterating an object and all variants of + it. Currently, this has to be done using inline C. + +- Add experimental support for the Range header. This has to be enabled + using the parameter http\_range\_support. + +- The critbit hasher could get into a deadlock and had a race + condition. Both those have now been fixed. + +varnishsizes +-----------~ + +- varnishsizes, which is like varnishhost, but for the length of + objects, has been added.. + + +=========================== +Changes from 2.0.6 to 2.1.0 +=========================== + +varnishd +-------- + +- Persistent storage is now experimentally supported using the + persistent stevedore. It has the same command line arguments as the + file stevedore. + +- obj.\* is now called beresp.\* in vcl\_fetch, and obj.\* is now + read-only. + +- The regular expression engine is now PCRE instead of POSIX regular + expressions. + +- req.\* is now available in vcl\_deliver. + +- Add saint mode where we can attempt to grace an object if we don't + like the backend response for some reason. + + Related, add saintmode\_threshold which is the threshold for the + number of objects to be added to the trouble list before the backend + is considered sick. + +- Add a new hashing method called critbit. This autoscales and should + work better on large object workloads than the classic hash. Critbit + has been made the default hash algorithm. + +- When closing connections, we experimented with sending RST to free up + load balancers and free up threads more quickly. This caused some + problems with NAT routers and so has been reverted for now. + +- Add thread that checks objects against ban list in order to prevent + ban list from growing forever. Note that this needs purges to be + written so they don't depend on req.\*. Enabled by setting + ban\_lurker\_sleep to a nonzero value. + +- The shared memory log file format was limited to maximum 64k + simultaneous connections. This is now a 32 bit field which removes + this limitation. + +- Remove obj\_workspace, this is now sized automatically. + +- Rename acceptors to waiters + +- vcl\_prefetch has been removed. It was never fully implemented. + +- Add support for authenticating CLI connections. + +- Add hash director that chooses which backend to use depending on + req.hash. + +- Add client director that chooses which backend to use depending on + the client's IP address. Note that this ignores the X-Forwarded-For + header. + +- varnishd now displays a banner by default when you connect to the + CLI. + +- Increase performance somewhat by moving statistics gathering into a + per-worker structure that is regularly flushed to the global stats. + +- Make sure we store the header and body of object together. This may + in some cases improve performance and is needed for persistence. + +- Remove client-side address accounting. It was never used for anything + and presented a performance problem. + +- Add a timestamp to bans, so you can know how old they are. + +- Quite a few people got confused over the warning about not being able + to lock the shared memory log into RAM, so stop warning about that. + +- Change the default CLI timeout to 10 seconds. + +- We previously forced all inserts into the cache to be GET requests. + This has been changed to allow POST as well in order to be able to + implement purge-on-POST semantics. + +- The CLI command stats now only lists non-zero values. + +- The CLI command stats now only lists non-zero values. + +- Use daemon(3) from libcompat on Darwin. + +- Remove vcl\_discard as it causes too much complexity and never + actually worked particularly well. + +- Remove vcl\_timeout as it causes too much complexity and never + actually worked particularly well. + +- Update the documentation so it refers to sess\_workspace, not + http\_workspace. + +- Document the -i switch to varnishd as well as the server.identity and + server.hostname VCL variables. + +- purge.hash is now deprecated and no longer shown in help listings. + +- When processing ESI, replace the five mandatory XML entities when we + encounter them. + +- Add string representations of time and relative time. + +- Add locking for n\_vbe\_conn to make it stop underflowing. + +- When ESI-processing content, check for illegal XML character + entities. + +- Varnish can now connect its CLI to a remote instance when starting + up, rather than just being connected to. + +- It is no longer needed to specify the maximum number of HTTP headers + to allow from backends. This is now a run-time parameter. + +- The X-Forwarded-For header is now generated by vcl\_recv rather than + the C code. + +- It is now possible to not send all CLI traffic to syslog. + +- It is now possible to not send all CLI traffic to syslog. + +- In the case of varnish crashing, it now outputs a identifying string + with the OS, OS revision, architecture and storage parameters + together with the backtrace. + +- Use exponential backoff when we run out of file descriptors or + sessions. + +- Allow setting backend timeouts to zero. + +- Count uptime in the shared memory log. + +- Try to detect the case of two running varnishes with the same shmlog + and storage by writing the master and child process ids to the shmlog + and refusing to start if they are still running. + +- Make sure to use EOF mode when serving ESI content to HTTP/1.0 + clients. + +- Make sure we close the connection if it either sends Connection: + close or it is a HTTP/1.0 backend that does not send Connection: + keep-alive. + +- Increase the default session workspace to 64k on 64-bit systems. + +- Make the epoll waiter use level triggering, not edge triggering as + edge triggering caused problems on very busy servers. + +- Handle unforeseen client disconnections better on Solaris. + +- Make session lingering apply to new sessions, not just reused + sessions. + +varnishstat +----------- + +- Make use of the new uptime field in the shared memory log rather than + synthesizing it from the start time. + +varnishlog +---------- + +- Exit at the end of the file when started with -d. + +varnishadm +---------- + +- varnishadm can now have a timeout when trying to connect to the + running varnishd. + +- varnishadm now knows how to respond to the secret from a secured + varnishd + +=========================== +Changes from 2.0.5 to 2.0.6 +=========================== + +varnishd +-------- + +- 2.0.5 had an off-by-one error in the ESI handling causing includes to + fail a large part of the time. This has now been fixed. + +- Try harder to not confuse backends when sending them backend probes. + We half-closed the connection, something some backends thought meant + we had dropped the connection. Stop doing so, and add the capability + for specifying the expected response code. + +- In 2.0.5, session lingering was turned on. This caused statistics to + not be counted often enough in some cases. This has now been fixed. + +- Avoid triggering an assert if the other end closes the connection + while we are lingering and waiting for another request from them. + +- When generating backtraces, prefer the built-in backtrace function if + such exists. This fixes a problem compiling 2.0.5 on Solaris. + +- Make it possible to specify the per-thread stack size. This might be + useful on 32 bit systems with their limited address space. + +- Document the -C option to varnishd. + +=========================== +Changes from 2.0.4 to 2.0.5 +=========================== + +varnishd +-------- + +- Handle object workspace overruns better. + +- Allow turning off ESI processing per request by using set req.esi = + off. + +- Tell the kernel that we expect to use the mmap-ed file in a random + fashion. On Linux, this turns off/down readahead and increases + performance. + +- Make it possible to change the maximum number of HTTP headers we + allow by passing --with-max-header-fields=NUM rather than changing + the code. + +- Implement support for HTTP continuation lines. + +- Change how connections are closed and only use SO\_LINGER for orderly + connection closure. This should hopefully make worker threads less + prone to hangups on network problems. + +- Handle multi-element purges correctly. Previously we ended up with + parse errors when this was done from VCL. + +- Handle illegal responses from the backend better by serving a 503 + page rather than panic-ing. + +- When we run into an assertion that is not true, Varnish would + previously dump a little bit of information about itself. Extend that + information with a backtrace. Note that this relies on the varnish + binary being unstripped. + +- Add a session\_max parameter that limits the maximum number of + sessions we keep open before we start dropping new connections + summarily. + +- Try to consume less memory when doing ESI processing by properly + rolling back used workspace after processing an object. This should + make it possible to turn sess\_workspace quite a bit for users with + ESI-heavy pages. + +- Turn on session\_linger by default. Tests have shown that + session\_linger helps a fair bit with performance. + +- Rewrite the epoll acceptor for better performance. This should lead + to both higher processing rates and maximum number of connections on + Linux. + +- Add If-None-Match support, this gives significant bandwidth savings + for users with compliant browsers. + +- RFC2616 specifies that ETag, Content-Location, Expires, Cache-Control + and Vary should be emitted when delivering a response with the 304 + response code. + +- Various fixes which makes Varnish compile and work on AIX. + +- Turn on TCP\_DEFER\_ACCEPT on Linux. This should make us less + suspecible to denial of service attacks as well as give us slightly + better performance. + +- Add an .initial property to the backend probe specification. This is + the number of good probes we pretend to have seen. The default is one + less than .threshold, which means the first probe will decide if we + consider the backend healthy. + +- Make it possible to compare strings against other string-like + objects, not just plain strings. This allows you to compare two + headers, for instance. + +- When support for restart in vcl\_error was added, there was no check + to prevent infinte recursion. This has now been fixed. + +- Turn on purge\_dups by default. This should make us consume less + memory when there are many bans for the same pattern added. + +- Add a new log tag called FetchError which tries to explain why we + could not fetch an object from the backend. + +- Change the default srcaddr\_ttl to 0. It is not used by anything and + has been removed in the development version. This will increase + performance somewhat. + +varnishtop +---------- + +- varnishtop did not handle variable-length log fields correctly. This + is now fixed. + +- varnishtop previously did not print the name of the tag, which made + it very hard to understand. We now print out the tag name. + +=========================== +Changes from 2.0.3 to 2.0.4 +=========================== + +varnishd +-------- + +- Make Varnish more portable by pulling in fixes for Solaris and + NetBSD. + +- Correct description of -a in the manual page. + +- Ensure we are compiling in C99 mode. + +- If error was called with a null reason, we would crash on Solaris. + Make sure this no longer happens. + +- Varnish used to crash if you asked it to use a non-existent waiter. + This has now been fixed. + +- Add documentation to the default VCL explaining that using + Connection: close in vcl\_close is generally a good idea. + +- Add minimal facility for dealing with TELNET option negotiation by + returning WONT to DO and DONT requests. + +- If the backend is unhealthy, use a graced object if one is available. + +- Make server.hostname and server.identity available to VCL. The latter + can be set with the -i parameter to varnishd. + +- Make restart available from vcl\_error. + +- Previously, only the TTL of an object was considered in whether it + would be marked as cacheable. This has been changed to take the grace + into consideration as well. + +- Previously, if an included ESI fragment had a zero size, we would + send out a zero-sized chunk which signifies end-of-transmission. We + now ignore zero-sized chunks. + +- We accidentially slept for far too long when we reached the maximum + number of open file descriptors. This has been corrected and + accept\_fd\_holdoff now works correctly. + +- Previously, when ESI processing, we did not look at the full length, + but stopped at the first NULL byte. We no longer do that, enabling + ESI processing of binary data. + +varnishtest +----------- + +- Make sure system "..." returns successfully to ensure test failures + do not go unnoticed. + +- Make it possible to send NULL bytes through the testing framework. + +=========================== +Changes from 2.0.2 to 2.0.3 +=========================== + +varnishd +-------- + +- Handle If-Modified-Since and ESI sub-objects better, fixing a problem + where we sometimes neglected to insert included objects. + +- restart in vcl\_hit is now supported. + +- Setting the TTL of an object to 0 seconds would sometimes cause it to + be delivered for up to one second - epsilon. This has been corrected + and we should now never deliver those objects to other clients. + +- The malloc storage backend now prints the maximum storage size, just + like the file backend. + +- Various small documentation bugs have been fixed. + +- Varnish did not set a default interval for backend probes, causing it + to poll the backend continuously. This has been corrected. + +- Allow "true" and "false" when setting boolean parameters, in addition + to on/off, enable/disable and yes/no. + +- Default to always talking HTTP 1.1 with the backend. + +- Varnish did not make sure the file it was loading was a regular file. + This could cause Varnish to crash if it was asked to load a directory + or other non-regular file. We now check that the file is a regular + file before loading it. + +- The binary heap used for expiry processing had scalability problems. + Work around this by using stripes of a fixed size, which should make + this scale better, particularly when starting up and having lots of + objects. + +- When we imported the jemalloc library into the Varnish tree, it did + not compile without warnings. This has now been fixed. + +- Varnish took a very long time to detect that the backend did not + respond. To remedy this, we now have read timeouts in addition to the + connect timeout. Both the first\_byte\_timeout and the + between\_bytes\_timeout defaults to 60 seconds. The connect timeout + is no longer in milliseconds, but rather in seconds. + +- Previously, the VCL to C conversion as well as the invocation of the + C compiler was done in the management process. This is now done in a + separate sub-process. This prevents any bugs in the VCL compiler from + affecting the management process. + +- Chunked encoding headers were counted in the statistics for header + bytes. They no longer are. + +- ESI processed objects were not counted in the statistics for body + bytes. They now are. + +- It is now possible to adjust the maximum record length of log entries + in the shmlog by tuning the shm\_reclen parameter. + +- The management parameters listed in the CLI were not sorted, which + made it hard to find the parameter you were looking for. They are now + sorted, which should make this easier. + +- Add a new hashing type, "critbit", which uses a lock-less tree based + lookup algorithm. This is experimental and should not be enabled in + production environments without proper testing. + +- The session workspace had a default size of 8k. It is now 16k, which + should make VCLs where many headers are processed less prone to + panics. + +- We have seen that people seem to be confused as to which actions in + the different VCL functions return and which ones don't. Add a new + syntax return(action) to make this more explicit. The old syntax is + still supported. + +- Varnish would return an error if any of the management IPs listed in + the -T parameter could not be listened to. We now only return an + error if none of them can be listened to. + +- In the case of the backend or client giving us too many parameters, + we used to just ignore the overflowing headers. This is problematic + if you end up ignoreing Content-Length, Transfer-Encoding and similar + headers. We now give out a 400 error to the client if it sends us too + many and 503 if we get too many from the backend. + +- We used panic if we got a too large chunked header. This behaviour + has been changed into just failing the transaction. + +- Varnish now supports an extended purge method where it is possible to + do purge req.http.host ~ "web1.com" && req.url ~ "\\.png" and + similar. See the documentation for details. + +- Under heavy load, Varnish would sometimes crash when trying to update + the per-request statistics. This has now been fixed. + +- It is now possible to not save the hash string in the session and + object workspace. This will save a lot of memory on sites with many + small objects. Disabling the purge\_hash parameter also disables the + purge.hash facility. + +- Varnish now supports !~ as a "no match" regular expression matcher. + +- In some cases, you could get serialised access to "pass" objects. We + now make it default to the default\_ttl value; this can be overridden + in vcl\_fetch. + +- Varnish did not check the syntax of regsub calls properly. More + checking has been added. + +- If the client closed the connection while Varnish was processing ESI + elements, Varnish would crash while trying to write the object to the + client. We now check if the client has closed the connection. + +- The ESI parser had a bug where it would crash if an XML comment would + span storage segments. This has been fixed. + +VCL Manual page +--------------~ + +- The documentation on how capturing parentheses work was wrong. This + has been corrected. + +- Grace has now been documented. + +varnishreplay +------------- + +- varnishreplay did not work correctly on Linux, due to a too small + stack. This has now been fixed. + +=========================== +Changes from 2.0.1 to 2.0.2 +=========================== + +varnishd +-------- + +- In high-load situations, when using ESI, varnishd would sometimes + mishandle objects and crash. This has been worked around. + +varnishreplay +------------- + +- varnishreplay did not work correctly on Linux, due to a too small + stack. This has now been fixed. + + +========================= +Changes from 2.0 to 2.0.1 +========================= + +varnishd +-------- + +- When receiving a garbled HTTP request, varnishd would sometimes + crash. This has been fixed. + +- There was an off-by-one error in the ACL compilation. Now fixed. + +Red Hat spec file +----------------~ + +- A typo in the spec file made the .rpm file names wrong. + +========================= +Changes from 1.1.2 to 2.0 +========================= + +varnishd +-------- + +- Only look for sendfile on platforms where we know how to use it, + which is FreeBSD for now. + +- Make it possible to adjust the shared memory log size and bump the + size from 8MB to 80MB. + +- Fix up the handling of request bodies to better match what RFC2616 + mandates. This makes PUT, DELETE, OPTIONS and TRACE work in addition + to POST. + +- Change how backends are defined, to a constant structural defintion + style. See http://varnish.projects.linpro.no/wiki/VclSyntaxChanges + for the details. + +- Add directors, which wrap backends. Currently, there's a random + director and a round-robin director. + +- Add "grace", which is for how long and object will be served, even + after it has expired. To use this, both the object's and the + request's grace parameter need to be set. + +- Manual pages have been updated for new VCL syntax and varnishd + options. + +- Man pages and other docs have been updated. + +- The shared memory log file is now locked in memory, so it should not + be paged out to disk. + +- We now handle Vary correctly, as well as Expect. + +- ESI include support is implemented. + +- Make it possible to limit how much memory the malloc uses. + +- Solaris is now supported. + +- There is now a regsuball function, which works like regsub except it + replaces all occurences of the regex, not just the first. + +- Backend and director declarations can have a .connect\_timeout + parameter, which tells us how long to wait for a successful + connection. + +- It is now possible to select the acceptor to use by changing the + acceptor parameter. + +- Backends can have probes associated with them, which can be checked + with req.backend.health in VCL as well as being handled by directors + which do load-balancing. + +- Support larger-than-2GB files also on 32 bit hosts. Please note that + this does not mean we can support caches bigger than 2GB, it just + means logfiles and similar can be bigger. + +- In some cases, we would remove the wrong header when we were + stripping Content-Transfer-Encoding headers from a request. This has + been fixed. + +- Backends can have a .max\_connections associated with them. + +- On Linux, we need to set the dumpable bit on the child if we want + core dumps. Make sure it's set. + +- Doing purge.hash() with an empty string would cause us to dump core. + Fixed so we don't do that any more. + +- We ran into a problem with glibc's malloc on Linux where it seemed + like it failed to ever give memory back to the OS, causing the system + to swap. We have now switched to jemalloc which appears not to have + this problem. + +- max\_restarts was never checked, so we always ended up running out of + workspace. Now, vcl\_error is called when we reach max\_restarts. + +varnishtest +----------- + +- varnishtest is a tool to do correctness tests of varnishd. The test + suite is run by using make check. + +varnishtop +---------- + +- We now set the field widths dynamically based on the size of the + terminal and the name of the longest field. + +varnishstat +----------- + +- varnishstat -1 now displays the uptime too. + +varnishncsa +----------- + +- varnishncsa now does fflush after each write. This makes tail -f work + correctly, as well as avoiding broken lines in the log file. + +- It is possible to get varnishncsa to output the X-Forwarded-For + instead of the client IP by passing -f to it. + +Build system +-----------~ + +- Various sanity checks have been added to configure, it now complains + about no ncurses or if SO\_RCVTIMEO or SO\_SNDTIMEO are + non-functional. It also aborts if there's no working acceptor + mechanism + +- The C compiler invocation is decided by the configure script and can + now be overridden by passing VCC\_CC when running configure. + +=========================== +Changes from 1.1.1 to 1.1.2 +=========================== + +varnishd +-------- + +- When switching to a new VCL configuration, a race condition exists + which may cause Varnish to reference a backend which no longer exists + (see `ticket #144 `_). + This race condition has not been entirely eliminated, but it should + occur less frequently. + +- When dropping a TCP session before any requests were processed, an + assertion would be triggered due to an uninitialized timestamp (see + `ticket #132 `_). The + timestamp is now correctly initialized. + +- Varnish will now correctly generate a Date: header for every response + instead of copying the one it got from the backend (see `ticket + #157 `_). + +- Comparisons in VCL which involve a non-existent string (usually a + header which is not present in the request or object being processed) + would cause a NULL pointer dereference; now the comparison will + simply fail. + +- A bug in the VCL compiler which would cause a double-free when + processing include directives has been fixed. + +- A resource leak in the worker thread management code has been fixed. + +- When connecting to a backend, Varnish will usually get the address + from a cache. When the cache is refreshed, existing connections may + end up with a reference to an address structure which no longer + exists, resulting in a crash. This race condition has been somewhat + mitigated, but not entirely eliminated (see `ticket + #144 `_.) + +- Varnish will now pass the correct protocol version in pipe mode: the + backend will get what the client sent, and vice versa. + +- The core of the pipe mode code has been rewritten to increase + robustness and eliminate spurious error messages when either end + closes the connection in a manner Varnish did not anticipate. + +- A memory leak in the backend code has been plugged. + +- When using the kqueue acceptor, if a client shuts down the request + side of the connection (as many clients do after sending their final + request), it was possible for the acceptor code to receive the EOF + event and recycle the session while the last request was still being + serviced, resulting in a assertion failure and a crash when the + worker thread later tried to delete the session. This should no + longer happen (see `ticket + #162 `_.) + +- A mismatch between the recorded length of a cached object and the + amount of data actually present in cache for that object can + occasionally occur (see `ticket + #167 `_.) This has been + partially fixed, but may still occur for error pages generated by + Varnish when a problem arises while retrieving an object from the + backend. + +- Some socket-related system calls may return unexpected error codes + when operating on a TCP connection that has been shut down at the + other end. These error codes would previously cause assertion + failures, but are now recognized as harmless conditions. + +varnishhist +----------- + +- Pressing 0 though 9 while varnishhist is running will change the + refresh interval to the corresponding power of two, in seconds. + +varnishncsa +----------- + +- The varnishncsa tool can now daemonize and write a PID file like + varnishlog, using the same command-line options. It will also reopen + its output upon receipt of a SIGHUP if invoked with -w. + +varnishstat +----------- + +- Pressing 0 though 9 while varnishstat is running will change the + refresh interval to the corresponding power of two, in seconds. + +Build system +-----------~ + +- Varnish's has been modified to avoid conflicts with + on platforms where the latter is included indirectly + through system headers. + +- Several steps have been taken towards Solaris support, but this is + not yet complete. + +- When configure was run without an explicit prefix, Varnish's idea of + the default state directory would be garbage and a state directory + would have to be specified manually with -n. This has been corrected. + +========================= +Changes from 1.1 to 1.1.1 +========================= + +varnishd +-------- + +- The code required to allow VCL to read obj.status, which had + accidentally been left out, has now been added. + +- Varnish will now always include a Connection: header in its reply to + the client, to avoid possible misunderstandings. + +- A bug that triggered an assertion failure when generating synthetic + error documents has been corrected. + +- A new VCL function, purge\_url, provides the same functionality as + the url.purge management command. + +- Previously, Varnish assumed that the response body should be sent + only if the request method was GET. This was a problem for custom + request methods (such as PURGE), so the logic has been changed to + always send the response body except in the specific case of a HEAD + request. + +- Changes to run-time parameters are now correctly propagated to the + child process. + +- Due to the way run-time parameters are initialized at startup, + varnishd previously required the nobody user and the nogroup group to + exist even if a different user and group were specified on the + command line. This has been corrected. + +- Under certain conditions, the VCL compiler would carry on after a + syntax error instead of exiting after reporting the error. This has + been corrected. + +- The manner in which the hash string is assembled has been modified to + reduce memory usage and memory-to-memory copying. + +- Before calling vcl\_miss, Varnish assembles a tentative request + object for the backend request which will usually follow. This object + would be leaked if vcl\_miss returned anything else than fetch. This + has been corrected. + +- The code necessary to handle an error return from vcl\_fetch and + vcl\_deliver had inadvertantly been left out. This has been + corrected. + +- Varnish no longer prints a spurious "child died" message (the result + of reaping the compiler process) after compiling a new VCL + configuration. + +- Under some circumstances, due to an error in the workspace management + code, Varnish would lose the "tail" of a request, i.e. the part of + the request that has been received from the client but not yet + processed. The most obvious symptom of this was that POST requests + would work with some browsers but not others, depending on details of + the browser's HTTP implementation. This has been corrected. + +- On some platforms, due to incorrect assumptions in the CLI code, the + management process would crash while processing commands received + over the management port. This has been corrected. + +Build system +-----------~ + +- The top-level Makefile will now honor $DESTDIR when creating the + state directory. + +- The Debian and RedHat packages are now split into three (main / lib / + devel) as is customary. + +- A number of compile-time and run-time portability issues have been + addressed. + +- The autogen.sh script had workarounds for problems with the GNU + autotools on FreeBSD; these are no longer needed and have been + removed. + +- The libcompat library has been renamed to libvarnishcompat and is now + dynamic rather than static. This simplifies the build process and + resolves an issue with the Mac OS X linker. + +========================= +Changes from 1.0.4 to 1.1 +========================= + +varnishd +-------- + +- Readability of the C source code generated from VCL code has been + improved. + +- Equality (==) and inequality (!=) operators have been implemented for + IP addresses (which previously could only be compared using ACLs). + +- The address of the listening socket on which the client connection + was received is now available to VCL as the server.ip variable. + +- Each object's hash key is now computed based on a string which is + available to VCL as req.hash. A VCL hook named vcl\_hash has been + added to allow VCL scripts to control hash generation (for instance, + whether or not to include the value of the Host: header in the hash). + +- The setup code for listening sockets has been modified to detect and + handle situations where a host name resolves to multiple IP + addresses. It will now attempt to bind to each IP address separately, + and report a failure only if none of them worked. + +- Network or protocol errors that occur while retrieving an object from + a backend server now result in a synthetic error page being inserted + into the cache with a 30-second TTL. This should help avoid driving + an overburdened backend server into the ground by repeatedly + requesting the same object. + +- The child process will now drop root privileges immediately upon + startup. The user and group to use are specified with the user and + group run-time parameters, which default to nobody and nogroup, + respectively. Other changes have been made in an effort to increase + the isolation between parent and child, and reduce the impact of a + compromise of the child process. + +- Objects which are received from the backend with a Vary: header are + now stored separately according to the values of the headers + specified in Vary:. This allows Varnish to correctly cache e.g. + compressed and uncompressed versions of the same object. + +- Each Varnish instance now has a name, which by default is the host + name of the machine it runs on, but can be any string that would be + valid as a relative or absolute directory name. It is used to + construct the name of a directory in which the server state as well + as all temporary files are stored. This makes it possible to run + multiple Varnish instances on the same machine without conflict. + +- When invoked with the -C option, varnishd will now not just translate + the VCL code to C, but also compile the C code and attempt to load + the resulting shared object. + +- Attempts by VCL code to reference a variable outside its scope or to + assign a value to a read-only variable will now result in + compile-time rather than run-time errors. + +- The new command-line option -F will make varnishd run in the + foreground, without enabling debugging. + +- New VCL variables have been introduced to allow inspection and + manipulation of the request sent to the backend (bereq.request, + bereq.url, bereq.proto and bereq.http) and the response to the client + (resp.proto, resp.status, resp.response and resp.http). + +- Statistics from the storage code (including the amount of data and + free space in the cache) are now available to varnishstat and other + statistics-gathering tools. + +- Objects are now kept on an LRU list which is kept loosely up-to-date + (to within a few seconds). When cache runs out, the objects at the + tail end of the LRU list are discarded one by one until there is + enough space for the freshly requested object(s). A VCL hook, + vcl\_discard, is allowed to inspect each object and determine its + fate by returning either keep or discard. + +- A new VCL hook, vcl\_deliver, provides a chance to adjust the + response before it is sent to the client. + +- A new management command, vcl.show, displays the VCL source code of + any loaded configuration. + +- A new VCL variable, now, provides VCL scripts with the current time + in seconds since the epoch. + +- A new VCL variable, obj.lastuse, reflects the time in seconds since + the object in question was last used. + +- VCL scripts can now add an HTTP header (or modify the value of an + existing one) by assigning a value to the corresponding variable, and + strip an HTTP header by using the remove keyword. + +- VCL scripts can now modify the HTTP status code of cached objects + (obj.status) and responses (resp.status) + +- Numeric and other non-textual variables in VCL can now be assigned to + textual variables; they will be converted as needed. + +- VCL scripts can now apply regular expression substitutions to textual + variables using the regsub function. + +- A new management command, status, returns the state of the child. + +- Varnish will now build and run on Mac OS X. + +varnishadm +---------- + +- This is a new utility which sends a single command to a Varnish + server's management port and prints the result to stdout, greatly + simplifying the use of the management port from scripts. + +varnishhist +----------- + +- The user interface has been greatly improved; the histogram will be + automatically rescaled and redrawn when the window size changes, and + it is updated regularly rather than at a rate dependent on the amount + of log data gathered. In addition, the name of the Varnish instance + being watched is displayed in the upper right corner. + +varnishncsa +----------- + +- In addition to client traffic, varnishncsa can now also process log + data from backend traffic. + +- A bug that would cause varnishncsa to segfault when it encountered an + empty HTTP header in the log file has been fixed. + +varnishreplay +------------- + +- This new utility will attempt to recreate the HTTP traffic which + resulted in the raw Varnish log data which it is fed. + +varnishstat +----------- + +- Don't print lifetime averages when it doesn't make any sense?for + instance, there is no point in dividing the amount in bytes of free + cache space by the lifetime in seconds of the varnishd process. + +- The user interface has been greatly improved; varnishstat will no + longer print more than fits in the terminal, and will respond + correctly to window resize events. The output produced in one-shot + mode has been modified to include symbolic names for each entry. In + addition, the name of the Varnish instance being watched is displayed + in the upper right corner in curses mode. + +varnishtop +---------- + +- The user interface has been greatly improved; varnishtop will now + respond correctly to window resize events, and one-shot mode (-1) + actually works. In addition, the name of the Varnish instance being + watched is displayed in the upper right corner in curses mode. + +=========================== +Changes from 1.0.3 to 1.0.4 +=========================== + +varnishd +-------- + +- The request workflow has been redesigned to simplify request + processing and eliminate code duplication. All codepaths which need + to speak HTTP now share a single implementation of the protocol. Some + new VCL hooks have been added, though they aren't much use yet. The + only real user-visible change should be that Varnish now handles + persistent backend connections correctly (see `ticket + #56 `_). + +- Support for multiple listen addresses has been added. + +- An "include" facility has been added to VCL, allowing VCL code to + pull in code fragments from multiple files. + +- Multiple definitions of the same VCL function are now concatenated + into one in the order in which they appear in the source. This + simplifies the mechanism for falling back to the built-in default for + cases which aren't handled in custom code, and facilitates + modularization. + +- The code used to format management command arguments before passing + them on to the child process would underestimate the amount of space + needed to hold each argument once quotes and special characters were + properly escaped, resulting in a buffer overflow. This has been + corrected. + +- The VCL compiler has been overhauled. Several memory leaks have been + plugged, and error detection and reporting has been improved + throughout. Parts of the compiler have been refactored to simplify + future extension of the language. + +- A bug in the VCL compiler which resulted in incorrect parsing of the + decrement (-=) operator has been fixed. + +- A new -C command-line option has been added which causes varnishd to + compile the VCL code (either from a file specified with -f or the + built-in default), print the resulting C code and exit. + +- When processing a backend response using chunked encoding, if a chunk + header crosses a read buffer boundary, read additional bytes from the + backend connection until the chunk header is complete. + +- A new ping\_interval run-time parameter controls how often the + management process checks that the worker process is alive. + +- A bug which would cause the worker process to dereference a NULL + pointer and crash if the backend did not respond has been fixed. + +- In some cases, such as when they are used by AJAX applications to + circumvent Internet Explorer's over-eager disk cache, it may be + desirable to cache POST requests. However, the code path responsible + for delivering objects from cache would only transmit the response + body when replying to a GET request. This has been extended to also + apply to POST. + + This should be revisited at a later date to allow VCL code to control + whether the body is delivered. + +- Varnish now respects Cache-control: s-maxage, and prefers it to + Cache-control: max-age if both are present. + + This should be revisited at a later date to allow VCL code to control + which headers are used and how they are interpreted. + +- When loading a new VCL script, the management process will now load + the compiled object to verify that it links correctly before + instructing the worker process to load it. + +- A new -P command-line options has been added which causes varnishd to + create a PID file. + +- The sendfile\_threshold run-time parameter's default value has been + set to infinity after a variety of sendfile()-related bugs were + discovered on several platforms. + +varnishlog +---------- + +- When grouping log entries by request, varnishlog attempts to collapse + the log entry for a call to a VCL function with the log entry for the + corresponding return from VCL. When two VCL calls were made in + succession, varnishlog would incorrectly omit the newline between the + two calls (see `ticket + #95 `_). + +- New -D and -P command-line options have been added to daemonize and + create a pidfile, respectively. + +- The flag that is raised upon reception of a SIGHUP has been marked + volatile so it will not be optimized away by the compiler. + +varnishncsa +----------- + +- The formatting callback has been largely rewritten for clarity, + robustness and efficiency. + + If a request included a Host: header, construct and output an + absolute URL. This makes varnishncsa output from servers which handle + multiple virtual hosts far more useful. + +- The flag that is raised upon reception of a SIGHUP has been marked + volatile so it will not be optimized away by the compiler. + +Documentation +------------- + +- The documentation?especially the VCL documentation?has been greatly + extended and improved. + +Build system +------------ + +- The name and location of the curses or ncurses library is now + correctly detected by the configure script instead of being hardcoded + into affected Makefiles. This allows Varnish to build correctly on a + wider range of platforms. + +- Compatibility shims for clock\_gettime() are now correctly applied + where needed, allowing Varnish to build on MacOS X. + +- The autogen.sh script will now correctly detect and warn about + automake versions which are known not to work correctly. diff --git a/doc/sphinx/installation/install.rst b/doc/sphinx/installation/install.rst index d725f81..fe8496d 100644 --- a/doc/sphinx/installation/install.rst +++ b/doc/sphinx/installation/install.rst @@ -92,7 +92,6 @@ installed. On a Debian or Ubuntu system these are: * libtool * autoconf * libncurses-dev -* xsltproc * groff-base * libpcre3-dev * pkg-config @@ -107,7 +106,6 @@ packages installed: * autoconf * libtool * ncurses-devel -* libxslt * groff * pcre-devel * pkgconfig diff --git a/redhat/varnish.spec b/redhat/varnish.spec index 5cf9c97..ead5745 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -15,7 +15,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # To build from git, start with a make dist, see redhat/README.redhat # You will need at least automake autoconf libtool python-docutils #BuildRequires: automake autoconf libtool python-docutils -BuildRequires: ncurses-devel libxslt groff pcre-devel pkgconfig +BuildRequires: ncurses-devel groff pcre-devel pkgconfig Requires: varnish-libs = %{version}-%{release} Requires: logrotate Requires: ncurses From phk at varnish-cache.org Mon Oct 31 08:09:16 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 09:09:16 +0100 Subject: [master] a0db44f Don't abbreviate panic message output. Message-ID: commit a0db44fdc2ea7b361dce9f17e54a3233ab1886ca Author: Poul-Henning Kamp Date: Mon Oct 31 08:09:01 2011 +0000 Don't abbreviate panic message output. diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 651bd89..57fa27a 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -164,7 +164,7 @@ vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...) void vtc_dump(struct vtclog *vl, int lvl, const char *pfx, const char *str, int len) { - int nl = 1; + int nl = 1, olen; unsigned l; double tx; @@ -181,10 +181,11 @@ vtc_dump(struct vtclog *vl, int lvl, const char *pfx, const char *str, int len) VSB_printf(vl->vsb, "%s %-4s %4.1f %s(null)\n", lead[lvl], vl->id, tx, pfx); else { - if (len == -1) + olen = len; + if (len < 0) len = strlen(str); for (l = 0; l < len; l++, str++) { - if (l > 512) { + if (l > 512 && olen != -2) { VSB_printf(vl->vsb, "..."); break; } diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 87b9423..cf1742d 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -316,7 +316,7 @@ varnish_thread(void *priv) if (i <= 0) break; buf[i] = '\0'; - vtc_dump(v->vl, 3, "debug", buf, -1); + vtc_dump(v->vl, 3, "debug", buf, -2); } return (NULL); } From phk at varnish-cache.org Mon Oct 31 09:03:27 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 10:03:27 +0100 Subject: [master] 2fceda5 Make the VFP calls symmetric and pair-wise visible, allow ->end() to fail, and act accordingly. Message-ID: commit 2fceda5de01b6adee39436b7631fbadb5d80efac Author: Poul-Henning Kamp Date: Mon Oct 31 09:03:04 2011 +0000 Make the VFP calls symmetric and pair-wise visible, allow ->end() to fail, and act accordingly. diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index acef94b..6e92963 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -198,15 +198,12 @@ fetch_number(const char *nbr, int radix) /*--------------------------------------------------------------------*/ static int -fetch_straight(struct worker *w, struct http_conn *htc, const char *b) +fetch_straight(struct worker *w, struct http_conn *htc, ssize_t cl) { int i; - ssize_t cl; assert(w->body_status == BS_LENGTH); - cl = fetch_number(b, 10); - w->vfp->begin(w, cl > 0 ? cl : 0); if (cl < 0) { WSLB(w, SLT_FetchError, "straight length field bogus"); return (-1); @@ -242,7 +239,6 @@ fetch_chunked(struct worker *w, struct http_conn *htc) unsigned u; ssize_t cl; - w->vfp->begin(w, 0); assert(w->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ @@ -310,7 +306,6 @@ fetch_eof(struct worker *w, struct http_conn *htc) int i; assert(w->body_status == BS_EOF); - w->vfp->begin(w, 0); i = w->vfp->bytes(w, htc, SSIZE_MAX); if (i < 0) { WSLB(w, SLT_FetchError, "eof read_error: %d (%s)", @@ -485,6 +480,7 @@ FetchBody(struct worker *w, struct object *obj) int cls; struct storage *st; int mklen; + ssize_t cl; CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); AZ(w->fetch_obj); @@ -502,6 +498,8 @@ FetchBody(struct worker *w, struct object *obj) w->fetch_obj = obj; + /* XXX: pick up estimate from objdr ? */ + cl = 0; switch (w->body_status) { case BS_NONE: cls = 0; @@ -512,20 +510,26 @@ FetchBody(struct worker *w, struct object *obj) mklen = 1; break; case BS_LENGTH: - cls = fetch_straight(w, w->htc, - w->h_content_length); + cl = fetch_number( w->h_content_length, 10); + w->vfp->begin(w, cl > 0 ? cl : 0); + cls = fetch_straight(w, w->htc, cl); mklen = 1; - XXXAZ(w->vfp->end(w)); + if (w->vfp->end(w)) + cls = -1; break; case BS_CHUNKED: + w->vfp->begin(w, cl); cls = fetch_chunked(w, w->htc); mklen = 1; - XXXAZ(w->vfp->end(w)); + if (w->vfp->end(w)) + cls = -1; break; case BS_EOF: + w->vfp->begin(w, cl); cls = fetch_eof(w, w->htc); mklen = 1; - XXXAZ(w->vfp->end(w)); + if (w->vfp->end(w)) + cls = -1; break; case BS_ERROR: cls = 1; From tfheen at varnish-cache.org Mon Oct 31 09:18:39 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 31 Oct 2011 10:18:39 +0100 Subject: [master] cf66e08 Typographical corrections, spelling Message-ID: commit cf66e086e6cfe8c6a530ac16ea5a7bc69bf67954 Author: Tollef Fog Heen Date: Mon Oct 31 09:59:45 2011 +0100 Typographical corrections, spelling diff --git a/doc/sphinx/phk/backends.rst b/doc/sphinx/phk/backends.rst index 2b32353..9ab6123 100644 --- a/doc/sphinx/phk/backends.rst +++ b/doc/sphinx/phk/backends.rst @@ -9,10 +9,10 @@ question answered conclusively long time ago, but once you try to be efficient, things get hairy fast. One of the features of Varnish we are very fundamental about, is the -ability to have multiple VCL's loaded at the same time, and to switch +ability to have multiple VCLs loaded at the same time, and to switch between them instantly and seamlessly. -So Imagine you have 1000 backends in your VCL, not an unreasonable +So imagine you have 1000 backends in your VCL, not an unreasonable number, each configured with health-polling. Now you fiddle your vcl_recv{} a bit and load the VCL again, but @@ -25,7 +25,7 @@ be up to date the instant we switch to the other VCL. This basically means that either all VCLs poll all their backends, or they must share, somehow. -We can dismiss the all VCL's poll all their backends scenario, +We can dismiss the all VCLs poll all their backends scenario, because it scales truly horribly, and would pummel backends with probes if people forget to vcl.discard their old dusty VCLs. @@ -39,7 +39,7 @@ It would be truly stupid to close 100 ready and usable connections to a backend, and open 100 other, just because we switch to a different VCL that has an identical backend definition. -But what is an identical backend definition in this context ? +But what is an identical backend definition in this context? It is important to remember that we are not talking physical backends: For instance, there is nothing preventing a VCL for @@ -48,7 +48,7 @@ backends. The most obvious thing to do, is to use the VCL name of the backend as identifier, but that is not enough. We can have two different -VCL's where backend "b1" points at two different physical machines, +VCLs where backend "b1" points at two different physical machines, for instance when we migrate or upgrade the backend. The identity of the state than can be shared is therefore the triplet: @@ -78,11 +78,11 @@ is a wildcard-ish scheme, where you can write things like:: b1() # All backends named b1 - b1(127.0.0.1) # All b1's on Ipv4 lookback + b1(127.0.0.1) # All b1s on IPv4 lookback - b1(:8080) # All b1's on port 8080, (IPv4 or IPv6) + b1(:8080) # All b1s on port 8080, (IPv4 or IPv6) - b1(192.168.60.1,192.168.60.2) # All b1's on one of those addresses. + b1(192.168.60.1,192.168.60.2) # All b1s on one of those addresses. (Input very much welcome) @@ -112,7 +112,7 @@ the backend gets retired anyway. We should either park a thread on each backend, or have a poller thread which throws jobs into the work-pool as the backends needs polled. -The patternmatching is confined to CLI and possibly libvarnishapi +The pattern matching is confined to CLI and possibly libvarnishapi I think this will work, From tfheen at varnish-cache.org Mon Oct 31 13:37:32 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 31 Oct 2011 14:37:32 +0100 Subject: [master] 56d17a6 Add new format %{VCL_Log:foo}x which output key:value from std.log() in VCL Message-ID: commit 56d17a6dc795a8f61821e9edcaa04a57a3d13f00 Author: Lasse Karstensen Date: Mon Oct 31 14:28:10 2011 +0100 Add new format %{VCL_Log:foo}x which output key:value from std.log() in VCL diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 47e5e2a..f699d9b 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -108,6 +108,7 @@ static struct logline { uint64_t bitmap; /* Bitmap for regex matches */ VTAILQ_HEAD(, hdr) req_headers; /* Request headers */ VTAILQ_HEAD(, hdr) resp_headers; /* Response headers */ + VTAILQ_HEAD(, hdr) vcl_log; /* VLC_Log entries */ } **ll; struct VSM_data *vd; @@ -219,6 +220,19 @@ resp_header(struct logline *l, const char *name) return NULL; } +static char * +vcl_log(struct logline *l, const char *name) +{ + struct hdr *h; + VTAILQ_FOREACH(h, &l->vcl_log, list) { + if (strcasecmp(h->key, name) == 0) { + return h->value; + break; + } + } + return NULL; +} + static void clean_logline(struct logline *lp) { @@ -245,6 +259,12 @@ clean_logline(struct logline *lp) freez(h->value); freez(h); } + VTAILQ_FOREACH_SAFE(h, &lp->vcl_log, list, h2) { + VTAILQ_REMOVE(&lp->vcl_log, h, list); + freez(h->key); + freez(h->value); + freez(h); + } #undef freez memset(lp, 0, sizeof *lp); } @@ -465,6 +485,25 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, } break; + case SLT_VCL_Log: + if(!lp->active) + break; + + split = strchr(ptr, ':'); + if (split == NULL) + break; + + struct hdr *h; + h = malloc(sizeof(struct hdr)); + AN(h); + AN(split); + + h->key = trimline(ptr, split); + h->value = trimline(split+1, end); + + VTAILQ_INSERT_HEAD(&lp->vcl_log, h, list); + break; + case SLT_VCL_call: if(!lp->active) break; @@ -718,6 +757,14 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, VSB_cat(os, (lp->df_handling ? lp->df_handling : "-")); p = tmp; break; + } else if (strncmp(fname, "VCL_Log:", 8) == 0) { + // support pulling entries logged with std.log() into output. + // Format: %{VCL_Log:keyname}x + // Logging: std.log("keyname:value") + h = vcl_log(lp, fname+8); + VSB_cat(os, h ? h : "-"); + p = tmp; + break; } default: fprintf(stderr, "Unknown format starting at: %s\n", --p); diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index e654e37..ddb6538 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -116,6 +116,10 @@ The following options are available: Varnish:handling How the request was handled, whether it was a cache hit, miss, pass, pipe or error. + + VCL_Log:key + Output value set by std.log("key=value") in VCL. + -m tag:regex only list records where tag matches regex. Multiple -m options are AND-ed together. From tfheen at varnish-cache.org Mon Oct 31 13:37:32 2011 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 31 Oct 2011 14:37:32 +0100 Subject: [master] e9e02a4 Support for \t\n in varnishncsa format strings Message-ID: commit e9e02a49c2a5606264b3ee9cd8e1c795639f4d61 Author: Tollef Fog Heen Date: Mon Oct 31 14:35:28 2011 +0100 Support for \t\n in varnishncsa format strings diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index f699d9b..8d969eb 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -629,6 +629,14 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, for (p = format; *p != '\0'; p++) { + /* allow the most essential escape sequences in format. */ + if (*p == '\\') { + p++; + if (*p == 't') VSB_putc(os, '\t'); + if (*p == 'n') VSB_putc(os, '\n'); + continue; + } + if (*p != '%') { VSB_putc(os, *p); continue; diff --git a/doc/sphinx/reference/varnishncsa.rst b/doc/sphinx/reference/varnishncsa.rst index ddb6538..8499d29 100644 --- a/doc/sphinx/reference/varnishncsa.rst +++ b/doc/sphinx/reference/varnishncsa.rst @@ -54,6 +54,8 @@ The following options are available: %h %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i" + Escape sequences \\n and \\t are supported. + Supported formatters are: %b From phk at varnish-cache.org Mon Oct 31 14:22:23 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 15:22:23 +0100 Subject: [master] 6e4e013 Overhaul the detection and reporting of fetch errors, to properly catch trouble that materializes only when we destroy the VGZ instance. Message-ID: commit 6e4e013f407c6685241c7a4c88a72dbd671102ba Author: Poul-Henning Kamp Date: Mon Oct 31 14:20:34 2011 +0000 Overhaul the detection and reporting of fetch errors, to properly catch trouble that materializes only when we destroy the VGZ instance. Fixes #1037 Fixes #1043 Fixes #1044 diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index bce7377..53e8ae8 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -345,6 +345,7 @@ struct worker { struct vfp *vfp; struct vgz *vgz_rx; struct vef_priv *vef_priv; + unsigned fetch_failed; unsigned do_stream; unsigned do_esi; unsigned do_gzip; @@ -703,6 +704,8 @@ int EXP_NukeOne(struct worker *w, struct lru *lru); /* cache_fetch.c */ struct storage *FetchStorage(struct worker *w, ssize_t sz); +int FetchError(struct worker *w, const char *error); +int FetchError2(struct worker *w, const char *error, const char *more); int FetchHdr(struct sess *sp); int FetchBody(struct worker *w, struct object *obj); int FetchReqBody(struct sess *sp); @@ -721,7 +724,7 @@ int VGZ_ObufFull(const struct vgz *vg); int VGZ_ObufStorage(struct worker *w, struct vgz *vg); int VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag); int VGZ_Gunzip(struct vgz *, const void **, size_t *len); -void VGZ_Destroy(struct vgz **, int vsl_id); +int VGZ_Destroy(struct vgz **, int vsl_id); void VGZ_UpdateObj(const struct vgz*, struct object *); int VGZ_WrwGunzip(struct worker *w, struct vgz *, const void *ibuf, ssize_t ibufl, char *obuf, ssize_t obufl, ssize_t *obufp); diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c index fe7dae6..37c4b7b 100644 --- a/bin/varnishd/cache_center.c +++ b/bin/varnishd/cache_center.c @@ -934,7 +934,7 @@ cnt_streambody(struct sess *sp) RES_StreamEnd(sp); if (sp->wrk->res_mode & RES_GUNZIP) - VGZ_Destroy(&sctx.vgz, sp->vsl_id); + (void)VGZ_Destroy(&sctx.vgz, sp->vsl_id); sp->wrk->sctx = NULL; assert(WRW_IsReleased(sp->wrk)); diff --git a/bin/varnishd/cache_esi_deliver.c b/bin/varnishd/cache_esi_deliver.c index a06bbb8..2c62bb7 100644 --- a/bin/varnishd/cache_esi_deliver.c +++ b/bin/varnishd/cache_esi_deliver.c @@ -406,7 +406,7 @@ ESI_Deliver(struct sess *sp) if (vgz != NULL) { if (obufl > 0) (void)WRW_Write(sp->wrk, obuf, obufl); - VGZ_Destroy(&vgz, sp->vsl_id); + (void)VGZ_Destroy(&vgz, sp->vsl_id); } if (sp->wrk->gzip_resp && sp->esi_level == 0) { /* Emit a gzip literal block with finish bit set */ diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 69896aa..1c75054 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -112,7 +112,7 @@ vfp_esi_bytes_gu(struct worker *w, struct http_conn *htc, ssize_t bytes) bytes -= wl; } if (VGZ_ObufStorage(w, vg)) - return (-1); + return(FetchError(w, "Could not get storage")); i = VGZ_Gunzip(vg, &dp, &dl); xxxassert(i == VGZ_OK || i == VGZ_END); VEP_Parse(w, dp, dl); @@ -297,7 +297,6 @@ vfp_esi_begin(struct worker *w, size_t estimate) struct vef_priv *vef; CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); - /* XXX: snapshot WS's ? We'll need the space */ AZ(w->vgz_rx); if (w->is_gzip && w->do_gunzip) { @@ -306,9 +305,6 @@ vfp_esi_begin(struct worker *w, size_t estimate) } else if (w->is_gunzip && w->do_gzip) { ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); - //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); - //memset(vef, 0, sizeof *vef); - //vef->magic = VEF_MAGIC; vef->vgz = VGZ_NewGzip(w, "G F E"); AZ(w->vef_priv); w->vef_priv = vef; @@ -317,9 +313,6 @@ vfp_esi_begin(struct worker *w, size_t estimate) w->vgz_rx = VGZ_NewUngzip(w, "U F E"); ALLOC_OBJ(vef, VEF_MAGIC); AN(vef); - //vef = (void*)WS_Alloc(sp->ws, sizeof *vef); - //memset(vef, 0, sizeof *vef); - //vef->magic = VEF_MAGIC; vef->vgz = VGZ_NewGzip(w, "G F E"); AZ(w->vef_priv); w->vef_priv = vef; @@ -339,6 +332,7 @@ vfp_esi_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) int i; CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + AZ(w->fetch_failed); AN(w->vep); if (w->is_gzip && w->do_gunzip) i = vfp_esi_bytes_gu(w, htc, bytes); @@ -358,35 +352,48 @@ vfp_esi_end(struct worker *w) struct vsb *vsb; struct vef_priv *vef; ssize_t l; + int retval; CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); AN(w->vep); + retval = w->fetch_failed; + + if (w->vgz_rx != NULL && VGZ_Destroy(&w->vgz_rx, -1) != VGZ_END) + retval = FetchError(w, + "Gunzip+ESI Failed at the very end"); + vsb = VEP_Finish(w); if (vsb != NULL) { - l = VSB_len(vsb); - assert(l > 0); - /* XXX: This is a huge waste of storage... */ - w->fetch_obj->esidata = STV_alloc(w, l); - XXXAN(w->fetch_obj->esidata); - memcpy(w->fetch_obj->esidata->ptr, VSB_data(vsb), l); - w->fetch_obj->esidata->len = l; + if (!retval) { + l = VSB_len(vsb); + assert(l > 0); + /* XXX: This is a huge waste of storage... */ + w->fetch_obj->esidata = STV_alloc(w, l); + if (w->fetch_obj->esidata != NULL) { + memcpy(w->fetch_obj->esidata->ptr, + VSB_data(vsb), l); + w->fetch_obj->esidata->len = l; + } else { + retval = FetchError(w, + "Could not allocate storage for esidata"); + } + } VSB_delete(vsb); } - if (w->vgz_rx != NULL) - VGZ_Destroy(&w->vgz_rx, -1); if (w->vef_priv != NULL) { vef = w->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); w->vef_priv = NULL; VGZ_UpdateObj(vef->vgz, w->fetch_obj); - VGZ_Destroy(&vef->vgz, -1); - XXXAZ(vef->error); + if (VGZ_Destroy(&vef->vgz, -1) != VGZ_END) + retval = FetchError(w, + "ESI+Gzip Failed at the very end"); FREE_OBJ(vef); } - return (0); + return (retval); } struct vfp vfp_esi = { diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 6e92963..dd3a1c7 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -43,6 +43,36 @@ static unsigned fetchfrag; /*-------------------------------------------------------------------- + * We want to issue the first error we encounter on fetching and + * supress the rest. This function does that. + * + * Other code is allowed to look at w->fetch_failed to bail out + * + * For convenience, always return -1 + */ + +int +FetchError2(struct worker *w, const char *error, const char *more) +{ + + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + if (!w->fetch_failed) { + if (more == NULL) + WSLB(w, SLT_FetchError, "%s", error); + else + WSLB(w, SLT_FetchError, "%s: %s", error, more); + } + w->fetch_failed = 1; + return (-1); +} + +int +FetchError(struct worker *w, const char *error) +{ + return(FetchError2(w, error, NULL)); +} + +/*-------------------------------------------------------------------- * VFP_NOP * * This fetch-processor does nothing but store the object. @@ -74,7 +104,8 @@ vfp_nop_begin(struct worker *w, size_t estimate) * * Process (up to) 'bytes' from the socket. * - * Return -1 on error + * Return -1 on error, issue FetchError() + * will not be called again, once error happens. * Return 0 on EOF on socket even if bytes not reached. * Return 1 when 'bytes' have been processed. */ @@ -85,17 +116,18 @@ vfp_nop_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) ssize_t l, wl; struct storage *st; + AZ(w->fetch_failed); while (bytes > 0) { st = FetchStorage(w, 0); - if (st == NULL) { - htc->error = "Could not get storage"; - return (-1); - } + if (st == NULL) + return(FetchError(w, "Could not get storage")); l = st->space - st->len; if (l > bytes) l = bytes; wl = HTC_Read(htc, st->ptr + st->len, l); - if (wl <= 0) + if (wl < 0) + return(FetchError(w, htc->error)); + if (wl == 0) return (wl); st->len += wl; w->fetch_obj->len += wl; @@ -205,17 +237,13 @@ fetch_straight(struct worker *w, struct http_conn *htc, ssize_t cl) assert(w->body_status == BS_LENGTH); if (cl < 0) { - WSLB(w, SLT_FetchError, "straight length field bogus"); - return (-1); + return (FetchError(w, "straight length field bogus")); } else if (cl == 0) return (0); i = w->vfp->bytes(w, htc, cl); - if (i <= 0) { - WSLB(w, SLT_FetchError, "straight read_error: %d %d (%s)", - i, errno, htc->error); - return (-1); - } + if (i <= 0) + return (FetchError(w, "straight insufficient bytes")); return (0); } @@ -257,10 +285,8 @@ fetch_chunked(struct worker *w, struct http_conn *htc) break; } - if (u >= sizeof buf) { - WSLB(w, SLT_FetchError, "chunked header too long"); - return (-1); - } + if (u >= sizeof buf) + return (FetchError(w,"chunked header too long")); /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') { @@ -268,19 +294,17 @@ fetch_chunked(struct worker *w, struct http_conn *htc) CERR(); } - if (buf[u] != '\n') { - WSLB(w, SLT_FetchError, "chunked header char syntax"); - return (-1); - } + if (buf[u] != '\n') + return (FetchError(w,"chunked header no NL")); buf[u] = '\0'; cl = fetch_number(buf, 16); if (cl < 0) { - WSLB(w, SLT_FetchError, "chunked header nbr syntax"); - return (-1); + return (FetchError(w,"chunked header number syntax")); } else if (cl > 0) { i = w->vfp->bytes(w, htc, cl); - CERR(); + if (i <= 0) + return (-1); } i = HTC_Read(htc, buf, 1); CERR(); @@ -288,10 +312,8 @@ fetch_chunked(struct worker *w, struct http_conn *htc) i = HTC_Read(htc, buf, 1); CERR(); } - if (buf[0] != '\n') { - WSLB(w, SLT_FetchError, "chunked tail syntax"); - return (-1); - } + if (buf[0] != '\n') + return (FetchError(w,"chunked tail no NL")); } while (cl > 0); return (0); } @@ -307,11 +329,8 @@ fetch_eof(struct worker *w, struct http_conn *htc) assert(w->body_status == BS_EOF); i = w->vfp->bytes(w, htc, SSIZE_MAX); - if (i < 0) { - WSLB(w, SLT_FetchError, "eof read_error: %d (%s)", - errno, htc->error); + if (i < 0) return (-1); - } return (0); } @@ -497,6 +516,7 @@ FetchBody(struct worker *w, struct object *obj) AZ(VTAILQ_FIRST(&obj->store)); w->fetch_obj = obj; + w->fetch_failed = 0; /* XXX: pick up estimate from objdr ? */ cl = 0; @@ -572,6 +592,7 @@ FetchBody(struct worker *w, struct object *obj) obj->len = 0; return (__LINE__); } + AZ(w->fetch_failed); if (cls == 0 && w->do_close) cls = 1; @@ -588,6 +609,7 @@ FetchBody(struct worker *w, struct object *obj) if (w->do_stream) /* Streaming might have started freeing stuff */ assert (uu <= obj->len); + else assert(uu == obj->len); } diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 7df69cd..73f4bb9 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -81,7 +81,7 @@ struct vgz { const char *id; struct ws *tmp; char *tmp_snapshot; - const char *error; + int last_i; struct storage *obuf; @@ -201,8 +201,6 @@ VGZ_NewGzip(struct worker *wrk, const char *id) 16 + params->gzip_window, /* Window bits (16=gzip + 15) */ params->gzip_memlevel, /* memLevel */ Z_DEFAULT_STRATEGY); - if (i != Z_OK) - printf("deflateInit2() = %d\n", i); assert(Z_OK == i); return (vg); } @@ -259,10 +257,8 @@ VGZ_ObufStorage(struct worker *w, struct vgz *vg) struct storage *st; st = FetchStorage(w, 0); - if (st == NULL) { - vg->error = "Could not get ObufStorage"; + if (st == NULL) return (-1); - } vg->obuf = st; VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len); @@ -294,6 +290,7 @@ VGZ_Gunzip(struct vgz *vg, const void **pptr, size_t *plen) if (vg->obuf != NULL) vg->obuf->len += l; } + vg->last_i = i; if (i == Z_OK) return (VGZ_OK); if (i == Z_STREAM_END) @@ -336,6 +333,7 @@ VGZ_Gzip(struct vgz *vg, const void **pptr, size_t *plen, enum vgz_flag flags) if (vg->obuf != NULL) vg->obuf->len += l; } + vg->last_i = i; if (i == Z_OK) return (0); if (i == Z_STREAM_END) @@ -405,11 +403,11 @@ VGZ_UpdateObj(const struct vgz *vg, struct object *obj) * Passing a vsl_id of -1 means "use w->vbc->vsl_id" */ -void +int VGZ_Destroy(struct vgz **vgp, int vsl_id) { struct vgz *vg; - const char *err; + int i; vg = *vgp; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); @@ -431,14 +429,22 @@ VGZ_Destroy(struct vgz **vgp, int vsl_id) (intmax_t)vg->vz.start_bit, (intmax_t)vg->vz.last_bit, (intmax_t)vg->vz.stop_bit); - err = vg->error; if (vg->tmp != NULL) WS_Reset(vg->tmp, vg->tmp_snapshot); if (vg->dir == VGZ_GZ) - assert(deflateEnd(&vg->vz) == 0 || err != NULL); + i = deflateEnd(&vg->vz); else - assert(inflateEnd(&vg->vz) == 0 || err != NULL); + i = inflateEnd(&vg->vz); + if (vg->last_i == Z_STREAM_END && i == Z_OK) + i = Z_STREAM_END; FREE_OBJ(vg); + if (i == Z_OK) + return (VGZ_OK); + if (i == Z_STREAM_END) + return (VGZ_END); + if (i == Z_BUF_ERROR) + return (VGZ_STUCK); + return (VGZ_ERROR); } /*-------------------------------------------------------------------- @@ -465,6 +471,7 @@ vfp_gunzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) size_t dl; const void *dp; + AZ(w->fetch_failed); vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); @@ -474,27 +481,25 @@ vfp_gunzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) if (l > bytes) l = bytes; wl = HTC_Read(htc, ibuf, l); - if (wl <= 0) + if (wl < 0) + return(FetchError(w, htc->error)); + if (wl == 0) return (wl); VGZ_Ibuf(vg, ibuf, wl); bytes -= wl; } - if (VGZ_ObufStorage(w, vg)) { - htc->error = "Could not get storage"; - return (-1); - } + if (VGZ_ObufStorage(w, vg)) + return(FetchError(w, "Could not get storage")); i = VGZ_Gunzip(vg, &dp, &dl); - assert(i == VGZ_OK || i == VGZ_END); + if (i != VGZ_OK && i != VGZ_END) + return(FetchError(w, "Gunzip data error")); w->fetch_obj->len += dl; if (w->do_stream) RES_StreamPoll(w); } - if (i == Z_OK || i == Z_STREAM_END) - return (1); - htc->error = "See other message"; - WSLB(w, SLT_FetchError, "Gunzip trouble (%d)", i); - return (-1); + assert(i == Z_OK || i == Z_STREAM_END); + return (1); } static int __match_proto__() @@ -505,7 +510,12 @@ vfp_gunzip_end(struct worker *w) vg = w->vgz_rx; w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); - VGZ_Destroy(&vg, -1); + if (w->fetch_failed) { + (void)VGZ_Destroy(&vg, -1); + return(0); + } + if (VGZ_Destroy(&vg, -1) != VGZ_END) + return(FetchError(w, "Gunzip error at the very end")); return (0); } @@ -541,6 +551,7 @@ vfp_gzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) size_t dl; const void *dp; + AZ(w->fetch_failed); vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); @@ -550,15 +561,15 @@ vfp_gzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) if (l > bytes) l = bytes; wl = HTC_Read(htc, ibuf, l); - if (wl <= 0) + if (wl < 0) + return(FetchError(w, htc->error)); + if (wl == 0) return (wl); VGZ_Ibuf(vg, ibuf, wl); bytes -= wl; } - if (VGZ_ObufStorage(w, vg)) { - htc->error = "Could not get storage"; - return (-1); - } + if (VGZ_ObufStorage(w, vg)) + return(FetchError(w, "Could not get storage")); i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL); assert(i == Z_OK); w->fetch_obj->len += dl; @@ -579,19 +590,22 @@ vfp_gzip_end(struct worker *w) vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); w->vgz_rx = NULL; - if (vg->error == NULL) { - do { - VGZ_Ibuf(vg, "", 0); - if (VGZ_ObufStorage(w, vg)) - return (-1); - i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); - w->fetch_obj->len += dl; - } while (i != Z_STREAM_END); - if (w->do_stream) - RES_StreamPoll(w); - VGZ_UpdateObj(vg, w->fetch_obj); + if (w->fetch_failed) { + (void)VGZ_Destroy(&vg, -1); + return(0); } - VGZ_Destroy(&vg, -1); + do { + VGZ_Ibuf(vg, "", 0); + if (VGZ_ObufStorage(w, vg)) + return(FetchError(w, "Could not get storage")); + i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); + w->fetch_obj->len += dl; + } while (i != Z_STREAM_END); + if (w->do_stream) + RES_StreamPoll(w); + VGZ_UpdateObj(vg, w->fetch_obj); + if (VGZ_Destroy(&vg, -1) != VGZ_END) + return(FetchError(w, "Gzip error at the very end")); return (0); } @@ -627,21 +641,21 @@ vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) const void *dp; struct storage *st; + AZ(w->fetch_failed); vg = w->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0) { st = FetchStorage(w, 0); - if (st == NULL) { - htc->error = "Could not get storage"; - vg->error = htc->error; - return (-1); - } + if (st == NULL) + return(FetchError(w, "Could not get storage")); l = st->space - st->len; if (l > bytes) l = bytes; wl = HTC_Read(htc, st->ptr + st->len, l); - if (wl <= 0) + if (wl < 0) + return(FetchError(w, htc->error)); + if (wl == 0) return (wl); bytes -= wl; VGZ_Ibuf(vg, st->ptr + st->len, wl); @@ -653,23 +667,15 @@ vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) while (!VGZ_IbufEmpty(vg)) { VGZ_Obuf(vg, obuf, sizeof obuf); i = VGZ_Gunzip(vg, &dp, &dl); - if (i == VGZ_END && !VGZ_IbufEmpty(vg)) { - htc->error = "Junk after gzip data"; - return (-1); - } - if (i != VGZ_OK && i != VGZ_END) { - htc->error = "See other message"; - WSLB(w, SLT_FetchError, - "Invalid Gzip data: %s", vg->vz.msg); - return (-1); - } + if (i == VGZ_END && !VGZ_IbufEmpty(vg)) + return(FetchError(w, "Junk after gzip data")); + if (i != VGZ_OK && i != VGZ_END) + return(FetchError2(w, + "Invalid Gzip data", vg->vz.msg)); } } - if (i == VGZ_OK || i == VGZ_END) - return (1); - htc->error = "See other message"; - WSLB(w, SLT_FetchError, "Gunzip trouble (%d)", i); - return (-1); + assert(i == VGZ_OK || i == VGZ_END); + return (1); } static int __match_proto__() @@ -680,8 +686,13 @@ vfp_testgzip_end(struct worker *w) vg = w->vgz_rx; w->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); + if (w->fetch_failed) { + (void)VGZ_Destroy(&vg, -1); + return(0); + } VGZ_UpdateObj(vg, w->fetch_obj); - VGZ_Destroy(&vg, -1); + if (VGZ_Destroy(&vg, -1) != VGZ_END) + return(FetchError(w, "TestGunzip error at the very end")); return (0); } diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c index 84606b6..04d2da5 100644 --- a/bin/varnishd/cache_response.c +++ b/bin/varnishd/cache_response.c @@ -182,7 +182,7 @@ res_WriteGunzipObj(const struct sess *sp) (void)WRW_Write(sp->wrk, obuf, obufl); (void)WRW_Flush(sp->wrk); } - VGZ_Destroy(&vg, sp->vsl_id); + (void)VGZ_Destroy(&vg, sp->vsl_id); assert(u == sp->obj->len); } diff --git a/bin/varnishtest/tests/g00004.vtc b/bin/varnishtest/tests/g00004.vtc new file mode 100644 index 0000000..5d518e0 --- /dev/null +++ b/bin/varnishtest/tests/g00004.vtc @@ -0,0 +1,43 @@ +varnishtest "truncated gzip from backend" + +server s1 -repeat 2 { + rxreq + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "18\r\n" + # A truncate gzip file + sendhex "1f8b" + sendhex "08" + sendhex "00" + sendhex "f5 64 ae 4e 02 03 f3 cd cf 53 f0 4f" + sendhex "2e 51 30 36 54 30 b0 b4" + send "\r\n" + chunkedlen 0 + +} -start + +varnish v1 \ + -arg {-p diag_bitmap=0x00010000} \ + -vcl+backend { + sub vcl_fetch { + if (req.url == "/gunzip") { + set beresp.do_gunzip = true; + } + } +} + +varnish v1 -start + +client c1 { + txreq + rxresp + expect resp.status == 503 +} -run + +client c1 { + txreq -url /gunzip + rxresp + expect resp.status == 503 +} -run + diff --git a/bin/varnishtest/tests/r01037.vtc b/bin/varnishtest/tests/r01037.vtc new file mode 100644 index 0000000..acb77d3 --- /dev/null +++ b/bin/varnishtest/tests/r01037.vtc @@ -0,0 +1,29 @@ +varnishtest "Test case for #1037" + +server s1 { + rxreq + # Send a bodylen of 1,5M, which will exceed cache space of 1M + non-fatal + txresp -nolen -hdr "Transfer-encoding: chunked" + chunked {} + chunkedlen 500000 + chunked {} + chunkedlen 500000 + chunked {} + chunkedlen 500000 + chunkedlen 0 +} -start + +varnish v1 -arg "-smalloc,1M" -arg "-pgzip_level=0" -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + set beresp.do_gzip = true; + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == "503" +} -run + From phk at varnish-cache.org Mon Oct 31 14:22:24 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 15:22:24 +0100 Subject: [master] 2b47445 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache Message-ID: commit 2b4744555f48c7314f4aaaf42a1749c09e9acdef Merge: 6e4e013 e9e02a4 Author: Poul-Henning Kamp Date: Mon Oct 31 14:22:10 2011 +0000 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache From phk at varnish-cache.org Mon Oct 31 21:38:19 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 22:38:19 +0100 Subject: [master] 01dfd01 More cleanup and simplification of FetchError reporting. Message-ID: commit 01dfd019aafca831af9adabc0bcc17a03097a40d Author: Poul-Henning Kamp Date: Mon Oct 31 21:37:47 2011 +0000 More cleanup and simplification of FetchError reporting. diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h index 53e8ae8..1875ece 100644 --- a/bin/varnishd/cache.h +++ b/bin/varnishd/cache.h @@ -199,7 +199,6 @@ struct http_conn { struct ws *ws; txt rxbuf; txt pipeline; - const char *error; }; /*--------------------------------------------------------------------*/ @@ -785,7 +784,7 @@ void HTC_Init(struct http_conn *htc, struct ws *ws, int fd, unsigned vsl_id, unsigned maxbytes, unsigned maxhdr); int HTC_Reinit(struct http_conn *htc); int HTC_Rx(struct http_conn *htc); -ssize_t HTC_Read(struct http_conn *htc, void *d, size_t len); +ssize_t HTC_Read(struct worker *w, struct http_conn *htc, void *d, size_t len); int HTC_Complete(struct http_conn *htc); #define HTTPH(a, b, c, d, e, f, g) extern char b[]; diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index 1c75054..728436c 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -44,7 +44,8 @@ */ static ssize_t -vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes) +vef_read(struct worker *w, struct http_conn *htc, void *buf, ssize_t buflen, + ssize_t bytes) { ssize_t d; @@ -55,7 +56,7 @@ vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes) if (d < bytes) bytes = d; } - return (HTC_Read(htc, buf, bytes)); + return (HTC_Read(w, htc, buf, bytes)); } /*--------------------------------------------------------------------- @@ -74,7 +75,7 @@ vfp_esi_bytes_uu(struct worker *w, struct http_conn *htc, ssize_t bytes) st = FetchStorage(w, 0); if (st == NULL) return (-1); - wl = vef_read(htc, + wl = vef_read(w, htc, st->ptr + st->len, st->space - st->len, bytes); if (wl <= 0) return (wl); @@ -105,14 +106,14 @@ vfp_esi_bytes_gu(struct worker *w, struct http_conn *htc, ssize_t bytes) while (bytes > 0) { if (VGZ_IbufEmpty(vg) && bytes > 0) { - wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + wl = vef_read(w, htc, ibuf, sizeof ibuf, bytes); if (wl <= 0) return (wl); VGZ_Ibuf(vg, ibuf, wl); bytes -= wl; } if (VGZ_ObufStorage(w, vg)) - return(FetchError(w, "Could not get storage")); + return(-1); i = VGZ_Gunzip(vg, &dp, &dl); xxxassert(i == VGZ_OK || i == VGZ_END); VEP_Parse(w, dp, dl); @@ -180,7 +181,7 @@ vfp_vep_callback(struct worker *w, ssize_t l, enum vgz_flag flg) } do { if (VGZ_ObufStorage(w, vef->vgz)) { - vef->error = errno; + vef->error = ENOMEM; vef->tot += l; return (vef->tot); } @@ -203,7 +204,7 @@ vfp_vep_callback(struct worker *w, ssize_t l, enum vgz_flag flg) } static int -vfp_esi_bytes_ug(const struct worker *w, struct http_conn *htc, ssize_t bytes) +vfp_esi_bytes_ug(struct worker *w, struct http_conn *htc, ssize_t bytes) { ssize_t wl; char ibuf[params->gzip_stack_buffer]; @@ -214,7 +215,7 @@ vfp_esi_bytes_ug(const struct worker *w, struct http_conn *htc, ssize_t bytes) CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); while (bytes > 0) { - wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + wl = vef_read(w, htc, ibuf, sizeof ibuf, bytes); if (wl <= 0) return (wl); bytes -= wl; @@ -240,7 +241,7 @@ vfp_esi_bytes_ug(const struct worker *w, struct http_conn *htc, ssize_t bytes) */ static int -vfp_esi_bytes_gg(const struct worker *w, struct http_conn *htc, size_t bytes) +vfp_esi_bytes_gg(struct worker *w, struct http_conn *htc, size_t bytes) { ssize_t wl; char ibuf[params->gzip_stack_buffer]; @@ -257,7 +258,7 @@ vfp_esi_bytes_gg(const struct worker *w, struct http_conn *htc, size_t bytes) ibuf2[0] = 0; /* For Flexelint */ while (bytes > 0) { - wl = vef_read(htc, ibuf, sizeof ibuf, bytes); + wl = vef_read(w, htc, ibuf, sizeof ibuf, bytes); if (wl <= 0) return (wl); bytes -= wl; @@ -334,6 +335,7 @@ vfp_esi_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); AZ(w->fetch_failed); AN(w->vep); + assert(w->htc == htc); if (w->is_gzip && w->do_gunzip) i = vfp_esi_bytes_gu(w, htc, bytes); else if (w->is_gunzip && w->do_gzip) diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index dd3a1c7..fb2ce41 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -120,14 +120,12 @@ vfp_nop_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) while (bytes > 0) { st = FetchStorage(w, 0); if (st == NULL) - return(FetchError(w, "Could not get storage")); + return(-1); l = st->space - st->len; if (l > bytes) l = bytes; - wl = HTC_Read(htc, st->ptr + st->len, l); - if (wl < 0) - return(FetchError(w, htc->error)); - if (wl == 0) + wl = HTC_Read(w, htc, st->ptr + st->len, l); + if (wl <= 0) return (wl); st->len += wl; w->fetch_obj->len += wl; @@ -173,7 +171,8 @@ static struct vfp vfp_nop = { }; /*-------------------------------------------------------------------- - * Fetch Storage + * Fetch Storage to put object into. + * */ struct storage * @@ -196,7 +195,7 @@ FetchStorage(struct worker *w, ssize_t sz) l = params->fetch_chunksize * 1024LL; st = STV_alloc(w, l); if (st == NULL) { - errno = ENOMEM; + (void)FetchError(w, "Could not get storage"); return (NULL); } AZ(st->len); @@ -247,17 +246,11 @@ fetch_straight(struct worker *w, struct http_conn *htc, ssize_t cl) return (0); } -/*--------------------------------------------------------------------*/ -/* XXX: Cleanup. It must be possible somehow :-( */ - -#define CERR() do { \ - if (i != 1) { \ - WSLB(w, SLT_FetchError, \ - "chunked read_error: %d (%s)", \ - errno, htc->error); \ - return (-1); \ - } \ - } while (0) +/*-------------------------------------------------------------------- + * Read a chunked HTTP object. + * XXX: Reading one byte at a time is pretty pessimal. + */ + static int fetch_chunked(struct worker *w, struct http_conn *htc) @@ -271,15 +264,17 @@ fetch_chunked(struct worker *w, struct http_conn *htc) do { /* Skip leading whitespace */ do { - i = HTC_Read(htc, buf, 1); - CERR(); + i = HTC_Read(w, htc, buf, 1); + if (i <= 0) + return (i); } while (vct_islws(buf[0])); /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { - i = HTC_Read(htc, buf + u, 1); - CERR(); + i = HTC_Read(w, htc, buf + u, 1); + if (i <= 0) + return (i); } while (u == 1 && buf[0] == '0' && buf[u] == '0'); if (!vct_ishex(buf[u])) break; @@ -290,8 +285,9 @@ fetch_chunked(struct worker *w, struct http_conn *htc) /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') { - i = HTC_Read(htc, buf + u, 1); - CERR(); + i = HTC_Read(w, htc, buf + u, 1); + if (i <= 0) + return (i); } if (buf[u] != '\n') @@ -306,11 +302,13 @@ fetch_chunked(struct worker *w, struct http_conn *htc) if (i <= 0) return (-1); } - i = HTC_Read(htc, buf, 1); - CERR(); + i = HTC_Read(w, htc, buf, 1); + if (i <= 0) + return (-1); if (buf[0] == '\r') { - i = HTC_Read(htc, buf, 1); - CERR(); + i = HTC_Read(w, htc, buf, 1); + if (i <= 0) + return (-1); } if (buf[0] != '\n') return (FetchError(w,"chunked tail no NL")); @@ -358,7 +356,7 @@ FetchReqBody(struct sess *sp) rdcnt = sizeof buf; else rdcnt = content_length; - rdcnt = HTC_Read(sp->htc, buf, rdcnt); + rdcnt = HTC_Read(sp->wrk, sp->htc, buf, rdcnt); if (rdcnt <= 0) return (1); content_length -= rdcnt; @@ -459,7 +457,7 @@ FetchHdr(struct sess *sp) if (i < 0) { WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)", - i, errno, w->htc->error); + i, errno, strerror(errno)); VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ /* Retryable if we never received anything */ @@ -473,7 +471,7 @@ FetchHdr(struct sess *sp) if (i < 0) { WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)", - i, errno, w->htc->error); + i, errno, strerror(errno)); VDI_CloseFd(sp->wrk); /* XXX: other cleanup ? */ return (-1); diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c index 73f4bb9..1820ffc 100644 --- a/bin/varnishd/cache_gzip.c +++ b/bin/varnishd/cache_gzip.c @@ -480,17 +480,15 @@ vfp_gunzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) l = sizeof ibuf; if (l > bytes) l = bytes; - wl = HTC_Read(htc, ibuf, l); - if (wl < 0) - return(FetchError(w, htc->error)); - if (wl == 0) + wl = HTC_Read(w, htc, ibuf, l); + if (wl <= 0) return (wl); VGZ_Ibuf(vg, ibuf, wl); bytes -= wl; } if (VGZ_ObufStorage(w, vg)) - return(FetchError(w, "Could not get storage")); + return(-1); i = VGZ_Gunzip(vg, &dp, &dl); if (i != VGZ_OK && i != VGZ_END) return(FetchError(w, "Gunzip data error")); @@ -560,16 +558,14 @@ vfp_gzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) l = sizeof ibuf; if (l > bytes) l = bytes; - wl = HTC_Read(htc, ibuf, l); - if (wl < 0) - return(FetchError(w, htc->error)); - if (wl == 0) + wl = HTC_Read(w, htc, ibuf, l); + if (wl <= 0) return (wl); VGZ_Ibuf(vg, ibuf, wl); bytes -= wl; } if (VGZ_ObufStorage(w, vg)) - return(FetchError(w, "Could not get storage")); + return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL); assert(i == Z_OK); w->fetch_obj->len += dl; @@ -597,7 +593,7 @@ vfp_gzip_end(struct worker *w) do { VGZ_Ibuf(vg, "", 0); if (VGZ_ObufStorage(w, vg)) - return(FetchError(w, "Could not get storage")); + return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); w->fetch_obj->len += dl; } while (i != Z_STREAM_END); @@ -648,14 +644,12 @@ vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes) while (bytes > 0) { st = FetchStorage(w, 0); if (st == NULL) - return(FetchError(w, "Could not get storage")); + return(-1); l = st->space - st->len; if (l > bytes) l = bytes; - wl = HTC_Read(htc, st->ptr + st->len, l); - if (wl < 0) - return(FetchError(w, htc->error)); - if (wl == 0) + wl = HTC_Read(w, htc, st->ptr + st->len, l); + if (wl <= 0) return (wl); bytes -= wl; VGZ_Ibuf(vg, st->ptr + st->len, wl); diff --git a/bin/varnishd/cache_httpconn.c b/bin/varnishd/cache_httpconn.c index ba881c9..1b718e5 100644 --- a/bin/varnishd/cache_httpconn.c +++ b/bin/varnishd/cache_httpconn.c @@ -27,6 +27,17 @@ * SUCH DAMAGE. * * HTTP protocol requests + * + * The trouble with the "until magic sequence" design of HTTP protocol messages + * is that either you have to read a single character at a time, which is + * inefficient, or you risk reading too much, and pre-read some of the object, + * or even the next pipelined request, which follows the one you want. + * + * HTC reads a HTTP protocol header into a workspace, subject to limits, + * and stops when we see the magic marker (double [CR]NL), and if we overshoot, + * it keeps track of the "pipelined" data. + * + * We use this both for client and backend connections. */ #include "config.h" @@ -53,7 +64,8 @@ htc_header_complete(txt *t) /* Skip any leading white space */ for (p = t->b ; vct_issp(*p); p++) continue; - if (*p == '\0') { + if (p == t->e) { + /* All white space */ t->e = t->b; *t->e = '\0'; return (0); @@ -85,7 +97,6 @@ HTC_Init(struct http_conn *htc, struct ws *ws, int fd, unsigned vsl_id, htc->vsl_id = vsl_id; htc->maxbytes = maxbytes; htc->maxhdr = maxhdr; - htc->error = "No error recorded"; (void)WS_Reserve(htc->ws, htc->maxbytes); htc->rxbuf.b = ws->f; @@ -107,7 +118,6 @@ HTC_Reinit(struct http_conn *htc) unsigned l; CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); - htc->error = "No error recorded"; (void)WS_Reserve(htc->ws, htc->maxbytes); htc->rxbuf.b = htc->ws->f; htc->rxbuf.e = htc->ws->f; @@ -123,7 +133,7 @@ HTC_Reinit(struct http_conn *htc) } /*-------------------------------------------------------------------- - * + * Return 1 if we have a complete HTTP procol header */ int @@ -137,6 +147,8 @@ HTC_Complete(struct http_conn *htc) if (i == 0) return (0); WS_ReleaseP(htc->ws, htc->rxbuf.e); + AZ(htc->pipeline.b); + AZ(htc->pipeline.e); if (htc->rxbuf.b + i < htc->rxbuf.e) { htc->pipeline.b = htc->rxbuf.b + i; htc->pipeline.e = htc->rxbuf.e; @@ -168,6 +180,10 @@ HTC_Rx(struct http_conn *htc) } i = read(htc->fd, htc->rxbuf.e, i); if (i <= 0) { + /* + * We wouldn't come here if we had a complete HTTP header + * so consequently an EOF can not be OK + */ WS_ReleaseP(htc->ws, htc->rxbuf.b); return (-1); } @@ -176,16 +192,21 @@ HTC_Rx(struct http_conn *htc) return (HTC_Complete(htc)); } +/*-------------------------------------------------------------------- + * Read up to len bytes, returning pipelined data first. + */ + ssize_t -HTC_Read(struct http_conn *htc, void *d, size_t len) +HTC_Read(struct worker *w, struct http_conn *htc, void *d, size_t len) { size_t l; unsigned char *p; ssize_t i; + CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); l = 0; p = d; - CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); if (htc->pipeline.b) { l = Tlen(htc->pipeline); if (l > len) @@ -201,9 +222,8 @@ HTC_Read(struct http_conn *htc, void *d, size_t len) return (l); i = read(htc->fd, p, len); if (i < 0) { - htc->error = strerror(errno); + WSL(w, SLT_FetchError, htc->vsl_id, "%s", strerror(errno)); return (i); - } else if (i == 0) - htc->error = "Remote closed connection"; + } return (i + l); } From phk at varnish-cache.org Mon Oct 31 22:20:13 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 23:20:13 +0100 Subject: [master] 8d2badd Polish the chunked body fetcher. It still irks me that it does one byte reads for the hex-length headers. Message-ID: commit 8d2badd80efbf33cd17aa6b48d33e33e55e53bbf Author: Poul-Henning Kamp Date: Mon Oct 31 22:19:45 2011 +0000 Polish the chunked body fetcher. It still irks me that it does one byte reads for the hex-length headers. diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index fb2ce41..516517f 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -248,9 +248,9 @@ fetch_straight(struct worker *w, struct http_conn *htc, ssize_t cl) /*-------------------------------------------------------------------- * Read a chunked HTTP object. + * * XXX: Reading one byte at a time is pretty pessimal. */ - static int fetch_chunked(struct worker *w, struct http_conn *htc) @@ -264,17 +264,18 @@ fetch_chunked(struct worker *w, struct http_conn *htc) do { /* Skip leading whitespace */ do { - i = HTC_Read(w, htc, buf, 1); - if (i <= 0) - return (i); + if (HTC_Read(w, htc, buf, 1) <= 0) + return (-1); } while (vct_islws(buf[0])); + if (!vct_ishex(buf[0])) + return (FetchError(w,"chunked header non-hex")); + /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { - i = HTC_Read(w, htc, buf + u, 1); - if (i <= 0) - return (i); + if (HTC_Read(w, htc, buf + u, 1) <= 0) + return (-1); } while (u == 1 && buf[0] == '0' && buf[u] == '0'); if (!vct_ishex(buf[u])) break; @@ -284,40 +285,32 @@ fetch_chunked(struct worker *w, struct http_conn *htc) return (FetchError(w,"chunked header too long")); /* Skip trailing white space */ - while(vct_islws(buf[u]) && buf[u] != '\n') { - i = HTC_Read(w, htc, buf + u, 1); - if (i <= 0) - return (i); - } + while(vct_islws(buf[u]) && buf[u] != '\n') + if (HTC_Read(w, htc, buf + u, 1) <= 0) + return (-1); if (buf[u] != '\n') return (FetchError(w,"chunked header no NL")); - buf[u] = '\0'; + buf[u] = '\0'; cl = fetch_number(buf, 16); - if (cl < 0) { + if (cl < 0) return (FetchError(w,"chunked header number syntax")); - } else if (cl > 0) { - i = w->vfp->bytes(w, htc, cl); - if (i <= 0) - return (-1); - } + + if (cl > 0 && w->vfp->bytes(w, htc, cl) <= 0) + return (-1); + i = HTC_Read(w, htc, buf, 1); if (i <= 0) return (-1); - if (buf[0] == '\r') { - i = HTC_Read(w, htc, buf, 1); - if (i <= 0) - return (-1); - } + if (buf[0] == '\r' && HTC_Read(w, htc, buf, 1) <= 0) + return (-1); if (buf[0] != '\n') return (FetchError(w,"chunked tail no NL")); } while (cl > 0); return (0); } -#undef CERR - /*--------------------------------------------------------------------*/ static int From phk at varnish-cache.org Mon Oct 31 22:59:34 2011 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 31 Oct 2011 23:59:34 +0100 Subject: [master] 76ca3a1 Remove a bit of stale debugging. Message-ID: commit 76ca3a10089adb2993d817ff1967e0079cbbed4a Author: Poul-Henning Kamp Date: Mon Oct 31 22:59:25 2011 +0000 Remove a bit of stale debugging. diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c index 516517f..ed1e5c8 100644 --- a/bin/varnishd/cache_fetch.c +++ b/bin/varnishd/cache_fetch.c @@ -91,10 +91,6 @@ static void __match_proto__() vfp_nop_begin(struct worker *w, size_t estimate) { - if (fetchfrag > 0) { - estimate = fetchfrag; - WSLB(w, SLT_Debug, "Fetch %d byte segments:", fetchfrag); - } if (estimate > 0) (void)FetchStorage(w, estimate); }