From apj at varnish-cache.org Sun Aug 5 21:51:52 2012 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Sun, 05 Aug 2012 23:51:52 +0200 Subject: [3.0] c3a7126 Duplicate changelog entry Message-ID: commit c3a71262a789df753578804e993191c33bab1022 Author: Andreas Plesner Jacobsen Date: Sun Aug 5 23:51:31 2012 +0200 Duplicate changelog entry diff --git a/doc/changes.rst b/doc/changes.rst index 1035f88..946974c 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -28,8 +28,6 @@ Varnishd - Add CLI commands to manually control health state of a backend. - Fix an issue where the s_bodybytes counter is not updated correctly on gunzipped delivery. -- Fix a race on the n_sess counter that leads to increased session object - allocation. `Bug #897`_. - Fix a crash when we couldn't allocate memory for a fetched object. `Bug #1100`_. - Fix an issue where objects could end up in the transient store with a From phk at varnish-cache.org Mon Aug 6 08:12:58 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 06 Aug 2012 10:12:58 +0200 Subject: [master] d47db77 Add the version identifier to the CLI banner. Message-ID: commit d47db772a308970b8e0b61cbc985e51c1a2e2947 Author: Poul-Henning Kamp Date: Mon Aug 6 08:12:13 2012 +0000 Add the version identifier to the CLI banner. Inspired by: patch from geoff diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c index 3b0c1a7..6f319f6 100644 --- a/bin/varnishd/mgt/mgt_cli.c +++ b/bin/varnishd/mgt/mgt_cli.c @@ -80,6 +80,7 @@ mcf_banner(struct cli *cli, const char *const *av, void *priv) 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, "%s\n", VCS_version); VCLI_Out(cli, "\n"); VCLI_Out(cli, "Type 'help' for command list.\n"); VCLI_Out(cli, "Type 'quit' to close CLI session.\n"); diff --git a/include/vcs.h b/include/vcs.h index f764100..d3a1585 100644 --- a/include/vcs.h +++ b/include/vcs.h @@ -29,4 +29,5 @@ */ /* from libvarnish/version.c */ +extern const char *VCS_version; void VCS_Message(const char *); diff --git a/lib/libvarnish/version.c b/lib/libvarnish/version.c index 2220a69..b7b2edc 100644 --- a/lib/libvarnish/version.c +++ b/lib/libvarnish/version.c @@ -36,11 +36,13 @@ #include "vcs.h" #include "vcs_version.h" +const char *VCS_version = + PACKAGE_TARNAME "-" PACKAGE_VERSION " revision " VCS_Version; + void VCS_Message(const char *progname) { - fprintf(stderr, "%s (%s-%s revision %s)\n", progname, - PACKAGE_TARNAME, PACKAGE_VERSION, VCS_Version); + fprintf(stderr, "%s (%s)\n", progname, VCS_version); fprintf(stderr, "Copyright (c) 2006 Verdens Gang AS\n"); fprintf(stderr, "Copyright (c) 2006-2011 Varnish Software AS\n"); } From phk at varnish-cache.org Mon Aug 6 08:29:19 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 06 Aug 2012 10:29:19 +0200 Subject: [master] 38a7199 Add updated Solaris Sandbox from Nils Goroll Message-ID: commit 38a7199215f5f76ef771f55e44d25ae11d3b3f06 Author: Poul-Henning Kamp Date: Mon Aug 6 08:28:52 2012 +0000 Add updated Solaris Sandbox from Nils Goroll (untested by me) diff --git a/bin/varnishd/mgt/mgt_sandbox.c b/bin/varnishd/mgt/mgt_sandbox.c index bf9802f..069d660 100644 --- a/bin/varnishd/mgt/mgt_sandbox.c +++ b/bin/varnishd/mgt/mgt_sandbox.c @@ -57,8 +57,7 @@ /*--------------------------------------------------------------------*/ -/* Waive all privileges in the child, it does not need any */ - +#ifndef HAVE_SETPPRIV static void __match_proto__(mgt_sandbox_f) mgt_sandbox_unix(enum sandbox_e who) { @@ -70,6 +69,7 @@ mgt_sandbox_unix(enum sandbox_e who) REPORT0(LOG_INFO, "Not running as root, no priv-sep"); } } +#endif /*--------------------------------------------------------------------*/ @@ -90,7 +90,7 @@ mgt_sandbox_linux(enum sandbox_e who) /*--------------------------------------------------------------------*/ mgt_sandbox_f *mgt_sandbox = -#ifdef HAVE_SETPRIV +#ifdef HAVE_SETPPRIV mgt_sandbox_solaris; #elif defined (__linux__) mgt_sandbox_linux; diff --git a/bin/varnishd/mgt/mgt_sandbox_solaris.c b/bin/varnishd/mgt/mgt_sandbox_solaris.c index e043fef..d443cc0 100644 --- a/bin/varnishd/mgt/mgt_sandbox_solaris.c +++ b/bin/varnishd/mgt/mgt_sandbox_solaris.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006-2011 Varnish Software AS + * Copyright (c) 2011-2012 UPLEX - Nils Goroll Systemoptimierung * All rights reserved. * * Author: Poul-Henning Kamp @@ -38,6 +39,7 @@ #include #endif #include +#include #include #include #include @@ -95,49 +97,113 @@ * */ -/* effective during runtime of the child */ -static inline void -mgt_sandbox_solaris_add_effective(priv_set_t *pset) +static void +mgt_sandbox_solaris_add_inheritable(priv_set_t *pset, enum sandbox_e who) { - /* PSARC/2009/685 - 8eca52188202 - onnv_132 */ - priv_addset(pset, "net_access"); + switch (who) { + case SANDBOX_VCC: + break; + case SANDBOX_CC: + priv_addset(pset, "proc_exec"); + priv_addset(pset, "proc_fork"); + /* PSARC/2009/378 - 63678502e95e - onnv_140 */ + priv_addset(pset, "file_read"); + priv_addset(pset, "file_write"); + break; + case SANDBOX_VCLLOAD: + break; + case SANDBOX_WORKER: + break; + default: + REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__); + exit(1); + } +} + +/* + * effective is initialized from inheritable (see mgt_sandbox_solaris_waive) + * so only additionally required privileges need to be added here + */ - /* PSARC/2009/378 - 63678502e95e - onnv_140 */ - priv_addset(pset, "file_read"); - priv_addset(pset, "file_write"); +static void +mgt_sandbox_solaris_add_effective(priv_set_t *pset, enum sandbox_e who) +{ + switch (who) { + case SANDBOX_VCC: + /* PSARC/2009/378 - 63678502e95e - onnv_140 */ + priv_addset(pset, "file_write"); + break; + case SANDBOX_CC: + break; + case SANDBOX_VCLLOAD: + /* PSARC/2009/378 - 63678502e95e - onnv_140 */ + priv_addset(pset, "file_read"); + case SANDBOX_WORKER: + /* PSARC/2009/685 - 8eca52188202 - onnv_132 */ + priv_addset(pset, "net_access"); + /* PSARC/2009/378 - 63678502e95e - onnv_140 */ + priv_addset(pset, "file_read"); + priv_addset(pset, "file_write"); + break; + default: + REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__); + exit(1); + } } -/* permitted during runtime of the child - for privilege bracketing */ -static inline void -mgt_sandbox_solaris_add_permitted(priv_set_t *pset) +/* + * permitted is initialized from effective (see mgt_sandbox_solaris_waive) + * so only additionally required privileges need to be added here + */ + +static void +mgt_sandbox_solaris_add_permitted(priv_set_t *pset, enum sandbox_e who) { - /* for raising limits in cache_waiter_ports.c */ - priv_addset(pset, PRIV_SYS_RESOURCE); + switch (who) { + case SANDBOX_VCC: + case SANDBOX_CC: + case SANDBOX_VCLLOAD: + break; + case SANDBOX_WORKER: + /* for raising limits in cache_waiter_ports.c */ + priv_addset(pset, PRIV_SYS_RESOURCE); + break; + default: + REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__); + exit(1); + } } -/* effective during mgt_sandbox */ -static inline void -mgt_sandbox_solaris_add_initial(priv_set_t *pset) +/* + * additional privileges needed by mgt_sandbox_solaris_privsep - + * will get waived in mgt_sandbox_solaris_waive + */ +static void +mgt_sandbox_solaris_add_initial(priv_set_t *pset, enum sandbox_e who) { + (void)who; + /* for setgid/setuid */ priv_addset(pset, PRIV_PROC_SETID); } /* * if we are not yet privilege-aware already (ie we have been started - * not-privilege aware wird euid 0), we need to grab any additional privileges - * needed during mgt_standbox, until we reduce to least privileges in - * mgt_sandbox_waive, otherwise we would loose them with setuid() + * not-privilege aware with euid 0), we try to grab any privileges we + * will need later. + * We will reduce to least privileges in mgt_sandbox_solaris_waive + * + * We need to become privilege-aware to avoid setuid resetting them. */ -void -mgt_sandbox_solaris_init(void) +static void +mgt_sandbox_solaris_init(enum sandbox_e who) { priv_set_t *priv_all; if (! (priv_all = priv_allocset())) { REPORT(LOG_ERR, - "Child start warning: " + "Sandbox warning: " " mgt_sandbox_init - priv_allocset failed: errno=%d (%s)", errno, strerror(errno)); return; @@ -145,9 +211,10 @@ mgt_sandbox_solaris_init(void) priv_emptyset(priv_all); - mgt_sandbox_solaris_add_effective(priv_all); - mgt_sandbox_solaris_add_permitted(priv_all); - mgt_sandbox_solaris_add_initial(priv_all); + mgt_sandbox_solaris_add_inheritable(priv_all, who); + mgt_sandbox_solaris_add_effective(priv_all, who); + mgt_sandbox_solaris_add_permitted(priv_all, who); + mgt_sandbox_solaris_add_initial(priv_all, who); setppriv(PRIV_ON, PRIV_PERMITTED, priv_all); setppriv(PRIV_ON, PRIV_EFFECTIVE, priv_all); @@ -156,9 +223,11 @@ mgt_sandbox_solaris_init(void) priv_freeset(priv_all); } -void -mgt_sandbox_solaris_privsep(void) +static void +mgt_sandbox_solaris_privsep(enum sandbox_e who) { + (void)who; + if (priv_ineffect(PRIV_PROC_SETID)) { if (getgid() != mgt_param.gid) XXXAZ(setgid(mgt_param.gid)); @@ -187,8 +256,8 @@ mgt_sandbox_solaris_privsep(void) * We should keep sys_resource in P in order to adjust our limits if we need to */ -void -mgt_sandbox_solaris_fini(void) +static void +mgt_sandbox_solaris_waive(enum sandbox_e who) { priv_set_t *effective, *inheritable, *permitted; @@ -196,19 +265,22 @@ mgt_sandbox_solaris_fini(void) !(inheritable = priv_allocset()) || !(permitted = priv_allocset())) { REPORT(LOG_ERR, - "Child start warning: " + "Sandbox warning: " " mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)", errno, strerror(errno)); return; } + /* simple scheme: (inheritable subset-of effective) subset-of permitted */ + priv_emptyset(inheritable); + mgt_sandbox_solaris_add_inheritable(inheritable, who); - priv_emptyset(effective); - mgt_sandbox_solaris_add_effective(effective); + priv_copyset(inheritable, effective); + mgt_sandbox_solaris_add_effective(effective, who); priv_copyset(effective, permitted); - mgt_sandbox_solaris_add_permitted(permitted); + mgt_sandbox_solaris_add_permitted(permitted, who); /* * invert the sets and clear privileges such that setppriv will always @@ -221,7 +293,7 @@ mgt_sandbox_solaris_fini(void) #define SETPPRIV(which, set) \ if (setppriv(PRIV_OFF, which, set)) \ REPORT(LOG_ERR, \ - "Child start warning: " \ + "Sandbox warning: " \ " Waiving privileges failed on %s: errno=%d (%s)", \ #which, errno, strerror(errno)); @@ -233,6 +305,14 @@ mgt_sandbox_solaris_fini(void) priv_freeset(inheritable); priv_freeset(effective); + priv_freeset(permitted); } +void __match_proto__(mgt_sandbox_f) +mgt_sandbox_solaris(enum sandbox_e who) +{ + mgt_sandbox_solaris_init(who); + mgt_sandbox_solaris_privsep(who); + mgt_sandbox_solaris_waive(who); +} #endif /* HAVE_SETPPRIV */ From phk at varnish-cache.org Mon Aug 6 09:59:34 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 06 Aug 2012 11:59:34 +0200 Subject: [master] 57412eb Disable CLANG for now, until some auto* magic happens to remove the -g option from linker-commands. Message-ID: commit 57412ebfc088ec242e93722337f110c0f40f79b1 Author: Poul-Henning Kamp Date: Mon Aug 6 09:58:21 2012 +0000 Disable CLANG for now, until some auto* magic happens to remove the -g option from linker-commands. diff --git a/autogen.des b/autogen.des index 58f3c2b..3a706f3 100755 --- a/autogen.des +++ b/autogen.des @@ -9,6 +9,10 @@ make -k distclean > /dev/null 2>&1 || true # Prefer CLANG if we have it, and have not given preferences if [ -f /usr/bin/clang -a "x${CC}" = "x" ] ; then CC=clang + + # XXX: clang complains about -g in linker invocations + # XXX: so fall back to gcc for now... + CC=gcc export CC fi From phk at varnish-cache.org Mon Aug 6 09:59:34 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 06 Aug 2012 11:59:34 +0200 Subject: [master] fe2ad14 Finally split cache_center.c into a HTTP/1 and a Request Finite State Machine. Message-ID: commit fe2ad14cdc379db7c5de9454ac1d8135849e1af3 Author: Poul-Henning Kamp Date: Mon Aug 6 09:58:49 2012 +0000 Finally split cache_center.c into a HTTP/1 and a Request Finite State Machine. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index bd91dd7..967d3bb 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -17,7 +17,6 @@ varnishd_SOURCES = \ cache/cache_backend_poll.c \ cache/cache_ban.c \ cache/cache_busyobj.c \ - cache/cache_center.c \ cache/cache_cli.c \ cache/cache_dir.c \ cache/cache_dir_dns.c \ @@ -31,6 +30,7 @@ varnishd_SOURCES = \ cache/cache_gzip.c \ cache/cache_hash.c \ cache/cache_http.c \ + cache/cache_http1_fsm.c \ cache/cache_httpconn.c \ cache/cache_lck.c \ cache/cache_main.c \ @@ -38,6 +38,7 @@ varnishd_SOURCES = \ cache/cache_panic.c \ cache/cache_pipe.c \ cache/cache_pool.c \ + cache/cache_req_fsm.c \ cache/cache_response.c \ cache/cache_rfc2616.c \ cache/cache_session.c \ diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c deleted file mode 100644 index dc7b4cc..0000000 --- a/bin/varnishd/cache/cache_center.c +++ /dev/null @@ -1,1662 +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 file contains the two central state machine for pushing - * sessions and requests. - * - * The first part of the file, entrypoint CNT_Session() and down to - * the ==== separator, is concerned with sessions. When a session has - * a request to deal with, it calls into the second half of the file. - * This part is for all practical purposes HTTP/1.x specific. - * - * The second part of the file, entrypoint CNT_Request() and below the - * ==== separator, is intended to (over time) be(ome) protocol agnostic. - * We already use this now with ESI:includes, which are for all relevant - * purposes a different "protocol" - * - * A special complication is the fact that we can suspend processing of - * a request when hash-lookup finds a busy objhdr. - * - * Since the states are rather nasty in detail, I have decided to embedd - * a dot(1) graph in the source code comments. So to see the big picture, - * extract the DOT lines and run though dot(1), for instance with the - * command: - * sed -n '/^DOT/s///p' cache/cache_center.c | dot -Tps > /tmp/_.ps - */ - -/* -DOT digraph vcl_center { -xDOT page="8.2,11.5" -DOT size="7.2,10.5" -DOT margin="0.5" -DOT center="1" -DOT acceptor [ -DOT shape=hexagon -DOT label="Request received" -DOT ] -DOT ERROR [shape=plaintext] -DOT RESTART [shape=plaintext] -DOT acceptor -> first [style=bold,color=green] - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "cache.h" - -#include "hash/hash_slinger.h" -#include "vcl.h" -#include "vcli_priv.h" -#include "vsha256.h" -#include "vtcp.h" -#include "vtim.h" - -#ifndef HAVE_SRANDOMDEV -#include "compat/srandomdev.h" -#endif - -static unsigned xids; - -/*-------------------------------------------------------------------- - * WAIT - * Collect the request from the client. - * -DOT subgraph xcluster_wait { -DOT wait [ -DOT shape=box -DOT label="cnt_sess_wait:\nwait for\ncomplete\nrequest" -DOT ] -DOT herding [shape=hexagon] -DOT wait -> start [label="got req",style=bold,color=green] -DOT wait -> "SES_Delete()" [label="errors"] -DOT wait -> herding [label="timeout_linger"] -DOT herding -> wait [label="fd read_ready"] -DOT } - */ - -static int -cnt_sess_wait(struct sess *sp, struct worker *wrk, struct req *req) -{ - int j, tmo; - struct pollfd pfd[1]; - double now, when; - enum sess_close why = SC_NULL; - enum htc_status_e hs; - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - assert(req->sp == sp); - - - AZ(req->vcl); - AZ(req->obj); - AZ(req->esi_level); - assert(req->xid == 0); - assert(isnan(req->t_req)); - assert(isnan(req->t_resp)); - - tmo = (int)(1e3 * cache_param->timeout_linger); - while (1) { - pfd[0].fd = sp->fd; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - j = poll(pfd, 1, tmo); - assert(j >= 0); - now = VTIM_real(); - if (j != 0) - hs = HTC_Rx(req->htc); - else - hs = HTC_Complete(req->htc); - if (hs == HTC_COMPLETE) { - /* Got it, run with it */ - req->t_req = now; - return (0); - } else if (hs == HTC_ERROR_EOF) { - why = SC_REM_CLOSE; - break; - } else if (hs == HTC_OVERFLOW) { - why = SC_RX_OVERFLOW; - break; - } else if (hs == HTC_ALL_WHITESPACE) { - /* Nothing but whitespace */ - when = sp->t_idle + cache_param->timeout_idle; - if (when < now) { - why = SC_RX_TIMEOUT; - break; - } - when = sp->t_idle + cache_param->timeout_linger; - tmo = (int)(1e3 * (when - now)); - if (when < now || tmo == 0) { - req->t_req = NAN; - wrk->stats.sess_herd++; - SES_ReleaseReq(req); - WAIT_Enter(sp); - return (1); - } - } else { - /* Working on it */ - if (isnan(req->t_req)) - req->t_req = now; - when = req->t_req + cache_param->timeout_req; - tmo = (int)(1e3 * (when - now)); - if (when < now || tmo == 0) { - why = SC_RX_TIMEOUT; - break; - } - } - } - SES_ReleaseReq(req); - assert(why != SC_NULL); - SES_Delete(sp, why, now); - return (1); -} - -/*-------------------------------------------------------------------- - * This is the final state, figure out if we should close or recycle - * the client connection - * -DOT DONE [ -DOT shape=record -DOT label="{cnt_done:|Request completed}" -DOT ] -DOT ESI_RESP [ shape=hexagon ] -DOT DONE -> start [label="full pipeline"] -DOT DONE -> wait -DOT DONE -> ESI_RESP - */ - -enum cnt_sess_done_ret { - SESS_DONE_RET_GONE, - SESS_DONE_RET_WAIT, - SESS_DONE_RET_START, -}; - -static enum cnt_sess_done_ret -cnt_sess_done(struct sess *sp, struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC); - - AZ(req->obj); - AZ(req->busyobj); - req->director = NULL; - req->restarts = 0; - - AZ(req->esi_level); - - if (req->vcl != NULL) { - if (wrk->vcl != NULL) - VCL_Rel(&wrk->vcl); - wrk->vcl = req->vcl; - req->vcl = NULL; - } - - sp->t_idle = W_TIM_real(wrk); - if (req->xid == 0) - req->t_resp = sp->t_idle; - req->xid = 0; - VSL_Flush(req->vsl, 0); - - req->t_req = NAN; - req->t_resp = NAN; - - req->req_bodybytes = 0; - - req->hash_always_miss = 0; - req->hash_ignore_busy = 0; - - if (sp->fd >= 0 && req->doclose != SC_NULL) - SES_Close(sp, req->doclose); - - if (sp->fd < 0) { - wrk->stats.sess_closed++; - AZ(req->vcl); - SES_ReleaseReq(req); - SES_Delete(sp, SC_NULL, NAN); - return (SESS_DONE_RET_GONE); - } - - if (wrk->stats.client_req >= cache_param->wthread_stats_rate) - WRK_SumStat(wrk); - - WS_Reset(req->ws, NULL); - WS_Reset(wrk->aws, NULL); - req->vxid = VXID_Get(&wrk->vxid_pool); - - if (HTC_Reinit(req->htc) == HTC_COMPLETE) { - req->t_req = sp->t_idle; - wrk->stats.sess_pipeline++; - return (SESS_DONE_RET_START); - } else { - if (Tlen(req->htc->rxbuf)) - wrk->stats.sess_readahead++; - return (SESS_DONE_RET_WAIT); - } -} - -/*-------------------------------------------------------------------- - */ - -void -CNT_Session(struct worker *wrk, struct req *req) -{ - int done; - struct sess *sp; - enum cnt_sess_done_ret sdr; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - - /* - * 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 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->sess_step == S_STP_NEWREQ && VTCP_blocking(sp->fd)) { - if (errno == ECONNRESET) - SES_Close(sp, SC_REM_CLOSE); - else - SES_Close(sp, SC_TX_ERROR); - sdr = cnt_sess_done(sp, wrk, req); - assert(sdr == SESS_DONE_RET_GONE); - return; - } - - if (sp->sess_step == S_STP_NEWREQ) { - HTC_Init(req->htc, req->ws, sp->fd, req->vsl, - cache_param->http_req_size, - cache_param->http_req_hdr_len); - } - - while (1) { - /* - * Possible entrance states - */ - - assert( - sp->sess_step == S_STP_NEWREQ || - req->req_step == R_STP_LOOKUP || - req->req_step == R_STP_START); - - if (sp->sess_step == S_STP_WORKING) { - done = CNT_Request(wrk, req); - if (done == 2) - return; - assert(done == 1); - sdr = cnt_sess_done(sp, wrk, req); - switch (sdr) { - case SESS_DONE_RET_GONE: - return; - case SESS_DONE_RET_WAIT: - sp->sess_step = S_STP_NEWREQ; - break; - case SESS_DONE_RET_START: - sp->sess_step = S_STP_WORKING; - req->req_step = R_STP_START; - break; - default: - WRONG("Illegal enum cnt_sess_done_ret"); - } - } - - if (sp->sess_step == S_STP_NEWREQ) { - done = cnt_sess_wait(sp, wrk, req); - if (done) - return; - sp->sess_step = S_STP_WORKING; - req->req_step = R_STP_START; - } - } -} - -/*====================================================================*/ - - -/*-------------------------------------------------------------------- - * We have a refcounted object on the session, and possibly the busyobj - * which is fetching it, prepare a response. - * -DOT subgraph xcluster_prepresp { -DOT prepresp [ -DOT shape=record -DOT label="{cnt_prepresp:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{error?|restart?}|stream ?}" -DOT ] -DOT prepresp -> deliver [style=bold,color=green,label=deliver] -DOT prepresp -> deliver [style=bold,color=red] -DOT prepresp -> deliver [style=bold,color=blue] -DOT } - * - */ - -static int -cnt_prepresp(struct worker *wrk, struct req *req) -{ - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - bo = req->busyobj; - CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); - - CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - - req->res_mode = 0; - - if (bo == NULL) { - if (!req->disable_esi && req->obj->esidata != NULL) { - /* In ESI mode, we can't know the aggregate length */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI; - } else { - req->res_mode |= RES_LEN; - } - } else { - AZ(bo->do_esi); - } - - if (req->esi_level > 0) { - /* Included ESI object, always CHUNKED or EOF */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_ESI_CHILD; - } - - if (cache_param->http_gzip_support && req->obj->gziped && - !RFC2616_Req_Gzip(req->http)) { - /* - * We don't know what it uncompresses to - * XXX: we could cache that - */ - req->res_mode &= ~RES_LEN; - req->res_mode |= RES_GUNZIP; - } - - if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { - /* We havn't chosen yet, do so */ - if (!req->wantbody) { - /* Nothing */ - } else if (req->http->protover >= 11) { - req->res_mode |= RES_CHUNKED; - } else { - req->res_mode |= RES_EOF; - req->doclose = SC_TX_EOF; - } - } - - req->t_resp = W_TIM_real(wrk); - if (req->obj->objcore->objhead != NULL) { - if ((req->t_resp - req->obj->last_lru) > - cache_param->lru_timeout && - EXP_Touch(req->obj->objcore)) - req->obj->last_lru = req->t_resp; - if (!cache_param->obj_readonly) - req->obj->last_use = req->t_resp; /* XXX: locking ? */ - } - HTTP_Setup(req->resp, req->ws, req->vsl, HTTP_Resp); - RES_BuildHttp(req); - - VCL_deliver_method(req); - switch (req->handling) { - case VCL_RET_DELIVER: - break; - case VCL_RET_RESTART: - if (req->restarts >= cache_param->max_restarts) - break; - if (bo != NULL) { - AN(bo->do_stream); - (void)HSH_Deref(&wrk->stats, NULL, &req->obj); - VBO_DerefBusyObj(wrk, &req->busyobj); - } else { - (void)HSH_Deref(&wrk->stats, NULL, &req->obj); - } - AZ(req->obj); - http_Teardown(req->resp); - req->req_step = R_STP_RESTART; - return (0); - default: - WRONG("Illegal action in vcl_deliver{}"); - } - req->req_step = R_STP_DELIVER; - return (0); -} - -/*-------------------------------------------------------------------- - * Deliver an already stored object - * -DOT subgraph xcluster_deliver { -DOT deliver [ -DOT shape=record -DOT label="{cnt_deliver:|Send body}" -DOT ] -DOT } -DOT deliver -> DONE [style=bold,color=green] -DOT deliver -> DONE [style=bold,color=red] -DOT deliver -> DONE [style=bold,color=blue] - * - */ - -static int -cnt_deliver(struct worker *wrk, struct req *req) -{ - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - bo = req->busyobj; - CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); - - if (bo != NULL) { - while (bo->state < BOS_FAILED) - (void)usleep(10000); - assert(bo->state >= BOS_FAILED); - - if (bo->state == BOS_FAILED) { - HSH_Deref(&wrk->stats, NULL, &req->obj); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->err_code = 503; - req->req_step = R_STP_ERROR; - return (0); - } - VBO_DerefBusyObj(wrk, &req->busyobj); - } - - AZ(req->busyobj); - req->director = NULL; - req->restarts = 0; - - RES_WriteObj(req); - - /* No point in saving the body if it is hit-for-pass */ - if (req->obj->objcore->flags & OC_F_PASS) - STV_Freestore(req->obj); - - assert(WRW_IsReleased(wrk)); - (void)HSH_Deref(&wrk->stats, NULL, &req->obj); - http_Teardown(req->resp); - return (1); -} -/*-------------------------------------------------------------------- - * Emit an error - * -DOT subgraph xcluster_error { -DOT vcl_error [ -DOT shape=record -DOT label="vcl_error()|resp." -DOT ] -DOT ERROR -> vcl_error -DOT vcl_error-> prepresp [label=deliver] -DOT } -DOT vcl_error-> rsterr [label="restart",color=purple] -DOT rsterr [label="RESTART",shape=plaintext] - */ - -static int -cnt_error(struct worker *wrk, struct req *req) -{ - struct http *h; - struct busyobj *bo; - char date[40]; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AZ(req->objcore); - AZ(req->obj); - AZ(req->busyobj); - - bo = VBO_GetBusyObj(wrk); - req->busyobj = bo; - bo->vsl->wid = req->sp->vsl_id; - AZ(bo->stats); - bo->stats = &wrk->stats; - req->objcore = HSH_NewObjCore(wrk); - req->obj = STV_NewObject(bo, &req->objcore, - TRANSIENT_STORAGE, cache_param->http_resp_size, - (uint16_t)cache_param->http_max_hdr); - bo->stats = NULL; - if (req->obj == NULL) { - req->doclose = SC_OVERLOAD; - req->director = NULL; - http_Teardown(bo->beresp); - http_Teardown(bo->bereq); - return(1); - } - CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - req->obj->xid = req->xid; - req->obj->exp.entered = req->t_req; - - h = req->obj->http; - - if (req->err_code < 100 || req->err_code > 999) - req->err_code = 501; - - http_PutProtocol(h, "HTTP/1.1"); - http_PutStatus(h, req->err_code); - VTIM_format(W_TIM_real(wrk), date); - http_PrintfHeader(h, "Date: %s", date); - http_SetHeader(h, "Server: Varnish"); - - if (req->err_reason != NULL) - http_PutResponse(h, req->err_reason); - else - http_PutResponse(h, http_StatusMessage(req->err_code)); - VCL_error_method(req); - - if (req->handling == VCL_RET_RESTART && - req->restarts < cache_param->max_restarts) { - HSH_Drop(wrk, &req->obj); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->req_step = R_STP_RESTART; - return (0); - } else if (req->handling == VCL_RET_RESTART) - req->handling = VCL_RET_DELIVER; - - - /* We always close when we take this path */ - req->doclose = SC_TX_ERROR; - req->wantbody = 1; - - assert(req->handling == VCL_RET_DELIVER); - req->err_code = 0; - req->err_reason = NULL; - http_Teardown(bo->bereq); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->req_step = R_STP_PREPRESP; - return (0); -} - -/*-------------------------------------------------------------------- - * Fetch response headers from the backend - * -DOT subgraph xcluster_fetch { -DOT fetch [ -DOT shape=record -DOT label="{cnt_fetch:|fetch hdr\nfrom backend|(find obj.ttl)|{vcl_fetch\{\}|{req.|bereq.|beresp.}}|{error?|restart?}}" -DOT ] -DOT } -DOT fetch -> fetchbody [style=bold,color=red] -DOT fetch -> fetchbody [style=bold,color=blue] - */ - -static int -cnt_fetch(struct worker *wrk, struct req *req) -{ - int i, need_host_hdr; - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - bo = req->busyobj; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - AN(req->director); - AZ(bo->vbc); - AZ(bo->should_close); - AZ(req->storage_hint); - - HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp); - - need_host_hdr = !http_GetHdr(bo->bereq, H_Host, NULL); - - req->acct_req.fetch++; - - i = FetchHdr(req, need_host_hdr, req->objcore->objhead == NULL); - /* - * If we recycle a backend connection, there is a finite chance - * that the backend closed it before we get a request to it. - * Do a single retry in that case. - */ - if (i == 1) { - VSC_C_main->backend_retry++; - i = FetchHdr(req, need_host_hdr, req->objcore->objhead == NULL); - } - - if (i) { - req->handling = VCL_RET_ERROR; - req->err_code = 503; - } else { - /* - * These two headers can be spread over multiple actual headers - * and we rely on their content outside of VCL, so collect them - * into one line here. - */ - http_CollectHdr(bo->beresp, H_Cache_Control); - http_CollectHdr(bo->beresp, H_Vary); - - /* - * Figure out how the fetch is supposed to happen, before the - * headers are adultered by VCL - * NB: Also sets other wrk variables - */ - bo->body_status = RFC2616_Body(bo, &wrk->stats); - - req->err_code = http_GetStatus(bo->beresp); - - /* - * What does RFC2616 think about TTL ? - */ - EXP_Clr(&bo->exp); - bo->exp.entered = W_TIM_real(wrk); - RFC2616_Ttl(bo, req->xid); - - /* pass from vclrecv{} has negative TTL */ - if (req->objcore->objhead == NULL) - bo->exp.ttl = -1.; - - AZ(bo->do_esi); - AZ(bo->do_pass); - - VCL_fetch_method(req); - - if (bo->do_pass) - req->objcore->flags |= OC_F_PASS; - - switch (req->handling) { - case VCL_RET_DELIVER: - req->req_step = R_STP_FETCHBODY; - return (0); - default: - break; - } - - /* We are not going to fetch the body, Close the connection */ - VDI_CloseFd(&bo->vbc); - } - - /* Clean up partial fetch */ - AZ(bo->vbc); - - if (req->objcore->objhead != NULL || req->handling == VCL_RET_ERROR) { - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); - req->objcore = NULL; - } - assert(bo->refcount == 2); - VBO_DerefBusyObj(wrk, &bo); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->director = NULL; - req->storage_hint = NULL; - - switch (req->handling) { - case VCL_RET_RESTART: - req->req_step = R_STP_RESTART; - return (0); - case VCL_RET_ERROR: - req->req_step = R_STP_ERROR; - return (0); - default: - WRONG("Illegal action in vcl_fetch{}"); - } -} - -/*-------------------------------------------------------------------- - * Prepare to fetch body from backend - * -DOT subgraph xcluster_body { -DOT fetchbody [ -DOT shape=record -DOT label="{cnt_fetchbody:|start fetch_thread}" -DOT ] -DOT } -DOT fetchbody:out -> prepresp [style=bold,color=red] -DOT fetchbody:out -> prepresp [style=bold,color=blue] - */ - -static int -cnt_fetchbody(struct worker *wrk, struct req *req) -{ - struct http *hp, *hp2; - char *b; - uint16_t nhttp; - unsigned l; - struct vsb *vary = NULL; - int varyl = 0, pass; - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - bo = req->busyobj; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - - assert(req->handling == VCL_RET_DELIVER); - - if (req->objcore->objhead == NULL) { - /* This is a pass from vcl_recv */ - pass = 1; - /* VCL may have fiddled this, but that doesn't help */ - bo->exp.ttl = -1.; - } else if (bo->do_pass) { - pass = 1; - } else { - /* regular object */ - pass = 0; - } - - /* - * The VCL variables beresp.do_g[un]zip tells us how we want the - * object processed before it is stored. - * - * The backend Content-Encoding header tells us what we are going - * to receive, which we classify in the following three classes: - * - * "Content-Encoding: gzip" --> object is gzip'ed. - * no Content-Encoding --> object is not gzip'ed. - * anything else --> do nothing wrt gzip - * - */ - - /* We do nothing unless the param is set */ - if (!cache_param->http_gzip_support) - bo->do_gzip = bo->do_gunzip = 0; - - bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); - - bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); - - /* It can't be both */ - assert(bo->is_gzip == 0 || bo->is_gunzip == 0); - - /* We won't gunzip unless it is gzip'ed */ - if (bo->do_gunzip && !bo->is_gzip) - bo->do_gunzip = 0; - - /* If we do gunzip, remove the C-E header */ - if (bo->do_gunzip) - http_Unset(bo->beresp, H_Content_Encoding); - - /* We wont gzip unless it is ungziped */ - if (bo->do_gzip && !bo->is_gunzip) - bo->do_gzip = 0; - - /* If we do gzip, add the C-E header */ - if (bo->do_gzip) - http_SetHeader(bo->beresp, "Content-Encoding: gzip"); - - /* But we can't do both at the same time */ - assert(bo->do_gzip == 0 || bo->do_gunzip == 0); - - /* ESI takes precedence and handles gzip/gunzip itself */ - if (bo->do_esi) - bo->vfp = &vfp_esi; - else if (bo->do_gunzip) - bo->vfp = &vfp_gunzip; - else if (bo->do_gzip) - bo->vfp = &vfp_gzip; - else if (bo->is_gzip) - bo->vfp = &vfp_testgzip; - - if (bo->do_esi || req->esi_level > 0) - bo->do_stream = 0; - if (!req->wantbody) - bo->do_stream = 0; - - /* No reason to try streaming a non-existing body */ - if (bo->body_status == BS_NONE) - bo->do_stream = 0; - - l = http_EstimateWS(bo->beresp, - pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp); - - /* Create Vary instructions */ - if (req->objcore->objhead != NULL) { - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - vary = VRY_Create(req, bo->beresp); - if (vary != NULL) { - varyl = VSB_len(vary); - assert(varyl > 0); - l += varyl; - } - } - - /* - * Space for producing a Content-Length: header including padding - * A billion gigabytes is enough for anybody. - */ - l += strlen("Content-Length: XxxXxxXxxXxxXxxXxx") + sizeof(void *); - - if (bo->exp.ttl < cache_param->shortlived || - req->objcore == NULL) - req->storage_hint = TRANSIENT_STORAGE; - - AZ(bo->stats); - bo->stats = &wrk->stats; - req->obj = STV_NewObject(bo, &req->objcore, req->storage_hint, l, - nhttp); - if (req->obj == NULL) { - /* - * Try to salvage the transaction by allocating a - * shortlived object on Transient storage. - */ - if (bo->exp.ttl > cache_param->shortlived) - bo->exp.ttl = cache_param->shortlived; - bo->exp.grace = 0.0; - bo->exp.keep = 0.0; - req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE, - l, nhttp); - } - bo->stats = NULL; - if (req->obj == NULL) { - req->err_code = 503; - req->req_step = R_STP_ERROR; - VDI_CloseFd(&bo->vbc); - VBO_DerefBusyObj(wrk, &req->busyobj); - return (0); - } - CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - - req->storage_hint = NULL; - - AZ(bo->fetch_obj); - bo->fetch_obj = req->obj; - - if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip)) - req->obj->gziped = 1; - - if (vary != NULL) { - req->obj->vary = (void *)WS_Alloc(req->obj->http->ws, varyl); - AN(req->obj->vary); - memcpy(req->obj->vary, VSB_data(vary), varyl); - VRY_Validate(req->obj->vary); - VSB_delete(vary); - } - - req->obj->xid = req->xid; - req->obj->response = req->err_code; - WS_Assert(req->obj->ws_o); - - /* Filter into object */ - hp = bo->beresp; - hp2 = req->obj->http; - - hp2->logtag = HTTP_Obj; - http_FilterResp(hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS); - http_CopyHome(hp2); - - if (http_GetHdr(hp, H_Last_Modified, &b)) - req->obj->last_modified = VTIM_parse(b); - else - req->obj->last_modified = floor(bo->exp.entered); - - assert(WRW_IsReleased(wrk)); - - /* - * If we can deliver a 304 reply, we don't bother streaming. - * Notice that vcl_deliver{} could still nuke the headers - * that allow the 304, in which case we return 200 non-stream. - */ - if (req->obj->response == 200 && - req->http->conds && - RFC2616_Do_Cond(req)) - bo->do_stream = 0; - - /* - * Ready to fetch the body - */ - bo->fetch_task.func = FetchBody; - bo->fetch_task.priv = bo; - - assert(bo->refcount == 2); /* one for each thread */ - - if (req->obj->objcore->objhead != NULL) { - EXP_Insert(req->obj); - AN(req->obj->objcore->ban); - AZ(req->obj->ws_o->overflow); - HSH_Unbusy(&wrk->stats, req->obj->objcore); - } - - if (!bo->do_stream || - Pool_Task(wrk->pool, &bo->fetch_task, POOL_NO_QUEUE)) - FetchBody(wrk, bo); - - if (req->obj->objcore->objhead != NULL) - HSH_Ref(req->obj->objcore); - - if (bo->state == BOS_FINISHED) { - VBO_DerefBusyObj(wrk, &req->busyobj); - } else if (bo->state == BOS_FAILED) { - /* handle early failures */ - HSH_Deref(&wrk->stats, NULL, &req->obj); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->err_code = 503; - req->req_step = R_STP_ERROR; - return (0); - } - - assert(WRW_IsReleased(wrk)); - req->req_step = R_STP_PREPRESP; - return (0); -} - -/*-------------------------------------------------------------------- - * HIT - * We had a cache hit. Ask VCL, then march off as instructed. - * -DOT subgraph xcluster_hit { -DOT hit [ -DOT shape=record -DOT label="{cnt_hit:|{vcl_hit()|{req.|obj.}}|{error?|restart?}|{deliver?|pass?}}" -DOT ] -DOT } -XDOT hit:err -> err_hit [label="error"] -XDOT err_hit [label="ERROR",shape=plaintext] -XDOT hit:rst -> rst_hit [label="restart",color=purple] -XDOT rst_hit [label="RESTART",shape=plaintext] -DOT hit:pass -> pass [label=pass,style=bold,color=red] -DOT hit:del -> prepresp [label="deliver",style=bold,color=green] - */ - -static int -cnt_hit(struct worker *wrk, struct req *req) -{ - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - AZ(req->objcore); - AZ(req->busyobj); - - assert(!(req->obj->objcore->flags & OC_F_PASS)); - - VCL_hit_method(req); - - if (req->handling == VCL_RET_DELIVER) { - //AZ(req->busyobj->bereq->ws); - //AZ(req->busyobj->beresp->ws); - (void)FetchReqBody(req, 0); - req->req_step = R_STP_PREPRESP; - return (0); - } - - /* Drop our object, we won't need it */ - (void)HSH_Deref(&wrk->stats, NULL, &req->obj); - req->objcore = NULL; - - switch(req->handling) { - case VCL_RET_PASS: - req->req_step = R_STP_PASS; - return (0); - case VCL_RET_ERROR: - req->req_step = R_STP_ERROR; - return (0); - case VCL_RET_RESTART: - req->req_step = R_STP_RESTART; - return (0); - default: - WRONG("Illegal action in vcl_hit{}"); - } -} - -/*-------------------------------------------------------------------- - * LOOKUP - * Hash things together and look object up in hash-table. - * - * LOOKUP consists of two substates so that we can reenter if we - * encounter a busy object. - * -DOT subgraph xcluster_lookup { -DOT lookup [ -DOT shape=record -DOT label="{cnt_lookup:|hash lookup|{busy ?|miss ?}|{no|obj.f.pass?|yes}}" -DOT ] -DOT } -DOT lookup:busy -> lookup:top [label="(waitinglist)"] -DOT lookup:miss -> miss [style=bold,color=blue] -DOT lookup:no -> hit [style=bold,color=green] -DOT lookup:yes -> pass [style=bold,color=red] - */ - -static int -cnt_lookup(struct worker *wrk, struct req *req) -{ - struct objcore *oc; - struct object *o; - struct objhead *oh; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AZ(req->objcore); - - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - AZ(req->busyobj); - - VRY_Prep(req); - - AZ(req->objcore); - oc = HSH_Lookup(req); - if (oc == NULL) { - /* - * We lost the session to a busy object, disembark the - * worker thread. We return to STP_LOOKUP when the busy - * object has been unbusied, and still have the hash digest - * around to do the lookup with. - */ - return (2); - } - AZ(req->objcore); - - CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - oh = oc->objhead; - CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); - - /* If we inserted a new object it's a miss */ - if (oc->flags & OC_F_BUSY) { - CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC); - assert(oc->busyobj == req->busyobj); - wrk->stats.cache_miss++; - - if (req->vary_l != NULL) { - assert(oc->busyobj->vary == req->vary_b); - VRY_Validate(oc->busyobj->vary); - WS_ReleaseP(req->ws, (void*)req->vary_l); - } else { - AZ(oc->busyobj->vary); - WS_Release(req->ws, 0); - } - req->vary_b = NULL; - req->vary_l = NULL; - req->vary_e = NULL; - - req->objcore = oc; - req->req_step = R_STP_MISS; - return (0); - } - - /* We are not prepared to do streaming yet */ - XXXAZ(req->busyobj); - - o = oc_getobj(&wrk->stats, oc); - CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - req->obj = o; - - WS_Release(req->ws, 0); - req->vary_b = NULL; - req->vary_l = NULL; - req->vary_e = NULL; - - if (oc->flags & OC_F_PASS) { - wrk->stats.cache_hitpass++; - VSLb(req->vsl, SLT_HitPass, "%u", req->obj->xid); - (void)HSH_Deref(&wrk->stats, NULL, &req->obj); - AZ(req->objcore); - req->req_step = R_STP_PASS; - return (0); - } - - wrk->stats.cache_hit++; - VSLb(req->vsl, SLT_Hit, "%u", req->obj->xid); - req->req_step = R_STP_HIT; - return (0); -} - -/*-------------------------------------------------------------------- - * We had a miss, ask VCL, proceed as instructed - * -DOT subgraph xcluster_miss { -DOT miss [ -DOT shape=record -DOT label="{cnt_miss:|filter req.-\>bereq.|{vcl_miss\{\}|{req.*|bereq.*}}|{error?|restart?}|{pass?|fetch?}}" -DOT ] -DOT } -DOT miss:fetch -> fetch [label="fetch",style=bold,color=blue] -DOT miss:pass -> pass [label="pass",style=bold,color=red] -DOT - */ - -static int -cnt_miss(struct worker *wrk, struct req *req) -{ - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); - bo = req->busyobj; - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - AZ(req->obj); - - HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); - http_FilterReq(req, HTTPH_R_FETCH); - http_ForceGet(bo->bereq); - if (cache_param->http_gzip_support) { - /* - * We always ask the backend for gzip, even if the - * client doesn't grok it. We will uncompress for - * the minority of clients which don't. - */ - http_Unset(bo->bereq, H_Accept_Encoding); - http_SetHeader(bo->bereq, "Accept-Encoding: gzip"); - } - - VCL_miss_method(req); - - if (req->handling == VCL_RET_FETCH) { - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - req->req_step = R_STP_FETCH; - return (0); - } - - AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); - req->objcore = NULL; - http_Teardown(bo->bereq); - VBO_DerefBusyObj(wrk, &req->busyobj); - - switch(req->handling) { - case VCL_RET_ERROR: - req->req_step = R_STP_ERROR; - break; - case VCL_RET_PASS: - req->req_step = R_STP_PASS; - break; - case VCL_RET_RESTART: - req->req_step = R_STP_RESTART; - break; - default: - WRONG("Illegal action in vcl_miss{}"); - } - return (0); -} - -/*-------------------------------------------------------------------- - * Start pass processing by getting headers from backend, then - * continue in passbody. - * -DOT subgraph xcluster_pass { -DOT pass [ -DOT shape=record -DOT label="{cnt_pass:|(XXX: deref obj.)|filter req.*-\>bereq.|{vcl_pass\{\}|{req.*|bereq.*}}|{error?|restart?}|create anon obj}" -DOT ] -DOT } -DOT pass:pass -> fetch [style=bold, color=red] -XDOT pass:rst -> rst_pass [label="restart",color=purple] -XDOT rst_pass [label="RESTART",shape=plaintext] -XDOT pass:err -> err_pass [label="error"] -XDOT err_pass [label="ERROR",shape=plaintext] - */ - -static int -cnt_pass(struct worker *wrk, struct req *req) -{ - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - AZ(req->objcore); - AZ(req->obj); - AZ(req->busyobj); - - req->busyobj = VBO_GetBusyObj(wrk); - bo = req->busyobj; - bo->vsl->wid = req->sp->vsl_id; - bo->refcount = 2; - HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); - http_FilterReq(req, HTTPH_R_PASS); - - VCL_pass_method(req); - - if (req->handling == VCL_RET_ERROR) { - http_Teardown(bo->bereq); - VBO_DerefBusyObj(wrk, &req->busyobj); - req->req_step = R_STP_ERROR; - return (0); - } - assert(req->handling == VCL_RET_PASS); - req->acct_req.pass++; - req->req_step = R_STP_FETCH; - - req->objcore = HSH_NewObjCore(wrk); - req->objcore->busyobj = bo; - return (0); -} - -/*-------------------------------------------------------------------- - * Ship the request header to the backend unchanged, then pipe - * until one of the ends close the connection. - * -DOT subgraph xcluster_pipe { -DOT pipe [ -DOT shape=ellipse -DOT label="Filter req.->bereq." -DOT ] -DOT vcl_pipe [ -DOT shape=record -DOT label="vcl_pipe()|req.\nbereq\." -DOT ] -DOT pipe_do [ -DOT shape=ellipse -DOT label="send bereq.\npipe until close" -DOT ] -DOT vcl_pipe -> pipe_do [label="pipe",style=bold,color=orange] -DOT pipe -> vcl_pipe [style=bold,color=orange] -DOT } -DOT pipe_do -> DONE [style=bold,color=orange] -DOT vcl_pipe -> err_pipe [label="error"] -DOT err_pipe [label="ERROR",shape=plaintext] - */ - -static int -cnt_pipe(struct worker *wrk, struct req *req) -{ - struct busyobj *bo; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - AZ(req->busyobj); - - req->acct_req.pipe++; - req->busyobj = VBO_GetBusyObj(wrk); - bo = req->busyobj; - bo->vsl->wid = req->sp->vsl_id; - HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); - http_FilterReq(req, 0); - - VCL_pipe_method(req); - - if (req->handling == VCL_RET_ERROR) - INCOMPL(); - assert(req->handling == VCL_RET_PIPE); - - PipeRequest(req); - assert(WRW_IsReleased(wrk)); - http_Teardown(bo->bereq); - VBO_DerefBusyObj(wrk, &req->busyobj); - return (1); -} - -/*-------------------------------------------------------------------- - * -DOT subgraph xcluster_restart { -DOT restart [ -DOT shape=record -DOT label="{cnt_restart}" -DOT ] -DOT } -DOT RESTART -> restart [color=purple] -DOT restart -> recv [color=purple] - */ - -static int -cnt_restart(const struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - req->director = NULL; - if (++req->restarts >= cache_param->max_restarts) { - req->err_code = 503; - req->req_step = R_STP_ERROR; - } else { - req->err_code = 0; - req->req_step = R_STP_RECV; - } - return (0); -} - -/*-------------------------------------------------------------------- - * RECV - * We have a complete request, set everything up and start it. - * We can come here both with a request from the client and with - * a interior request during ESI delivery. - * -DOT subgraph xcluster_recv { -DOT recv [ -DOT shape=record -DOT label="{cnt_recv:|{vcl_recv\{\}|req.*}|{pipe?|pass?|error?|lookup?}}" -DOT ] -DOT } -DOT subgraph xcluster_hash { -DOT hash [ -DOT shape=record -DOT label="{cnt_recv:|{vcl_hash\{\}|req.*}}" -DOT ] -DOT } -DOT ESI_REQ [ shape=hexagon ] -DOT ESI_REQ -> recv -DOT recv:pipe -> pipe [style=bold,color=orange] -DOT recv:pass -> pass [style=bold,color=red] -#DOT recv:error -> err_recv -#DOT err_recv [label="ERROR",shape=plaintext] -DOT recv:lookup -> hash [style=bold,color=green] -DOT hash -> lookup [label="hash",style=bold,color=green] - */ - -static int -cnt_recv(const struct worker *wrk, struct req *req) -{ - unsigned recv_handling; - struct SHA256Context sha256ctx; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); - AZ(req->obj); - AZ(req->busyobj); - - /* By default we use the first backend */ - AZ(req->director); - req->director = req->vcl->director[0]; - AN(req->director); - - req->disable_esi = 0; - req->hash_always_miss = 0; - req->hash_ignore_busy = 0; - req->client_identity = NULL; - - http_CollectHdr(req->http, H_Cache_Control); - - VCL_recv_method(req); - recv_handling = req->handling; - - if (cache_param->http_gzip_support && - (recv_handling != VCL_RET_PIPE) && - (recv_handling != VCL_RET_PASS)) { - if (RFC2616_Req_Gzip(req->http)) { - http_Unset(req->http, H_Accept_Encoding); - http_SetHeader(req->http, "Accept-Encoding: gzip"); - } else { - http_Unset(req->http, H_Accept_Encoding); - } - } - - req->sha256ctx = &sha256ctx; /* so HSH_AddString() can find it */ - SHA256_Init(req->sha256ctx); - VCL_hash_method(req); - assert(req->handling == VCL_RET_HASH); - SHA256_Final(req->digest, req->sha256ctx); - req->sha256ctx = NULL; - - if (!strcmp(req->http->hd[HTTP_HDR_REQ].b, "HEAD")) - req->wantbody = 0; - else - req->wantbody = 1; - - switch(recv_handling) { - case VCL_RET_LOOKUP: - req->req_step = R_STP_LOOKUP; - return (0); - case VCL_RET_PIPE: - if (req->esi_level > 0) { - /* XXX: VSL something */ - INCOMPL(); - return (1); - } - req->req_step = R_STP_PIPE; - return (0); - case VCL_RET_PASS: - req->req_step = R_STP_PASS; - return (0); - case VCL_RET_ERROR: - req->req_step = R_STP_ERROR; - return (0); - default: - WRONG("Illegal action in vcl_recv{}"); - } -} - -/*-------------------------------------------------------------------- - * START - * First time we see a request - * -DOT start [ -DOT shape=box -DOT label="cnt_start:\nDissect request\nHandle expect" -DOT ] -DOT start -> recv [style=bold,color=green] -DOT start -> DONE [label=errors] - */ - -static int -cnt_start(struct worker *wrk, struct req *req) -{ - char *p; - const char *r = "HTTP/1.1 100 Continue\r\n\r\n"; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AZ(req->restarts); - AZ(req->obj); - AZ(req->vcl); - AZ(req->esi_level); - assert(!isnan(req->t_req)); - - /* Update stats of various sorts */ - wrk->stats.client_req++; - req->acct_req.req++; - - /* Assign XID and log */ - req->xid = ++xids; /* XXX not locked */ - VSLb(req->vsl, SLT_ReqStart, "%s %s %u", - req->sp->addr, req->sp->port, req->xid); - - /* Borrow VCL reference from worker thread */ - VCL_Refresh(&wrk->vcl); - req->vcl = wrk->vcl; - wrk->vcl = NULL; - - EXP_Clr(&req->exp); - - HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); - req->err_code = http_DissectRequest(req); - - /* If we could not even parse the request, just close */ - if (req->err_code == 400) { - SES_Close(req->sp, SC_RX_JUNK); - return (1); - } - - req->ws_req = WS_Snapshot(req->ws); - - req->doclose = http_DoConnection(req->http); - - /* - * We want to deal with Expect: headers the first time we - * attempt the request, and remove them before we move on. - */ - if (req->err_code == 0 && http_GetHdr(req->http, H_Expect, &p)) { - if (strcasecmp(p, "100-continue")) { - req->err_code = 417; - } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { - SES_Close(req->sp, SC_REM_CLOSE); - return (1); - } - } - http_Unset(req->http, H_Expect); - - /* XXX: pull in req-body and make it available instead. */ - req->reqbodydone = 0; - - HTTP_Copy(req->http0, req->http); /* Copy for restart/ESI use */ - - if (req->err_code) - req->req_step = R_STP_ERROR; - else - req->req_step = R_STP_RECV; - return (0); -} - -/*-------------------------------------------------------------------- - * Central state engine dispatcher. - * - * Kick the session around until it has had enough. - * - */ - -static void -cnt_diag(struct req *req, const char *state) -{ - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - VSLb(req->vsl, SLT_Debug, "vsl_id %u STP_%s sp %p obj %p vcl %p", - req->sp->vsl_id, state, req->sp, req->obj, req->vcl); - VSL_Flush(req->vsl, 0); -} - -int -CNT_Request(struct worker *wrk, struct req *req) -{ - int done; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - /* - * Possible entrance states - */ - assert( - req->req_step == R_STP_LOOKUP || - req->req_step == R_STP_START || - req->req_step == R_STP_RECV); - - req->wrk = wrk; - - for (done = 0; !done; ) { - /* - * This is a good place to be paranoid about the various - * pointers still pointing to the things we expect. - */ - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); - WS_Assert(wrk->aws); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - switch (req->req_step) { -#define REQ_STEP(l,u,arg) \ - case R_STP_##u: \ - if (cache_param->diag_bitmap & 0x01) \ - cnt_diag(req, #u); \ - done = cnt_##l arg; \ - break; -#include "tbl/steps.h" -#undef REQ_STEP - default: - WRONG("State engine misfire"); - } - WS_Assert(wrk->aws); - CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); - } - if (done == 1) { - /* XXX: Workaround for pipe */ - if (req->sp->fd >= 0) { - VSLb(req->vsl, SLT_Length, "%ju", - (uintmax_t)req->req_bodybytes); - } - VSLb(req->vsl, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f", - req->xid, - req->t_req, - req->sp->t_idle, - req->sp->t_idle - req->t_resp, - req->t_resp - req->t_req, - req->sp->t_idle - req->t_resp); - - /* done == 2 was charged by cache_hash.c */ - SES_Charge(wrk, req); - } - - req->wrk = NULL; - - assert(WRW_IsReleased(wrk)); - return (done); -} - -/* -DOT } -*/ - -/*-------------------------------------------------------------------- - * Debugging aids - */ - -static void -cli_debug_xid(struct cli *cli, const char * const *av, void *priv) -{ - (void)priv; - if (av[2] != NULL) - xids = strtoul(av[2], NULL, 0); - VCLI_Out(cli, "XID is %u", xids); -} - -/* - * Default to seed=1, this is the only seed value POSIXl guarantees will - * result in a reproducible random number sequence. - */ -static void -cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) -{ - (void)priv; - unsigned seed = 1; - - if (av[2] != NULL) - seed = strtoul(av[2], NULL, 0); - srandom(seed); - srand48(random()); - VCLI_Out(cli, "Random(3) seeded with %u", seed); -} - -static struct cli_proto debug_cmds[] = { - { "debug.xid", "debug.xid", - "\tExamine or set XID\n", 0, 1, "d", cli_debug_xid }, - { "debug.srandom", "debug.srandom", - "\tSeed the random(3) function\n", 0, 1, "d", - cli_debug_srandom }, - { NULL } -}; - -/*-------------------------------------------------------------------- - * - */ - -void -CNT_Init(void) -{ - - srandomdev(); - srand48(random()); - xids = random(); - CLI_AddFuncs(debug_cmds); -} diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c new file mode 100644 index 0000000..586fd50 --- /dev/null +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -0,0 +1,348 @@ +/*- + * 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 file contains the two central state machine for pushing + * sessions and requests. + * + * The first part of the file, entrypoint CNT_Session() and down to + * the ==== separator, is concerned with sessions. When a session has + * a request to deal with, it calls into the second half of the file. + * This part is for all practical purposes HTTP/1.x specific. + * + * The second part of the file, entrypoint CNT_Request() and below the + * ==== separator, is intended to (over time) be(ome) protocol agnostic. + * We already use this now with ESI:includes, which are for all relevant + * purposes a different "protocol" + * + * A special complication is the fact that we can suspend processing of + * a request when hash-lookup finds a busy objhdr. + * + * Since the states are rather nasty in detail, I have decided to embedd + * a dot(1) graph in the source code comments. So to see the big picture, + * extract the DOT lines and run though dot(1), for instance with the + * command: + * sed -n '/^DOT/s///p' cache/cache_center.c | dot -Tps > /tmp/_.ps + */ + +/* +DOT digraph vcl_center { +xDOT page="8.2,11.5" +DOT size="7.2,10.5" +DOT margin="0.5" +DOT center="1" +DOT acceptor [ +DOT shape=hexagon +DOT label="Request received" +DOT ] +DOT ERROR [shape=plaintext] +DOT RESTART [shape=plaintext] +DOT acceptor -> first [style=bold,color=green] + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cache.h" + +#include "hash/hash_slinger.h" +#include "vcl.h" +#include "vcli_priv.h" +#include "vsha256.h" +#include "vtcp.h" +#include "vtim.h" + +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif + + +/*-------------------------------------------------------------------- + * WAIT + * Collect the request from the client. + * +DOT subgraph xcluster_wait { +DOT wait [ +DOT shape=box +DOT label="cnt_sess_wait:\nwait for\ncomplete\nrequest" +DOT ] +DOT herding [shape=hexagon] +DOT wait -> start [label="got req",style=bold,color=green] +DOT wait -> "SES_Delete()" [label="errors"] +DOT wait -> herding [label="timeout_linger"] +DOT herding -> wait [label="fd read_ready"] +DOT } + */ + +static int +cnt_sess_wait(struct sess *sp, struct worker *wrk, struct req *req) +{ + int j, tmo; + struct pollfd pfd[1]; + double now, when; + enum sess_close why = SC_NULL; + enum htc_status_e hs; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + assert(req->sp == sp); + + + AZ(req->vcl); + AZ(req->obj); + AZ(req->esi_level); + assert(req->xid == 0); + assert(isnan(req->t_req)); + assert(isnan(req->t_resp)); + + tmo = (int)(1e3 * cache_param->timeout_linger); + while (1) { + pfd[0].fd = sp->fd; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + j = poll(pfd, 1, tmo); + assert(j >= 0); + now = VTIM_real(); + if (j != 0) + hs = HTC_Rx(req->htc); + else + hs = HTC_Complete(req->htc); + if (hs == HTC_COMPLETE) { + /* Got it, run with it */ + req->t_req = now; + return (0); + } else if (hs == HTC_ERROR_EOF) { + why = SC_REM_CLOSE; + break; + } else if (hs == HTC_OVERFLOW) { + why = SC_RX_OVERFLOW; + break; + } else if (hs == HTC_ALL_WHITESPACE) { + /* Nothing but whitespace */ + when = sp->t_idle + cache_param->timeout_idle; + if (when < now) { + why = SC_RX_TIMEOUT; + break; + } + when = sp->t_idle + cache_param->timeout_linger; + tmo = (int)(1e3 * (when - now)); + if (when < now || tmo == 0) { + req->t_req = NAN; + wrk->stats.sess_herd++; + SES_ReleaseReq(req); + WAIT_Enter(sp); + return (1); + } + } else { + /* Working on it */ + if (isnan(req->t_req)) + req->t_req = now; + when = req->t_req + cache_param->timeout_req; + tmo = (int)(1e3 * (when - now)); + if (when < now || tmo == 0) { + why = SC_RX_TIMEOUT; + break; + } + } + } + SES_ReleaseReq(req); + assert(why != SC_NULL); + SES_Delete(sp, why, now); + return (1); +} + +/*-------------------------------------------------------------------- + * This is the final state, figure out if we should close or recycle + * the client connection + * +DOT DONE [ +DOT shape=record +DOT label="{cnt_done:|Request completed}" +DOT ] +DOT ESI_RESP [ shape=hexagon ] +DOT DONE -> start [label="full pipeline"] +DOT DONE -> wait +DOT DONE -> ESI_RESP + */ + +enum cnt_sess_done_ret { + SESS_DONE_RET_GONE, + SESS_DONE_RET_WAIT, + SESS_DONE_RET_START, +}; + +static enum cnt_sess_done_ret +cnt_sess_done(struct sess *sp, struct worker *wrk, struct req *req) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC); + + AZ(req->obj); + AZ(req->busyobj); + req->director = NULL; + req->restarts = 0; + + AZ(req->esi_level); + + if (req->vcl != NULL) { + if (wrk->vcl != NULL) + VCL_Rel(&wrk->vcl); + wrk->vcl = req->vcl; + req->vcl = NULL; + } + + sp->t_idle = W_TIM_real(wrk); + if (req->xid == 0) + req->t_resp = sp->t_idle; + req->xid = 0; + VSL_Flush(req->vsl, 0); + + req->t_req = NAN; + req->t_resp = NAN; + + req->req_bodybytes = 0; + + req->hash_always_miss = 0; + req->hash_ignore_busy = 0; + + if (sp->fd >= 0 && req->doclose != SC_NULL) + SES_Close(sp, req->doclose); + + if (sp->fd < 0) { + wrk->stats.sess_closed++; + AZ(req->vcl); + SES_ReleaseReq(req); + SES_Delete(sp, SC_NULL, NAN); + return (SESS_DONE_RET_GONE); + } + + if (wrk->stats.client_req >= cache_param->wthread_stats_rate) + WRK_SumStat(wrk); + + WS_Reset(req->ws, NULL); + WS_Reset(wrk->aws, NULL); + req->vxid = VXID_Get(&wrk->vxid_pool); + + if (HTC_Reinit(req->htc) == HTC_COMPLETE) { + req->t_req = sp->t_idle; + wrk->stats.sess_pipeline++; + return (SESS_DONE_RET_START); + } else { + if (Tlen(req->htc->rxbuf)) + wrk->stats.sess_readahead++; + return (SESS_DONE_RET_WAIT); + } +} + +/*-------------------------------------------------------------------- + */ + +void +CNT_Session(struct worker *wrk, struct req *req) +{ + int done; + struct sess *sp; + enum cnt_sess_done_ret sdr; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + sp = req->sp; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + + /* + * 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 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->sess_step == S_STP_NEWREQ && VTCP_blocking(sp->fd)) { + if (errno == ECONNRESET) + SES_Close(sp, SC_REM_CLOSE); + else + SES_Close(sp, SC_TX_ERROR); + sdr = cnt_sess_done(sp, wrk, req); + assert(sdr == SESS_DONE_RET_GONE); + return; + } + + if (sp->sess_step == S_STP_NEWREQ) { + HTC_Init(req->htc, req->ws, sp->fd, req->vsl, + cache_param->http_req_size, + cache_param->http_req_hdr_len); + } + + while (1) { + /* + * Possible entrance states + */ + + assert( + sp->sess_step == S_STP_NEWREQ || + req->req_step == R_STP_LOOKUP || + req->req_step == R_STP_START); + + if (sp->sess_step == S_STP_WORKING) { + done = CNT_Request(wrk, req); + if (done == 2) + return; + assert(done == 1); + sdr = cnt_sess_done(sp, wrk, req); + switch (sdr) { + case SESS_DONE_RET_GONE: + return; + case SESS_DONE_RET_WAIT: + sp->sess_step = S_STP_NEWREQ; + break; + case SESS_DONE_RET_START: + sp->sess_step = S_STP_WORKING; + req->req_step = R_STP_START; + break; + default: + WRONG("Illegal enum cnt_sess_done_ret"); + } + } + + if (sp->sess_step == S_STP_NEWREQ) { + done = cnt_sess_wait(sp, wrk, req); + if (done) + return; + sp->sess_step = S_STP_WORKING; + req->req_step = R_STP_START; + } + } +} diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c new file mode 100644 index 0000000..34cfbfa --- /dev/null +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -0,0 +1,1395 @@ +/*- + * 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 file contains the two central state machine for pushing + * sessions and requests. + * + * The first part of the file, entrypoint CNT_Session() and down to + * the ==== separator, is concerned with sessions. When a session has + * a request to deal with, it calls into the second half of the file. + * This part is for all practical purposes HTTP/1.x specific. + * + * The second part of the file, entrypoint CNT_Request() and below the + * ==== separator, is intended to (over time) be(ome) protocol agnostic. + * We already use this now with ESI:includes, which are for all relevant + * purposes a different "protocol" + * + * A special complication is the fact that we can suspend processing of + * a request when hash-lookup finds a busy objhdr. + * + * Since the states are rather nasty in detail, I have decided to embedd + * a dot(1) graph in the source code comments. So to see the big picture, + * extract the DOT lines and run though dot(1), for instance with the + * command: + * sed -n '/^DOT/s///p' cache/cache_center.c | dot -Tps > /tmp/_.ps + */ + +/* +DOT digraph vcl_center { +xDOT page="8.2,11.5" +DOT size="7.2,10.5" +DOT margin="0.5" +DOT center="1" +DOT acceptor [ +DOT shape=hexagon +DOT label="Request received" +DOT ] +DOT ERROR [shape=plaintext] +DOT RESTART [shape=plaintext] +DOT acceptor -> first [style=bold,color=green] + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cache.h" + +#include "hash/hash_slinger.h" +#include "vcl.h" +#include "vcli_priv.h" +#include "vsha256.h" +#include "vtim.h" + +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif + +static unsigned xids; +/*-------------------------------------------------------------------- + * We have a refcounted object on the session, and possibly the busyobj + * which is fetching it, prepare a response. + * +DOT subgraph xcluster_prepresp { +DOT prepresp [ +DOT shape=record +DOT label="{cnt_prepresp:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{error?|restart?}|stream ?}" +DOT ] +DOT prepresp -> deliver [style=bold,color=green,label=deliver] +DOT prepresp -> deliver [style=bold,color=red] +DOT prepresp -> deliver [style=bold,color=blue] +DOT } + * + */ + +static int +cnt_prepresp(struct worker *wrk, struct req *req) +{ + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + bo = req->busyobj; + CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); + + CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + + req->res_mode = 0; + + if (bo == NULL) { + if (!req->disable_esi && req->obj->esidata != NULL) { + /* In ESI mode, we can't know the aggregate length */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_ESI; + } else { + req->res_mode |= RES_LEN; + } + } else { + AZ(bo->do_esi); + } + + if (req->esi_level > 0) { + /* Included ESI object, always CHUNKED or EOF */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_ESI_CHILD; + } + + if (cache_param->http_gzip_support && req->obj->gziped && + !RFC2616_Req_Gzip(req->http)) { + /* + * We don't know what it uncompresses to + * XXX: we could cache that + */ + req->res_mode &= ~RES_LEN; + req->res_mode |= RES_GUNZIP; + } + + if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { + /* We havn't chosen yet, do so */ + if (!req->wantbody) { + /* Nothing */ + } else if (req->http->protover >= 11) { + req->res_mode |= RES_CHUNKED; + } else { + req->res_mode |= RES_EOF; + req->doclose = SC_TX_EOF; + } + } + + req->t_resp = W_TIM_real(wrk); + if (req->obj->objcore->objhead != NULL) { + if ((req->t_resp - req->obj->last_lru) > + cache_param->lru_timeout && + EXP_Touch(req->obj->objcore)) + req->obj->last_lru = req->t_resp; + if (!cache_param->obj_readonly) + req->obj->last_use = req->t_resp; /* XXX: locking ? */ + } + HTTP_Setup(req->resp, req->ws, req->vsl, HTTP_Resp); + RES_BuildHttp(req); + + VCL_deliver_method(req); + switch (req->handling) { + case VCL_RET_DELIVER: + break; + case VCL_RET_RESTART: + if (req->restarts >= cache_param->max_restarts) + break; + if (bo != NULL) { + AN(bo->do_stream); + (void)HSH_Deref(&wrk->stats, NULL, &req->obj); + VBO_DerefBusyObj(wrk, &req->busyobj); + } else { + (void)HSH_Deref(&wrk->stats, NULL, &req->obj); + } + AZ(req->obj); + http_Teardown(req->resp); + req->req_step = R_STP_RESTART; + return (0); + default: + WRONG("Illegal action in vcl_deliver{}"); + } + req->req_step = R_STP_DELIVER; + return (0); +} + +/*-------------------------------------------------------------------- + * Deliver an already stored object + * +DOT subgraph xcluster_deliver { +DOT deliver [ +DOT shape=record +DOT label="{cnt_deliver:|Send body}" +DOT ] +DOT } +DOT deliver -> DONE [style=bold,color=green] +DOT deliver -> DONE [style=bold,color=red] +DOT deliver -> DONE [style=bold,color=blue] + * + */ + +static int +cnt_deliver(struct worker *wrk, struct req *req) +{ + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); + bo = req->busyobj; + CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); + + if (bo != NULL) { + while (bo->state < BOS_FAILED) + (void)usleep(10000); + assert(bo->state >= BOS_FAILED); + + if (bo->state == BOS_FAILED) { + HSH_Deref(&wrk->stats, NULL, &req->obj); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->err_code = 503; + req->req_step = R_STP_ERROR; + return (0); + } + VBO_DerefBusyObj(wrk, &req->busyobj); + } + + AZ(req->busyobj); + req->director = NULL; + req->restarts = 0; + + RES_WriteObj(req); + + /* No point in saving the body if it is hit-for-pass */ + if (req->obj->objcore->flags & OC_F_PASS) + STV_Freestore(req->obj); + + assert(WRW_IsReleased(wrk)); + (void)HSH_Deref(&wrk->stats, NULL, &req->obj); + http_Teardown(req->resp); + return (1); +} +/*-------------------------------------------------------------------- + * Emit an error + * +DOT subgraph xcluster_error { +DOT vcl_error [ +DOT shape=record +DOT label="vcl_error()|resp." +DOT ] +DOT ERROR -> vcl_error +DOT vcl_error-> prepresp [label=deliver] +DOT } +DOT vcl_error-> rsterr [label="restart",color=purple] +DOT rsterr [label="RESTART",shape=plaintext] + */ + +static int +cnt_error(struct worker *wrk, struct req *req) +{ + struct http *h; + struct busyobj *bo; + char date[40]; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AZ(req->objcore); + AZ(req->obj); + AZ(req->busyobj); + + bo = VBO_GetBusyObj(wrk); + req->busyobj = bo; + bo->vsl->wid = req->sp->vsl_id; + AZ(bo->stats); + bo->stats = &wrk->stats; + req->objcore = HSH_NewObjCore(wrk); + req->obj = STV_NewObject(bo, &req->objcore, + TRANSIENT_STORAGE, cache_param->http_resp_size, + (uint16_t)cache_param->http_max_hdr); + bo->stats = NULL; + if (req->obj == NULL) { + req->doclose = SC_OVERLOAD; + req->director = NULL; + http_Teardown(bo->beresp); + http_Teardown(bo->bereq); + return(1); + } + CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); + req->obj->xid = req->xid; + req->obj->exp.entered = req->t_req; + + h = req->obj->http; + + if (req->err_code < 100 || req->err_code > 999) + req->err_code = 501; + + http_PutProtocol(h, "HTTP/1.1"); + http_PutStatus(h, req->err_code); + VTIM_format(W_TIM_real(wrk), date); + http_PrintfHeader(h, "Date: %s", date); + http_SetHeader(h, "Server: Varnish"); + + if (req->err_reason != NULL) + http_PutResponse(h, req->err_reason); + else + http_PutResponse(h, http_StatusMessage(req->err_code)); + VCL_error_method(req); + + if (req->handling == VCL_RET_RESTART && + req->restarts < cache_param->max_restarts) { + HSH_Drop(wrk, &req->obj); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->req_step = R_STP_RESTART; + return (0); + } else if (req->handling == VCL_RET_RESTART) + req->handling = VCL_RET_DELIVER; + + + /* We always close when we take this path */ + req->doclose = SC_TX_ERROR; + req->wantbody = 1; + + assert(req->handling == VCL_RET_DELIVER); + req->err_code = 0; + req->err_reason = NULL; + http_Teardown(bo->bereq); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->req_step = R_STP_PREPRESP; + return (0); +} + +/*-------------------------------------------------------------------- + * Fetch response headers from the backend + * +DOT subgraph xcluster_fetch { +DOT fetch [ +DOT shape=record +DOT label="{cnt_fetch:|fetch hdr\nfrom backend|(find obj.ttl)|{vcl_fetch\{\}|{req.|bereq.|beresp.}}|{error?|restart?}}" +DOT ] +DOT } +DOT fetch -> fetchbody [style=bold,color=red] +DOT fetch -> fetchbody [style=bold,color=blue] + */ + +static int +cnt_fetch(struct worker *wrk, struct req *req) +{ + int i, need_host_hdr; + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + bo = req->busyobj; + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + AN(req->director); + AZ(bo->vbc); + AZ(bo->should_close); + AZ(req->storage_hint); + + HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp); + + need_host_hdr = !http_GetHdr(bo->bereq, H_Host, NULL); + + req->acct_req.fetch++; + + i = FetchHdr(req, need_host_hdr, req->objcore->objhead == NULL); + /* + * If we recycle a backend connection, there is a finite chance + * that the backend closed it before we get a request to it. + * Do a single retry in that case. + */ + if (i == 1) { + VSC_C_main->backend_retry++; + i = FetchHdr(req, need_host_hdr, req->objcore->objhead == NULL); + } + + if (i) { + req->handling = VCL_RET_ERROR; + req->err_code = 503; + } else { + /* + * These two headers can be spread over multiple actual headers + * and we rely on their content outside of VCL, so collect them + * into one line here. + */ + http_CollectHdr(bo->beresp, H_Cache_Control); + http_CollectHdr(bo->beresp, H_Vary); + + /* + * Figure out how the fetch is supposed to happen, before the + * headers are adultered by VCL + * NB: Also sets other wrk variables + */ + bo->body_status = RFC2616_Body(bo, &wrk->stats); + + req->err_code = http_GetStatus(bo->beresp); + + /* + * What does RFC2616 think about TTL ? + */ + EXP_Clr(&bo->exp); + bo->exp.entered = W_TIM_real(wrk); + RFC2616_Ttl(bo, req->xid); + + /* pass from vclrecv{} has negative TTL */ + if (req->objcore->objhead == NULL) + bo->exp.ttl = -1.; + + AZ(bo->do_esi); + AZ(bo->do_pass); + + VCL_fetch_method(req); + + if (bo->do_pass) + req->objcore->flags |= OC_F_PASS; + + switch (req->handling) { + case VCL_RET_DELIVER: + req->req_step = R_STP_FETCHBODY; + return (0); + default: + break; + } + + /* We are not going to fetch the body, Close the connection */ + VDI_CloseFd(&bo->vbc); + } + + /* Clean up partial fetch */ + AZ(bo->vbc); + + if (req->objcore->objhead != NULL || req->handling == VCL_RET_ERROR) { + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); + req->objcore = NULL; + } + assert(bo->refcount == 2); + VBO_DerefBusyObj(wrk, &bo); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->director = NULL; + req->storage_hint = NULL; + + switch (req->handling) { + case VCL_RET_RESTART: + req->req_step = R_STP_RESTART; + return (0); + case VCL_RET_ERROR: + req->req_step = R_STP_ERROR; + return (0); + default: + WRONG("Illegal action in vcl_fetch{}"); + } +} + +/*-------------------------------------------------------------------- + * Prepare to fetch body from backend + * +DOT subgraph xcluster_body { +DOT fetchbody [ +DOT shape=record +DOT label="{cnt_fetchbody:|start fetch_thread}" +DOT ] +DOT } +DOT fetchbody:out -> prepresp [style=bold,color=red] +DOT fetchbody:out -> prepresp [style=bold,color=blue] + */ + +static int +cnt_fetchbody(struct worker *wrk, struct req *req) +{ + struct http *hp, *hp2; + char *b; + uint16_t nhttp; + unsigned l; + struct vsb *vary = NULL; + int varyl = 0, pass; + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + bo = req->busyobj; + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + + assert(req->handling == VCL_RET_DELIVER); + + if (req->objcore->objhead == NULL) { + /* This is a pass from vcl_recv */ + pass = 1; + /* VCL may have fiddled this, but that doesn't help */ + bo->exp.ttl = -1.; + } else if (bo->do_pass) { + pass = 1; + } else { + /* regular object */ + pass = 0; + } + + /* + * The VCL variables beresp.do_g[un]zip tells us how we want the + * object processed before it is stored. + * + * The backend Content-Encoding header tells us what we are going + * to receive, which we classify in the following three classes: + * + * "Content-Encoding: gzip" --> object is gzip'ed. + * no Content-Encoding --> object is not gzip'ed. + * anything else --> do nothing wrt gzip + * + */ + + /* We do nothing unless the param is set */ + if (!cache_param->http_gzip_support) + bo->do_gzip = bo->do_gunzip = 0; + + bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); + + bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); + + /* It can't be both */ + assert(bo->is_gzip == 0 || bo->is_gunzip == 0); + + /* We won't gunzip unless it is gzip'ed */ + if (bo->do_gunzip && !bo->is_gzip) + bo->do_gunzip = 0; + + /* If we do gunzip, remove the C-E header */ + if (bo->do_gunzip) + http_Unset(bo->beresp, H_Content_Encoding); + + /* We wont gzip unless it is ungziped */ + if (bo->do_gzip && !bo->is_gunzip) + bo->do_gzip = 0; + + /* If we do gzip, add the C-E header */ + if (bo->do_gzip) + http_SetHeader(bo->beresp, "Content-Encoding: gzip"); + + /* But we can't do both at the same time */ + assert(bo->do_gzip == 0 || bo->do_gunzip == 0); + + /* ESI takes precedence and handles gzip/gunzip itself */ + if (bo->do_esi) + bo->vfp = &vfp_esi; + else if (bo->do_gunzip) + bo->vfp = &vfp_gunzip; + else if (bo->do_gzip) + bo->vfp = &vfp_gzip; + else if (bo->is_gzip) + bo->vfp = &vfp_testgzip; + + if (bo->do_esi || req->esi_level > 0) + bo->do_stream = 0; + if (!req->wantbody) + bo->do_stream = 0; + + /* No reason to try streaming a non-existing body */ + if (bo->body_status == BS_NONE) + bo->do_stream = 0; + + l = http_EstimateWS(bo->beresp, + pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp); + + /* Create Vary instructions */ + if (req->objcore->objhead != NULL) { + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + vary = VRY_Create(req, bo->beresp); + if (vary != NULL) { + varyl = VSB_len(vary); + assert(varyl > 0); + l += varyl; + } + } + + /* + * Space for producing a Content-Length: header including padding + * A billion gigabytes is enough for anybody. + */ + l += strlen("Content-Length: XxxXxxXxxXxxXxxXxx") + sizeof(void *); + + if (bo->exp.ttl < cache_param->shortlived || + req->objcore == NULL) + req->storage_hint = TRANSIENT_STORAGE; + + AZ(bo->stats); + bo->stats = &wrk->stats; + req->obj = STV_NewObject(bo, &req->objcore, req->storage_hint, l, + nhttp); + if (req->obj == NULL) { + /* + * Try to salvage the transaction by allocating a + * shortlived object on Transient storage. + */ + if (bo->exp.ttl > cache_param->shortlived) + bo->exp.ttl = cache_param->shortlived; + bo->exp.grace = 0.0; + bo->exp.keep = 0.0; + req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE, + l, nhttp); + } + bo->stats = NULL; + if (req->obj == NULL) { + req->err_code = 503; + req->req_step = R_STP_ERROR; + VDI_CloseFd(&bo->vbc); + VBO_DerefBusyObj(wrk, &req->busyobj); + return (0); + } + CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); + + req->storage_hint = NULL; + + AZ(bo->fetch_obj); + bo->fetch_obj = req->obj; + + if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip)) + req->obj->gziped = 1; + + if (vary != NULL) { + req->obj->vary = (void *)WS_Alloc(req->obj->http->ws, varyl); + AN(req->obj->vary); + memcpy(req->obj->vary, VSB_data(vary), varyl); + VRY_Validate(req->obj->vary); + VSB_delete(vary); + } + + req->obj->xid = req->xid; + req->obj->response = req->err_code; + WS_Assert(req->obj->ws_o); + + /* Filter into object */ + hp = bo->beresp; + hp2 = req->obj->http; + + hp2->logtag = HTTP_Obj; + http_FilterResp(hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS); + http_CopyHome(hp2); + + if (http_GetHdr(hp, H_Last_Modified, &b)) + req->obj->last_modified = VTIM_parse(b); + else + req->obj->last_modified = floor(bo->exp.entered); + + assert(WRW_IsReleased(wrk)); + + /* + * If we can deliver a 304 reply, we don't bother streaming. + * Notice that vcl_deliver{} could still nuke the headers + * that allow the 304, in which case we return 200 non-stream. + */ + if (req->obj->response == 200 && + req->http->conds && + RFC2616_Do_Cond(req)) + bo->do_stream = 0; + + /* + * Ready to fetch the body + */ + bo->fetch_task.func = FetchBody; + bo->fetch_task.priv = bo; + + assert(bo->refcount == 2); /* one for each thread */ + + if (req->obj->objcore->objhead != NULL) { + EXP_Insert(req->obj); + AN(req->obj->objcore->ban); + AZ(req->obj->ws_o->overflow); + HSH_Unbusy(&wrk->stats, req->obj->objcore); + } + + if (!bo->do_stream || + Pool_Task(wrk->pool, &bo->fetch_task, POOL_NO_QUEUE)) + FetchBody(wrk, bo); + + if (req->obj->objcore->objhead != NULL) + HSH_Ref(req->obj->objcore); + + if (bo->state == BOS_FINISHED) { + VBO_DerefBusyObj(wrk, &req->busyobj); + } else if (bo->state == BOS_FAILED) { + /* handle early failures */ + HSH_Deref(&wrk->stats, NULL, &req->obj); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->err_code = 503; + req->req_step = R_STP_ERROR; + return (0); + } + + assert(WRW_IsReleased(wrk)); + req->req_step = R_STP_PREPRESP; + return (0); +} + +/*-------------------------------------------------------------------- + * HIT + * We had a cache hit. Ask VCL, then march off as instructed. + * +DOT subgraph xcluster_hit { +DOT hit [ +DOT shape=record +DOT label="{cnt_hit:|{vcl_hit()|{req.|obj.}}|{error?|restart?}|{deliver?|pass?}}" +DOT ] +DOT } +XDOT hit:err -> err_hit [label="error"] +XDOT err_hit [label="ERROR",shape=plaintext] +XDOT hit:rst -> rst_hit [label="restart",color=purple] +XDOT rst_hit [label="RESTART",shape=plaintext] +DOT hit:pass -> pass [label=pass,style=bold,color=red] +DOT hit:del -> prepresp [label="deliver",style=bold,color=green] + */ + +static int +cnt_hit(struct worker *wrk, struct req *req) +{ + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->objcore); + AZ(req->busyobj); + + assert(!(req->obj->objcore->flags & OC_F_PASS)); + + VCL_hit_method(req); + + if (req->handling == VCL_RET_DELIVER) { + //AZ(req->busyobj->bereq->ws); + //AZ(req->busyobj->beresp->ws); + (void)FetchReqBody(req, 0); + req->req_step = R_STP_PREPRESP; + return (0); + } + + /* Drop our object, we won't need it */ + (void)HSH_Deref(&wrk->stats, NULL, &req->obj); + req->objcore = NULL; + + switch(req->handling) { + case VCL_RET_PASS: + req->req_step = R_STP_PASS; + return (0); + case VCL_RET_ERROR: + req->req_step = R_STP_ERROR; + return (0); + case VCL_RET_RESTART: + req->req_step = R_STP_RESTART; + return (0); + default: + WRONG("Illegal action in vcl_hit{}"); + } +} + +/*-------------------------------------------------------------------- + * LOOKUP + * Hash things together and look object up in hash-table. + * + * LOOKUP consists of two substates so that we can reenter if we + * encounter a busy object. + * +DOT subgraph xcluster_lookup { +DOT lookup [ +DOT shape=record +DOT label="{cnt_lookup:|hash lookup|{busy ?|miss ?}|{no|obj.f.pass?|yes}}" +DOT ] +DOT } +DOT lookup:busy -> lookup:top [label="(waitinglist)"] +DOT lookup:miss -> miss [style=bold,color=blue] +DOT lookup:no -> hit [style=bold,color=green] +DOT lookup:yes -> pass [style=bold,color=red] + */ + +static int +cnt_lookup(struct worker *wrk, struct req *req) +{ + struct objcore *oc; + struct object *o; + struct objhead *oh; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AZ(req->objcore); + + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->busyobj); + + VRY_Prep(req); + + AZ(req->objcore); + oc = HSH_Lookup(req); + if (oc == NULL) { + /* + * We lost the session to a busy object, disembark the + * worker thread. We return to STP_LOOKUP when the busy + * object has been unbusied, and still have the hash digest + * around to do the lookup with. + */ + return (2); + } + AZ(req->objcore); + + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + oh = oc->objhead; + CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); + + /* If we inserted a new object it's a miss */ + if (oc->flags & OC_F_BUSY) { + CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC); + assert(oc->busyobj == req->busyobj); + wrk->stats.cache_miss++; + + if (req->vary_l != NULL) { + assert(oc->busyobj->vary == req->vary_b); + VRY_Validate(oc->busyobj->vary); + WS_ReleaseP(req->ws, (void*)req->vary_l); + } else { + AZ(oc->busyobj->vary); + WS_Release(req->ws, 0); + } + req->vary_b = NULL; + req->vary_l = NULL; + req->vary_e = NULL; + + req->objcore = oc; + req->req_step = R_STP_MISS; + return (0); + } + + /* We are not prepared to do streaming yet */ + XXXAZ(req->busyobj); + + o = oc_getobj(&wrk->stats, oc); + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); + req->obj = o; + + WS_Release(req->ws, 0); + req->vary_b = NULL; + req->vary_l = NULL; + req->vary_e = NULL; + + if (oc->flags & OC_F_PASS) { + wrk->stats.cache_hitpass++; + VSLb(req->vsl, SLT_HitPass, "%u", req->obj->xid); + (void)HSH_Deref(&wrk->stats, NULL, &req->obj); + AZ(req->objcore); + req->req_step = R_STP_PASS; + return (0); + } + + wrk->stats.cache_hit++; + VSLb(req->vsl, SLT_Hit, "%u", req->obj->xid); + req->req_step = R_STP_HIT; + return (0); +} + +/*-------------------------------------------------------------------- + * We had a miss, ask VCL, proceed as instructed + * +DOT subgraph xcluster_miss { +DOT miss [ +DOT shape=record +DOT label="{cnt_miss:|filter req.-\>bereq.|{vcl_miss\{\}|{req.*|bereq.*}}|{error?|restart?}|{pass?|fetch?}}" +DOT ] +DOT } +DOT miss:fetch -> fetch [label="fetch",style=bold,color=blue] +DOT miss:pass -> pass [label="pass",style=bold,color=red] +DOT + */ + +static int +cnt_miss(struct worker *wrk, struct req *req) +{ + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); + bo = req->busyobj; + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + AZ(req->obj); + + HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); + http_FilterReq(req, HTTPH_R_FETCH); + http_ForceGet(bo->bereq); + if (cache_param->http_gzip_support) { + /* + * We always ask the backend for gzip, even if the + * client doesn't grok it. We will uncompress for + * the minority of clients which don't. + */ + http_Unset(bo->bereq, H_Accept_Encoding); + http_SetHeader(bo->bereq, "Accept-Encoding: gzip"); + } + + VCL_miss_method(req); + + if (req->handling == VCL_RET_FETCH) { + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + req->req_step = R_STP_FETCH; + return (0); + } + + AZ(HSH_Deref(&wrk->stats, req->objcore, NULL)); + req->objcore = NULL; + http_Teardown(bo->bereq); + VBO_DerefBusyObj(wrk, &req->busyobj); + + switch(req->handling) { + case VCL_RET_ERROR: + req->req_step = R_STP_ERROR; + break; + case VCL_RET_PASS: + req->req_step = R_STP_PASS; + break; + case VCL_RET_RESTART: + req->req_step = R_STP_RESTART; + break; + default: + WRONG("Illegal action in vcl_miss{}"); + } + return (0); +} + +/*-------------------------------------------------------------------- + * Start pass processing by getting headers from backend, then + * continue in passbody. + * +DOT subgraph xcluster_pass { +DOT pass [ +DOT shape=record +DOT label="{cnt_pass:|(XXX: deref obj.)|filter req.*-\>bereq.|{vcl_pass\{\}|{req.*|bereq.*}}|{error?|restart?}|create anon obj}" +DOT ] +DOT } +DOT pass:pass -> fetch [style=bold, color=red] +XDOT pass:rst -> rst_pass [label="restart",color=purple] +XDOT rst_pass [label="RESTART",shape=plaintext] +XDOT pass:err -> err_pass [label="error"] +XDOT err_pass [label="ERROR",shape=plaintext] + */ + +static int +cnt_pass(struct worker *wrk, struct req *req) +{ + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->objcore); + AZ(req->obj); + AZ(req->busyobj); + + req->busyobj = VBO_GetBusyObj(wrk); + bo = req->busyobj; + bo->vsl->wid = req->sp->vsl_id; + bo->refcount = 2; + HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); + http_FilterReq(req, HTTPH_R_PASS); + + VCL_pass_method(req); + + if (req->handling == VCL_RET_ERROR) { + http_Teardown(bo->bereq); + VBO_DerefBusyObj(wrk, &req->busyobj); + req->req_step = R_STP_ERROR; + return (0); + } + assert(req->handling == VCL_RET_PASS); + req->acct_req.pass++; + req->req_step = R_STP_FETCH; + + req->objcore = HSH_NewObjCore(wrk); + req->objcore->busyobj = bo; + return (0); +} + +/*-------------------------------------------------------------------- + * Ship the request header to the backend unchanged, then pipe + * until one of the ends close the connection. + * +DOT subgraph xcluster_pipe { +DOT pipe [ +DOT shape=ellipse +DOT label="Filter req.->bereq." +DOT ] +DOT vcl_pipe [ +DOT shape=record +DOT label="vcl_pipe()|req.\nbereq\." +DOT ] +DOT pipe_do [ +DOT shape=ellipse +DOT label="send bereq.\npipe until close" +DOT ] +DOT vcl_pipe -> pipe_do [label="pipe",style=bold,color=orange] +DOT pipe -> vcl_pipe [style=bold,color=orange] +DOT } +DOT pipe_do -> DONE [style=bold,color=orange] +DOT vcl_pipe -> err_pipe [label="error"] +DOT err_pipe [label="ERROR",shape=plaintext] + */ + +static int +cnt_pipe(struct worker *wrk, struct req *req) +{ + struct busyobj *bo; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->busyobj); + + req->acct_req.pipe++; + req->busyobj = VBO_GetBusyObj(wrk); + bo = req->busyobj; + bo->vsl->wid = req->sp->vsl_id; + HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); + http_FilterReq(req, 0); + + VCL_pipe_method(req); + + if (req->handling == VCL_RET_ERROR) + INCOMPL(); + assert(req->handling == VCL_RET_PIPE); + + PipeRequest(req); + assert(WRW_IsReleased(wrk)); + http_Teardown(bo->bereq); + VBO_DerefBusyObj(wrk, &req->busyobj); + return (1); +} + +/*-------------------------------------------------------------------- + * +DOT subgraph xcluster_restart { +DOT restart [ +DOT shape=record +DOT label="{cnt_restart}" +DOT ] +DOT } +DOT RESTART -> restart [color=purple] +DOT restart -> recv [color=purple] + */ + +static int +cnt_restart(const struct worker *wrk, struct req *req) +{ + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + req->director = NULL; + if (++req->restarts >= cache_param->max_restarts) { + req->err_code = 503; + req->req_step = R_STP_ERROR; + } else { + req->err_code = 0; + req->req_step = R_STP_RECV; + } + return (0); +} + +/*-------------------------------------------------------------------- + * RECV + * We have a complete request, set everything up and start it. + * We can come here both with a request from the client and with + * a interior request during ESI delivery. + * +DOT subgraph xcluster_recv { +DOT recv [ +DOT shape=record +DOT label="{cnt_recv:|{vcl_recv\{\}|req.*}|{pipe?|pass?|error?|lookup?}}" +DOT ] +DOT } +DOT subgraph xcluster_hash { +DOT hash [ +DOT shape=record +DOT label="{cnt_recv:|{vcl_hash\{\}|req.*}}" +DOT ] +DOT } +DOT ESI_REQ [ shape=hexagon ] +DOT ESI_REQ -> recv +DOT recv:pipe -> pipe [style=bold,color=orange] +DOT recv:pass -> pass [style=bold,color=red] +#DOT recv:error -> err_recv +#DOT err_recv [label="ERROR",shape=plaintext] +DOT recv:lookup -> hash [style=bold,color=green] +DOT hash -> lookup [label="hash",style=bold,color=green] + */ + +static int +cnt_recv(const struct worker *wrk, struct req *req) +{ + unsigned recv_handling; + struct SHA256Context sha256ctx; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); + AZ(req->obj); + AZ(req->busyobj); + + /* By default we use the first backend */ + AZ(req->director); + req->director = req->vcl->director[0]; + AN(req->director); + + req->disable_esi = 0; + req->hash_always_miss = 0; + req->hash_ignore_busy = 0; + req->client_identity = NULL; + + http_CollectHdr(req->http, H_Cache_Control); + + VCL_recv_method(req); + recv_handling = req->handling; + + if (cache_param->http_gzip_support && + (recv_handling != VCL_RET_PIPE) && + (recv_handling != VCL_RET_PASS)) { + if (RFC2616_Req_Gzip(req->http)) { + http_Unset(req->http, H_Accept_Encoding); + http_SetHeader(req->http, "Accept-Encoding: gzip"); + } else { + http_Unset(req->http, H_Accept_Encoding); + } + } + + req->sha256ctx = &sha256ctx; /* so HSH_AddString() can find it */ + SHA256_Init(req->sha256ctx); + VCL_hash_method(req); + assert(req->handling == VCL_RET_HASH); + SHA256_Final(req->digest, req->sha256ctx); + req->sha256ctx = NULL; + + if (!strcmp(req->http->hd[HTTP_HDR_REQ].b, "HEAD")) + req->wantbody = 0; + else + req->wantbody = 1; + + switch(recv_handling) { + case VCL_RET_LOOKUP: + req->req_step = R_STP_LOOKUP; + return (0); + case VCL_RET_PIPE: + if (req->esi_level > 0) { + /* XXX: VSL something */ + INCOMPL(); + return (1); + } + req->req_step = R_STP_PIPE; + return (0); + case VCL_RET_PASS: + req->req_step = R_STP_PASS; + return (0); + case VCL_RET_ERROR: + req->req_step = R_STP_ERROR; + return (0); + default: + WRONG("Illegal action in vcl_recv{}"); + } +} + +/*-------------------------------------------------------------------- + * START + * First time we see a request + * +DOT start [ +DOT shape=box +DOT label="cnt_start:\nDissect request\nHandle expect" +DOT ] +DOT start -> recv [style=bold,color=green] +DOT start -> DONE [label=errors] + */ + +static int +cnt_start(struct worker *wrk, struct req *req) +{ + char *p; + const char *r = "HTTP/1.1 100 Continue\r\n\r\n"; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AZ(req->restarts); + AZ(req->obj); + AZ(req->vcl); + AZ(req->esi_level); + assert(!isnan(req->t_req)); + + /* Update stats of various sorts */ + wrk->stats.client_req++; + req->acct_req.req++; + + /* Assign XID and log */ + req->xid = ++xids; /* XXX not locked */ + VSLb(req->vsl, SLT_ReqStart, "%s %s %u", + req->sp->addr, req->sp->port, req->xid); + + /* Borrow VCL reference from worker thread */ + VCL_Refresh(&wrk->vcl); + req->vcl = wrk->vcl; + wrk->vcl = NULL; + + EXP_Clr(&req->exp); + + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + req->err_code = http_DissectRequest(req); + + /* If we could not even parse the request, just close */ + if (req->err_code == 400) { + SES_Close(req->sp, SC_RX_JUNK); + return (1); + } + + req->ws_req = WS_Snapshot(req->ws); + + req->doclose = http_DoConnection(req->http); + + /* + * We want to deal with Expect: headers the first time we + * attempt the request, and remove them before we move on. + */ + if (req->err_code == 0 && http_GetHdr(req->http, H_Expect, &p)) { + if (strcasecmp(p, "100-continue")) { + req->err_code = 417; + } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { + SES_Close(req->sp, SC_REM_CLOSE); + return (1); + } + } + http_Unset(req->http, H_Expect); + + /* XXX: pull in req-body and make it available instead. */ + req->reqbodydone = 0; + + HTTP_Copy(req->http0, req->http); /* Copy for restart/ESI use */ + + if (req->err_code) + req->req_step = R_STP_ERROR; + else + req->req_step = R_STP_RECV; + return (0); +} + +/*-------------------------------------------------------------------- + * Central state engine dispatcher. + * + * Kick the session around until it has had enough. + * + */ + +static void +cnt_diag(struct req *req, const char *state) +{ + + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + VSLb(req->vsl, SLT_Debug, "vsl_id %u STP_%s sp %p obj %p vcl %p", + req->sp->vsl_id, state, req->sp, req->obj, req->vcl); + VSL_Flush(req->vsl, 0); +} + +int +CNT_Request(struct worker *wrk, struct req *req) +{ + int done; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + /* + * Possible entrance states + */ + assert( + req->req_step == R_STP_LOOKUP || + req->req_step == R_STP_START || + req->req_step == R_STP_RECV); + + req->wrk = wrk; + + for (done = 0; !done; ) { + /* + * This is a good place to be paranoid about the various + * pointers still pointing to the things we expect. + */ + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); + WS_Assert(wrk->aws); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + switch (req->req_step) { +#define REQ_STEP(l,u,arg) \ + case R_STP_##u: \ + if (cache_param->diag_bitmap & 0x01) \ + cnt_diag(req, #u); \ + done = cnt_##l arg; \ + break; +#include "tbl/steps.h" +#undef REQ_STEP + default: + WRONG("State engine misfire"); + } + WS_Assert(wrk->aws); + CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); + } + if (done == 1) { + /* XXX: Workaround for pipe */ + if (req->sp->fd >= 0) { + VSLb(req->vsl, SLT_Length, "%ju", + (uintmax_t)req->req_bodybytes); + } + VSLb(req->vsl, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f", + req->xid, + req->t_req, + req->sp->t_idle, + req->sp->t_idle - req->t_resp, + req->t_resp - req->t_req, + req->sp->t_idle - req->t_resp); + + /* done == 2 was charged by cache_hash.c */ + SES_Charge(wrk, req); + } + + req->wrk = NULL; + + assert(WRW_IsReleased(wrk)); + return (done); +} + +/* +DOT } +*/ + +/*-------------------------------------------------------------------- + * Debugging aids + */ + +static void +cli_debug_xid(struct cli *cli, const char * const *av, void *priv) +{ + (void)priv; + if (av[2] != NULL) + xids = strtoul(av[2], NULL, 0); + VCLI_Out(cli, "XID is %u", xids); +} + +/* + * Default to seed=1, this is the only seed value POSIXl guarantees will + * result in a reproducible random number sequence. + */ +static void +cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) +{ + (void)priv; + unsigned seed = 1; + + if (av[2] != NULL) + seed = strtoul(av[2], NULL, 0); + srandom(seed); + srand48(random()); + VCLI_Out(cli, "Random(3) seeded with %u", seed); +} + +static struct cli_proto debug_cmds[] = { + { "debug.xid", "debug.xid", + "\tExamine or set XID\n", 0, 1, "d", cli_debug_xid }, + { "debug.srandom", "debug.srandom", + "\tSeed the random(3) function\n", 0, 1, "d", + cli_debug_srandom }, + { NULL } +}; + +/*-------------------------------------------------------------------- + * + */ + +void +CNT_Init(void) +{ + + srandomdev(); + srand48(random()); + xids = random(); + CLI_AddFuncs(debug_cmds); +} From phk at varnish-cache.org Tue Aug 7 08:06:11 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 07 Aug 2012 10:06:11 +0200 Subject: [master] 1226479 Clean up the HTTP1 fsm and document it with a small dot-graph. Message-ID: commit 1226479c26eb10373d74d98bc0628706b64c3f4d Author: Poul-Henning Kamp Date: Tue Aug 7 08:05:34 2012 +0000 Clean up the HTTP1 fsm and document it with a small dot-graph. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 831c641..920d067 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -764,9 +764,11 @@ struct busyobj *VBO_GetBusyObj(struct worker *wrk); void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj); void VBO_Free(struct busyobj **vbo); -/* cache_center.c [CNT] */ +/* cache_http1_fsm.c [HTTP1] */ +void HTTP1_Session(struct worker *, struct req *); + +/* cache_req_fsm.c [FSM] */ int CNT_Request(struct worker *, struct req *); -void CNT_Session(struct worker *, struct req *); void CNT_Init(void); /* cache_cli.c [CLI] */ diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 586fd50..ae01a00 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -26,42 +26,44 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file contains the two central state machine for pushing - * sessions and requests. + * This file contains the two central state machine for pushing HTTP1 + * sessions through their states. * - * The first part of the file, entrypoint CNT_Session() and down to - * the ==== separator, is concerned with sessions. When a session has - * a request to deal with, it calls into the second half of the file. - * This part is for all practical purposes HTTP/1.x specific. + * The following dot-graph shows the big picture, and the two major + * complicating features: * - * The second part of the file, entrypoint CNT_Request() and below the - * ==== separator, is intended to (over time) be(ome) protocol agnostic. - * We already use this now with ESI:includes, which are for all relevant - * purposes a different "protocol" + * - The blue path is where a request disembarks its worker thread while + * waiting for a busy object to become available: * - * A special complication is the fact that we can suspend processing of - * a request when hash-lookup finds a busy objhdr. + * - The green path is where we time out waiting for the next request to + * arrive, release the worker thread and hand the session to the waiter. + * + * Render the graph with: + * sed -n '/^..DOT/s///p' % | dot -Tps > /tmp/_.ps + * + *DOT digraph vcl_center { + *DOT size="7.2,10.5" + *DOT margin="0.5" + *DOT center="1" + *DOT + *DOT acceptor -> http1_wait [label=S_STP_NEWREQ, align=center] + *DOT hash -> CNT_Request [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" + *DOT color=blue] + *DOT disembark -> hash [style=dotted, color=blue] + *DOT http1_wait -> CNT_Request [label="S_STP_WORKING\nR_STP_START"] + *DOT http1_wait -> disembark [label="Session close"] + *DOT http1_wait -> disembark [label="Timeout" color=green] + *DOT disembark -> waiter [style=dotted, color=green] + *DOT waiter -> http1_wait [color=green] + *DOT CNT_Request -> disembark + *DOT [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" color=blue] + *DOT CNT_Request -> http1_cleanup + *DOT http1_cleanup -> disembark [label="Session close"] + *DOT http1_cleanup -> CNT_Request [label="S_STP_WORKING\nR_STP_START"] + *DOT http1_cleanup -> http1_wait [label="S_STP_NEWREQ"] + *DOT + *DOT } * - * Since the states are rather nasty in detail, I have decided to embedd - * a dot(1) graph in the source code comments. So to see the big picture, - * extract the DOT lines and run though dot(1), for instance with the - * command: - * sed -n '/^DOT/s///p' cache/cache_center.c | dot -Tps > /tmp/_.ps - */ - -/* -DOT digraph vcl_center { -xDOT page="8.2,11.5" -DOT size="7.2,10.5" -DOT margin="0.5" -DOT center="1" -DOT acceptor [ -DOT shape=hexagon -DOT label="Request received" -DOT ] -DOT ERROR [shape=plaintext] -DOT RESTART [shape=plaintext] -DOT acceptor -> first [style=bold,color=green] */ #include "config.h" @@ -73,37 +75,16 @@ DOT acceptor -> first [style=bold,color=green] #include "cache.h" -#include "hash/hash_slinger.h" #include "vcl.h" -#include "vcli_priv.h" -#include "vsha256.h" #include "vtcp.h" #include "vtim.h" -#ifndef HAVE_SRANDOMDEV -#include "compat/srandomdev.h" -#endif - - /*-------------------------------------------------------------------- - * WAIT - * Collect the request from the client. - * -DOT subgraph xcluster_wait { -DOT wait [ -DOT shape=box -DOT label="cnt_sess_wait:\nwait for\ncomplete\nrequest" -DOT ] -DOT herding [shape=hexagon] -DOT wait -> start [label="got req",style=bold,color=green] -DOT wait -> "SES_Delete()" [label="errors"] -DOT wait -> herding [label="timeout_linger"] -DOT herding -> wait [label="fd read_ready"] -DOT } + * Collect a request from the client. */ static int -cnt_sess_wait(struct sess *sp, struct worker *wrk, struct req *req) +http1_wait(struct sess *sp, struct worker *wrk, struct req *req) { int j, tmo; struct pollfd pfd[1]; @@ -117,7 +98,6 @@ cnt_sess_wait(struct sess *sp, struct worker *wrk, struct req *req) assert(req->sp == sp); - AZ(req->vcl); AZ(req->obj); AZ(req->esi_level); @@ -184,25 +164,16 @@ cnt_sess_wait(struct sess *sp, struct worker *wrk, struct req *req) /*-------------------------------------------------------------------- * This is the final state, figure out if we should close or recycle * the client connection - * -DOT DONE [ -DOT shape=record -DOT label="{cnt_done:|Request completed}" -DOT ] -DOT ESI_RESP [ shape=hexagon ] -DOT DONE -> start [label="full pipeline"] -DOT DONE -> wait -DOT DONE -> ESI_RESP */ -enum cnt_sess_done_ret { +enum http1_cleanup_ret { SESS_DONE_RET_GONE, SESS_DONE_RET_WAIT, SESS_DONE_RET_START, }; -static enum cnt_sess_done_ret -cnt_sess_done(struct sess *sp, struct worker *wrk, struct req *req) +static enum http1_cleanup_ret +http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); @@ -225,7 +196,7 @@ cnt_sess_done(struct sess *sp, struct worker *wrk, struct req *req) } sp->t_idle = W_TIM_real(wrk); - if (req->xid == 0) + if (req->xid == 0) req->t_resp = sp->t_idle; req->xid = 0; VSL_Flush(req->vsl, 0); @@ -271,11 +242,11 @@ cnt_sess_done(struct sess *sp, struct worker *wrk, struct req *req) */ void -CNT_Session(struct worker *wrk, struct req *req) +HTTP1_Session(struct worker *wrk, struct req *req) { int done; struct sess *sp; - enum cnt_sess_done_ret sdr; + enum http1_cleanup_ret sdr; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -295,7 +266,7 @@ CNT_Session(struct worker *wrk, struct req *req) SES_Close(sp, SC_REM_CLOSE); else SES_Close(sp, SC_TX_ERROR); - sdr = cnt_sess_done(sp, wrk, req); + sdr = http1_cleanup(sp, wrk, req); assert(sdr == SESS_DONE_RET_GONE); return; } @@ -307,10 +278,6 @@ CNT_Session(struct worker *wrk, struct req *req) } while (1) { - /* - * Possible entrance states - */ - assert( sp->sess_step == S_STP_NEWREQ || req->req_step == R_STP_LOOKUP || @@ -321,7 +288,7 @@ CNT_Session(struct worker *wrk, struct req *req) if (done == 2) return; assert(done == 1); - sdr = cnt_sess_done(sp, wrk, req); + sdr = http1_cleanup(sp, wrk, req); switch (sdr) { case SESS_DONE_RET_GONE: return; @@ -333,12 +300,12 @@ CNT_Session(struct worker *wrk, struct req *req) req->req_step = R_STP_START; break; default: - WRONG("Illegal enum cnt_sess_done_ret"); + WRONG("Illegal enum http1_cleanup_ret"); } } if (sp->sess_step == S_STP_NEWREQ) { - done = cnt_sess_wait(sp, wrk, req); + done = http1_wait(sp, wrk, req); if (done) return; sp->sess_step = S_STP_WORKING; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index d67d5ff..41dca5c 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -139,7 +139,7 @@ ses_req_pool_task(struct worker *wrk, void *arg) THR_SetRequest(req); AZ(wrk->aws->r); wrk->lastused = NAN; - CNT_Session(wrk, req); + HTTP1_Session(wrk, req); WS_Assert(wrk->aws); AZ(wrk->wrw); if (cache_param->diag_bitmap & 0x00040000) { From phk at varnish-cache.org Tue Aug 7 08:19:27 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 07 Aug 2012 10:19:27 +0200 Subject: [master] 27f24b5 Fix the dot graph of the request fsm Message-ID: commit 27f24b57f958f02854d63e48aca1ce0baf29928c Author: Poul-Henning Kamp Date: Tue Aug 7 08:19:11 2012 +0000 Fix the dot graph of the request fsm diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 920d067..89931aa 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -767,7 +767,7 @@ void VBO_Free(struct busyobj **vbo); /* cache_http1_fsm.c [HTTP1] */ void HTTP1_Session(struct worker *, struct req *); -/* cache_req_fsm.c [FSM] */ +/* cache_req_fsm.c [CNT] */ int CNT_Request(struct worker *, struct req *); void CNT_Init(void); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 34cfbfa..588b4ff 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -26,13 +26,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * This file contains the two central state machine for pushing - * sessions and requests. - * - * The first part of the file, entrypoint CNT_Session() and down to - * the ==== separator, is concerned with sessions. When a session has - * a request to deal with, it calls into the second half of the file. - * This part is for all practical purposes HTTP/1.x specific. + * This file contains the two central state machine for pushing HTTP + * requests through their paces. * * The second part of the file, entrypoint CNT_Request() and below the * ==== separator, is intended to (over time) be(ome) protocol agnostic. @@ -46,7 +41,7 @@ * a dot(1) graph in the source code comments. So to see the big picture, * extract the DOT lines and run though dot(1), for instance with the * command: - * sed -n '/^DOT/s///p' cache/cache_center.c | dot -Tps > /tmp/_.ps + * sed -n '/^DOT/s///p' cache/cache_req_fsm.c | dot -Tps > /tmp/_.ps */ /* @@ -61,7 +56,7 @@ DOT label="Request received" DOT ] DOT ERROR [shape=plaintext] DOT RESTART [shape=plaintext] -DOT acceptor -> first [style=bold,color=green] +DOT acceptor -> start [style=bold,color=green] */ #include "config.h" @@ -1284,7 +1279,7 @@ CNT_Request(struct worker *wrk, struct req *req) assert( req->req_step == R_STP_LOOKUP || req->req_step == R_STP_START || - req->req_step == R_STP_RECV); + req->req_step == R_STP_RECV); // from ESI req->wrk = wrk; From phk at varnish-cache.org Tue Aug 7 08:54:15 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 07 Aug 2012 10:54:15 +0200 Subject: [master] 279bc2e Move most of CNT::start into HTTP1_fsm where it belongs. Message-ID: commit 279bc2eae8f73555e392909a936c63e720ba2b7b Author: Poul-Henning Kamp Date: Tue Aug 7 08:53:47 2012 +0000 Move most of CNT::start into HTTP1_fsm where it belongs. diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index ae01a00..e8c26ca 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -241,10 +241,57 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) /*-------------------------------------------------------------------- */ +static int +http1_dissect(struct worker *wrk, struct req *req) +{ + const char *r = "HTTP/1.1 100 Continue\r\n\r\n"; + char *p; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + /* Borrow VCL reference from worker thread */ + VCL_Refresh(&wrk->vcl); + req->vcl = wrk->vcl; + wrk->vcl = NULL; + + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + req->err_code = http_DissectRequest(req); + + /* If we could not even parse the request, just close */ + if (req->err_code == 400) { + SES_Close(req->sp, SC_RX_JUNK); + return (1); + } + + req->ws_req = WS_Snapshot(req->ws); + req->doclose = http_DoConnection(req->http); + + /* XXX: Expect headers are a mess */ + if (req->err_code == 0 && http_GetHdr(req->http, H_Expect, &p)) { + if (strcasecmp(p, "100-continue")) { + req->err_code = 417; + } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { + SES_Close(req->sp, SC_REM_CLOSE); + return (1); + } + } + http_Unset(req->http, H_Expect); + /* XXX: pull in req-body and make it available instead. */ + req->reqbodydone = 0; + + HTTP_Copy(req->http0, req->http); // For ESI & restart + + return (0); +} + +/*-------------------------------------------------------------------- + */ + void HTTP1_Session(struct worker *wrk, struct req *req) { - int done; + int done = 0; struct sess *sp; enum http1_cleanup_ret sdr; @@ -284,7 +331,10 @@ HTTP1_Session(struct worker *wrk, struct req *req) req->req_step == R_STP_START); if (sp->sess_step == S_STP_WORKING) { - done = CNT_Request(wrk, req); + if (req->req_step == R_STP_START) + done = http1_dissect(wrk, req); + if (done == 0) + done = CNT_Request(wrk, req); if (done == 2) return; assert(done == 1); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 588b4ff..63ba22c 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1181,14 +1181,12 @@ DOT start -> DONE [label=errors] static int cnt_start(struct worker *wrk, struct req *req) { - char *p; - const char *r = "HTTP/1.1 100 Continue\r\n\r\n"; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->restarts); AZ(req->obj); - AZ(req->vcl); + AN(req->vcl); AZ(req->esi_level); assert(!isnan(req->t_req)); @@ -1201,45 +1199,8 @@ cnt_start(struct worker *wrk, struct req *req) VSLb(req->vsl, SLT_ReqStart, "%s %s %u", req->sp->addr, req->sp->port, req->xid); - /* Borrow VCL reference from worker thread */ - VCL_Refresh(&wrk->vcl); - req->vcl = wrk->vcl; - wrk->vcl = NULL; - EXP_Clr(&req->exp); - HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); - req->err_code = http_DissectRequest(req); - - /* If we could not even parse the request, just close */ - if (req->err_code == 400) { - SES_Close(req->sp, SC_RX_JUNK); - return (1); - } - - req->ws_req = WS_Snapshot(req->ws); - - req->doclose = http_DoConnection(req->http); - - /* - * We want to deal with Expect: headers the first time we - * attempt the request, and remove them before we move on. - */ - if (req->err_code == 0 && http_GetHdr(req->http, H_Expect, &p)) { - if (strcasecmp(p, "100-continue")) { - req->err_code = 417; - } else if (strlen(r) != write(req->sp->fd, r, strlen(r))) { - SES_Close(req->sp, SC_REM_CLOSE); - return (1); - } - } - http_Unset(req->http, H_Expect); - - /* XXX: pull in req-body and make it available instead. */ - req->reqbodydone = 0; - - HTTP_Copy(req->http0, req->http); /* Copy for restart/ESI use */ - if (req->err_code) req->req_step = R_STP_ERROR; else From phk at varnish-cache.org Tue Aug 7 09:39:10 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 07 Aug 2012 11:39:10 +0200 Subject: [master] d11b853 Shave another couple of lines out of cnt_start{} Message-ID: commit d11b853126d1be95a8bf7412975753c6bd4bde49 Author: Poul-Henning Kamp Date: Tue Aug 7 09:38:57 2012 +0000 Shave another couple of lines out of cnt_start{} diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index e8c26ca..0cee630 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -264,6 +264,9 @@ http1_dissect(struct worker *wrk, struct req *req) return (1); } + wrk->stats.client_req++; + req->acct_req.req++; + req->ws_req = WS_Snapshot(req->ws); req->doclose = http_DoConnection(req->http); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 63ba22c..b809c6d 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1110,6 +1110,8 @@ cnt_recv(const struct worker *wrk, struct req *req) req->director = req->vcl->director[0]; AN(req->director); + EXP_Clr(&req->exp); + req->disable_esi = 0; req->hash_always_miss = 0; req->hash_ignore_busy = 0; @@ -1190,17 +1192,11 @@ cnt_start(struct worker *wrk, struct req *req) AZ(req->esi_level); assert(!isnan(req->t_req)); - /* Update stats of various sorts */ - wrk->stats.client_req++; - req->acct_req.req++; - /* Assign XID and log */ req->xid = ++xids; /* XXX not locked */ VSLb(req->vsl, SLT_ReqStart, "%s %s %u", req->sp->addr, req->sp->port, req->xid); - EXP_Clr(&req->exp); - if (req->err_code) req->req_step = R_STP_ERROR; else From apj at varnish-cache.org Wed Aug 8 07:34:43 2012 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Wed, 08 Aug 2012 09:34:43 +0200 Subject: [3.0] e1dba87 Another duplicate changelog entry, thanks fgs Message-ID: commit e1dba8772f5bec9f7a594225038da265514d22a4 Author: Andreas Plesner Jacobsen Date: Wed Aug 8 09:34:29 2012 +0200 Another duplicate changelog entry, thanks fgs diff --git a/doc/changes.rst b/doc/changes.rst index 946974c..99955cd 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -5,8 +5,6 @@ Changes from 3.0.2 to 3.0.3 Varnishd -------- -- Fix an issue where the bodybytes counter is not updated correctly on - gunzipped delivery. - Fix a race on the n_sess counter. This race made varnish do excessive session workspace allocations. `Bug #897`_. - Fix some crashes in the gzip code when it runs out of memory. `Bug #1037`_. From phk at varnish-cache.org Wed Aug 8 08:10:59 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 08 Aug 2012 10:10:59 +0200 Subject: [master] 5ce8786 Expose SES_GetReq() Message-ID: commit 5ce878666db6db0b8d5d0ff61c5f28442ab8ea31 Author: Poul-Henning Kamp Date: Wed Aug 8 07:57:36 2012 +0000 Expose SES_GetReq() diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 89931aa..71bba01 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -959,6 +959,7 @@ void SES_Charge(struct worker *, struct req *); struct sesspool *SES_NewPool(struct pool *pp, unsigned pool_no); void SES_DeletePool(struct sesspool *sp); int SES_ScheduleReq(struct req *); +struct req *SES_GetReq(struct sess *sp); void SES_Handle(struct sess *sp, double now); void SES_ReleaseReq(struct req *); pool_func_t SES_pool_accept_task; diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 41dca5c..9d3d3cb 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -52,8 +52,6 @@ static unsigned ses_size = sizeof (struct sess); -static struct req * ses_GetReq(struct sess *sp); - /*--------------------------------------------------------------------*/ struct sesspool { @@ -162,7 +160,7 @@ ses_sess_pool_task(struct worker *wrk, void *arg) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC); - req = ses_GetReq(sp); + req = SES_GetReq(sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); req->vxid = VXID_Get(&wrk->vxid_pool); @@ -346,8 +344,8 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) * Alloc/Free a request */ -static struct req * -ses_GetReq(struct sess *sp) +struct req * +SES_GetReq(struct sess *sp) { struct sesspool *pp; struct req *req; From phk at varnish-cache.org Wed Aug 8 10:06:24 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 08 Aug 2012 12:06:24 +0200 Subject: [master] d9a9ecd Doing rollback in a esi:include request would roll back to the original ESI processed request, rather than to the included requests. Message-ID: commit d9a9ecd999f78123ac6ef5dfa8fd4aac38130c26 Author: Poul-Henning Kamp Date: Wed Aug 8 10:04:57 2012 +0000 Doing rollback in a esi:include request would roll back to the original ESI processed request, rather than to the included requests. Fix by allocating/cloning a new request for the esi:include transactions. Testcase by: scoof Fixes #1168 diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index a6e5f11..daef6a9 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -42,80 +42,93 @@ /*--------------------------------------------------------------------*/ static void -ved_include(struct req *req, const char *src, const char *host) +ved_include(struct req *preq, const char *src, const char *host) { - struct object *obj; struct worker *wrk; - char *sp_ws_wm; + struct req *req; char *wrk_ws_wm; - unsigned sxid, res_mode; int i; - wrk = req->wrk; + wrk = preq->wrk; - if (req->esi_level >= cache_param->max_esi_depth) + if (preq->esi_level >= cache_param->max_esi_depth) return; - req->esi_level++; (void)WRW_FlushRelease(wrk); - obj = req->obj; - req->obj = NULL; - res_mode = req->res_mode; - - /* Reset request to status before we started messing with it */ - HTTP_Copy(req->http, req->http0); - /* Take a workspace snapshot */ - sp_ws_wm = WS_Snapshot(req->ws); wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ - http_SetH(req->http, HTTP_HDR_URL, src); + req = SES_GetReq(preq->sp); + req->esi_level = preq->esi_level + 1; + + HTTP_Copy(req->http0, preq->http0); + + req->http0->conds = 0; + + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + + http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { - http_Unset(req->http, H_Host); - http_Unset(req->http, H_If_Modified_Since); - http_SetHeader(req->http, host); + http_Unset(req->http0, H_Host); + http_SetHeader(req->http0, host); } + + http_ForceGet(req->http0); + http_Unset(req->http0, H_If_Modified_Since); + + /* Client content already taken care of */ + http_Unset(req->http0, H_Content_Length); + + /* Reset request to status before we started messing with it */ + HTTP_Copy(req->http, req->http0); + + req->vcl = preq->vcl; + preq->vcl = NULL; + req->wrk = preq->wrk; + /* * XXX: We should decide if we should cache the director * XXX: or not (for session/backend coupling). Until then * XXX: make sure we don't trip up the check in vcl_recv. */ - req->director = NULL; req->req_step = R_STP_RECV; - http_ForceGet(req->http); + req->t_req = preq->t_req; + req->gzip_resp = preq->gzip_resp; + req->crc = preq->crc; + req->l_crc = preq->l_crc; - /* Don't do conditionals */ - req->http->conds = 0; - http_Unset(req->http, H_If_Modified_Since); + THR_SetRequest(req); - /* Client content already taken care of */ - http_Unset(req->http, H_Content_Length); - - sxid = req->xid; while (1) { req->wrk = wrk; i = CNT_Request(wrk, req); if (i == 1) break; + DSL(0x20, SLT_Debug, req->sp->vsl_id, + "loop waiting for ESI (%d)", i); assert(i == 2); AZ(req->wrk); - DSL(0x20, SLT_Debug, req->sp->vsl_id, "loop waiting for ESI"); (void)usleep(10000); } - req->xid = sxid; - req->wrk = wrk; - req->esi_level--; - req->obj = obj; - req->res_mode = res_mode; /* Reset the workspace */ - WS_Reset(req->ws, sp_ws_wm); WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_resp); - if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); + WRW_Reserve(preq->wrk, &preq->sp->fd, preq->vsl, preq->t_resp); + if (preq->res_mode & RES_CHUNKED) + WRW_Chunked(preq->wrk); + + preq->vcl = req->vcl; + req->vcl = NULL; + + preq->crc = req->crc; + preq->l_crc = req->l_crc; + + req->wrk = NULL; + + THR_SetRequest(preq); + SES_ReleaseReq(req); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/r01168.vtc b/bin/varnishtest/tests/r01168.vtc new file mode 100644 index 0000000..fb0a0c5 --- /dev/null +++ b/bin/varnishtest/tests/r01168.vtc @@ -0,0 +1,26 @@ +varnishtest "Test ESI rollback interaction" + +server s1 { + rxreq + expect req.url == "/" + txresp -body {} + + rxreq + expect req.url == "/esi" + txresp -body "1" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + rollback; + } + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 1 +} -run From kristian at varnish-cache.org Wed Aug 8 14:41:12 2012 From: kristian at varnish-cache.org (=?UTF-8?Q?Kristian_Lyngst=C3=B8l?=) Date: Wed, 08 Aug 2012 16:41:12 +0200 Subject: [master] 579f712 Doc: Fix indentation issue Message-ID: commit 579f7120c0c03e0bd9da25d5a8287beace4f872e Author: Kristian Lyngstol Date: Wed Aug 8 16:40:14 2012 +0200 Doc: Fix indentation issue Old indentation made the :ref: into a literal block, thus not a real reference. This should do the trick. diff --git a/doc/sphinx/faq/general.rst b/doc/sphinx/faq/general.rst index 2444394..44a11b3 100644 --- a/doc/sphinx/faq/general.rst +++ b/doc/sphinx/faq/general.rst @@ -187,7 +187,7 @@ Yes, you need VCL code like this:: set req.backend = foobar; } - Please see :ref:`tutorial-advanced_backend_servers-directors_`. +Please see :ref:`tutorial-advanced_backend_servers-directors_`. Why ... From kristian at varnish-cache.org Wed Aug 8 14:45:15 2012 From: kristian at varnish-cache.org (=?UTF-8?Q?Kristian_Lyngst=C3=B8l?=) Date: Wed, 08 Aug 2012 16:45:15 +0200 Subject: [master] 2b08b3d doc: Attempt two at fixing references. Message-ID: commit 2b08b3dd05689534d8aeb7e966eafd15a292a9d8 Author: Kristian Lyngstol Date: Wed Aug 8 16:45:06 2012 +0200 doc: Attempt two at fixing references. diff --git a/doc/sphinx/faq/general.rst b/doc/sphinx/faq/general.rst index 44a11b3..b0c7e13 100644 --- a/doc/sphinx/faq/general.rst +++ b/doc/sphinx/faq/general.rst @@ -187,7 +187,7 @@ Yes, you need VCL code like this:: set req.backend = foobar; } -Please see :ref:`tutorial-advanced_backend_servers-directors_`. +Please see :ref:`tutorial-advanced_backend_servers-directors`. Why ... @@ -196,7 +196,7 @@ Why ... **Why does it look like Varnish sends all requests to the backend? I thought it was a cache?** -Please see ref:`tutorial-increasing_your_hitrate`. +Please see :ref:`tutorial-increasing_your_hitrate`. **Why does Varnish require the system to have a C compiler?** From apj at varnish-cache.org Wed Aug 8 19:41:02 2012 From: apj at varnish-cache.org (Andreas Plesner Jacobsen) Date: Wed, 08 Aug 2012 21:41:02 +0200 Subject: [master] e9a47e8 Spelling Message-ID: commit e9a47e802bc95d4685b5c0a1eee50a9ce9d497c5 Author: Andreas Plesner Jacobsen Date: Wed Aug 8 21:40:52 2012 +0200 Spelling diff --git a/doc/sphinx/phk/index.rst b/doc/sphinx/phk/index.rst index f4f880d..3b49a85 100644 --- a/doc/sphinx/phk/index.rst +++ b/doc/sphinx/phk/index.rst @@ -4,7 +4,7 @@ Poul-Hennings random outbursts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -You may or may not want to know what Poul-Henning think. +You may or may not want to know what Poul-Henning thinks. .. toctree:: :maxdepth: 1 From phk at varnish-cache.org Thu Aug 9 08:23:12 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 09 Aug 2012 10:23:12 +0200 Subject: [master] cc710d5 Explicitly sync the header of the VSM so other processes can read(2) it on kernels without coherent VM/buf (OpenBSD, still ?, really ?) Message-ID: commit cc710d56021a4d1927ceedf426cebfff48ef1860 Author: Poul-Henning Kamp Date: Thu Aug 9 08:22:24 2012 +0000 Explicitly sync the header of the VSM so other processes can read(2) it on kernels without coherent VM/buf (OpenBSD, still ?, really ?) Submitted by: Federico G. Schwindt diff --git a/bin/varnishd/mgt/mgt_shmem.c b/bin/varnishd/mgt/mgt_shmem.c index 79f8c41..bc59194 100644 --- a/bin/varnishd/mgt/mgt_shmem.c +++ b/bin/varnishd/mgt/mgt_shmem.c @@ -187,8 +187,7 @@ mgt_shm_size(void) size = mgt_param.vsl_space + mgt_param.vsm_space; ps = getpagesize(); - size += ps - 1; - size &= ~(ps - 1U); + size = RUP2(size, ps); return (size); } @@ -247,6 +246,9 @@ mgt_SHM_Create(void) (void)unlink(fnbuf); exit (-1); } + + /* Commit changes, for OS's without coherent VM/buf */ + AZ(msync(p, getpagesize(), MS_SYNC)); } /*-------------------------------------------------------------------- From phk at varnish-cache.org Thu Aug 9 08:27:31 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 09 Aug 2012 10:27:31 +0200 Subject: [master] efaba47 Recognize OpenBSD as platform. Federico says it almost works. Message-ID: commit efaba477e6235e283252d3bd63c570e02166ef64 Author: Poul-Henning Kamp Date: Thu Aug 9 08:27:03 2012 +0000 Recognize OpenBSD as platform. Federico says it almost works. Submitted by: Federico G. Schwindt diff --git a/autogen.sh b/autogen.sh index 07df626..6d28093 100755 --- a/autogen.sh +++ b/autogen.sh @@ -12,6 +12,9 @@ Darwin) FreeBSD) LIBTOOLIZE=libtoolize ;; +OpenBSD) + LIBTOOLIZE=libtoolize + ;; Linux) LIBTOOLIZE=libtoolize ;; From phk at varnish-cache.org Thu Aug 9 08:29:12 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 09 Aug 2012 10:29:12 +0200 Subject: [master] 1b3b48e Remove long gone cli.debug cli calls Message-ID: commit 1b3b48e3e9b3ea1d8659da13fb78983d8299bed2 Author: Poul-Henning Kamp Date: Thu Aug 9 08:28:56 2012 +0000 Remove long gone cli.debug cli calls diff --git a/bin/varnishtest/tests/v00006.vtc b/bin/varnishtest/tests/v00006.vtc index ca4c827..494007f 100644 --- a/bin/varnishtest/tests/v00006.vtc +++ b/bin/varnishtest/tests/v00006.vtc @@ -41,7 +41,7 @@ varnish v1 -expect n_backend == 2 varnish v1 -expect n_vcl_avail == 2 varnish v1 -expect n_vcl_discard == 0 -varnish v1 -cli "debug.backend" -cli "vcl.list" +varnish v1 -cli "vcl.list" # Discard the first VCL @@ -64,7 +64,7 @@ client c1 { # The workthread should have released its VCL reference now # but we need to tickle the CLI to notice -varnish v1 -cli "debug.backend" -cli "vcl.list" +varnish v1 -cli "vcl.list" varnish v1 -expect n_backend == 1 varnish v1 -expect n_vcl_avail == 1 From phk at varnish-cache.org Thu Aug 9 08:30:04 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 09 Aug 2012 10:30:04 +0200 Subject: [master] a47e651 Remove long since gone debug.backend cli. Message-ID: commit a47e651f8632c4da0b6be5e4b5d8db386a6bd8f4 Author: Poul-Henning Kamp Date: Thu Aug 9 08:29:39 2012 +0000 Remove long since gone debug.backend cli. Submitted by: Federico G. Schwindt diff --git a/bin/varnishtest/tests/v00012.vtc b/bin/varnishtest/tests/v00012.vtc index 285f2c1..e7c8d44 100644 --- a/bin/varnishtest/tests/v00012.vtc +++ b/bin/varnishtest/tests/v00012.vtc @@ -33,8 +33,6 @@ client c2 { expect resp.status == 503 } -run -varnish v1 -cli "debug.backend" - sema r2 sync 2 client c1 -wait From phk at varnish-cache.org Thu Aug 9 10:54:36 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Thu, 09 Aug 2012 12:54:36 +0200 Subject: [master] 5d82c73 Remove comment OBE. Message-ID: commit 5d82c73b6686d66bfd0279fd3b7be6bd1767015f Author: Poul-Henning Kamp Date: Thu Aug 9 09:49:06 2012 +0000 Remove comment OBE. diff --git a/bin/varnishd/cache/cache_httpconn.c b/bin/varnishd/cache/cache_httpconn.c index 6ebb86c..8b331af 100644 --- a/bin/varnishd/cache/cache_httpconn.c +++ b/bin/varnishd/cache/cache_httpconn.c @@ -96,12 +96,6 @@ HTC_Reinit(struct http_conn *htc) } /*-------------------------------------------------------------------- - * Return -3 if it's all whitespace so far - * Return 0 if we need more text - * Return 1 if we have a complete HTTP procol header - */ - -/*-------------------------------------------------------------------- * Check if we have a complete HTTP request or response yet * */ From phk at varnish-cache.org Mon Aug 13 06:48:28 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2012 08:48:28 +0200 Subject: [master] 09c459c Eliminate the cnt_start state by folding it into cnt_recv Message-ID: commit 09c459cb263f2551213d52fb4c56b27e7757cf71 Author: Poul-Henning Kamp Date: Mon Aug 13 06:48:12 2012 +0000 Eliminate the cnt_start state by folding it into cnt_recv diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 0cee630..31e0a46 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -50,7 +50,7 @@ *DOT hash -> CNT_Request [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" *DOT color=blue] *DOT disembark -> hash [style=dotted, color=blue] - *DOT http1_wait -> CNT_Request [label="S_STP_WORKING\nR_STP_START"] + *DOT http1_wait -> CNT_Request [label="S_STP_WORKING\nR_STP_RECV"] *DOT http1_wait -> disembark [label="Session close"] *DOT http1_wait -> disembark [label="Timeout" color=green] *DOT disembark -> waiter [style=dotted, color=green] @@ -59,7 +59,7 @@ *DOT [label="Busy object\nS_STP_WORKING\nR_STP_LOOKUP" color=blue] *DOT CNT_Request -> http1_cleanup *DOT http1_cleanup -> disembark [label="Session close"] - *DOT http1_cleanup -> CNT_Request [label="S_STP_WORKING\nR_STP_START"] + *DOT http1_cleanup -> CNT_Request [label="S_STP_WORKING\nR_STP_RECV"] *DOT http1_cleanup -> http1_wait [label="S_STP_NEWREQ"] *DOT *DOT } @@ -331,10 +331,10 @@ HTTP1_Session(struct worker *wrk, struct req *req) assert( sp->sess_step == S_STP_NEWREQ || req->req_step == R_STP_LOOKUP || - req->req_step == R_STP_START); + req->req_step == R_STP_RECV); if (sp->sess_step == S_STP_WORKING) { - if (req->req_step == R_STP_START) + if (req->req_step == R_STP_RECV) done = http1_dissect(wrk, req); if (done == 0) done = CNT_Request(wrk, req); @@ -350,7 +350,7 @@ HTTP1_Session(struct worker *wrk, struct req *req) break; case SESS_DONE_RET_START: sp->sess_step = S_STP_WORKING; - req->req_step = R_STP_START; + req->req_step = R_STP_RECV; break; default: WRONG("Illegal enum http1_cleanup_ret"); @@ -362,7 +362,7 @@ HTTP1_Session(struct worker *wrk, struct req *req) if (done) return; sp->sess_step = S_STP_WORKING; - req->req_step = R_STP_START; + req->req_step = R_STP_RECV; } } } diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index b809c6d..0fbca29 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1105,6 +1105,16 @@ cnt_recv(const struct worker *wrk, struct req *req) AZ(req->obj); AZ(req->busyobj); + /* Assign XID and log */ + req->xid = ++xids; /* XXX not locked */ + VSLb(req->vsl, SLT_ReqStart, "%s %s %u", + req->sp->addr, req->sp->port, req->xid); + + if (req->err_code) { + req->req_step = R_STP_ERROR; + return (0); + } + /* By default we use the first backend */ AZ(req->director); req->director = req->vcl->director[0]; @@ -1169,42 +1179,6 @@ cnt_recv(const struct worker *wrk, struct req *req) } /*-------------------------------------------------------------------- - * START - * First time we see a request - * -DOT start [ -DOT shape=box -DOT label="cnt_start:\nDissect request\nHandle expect" -DOT ] -DOT start -> recv [style=bold,color=green] -DOT start -> DONE [label=errors] - */ - -static int -cnt_start(struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - AZ(req->restarts); - AZ(req->obj); - AN(req->vcl); - AZ(req->esi_level); - assert(!isnan(req->t_req)); - - /* Assign XID and log */ - req->xid = ++xids; /* XXX not locked */ - VSLb(req->vsl, SLT_ReqStart, "%s %s %u", - req->sp->addr, req->sp->port, req->xid); - - if (req->err_code) - req->req_step = R_STP_ERROR; - else - req->req_step = R_STP_RECV; - return (0); -} - -/*-------------------------------------------------------------------- * Central state engine dispatcher. * * Kick the session around until it has had enough. @@ -1235,8 +1209,7 @@ CNT_Request(struct worker *wrk, struct req *req) */ assert( req->req_step == R_STP_LOOKUP || - req->req_step == R_STP_START || - req->req_step == R_STP_RECV); // from ESI + req->req_step == R_STP_RECV); req->wrk = wrk; diff --git a/include/tbl/steps.h b/include/tbl/steps.h index cef939b..3ceaa5e 100644 --- a/include/tbl/steps.h +++ b/include/tbl/steps.h @@ -38,7 +38,6 @@ SESS_STEP(working, WORKING) #ifdef REQ_STEP REQ_STEP(restart, RESTART, (wrk, req)) REQ_STEP(recv, RECV, (wrk, req)) -REQ_STEP(start, START, (wrk, req)) REQ_STEP(pipe, PIPE, (wrk, req)) REQ_STEP(pass, PASS, (wrk, req)) REQ_STEP(lookup, LOOKUP, (wrk, req)) From phk at varnish-cache.org Mon Aug 13 09:30:49 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2012 11:30:49 +0200 Subject: [master] e7d5afe Allocate a unique "vxid" to all sessions, requests and backend requests (busyobj). Message-ID: commit e7d5afec68f4a62ca8037d928c6298fca7691287 Author: Poul-Henning Kamp Date: Mon Aug 13 09:27:41 2012 +0000 Allocate a unique "vxid" to all sessions, requests and backend requests (busyobj). This replaces the current "VID" as visible in the X-Varnish header. The new "stolen numbers" causes a lot of testcases to need updates, most trivial, but a few needed more extensive work to be predictable under the new circumstances. Next step is to carry this change through in VSL, and link all the VXID's to each other. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 71bba01..35c2b52 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -543,7 +543,7 @@ VTAILQ_HEAD(storagehead, storage); struct object { unsigned magic; #define OBJECT_MAGIC 0x32851d42 - unsigned xid; + uint32_t vxid; struct storage *objstore; struct objcore *objcore; @@ -584,7 +584,6 @@ struct req { #define REQ_MAGIC 0x2751aaa1 uint32_t vxid; - unsigned xid; int restarts; int esi_level; int disable_esi; @@ -769,7 +768,6 @@ void HTTP1_Session(struct worker *, struct req *); /* cache_req_fsm.c [CNT] */ int CNT_Request(struct worker *, struct req *); -void CNT_Init(void); /* cache_cli.c [CLI] */ void CLI_Init(void); @@ -1054,7 +1052,7 @@ char *WS_Alloc(struct ws *ws, unsigned bytes); char *WS_Snapshot(struct ws *ws); /* rfc2616.c */ -void RFC2616_Ttl(struct busyobj *, unsigned xid); +void RFC2616_Ttl(struct busyobj *); enum body_status RFC2616_Body(struct busyobj *, struct dstat *); unsigned RFC2616_Req_Gzip(const struct http *); int RFC2616_Do_Cond(const struct req *sp); diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 4164e4b..c949acc 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -758,7 +758,7 @@ ban_check_object(struct object *o, struct vsl_log *vsl, oc_updatemeta(oc); /* BAN also changed, but that is not important any more */ /* XXX: no req in lurker */ - VSLb(vsl, SLT_ExpBan, "%u was banned", o->xid); + VSLb(vsl, SLT_ExpBan, "%u was banned", o->vxid); EXP_Rearm(o); return (1); } diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index eb5998a..3b9ae2e 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -852,7 +852,7 @@ http_FilterReq(const struct req *req, unsigned how) else http_linkh(hp, req->http, HTTP_HDR_PROTO); http_filterfields(hp, req->http, how); - http_PrintfHeader(hp, "X-Varnish: %u", req->xid); + http_PrintfHeader(hp, "X-Varnish: %u", req->vxid); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index 31e0a46..d181d11 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -101,7 +101,6 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req) AZ(req->vcl); AZ(req->obj); AZ(req->esi_level); - assert(req->xid == 0); assert(isnan(req->t_req)); assert(isnan(req->t_resp)); @@ -196,9 +195,6 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) } sp->t_idle = W_TIM_real(wrk); - if (req->xid == 0) - req->t_resp = sp->t_idle; - req->xid = 0; VSL_Flush(req->vsl, 0); req->t_req = NAN; @@ -225,7 +221,6 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) WS_Reset(req->ws, NULL); WS_Reset(wrk->aws, NULL); - req->vxid = VXID_Get(&wrk->vxid_pool); if (HTC_Reinit(req->htc) == HTC_COMPLETE) { req->t_req = sp->t_idle; @@ -341,6 +336,7 @@ HTTP1_Session(struct worker *wrk, struct req *req) if (done == 2) return; assert(done == 1); + assert(req->vxid == 0); sdr = http1_cleanup(sp, wrk, req); switch (sdr) { case SESS_DONE_RET_GONE: diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index c48a3d9..37aea3a 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -35,6 +35,8 @@ #include "cache.h" #include "common/heritage.h" +#include "vcli_priv.h" + #include "waiter/waiter.h" #include "hash/hash_slinger.h" @@ -93,6 +95,7 @@ THR_GetName(void) */ static uint32_t vxid_base; +static uint32_t vxid_chunk = 32768; static struct lock vxid_lock; uint32_t @@ -102,8 +105,8 @@ VXID_Get(struct vxid_pool *v) if (v->count == 0) { Lck_Lock(&vxid_lock); v->next = vxid_base; - v->count = 32768; - vxid_base = v->count; + v->count = vxid_chunk; + vxid_base += v->count; Lck_Unlock(&vxid_lock); } v->count--; @@ -113,6 +116,52 @@ VXID_Get(struct vxid_pool *v) } /*-------------------------------------------------------------------- + * Debugging aids + */ + +/* + * Dumb down the VXID allocation to make it predictable for + * varnishtest cases + */ +static void +cli_debug_xid(struct cli *cli, const char * const *av, void *priv) +{ + (void)priv; + if (av[2] != NULL) { + vxid_base = strtoul(av[2], NULL, 0); + vxid_chunk = 1; + } + VCLI_Out(cli, "XID is %u", vxid_base); +} + +/* + * Default to seed=1, this is the only seed value POSIXl guarantees will + * result in a reproducible random number sequence. + */ +static void +cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) +{ + (void)priv; + unsigned seed = 1; + + if (av[2] != NULL) + seed = strtoul(av[2], NULL, 0); + srandom(seed); + srand48(random()); + VCLI_Out(cli, "Random(3) seeded with %u", seed); +} + +static struct cli_proto debug_cmds[] = { + { "debug.xid", "debug.xid", + "\tExamine or set XID\n", 0, 1, "d", cli_debug_xid }, + { "debug.srandom", "debug.srandom", + "\tSeed the random(3) function\n", 0, 1, "d", + cli_debug_srandom }, + { NULL } +}; + + +/*-------------------------------------------------------------------- * XXX: Think more about which order we start things */ @@ -142,7 +191,6 @@ child_main(void) CLI_Init(); Fetch_Init(); - CNT_Init(); VCL_Init(); HTTP_Init(); @@ -168,6 +216,10 @@ child_main(void) BAN_Compile(); + srandomdev(); + srand48(random()); + CLI_AddFuncs(debug_cmds); + /* Wait for persistent storage to load if asked to */ if (cache_param->diag_bitmap & 0x00020000) SMP_Ready(); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index ff9a65b..c38da38 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -164,7 +164,7 @@ pan_object(const struct object *o) const struct storage *st; VSB_printf(pan_vsp, " obj = %p {\n", o); - VSB_printf(pan_vsp, " xid = %u,\n", o->xid); + VSB_printf(pan_vsp, " vxid = %u,\n", o->vxid); pan_ws(o->ws_o, 4); pan_http("obj", o->http, 4); VSB_printf(pan_vsp, " len = %jd,\n", (intmax_t)o->len); @@ -236,8 +236,8 @@ pan_req(const struct req *req) VSB_printf(pan_vsp, "req = %p {\n", req); - VSB_printf(pan_vsp, " sp = %p, xid = %u,", - req->sp, req->xid); + VSB_printf(pan_vsp, " sp = %p, vxid = %u,", + req->sp, req->vxid); switch (req->req_step) { #define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break; diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 0fbca29..6e03e4c 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -62,7 +62,6 @@ DOT acceptor -> start [style=bold,color=green] #include "config.h" #include -#include #include #include @@ -70,7 +69,6 @@ DOT acceptor -> start [style=bold,color=green] #include "hash/hash_slinger.h" #include "vcl.h" -#include "vcli_priv.h" #include "vsha256.h" #include "vtim.h" @@ -78,7 +76,6 @@ DOT acceptor -> start [style=bold,color=green] #include "compat/srandomdev.h" #endif -static unsigned xids; /*-------------------------------------------------------------------- * We have a refcounted object on the session, and possibly the busyobj * which is fetching it, prepare a response. @@ -289,7 +286,7 @@ cnt_error(struct worker *wrk, struct req *req) return(1); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - req->obj->xid = req->xid; + req->obj->vxid = req->vxid; req->obj->exp.entered = req->t_req; h = req->obj->http; @@ -406,7 +403,7 @@ cnt_fetch(struct worker *wrk, struct req *req) */ EXP_Clr(&bo->exp); bo->exp.entered = W_TIM_real(wrk); - RFC2616_Ttl(bo, req->xid); + RFC2616_Ttl(bo); /* pass from vclrecv{} has negative TTL */ if (req->objcore->objhead == NULL) @@ -629,7 +626,7 @@ cnt_fetchbody(struct worker *wrk, struct req *req) VSB_delete(vary); } - req->obj->xid = req->xid; + req->obj->vxid = req->vxid; req->obj->response = req->err_code; WS_Assert(req->obj->ws_o); @@ -845,7 +842,7 @@ cnt_lookup(struct worker *wrk, struct req *req) if (oc->flags & OC_F_PASS) { wrk->stats.cache_hitpass++; - VSLb(req->vsl, SLT_HitPass, "%u", req->obj->xid); + VSLb(req->vsl, SLT_HitPass, "%u", req->obj->vxid); (void)HSH_Deref(&wrk->stats, NULL, &req->obj); AZ(req->objcore); req->req_step = R_STP_PASS; @@ -853,7 +850,7 @@ cnt_lookup(struct worker *wrk, struct req *req) } wrk->stats.cache_hit++; - VSLb(req->vsl, SLT_Hit, "%u", req->obj->xid); + VSLb(req->vsl, SLT_Hit, "%u", req->obj->vxid); req->req_step = R_STP_HIT; return (0); } @@ -1106,9 +1103,8 @@ cnt_recv(const struct worker *wrk, struct req *req) AZ(req->busyobj); /* Assign XID and log */ - req->xid = ++xids; /* XXX not locked */ VSLb(req->vsl, SLT_ReqStart, "%s %s %u", - req->sp->addr, req->sp->port, req->xid); + req->sp->addr, req->sp->port, req->vxid); if (req->err_code) { req->req_step = R_STP_ERROR; @@ -1211,6 +1207,9 @@ CNT_Request(struct worker *wrk, struct req *req) req->req_step == R_STP_LOOKUP || req->req_step == R_STP_RECV); + if (req->req_step == R_STP_RECV) + req->vxid = VXID_Get(&wrk->vxid_pool); + req->wrk = wrk; for (done = 0; !done; ) { @@ -1245,7 +1244,7 @@ CNT_Request(struct worker *wrk, struct req *req) (uintmax_t)req->req_bodybytes); } VSLb(req->vsl, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f", - req->xid, + req->vxid, req->t_req, req->sp->t_idle, req->sp->t_idle - req->t_resp, @@ -1254,6 +1253,7 @@ CNT_Request(struct worker *wrk, struct req *req) /* done == 2 was charged by cache_hash.c */ SES_Charge(wrk, req); + req->vxid = 0; } req->wrk = NULL; @@ -1265,56 +1265,3 @@ CNT_Request(struct worker *wrk, struct req *req) /* DOT } */ - -/*-------------------------------------------------------------------- - * Debugging aids - */ - -static void -cli_debug_xid(struct cli *cli, const char * const *av, void *priv) -{ - (void)priv; - if (av[2] != NULL) - xids = strtoul(av[2], NULL, 0); - VCLI_Out(cli, "XID is %u", xids); -} - -/* - * Default to seed=1, this is the only seed value POSIXl guarantees will - * result in a reproducible random number sequence. - */ -static void -cli_debug_srandom(struct cli *cli, const char * const *av, void *priv) -{ - (void)priv; - unsigned seed = 1; - - if (av[2] != NULL) - seed = strtoul(av[2], NULL, 0); - srandom(seed); - srand48(random()); - VCLI_Out(cli, "Random(3) seeded with %u", seed); -} - -static struct cli_proto debug_cmds[] = { - { "debug.xid", "debug.xid", - "\tExamine or set XID\n", 0, 1, "d", cli_debug_xid }, - { "debug.srandom", "debug.srandom", - "\tSeed the random(3) function\n", 0, 1, "d", - cli_debug_srandom }, - { NULL } -}; - -/*-------------------------------------------------------------------- - * - */ - -void -CNT_Init(void) -{ - - srandomdev(); - srand48(random()); - xids = random(); - CLI_AddFuncs(debug_cmds); -} diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c index fda117d..0a554f4 100644 --- a/bin/varnishd/cache/cache_response.c +++ b/bin/varnishd/cache/cache_response.c @@ -134,11 +134,11 @@ RES_BuildHttp(struct req *req) VTIM_format(VTIM_real(), time_str); http_PrintfHeader(req->resp, "Date: %s", time_str); - if (req->xid != req->obj->xid) + if (req->vxid != req->obj->vxid) http_PrintfHeader(req->resp, - "X-Varnish: %u %u", req->xid, req->obj->xid); + "X-Varnish: %u %u", req->vxid, req->obj->vxid); else - http_PrintfHeader(req->resp, "X-Varnish: %u", req->xid); + http_PrintfHeader(req->resp, "X-Varnish: %u", req->vxid); http_PrintfHeader(req->resp, "Age: %.0f", req->obj->exp.age + req->t_resp - req->obj->exp.entered); diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c index 905b744..7f5fd35 100644 --- a/bin/varnishd/cache/cache_rfc2616.c +++ b/bin/varnishd/cache/cache_rfc2616.c @@ -63,7 +63,7 @@ */ void -RFC2616_Ttl(struct busyobj *bo, unsigned xid) +RFC2616_Ttl(struct busyobj *bo) { unsigned max_age, age; double h_date, h_expires; @@ -170,7 +170,7 @@ RFC2616_Ttl(struct busyobj *bo, unsigned xid) /* calculated TTL, Our time, Date, Expires, max-age, age */ VSLb(bo->vsl, SLT_TTL, "%u RFC %.0f %.0f %.0f %.0f %.0f %.0f %.0f %u", - xid, expp->ttl, -1., -1., expp->entered, + bo->vxid, expp->ttl, -1., -1., expp->entered, expp->age, h_date, h_expires, max_age); } diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 9d3d3cb..c7b9a4a 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -163,8 +163,6 @@ ses_sess_pool_task(struct worker *wrk, void *arg) req = SES_GetReq(sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - req->vxid = VXID_Get(&wrk->vxid_pool); - sp->sess_step = S_STP_NEWREQ; ses_req_pool_task(wrk, req); } @@ -199,8 +197,8 @@ ses_vsl_socket(struct sess *sp, const char *lsockname) strcpy(laddr, "-"); strcpy(lport, "-"); } - VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f", - sp->addr, sp->port, lsockname, laddr, lport, sp->t_open); + VSL(SLT_SessOpen, sp->vxid, "%u %s %s %s %s %s %.6f", + sp->vxid, sp->addr, sp->port, lsockname, laddr, lport, sp->t_open); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 7563184..215e7b6 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -412,21 +412,21 @@ VRT_DO_EXP(req, req->exp, keep, 0, ) VRT_DO_EXP(obj, req->obj->exp, grace, 0, EXP_Rearm(req->obj); - vrt_wsp_exp(req, req->obj->xid, &req->obj->exp);) + vrt_wsp_exp(req, req->obj->vxid, &req->obj->exp);) VRT_DO_EXP(obj, req->obj->exp, ttl, (req->t_req - req->obj->exp.entered), EXP_Rearm(req->obj); - vrt_wsp_exp(req, req->obj->xid, &req->obj->exp);) + vrt_wsp_exp(req, req->obj->vxid, &req->obj->exp);) VRT_DO_EXP(obj, req->obj->exp, keep, 0, EXP_Rearm(req->obj); - vrt_wsp_exp(req, req->obj->xid, &req->obj->exp);) + vrt_wsp_exp(req, req->obj->vxid, &req->obj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, grace, 0, - vrt_wsp_exp(req, req->xid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, ttl, 0, - vrt_wsp_exp(req, req->xid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, keep, 0, - vrt_wsp_exp(req, req->xid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) /*-------------------------------------------------------------------- * req.xid @@ -439,9 +439,9 @@ VRT_r_req_xid(const struct req *req) int size; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - size = snprintf(NULL, 0, "%u", req->xid) + 1; + size = snprintf(NULL, 0, "%u", req->vxid) + 1; AN(p = WS_Alloc(req->http->ws, size)); - assert(snprintf(p, size, "%u", req->xid) < size); + assert(snprintf(p, size, "%u", req->vxid) < size); return (p); } diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 53846a0..910808f 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -54,7 +54,7 @@ default_oc_getxid(struct dstat *ds, struct objcore *oc) struct object *o; o = oc_getobj(ds, oc); - return (o->xid); + return (o->vxid); } static struct object * __match_proto__(getobj_f) diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c index 09b2497..ff53af8 100644 --- a/bin/varnishd/storage/storage_persistent_silo.c +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -389,7 +389,7 @@ smp_oc_getxid(struct dstat *ds, struct objcore *oc) */ ASSERT_PTR_IN_SILO(sg->sc, o); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - return (o->xid); + return (o->vxid); } /*--------------------------------------------------------------------- diff --git a/bin/varnishtest/tests/b00003.vtc b/bin/varnishtest/tests/b00003.vtc index 8c2bf00..177643c 100644 --- a/bin/varnishtest/tests/b00003.vtc +++ b/bin/varnishtest/tests/b00003.vtc @@ -18,7 +18,7 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002 1001" + expect resp.http.X-Varnish == "1004 1001" } -run # Give varnish a chance to update stats diff --git a/bin/varnishtest/tests/b00010.vtc b/bin/varnishtest/tests/b00010.vtc index b27dd42..cfa3266 100644 --- a/bin/varnishtest/tests/b00010.vtc +++ b/bin/varnishtest/tests/b00010.vtc @@ -14,5 +14,5 @@ client c1 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.x-varnish == "1002 1001" + expect resp.http.x-varnish == "1003 1001" } -run diff --git a/bin/varnishtest/tests/b00012.vtc b/bin/varnishtest/tests/b00012.vtc index 154f6c0..302767b 100644 --- a/bin/varnishtest/tests/b00012.vtc +++ b/bin/varnishtest/tests/b00012.vtc @@ -20,11 +20,11 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1003" rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1003 1002" + expect resp.http.x-varnish == "1005 1003" } -run varnish v1 -expect sess_pipeline == 2 diff --git a/bin/varnishtest/tests/b00013.vtc b/bin/varnishtest/tests/b00013.vtc index b8e25e6..f0be1d9 100644 --- a/bin/varnishtest/tests/b00013.vtc +++ b/bin/varnishtest/tests/b00013.vtc @@ -21,12 +21,12 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1003" send "HTTP/1.1\n\n" rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1003 1002" + expect resp.http.x-varnish == "1005 1003" } -run varnish v1 -expect sess_readahead == 2 diff --git a/bin/varnishtest/tests/b00015.vtc b/bin/varnishtest/tests/b00015.vtc index 6e9d693..2e94add 100644 --- a/bin/varnishtest/tests/b00015.vtc +++ b/bin/varnishtest/tests/b00015.vtc @@ -19,7 +19,7 @@ client c1 { txreq -url "/" rxresp expect resp.status == 503 - expect resp.http.X-varnish == "1002" + expect resp.http.X-varnish == "1005" } -run # Then check that an cacheable error from the backend is @@ -35,14 +35,14 @@ client c1 { txreq -url "/" rxresp expect resp.status == 302 - expect resp.http.X-varnish == "1003" + expect resp.http.X-varnish == "1009" } -run client c1 { txreq -url "/" rxresp expect resp.status == 302 - expect resp.http.X-varnish == "1004 1003" + expect resp.http.X-varnish == "1012 1009" } -run # Then check that a non-cacheable error from the backend can be @@ -64,12 +64,12 @@ client c1 { txreq -url "/2" rxresp expect resp.status == 502 - expect resp.http.X-varnish == "1005" + expect resp.http.X-varnish == "1014" } -run client c1 { txreq -url "/2" rxresp expect resp.status == 502 - expect resp.http.X-varnish == "1006 1005" + expect resp.http.X-varnish == "1017 1014" } -run diff --git a/bin/varnishtest/tests/c00004.vtc b/bin/varnishtest/tests/c00004.vtc index 6b47ad5..cd79441 100644 --- a/bin/varnishtest/tests/c00004.vtc +++ b/bin/varnishtest/tests/c00004.vtc @@ -26,25 +26,25 @@ client c1 { txreq -hdr "Foobar: 2" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1003" expect resp.http.snafu == "2" txreq -hdr "Foobar: 3" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1003" + expect resp.http.X-Varnish == "1005" expect resp.http.snafu == "3" txreq rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1004" + expect resp.http.X-Varnish == "1007" expect resp.http.snafu == "4" txreq -hdr "Foobar: 1 " rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1005 1001" + expect resp.http.X-Varnish == "1009 1001" expect resp.http.snafu == "1" } -run diff --git a/bin/varnishtest/tests/c00010.vtc b/bin/varnishtest/tests/c00010.vtc index 6f0aca3..1b6a5ec 100644 --- a/bin/varnishtest/tests/c00010.vtc +++ b/bin/varnishtest/tests/c00010.vtc @@ -25,7 +25,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 7 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1003" } client c1 -run diff --git a/bin/varnishtest/tests/c00011.vtc b/bin/varnishtest/tests/c00011.vtc index 6bea217..952966b 100644 --- a/bin/varnishtest/tests/c00011.vtc +++ b/bin/varnishtest/tests/c00011.vtc @@ -25,7 +25,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 7 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1003" } client c1 -run diff --git a/bin/varnishtest/tests/c00012.vtc b/bin/varnishtest/tests/c00012.vtc index b578625..79185e1 100644 --- a/bin/varnishtest/tests/c00012.vtc +++ b/bin/varnishtest/tests/c00012.vtc @@ -25,7 +25,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 7 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1004" } client c1 -run diff --git a/bin/varnishtest/tests/c00013.vtc b/bin/varnishtest/tests/c00013.vtc index 885be31..fee1271 100644 --- a/bin/varnishtest/tests/c00013.vtc +++ b/bin/varnishtest/tests/c00013.vtc @@ -20,14 +20,16 @@ client c1 { expect resp.http.x-varnish == "1001" } -start +sema r1 sync 2 + client c2 { - sema r1 sync 2 txreq -url "/foo" -hdr "client: c2" + delay .1 sema r1 sync 2 rxresp expect resp.status == 200 expect resp.bodylen == 12 - expect resp.http.x-varnish == "1002 1001" + expect resp.http.x-varnish == "1004 1001" } -run client c1 -wait diff --git a/bin/varnishtest/tests/c00014.vtc b/bin/varnishtest/tests/c00014.vtc index 545c469..7e5dab1 100644 --- a/bin/varnishtest/tests/c00014.vtc +++ b/bin/varnishtest/tests/c00014.vtc @@ -32,7 +32,7 @@ client c2 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1004" } -run client c1 -wait diff --git a/bin/varnishtest/tests/c00015.vtc b/bin/varnishtest/tests/c00015.vtc index c323b9c..8490bf3 100644 --- a/bin/varnishtest/tests/c00015.vtc +++ b/bin/varnishtest/tests/c00015.vtc @@ -36,7 +36,7 @@ client c2 { rxresp expect resp.status == 200 expect resp.bodylen == 7 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1004" } -run varnish v1 -cli "vcl.use vcl1" @@ -46,7 +46,7 @@ client c3 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1003 1001" + expect resp.http.x-varnish == "1007 1001" } -run varnish v1 -cli "vcl.show vcl2" diff --git a/bin/varnishtest/tests/c00020.vtc b/bin/varnishtest/tests/c00020.vtc index 7fc707c..8e14f12 100644 --- a/bin/varnishtest/tests/c00020.vtc +++ b/bin/varnishtest/tests/c00020.vtc @@ -19,7 +19,7 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002 1001" + expect resp.http.X-Varnish == "1004 1001" } -run server s1 { @@ -35,19 +35,19 @@ client c2 { txreq -url "/foo" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1003" + expect resp.http.X-Varnish == "1006" txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1004 1001" + expect resp.http.X-Varnish == "1008 1001" txreq -url "/bar" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1005" + expect resp.http.X-Varnish == "1009" txreq -url "/foo" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1006 1003" + expect resp.http.X-Varnish == "1011 1006" } -run varnish v1 -expect sess_conn == 3 diff --git a/bin/varnishtest/tests/c00023.vtc b/bin/varnishtest/tests/c00023.vtc index 8c65eaa..a29908d 100644 --- a/bin/varnishtest/tests/c00023.vtc +++ b/bin/varnishtest/tests/c00023.vtc @@ -44,49 +44,49 @@ client c1 { rxresp expect resp.bodylen == 2 expect resp.status == 200 - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1003" txreq -url "/3" rxresp expect resp.bodylen == 3 expect resp.status == 200 - expect resp.http.X-Varnish == "1003" + expect resp.http.X-Varnish == "1005" txreq -url "/4" rxresp expect resp.bodylen == 4 expect resp.status == 200 - expect resp.http.X-Varnish == "1004" + expect resp.http.X-Varnish == "1007" txreq -url "/5" rxresp expect resp.bodylen == 5 expect resp.status == 200 - expect resp.http.X-Varnish == "1005" + expect resp.http.X-Varnish == "1009" txreq -url "/6" rxresp expect resp.bodylen == 6 expect resp.status == 200 - expect resp.http.X-Varnish == "1006" + expect resp.http.X-Varnish == "1011" txreq -url "/7" rxresp expect resp.bodylen == 7 expect resp.status == 200 - expect resp.http.X-Varnish == "1007" + expect resp.http.X-Varnish == "1013" txreq -url "/8" rxresp expect resp.bodylen == 8 expect resp.status == 200 - expect resp.http.X-Varnish == "1008" + expect resp.http.X-Varnish == "1015" txreq -url "/9" rxresp expect resp.bodylen == 9 expect resp.status == 200 - expect resp.http.X-Varnish == "1009" + expect resp.http.X-Varnish == "1017" } -run @@ -95,55 +95,55 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 1 - expect resp.http.X-Varnish == "1010 1001" + expect resp.http.X-Varnish == "1020 1001" txreq -url "/2" rxresp expect resp.bodylen == 2 expect resp.status == 200 - expect resp.http.X-Varnish == "1011 1002" + expect resp.http.X-Varnish == "1021 1003" txreq -url "/3" rxresp expect resp.bodylen == 3 expect resp.status == 200 - expect resp.http.X-Varnish == "1012 1003" + expect resp.http.X-Varnish == "1022 1005" txreq -url "/4" rxresp expect resp.bodylen == 4 expect resp.status == 200 - expect resp.http.X-Varnish == "1013 1004" + expect resp.http.X-Varnish == "1023 1007" txreq -url "/5" rxresp expect resp.bodylen == 5 expect resp.status == 200 - expect resp.http.X-Varnish == "1014 1005" + expect resp.http.X-Varnish == "1024 1009" txreq -url "/6" rxresp expect resp.bodylen == 6 expect resp.status == 200 - expect resp.http.X-Varnish == "1015 1006" + expect resp.http.X-Varnish == "1025 1011" txreq -url "/7" rxresp expect resp.bodylen == 7 expect resp.status == 200 - expect resp.http.X-Varnish == "1016 1007" + expect resp.http.X-Varnish == "1026 1013" txreq -url "/8" rxresp expect resp.bodylen == 8 expect resp.status == 200 - expect resp.http.X-Varnish == "1017 1008" + expect resp.http.X-Varnish == "1027 1015" txreq -url "/9" rxresp expect resp.bodylen == 9 expect resp.status == 200 - expect resp.http.X-Varnish == "1018 1009" + expect resp.http.X-Varnish == "1028 1017" } -run varnish v1 -cliok "hcb.dump" diff --git a/bin/varnishtest/tests/p00004.vtc b/bin/varnishtest/tests/p00004.vtc index e9b08f5..dab8ea4 100644 --- a/bin/varnishtest/tests/p00004.vtc +++ b/bin/varnishtest/tests/p00004.vtc @@ -29,7 +29,7 @@ client c1 { txreq -url "/bar" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1004" expect resp.http.bar == "bar" } -run @@ -37,7 +37,7 @@ varnish v1 -expect n_object == 2 varnish v1 -stop varnish v1 -start -varnish v1 -cliok "debug.xid 2000" +varnish v1 -cliok "debug.xid 1999" varnish v1 -expect n_vampireobject == 2 varnish v1 -expect n_object == 0 @@ -57,7 +57,7 @@ client c1 { txreq -url "/bar" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "2002 1002" + expect resp.http.X-Varnish == "2003 1004" expect resp.http.bar == "bar" } -run diff --git a/bin/varnishtest/tests/p00006.vtc b/bin/varnishtest/tests/p00006.vtc index d30c6cb..3334f36 100644 --- a/bin/varnishtest/tests/p00006.vtc +++ b/bin/varnishtest/tests/p00006.vtc @@ -25,7 +25,7 @@ client c1 { txreq -url "/foo" -hdr "foo: 2" -hdr "bar: 1" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1003" expect resp.http.foo == "foo2" } -run @@ -35,6 +35,7 @@ server s1 -wait varnish v1 -stop varnish v1 -start +varnish v1 -cliok "debug.xid 1999" varnish v1 -expect n_vampireobject == 2 @@ -42,13 +43,13 @@ client c1 { txreq -url "/foo" -hdr "foo: 1" -hdr "bar: 2" rxresp expect resp.status == 200 - #expect resp.http.X-Varnish == "1001" + expect resp.http.X-Varnish == "2001 1001" expect resp.http.foo == "foo1" txreq -url "/foo" -hdr "foo: 2" -hdr "bar: 1" rxresp expect resp.status == 200 - #expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "2002 1003" expect resp.http.foo == "foo2" } -run diff --git a/bin/varnishtest/tests/r00102.vtc b/bin/varnishtest/tests/r00102.vtc index 6d2d8aa..d2a3c13 100644 --- a/bin/varnishtest/tests/r00102.vtc +++ b/bin/varnishtest/tests/r00102.vtc @@ -28,7 +28,7 @@ client c1 { -body "123456789\n" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002 1001" + expect resp.http.X-Varnish == "1003 1001" } client c1 -run diff --git a/bin/varnishtest/tests/r00262.vtc b/bin/varnishtest/tests/r00262.vtc index b3c1cf9..1deb9ea 100644 --- a/bin/varnishtest/tests/r00262.vtc +++ b/bin/varnishtest/tests/r00262.vtc @@ -19,7 +19,7 @@ client c1 { send "GET / HTTP/1.1\r\n\r\n" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1002 1001" + expect resp.http.X-Varnish == "1003 1001" } client c1 -run diff --git a/bin/varnishtest/tests/r00466.vtc b/bin/varnishtest/tests/r00466.vtc index 8d753ba..3d64b22 100644 --- a/bin/varnishtest/tests/r00466.vtc +++ b/bin/varnishtest/tests/r00466.vtc @@ -34,5 +34,5 @@ client c1 { txreq -url "/bar" -hdr "Range: 200-300" rxresp expect resp.status == 206 - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1003" } -run diff --git a/bin/varnishtest/tests/s00000.vtc b/bin/varnishtest/tests/s00000.vtc index bde8934..b5090ff 100644 --- a/bin/varnishtest/tests/s00000.vtc +++ b/bin/varnishtest/tests/s00000.vtc @@ -26,6 +26,6 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1004" expect resp.bodylen == 6 } -run diff --git a/bin/varnishtest/tests/s00001.vtc b/bin/varnishtest/tests/s00001.vtc index 68fd520..44ea211 100644 --- a/bin/varnishtest/tests/s00001.vtc +++ b/bin/varnishtest/tests/s00001.vtc @@ -27,6 +27,6 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.x-varnish == "1002" + expect resp.http.x-varnish == "1004" expect resp.bodylen == 6 } -run diff --git a/bin/varnishtest/tests/s00002.vtc b/bin/varnishtest/tests/s00002.vtc index 3cb56cf..31fb400 100644 --- a/bin/varnishtest/tests/s00002.vtc +++ b/bin/varnishtest/tests/s00002.vtc @@ -69,5 +69,5 @@ client c2 { rxresp expect resp.http.foo == "bar" expect resp.status == 200 - expect resp.http.x-varnish == "1002 1001" + expect resp.http.x-varnish == "1004 1001" } -run diff --git a/bin/varnishtest/tests/v00011.vtc b/bin/varnishtest/tests/v00011.vtc index 6cce4de..43ea8c2 100644 --- a/bin/varnishtest/tests/v00011.vtc +++ b/bin/varnishtest/tests/v00011.vtc @@ -27,13 +27,13 @@ client c1 { client c1 { txreq -req "PURGE" rxresp - expect resp.http.X-Varnish == "1002" + expect resp.http.X-Varnish == "1004" expect resp.status == 209 } -run client c1 { txreq rxresp - expect resp.http.X-Varnish == "1003" + expect resp.http.X-Varnish == "1007" } -run diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index e493ae7..0ddf1d0 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -483,7 +483,7 @@ varnish_start(struct varnish *v) 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); + u = varnish_ask_cli(v, "debug.xid 999", &resp); if (vtc_error) return; if (u != CLIS_OK) From phk at varnish-cache.org Mon Aug 13 10:44:06 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2012 12:44:06 +0200 Subject: [master] 4670e05 Add a couple of counters to keep track of how many requests are on the busy-obj waitinglists Message-ID: commit 4670e0541e9559239c6f9aa360385ef45dc2928a Author: Poul-Henning Kamp Date: Mon Aug 13 10:43:38 2012 +0000 Add a couple of counters to keep track of how many requests are on the busy-obj waitinglists diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index abcb4c0..fd0bbe1 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -424,6 +424,8 @@ HSH_Lookup(struct req *req) if (cache_param->diag_bitmap & 0x20) VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh); + + wrk->stats.busy_sleep++; SES_Charge(req->wrk, req); /* * The objhead reference transfers to the sess, we get it @@ -480,6 +482,7 @@ hsh_rush(struct dstat *ds, struct objhead *oh) if (req == NULL) break; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + ds->busy_wakeup++; AZ(req->wrk); VTAILQ_REMOVE(&wl->list, req, w_list); DSL(0x20, SLT_Debug, req->sp->vsl_id, "off waiting list"); diff --git a/bin/varnishtest/tests/c00013.vtc b/bin/varnishtest/tests/c00013.vtc index fee1271..a79244b 100644 --- a/bin/varnishtest/tests/c00013.vtc +++ b/bin/varnishtest/tests/c00013.vtc @@ -33,3 +33,6 @@ client c2 { } -run client c1 -wait + +varnish v1 -expect busy_sleep == 1 +varnish v1 -expect busy_wakeup == 1 diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h index c3fd288..d9c78ce 100644 --- a/include/tbl/vsc_f_main.h +++ b/include/tbl/vsc_f_main.h @@ -249,6 +249,18 @@ VSC_F(thread_queue_len, uint64_t, 0, 'g', " See also param queue_max." ) +VSC_F(busy_sleep, uint64_t, 1, 'c', + "Number of requests sent to sleep on busy objhdr", + "Number of requests sent to sleep without a worker threads because" + " they found a busy object." +) + +VSC_F(busy_wakeup, uint64_t, 1, 'c', + "Number of requests woken after sleep on busy objhdr", + "Number of requests taken of the busy object sleep list and" + " and rescheduled." +) + VSC_F(sess_queued, uint64_t, 0, 'c', "Sessions queued for thread", "Number of times session was queued waiting for a thread." From phk at varnish-cache.org Mon Aug 13 11:06:22 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2012 13:06:22 +0200 Subject: [master] dc79130 If people only specify the Transient storage, only run on the Transient storage. Message-ID: commit dc7913071e7bc19ddc7139b0bc9e13ca99357bda Author: Poul-Henning Kamp Date: Mon Aug 13 11:05:05 2012 +0000 If people only specify the Transient storage, only run on the Transient storage. Fixes #1176 diff --git a/bin/varnishtest/tests/r01176.vtc b/bin/varnishtest/tests/r01176.vtc new file mode 100644 index 0000000..d9a0a99 --- /dev/null +++ b/bin/varnishtest/tests/r01176.vtc @@ -0,0 +1,14 @@ +varnishtest "-s Transient=malloc crash" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -storage "-s Transient=malloc" -vcl+backend {} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 +} -run From phk at varnish-cache.org Mon Aug 13 11:06:22 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2012 13:06:22 +0200 Subject: [master] 58596b2 Sigh, this one is the working part of the fix: Message-ID: commit 58596b2780fdfdfeea4c000fe3e3912196369df2 Author: Poul-Henning Kamp Date: Mon Aug 13 11:05:39 2012 +0000 Sigh, this one is the working part of the fix: If people only specify Transient, run only on Transient. Fixes #1176 diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c index 910808f..cd1a316 100644 --- a/bin/varnishd/storage/stevedore.c +++ b/bin/varnishd/storage/stevedore.c @@ -144,6 +144,8 @@ stv_pick_stevedore(struct vsl_log *vsl, const char **hint) VSLb(vsl, SLT_Debug, "Storage hint not usable"); *hint = NULL; } + if (stv_next == NULL) + return (stv_transient); /* pick a stevedore and bump the head along */ stv = VTAILQ_NEXT(stv_next, list); if (stv == NULL) From phk at varnish-cache.org Tue Aug 14 07:03:41 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 14 Aug 2012 09:03:41 +0200 Subject: [master] 158b428 Not sure what I was thinking: Have SLT_SessOpen log the fd#, not the xid, we already have that. Message-ID: commit 158b428abfe2566c17eaf510bee2c4f4e1a1c0e7 Author: Poul-Henning Kamp Date: Tue Aug 14 06:52:42 2012 +0000 Not sure what I was thinking: Have SLT_SessOpen log the fd#, not the xid, we already have that. diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index c7b9a4a..33c63ba 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -197,8 +197,8 @@ ses_vsl_socket(struct sess *sp, const char *lsockname) strcpy(laddr, "-"); strcpy(lport, "-"); } - VSL(SLT_SessOpen, sp->vxid, "%u %s %s %s %s %s %.6f", - sp->vxid, sp->addr, sp->port, lsockname, laddr, lport, sp->t_open); + VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f %d", + sp->addr, sp->port, lsockname, laddr, lport, sp->t_open, sp->fd); } /*-------------------------------------------------------------------- diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index ae83bf7..9d970e1 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -73,6 +73,7 @@ SLTM(SessOpen, "Client connection opened", "lsock\n Listen socket\n\n" "laddr\n Local IPv4/6 address ('-' if !$log_local_addr)\n\n" "lport\n Local TCP port ('-' if !$log_local_addr)\n\n" + "fd\n File descriptor number" ) /* From phk at varnish-cache.org Tue Aug 14 07:03:41 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 14 Aug 2012 09:03:41 +0200 Subject: [master] f5fe417 Move INCOMPL() into the VAS family and apply a bit of polish while there. Message-ID: commit f5fe41770bc33069377a11a4032a32faa8452f9f Author: Poul-Henning Kamp Date: Tue Aug 14 07:03:18 2012 +0000 Move INCOMPL() into the VAS family and apply a bit of polish while there. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 35c2b52..add0150 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -984,13 +984,6 @@ void VSL_Flush(struct vsl_log *, int overflow); VSL((tag), (id), __VA_ARGS__); \ } while (0) -#define INCOMPL() do { \ - VSL(SLT_Debug, 0, "INCOMPLETE AT: %s(%d)", __func__, __LINE__); \ - fprintf(stderr, \ - "INCOMPLETE AT: %s(%d)\n", \ - (const char *)__func__, __LINE__); \ - abort(); \ - } while (0) #endif /* cache_response.c */ diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index c38da38..e6b0941 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -343,9 +343,9 @@ pan_backtrace(void) /*--------------------------------------------------------------------*/ -static void +static void __attribute__((__noreturn__)) pan_ic(const char *func, const char *file, int line, const char *cond, - int err, int xxx) + int err, enum vas_e kind) { const char *q; const struct req *req; @@ -353,23 +353,28 @@ pan_ic(const char *func, const char *file, int line, const char *cond, AZ(pthread_mutex_lock(&panicstr_mtx)); /* Won't be released, we're going to die anyway */ - switch(xxx) { - case 3: + switch(kind) { + case VAS_WRONG: VSB_printf(pan_vsp, "Wrong turn at %s:%d:\n%s\n", file, line, cond); break; - case 2: + case VAS_VCL: VSB_printf(pan_vsp, "Panic from VCL:\n %s\n", cond); break; - case 1: + case VAS_MISSING: VSB_printf(pan_vsp, "Missing errorhandling code in %s(), %s line %d:\n" " Condition(%s) not true.", func, file, line, cond); break; + case VAS_INCOMPLETE: + VSB_printf(pan_vsp, + "Incomplete code in %s(), %s line %d:\n", + func, file, line); + break; default: - case 0: + case VAS_ASSERT: VSB_printf(pan_vsp, "Assert error in %s(), %s line %d:\n" " Condition(%s) not true.\n", diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 402b49f..1fc3760 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -285,14 +285,14 @@ vtc_hexdump(struct vtclog *vl, int lvl, const char *pfx, /**********************************************************************/ -static void +static void __attribute__((__noreturn__)) vtc_log_VAS_Fail(const char *func, const char *file, int line, - const char *cond, int err, int xxx) + const char *cond, int err, enum vas_e why) { struct vtclog *vl; (void)err; - (void)xxx; + (void)why; vl = pthread_getspecific(log_key); if (vl == NULL || vl->act) { fprintf(stderr, @@ -303,6 +303,7 @@ vtc_log_VAS_Fail(const char *func, const char *file, int line, vtc_log(vl, 0, "Assert error in %s(), %s line %d:" " Condition(%s) not true.\n", func, file, line, cond); } + abort(); } -vas_f *VAS_Fail = vtc_log_VAS_Fail; +vas_f *VAS_Fail __attribute__((__noreturn__)) = vtc_log_VAS_Fail; diff --git a/include/vas.h b/include/vas.h index ff20036..246acc1 100644 --- a/include/vas.h +++ b/include/vas.h @@ -38,24 +38,37 @@ #ifndef VAS_H_INCLUDED #define VAS_H_INCLUDED -typedef void vas_f(const char *, const char *, int, const char *, int, int); +enum vas_e { + VAS_WRONG, + VAS_MISSING, + VAS_ASSERT, + VAS_INCOMPLETE, + VAS_VCL, +}; -extern vas_f *VAS_Fail; +typedef void vas_f(const char *, const char *, int, const char *, int, + enum vas_e); + +extern vas_f *VAS_Fail __attribute__((__noreturn__)); #ifdef WITHOUT_ASSERTS #define assert(e) ((void)(e)) #else /* WITH_ASSERTS */ #define assert(e) \ do { \ - if (!(e)) \ - VAS_Fail(__func__, __FILE__, __LINE__, #e, errno, 0); \ + if (!(e)) { \ + VAS_Fail(__func__, __FILE__, __LINE__, \ + #e, errno, VAS_ASSERT); \ + } \ } while (0) #endif #define xxxassert(e) \ do { \ - if (!(e)) \ - VAS_Fail(__func__, __FILE__, __LINE__, #e, errno, 1); \ + if (!(e)) { \ + VAS_Fail(__func__, __FILE__, __LINE__, \ + #e, errno, VAS_MISSING); \ + } \ } while (0) /* Assert zero return value */ @@ -66,8 +79,13 @@ do { \ #define diagnostic(foo) assert(foo) #define WRONG(expl) \ do { \ - VAS_Fail(__func__, __FILE__, __LINE__, expl, errno, 3); \ - abort(); \ + VAS_Fail(__func__, __FILE__, __LINE__, expl, errno, VAS_WRONG); \ +} while (0) + +#define INCOMPL() \ +do { \ + VAS_Fail(__func__, __FILE__, __LINE__, \ + "", errno, VAS_INCOMPLETE); \ } while (0) #endif diff --git a/lib/libvarnish/vas.c b/lib/libvarnish/vas.c index 6f69928..d63763d 100644 --- a/lib/libvarnish/vas.c +++ b/lib/libvarnish/vas.c @@ -37,16 +37,24 @@ #include "vas.h" -static void +static void __attribute__((__noreturn__)) VAS_Fail_default(const char *func, const char *file, int line, - const char *cond, int err, int xxx) + const char *cond, int err, enum vas_e kind) { - if (xxx) { + if (kind == VAS_MISSING) { fprintf(stderr, "Missing errorhandling code in %s(), %s line %d:\n" " Condition(%s) not true.\n", func, file, line, cond); + } else if (kind == VAS_INCOMPLETE) { + fprintf(stderr, + "Incompelte code in %s(), %s line %d:\n", + func, file, line); + } else if (kind == VAS_WRONG) { + fprintf(stderr, + "Wrong turn in %s(), %s line %d:\n", + func, file, line); } else { fprintf(stderr, "Assert error in %s(), %s line %d:\n" @@ -59,4 +67,4 @@ VAS_Fail_default(const char *func, const char *file, int line, abort(); } -vas_f *VAS_Fail = VAS_Fail_default; +vas_f *VAS_Fail __attribute__((__noreturn__)) = VAS_Fail_default; diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index cd23473..fd1a135 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -45,7 +45,7 @@ vmod_panic(struct req *req, const char *str, ...) va_start(ap, str); b = VRT_String(req->http->ws, "PANIC: ", str, ap); va_end(ap); - VAS_Fail("VCL", "", 0, b, 0, 2); + VAS_Fail("VCL", "", 0, b, 0, VAS_VCL); } const char * __match_proto__(td_debug_author) From phk at varnish-cache.org Tue Aug 14 10:16:46 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 14 Aug 2012 12:16:46 +0200 Subject: [master] 3c53c1a Replace the fd# with the VXID in VSL records. Message-ID: commit 3c53c1affef3c7fdd0bb040c4f0f7c7f87694a61 Author: Poul-Henning Kamp Date: Tue Aug 14 10:16:23 2012 +0000 Replace the fd# with the VXID in VSL records. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index add0150..2441bd6 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -494,7 +494,6 @@ struct busyobj { * is recycled. */ unsigned refcount; - uint32_t vxid; uint8_t *vary; unsigned is_gzip; @@ -583,7 +582,6 @@ struct req { unsigned magic; #define REQ_MAGIC 0x2751aaa1 - uint32_t vxid; int restarts; int esi_level; int disable_esi; @@ -679,7 +677,6 @@ struct sess { enum sess_step sess_step; int fd; enum sess_close reason; - unsigned vsl_id; uint32_t vxid; /* Cross references ------------------------------------------*/ @@ -957,7 +954,7 @@ void SES_Charge(struct worker *, struct req *); struct sesspool *SES_NewPool(struct pool *pp, unsigned pool_no); void SES_DeletePool(struct sesspool *sp); int SES_ScheduleReq(struct req *); -struct req *SES_GetReq(struct sess *sp); +struct req *SES_GetReq(struct worker *, struct sess *); void SES_Handle(struct sess *sp, double now); void SES_ReleaseReq(struct req *); pool_func_t SES_pool_accept_task; diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index da2cdf8..c5831fd 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -251,7 +251,6 @@ VCA_SetupSess(struct worker *wrk, struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CAST_OBJ_NOTNULL(wa, (void*)wrk->aws->f, WRK_ACCEPT_MAGIC); sp->fd = wa->acceptsock; - sp->vsl_id = wa->acceptsock | VSL_CLIENTMARKER ; wa->acceptsock = -1; retval = wa->acceptlsock->name; assert(wa->acceptaddrlen <= sp->sockaddrlen); diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 7b3101b..e8efb90 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -181,7 +181,6 @@ bes_conn_try(struct req *req, struct vbc *vc, const struct vdi_simple *vs) vc->addr = NULL; vc->addrlen = 0; } else { - vc->vsl_id = s | VSL_BACKENDMARKER; VTCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); VSLb(req->vsl, SLT_BackendOpen, "%d %s %s %s ", vc->fd, vs->backend->display_name, abuf1, pbuf1); diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index 3baa0ca..b84e702 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -153,8 +153,6 @@ struct vbc { struct backend *backend; struct vdi_simple *vdis; struct vsl_log *vsl; - unsigned orig_vsl_id; - unsigned vsl_id; int fd; struct sockaddr_storage *addr; diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 8f0cc50..014e564 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -108,7 +108,6 @@ VBO_GetBusyObj(struct worker *wrk) AZ(bo->refcount); bo->refcount = 1; - bo->vxid = VXID_Get(&wrk->vxid_pool); p = (void*)(bo + 1); p = (void*)PRNDUP(p); @@ -129,6 +128,7 @@ VBO_GetBusyObj(struct worker *wrk) sz = cache_param->vsl_buffer; VSL_Setup(bo->vsl, p, sz); + bo->vsl->wid = VXID_Get(&wrk->vxid_pool) | VSL_BACKENDMARKER; p += sz; p = (void*)PRNDUP(p); assert(p < bo->end); diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c index 528a57c..ab43cf1 100644 --- a/bin/varnishd/cache/cache_dir.c +++ b/bin/varnishd/cache/cache_dir.c @@ -61,9 +61,7 @@ VDI_CloseFd(struct vbc **vbp) * before the OS reuses the FD */ VSL_Flush(vc->vsl, 0); - vc->vsl->wid = vc->orig_vsl_id; vc->vsl = NULL; - vc->orig_vsl_id = 0; VTCP_close(&vc->fd); VBE_DropRefConn(bp); @@ -92,9 +90,7 @@ VDI_RecycleFd(struct vbc **vbp) /* XXX: revisit this hack */ VSL_Flush(vc->vsl, 0); - vc->vsl->wid = vc->orig_vsl_id; vc->vsl = NULL; - vc->orig_vsl_id = 0; Lck_Lock(&bp->mtx); VSC_C_main->backend_recycle++; @@ -114,11 +110,8 @@ VDI_GetFd(const struct director *d, struct req *req) d = req->director; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); vc = d->getfd(d, req); - if (vc != NULL) { + if (vc != NULL) vc->vsl = req->busyobj->vsl; - vc->orig_vsl_id = vc->vsl->wid; - vc->vsl->wid = vc->vsl_id; - } return (vc); } diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index daef6a9..e7fee9b 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -59,7 +59,7 @@ ved_include(struct req *preq, const char *src, const char *host) /* Take a workspace snapshot */ wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ - req = SES_GetReq(preq->sp); + req = SES_GetReq(wrk, preq->sp); req->esi_level = preq->esi_level + 1; HTTP_Copy(req->http0, preq->http0); @@ -105,7 +105,7 @@ ved_include(struct req *preq, const char *src, const char *host) i = CNT_Request(wrk, req); if (i == 1) break; - DSL(0x20, SLT_Debug, req->sp->vsl_id, + DSL(0x20, SLT_Debug, req->vsl->wid, "loop waiting for ESI (%d)", i); assert(i == 2); AZ(req->wrk); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index aed84d9..80149c6 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -391,7 +391,6 @@ VGZ_UpdateObj(const struct vgz *vg, struct object *obj) } /*-------------------------------------------------------------------- - * Passing a vsl_id of -1 means "use wrk->vbc->vsl_id" */ int diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index fd0bbe1..0db0d6b 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -449,7 +449,6 @@ HSH_Lookup(struct req *req) AZ(req->busyobj); req->busyobj = VBO_GetBusyObj(wrk); - req->busyobj->vsl->wid = req->sp->vsl_id; req->busyobj->refcount = 2; /* One for req, one for FetchBody */ VRY_Validate(req->vary_b); @@ -485,7 +484,7 @@ hsh_rush(struct dstat *ds, struct objhead *oh) ds->busy_wakeup++; AZ(req->wrk); VTAILQ_REMOVE(&wl->list, req, w_list); - DSL(0x20, SLT_Debug, req->sp->vsl_id, "off waiting list"); + DSL(0x20, SLT_Debug, req->vsl->wid, "off waiting list"); if (SES_ScheduleReq(req)) { /* * We could not schedule the session, leave the diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 3b9ae2e..ad29899 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -852,7 +852,7 @@ http_FilterReq(const struct req *req, unsigned how) else http_linkh(hp, req->http, HTTP_HDR_PROTO); http_filterfields(hp, req->http, how); - http_PrintfHeader(hp, "X-Varnish: %u", req->vxid); + http_PrintfHeader(hp, "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c index d181d11..ab870ad 100644 --- a/bin/varnishd/cache/cache_http1_fsm.c +++ b/bin/varnishd/cache/cache_http1_fsm.c @@ -245,6 +245,13 @@ http1_dissect(struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + /* + * Cache_req_fsm zeros the vxid once a requests is processed. + * Allocate a new one only now that we know will need it. + */ + if (req->vsl->wid == 0) + req->vsl->wid = VXID_Get(&wrk->vxid_pool) | VSL_CLIENTMARKER; + /* Borrow VCL reference from worker thread */ VCL_Refresh(&wrk->vcl); req->vcl = wrk->vcl; @@ -336,7 +343,6 @@ HTTP1_Session(struct worker *wrk, struct req *req) if (done == 2) return; assert(done == 1); - assert(req->vxid == 0); sdr = http1_cleanup(sp, wrk, req); switch (sdr) { case SESS_DONE_RET_GONE: diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index e6b0941..ee7dd78 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -236,8 +236,7 @@ pan_req(const struct req *req) VSB_printf(pan_vsp, "req = %p {\n", req); - VSB_printf(pan_vsp, " sp = %p, vxid = %u,", - req->sp, req->vxid); + VSB_printf(pan_vsp, " sp = %p, vxid = %u,", req->sp, req->vsl->wid); switch (req->req_step) { #define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break; @@ -294,8 +293,8 @@ pan_sess(const struct sess *sp) const char *stp; VSB_printf(pan_vsp, " sp = %p {\n", sp); - VSB_printf(pan_vsp, " fd = %d, id = %u,\n", - sp->fd, sp->vsl_id & VSL_IDENTMASK); + VSB_printf(pan_vsp, " fd = %d, vxid = %u,\n", + sp->fd, sp->vxid & VSL_IDENTMASK); VSB_printf(pan_vsp, " client = %s %s,\n", sp->addr ? sp->addr : "?.?.?.?", sp->port ? sp->port : "?"); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 6e03e4c..e99ed6c 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -270,7 +270,6 @@ cnt_error(struct worker *wrk, struct req *req) bo = VBO_GetBusyObj(wrk); req->busyobj = bo; - bo->vsl->wid = req->sp->vsl_id; AZ(bo->stats); bo->stats = &wrk->stats; req->objcore = HSH_NewObjCore(wrk); @@ -286,7 +285,7 @@ cnt_error(struct worker *wrk, struct req *req) return(1); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); - req->obj->vxid = req->vxid; + req->obj->vxid = bo->vsl->wid; req->obj->exp.entered = req->t_req; h = req->obj->http; @@ -626,7 +625,7 @@ cnt_fetchbody(struct worker *wrk, struct req *req) VSB_delete(vary); } - req->obj->vxid = req->vxid; + req->obj->vxid = bo->vsl->wid; req->obj->response = req->err_code; WS_Assert(req->obj->ws_o); @@ -955,7 +954,6 @@ cnt_pass(struct worker *wrk, struct req *req) req->busyobj = VBO_GetBusyObj(wrk); bo = req->busyobj; - bo->vsl->wid = req->sp->vsl_id; bo->refcount = 2; HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); http_FilterReq(req, HTTPH_R_PASS); @@ -1015,7 +1013,6 @@ cnt_pipe(struct worker *wrk, struct req *req) req->acct_req.pipe++; req->busyobj = VBO_GetBusyObj(wrk); bo = req->busyobj; - bo->vsl->wid = req->sp->vsl_id; HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq); http_FilterReq(req, 0); @@ -1103,8 +1100,7 @@ cnt_recv(const struct worker *wrk, struct req *req) AZ(req->busyobj); /* Assign XID and log */ - VSLb(req->vsl, SLT_ReqStart, "%s %s %u", - req->sp->addr, req->sp->port, req->vxid); + VSLb(req->vsl, SLT_ReqStart, "%s %s", req->sp->addr, req->sp->port); if (req->err_code) { req->req_step = R_STP_ERROR; @@ -1187,8 +1183,8 @@ cnt_diag(struct req *req, const char *state) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - VSLb(req->vsl, SLT_Debug, "vsl_id %u STP_%s sp %p obj %p vcl %p", - req->sp->vsl_id, state, req->sp, req->obj, req->vcl); + VSLb(req->vsl, SLT_Debug, "vxid %u STP_%s sp %p obj %p vcl %p", + req->vsl->wid, state, req->sp, req->obj, req->vcl); VSL_Flush(req->vsl, 0); } @@ -1207,8 +1203,7 @@ CNT_Request(struct worker *wrk, struct req *req) req->req_step == R_STP_LOOKUP || req->req_step == R_STP_RECV); - if (req->req_step == R_STP_RECV) - req->vxid = VXID_Get(&wrk->vxid_pool); + AN(req->vsl->wid & VSL_CLIENTMARKER); req->wrk = wrk; @@ -1243,8 +1238,7 @@ CNT_Request(struct worker *wrk, struct req *req) VSLb(req->vsl, SLT_Length, "%ju", (uintmax_t)req->req_bodybytes); } - VSLb(req->vsl, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f", - req->vxid, + VSLb(req->vsl, SLT_ReqEnd, "%.9f %.9f %.9f %.9f %.9f", req->t_req, req->sp->t_idle, req->sp->t_idle - req->t_resp, @@ -1253,7 +1247,12 @@ CNT_Request(struct worker *wrk, struct req *req) /* done == 2 was charged by cache_hash.c */ SES_Charge(wrk, req); - req->vxid = 0; + + /* + * Nuke the VXID, cache_http1_fsm.c::http1_dissect() will + * allocate a new one when necessary. + */ + req->vsl->wid = 0; } req->wrk = NULL; diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c index 0a554f4..cb152a5 100644 --- a/bin/varnishd/cache/cache_response.c +++ b/bin/varnishd/cache/cache_response.c @@ -134,11 +134,13 @@ RES_BuildHttp(struct req *req) VTIM_format(VTIM_real(), time_str); http_PrintfHeader(req->resp, "Date: %s", time_str); - if (req->vxid != req->obj->vxid) + if (req->wrk->stats.cache_hit) http_PrintfHeader(req->resp, - "X-Varnish: %u %u", req->vxid, req->obj->vxid); + "X-Varnish: %u %u", req->vsl->wid & VSL_IDENTMASK, + req->obj->vxid & VSL_IDENTMASK); else - http_PrintfHeader(req->resp, "X-Varnish: %u", req->vxid); + http_PrintfHeader(req->resp, + "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK); http_PrintfHeader(req->resp, "Age: %.0f", req->obj->exp.age + req->t_resp - req->obj->exp.entered); diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c index 7f5fd35..d0d0d87 100644 --- a/bin/varnishd/cache/cache_rfc2616.c +++ b/bin/varnishd/cache/cache_rfc2616.c @@ -169,8 +169,8 @@ RFC2616_Ttl(struct busyobj *bo) /* calculated TTL, Our time, Date, Expires, max-age, age */ VSLb(bo->vsl, SLT_TTL, - "%u RFC %.0f %.0f %.0f %.0f %.0f %.0f %.0f %u", - bo->vxid, expp->ttl, -1., -1., expp->entered, + "RFC %.0f %.0f %.0f %.0f %.0f %.0f %.0f %u", + expp->ttl, -1., -1., expp->entered, expp->age, h_date, h_expires, max_age); } diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 33c63ba..6cffa69 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -160,7 +160,7 @@ ses_sess_pool_task(struct worker *wrk, void *arg) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC); - req = SES_GetReq(sp); + req = SES_GetReq(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); sp->sess_step = S_STP_NEWREQ; @@ -228,7 +228,7 @@ SES_pool_accept_task(struct worker *wrk, void *arg) sp->t_open = VTIM_real(); sp->t_idle = sp->t_open; - sp->vxid = VXID_Get(&wrk->vxid_pool); + sp->vxid = VXID_Get(&wrk->vxid_pool) | VSL_CLIENTMARKER; lsockname = VCA_SetupSess(wrk, sp); ses_vsl_socket(sp, lsockname); @@ -343,7 +343,7 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) */ struct req * -SES_GetReq(struct sess *sp) +SES_GetReq(struct worker *wrk, struct sess *sp) { struct sesspool *pp; struct req *req; @@ -351,6 +351,7 @@ SES_GetReq(struct sess *sp) unsigned sz, hl; char *p, *e; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); pp = sp->sesspool; CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC); @@ -386,7 +387,7 @@ SES_GetReq(struct sess *sp) sz = cache_param->workspace_thread; VSL_Setup(req->vsl, p, sz); - req->vsl->wid = sp->vsl_id; + req->vsl->wid = VXID_Get(&wrk->vxid_pool) | VSL_CLIENTMARKER; p += sz; p = (void*)PRNDUP(p); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 215e7b6..61000a1 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -422,11 +422,11 @@ VRT_DO_EXP(obj, req->obj->exp, keep, 0, vrt_wsp_exp(req, req->obj->vxid, &req->obj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, grace, 0, - vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vsl->wid & VSL_IDENTMASK, &req->busyobj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, ttl, 0, - vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vsl->wid & VSL_IDENTMASK, &req->busyobj->exp);) VRT_DO_EXP(beresp, req->busyobj->exp, keep, 0, - vrt_wsp_exp(req, req->vxid, &req->busyobj->exp);) + vrt_wsp_exp(req, req->vsl->wid & VSL_IDENTMASK, &req->busyobj->exp);) /*-------------------------------------------------------------------- * req.xid @@ -439,9 +439,9 @@ VRT_r_req_xid(const struct req *req) int size; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - size = snprintf(NULL, 0, "%u", req->vxid) + 1; + size = snprintf(NULL, 0, "%u", req->vsl->wid & VSL_IDENTMASK) + 1; AN(p = WS_Alloc(req->http->ws, size)); - assert(snprintf(p, size, "%u", req->vxid) < size); + assert(snprintf(p, size, "%u", req->vsl->wid & VSL_IDENTMASK) < size); return (p); } diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c index a7403d6..bc5c67f 100644 --- a/bin/varnishd/waiter/cache_waiter_kqueue.c +++ b/bin/varnishd/waiter/cache_waiter_kqueue.c @@ -80,7 +80,7 @@ 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); + DSL(0x04, SLT_Debug, sp->vxid, "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); @@ -121,12 +121,10 @@ vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now) AN(kp->udata); assert(kp->udata != vwk->pipes); 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", + DSL(0x04, SLT_Debug, sp->vxid, "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) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Handle(sp, now); @@ -136,7 +134,7 @@ vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now) SES_Delete(sp, SC_REM_CLOSE, now); return; } else { - VSL(SLT_Debug, sp->vsl_id, + VSL(SLT_Debug, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); diff --git a/bin/varnishtest/tests/b00003.vtc b/bin/varnishtest/tests/b00003.vtc index 177643c..55442b3 100644 --- a/bin/varnishtest/tests/b00003.vtc +++ b/bin/varnishtest/tests/b00003.vtc @@ -18,7 +18,7 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1004 1001" + expect resp.http.X-Varnish == "1004 1002" } -run # Give varnish a chance to update stats diff --git a/bin/varnishtest/tests/b00010.vtc b/bin/varnishtest/tests/b00010.vtc index cfa3266..05b9e91 100644 --- a/bin/varnishtest/tests/b00010.vtc +++ b/bin/varnishtest/tests/b00010.vtc @@ -14,5 +14,5 @@ client c1 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.x-varnish == "1003 1001" + expect resp.http.x-varnish == "1003 1002" } -run diff --git a/bin/varnishtest/tests/b00012.vtc b/bin/varnishtest/tests/b00012.vtc index 302767b..0aa9cec 100644 --- a/bin/varnishtest/tests/b00012.vtc +++ b/bin/varnishtest/tests/b00012.vtc @@ -24,7 +24,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1005 1003" + expect resp.http.x-varnish == "1005 1004" } -run varnish v1 -expect sess_pipeline == 2 diff --git a/bin/varnishtest/tests/b00013.vtc b/bin/varnishtest/tests/b00013.vtc index f0be1d9..d0b957a 100644 --- a/bin/varnishtest/tests/b00013.vtc +++ b/bin/varnishtest/tests/b00013.vtc @@ -26,7 +26,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1005 1003" + expect resp.http.x-varnish == "1005 1004" } -run varnish v1 -expect sess_readahead == 2 diff --git a/bin/varnishtest/tests/b00015.vtc b/bin/varnishtest/tests/b00015.vtc index 2e94add..fc022c3 100644 --- a/bin/varnishtest/tests/b00015.vtc +++ b/bin/varnishtest/tests/b00015.vtc @@ -42,7 +42,7 @@ client c1 { txreq -url "/" rxresp expect resp.status == 302 - expect resp.http.X-varnish == "1012 1009" + expect resp.http.X-varnish == "1012 1010" } -run # Then check that a non-cacheable error from the backend can be @@ -71,5 +71,5 @@ client c1 { txreq -url "/2" rxresp expect resp.status == 502 - expect resp.http.X-varnish == "1017 1014" + expect resp.http.X-varnish == "1017 1015" } -run diff --git a/bin/varnishtest/tests/c00004.vtc b/bin/varnishtest/tests/c00004.vtc index cd79441..3074eb8 100644 --- a/bin/varnishtest/tests/c00004.vtc +++ b/bin/varnishtest/tests/c00004.vtc @@ -44,7 +44,7 @@ client c1 { txreq -hdr "Foobar: 1 " rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1009 1001" + expect resp.http.X-Varnish == "1009 1002" expect resp.http.snafu == "1" } -run diff --git a/bin/varnishtest/tests/c00010.vtc b/bin/varnishtest/tests/c00010.vtc index 1b6a5ec..238dada 100644 --- a/bin/varnishtest/tests/c00010.vtc +++ b/bin/varnishtest/tests/c00010.vtc @@ -25,7 +25,7 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 7 - expect resp.http.x-varnish == "1003" + expect resp.http.x-varnish == "1003 1004" } client c1 -run diff --git a/bin/varnishtest/tests/c00013.vtc b/bin/varnishtest/tests/c00013.vtc index a79244b..7bc36ae 100644 --- a/bin/varnishtest/tests/c00013.vtc +++ b/bin/varnishtest/tests/c00013.vtc @@ -29,7 +29,7 @@ client c2 { rxresp expect resp.status == 200 expect resp.bodylen == 12 - expect resp.http.x-varnish == "1004 1001" + expect resp.http.x-varnish == "1004 1002" } -run client c1 -wait diff --git a/bin/varnishtest/tests/c00015.vtc b/bin/varnishtest/tests/c00015.vtc index 8490bf3..cbf5cca 100644 --- a/bin/varnishtest/tests/c00015.vtc +++ b/bin/varnishtest/tests/c00015.vtc @@ -46,7 +46,7 @@ client c3 { rxresp expect resp.status == 200 expect resp.bodylen == 6 - expect resp.http.x-varnish == "1007 1001" + expect resp.http.x-varnish == "1007 1002" } -run varnish v1 -cli "vcl.show vcl2" diff --git a/bin/varnishtest/tests/c00020.vtc b/bin/varnishtest/tests/c00020.vtc index 8e14f12..3713951 100644 --- a/bin/varnishtest/tests/c00020.vtc +++ b/bin/varnishtest/tests/c00020.vtc @@ -19,7 +19,7 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1004 1001" + expect resp.http.X-Varnish == "1004 1002" } -run server s1 { @@ -39,7 +39,7 @@ client c2 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1008 1001" + expect resp.http.X-Varnish == "1008 1002" txreq -url "/bar" rxresp expect resp.status == 200 @@ -47,7 +47,7 @@ client c2 { txreq -url "/foo" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1011 1006" + expect resp.http.X-Varnish == "1011 1007" } -run varnish v1 -expect sess_conn == 3 diff --git a/bin/varnishtest/tests/c00023.vtc b/bin/varnishtest/tests/c00023.vtc index a29908d..b57c8c1 100644 --- a/bin/varnishtest/tests/c00023.vtc +++ b/bin/varnishtest/tests/c00023.vtc @@ -95,55 +95,55 @@ client c1 { rxresp expect resp.status == 200 expect resp.bodylen == 1 - expect resp.http.X-Varnish == "1020 1001" + expect resp.http.X-Varnish == "1020 1002" txreq -url "/2" rxresp expect resp.bodylen == 2 expect resp.status == 200 - expect resp.http.X-Varnish == "1021 1003" + expect resp.http.X-Varnish == "1021 1004" txreq -url "/3" rxresp expect resp.bodylen == 3 expect resp.status == 200 - expect resp.http.X-Varnish == "1022 1005" + expect resp.http.X-Varnish == "1022 1006" txreq -url "/4" rxresp expect resp.bodylen == 4 expect resp.status == 200 - expect resp.http.X-Varnish == "1023 1007" + expect resp.http.X-Varnish == "1023 1008" txreq -url "/5" rxresp expect resp.bodylen == 5 expect resp.status == 200 - expect resp.http.X-Varnish == "1024 1009" + expect resp.http.X-Varnish == "1024 1010" txreq -url "/6" rxresp expect resp.bodylen == 6 expect resp.status == 200 - expect resp.http.X-Varnish == "1025 1011" + expect resp.http.X-Varnish == "1025 1012" txreq -url "/7" rxresp expect resp.bodylen == 7 expect resp.status == 200 - expect resp.http.X-Varnish == "1026 1013" + expect resp.http.X-Varnish == "1026 1014" txreq -url "/8" rxresp expect resp.bodylen == 8 expect resp.status == 200 - expect resp.http.X-Varnish == "1027 1015" + expect resp.http.X-Varnish == "1027 1016" txreq -url "/9" rxresp expect resp.bodylen == 9 expect resp.status == 200 - expect resp.http.X-Varnish == "1028 1017" + expect resp.http.X-Varnish == "1028 1018" } -run varnish v1 -cliok "hcb.dump" diff --git a/bin/varnishtest/tests/p00000.vtc b/bin/varnishtest/tests/p00000.vtc index 0a17be2..12fa676 100644 --- a/bin/varnishtest/tests/p00000.vtc +++ b/bin/varnishtest/tests/p00000.vtc @@ -29,12 +29,13 @@ varnish v1 -cliok "debug.persistent s0 sync" varnish v1 -stop varnish v1 -start +varnish v1 -cliok "debug.xid 1999" client c1 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1001" + expect resp.http.X-Varnish == "2001 1002" } -run # shell "rm -f /tmp/__v1/_.per" diff --git a/bin/varnishtest/tests/p00001.vtc b/bin/varnishtest/tests/p00001.vtc index 4afccf3..26ea975 100644 --- a/bin/varnishtest/tests/p00001.vtc +++ b/bin/varnishtest/tests/p00001.vtc @@ -32,12 +32,13 @@ varnish v1 -vcl+backend { server s1 -wait varnish v1 -start +varnish v1 -cliok "debug.xid 1999" client c1 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1001" + expect resp.http.X-Varnish == "2001 1002" expect resp.http.foo == "foo" } -run @@ -53,12 +54,13 @@ varnish v1 -vcl+backend { } delay 2 varnish v1 -start +varnish v1 -cliok "debug.xid 2999" client c1 { txreq -url "/" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1001" + expect resp.http.X-Varnish == "3001" expect resp.http.foo == "bar" } -run diff --git a/bin/varnishtest/tests/p00004.vtc b/bin/varnishtest/tests/p00004.vtc index dab8ea4..343d7de 100644 --- a/bin/varnishtest/tests/p00004.vtc +++ b/bin/varnishtest/tests/p00004.vtc @@ -46,7 +46,7 @@ client c1 { txreq -url "/foo" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "2001 1001" + expect resp.http.X-Varnish == "2001 1002" expect resp.http.foo == "foo" } -run @@ -57,7 +57,7 @@ client c1 { txreq -url "/bar" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "2003 1004" + expect resp.http.X-Varnish == "2003 1005" expect resp.http.bar == "bar" } -run diff --git a/bin/varnishtest/tests/p00006.vtc b/bin/varnishtest/tests/p00006.vtc index 3334f36..0adb67b 100644 --- a/bin/varnishtest/tests/p00006.vtc +++ b/bin/varnishtest/tests/p00006.vtc @@ -43,13 +43,13 @@ client c1 { txreq -url "/foo" -hdr "foo: 1" -hdr "bar: 2" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "2001 1001" + expect resp.http.X-Varnish == "2001 1002" expect resp.http.foo == "foo1" txreq -url "/foo" -hdr "foo: 2" -hdr "bar: 1" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "2002 1003" + expect resp.http.X-Varnish == "2002 1004" expect resp.http.foo == "foo2" } -run diff --git a/bin/varnishtest/tests/r00102.vtc b/bin/varnishtest/tests/r00102.vtc index d2a3c13..0fa597b 100644 --- a/bin/varnishtest/tests/r00102.vtc +++ b/bin/varnishtest/tests/r00102.vtc @@ -28,7 +28,7 @@ client c1 { -body "123456789\n" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1003 1001" + expect resp.http.X-Varnish == "1003 1002" } client c1 -run diff --git a/bin/varnishtest/tests/r00262.vtc b/bin/varnishtest/tests/r00262.vtc index 1deb9ea..09ed730 100644 --- a/bin/varnishtest/tests/r00262.vtc +++ b/bin/varnishtest/tests/r00262.vtc @@ -19,7 +19,7 @@ client c1 { send "GET / HTTP/1.1\r\n\r\n" rxresp expect resp.status == 200 - expect resp.http.X-Varnish == "1003 1001" + expect resp.http.X-Varnish == "1003 1002" } client c1 -run diff --git a/bin/varnishtest/tests/s00002.vtc b/bin/varnishtest/tests/s00002.vtc index 31fb400..ab3736e 100644 --- a/bin/varnishtest/tests/s00002.vtc +++ b/bin/varnishtest/tests/s00002.vtc @@ -69,5 +69,5 @@ client c2 { rxresp expect resp.http.foo == "bar" expect resp.status == 200 - expect resp.http.x-varnish == "1004 1001" + expect resp.http.x-varnish == "1004 1002" } -run From martin at varnish-cache.org Wed Aug 15 12:00:45 2012 From: martin at varnish-cache.org (Martin Blix Grydeland) Date: Wed, 15 Aug 2012 14:00:45 +0200 Subject: [3.0] 3993225 Initialize nthr_max on startup to avoid a race between wrk_herder_thread and wrk_herdtimer_thread causing bogus n_wrk_max stat increments. Message-ID: commit 3993225fd998ebdf8e03d18105a7da65c3a83d8a Author: Martin Blix Grydeland Date: Wed Aug 15 13:51:40 2012 +0200 Initialize nthr_max on startup to avoid a race between wrk_herder_thread and wrk_herdtimer_thread causing bogus n_wrk_max stat increments. Fixes: #1183 diff --git a/bin/varnishd/cache_pool.c b/bin/varnishd/cache_pool.c index 14679a5..3c13d69 100644 --- a/bin/varnishd/cache_pool.c +++ b/bin/varnishd/cache_pool.c @@ -593,6 +593,10 @@ WRK_Init(void) Lck_New(&herder_mtx, lck_herder); Lck_New(&wstat_mtx, lck_wstat); + nthr_max = params->wthread_max; + if (nthr_max < params->wthread_min) + nthr_max = params->wthread_min; + wrk_addpools(params->wthread_pools); AZ(pthread_create(&tp, NULL, wrk_herdtimer_thread, NULL)); AZ(pthread_detach(tp)); From martin at varnish-cache.org Thu Aug 16 08:06:18 2012 From: martin at varnish-cache.org (Martin Blix Grydeland) Date: Thu, 16 Aug 2012 10:06:18 +0200 Subject: [master] 5d3dc29 Include compat/srandomdev.h in cache_main.c to fix build on Linux. Message-ID: commit 5d3dc293ecbf1d1944bfb60701543d2f47cb4b1c Author: Martin Blix Grydeland Date: Thu Aug 16 10:05:16 2012 +0200 Include compat/srandomdev.h in cache_main.c to fix build on Linux. diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 37aea3a..8af00f6 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -40,6 +40,10 @@ #include "waiter/waiter.h" #include "hash/hash_slinger.h" +#ifndef HAVE_SRANDOMDEV +#include "compat/srandomdev.h" +#endif + volatile struct params *cache_param; /*-------------------------------------------------------------------- From tfheen at varnish-cache.org Mon Aug 20 08:44:23 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 10:44:23 +0200 Subject: [3.0] 2f1f291 Update version numbers for 3.0.3 Message-ID: commit 2f1f291004b44f9eacda9944d3e2a210e2e742cb Author: Tollef Fog Heen Date: Mon Aug 20 10:13:32 2012 +0200 Update version numbers for 3.0.3 diff --git a/configure.ac b/configure.ac index 67c5c41..9e68374 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.3-rc1], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [3.0.3], [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 bc1cc85..23a2af9 100644 --- a/redhat/varnish.spec +++ b/redhat/varnish.spec @@ -1,8 +1,7 @@ -%define v_rc rc1 Summary: High-performance HTTP accelerator Name: varnish Version: 3.0.3 -Release: 0.rc1%{?dist} +Release: 1%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.varnish-cache.org/ From tfheen at varnish-cache.org Mon Aug 20 08:44:23 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 10:44:23 +0200 Subject: [3.0] 9e6a70f Update params Message-ID: commit 9e6a70f0bc41153b922a2ff2476da7e8d3f9bdef Author: Tollef Fog Heen Date: Mon Aug 20 10:40:46 2012 +0200 Update params diff --git a/doc/sphinx/reference/params.rst b/doc/sphinx/reference/params.rst index 71a938e..4fdd3e6 100644 --- a/doc/sphinx/reference/params.rst +++ b/doc/sphinx/reference/params.rst @@ -127,6 +127,7 @@ diag_bitmap 0x00010000 - synchronize shmlog. 0x00020000 - synchronous start of persistence. 0x00040000 - release VCL early. + 0x00080000 - ban-lurker debugging. 0x80000000 - do edge-detection on digest. Use 0x notation and do the bitor in your head :-) @@ -232,7 +233,6 @@ http_max_hdr http_range_support - Units: bool - Default: on - - Flags: experimental Enable support for HTTP Range headers. @@ -262,6 +262,15 @@ http_resp_size 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. 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. +idle_send_timeout + - Units: seconds + - Default: 60 + - Flags: delayed + + Time to wait with no data sent. If no data has been transmitted in this many + seconds the session is closed. + See setsockopt(2) under SO_SNDTIMEO for more information. + listen_address - Default: :80 - Flags: must_restart @@ -316,6 +325,16 @@ nuke_limit Maximum number of objects we attempt to nuke in orderto make space for a object body. +pcre_match_limit + - Default: 10000 + + The limit for the number of internal matching function calls in a pcre_exec() execution. + +pcre_match_limit_recursion + - Default: 10000 + + The limit for the number of internal matching function recursions in a pcre_exec() execution. + ping_interval - Units: seconds - Default: 3 @@ -362,7 +381,7 @@ saintmode_threshold send_timeout - Units: seconds - - Default: 60 + - Default: 600 - Flags: delayed Send timeout for client connections. If the HTTP response hasn't been transmitted in this many From tfheen at varnish-cache.org Mon Aug 20 12:36:22 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 14:36:22 +0200 Subject: [master] a591999 Update changes for 3.0.2 rc 1 Message-ID: commit a5919990d92a2bd5645a3c8e8e475f8c80c12060 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 cbf4834..87df237 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 Mon Aug 20 12:36:22 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 14:36:22 +0200 Subject: [master] ad169d8 Document 3.0.2 changes Message-ID: commit ad169d84763ac1c5900f58b00cbf3d0516b6aebe 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 87df237..7557393 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 Mon Aug 20 12:36:22 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 14:36:22 +0200 Subject: [master] 043e7dc Duplicate changelog entry Message-ID: commit 043e7dcf13ac6f40c2c55b3dbfdc0bd6dfc2b372 Author: Andreas Plesner Jacobsen Date: Sun Aug 5 23:51:31 2012 +0200 Duplicate changelog entry diff --git a/doc/changes.rst b/doc/changes.rst index e1c6979..27faf07 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -28,8 +28,6 @@ Varnishd - Add CLI commands to manually control health state of a backend. - Fix an issue where the s_bodybytes counter is not updated correctly on gunzipped delivery. -- Fix a race on the n_sess counter that leads to increased session object - allocation. `Bug #897`_. - Fix a crash when we couldn't allocate memory for a fetched object. `Bug #1100`_. - Fix an issue where objects could end up in the transient store with a From tfheen at varnish-cache.org Mon Aug 20 12:36:22 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 14:36:22 +0200 Subject: [master] 7be15ba Changelog for 3.0.3 Message-ID: commit 7be15ba0d899c7a3de0e4459dda41e206588be97 Author: Andreas Plesner Jacobsen Date: Fri Jul 27 14:59:36 2012 +0200 Changelog for 3.0.3 diff --git a/doc/changes.rst b/doc/changes.rst index 7557393..e1c6979 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,3 +1,123 @@ +=========================== +Changes from 3.0.2 to 3.0.3 +=========================== + +Varnishd +-------- + +- Fix an issue where the bodybytes counter is not updated correctly on + gunzipped delivery. +- Fix a race on the n_sess counter. This race made varnish do excessive + session workspace allocations. `Bug #897`_. +- Fix some crashes in the gzip code when it runs out of memory. `Bug #1037`_. + `Bug #1043`_. `Bug #1044`_. +- Fix a bug where the regular expression parser could end up in an infinite + loop. `Bug #1047`_. +- Fix a memory leak in the regex code. +- DNS director now uses port 80 by default if not specified. +- Introduce `idle_send_timeout` and increase default value for `send_timeout` + to 600s. This allows a long send timeout for slow clients while still being + able to disconnect idle clients. +- Fix an issue where did not remove HTML comments. `Bug #1092`_. +- Fix a crash when passing with streaming on. +- Fix a crash in the idle session timeout code. +- Fix an issue where the poll waiter did not timeout clients if all clients + were idle. `Bug #1023`_. +- Log regex errors instead of crashing. +- Introduce `pcre_match_limit`, and `pcre_match_limit_recursion` parameters. +- Add CLI commands to manually control health state of a backend. +- Fix an issue where the s_bodybytes counter is not updated correctly on + gunzipped delivery. +- Fix a race on the n_sess counter that leads to increased session object + allocation. `Bug #897`_. +- Fix a crash when we couldn't allocate memory for a fetched object. + `Bug #1100`_. +- Fix an issue where objects could end up in the transient store with a + long TTL, when memory could not be allocated for them in the requested + store. `Bug #1140`_. +- Activate req.hash_ignore_busy when req.hash_always_miss is activated. + `Bug #1073`_. +- Reject invalid tcp port numbers for listen address. `Bug #1035`_. +- Enable JIT for better performing regular expressions. `Bug #1080`_. +- Return VCL errors in exit code when using -C. `Bug #1069`_. +- Stricter validation of acl syntax, to avoid a crash with 5-octet IPv4 + addresses. `Bug #1126`_. +- Fix a crash when first argument to regsub was null. `Bug #1125`_. +- Fix a case where varnish delivered corrupt gzip content when using ESI. + `Bug #1109`_. +- Fix a case where varnish didn't remove the old Date header and served + it alongside the varnish-generated Date header. `Bug #1104`_. +- Make saint mode work, for the case where we have no object with that hash. + `Bug #1091`_. +- Don't save the object body on hit-for-pass objects. +- n_ban_gone counter added to count the number of "gone" bans. +- Ban lurker rewritten to properly sleep when no bans are present, and + otherwise to process the list at the configured speed. +- Fix a case where varnish delivered wrong content for an uncompressed page + with compressed ESI child. `Bug #1029`_. +- Fix an issue where varnish runs out of thread workspace when processing + many ESI includes on an object. `Bug #1038`_. +- Fix a crash when streaming was enabled for an empty body. +- Better error reporting for some fetch errors. +- Small performance optimizations. + +.. _bug #897: http://varnish-cache.org/trac/ticket/897 +.. _bug #1023: http://varnish-cache.org/trac/ticket/1023 +.. _bug #1029: http://varnish-cache.org/trac/ticket/1029 +.. _bug #1023: http://varnish-cache.org/trac/ticket/1023 +.. _bug #1035: http://varnish-cache.org/trac/ticket/1035 +.. _bug #1037: http://varnish-cache.org/trac/ticket/1037 +.. _bug #1038: http://varnish-cache.org/trac/ticket/1038 +.. _bug #1043: http://varnish-cache.org/trac/ticket/1043 +.. _bug #1044: http://varnish-cache.org/trac/ticket/1044 +.. _bug #1047: http://varnish-cache.org/trac/ticket/1047 +.. _bug #1069: http://varnish-cache.org/trac/ticket/1069 +.. _bug #1073: http://varnish-cache.org/trac/ticket/1073 +.. _bug #1080: http://varnish-cache.org/trac/ticket/1080 +.. _bug #1091: http://varnish-cache.org/trac/ticket/1091 +.. _bug #1092: http://varnish-cache.org/trac/ticket/1092 +.. _bug #1100: http://varnish-cache.org/trac/ticket/1100 +.. _bug #1104: http://varnish-cache.org/trac/ticket/1104 +.. _bug #1109: http://varnish-cache.org/trac/ticket/1109 +.. _bug #1125: http://varnish-cache.org/trac/ticket/1125 +.. _bug #1126: http://varnish-cache.org/trac/ticket/1126 +.. _bug #1140: http://varnish-cache.org/trac/ticket/1140 + +varnishncsa +----------- + +- Support for \t\n in varnishncsa format strings. +- Add new format: %{VCL_Log:foo}x which output key:value from std.log() in + VCL. +- Add user-defined date formatting, using %{format}t. + +varnishtest +----------- + +- resp.body is now available for inspection. +- Make it possible to test for the absence of an HTTP header. `Bug #1062`_. +- Log the full panic message instead of shortening it to 512 characters. + +.. _bug #1062: http://varnish-cache.org/trac/ticket/1062 + +varnishstat +----------- + +- Add json output (-j). + +Other +----- + +- Documentation updates. +- Bump minimum number of threads to 50 in RPM packages. +- RPM packaging updates. +- Fix some compilation warnings on Solaris. +- Fix some build issues on Open/Net/DragonFly-BSD. +- Fix build on FreeBSD 10-current. +- Fix libedit detection on \*BSD OSes. `Bug #1003`_. + +.. _bug #1003: http://varnish-cache.org/trac/ticket/1003 + ================================ Changes from 3.0.2 rc 1 to 3.0.2 ================================ @@ -60,10 +180,11 @@ Varnishd .. _bug #994: http://varnish-cache.org/trac/ticket/994 .. _bug #992: http://varnish-cache.org/trac/ticket/992 +.. _bug #996: http://varnish-cache.org/trac/ticket/996 .. _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 +.. _bug #1016: http://varnish-cache.org/trac/ticket/1016 VCL --- From tfheen at varnish-cache.org Mon Aug 20 12:36:22 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Mon, 20 Aug 2012 14:36:22 +0200 Subject: [master] 33f5bae Another duplicate changelog entry, thanks fgs Message-ID: commit 33f5bae99a64fc7b04fffe70eb2965346aadc3a7 Author: Andreas Plesner Jacobsen Date: Wed Aug 8 09:34:29 2012 +0200 Another duplicate changelog entry, thanks fgs diff --git a/doc/changes.rst b/doc/changes.rst index 27faf07..87a7648 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -5,8 +5,6 @@ Changes from 3.0.2 to 3.0.3 Varnishd -------- -- Fix an issue where the bodybytes counter is not updated correctly on - gunzipped delivery. - Fix a race on the n_sess counter. This race made varnish do excessive session workspace allocations. `Bug #897`_. - Fix some crashes in the gzip code when it runs out of memory. `Bug #1037`_. From phk at varnish-cache.org Tue Aug 21 08:20:39 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 21 Aug 2012 10:20:39 +0200 Subject: [master] 7c784d5 Add long time missing error handling of gunzip'ing fetched objects for ESI processing. Message-ID: commit 7c784d5c9d2dd959a5ea1a1bea5f7bbb4173437d Author: Poul-Henning Kamp Date: Tue Aug 21 08:19:44 2012 +0000 Add long time missing error handling of gunzip'ing fetched objects for ESI processing. Polish the VGZ code a bit while here anyway. Fixes #1184 diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 2441bd6..43c104e 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -803,6 +803,13 @@ void Fetch_Init(void); /* cache_gzip.c */ struct vgz; +enum vgzret_e { + VGZ_ERROR = -1, + VGZ_OK = 0, + VGZ_END = 1, + VGZ_STUCK = 2, +}; + enum vgz_flag { VGZ_NORMAL, VGZ_ALIGN, VGZ_RESET, VGZ_FINISH }; struct vgz *VGZ_NewUngzip(struct vsl_log *vsl, const char *id); struct vgz *VGZ_NewGzip(struct vsl_log *vsl, const char *id); @@ -811,22 +818,16 @@ 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(struct busyobj *, 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); -int VGZ_Destroy(struct vgz **); +enum vgzret_e VGZ_Gzip(struct vgz *, const void **, size_t *len, enum vgz_flag); +enum vgzret_e VGZ_Gunzip(struct vgz *, const void **, size_t *len); +enum vgzret_e VGZ_Destroy(struct vgz **); void VGZ_UpdateObj(const struct vgz*, struct object *); int VGZ_WrwInit(struct vgz *vg); -int VGZ_WrwGunzip(struct req *, struct vgz *, const void *ibuf, +enum vgzret_e VGZ_WrwGunzip(struct req *, struct vgz *, const void *ibuf, ssize_t ibufl); void VGZ_WrwFlush(struct req *, struct vgz *vg); -/* Return values */ -#define VGZ_ERROR -1 -#define VGZ_OK 0 -#define VGZ_END 1 -#define VGZ_STUCK 2 - /* cache_http.c */ unsigned HTTP_estimate(unsigned nhttp); void HTTP_Copy(struct http *to, const struct http * const fm); diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index c9cc689..7dc74ae 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -119,7 +119,7 @@ vfp_esi_bytes_gu(struct busyobj *bo, const struct vef_priv *vef, { struct vgz *vg; ssize_t wl; - int i; + enum vgzret_e vr; size_t dl; const void *dp; @@ -137,10 +137,13 @@ vfp_esi_bytes_gu(struct busyobj *bo, const struct vef_priv *vef, } if (VGZ_ObufStorage(bo, vg)) return(-1); - i = VGZ_Gunzip(vg, &dp, &dl); - xxxassert(i == VGZ_OK || i == VGZ_END); - VEP_Parse(bo, dp, dl); - VFP_update_length(bo, dl); + vr = VGZ_Gunzip(vg, &dp, &dl); + if (vr < VGZ_OK) + return (-1); + if (dl > 0) { + VEP_Parse(bo, dp, dl); + VFP_update_length(bo, dl); + } } return (1); } @@ -265,7 +268,7 @@ vfp_esi_bytes_gg(const struct busyobj *bo, struct vef_priv *vef, ssize_t wl; size_t dl; const void *dp; - int i; + enum vgzret_e vr; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); @@ -280,9 +283,9 @@ vfp_esi_bytes_gg(const struct busyobj *bo, struct vef_priv *vef, do { wl = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf); VGZ_Obuf(bo->vgz_rx, vef->ibuf_i, wl); - i = VGZ_Gunzip(bo->vgz_rx, &dp, &dl); - /* XXX: check i */ - assert(i >= VGZ_OK); + vr = VGZ_Gunzip(bo->vgz_rx, &dp, &dl); + if (vr < VGZ_OK) + return (-1); if (dl > 0 && vfp_vep_inject(bo, vef, dl)) return (-1); } while (!VGZ_IbufEmpty(bo->vgz_rx)); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 80149c6..5a53cd8 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -218,7 +218,7 @@ VGZ_ObufStorage(struct busyobj *bo, struct vgz *vg) /*--------------------------------------------------------------------*/ -int +enum vgzret_e VGZ_Gunzip(struct vgz *vg, const void **pptr, size_t *plen) { int i; @@ -247,13 +247,13 @@ VGZ_Gunzip(struct vgz *vg, const void **pptr, size_t *plen) return (VGZ_END); if (i == Z_BUF_ERROR) return (VGZ_STUCK); - VSL(SLT_Debug, 0, "Unknown INFLATE=%d (%s)\n", i, vg->vz.msg); + VSLb(vg->vsl, SLT_Gzip, "Gunzip error: %d (%s)", i, vg->vz.msg); return (VGZ_ERROR); } /*--------------------------------------------------------------------*/ -int +enum vgzret_e VGZ_Gzip(struct vgz *vg, const void **pptr, size_t *plen, enum vgz_flag flags) { int i; @@ -285,12 +285,13 @@ VGZ_Gzip(struct vgz *vg, const void **pptr, size_t *plen, enum vgz_flag flags) } vg->last_i = i; if (i == Z_OK) - return (0); + return (VGZ_OK); if (i == Z_STREAM_END) - return (1); + return (VGZ_END); if (i == Z_BUF_ERROR) - return (2); - return (-1); + return (VGZ_STUCK); + VSLb(vg->vsl, SLT_Gzip, "Gzip error: %d (%s)", i, vg->vz.msg); + return (VGZ_ERROR); } /*-------------------------------------------------------------------- @@ -314,11 +315,11 @@ VGZ_WrwInit(struct vgz *vg) * Leave flushing to caller, more data may be coming. */ -int +enum vgzret_e VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf, ssize_t ibufl) { - int i; + enum vgzret_e vr; size_t dl; const void *dp; struct worker *wrk; @@ -333,16 +334,14 @@ VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf, return (VGZ_OK); do { if (vg->m_len == vg->m_sz) - i = VGZ_STUCK; + vr = VGZ_STUCK; else { - i = VGZ_Gunzip(vg, &dp, &dl); + vr = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; } - if (i < VGZ_OK) { - /* XXX: VSL ? */ - return (-1); - } - if (vg->m_len == vg->m_sz || i == VGZ_STUCK) { + if (vr < VGZ_OK) + return (vr); + if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) { req->acct_req.bodybytes += vg->m_len; (void)WRW_Write(wrk, vg->m_buf, vg->m_len); (void)WRW_Flush(wrk); @@ -350,9 +349,9 @@ VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf, VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); - if (i == VGZ_STUCK) - i = VGZ_OK; - return (i); + if (vr == VGZ_STUCK) + vr = VGZ_OK; + return (vr); } /*--------------------------------------------------------------------*/ @@ -393,10 +392,11 @@ VGZ_UpdateObj(const struct vgz *vg, struct object *obj) /*-------------------------------------------------------------------- */ -int +enum vgzret_e VGZ_Destroy(struct vgz **vgp) { struct vgz *vg; + enum vgzret_e vr; int i; vg = *vgp; @@ -420,14 +420,18 @@ VGZ_Destroy(struct vgz **vgp) i = Z_STREAM_END; if (vg->m_buf) free(vg->m_buf); - 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); + vr = VGZ_OK; + else if (i == Z_STREAM_END) + vr = VGZ_END; + else if (i == Z_BUF_ERROR) + vr = VGZ_STUCK; + else { + VSLb(vg->vsl, SLT_Gzip, "G(un)zip error: %d (%s)", i, vg->vz.msg); + vr = VGZ_ERROR; + } + FREE_OBJ(vg); + return (vr); } /*-------------------------------------------------------------------- diff --git a/bin/varnishtest/tests/r01184.vtc b/bin/varnishtest/tests/r01184.vtc new file mode 100644 index 0000000..9a74f28 --- /dev/null +++ b/bin/varnishtest/tests/r01184.vtc @@ -0,0 +1,126 @@ +varnishtest "Corrupt gzip'ed ESI objects" + +# First, check that our data is actually good + +server s1 { + rxreq + expect req.url == "/" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " 8a 9c d1 92 77 48 d4 0a 72 ea 06 5f b3 1c fa dd" + sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" + sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" + sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" + sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" + sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" + sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" + sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" + sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" + send "\r\n" + chunkedlen 0 + rxreq + expect req.url == "/incl" + txresp -body "INCLUDED\n" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.bodylen == 315 +} -run + +# Second, corrupt them, while using the g-g path + +server s1 { + rxreq + expect req.url == "/c" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" + sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" + sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" + sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" + sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" + sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" + sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" + sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" + sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" + send "\r\n" + chunkedlen 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + } +} + +client c1 { + txreq -url "/c" + rxresp + expect resp.status == 503 +} -run + +# Third, corrupt them, while using the g-u path + +server s1 { + rxreq + expect req.url == "/d" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" + sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" + sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" + sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" + sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" + sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" + sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" + sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" + sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" + send "\r\n" + chunkedlen 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + set beresp.do_gunzip = true; + } +} + +client c1 { + txreq -url "/d" + rxresp + expect resp.status == 503 +} -run From perbu at varnish-cache.org Tue Aug 21 08:31:26 2012 From: perbu at varnish-cache.org (Per Buer) Date: Tue, 21 Aug 2012 10:31:26 +0200 Subject: [master] a3eb213 Remove the FAQ from sphinx. It was never properly maintained. Message-ID: commit a3eb21309ffd22e3143f779ad18e8f8ac6562d18 Author: Per Buer Date: Tue Aug 21 10:28:52 2012 +0200 Remove the FAQ from sphinx. It was never properly maintained. diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index d2e5258..987c069 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -91,11 +91,6 @@ doctest: EXTRA_DIST = \ conf.py \ index.rst \ - faq/configuration.rst \ - faq/general.rst \ - faq/http.rst \ - faq/index.rst \ - faq/logging.rst \ glossary/index.rst \ installation/bugs.rst \ installation/help.rst \ diff --git a/doc/sphinx/faq/configuration.rst b/doc/sphinx/faq/configuration.rst deleted file mode 100644 index df06b07..0000000 --- a/doc/sphinx/faq/configuration.rst +++ /dev/null @@ -1,53 +0,0 @@ -%%%%%%%%%%%%%%% -Configuration -%%%%%%%%%%%%%%% - -.. _faq-vcl: - -VCL -=== - -**What is VCL?** - -VCL is an acronym for Varnish Configuration Language. In a VCL file, you configure how Varnish should behave. Sample VCL files will be included in this Wiki at a later stage. - -**Where is the documentation on VCL?** - -Please see ``man 7 vcl``. There are also some real-world examples on -the `wiki `_ - - -**How do I load VCL file while Varnish is running?** - -* Place the VCL file on the server -* Telnet into the managment port. -* do a "vcl.load " in managment interface. is whatever you would like to call your new configuration. -* do a "vcl.use " to start using your new config. - -**Should I use ''pipe'' or ''pass'' in my VCL code? What is the difference?** - -When varnish does a ``pass`` it acts like a normal HTTP proxy. It -reads the request and pushes it onto the backend. The next HTTP -request can then be handled like any other. - -``pipe`` is only used when Varnish for some reason can't handle the -``pass``. ``pipe`` reads the request, pushes in onty the backend -_only_ pushes bytes back and forth, with no other actions taken. - -Since most HTTP clients do pipeline several requests into one -connection this might give you an undesirable result - as every -subsequent request will reuse the existing ``pipe``. Please see `this -article ` for -more details and a workaround. - -Varnish versions prior to 2.0 does not support handling a request body -with ``pass`` mode, so in those releases ``pipe`` is required for -correct handling. - -In 2.0 and later, ``pass`` will handle the request body correctly. - -If you get 503 errors when making a request which is ``pass`` ed, make sure -that you're specifying the backend before returning from vcl_recv with ``pass``. - - - diff --git a/doc/sphinx/faq/general.rst b/doc/sphinx/faq/general.rst deleted file mode 100644 index b0c7e13..0000000 --- a/doc/sphinx/faq/general.rst +++ /dev/null @@ -1,238 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -General questions -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -What is Varnish? -================ - -Please see ref:`tutorial-intro`. - -How... -====== - -**How much RAM/Disk do I need for Varnish?** - -That depends on pretty much everything. - -I think our best current guidance is that you go for a cost-effective -RAM configuration, something like 1-16GB, and an SSD. - -Unless you positively know that you will need it, there is -little point in spending a fortune on a hand-sewn motherboard -that can fit several TB in special RAM blocks, riveted together -by leftover watch-makers in Switzerland. - -On the other hand, if you plot your traffic in Gb/s, you probably -need all the RAM you can afford/get. - -**How can I limit Varnish to use less RAM?** - -You can not. Varnish operates in Virtual Memory and it is up to the -kernel to decide which process gets to use how much RAM to map the -virtual address-space of the process. - -**How do I instruct varnish to ignore the query parameters and only cache one instance of an object?** - -This can be achieved by removing the query parameters using a regexp:: - - sub vcl_recv { - set req.url = regsub(req.url, "\?.*", ""); - } - -**How can I force a refresh on a object cached by varnish?** - -Refreshing is often called `purging -`_ a document. You can -purge at least 2 different ways in Varnish: - -1. Command line - - From the command line you can write:: - - ban.url ^/$ - - to ban your / document. As you might see ban.url takes an `regular expression `_ - as its argument. Hence the ``^`` and ``$`` at the front and end. If the ``^`` is omitted, all the documents ending in a ``/`` in the cache would be deleted. - - So to delete all the documents in the cache, write:: - - ban.url . - - at the command line. - -2. HTTP PURGE - - VCL code to allow HTTP PURGE is to be found `here `_. Note that this method does not support wildcard purging. - -**How can I debug the requests of a single client?** - -The "varnishlog" utility may produce a horrendous amount of output. To be able debug our own traffic can be useful. - -The ReqStart token will include the client IP address. To see log entries matching this, type:: - - $ varnishlog -c -m ReqStart:192.0.2.123 - -To see the backend requests generated by a client IP address, we can match on the TxHeader token, since the IP address of the client is included in the X-Forwarded-For header in the request sent to the backend. - -At the shell command line, type:: - - $ varnishlog -b -m TxHeader:192.0.2.123 - -**How can I rewrite URLS before they are sent to the backend?** - -You can use the ``regsub()`` function to do this. Here's an example for zope, to rewrite URLs for the virtualhostmonster:: - - if (req.http.host ~ "^(www.)?example.com") { - set req.url = regsub(req.url, "^", "/VirtualHostBase/http/example.com:80/Sites/example.com/VirtualHostRoot"); - } - -**I have a site with many host names, how do I keep them from multiplying the cache?** - -You can do this by normalizing the ``Host`` header for all your host names. Here's a VCL example:: - - if (req.http.host ~ "^(www.)?example.com") { - set req.http.host = "example.com"; - } - -**How do I do to alter the request going to the backend?** -You can use the ``bereq`` object for altering requests going to the backend, but you can only 'set' values to it. Therefore use req.url to build the request:: - - sub vcl_miss { - set bereq.url = regsub(req.url,"stream/","/"); - return(fetch); - } - -**How can I customize the error messages that Varnish returns?** - -A custom error page can be generated by adding a ``vcl_error`` to your configuration file. The default error page looks like this:: - - sub vcl_error { - set obj.http.Content-Type = "text/html; charset=utf-8"; - - synthetic {" - - - - - "} + obj.status + " " + obj.response + {" - - -

Error "} + obj.status + " " + obj.response + {"

-

"} + obj.response + {"

-

Guru Meditation:

-

XID: "} + req.xid + {"

-
Varnish
- - - "}; - return(deliver); - } - -**How do I instruct varnish to ignore the query parameters and only cache one instance of an object?** - -This can be achieved by removing the query parameters using a regexp:: - - sub vcl_recv { - set req.url = regsub(req.url, "\?.*", ""); - } - - -Can I... -======== - -**Can I run Varnish on the same system as Apache?** - -Yes, and many people do that with good success. - -There will be competition for resources, but Apache is not particular -good at using RAM effectively and Varnish is, so this synergy usually -more than compensates for the competition. - -**Can I run multiple Varnish on the same system?** - -Yes, as long as you give them different TCP ports and different ``-n`` -arguments, you will be fine. - - -**Can I cache multiple virtual hosts with one Varnish?** - -Yes, that works right out of the box. - -**Can I see what is cached in Varnish?** - -That is not possible for several reasons. A command to list -all the contents of a Varnish cache with millions of objects would -bring your Varnish to a standstill while it traverses the index. - -Besides, the output is a lot less useful than you might think. - -**Can I use Varnish to do HTTPS?** - -Not at present, and while we keep an eye on this, there are no -current plans to add HTTPS support, until we can find a way where -it adds significant value, relative to running a stand-alone -HTTPS proxy such as nginx or pound. - -**Can Varnish load balance between multiple backends?** - -Yes, you need VCL code like this:: - - director foobar round-robin { - { .backend = { .host = "www1.example.com"; .port = "http"; } } - { .backend = { .host = "www2.example.com"; .port = "http"; } } - } - - sub vcl_recv { - set req.backend = foobar; - } - -Please see :ref:`tutorial-advanced_backend_servers-directors`. - - -Why ... -======= - -**Why does it look like Varnish sends all requests to the backend? I thought it was a cache?** - - -Please see :ref:`tutorial-increasing_your_hitrate`. - -**Why does Varnish require the system to have a C compiler?** - -The :ref:`VCL ` compiler generates C source as output (your -config file), and uses the systems C-compiler to compile that into a -shared library. If there is no C compiler, Varnish will not work. - -**Isn't that security problem?** - -The days when you could prevent people from running non-approved -programs by removing the C compiler from your system ended roughly -with the VAX 11/780 computer. - -Troubleshooting -=============== - -**Why am I getting a cache hit, but a request is still going to my backend?** - -Varnish has a feature called **hit for pass**, which is used when Varnish gets a response from the backend and finds out it cannot be cached. In such cases, Varnish will create a cache object that records that fact, so that the next request goes directly to "pass". - - Since Varnish bundles multiple requests for the same URL to the backend, a common case where a client will get a **hit for pass** is: - * Client 1 requests url /foo - * Client 2..N request url /foo - * Varnish tasks a worker to fetch /foo for Client 1 - * Client 2..N are now queued pending response from the worker - * Worker returns object to varnish which turns out to be non-cacheable. - * Client 2..N are now given the **hit for pass** object instructing them to go to the backend - -The **hit for pass** object will stay cached for the duration of its ttl. This means that subsequent clients requesting /foo will be sent straight to the backend as long as the **hit for pass** object exists. -The :command:`varnishstat` can tell you how many **hit for pass** objects varnish has served. The default vcl will set ttl for a hit_for_pass object to 120s. But you can override this, using the following logic:: - - sub vcl_fetch { - if (!obj.cacheable) { - # Limit the lifetime of all 'hit for pass' objects to 10 seconds - obj.ttl = 10s; - return(hit_for_pass); - } - } - diff --git a/doc/sphinx/faq/http.rst b/doc/sphinx/faq/http.rst deleted file mode 100644 index 1e276ba..0000000 --- a/doc/sphinx/faq/http.rst +++ /dev/null @@ -1,55 +0,0 @@ -%%%%%%%%%%% -HTTP -%%%%%%%%%%% - -**What is the purpose of the X-Varnish HTTP header?** - -The X-Varnish HTTP header allows you to find the correct log-entries for the transaction. For a cache hit, X-Varnish will contain both the ID of the current request and the ID of the request that populated the cache. It makes debugging Varnish a lot easier. - -**Does Varnish support compression?** - -This is a simple question with a complicated answer; see `WIKI `_. - -**How do I add a HTTP header?** - -To add a HTTP header, unless you want to add something about the client/request, it is best done in vcl_fetch as this means it will only be processed every time the object is fetched:: - - sub vcl_fetch { - # Add a unique header containing the cache servers IP address: - remove beresp.http.X-Varnish-IP; - set beresp.http.X-Varnish-IP = server.ip; - # Another header: - set beresp.http.Foo = "bar"; - } - -**How can I log the client IP address on the backend?** - -All I see is the IP address of the varnish server. How can I log the client IP address? - -We will need to add the IP address to a header used for the backend request, and configure the backend to log the content of this header instead of the address of the connecting client (which is the varnish server). - -Varnish configuration:: - - sub vcl_recv { - # Add a unique header containing the client address - remove req.http.X-Forwarded-For; - set req.http.X-Forwarded-For = client.ip; - # [...] - } - -For the apache configuration, we copy the "combined" log format to a new one we call "varnishcombined", for instance, and change the client IP field to use the content of the variable we set in the varnish configuration:: - - LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnishcombined - -And so, in our virtualhost, you need to specify this format instead of "combined" (or "common", or whatever else you use):: - - - ServerName www.example.com - # [...] - CustomLog /var/log/apache2/www.example.com/access.log varnishcombined - # [...] - - -The [http://www.openinfo.co.uk/apache/index.html mod_extract_forwarded Apache module] might also be useful. - - diff --git a/doc/sphinx/faq/index.rst b/doc/sphinx/faq/index.rst deleted file mode 100644 index a8136a8..0000000 --- a/doc/sphinx/faq/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. _faq: - -%%%%%%%%%%%%%%%%%%%%%%%%%% -Frequently asked questions -%%%%%%%%%%%%%%%%%%%%%%%%%% - -The most frequently asked questions about Varnish in different contexts. - - -.. toctree:: - - general.rst - http.rst - configuration.rst - logging.rst - -.. todo:: - [V] - Now that the FAQ has been all reStructureized, we need to qualitycheck the content, update old info, and delete unrelevant info. - - diff --git a/doc/sphinx/faq/logging.rst b/doc/sphinx/faq/logging.rst deleted file mode 100644 index 89fdbde..0000000 --- a/doc/sphinx/faq/logging.rst +++ /dev/null @@ -1,8 +0,0 @@ -%%%%%%%%%%%%%%%%%%% -Logging -%%%%%%%%%%%%%%%%%%% - -**Where can I find the log files?** - -Varnish does not log to a file, but to shared memory log. Use the varnishlog utility to print the shared memory log or varnishncsa to present it in the Apache / NCSA "combined" log format. - diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 2558413..06eb52a 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -21,7 +21,6 @@ Contents: installation/index.rst tutorial/index.rst reference/index.rst - faq/index.rst phk/index.rst glossary/index.rst From perbu at varnish-cache.org Tue Aug 21 08:31:26 2012 From: perbu at varnish-cache.org (Per Buer) Date: Tue, 21 Aug 2012 10:31:26 +0200 Subject: [master] 77d35ab remove warning (invalid comment Message-ID: commit 77d35ab8812311b871956f53bf27fb26b6cf5e93 Author: Per Buer Date: Tue Aug 21 10:30:26 2012 +0200 remove warning (invalid comment diff --git a/doc/sphinx/glossary/index.rst b/doc/sphinx/glossary/index.rst index 7a2787d..3da5af3 100644 --- a/doc/sphinx/glossary/index.rst +++ b/doc/sphinx/glossary/index.rst @@ -7,8 +7,7 @@ Varnish Glossary .. glossary:: :sorted: - .. comment: - + .. This file will be sorted automagically during formatting, so we keep the source in subject order to make sure we cover all bases. From phk at varnish-cache.org Tue Aug 21 09:03:35 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 21 Aug 2012 11:03:35 +0200 Subject: [master] f656558 Try to make osx build happier. Message-ID: commit f656558cc4d0350cd9f8340960d88c90f0e2783e Author: Poul-Henning Kamp Date: Tue Aug 21 09:01:36 2012 +0000 Try to make osx build happier. And yes, why ptrdiff_t even exists and why it can be different, semantically or otherwise, from ssize_t is beyond me... diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c index 76ef874..6404a3e 100644 --- a/lib/libvcl/vcc_backend.c +++ b/lib/libvcl/vcc_backend.c @@ -708,8 +708,8 @@ vcc_ParseDirector(struct vcc *tl) ERRCHK(tl); if (tl->t->e - tl->t->b > 64) { VSB_printf(tl->sb, - "Name of %.*s too long (max 64, is %zd):\n", - PF(t_first), (tl->t->e - tl->t->b)); + "Name of %.*s too long (max 64, is %zu):\n", + PF(t_first), (size_t)(tl->t->e - tl->t->b)); vcc_ErrWhere(tl, tl->t); return; } From tfheen at varnish-cache.org Tue Aug 21 09:47:07 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Tue, 21 Aug 2012 11:47:07 +0200 Subject: [master] 7bced23 Quiet build by default Message-ID: commit 7bced23aecd08a94c953835b16c63ea0f5264652 Author: Tollef Fog Heen Date: Tue Aug 21 11:44:13 2012 +0200 Quiet build by default diff --git a/configure.ac b/configure.ac index e1311f0..13c38d1 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,8 @@ OCFLAGS="$CFLAGS" AC_CANONICAL_SYSTEM AC_LANG(C) -AM_INIT_AUTOMAKE([foreign color-tests parallel-tests]) +AM_INIT_AUTOMAKE([1.11 foreign color-tests parallel-tests]) +AM_SILENT_RULES([yes]) AC_DISABLE_STATIC AC_PROG_LIBTOOL From perbu at varnish-cache.org Wed Aug 22 07:13:57 2012 From: perbu at varnish-cache.org (Per Buer) Date: Wed, 22 Aug 2012 09:13:57 +0200 Subject: [master] 652cdeb Showcase !~ in the regex example Message-ID: commit 652cdeb92ff3bd68d2485ae2f07f585dc75da1a4 Author: Per Buer Date: Wed Aug 22 09:13:36 2012 +0200 Showcase !~ in the regex example diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 736c7c0..eee9c0b 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -404,7 +404,8 @@ insensitivity* add the flag within parens following a question mark, like this: :: - if (req.http.host ~ "(?i)example.com$") { + # If host is NOT example dot com.. + if (req.http.host !~ "(?i)example.com$") { ... } From phk at varnish-cache.org Wed Aug 22 09:07:41 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 11:07:41 +0200 Subject: [master] 07d9e57 Pass -g to nm(1), it makes backtraces on OSX marginally less useless Message-ID: commit 07d9e57d2a2afaab66daf040c9b06699882b1021 Author: Poul-Henning Kamp Date: Wed Aug 22 08:59:47 2012 +0000 Pass -g to nm(1), it makes backtraces on OSX marginally less useless diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 7b42437..a760b40 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -246,7 +246,7 @@ Symbol_hack(const char *a0) uintptr_t a; struct symbols *s; - bprintf(buf, "nm -an %s 2>/dev/null", a0); + bprintf(buf, "nm -agn %s 2>/dev/null", a0); fi = popen(buf, "r"); if (fi == NULL) return; From phk at varnish-cache.org Wed Aug 22 09:07:41 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 11:07:41 +0200 Subject: [master] 83387b8 Initialize pthreads stuff before we use it. Message-ID: commit 83387b8ba36c9793370e99b79688c9cc9cae0ef7 Author: Poul-Henning Kamp Date: Wed Aug 22 09:07:09 2012 +0000 Initialize pthreads stuff before we use it. Spotted by: OSX pthread implementation diff --git a/bin/varnishd/cache/cache_pool.c b/bin/varnishd/cache/cache_pool.c index 21a8a31..336c76a 100644 --- a/bin/varnishd/cache/cache_pool.c +++ b/bin/varnishd/cache/cache_pool.c @@ -418,6 +418,8 @@ pool_mkpool(unsigned pool_no) VTAILQ_INIT(&pp->back_queue); pp->sesspool = SES_NewPool(pp, pool_no); AN(pp->sesspool); + AZ(pthread_cond_init(&pp->herder_cond, NULL)); + AZ(pthread_create(&pp->herder_thr, NULL, pool_herder, pp)); VTAILQ_FOREACH(ls, &heritage.socks, list) { if (ls->sock < 0) @@ -430,9 +432,6 @@ pool_mkpool(unsigned pool_no) AZ(Pool_Task(pp, &ps->task, POOL_QUEUE_BACK)); } - AZ(pthread_cond_init(&pp->herder_cond, NULL)); - AZ(pthread_create(&pp->herder_thr, NULL, pool_herder, pp)); - return (pp); } From phk at varnish-cache.org Wed Aug 22 09:31:38 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 11:31:38 +0200 Subject: [master] 86619ad A couple of cleanups to get OSX to be more happy. Message-ID: commit 86619addc250bede7f6be2f635fe0cf1deb067ea Author: Poul-Henning Kamp Date: Wed Aug 22 09:31:21 2012 +0000 A couple of cleanups to get OSX to be more happy. diff --git a/bin/varnishd/storage/storage_persistent.h b/bin/varnishd/storage/storage_persistent.h index a755b89..c817faf 100644 --- a/bin/varnishd/storage/storage_persistent.h +++ b/bin/varnishd/storage/storage_persistent.h @@ -34,7 +34,7 @@ */ #define ASSERT_SILO_THREAD(sc) \ - do {assert(pthread_self() == (sc)->thread);} while (0) + do {assert(pthread_equal(pthread_self(), (sc)->thread));} while (0) #define OC_F_NEEDFIXUP OC_F_PRIV diff --git a/bin/varnishtest/tests/r01035.vtc b/bin/varnishtest/tests/r01035.vtc index ccd6078..4bcb735 100644 --- a/bin/varnishtest/tests/r01035.vtc +++ b/bin/varnishtest/tests/r01035.vtc @@ -1,6 +1,6 @@ varnishtest "Test case for #1035" -varnish v1 -arg "-a 127.0.0.1:80 -b localhost:8080" +varnish v1 -arg "-a 127.0.0.1:80 -b 127.0.0.1:8080" varnish v1 -cliok "param.set listen_address 127.0.0.1:80" varnish v1 -clierr 106 "param.set listen_address 127.0.0.1:65540" varnish v1 -clierr 106 "param.set listen_address 127.0.0.1:65536" From phk at varnish-cache.org Wed Aug 22 10:02:06 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 12:02:06 +0200 Subject: [master] 4711b4b Fix a race condition, the child thread could get to the first assert before the parent carried out the assignment of the thread id to the variable. Message-ID: commit 4711b4b3187b7088c841aedaf56797997ffef6fe Author: Poul-Henning Kamp Date: Wed Aug 22 10:01:19 2012 +0000 Fix a race condition, the child thread could get to the first assert before the parent carried out the assignment of the thread id to the variable. Detected by: OSX diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index 6118fbf..b4e8c8c 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -275,6 +275,7 @@ smp_thread(struct worker *wrk, void *priv) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sc, priv, SMP_SC_MAGIC); + sc->thread = pthread_self(); /* First, load all the objects from all segments */ VTAILQ_FOREACH(sg, &sc->segments, list) @@ -305,6 +306,7 @@ static void smp_open(const struct stevedore *st) { struct smp_sc *sc; + pthread_t pt; ASSERT_CLI(); @@ -346,7 +348,7 @@ smp_open(const struct stevedore *st) smp_new_seg(sc); /* Start the worker silo worker thread, it will load the objects */ - WRK_BgThread(&sc->thread, "persistence", smp_thread, sc); + WRK_BgThread(&pt, "persistence", smp_thread, sc); VTAILQ_INSERT_TAIL(&silos, sc, list); Lck_Unlock(&sc->mtx); From daghf at varnish-cache.org Wed Aug 22 11:32:28 2012 From: daghf at varnish-cache.org (Dag Haavi Finstad) Date: Wed, 22 Aug 2012 13:32:28 +0200 Subject: [3.0] e837c4b Fix for missing error handling of gunzip'ing fetched objects for ESI processing. Adapted from phk's fix for #1184. Message-ID: commit e837c4bcd26218489576af899f563c66e6b0511f Author: Dag Haavi Finstad Date: Wed Aug 22 13:07:59 2012 +0200 Fix for missing error handling of gunzip'ing fetched objects for ESI processing. Adapted from phk's fix for #1184. diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c index ab86ac8..b870aa7 100644 --- a/bin/varnishd/cache_esi_fetch.c +++ b/bin/varnishd/cache_esi_fetch.c @@ -117,9 +117,12 @@ vfp_esi_bytes_gu(struct sess *sp, struct http_conn *htc, ssize_t bytes) if (VGZ_ObufStorage(sp, vg)) return(-1); i = VGZ_Gunzip(vg, &dp, &dl); - xxxassert(i == VGZ_OK || i == VGZ_END); - VEP_parse(sp, dp, dl); - sp->obj->len += dl; + if (i < VGZ_OK) + return (-1); + if (dl > 0) { + VEP_parse(sp, dp, dl); + sp->obj->len += dl; + } } return (1); } @@ -270,8 +273,8 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) do { VGZ_Obuf(sp->wrk->vgz_rx, ibuf2, sizeof ibuf2); i = VGZ_Gunzip(sp->wrk->vgz_rx, &dp, &dl); - /* XXX: check i */ - assert(i >= VGZ_OK); + if (i < VGZ_OK) + return (-1); vef->bufp = ibuf2; if (dl > 0) VEP_parse(sp, ibuf2, dl); diff --git a/bin/varnishtest/tests/r01184.vtc b/bin/varnishtest/tests/r01184.vtc new file mode 100644 index 0000000..30dc177 --- /dev/null +++ b/bin/varnishtest/tests/r01184.vtc @@ -0,0 +1,130 @@ +varnishtest "Corrupt gzip'ed ESI objects" + +# First, check that our data is actually good + +server s1 { + rxreq + expect req.url == "/" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " 8a 9c d1 92 77 48 d4 0a 72 ea 06 5f b3 1c fa dd" + sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" + sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" + sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" + sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" + sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" + sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" + sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" + sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" + send "\r\n" + chunkedlen 0 + rxreq + expect req.url == "/incl" + txresp -body "INCLUDED\n" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.bodylen == 315 +} -run + +# Second, corrupt them, while using the g-g path + +server s1 { + rxreq + expect req.url == "/c" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" + expect_close + +# sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" +# sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" +# sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" +# sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" +# sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" +# sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" +# sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" +# sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" +# send "\r\n" +# chunkedlen 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + } +} + +client c1 { + txreq -url "/c" + rxresp + expect resp.status == 503 +} -run + +# Third, corrupt them, while using the g-u path + +server s1 { + rxreq + expect req.url == "/d" + txresp -nolen \ + -hdr "Content-Encoding: gzip" \ + -hdr "Transfer-Encoding: Chunked" + send "ed\r\n" + sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" + sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" + sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" + sendhex " 25 89 a7 f7 3e b4 be 6f d7 8f db 76 59 e8 28 d8" + sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" + sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" + sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" + expect_close + +# sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" +# sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" +# sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" +# sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" +# sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" +# sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" +# sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" +# sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" +# send "\r\n" +# chunkedlen 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set beresp.do_esi = true; + set beresp.do_gunzip = true; + } +} + +client c1 { + txreq -url "/d" + rxresp + expect resp.status == 503 +} -run From phk at varnish-cache.org Wed Aug 22 12:08:32 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 14:08:32 +0200 Subject: [master] bbdf093 Use expect_close after we munged the gzip stream, varnishd isn't going to like it... Message-ID: commit bbdf093f2a637cc7ef83ad4336849c363cebe501 Author: Poul-Henning Kamp Date: Wed Aug 22 12:07:55 2012 +0000 Use expect_close after we munged the gzip stream, varnishd isn't going to like it... Patch by: daghf diff --git a/bin/varnishtest/tests/r01184.vtc b/bin/varnishtest/tests/r01184.vtc index 9a74f28..3977eb1 100644 --- a/bin/varnishtest/tests/r01184.vtc +++ b/bin/varnishtest/tests/r01184.vtc @@ -60,16 +60,7 @@ server s1 { sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" - sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" - sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" - sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" - sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" - sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" - sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" - sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" - sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" - send "\r\n" - chunkedlen 0 + expect_close } -start varnish v1 -vcl+backend { @@ -100,16 +91,7 @@ server s1 { sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" - sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" - sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" - sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" - sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" - sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" - sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" - sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" - sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" - send "\r\n" - chunkedlen 0 + expect_close } -start varnish v1 -vcl+backend { From phk at varnish-cache.org Wed Aug 22 13:31:27 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2012 15:31:27 +0200 Subject: [master] 4f9c5b9 Trim chunk headers to force the bogus data into varnishd's processing Message-ID: commit 4f9c5b93d61d82dc48f71c9d7373c4d8eb5cc53b Author: Poul-Henning Kamp Date: Wed Aug 22 13:30:56 2012 +0000 Trim chunk headers to force the bogus data into varnishd's processing diff --git a/bin/varnishtest/tests/r01184.vtc b/bin/varnishtest/tests/r01184.vtc index 3977eb1..046b371 100644 --- a/bin/varnishtest/tests/r01184.vtc +++ b/bin/varnishtest/tests/r01184.vtc @@ -52,7 +52,7 @@ server s1 { txresp -nolen \ -hdr "Content-Encoding: gzip" \ -hdr "Transfer-Encoding: Chunked" - send "ed\r\n" + send "70\r\n" sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" @@ -83,7 +83,7 @@ server s1 { txresp -nolen \ -hdr "Content-Encoding: gzip" \ -hdr "Transfer-Encoding: Chunked" - send "ed\r\n" + send "70\r\n" sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" From daghf at varnish-cache.org Wed Aug 22 13:34:51 2012 From: daghf at varnish-cache.org (Dag Haavi Finstad) Date: Wed, 22 Aug 2012 15:34:51 +0200 Subject: [3.0] 31645c9 Fix for wrong chunked header in #1184 test case Message-ID: commit 31645c92f8b64575b04dc96f166552c77d463fcb Author: Dag Haavi Finstad Date: Wed Aug 22 15:34:45 2012 +0200 Fix for wrong chunked header in #1184 test case diff --git a/bin/varnishtest/tests/r01184.vtc b/bin/varnishtest/tests/r01184.vtc index 30dc177..d6a6ee7 100644 --- a/bin/varnishtest/tests/r01184.vtc +++ b/bin/varnishtest/tests/r01184.vtc @@ -52,7 +52,7 @@ server s1 { txresp -nolen \ -hdr "Content-Encoding: gzip" \ -hdr "Transfer-Encoding: Chunked" - send "ed\r\n" + send "70\r\n" sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" @@ -60,18 +60,7 @@ server s1 { sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" - expect_close - -# sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" -# sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" -# sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" -# sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" -# sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" -# sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" -# sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" -# sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" -# send "\r\n" -# chunkedlen 0 + expect_close } -start varnish v1 -vcl+backend { @@ -94,7 +83,7 @@ server s1 { txresp -nolen \ -hdr "Content-Encoding: gzip" \ -hdr "Transfer-Encoding: Chunked" - send "ed\r\n" + send "70\r\n" sendhex " 1f 8b 08 00 c2 39 33 50 02 03 45 90 4d 6a 03 31" sendhex " 0c 85 f7 73 8a 47 2e 10 d9 f2 9f ca 34 d0 c2 64" sendhex " 5b 08 bd 80 2d cb 10 28 5d 34 f4 fe f5 30 d0 68" @@ -102,18 +91,7 @@ server s1 { sendhex " 10 45 f3 a9 83 b8 18 1c 7b c2 30 55 04 17 13 c4" sendhex " 0f 07 5f 7a 38 f4 8e 50 b3 37 d4 3a 32 4a 34 07" sendhex " FF FF FF FF FF FF FF FF 72 ea 06 5f b3 1c fa dd" - expect_close - -# sendhex " 2b b9 88 20 99 e6 9a 3c 84 7c 85 8e 50 e0 59 2a" -# sendhex " 42 b0 8a 34 0f 96 d5 1e f7 97 fb b7 7e fd 4e 87" -# sendhex " c7 8f be 9e ce fb 74 3a 3f 51 89 a3 9b 7e b2 43" -# sendhex " a4 86 a2 55 90 b9 29 4c 4b 83 b8 99 5f b5 bb 27" -# sendhex " 6a d4 86 18 22 83 8a 26 f4 11 1a 5c eb 34 3b ca" -# sendhex " 20 31 9e 12 29 ff a8 92 78 a2 e6 ec 61 55 12 fc" -# sendhex " 68 84 6c 12 41 b9 cf 2f 30 3b f0 10 5e d6 b7 eb" -# sendhex " e7 76 bb 2c 7f 8c 90 4a 14 4c 01 00 00" -# send "\r\n" -# chunkedlen 0 + expect_close } -start varnish v1 -vcl+backend { From perbu at varnish-cache.org Thu Aug 23 08:19:54 2012 From: perbu at varnish-cache.org (Per Buer) Date: Thu, 23 Aug 2012 10:19:54 +0200 Subject: [master] 7ad9ae5 Fix the CLI ref documentation (including a bug in the built in docs). Message-ID: commit 7ad9ae5cf540534f629b2c2eb14bf5eaabdb388b Author: Per Buer Date: Thu Aug 23 10:19:01 2012 +0200 Fix the CLI ref documentation (including a bug in the built in docs). diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c index 45b85d0..3f15ada 100644 --- a/bin/varnishd/cache/cache_backend_cfg.c +++ b/bin/varnishd/cache/cache_backend_cfg.c @@ -489,7 +489,7 @@ static struct cli_proto backend_cmds[] = { { "backend.list", "backend.list", "\tList all backends\n", 0, 1, "", cli_backend_list }, { "backend.set_health", "backend.set_health matcher state", - "\tShow a backend\n", 2, 2, "", cli_backend_set_health }, + "\tSet health status on a backend\n", 2, 2, "", cli_backend_set_health }, { NULL } }; diff --git a/doc/sphinx/reference/varnish-cli.rst b/doc/sphinx/reference/varnish-cli.rst index ad9cc9c..033be5a 100644 --- a/doc/sphinx/reference/varnish-cli.rst +++ b/doc/sphinx/reference/varnish-cli.rst @@ -76,108 +76,121 @@ be entered with the \\xnn syntax. Commands -------- -help [command] - Display a list of available commands. +.. glossary:: + :sorted: + help [command] + Display a list of available commands. If the command is specified, display help for this command. -param.set param value + param.set param value Set the parameter specified by param to the specified value. See Run-Time Parameters for a list of parame? ters. -param.show [-l] [param] + param.show [-l] [param] Display a list if run-time parameters and their values. - + If the -l option is specified, the list includes a brief explanation of each parameter. - + If a param is specified, display only the value and explanation for this parameter. -ping [timestamp] + ping [timestamp] Ping the Varnish cache process, keeping the connection alive. -ban *field operator argument* [&& field operator argument [...]] + ban *field operator argument* [&& field operator argument [...]] Immediately invalidate all documents matching the ban expression. See *Ban Expressions* for more documentation and examples. -ban.list + ban.list All requests for objects from the cache are matched against items on the ban list. If an object in the cache is older than a matching ban list item, it is considered "banned", and will be fetched from the backend instead. - + When a ban expression is older than all the objects in the cache, it is removed from the list. - + ban.list displays the ban list. The output looks something like this (broken into two lines): - + 0x7fea4fcb0580 1303835108.618863 131G req.http.host ~ www.myhost.com && req.url ~ /some/url - + The first field is the address of the ban. - + The second is the time of entry into the list, given as a high precision timestamp. - + The third field describes many objects point to this ban. When an object is compared to a ban the object is marked with a reference to the newest ban it was tested against. This isn't really useful unless you're debugging. - + A "G" marks that the ban is "Gone". Meaning it has been marked as a duplicate or it is no longer valid. It stays in the list for effiency reasons. - + Then follows the actual ban it self. -ban.url regexp + ban.url regexp Immediately invalidate all documents whose URL matches the specified regular expression. Please note that the Host part of the URL is ignored, so if you have several virtual hosts all of them will be banned. Use *ban* to specify a complete ban if you need to narrow it down. -quit + quit Close the connection to the varnish admin port. -start + start Start the Varnish cache process if it is not already running. -status + status Check the status of the Varnish cache process. -stop + stop Stop the Varnish cache process. -vcl.discard configname + vcl.discard configname Discard the configuration specified by configname. This will have no effect if the specified configuration has a non-zero reference count. -vcl.inline configname vcl + vcl.inline configname vcl Create a new configuration named configname with the VCL code specified by vcl, which must be a quoted string. -vcl.list + vcl.list List available configurations and their respective reference counts. The active configuration is indicated with an asterisk ("*"). -vcl.load configname filename + vcl.load configname filename Create a new configuration named configname with the contents of the specified file. -vcl.show configname + vcl.show configname Display the source code for the specified configuration. -vcl.use configname + vcl.use configname Start using the configuration specified by configname for all new requests. Existing requests will con? tinue using whichever configuration was in use when they arrived. + storage.list + Lists the defined storage backends. + + backend.list + Lists the defined backends including health state. + + backend.set_health matcher state + Sets the health state on a specific backend. This is useful if + you want to take a certain backend out of sirculations. + + Ban Expressions --------------- From tfheen at varnish-cache.org Thu Aug 23 09:40:56 2012 From: tfheen at varnish-cache.org (Tollef Fog Heen) Date: Thu, 23 Aug 2012 11:40:56 +0200 Subject: [master] e60db5b Pass -Wc, -fstack-protector to the libtool ld stage, to make the stack protector work on omnios Message-ID: commit e60db5be39c24347edb54de6df4130c4ee1f4c38 Author: Tollef Fog Heen Date: Thu Aug 23 11:40:33 2012 +0200 Pass -Wc,-fstack-protector to the libtool ld stage, to make the stack protector work on omnios diff --git a/configure.ac b/configure.ac index 13c38d1..e831b31 100644 --- a/configure.ac +++ b/configure.ac @@ -480,12 +480,16 @@ AC_ARG_ENABLE(stack-protector, if test "x$enable_stack_protector" != "xno"; then save_CFLAGS="$CFLAGS" CFLAGS="${CFLAGS} -fstack-protector-all" + save_AM_LT_LDFLAGS="$AM_LT_LDFLAGS" + AM_LT_LDFLAGS="${AM_LT_LDFLAGS} -Wc,-fstack-protector" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([],[],[])], [], [AC_MSG_WARN([-fstack-protector not supported, disabling]) - CFLAGS="$save_CFLAGS"]) + CFLAGS="$save_CFLAGS"] + AM_LT_LDFLAGS="$save_AM_LT_LDFLAGS") fi +AC_SUBST(AM_LT_LDFLAGS) # --enable-tests AC_ARG_ENABLE(tests, diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am index ab2cc94..740ae16 100644 --- a/lib/libvarnish/Makefile.am +++ b/lib/libvarnish/Makefile.am @@ -1,8 +1,10 @@ INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@ +AM_LDFLAGS = $(AM_LT_LDFLAGS) + pkglib_LTLIBRARIES = libvarnish.la -libvarnish_la_LDFLAGS = -avoid-version +libvarnish_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version libvarnish_la_SOURCES = \ vav.c \ diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am index 492b10d..ee86abc 100644 --- a/lib/libvarnishapi/Makefile.am +++ b/lib/libvarnishapi/Makefile.am @@ -1,10 +1,12 @@ # +AM_LDFLAGS = $(AM_LT_LDFLAGS) + INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@ lib_LTLIBRARIES = libvarnishapi.la -libvarnishapi_la_LDFLAGS = -version-info 1:0:0 +libvarnishapi_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 libvarnishapi_la_SOURCES = \ vsm_api.h \ diff --git a/lib/libvarnishcompat/Makefile.am b/lib/libvarnishcompat/Makefile.am index 22c652e..33aac4a 100644 --- a/lib/libvarnishcompat/Makefile.am +++ b/lib/libvarnishcompat/Makefile.am @@ -1,10 +1,11 @@ # INCLUDES = -I$(top_srcdir)/include +AM_LDFLAGS = $(AM_LT_LDFLAGS) pkglib_LTLIBRARIES = libvarnishcompat.la -libvarnishcompat_la_LDFLAGS = -avoid-version +libvarnishcompat_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version libvarnishcompat_la_SOURCES = \ daemon.c \ diff --git a/lib/libvcl/Makefile.am b/lib/libvcl/Makefile.am index 02a685f..f07facd 100644 --- a/lib/libvcl/Makefile.am +++ b/lib/libvcl/Makefile.am @@ -1,10 +1,12 @@ # +AM_LDFLAGS = $(AM_LT_LDFLAGS) + INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include pkglib_LTLIBRARIES = libvcl.la -libvcl_la_LDFLAGS = -avoid-version +libvcl_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version libvcl_la_SOURCES = \ vcc_compile.h \ diff --git a/lib/libvgz/Makefile.am b/lib/libvgz/Makefile.am index c04242c..7497aab 100644 --- a/lib/libvgz/Makefile.am +++ b/lib/libvgz/Makefile.am @@ -1,8 +1,9 @@ # +AM_LDFLAGS = $(AM_LT_LDFLAGS) pkglib_LTLIBRARIES = libvgz.la -libvgz_la_LDFLAGS = -avoid-version +libvgz_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version libvgz_la_CFLAGS = -D_LARGEFILE64_SOURCE=1 $(libvgz_extra_cflags) libvgz_la_SOURCES = \ diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am index 23a6d53..1705cf9 100644 --- a/lib/libvmod_debug/Makefile.am +++ b/lib/libvmod_debug/Makefile.am @@ -1,4 +1,5 @@ # +AM_LDFLAGS = $(AM_LT_LDFLAGS) INCLUDES = \ -I$(top_srcdir)/include \ @@ -10,7 +11,7 @@ vmod_srcdir = $(top_srcdir)/lib/libvmod_debug vmodtool = $(top_srcdir)/lib/libvcl/vmodtool.py noinst_LTLIBRARIES = libvmod_debug.la -libvmod_debug_la_LDFLAGS = -module -export-dynamic -avoid-version -rpath /nowhere +libvmod_debug_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version -rpath /nowhere libvmod_debug_la_SOURCES = \ vcc_if.c \ diff --git a/lib/libvmod_std/Makefile.am b/lib/libvmod_std/Makefile.am index a872837..0a4736a 100644 --- a/lib/libvmod_std/Makefile.am +++ b/lib/libvmod_std/Makefile.am @@ -1,5 +1,7 @@ # +AM_LDFLAGS = $(AM_LT_LDFLAGS) + INCLUDES = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/bin/varnishd \ @@ -12,7 +14,7 @@ vmod_srcdir = $(top_srcdir)/lib/libvmod_std vmodtool = $(top_srcdir)/lib/libvcl/vmodtool.py vmod_LTLIBRARIES = libvmod_std.la -libvmod_std_la_LDFLAGS = -module -export-dynamic -avoid-version +libvmod_std_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version libvmod_std_la_SOURCES = \ vcc_if.c \ From perbu at varnish-cache.org Mon Aug 27 08:47:55 2012 From: perbu at varnish-cache.org (Per Buer) Date: Mon, 27 Aug 2012 10:47:55 +0200 Subject: [master] 1ecffcd remove indent warning Message-ID: commit 1ecffcdc5d91c000faf5ae6e4c9bf38d2b27847c Author: Per Buer Date: Mon Aug 27 10:47:43 2012 +0200 remove indent warning diff --git a/doc/sphinx/reference/varnish-cli.rst b/doc/sphinx/reference/varnish-cli.rst index 033be5a..a4ec1b9 100644 --- a/doc/sphinx/reference/varnish-cli.rst +++ b/doc/sphinx/reference/varnish-cli.rst @@ -77,12 +77,12 @@ Commands -------- .. glossary:: - :sorted: + :sorted: help [command] Display a list of available commands. If the command is specified, display help for this command. - + param.set param value Set the parameter specified by param to the specified value. See Run-Time Parameters for a list of parame? ters. From perbu at varnish-cache.org Mon Aug 27 08:47:55 2012 From: perbu at varnish-cache.org (Per Buer) Date: Mon, 27 Aug 2012 10:47:55 +0200 Subject: [master] 9d052cb Clarify storage backend usage Some more text describing the behaviour on the various storage backend + some reformatting for readability Message-ID: commit 9d052cb74759aa89d4358fe58632b4c0307137dc Author: Per Buer Date: Mon Aug 27 10:41:19 2012 +0200 Clarify storage backend usage Some more text describing the behaviour on the various storage backend + some reformatting for readability diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index 17e6c03..e6857a8 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -156,10 +156,16 @@ Storage Types The following storage types are available: malloc[,size] - Storage for each object is allocated with malloc(3). - The size parameter specifies the maximum amount of memory varnishd will allocate. The size is assumed to - be in bytes, unless followed by one of the following suffixes: + Malloc is a memory based backend. Each object will be allocated + from memory. If your system runs low on memory swap will be + used. Be aware that the size limitation only limits the actual + storage and that approximately 1k of memory per object will be + used for various internal structures. + + The size parameter specifies the maximum amount of memory + varnishd will allocate. The size is assumed to be in bytes, + unless followed by one of the following suffixes: K, k The size is expressed in kibibytes. @@ -169,16 +175,24 @@ malloc[,size] T, t The size is expressed in tebibytes. - The default size is unlimited. + The default size is unlimited. + + Mallocs performance is bound by memory speed so it is very fast. file[,path[,size[,granularity]]] - Storage for each object is allocated from an arena backed by a file. This is the default. - The path parameter specifies either the path to the backing file or the path to a directory in which - varnishd will create the backing file. The default is /tmp. + The file backend stores objects in memory backed by a file on + disk with mmap. This is the default storage backend and unless + you specify another storage this one will used along with + Transient storage. - The size parameter specifies the size of the backing file. The size is assumed to be in bytes, unless fol? - lowed by one of the following suffixes: + The path parameter specifies either the path to the backing file + or the path to a directory in which varnishd will create the + backing file. The default is /tmp. + + The size parameter specifies the size of the backing file. The + size is assumed to be in bytes, unless fol? lowed by one of the + following suffixes: K, k The size is expressed in kibibytes. @@ -188,21 +202,29 @@ file[,path[,size[,granularity]]] T, t The size is expressed in tebibytes. - % The size is expressed as a percentage of the free space on the file system where it resides. + % The size is expressed as a percentage of the free space on the + file system where it resides. The default size is 50%. - If the backing file already exists, it will be truncated or expanded to the specified size. + If the backing file already exists, it will be truncated or + expanded to the specified size. + + Note that if varnishd has to create or expand the file, it will + not pre-allocate the added space, leading to fragmentation, + which may adversely impact performance. Pre-creating the + storage file using dd(1) will reduce fragmentation to a minimum. - Note that if varnishd has to create or expand the file, it will not pre-allocate the added space, leading - to fragmentation, which may adversely impact performance. Pre-creating the storage file using dd(1) will - reduce fragmentation to a minimum. + The granularity parameter specifies the granularity of + allocation. All allocations are rounded up to this size. The + size is assumed to be in bytes, unless followed by one of the + suffixes described for size except for %. - The granularity parameter specifies the granularity of allocation. All allocations are rounded up to this - size. The size is assumed to be in bytes, unless followed by one of the suffixes described for size except - for %. + The default size is the VM page size. The size should be + reduced if you have many small objects. - The default size is the VM page size. The size should be reduced if you have many small objects. + File performance is typically limited by the write speed of the + device, and depending on use, the seek time. persistent,path,size {experimental} @@ -241,38 +263,47 @@ Transient Storage Management Interface -------------------- -If the -T option was specified, varnishd will offer a command-line management interface on the specified address -and port. The recommended way of connecting to the command-line management interface is through varnishadm(1). +If the -T option was specified, varnishd will offer a command-line +management interface on the specified address and port. The +recommended way of connecting to the command-line management interface +is through varnishadm(1). The commands available are documented in varnish(7). Run-Time Parameters ------------------- -Runtime parameters are marked with shorthand flags to avoid repeating the same text over and over in the table -below. The meaning of the flags are: +Runtime parameters are marked with shorthand flags to avoid repeating +the same text over and over in the table below. The meaning of the +flags are: experimental - We have no solid information about good/bad/optimal values for this parameter. Feedback with experience - and observations are most welcome. + We have no solid information about good/bad/optimal values for + this parameter. Feedback with experience and observations are + most welcome. delayed - This parameter can be changed on the fly, but will not take effect immediately. + This parameter can be changed on the fly, but will not take + effect immediately. restart - The worker process must be stopped and restarted, before this parameter takes effect. + The worker process must be stopped and restarted, before this + parameter takes effect. reload The VCL programs must be reloaded for this parameter to take effect. -Here is a list of all parameters, current as of last time we remembered to update the manual page. This text is -produced from the same text you will find in the CLI if you use the param.show command, so should there be a new -parameter which is not listed here, you can find the description using the CLI commands. +Here is a list of all parameters, current as of last time we +remembered to update the manual page. This text is produced from the +same text you will find in the CLI if you use the param.show command, +so should there be a new parameter which is not listed here, you can +find the description using the CLI commands. Be aware that on 32 bit systems, certain default values, such as -workspace_client (=16k), thread_pool_workspace (=16k), http_resp_size (=8k), -http_req_size (=12k), gzip_stack_buffer (=4k) and thread_pool_stack (=64k) are -reduced relative to the values listed here, in order to conserve VM space. +workspace_client (=16k), thread_pool_workspace (=16k), http_resp_size +(=8k), http_req_size (=12k), gzip_stack_buffer (=4k) and +thread_pool_stack (=64k) are reduced relative to the values listed +here, in order to conserve VM space. .. include:: params.rst From phk at varnish-cache.org Mon Aug 27 10:33:07 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 12:33:07 +0200 Subject: [master] 71a1806 Add a "vsl_mask" parameter, that allows individual SLT tags to be suppressed so the never take up space/bandwidth in the VSL. Message-ID: commit 71a18061e026ecde6b319e798b1e61cf887f0829 Author: Poul-Henning Kamp Date: Mon Aug 27 10:30:46 2012 +0000 Add a "vsl_mask" parameter, that allows individual SLT tags to be suppressed so the never take up space/bandwidth in the VSL. Reimplement vcl_trace using this: param.set vsl_mask +VCL_trace param.set vsl_mask -VCL_trace XXX: doc-update needed diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 967d3bb..78f253c 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -61,6 +61,7 @@ varnishd_SOURCES = \ mgt/mgt_cli.c \ mgt/mgt_main.c \ mgt/mgt_param.c \ + mgt/mgt_param_vsl.c \ mgt/mgt_pool.c \ mgt/mgt_sandbox.c \ mgt/mgt_sandbox_solaris.c \ diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index f5cc879..167c25e 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -50,6 +50,18 @@ static uint32_t *vsl_ptr; struct VSC_C_main *VSC_C_main; +static inline int +vsl_tag_is_masked(enum VSL_tag_e tag) +{ + volatile uint8_t *bm = &cache_param->vsl_mask[0]; + uint8_t b; + + assert(tag < SLT_Reserved); + bm += ((unsigned)tag >> 3); + b = (0x80 >> ((unsigned)tag & 7)); + return (*bm & b); +} + static inline uint32_t vsl_w0(uint32_t type, uint32_t length) { @@ -159,6 +171,8 @@ VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...) unsigned n, mlen = cache_param->shm_reclen; char buf[mlen]; + if (vsl_tag_is_masked(tag)) + return; AN(fmt); va_start(ap, fmt); @@ -281,6 +295,8 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) va_list ap; AN(fmt); + if (vsl_tag_is_masked(tag)) + return; va_start(ap, fmt); wsl(vsl, tag, vsl->wid, fmt, ap); va_end(ap); @@ -293,6 +309,9 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) void VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t) { + + if (vsl_tag_is_masked(tag)) + return; wslr(vsl, tag, -1, t); } diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 8cc2920..477d337 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -75,9 +75,8 @@ VRT_count(struct req *req, unsigned u) if (req == NULL) return; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - if (cache_param->vcl_trace) - VSLb(req->vsl, SLT_VCL_trace, "%u %u.%u", u, - req->vcl->ref[u].line, req->vcl->ref[u].pos); + VSLb(req->vsl, SLT_VCL_trace, "%u %u.%u", u, + req->vcl->ref[u].line, req->vcl->ref[u].pos); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index a66bcf8..79de607 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -103,10 +103,6 @@ struct params { ssize_t fetch_maxchunksize; unsigned nuke_limit; - - /* VCL traces */ - unsigned vcl_trace; - unsigned accept_filter; /* Listen address */ @@ -204,4 +200,6 @@ struct params { struct poolparam req_pool; struct poolparam sess_pool; struct poolparam vbo_pool; + + uint8_t vsl_mask[256/8]; }; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 2f090dc..026207c 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -872,14 +872,6 @@ static const struct parspec input_parspec[] = { "fragmentation.\n", EXPERIMENTAL, "256m", "bytes" }, - { "vcl_trace", tweak_bool, &mgt_param.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" }, { "accept_filter", tweak_bool, &mgt_param.accept_filter, 0, 0, "Enable kernel accept-filters, if supported by the kernel.", MUST_RESTART, @@ -1318,7 +1310,7 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) continue; } pp->func(cli, pp, NULL); - if (pp->units != NULL) + if (pp->units != NULL && *pp->units != '\0') VCLI_Out(cli, " [%s]\n", pp->units); else VCLI_Out(cli, "\n"); @@ -1496,6 +1488,7 @@ MCF_ParamInit(struct cli *cli) MCF_AddParams(input_parspec); MCF_AddParams(WRK_parspec); + MCF_AddParams(VSL_parspec); /* XXX: We do this twice, to get past any interdependencies */ MCF_SetDefaults(NULL); diff --git a/bin/varnishd/mgt/mgt_param.h b/bin/varnishd/mgt/mgt_param.h index ee1ad52..d25411d 100644 --- a/bin/varnishd/mgt/mgt_param.h +++ b/bin/varnishd/mgt/mgt_param.h @@ -57,5 +57,8 @@ void tweak_timeout_double(struct cli *cli, const struct parspec *par, const char *arg); void tweak_bytes(struct cli *cli, const struct parspec *par, const char *arg); +/* mgt_param_vsl.c */ +extern const struct parspec VSL_parspec[]; + /* mgt_pool.c */ extern const struct parspec WRK_parspec[]; diff --git a/bin/varnishd/mgt/mgt_param_vsl.c b/bin/varnishd/mgt/mgt_param_vsl.c new file mode 100644 index 0000000..6338d49 --- /dev/null +++ b/bin/varnishd/mgt/mgt_param_vsl.c @@ -0,0 +1,137 @@ +/*- + * 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 "common/params.h" +#include "mgt/mgt.h" +#include "mgt/mgt_param.h" + +#include "vav.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" + +#include "vapi/vsl_int.h" + +static const char * const VSL_tags[256] = { +# define SLTM(foo,sdesc,ldesc) [SLT_##foo] = #foo, +# include "tbl/vsl_tags.h" +# undef SLTM +}; + +enum bit_do {BSET, BCLR, BTST}; + +static int +vsl_bit(unsigned no, enum bit_do act) +{ + volatile uint8_t *bm = &mgt_param.vsl_mask[0]; + uint8_t b; + + assert(no < (unsigned)SLT_Reserved); + + bm += (no >> 3); + b = (0x80 >> (no & 7)); + if (act == BSET) + *bm |= b; + else if (act == BCLR) + *bm &= ~b; + return (*bm & b); +} + +static void +tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) +{ + int i, n; + unsigned j; + const char *s; + char **av; + (void)par; + + if (arg != NULL) { + if (!strcmp(arg, "default")) { + (void)vsl_bit(SLT_VCL_trace, BSET); + (void)vsl_bit(SLT_WorkThread, BSET); + } else if (*arg != 0) { + av = VAV_Parse(arg, &n, ARGV_COMMA); + if (av[0] != NULL) { + VCLI_Out(cli, "Cannot parse: %s\n", av[0]); + VCLI_SetResult(cli, CLIS_PARAM); + return; + } + for (i = 1; av[i] != NULL; i++) { + s = av[i]; + if (*s != '-' && *s != '+') { + VCLI_Out(cli, + "Missing '+' or '-' (%s)\n", s); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + for (j = 0; j < 256; j++) + if (VSL_tags[j] != NULL && + !strcasecmp(s + 1, VSL_tags[j])) + break; + if (j == 256) { + VCLI_Out(cli, + "Unknown VSL tag (%s)\n", s); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + if (s[0] == '+') + (void)vsl_bit(j, BCLR); + else + (void)vsl_bit(j, BSET); + } + VAV_Free(av); + } + } else { + s = ""; + for (j = 0; j < 256; j++) { + if (vsl_bit(j, BTST)) { + VCLI_Out(cli, "%s-%s", s, VSL_tags[j]); + s = ","; + } + } + if (*s == '\0') + VCLI_Out(cli, "(all enabled)"); + } +} + +const struct parspec VSL_parspec[] = { + { "vsl_mask", tweak_vsl_mask, NULL, 0, 0, + "Mask individual VSL messages from being logged", + 0, "default", "" }, + { NULL, NULL, NULL } +}; diff --git a/bin/varnishtest/tests/c00005.vtc b/bin/varnishtest/tests/c00005.vtc index 7a7965c..846b283 100644 --- a/bin/varnishtest/tests/c00005.vtc +++ b/bin/varnishtest/tests/c00005.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body "2222\n" } -start -varnish v1 -arg "-p vcl_trace=on" -vcl+backend { +varnish v1 -arg "-p vsl_mask=+VCL_trace" -vcl+backend { acl acl1 { "localhost"; } diff --git a/bin/varnishtest/tests/c00054.vtc b/bin/varnishtest/tests/c00054.vtc new file mode 100644 index 0000000..3299604 --- /dev/null +++ b/bin/varnishtest/tests/c00054.vtc @@ -0,0 +1,23 @@ +varnishtest "SLT masking" + + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend {} -start + +varnish v1 -cliok "param.show vsl_mask" +varnish v1 -cliok "param.set vsl_mask +VCL_trace" +varnish v1 -cliok "param.show vsl_mask" +varnish v1 -cliok "param.set vsl_mask -WorkThread,-TTL" +varnish v1 -cliok "param.show vsl_mask" +varnish v1 -cliok "param.set vsl_mask +WorkThread" +varnish v1 -clierr 106 "param.set vsl_mask FooBar" +varnish v1 -clierr 106 "param.set vsl_mask -FooBar" + +client c1 { + txreq + rxresp +} -run From phk at varnish-cache.org Mon Aug 27 10:47:16 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 12:47:16 +0200 Subject: [master] cf4da22 Reimplement param log_hashstring using vsl_mask Message-ID: commit cf4da2286ef0f3321c5e0c12b7a4bee50eacc83c Author: Poul-Henning Kamp Date: Mon Aug 27 10:46:45 2012 +0000 Reimplement param log_hashstring using vsl_mask XXX: doc-update needed diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 0db0d6b..5e1b004 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -169,8 +169,7 @@ HSH_AddString(struct req *req, const char *str) SHA256_Update(req->sha256ctx, str, l); SHA256_Update(req->sha256ctx, "#", 1); - if (cache_param->log_hash) - VSLb(req->vsl, SLT_Hash, "%s", str); + VSLb(req->vsl, SLT_Hash, "%s", str); } /*--------------------------------------------------------------------- diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index 79de607..e2c9ec1 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -144,9 +144,6 @@ struct params { /* Control diagnostic code */ unsigned diag_bitmap; - /* Log hash string to shm */ - unsigned log_hash; - /* Log local socket address to shm */ unsigned log_local_addr; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 026207c..9ce9470 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1033,10 +1033,6 @@ static const struct parspec input_parspec[] = { "more sessions take a detour around the waiter.", EXPERIMENTAL, "0.050", "seconds" }, - { "log_hashstring", tweak_bool, &mgt_param.log_hash, 0, 0, - "Log the hash string components to shared memory log.\n", - 0, - "on", "bool" }, { "log_local_address", tweak_bool, &mgt_param.log_local_addr, 0, 0, "Log the local address on the TCP connection in the " "SessionOpen VSL record.\n" diff --git a/bin/varnishd/mgt/mgt_param_vsl.c b/bin/varnishd/mgt/mgt_param_vsl.c index 6338d49..28ba7de 100644 --- a/bin/varnishd/mgt/mgt_param_vsl.c +++ b/bin/varnishd/mgt/mgt_param_vsl.c @@ -82,6 +82,7 @@ tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) if (!strcmp(arg, "default")) { (void)vsl_bit(SLT_VCL_trace, BSET); (void)vsl_bit(SLT_WorkThread, BSET); + (void)vsl_bit(SLT_Hash, BSET); } else if (*arg != 0) { av = VAV_Parse(arg, &n, ARGV_COMMA); if (av[0] != NULL) { @@ -118,7 +119,7 @@ tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) } } else { s = ""; - for (j = 0; j < 256; j++) { + for (j = 0; j < (unsigned)SLT_Reserved; j++) { if (vsl_bit(j, BTST)) { VCLI_Out(cli, "%s-%s", s, VSL_tags[j]); s = ","; From phk at varnish-cache.org Mon Aug 27 18:10:21 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 20:10:21 +0200 Subject: [master] 9232cd6 Generalize the param/bits code, we can do more with it that way. Message-ID: commit 9232cd638abebd9868c859c16dbbb4c64ae39391 Author: Poul-Henning Kamp Date: Mon Aug 27 16:46:01 2012 +0000 Generalize the param/bits code, we can do more with it that way. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 78f253c..3d35113 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -61,7 +61,7 @@ varnishd_SOURCES = \ mgt/mgt_cli.c \ mgt/mgt_main.c \ mgt/mgt_param.c \ - mgt/mgt_param_vsl.c \ + mgt/mgt_param_bits.c \ mgt/mgt_pool.c \ mgt/mgt_sandbox.c \ mgt/mgt_sandbox_solaris.c \ diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c new file mode 100644 index 0000000..1910f2b --- /dev/null +++ b/bin/varnishd/mgt/mgt_param_bits.c @@ -0,0 +1,168 @@ +/*- + * 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 "common/params.h" +#include "mgt/mgt.h" +#include "mgt/mgt_param.h" + +#include "vav.h" +#include "vcli.h" +#include "vcli_common.h" +#include "vcli_priv.h" + +#include "vapi/vsl_int.h" + +/*-------------------------------------------------------------------- + */ + +enum bit_do {BSET, BCLR, BTST}; + +static int +bit(uint8_t *p, unsigned no, enum bit_do act) +{ + uint8_t b; + + p += (no >> 3); + b = (0x80 >> (no & 7)); + if (act == BSET) + *p |= b; + else if (act == BCLR) + *p &= ~b; + return (*p & b); +} + +/*-------------------------------------------------------------------- + */ + +static void +bit_tweak(struct cli *cli, uint8_t *p, unsigned l, const char *arg, + const char * const *tags, const char *desc, const char *sign) +{ + int i, n; + unsigned j; + char **av; + const char *s; + + av = VAV_Parse(arg, &n, ARGV_COMMA); + if (av[0] != NULL) { + VCLI_Out(cli, "Cannot parse: %s\n", av[0]); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + for (i = 1; av[i] != NULL; i++) { + s = av[i]; + if (*s != '-' && *s != '+') { + VCLI_Out(cli, "Missing '+' or '-' (%s)\n", s); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + for (j = 0; j < l; j++) { + if (tags[j] != NULL && !strcasecmp(s + 1, tags[j])) + break; + } + if (tags[j] == NULL) { + VCLI_Out(cli, "Unknown %s (%s)\n", desc, s); + VCLI_SetResult(cli, CLIS_PARAM); + VAV_Free(av); + return; + } + assert(j < l); + if (s[0] == *sign) + (void)bit(p, j, BSET); + else + (void)bit(p, j, BCLR); + } + VAV_Free(av); +} + + +/*-------------------------------------------------------------------- + * The vsl_mask parameter + */ + +static const char * const VSL_tags[256] = { +# define SLTM(foo,sdesc,ldesc) [SLT_##foo] = #foo, +# include "tbl/vsl_tags.h" +# undef SLTM + NULL +}; + +static void +tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) +{ + unsigned j; + const char *s; + (void)par; + + if (arg != NULL) { + if (!strcmp(arg, "default")) { + memset(mgt_param.vsl_mask, + 0, sizeof mgt_param.vsl_mask); + (void)bit(mgt_param.vsl_mask, SLT_VCL_trace, BSET); + (void)bit(mgt_param.vsl_mask, SLT_WorkThread, BSET); + (void)bit(mgt_param.vsl_mask, SLT_Hash, BSET); + } else { + bit_tweak(cli, mgt_param.vsl_mask, + SLT_Reserved, arg, VSL_tags, + "VSL tag", "-"); + } + } else { + s = ""; + for (j = 0; j < (unsigned)SLT_Reserved; j++) { + if (bit(mgt_param.vsl_mask, j, BTST)) { + VCLI_Out(cli, "%s-%s", s, VSL_tags[j]); + s = ","; + } + } + if (*s == '\0') + VCLI_Out(cli, "(all enabled)"); + } +} + +/*-------------------------------------------------------------------- + * The parameter table itself + */ + +const struct parspec VSL_parspec[] = { + { "vsl_mask", tweak_vsl_mask, NULL, 0, 0, + "Mask individual VSL messages from being logged.\n" + "\tdefault\tSet default value\n" + "Use +/- prefixe in front of VSL tag name, to mask/unmask " + "individual VSL messages.", + 0, "default", "" }, + { NULL, NULL, NULL } +}; diff --git a/bin/varnishd/mgt/mgt_param_vsl.c b/bin/varnishd/mgt/mgt_param_vsl.c deleted file mode 100644 index 28ba7de..0000000 --- a/bin/varnishd/mgt/mgt_param_vsl.c +++ /dev/null @@ -1,138 +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 "common/params.h" -#include "mgt/mgt.h" -#include "mgt/mgt_param.h" - -#include "vav.h" -#include "vcli.h" -#include "vcli_common.h" -#include "vcli_priv.h" - -#include "vapi/vsl_int.h" - -static const char * const VSL_tags[256] = { -# define SLTM(foo,sdesc,ldesc) [SLT_##foo] = #foo, -# include "tbl/vsl_tags.h" -# undef SLTM -}; - -enum bit_do {BSET, BCLR, BTST}; - -static int -vsl_bit(unsigned no, enum bit_do act) -{ - volatile uint8_t *bm = &mgt_param.vsl_mask[0]; - uint8_t b; - - assert(no < (unsigned)SLT_Reserved); - - bm += (no >> 3); - b = (0x80 >> (no & 7)); - if (act == BSET) - *bm |= b; - else if (act == BCLR) - *bm &= ~b; - return (*bm & b); -} - -static void -tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) -{ - int i, n; - unsigned j; - const char *s; - char **av; - (void)par; - - if (arg != NULL) { - if (!strcmp(arg, "default")) { - (void)vsl_bit(SLT_VCL_trace, BSET); - (void)vsl_bit(SLT_WorkThread, BSET); - (void)vsl_bit(SLT_Hash, BSET); - } else if (*arg != 0) { - av = VAV_Parse(arg, &n, ARGV_COMMA); - if (av[0] != NULL) { - VCLI_Out(cli, "Cannot parse: %s\n", av[0]); - VCLI_SetResult(cli, CLIS_PARAM); - return; - } - for (i = 1; av[i] != NULL; i++) { - s = av[i]; - if (*s != '-' && *s != '+') { - VCLI_Out(cli, - "Missing '+' or '-' (%s)\n", s); - VCLI_SetResult(cli, CLIS_PARAM); - VAV_Free(av); - return; - } - for (j = 0; j < 256; j++) - if (VSL_tags[j] != NULL && - !strcasecmp(s + 1, VSL_tags[j])) - break; - if (j == 256) { - VCLI_Out(cli, - "Unknown VSL tag (%s)\n", s); - VCLI_SetResult(cli, CLIS_PARAM); - VAV_Free(av); - return; - } - if (s[0] == '+') - (void)vsl_bit(j, BCLR); - else - (void)vsl_bit(j, BSET); - } - VAV_Free(av); - } - } else { - s = ""; - for (j = 0; j < (unsigned)SLT_Reserved; j++) { - if (vsl_bit(j, BTST)) { - VCLI_Out(cli, "%s-%s", s, VSL_tags[j]); - s = ","; - } - } - if (*s == '\0') - VCLI_Out(cli, "(all enabled)"); - } -} - -const struct parspec VSL_parspec[] = { - { "vsl_mask", tweak_vsl_mask, NULL, 0, 0, - "Mask individual VSL messages from being logged", - 0, "default", "" }, - { NULL, NULL, NULL } -}; From phk at varnish-cache.org Mon Aug 27 18:10:21 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 20:10:21 +0200 Subject: [master] 73632b2 Add a debug parameter and start moving diag_bitmap stuff into it. Message-ID: commit 73632b2c74bfc12f15ec06d9e0ad0cea1acd0fe6 Author: Poul-Henning Kamp Date: Mon Aug 27 18:09:17 2012 +0000 Add a debug parameter and start moving diag_bitmap stuff into it. XXX: doc-update needed diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 43c104e..f3e32c3 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -976,12 +976,6 @@ void VSLbt(struct vsl_log *, enum VSL_tag_e tag, txt t); void VSL_Flush(struct vsl_log *, int overflow); -#define DSL(flag, tag, id, ...) \ - do { \ - if (cache_param->diag_bitmap & (flag)) \ - VSL((tag), (id), __VA_ARGS__); \ - } while (0) - #endif /* cache_response.c */ @@ -1122,3 +1116,16 @@ Tadd(txt *t, const char *p, int l) * extra timestamps in cache_pool.c. Hide this detail with a macro */ #define W_TIM_real(w) ((w)->lastused = VTIM_real()) + +static inline int +DO_DEBUG(enum debug_bits x) +{ + return (cache_param->debug_bits[(unsigned)x>>3] & + (0x80U >> ((unsigned)x & 7))); +} + +#define DSL(flag, tag, id, ...) \ + do { \ + if (cache_param->diag_bitmap & (flag)) \ + VSL((tag), (id), __VA_ARGS__); \ + } while (0) diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index e99ed6c..e12da55 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1220,7 +1220,7 @@ CNT_Request(struct worker *wrk, struct req *req) switch (req->req_step) { #define REQ_STEP(l,u,arg) \ case R_STP_##u: \ - if (cache_param->diag_bitmap & 0x01) \ + if (DO_DEBUG(DBG_REQ_STATE)) \ cnt_diag(req, #u); \ done = cnt_##l arg; \ break; diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index e2c9ec1..6c3abb4 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -33,6 +33,13 @@ #define VSM_CLASS_PARAM "Params" +enum debug_bits { +#define DEBUG_BIT(U, l, p, d) DBG_##U, +#include "tbl/debug_bits.h" +#undef DEBUG_BIT + DBG_Reserved +}; + struct poolparam { unsigned min_pool; unsigned max_pool; @@ -198,5 +205,6 @@ struct params { struct poolparam sess_pool; struct poolparam vbo_pool; - uint8_t vsl_mask[256/8]; + uint8_t vsl_mask[256>>3]; + uint8_t debug_bits[(DBG_Reserved+7)>>3]; }; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 9ce9470..7696292 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1046,7 +1046,6 @@ static const struct parspec input_parspec[] = { WAITER_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" diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c index 1910f2b..b238823 100644 --- a/bin/varnishd/mgt/mgt_param_bits.c +++ b/bin/varnishd/mgt/mgt_param_bits.c @@ -154,6 +154,45 @@ tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) } /*-------------------------------------------------------------------- + * The debug parameter + */ + +static const char * const debug_tags[] = { +# define DEBUG_BIT(U,l,p,d) [DBG_##U] = #l, +# include "tbl/debug_bits.h" +# undef DEBUG_BIT + NULL +}; + +static void +tweak_debug(struct cli *cli, const struct parspec *par, const char *arg) +{ + const char *s; + unsigned j; + (void)par; + + if (arg != NULL) { + if (!strcmp(arg, "none")) { + memset(mgt_param.debug_bits, + 0, sizeof mgt_param.debug_bits); + } else { + bit_tweak(cli, mgt_param.debug_bits, + DBG_Reserved, arg, debug_tags, "debug bit", "+"); + } + } else { + s = ""; + for (j = 0; j < (unsigned)DBG_Reserved; j++) { + if (bit(mgt_param.debug_bits, j, BTST)) { + VCLI_Out(cli, "%s+%s", s, debug_tags[j]); + s = ","; + } + } + if (*s == '\0') + VCLI_Out(cli, "none"); + } +} + +/*-------------------------------------------------------------------- * The parameter table itself */ @@ -164,5 +203,13 @@ const struct parspec VSL_parspec[] = { "Use +/- prefixe in front of VSL tag name, to mask/unmask " "individual VSL messages.", 0, "default", "" }, + { "debug", tweak_debug, NULL, 0, 0, + "Enable/Disable various kinds of debugging.\n" + "\tnone\t\tDisable all debugging\n" + "Use +/- prefix to set/reset individual bits:\n" +#define DEBUG_BIT(U, l, p, d) "\t" #l "\t" p d "\n" +#include "tbl/debug_bits.h" +#undef DEBUG_BIT + , 0, "none", "" }, { NULL, NULL, NULL } }; diff --git a/bin/varnishtest/tests.disabled/t00000.vtc b/bin/varnishtest/tests.disabled/t00000.vtc index 57ab7c7..8265195 100644 --- a/bin/varnishtest/tests.disabled/t00000.vtc +++ b/bin/varnishtest/tests.disabled/t00000.vtc @@ -20,7 +20,7 @@ varnish v1 -vcl+backend { } } -start -varnish v1 -cliok "param.set diag_bitmap 1" +varnish v1 -cliok "param.set debug +req_state" client c1 { txreq -hdr "foo: /foo" diff --git a/bin/varnishtest/tests/r00902.vtc b/bin/varnishtest/tests/r00902.vtc index 67e4c96..8caf652 100644 --- a/bin/varnishtest/tests/r00902.vtc +++ b/bin/varnishtest/tests/r00902.vtc @@ -15,7 +15,7 @@ server s1 { varnish v1 -vcl+backend { } -start -varnish v1 -cliok "param.set diag_bitmap 1" +varnish v1 -cliok "param.set debug +req_state" client c1 { txreq -hdr "foo: /foo" diff --git a/include/Makefile.am b/include/Makefile.am index b70a825..7562f6c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -6,6 +6,7 @@ nobase_pkginclude_HEADERS = \ tbl/backend_poll.h \ tbl/ban_vars.h \ tbl/body_status.h \ + tbl/debug_bits.h \ tbl/http_headers.h \ tbl/http_response.h \ tbl/locks.h \ diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h new file mode 100644 index 0000000..7acf6d8 --- /dev/null +++ b/include/tbl/debug_bits.h @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2012 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. + * + * Fields in the debug parameter + * + */ + +DEBUG_BIT(REQ_STATE, req_state, "", "Request state engine") From phk at varnish-cache.org Mon Aug 27 18:58:51 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 20:58:51 +0200 Subject: [master] 4dbf7e7 Move 3 bits more from diag_bitmaps to debug Message-ID: commit 4dbf7e7f2a5721a76b9b46a10cb5638c4972d0a1 Author: Poul-Henning Kamp Date: Mon Aug 27 18:58:13 2012 +0000 Move 3 bits more from diag_bitmaps to debug XXX: doc-update needed diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f3e32c3..30f8e99 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1124,8 +1124,8 @@ DO_DEBUG(enum debug_bits x) (0x80U >> ((unsigned)x & 7))); } -#define DSL(flag, tag, id, ...) \ +#define DSL(debug_bit, id, ...) \ do { \ - if (cache_param->diag_bitmap & (flag)) \ - VSL((tag), (id), __VA_ARGS__); \ + if (DO_DEBUG(debug_bit)) \ + VSL(SLT_Debug, (id), __VA_ARGS__); \ } while (0) diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index e7fee9b..404409f 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -105,7 +105,7 @@ ved_include(struct req *preq, const char *src, const char *host) i = CNT_Request(wrk, req); if (i == 1) break; - DSL(0x20, SLT_Debug, req->vsl->wid, + DSL(DBG_WAITINGLIST, req->vsl->wid, "loop waiting for ESI (%d)", i); assert(i == 2); AZ(req->wrk); diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 5e1b004..fcf447a 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -420,7 +420,7 @@ HSH_Lookup(struct req *req) VTAILQ_INSERT_TAIL(&oh->waitinglist->list, req, w_list); } - if (cache_param->diag_bitmap & 0x20) + if (DO_DEBUG(DBG_WAITINGLIST)) VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh); @@ -483,7 +483,7 @@ hsh_rush(struct dstat *ds, struct objhead *oh) ds->busy_wakeup++; AZ(req->wrk); VTAILQ_REMOVE(&wl->list, req, w_list); - DSL(0x20, SLT_Debug, req->vsl->wid, "off waiting list"); + DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list"); if (SES_ScheduleReq(req)) { /* * We could not schedule the session, leave the diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index d84e937..a5251ff 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -37,7 +37,7 @@ WS_Assert(const struct ws *ws) { CHECK_OBJ_NOTNULL(ws, WS_MAGIC); - DSL(0x02, SLT_Debug, 0, "WS(%p = (%s, %p %u %u %u)", + DSL(DBG_WORKSPACE, 0, "WS(%p = (%s, %p %u %u %u)", ws, ws->id, ws->s, pdiff(ws->s, ws->f), ws->r == NULL ? 0 : pdiff(ws->f, ws->r), pdiff(ws->s, ws->e)); @@ -60,7 +60,7 @@ void WS_Init(struct ws *ws, const char *id, void *space, unsigned len) { - DSL(0x02, SLT_Debug, 0, + DSL(DBG_WORKSPACE, 0, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); memset(ws, 0, sizeof *ws); @@ -83,7 +83,7 @@ WS_Reset(struct ws *ws, char *p) { WS_Assert(ws); - DSL(0x02, SLT_Debug, 0, "WS_Reset(%p, %p)", ws, p); + DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, %p)", ws, p); assert(ws->r == NULL); if (p == NULL) ws->f = ws->s; @@ -111,7 +111,7 @@ WS_Alloc(struct ws *ws, unsigned bytes) } r = ws->f; ws->f += bytes; - DSL(0x02, SLT_Debug, 0, "WS_Alloc(%p, %u) = %p", ws, bytes, r); + DSL(DBG_WORKSPACE, 0, "WS_Alloc(%p, %u) = %p", ws, bytes, r); WS_Assert(ws); return (r); } @@ -122,7 +122,7 @@ WS_Snapshot(struct ws *ws) WS_Assert(ws); assert(ws->r == NULL); - DSL(0x02, SLT_Debug, 0, "WS_Snapshot(%p) = %p", ws, ws->f); + DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = %p", ws, ws->f); return (ws->f); } @@ -142,7 +142,7 @@ WS_Reserve(struct ws *ws, unsigned bytes) b2 = PRNDDN(b2); xxxassert(ws->f + b2 <= ws->e); ws->r = ws->f + b2; - DSL(0x02, SLT_Debug, 0, "WS_Reserve(%p, %u/%u) = %u", + DSL(DBG_WORKSPACE, 0, "WS_Reserve(%p, %u/%u) = %u", ws, b2, bytes, pdiff(ws->f, ws->r)); WS_Assert(ws); return (pdiff(ws->f, ws->r)); @@ -154,7 +154,7 @@ WS_Release(struct ws *ws, unsigned bytes) WS_Assert(ws); bytes = PRNDUP(bytes); assert(bytes <= ws->e - ws->f); - DSL(0x02, SLT_Debug, 0, "WS_Release(%p, %u)", ws, bytes); + DSL(DBG_WORKSPACE, 0, "WS_Release(%p, %u)", ws, bytes); assert(ws->r != NULL); assert(ws->f + bytes <= ws->r); ws->f += bytes; @@ -166,7 +166,7 @@ void WS_ReleaseP(struct ws *ws, char *ptr) { WS_Assert(ws); - DSL(0x02, SLT_Debug, 0, "WS_ReleaseP(%p, %p)", ws, ptr); + DSL(DBG_WORKSPACE, 0, "WS_ReleaseP(%p, %p)", ws, ptr); assert(ws->r != NULL); assert(ptr >= ws->f); assert(ptr <= ws->r); diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 7696292..dd084ed 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1046,11 +1046,8 @@ static const struct parspec input_parspec[] = { WAITER_DEFAULT, NULL }, { "diag_bitmap", tweak_diag_bitmap, 0, 0, 0, "Bitmap controlling diagnostics code:\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" " 0x00000080 - mutex timing.\n" " 0x00001000 - do not core-dump child process.\n" diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c index bc5c67f..8d37ad6 100644 --- a/bin/varnishd/waiter/cache_waiter_kqueue.c +++ b/bin/varnishd/waiter/cache_waiter_kqueue.c @@ -80,7 +80,7 @@ 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->vxid, "KQ: EV_SET sp %p arm %x", sp, arm); + DSL(DBG_WAITER, sp->vxid, "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); @@ -121,7 +121,7 @@ vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now) AN(kp->udata); assert(kp->udata != vwk->pipes); CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); - DSL(0x04, SLT_Debug, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", + DSL(DBG_WAITER, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); diff --git a/bin/varnishtest/tests/b00000.vtc b/bin/varnishtest/tests/b00000.vtc index 2018235..2e6d5ce 100644 --- a/bin/varnishtest/tests/b00000.vtc +++ b/bin/varnishtest/tests/b00000.vtc @@ -7,7 +7,7 @@ server s1 { varnish v1 -storage "-smalloc,1m" -vcl+backend {} -start -varnish v1 -cliok "param.set diag_bitmap 0x2" +varnish v1 -cliok "param.set debug +workspace" varnish v1 -expect n_object == 0 varnish v1 -expect sess_conn == 0 diff --git a/bin/varnishtest/tests/r00345.vtc b/bin/varnishtest/tests/r00345.vtc index 712aa98..6ebbc99 100644 --- a/bin/varnishtest/tests/r00345.vtc +++ b/bin/varnishtest/tests/r00345.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body {DATA} } -start -varnish v1 -arg "-p diag_bitmap=0x20" -vcl+backend { +varnish v1 -arg "-p debug=+workspace" -vcl+backend { sub vcl_fetch { if (req.url == "/") { set beresp.do_esi = true; diff --git a/bin/varnishtest/tests/r00386.vtc b/bin/varnishtest/tests/r00386.vtc index f5f1907..c2fcc53 100644 --- a/bin/varnishtest/tests/r00386.vtc +++ b/bin/varnishtest/tests/r00386.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body {} } -start -varnish v1 -arg "-p diag_bitmap=0x20" -vcl+backend { +varnish v1 -arg "-p debug=+workspace" -vcl+backend { sub vcl_fetch { if (req.url == "/") { set beresp.do_esi = true; diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h index 7acf6d8..3300547 100644 --- a/include/tbl/debug_bits.h +++ b/include/tbl/debug_bits.h @@ -29,4 +29,7 @@ * */ -DEBUG_BIT(REQ_STATE, req_state, "", "Request state engine") +DEBUG_BIT(REQ_STATE, req_state, "", "VSL Request state engine") +DEBUG_BIT(WORKSPACE, workspace, "", "VSL Workspace operations") +DEBUG_BIT(WAITER, waiter, "", "VSL Waiter internals") +DEBUG_BIT(WAITINGLIST, waitinglist, "", "VSL Waitinglist events") From phk at varnish-cache.org Mon Aug 27 20:20:49 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 22:20:49 +0200 Subject: [master] 609c67d Move another bit from diag_bitmap to debug Message-ID: commit 609c67d18aa90cebb8301cbafec592c66e110a38 Author: Poul-Henning Kamp Date: Mon Aug 27 19:21:23 2012 +0000 Move another bit from diag_bitmap to debug XXX: doc-update needed diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 167c25e..228dde8 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -240,7 +240,7 @@ wslr(struct vsl_log *vsl, enum VSL_tag_e tag, int id, txt t) vsl->wlp = VSL_END(vsl->wlp, l); assert(vsl->wlp < vsl->wle); vsl->wlr++; - if (cache_param->diag_bitmap & 0x10000) + if (DO_DEBUG(DBG_SYNCVSL)) VSL_Flush(vsl, 0); } @@ -281,7 +281,7 @@ wsl(struct vsl_log *vsl, enum VSL_tag_e tag, int id, const char *fmt, assert(vsl->wlp < vsl->wle); vsl->wlr++; } - if (cache_param->diag_bitmap & 0x10000) + if (DO_DEBUG(DBG_SYNCVSL)) VSL_Flush(vsl, 0); } diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index dd084ed..2c8ad86 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1053,7 +1053,6 @@ static const struct parspec input_parspec[] = { " 0x00001000 - do not core-dump child process.\n" " 0x00002000 - only short panic message.\n" " 0x00004000 - panic to stderr.\n" - " 0x00010000 - synchronize shmlog.\n" " 0x00020000 - synchronous start of persistence.\n" " 0x00040000 - release VCL early.\n" " 0x00080000 - ban-lurker debugging.\n" diff --git a/bin/varnishtest/tests/e00008.vtc b/bin/varnishtest/tests/e00008.vtc index 9c8770f..15b915a 100644 --- a/bin/varnishtest/tests/e00008.vtc +++ b/bin/varnishtest/tests/e00008.vtc @@ -63,7 +63,7 @@ varnish v1 -vcl+backend { varnish v1 -cliok "param.set esi_syntax 0x3e" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq diff --git a/bin/varnishtest/tests/e00019.vtc b/bin/varnishtest/tests/e00019.vtc index 2c1e82b..54c756f 100644 --- a/bin/varnishtest/tests/e00019.vtc +++ b/bin/varnishtest/tests/e00019.vtc @@ -38,7 +38,7 @@ varnish v1 -vcl+backend { varnish v1 -cliok "param.set esi_syntax 8" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq -url bar diff --git a/bin/varnishtest/tests/e00023.vtc b/bin/varnishtest/tests/e00023.vtc index 1373fc8..03d185b 100644 --- a/bin/varnishtest/tests/e00023.vtc +++ b/bin/varnishtest/tests/e00023.vtc @@ -44,7 +44,7 @@ varnish v1 -vcl+backend { varnish v1 -cliok "param.set http_gzip_support true" varnish v1 -cliok "param.set esi_syntax 0x3e" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq -hdr "Accept-Encoding: gzip" diff --git a/bin/varnishtest/tests/e00024.vtc b/bin/varnishtest/tests/e00024.vtc index f728b3c..87235c5 100644 --- a/bin/varnishtest/tests/e00024.vtc +++ b/bin/varnishtest/tests/e00024.vtc @@ -69,7 +69,7 @@ varnish v1 -vcl+backend { varnish v1 -cliok "param.set http_gzip_support true" varnish v1 -cliok "param.set esi_syntax 0x3e" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq -hdr "Accept-Encoding: gzip" diff --git a/bin/varnishtest/tests/e00026.vtc b/bin/varnishtest/tests/e00026.vtc index bcb05b0..fa6cf9a 100644 --- a/bin/varnishtest/tests/e00026.vtc +++ b/bin/varnishtest/tests/e00026.vtc @@ -37,7 +37,7 @@ varnish v1 -vcl+backend { varnish v1 -cliok "param.set esi_syntax 0x21" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq -url /foo -hdr "Accept-Encoding: gzip" diff --git a/bin/varnishtest/tests/g00004.vtc b/bin/varnishtest/tests/g00004.vtc index 0ab74ad..0a23c01 100644 --- a/bin/varnishtest/tests/g00004.vtc +++ b/bin/varnishtest/tests/g00004.vtc @@ -18,7 +18,6 @@ server s1 -repeat 2 { } -start varnish v1 \ - -arg {-p diag_bitmap=0x00010000} \ -vcl+backend { sub vcl_fetch { set beresp.do_stream = false; @@ -29,6 +28,8 @@ varnish v1 \ } } +varnish v1 -cliok "param.set debug +syncvsl" + varnish v1 -start client c1 { diff --git a/bin/varnishtest/tests/r00433.vtc b/bin/varnishtest/tests/r00433.vtc index f782f14..1bcefa8 100644 --- a/bin/varnishtest/tests/r00433.vtc +++ b/bin/varnishtest/tests/r00433.vtc @@ -37,7 +37,7 @@ varnish v1 -vcl+backend { } -start varnish v1 -cliok "param.set esi_syntax 4" -varnish v1 -cliok "param.set diag_bitmap 0x10000" +varnish v1 -cliok "param.set debug +syncvsl" varnish v1 -cliok "debug.fragfetch 32" client c1 { diff --git a/bin/varnishtest/tests/r00466.vtc b/bin/varnishtest/tests/r00466.vtc index 3d64b22..e509de8 100644 --- a/bin/varnishtest/tests/r00466.vtc +++ b/bin/varnishtest/tests/r00466.vtc @@ -23,7 +23,9 @@ varnish v1 -vcl+backend { return(pass); } } -} -start -cliok "param.set diag_bitmap 0x10000" +} -start + +varnish v1 -cliok "param.set debug +syncvsl" client c1 { txreq -url "/foo" -hdr "Range: 100-200" diff --git a/bin/varnishtest/tests/r00942.vtc b/bin/varnishtest/tests/r00942.vtc index 6bb31e1..1506709 100644 --- a/bin/varnishtest/tests/r00942.vtc +++ b/bin/varnishtest/tests/r00942.vtc @@ -25,13 +25,13 @@ server s1 { } -start varnish v1 \ - -arg {-p diag_bitmap=0x00010000} \ -vcl+backend { sub vcl_fetch { set beresp.do_stream = false; } } +varnish v1 -cliok "param.set debug +syncvsl" varnish v1 -start client c1 { diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h index 3300547..ece0fc4 100644 --- a/include/tbl/debug_bits.h +++ b/include/tbl/debug_bits.h @@ -31,5 +31,6 @@ DEBUG_BIT(REQ_STATE, req_state, "", "VSL Request state engine") DEBUG_BIT(WORKSPACE, workspace, "", "VSL Workspace operations") -DEBUG_BIT(WAITER, waiter, "", "VSL Waiter internals") +DEBUG_BIT(WAITER, waiter, "\t","VSL Waiter internals") DEBUG_BIT(WAITINGLIST, waitinglist, "", "VSL Waitinglist events") +DEBUG_BIT(SYNCVSL, syncvsl, "\t","Make VSL synchronous") From phk at varnish-cache.org Mon Aug 27 20:20:49 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Mon, 27 Aug 2012 22:20:49 +0200 Subject: [master] 495b9f5 Move 3 more debug bits from diag_bitmaps to debug Message-ID: commit 495b9f51c6a7cc67e1c6b5609251cbcfb50ea3c2 Author: Poul-Henning Kamp Date: Mon Aug 27 20:19:33 2012 +0000 Move 3 more debug bits from diag_bitmaps to debug XXX: doc-update needed diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index c949acc..2054d3e 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -836,13 +836,13 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass) b->flags &= ~BAN_F_LURK; b->flags |= pass; } - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "lurker: %d actionable bans", i); if (i == 0) return (0); VTAILQ_FOREACH_REVERSE(b, &ban_head, banhead_s, list) { - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "lurker doing %f %d", ban_time(b->spec), b->refcount); while (1) { @@ -851,7 +851,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass) if (oc == NULL) break; CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "test: %p %u %u", oc, oc->flags & OC_F_LURK, pass); if ((oc->flags & OC_F_LURK) == pass) @@ -903,7 +903,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass) */ o = oc_getobj(&wrk->stats, oc); i = ban_check_object(o, vsl, NULL); - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "lurker got: %p %d", oc, i); if (i == -1) { @@ -915,7 +915,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass) Lck_Unlock(&ban_mtx); } Lck_Unlock(&oh->mtx); - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "lurker done: %p %u %u", oc, oc->flags & OC_F_LURK, pass); (void)HSH_Deref(&wrk->stats, NULL, &o); @@ -927,7 +927,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass) b->flags |= BAN_F_GONE; VSC_C_main->bans_gone++; } - if (cache_param->diag_bitmap & 0x80000) + if (DO_DEBUG(DBG_LURKER)) VSLb(vsl, SLT_Debug, "lurker BAN %f now gone", ban_time(b->spec)); } @@ -1091,7 +1091,7 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "Present bans:\n"); VTAILQ_FOREACH(b, &ban_head, list) { - if (b == bl && !(cache_param->diag_bitmap & 0x80000)) + if (b == bl && !DO_DEBUG(DBG_LURKER)) break; VCLI_Out(cli, "%10.6f %5u%s\t", ban_time(b->spec), bl == b ? b->refcount - 1 : b->refcount, @@ -1100,7 +1100,7 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "\n"); if (VCLI_Overflow(cli)) break; - if (cache_param->diag_bitmap & 0x80000) { + if (DO_DEBUG(DBG_LURKER)) { Lck_Lock(&ban_mtx); struct objcore *oc; VTAILQ_FOREACH(oc, &b->objcore, ban_list) diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index fcf447a..932cb67 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -305,7 +305,7 @@ HSH_Lookup(struct req *req) AN(hash); hsh_prealloc(wrk); - if (cache_param->diag_bitmap & 0x80000000) + if (DO_DEBUG(DBG_HASHEDGE)) hsh_testmagic(req->digest); if (req->hash_objhead != NULL) { diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 6cffa69..5caf03f 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -140,10 +140,8 @@ ses_req_pool_task(struct worker *wrk, void *arg) HTTP1_Session(wrk, req); WS_Assert(wrk->aws); AZ(wrk->wrw); - if (cache_param->diag_bitmap & 0x00040000) { - if (wrk->vcl != NULL) - VCL_Rel(&wrk->vcl); - } + if (DO_DEBUG(DBG_VCLREL) && wrk->vcl != NULL) + VCL_Rel(&wrk->vcl); THR_SetRequest(NULL); } diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 2c8ad86..a6f75b8 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1054,9 +1054,6 @@ static const struct parspec input_parspec[] = { " 0x00002000 - only short panic message.\n" " 0x00004000 - panic to stderr.\n" " 0x00020000 - synchronous start of persistence.\n" - " 0x00040000 - release VCL early.\n" - " 0x00080000 - ban-lurker debugging.\n" - " 0x80000000 - do edge-detection on digest.\n" "\n" "Use 0x notation and do the bitor in your head :-)\n" "\n" diff --git a/bin/varnishtest/tests/c00023.vtc b/bin/varnishtest/tests/c00023.vtc index b57c8c1..0e6aff1 100644 --- a/bin/varnishtest/tests/c00023.vtc +++ b/bin/varnishtest/tests/c00023.vtc @@ -31,7 +31,7 @@ server s1 { } -start varnish v1 -arg "-hcritbit" -vcl+backend { } -start -varnish v1 -cliok "param.set diag_bitmap 0x80000000" +varnish v1 -cliok "param.set debug +hashedge" client c1 { txreq -url "/1" diff --git a/bin/varnishtest/tests/c00049.vtc b/bin/varnishtest/tests/c00049.vtc index 59e6c14..2e31705 100644 --- a/bin/varnishtest/tests/c00049.vtc +++ b/bin/varnishtest/tests/c00049.vtc @@ -36,7 +36,7 @@ varnish v1 -vcl+backend { } -start varnish v1 -cliok "param.set ban_lurker_sleep 0" -varnish v1 -cliok "param.set diag_bitmap 0x80000" +varnish v1 -cliok "param.set debug +lurker" varnish v1 -cliok "ban.list" diff --git a/bin/varnishtest/tests/m00001.vtc b/bin/varnishtest/tests/m00001.vtc index dd2b064..9f4a743 100644 --- a/bin/varnishtest/tests/m00001.vtc +++ b/bin/varnishtest/tests/m00001.vtc @@ -15,7 +15,7 @@ varnish v1 -arg "-pthread_pools=1" -vcl+backend { } } -start -varnish v1 -cliok "param.set diag_bitmap 0x40000" +varnish v1 -cliok "param.set debug +vclrel" client c1 { txreq -url "/bar" diff --git a/bin/varnishtest/tests/p00005.vtc b/bin/varnishtest/tests/p00005.vtc index b41ded3..e519cc1 100644 --- a/bin/varnishtest/tests/p00005.vtc +++ b/bin/varnishtest/tests/p00005.vtc @@ -8,7 +8,6 @@ server s1 { } -start varnish v1 \ - -arg "-pdiag_bitmap=0x30000" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -arg "-pban_lurker_sleep=0" \ -vcl+backend { @@ -17,6 +16,9 @@ varnish v1 \ } } -start +varnish v1 -cliok "param.set debug +syncvsl" +varnish v1 -cliok "param.set diag_bitmap 0x20000" + client c1 { txreq -url "/foo" rxresp diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h index ece0fc4..72d298d 100644 --- a/include/tbl/debug_bits.h +++ b/include/tbl/debug_bits.h @@ -34,3 +34,6 @@ DEBUG_BIT(WORKSPACE, workspace, "", "VSL Workspace operations") DEBUG_BIT(WAITER, waiter, "\t","VSL Waiter internals") DEBUG_BIT(WAITINGLIST, waitinglist, "", "VSL Waitinglist events") DEBUG_BIT(SYNCVSL, syncvsl, "\t","Make VSL synchronous") +DEBUG_BIT(HASHEDGE, hashedge, "", "Edge cases in Hash") +DEBUG_BIT(VCLREL, vclrel, "\t","Rapid VCL release") +DEBUG_BIT(LURKER, lurker, "\t","VSL Ban lurker") From phk at varnish-cache.org Tue Aug 28 06:37:53 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 08:37:53 +0200 Subject: [master] a1781ca Minor polish to bitmap params Message-ID: commit a1781ca5c65cf4bc81c0b98136ce93d0ff7c325b Author: Poul-Henning Kamp Date: Tue Aug 28 06:37:36 2012 +0000 Minor polish to bitmap params diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index a6f75b8..aa99683 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1048,7 +1048,6 @@ static const struct parspec input_parspec[] = { "Bitmap controlling diagnostics code:\n" " 0x00000008 - mutex logging.\n" " 0x00000010 - mutex contests.\n" - " 0x00000040 - object workspace.\n" " 0x00000080 - mutex timing.\n" " 0x00001000 - do not core-dump child process.\n" " 0x00002000 - only short panic message.\n" diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc index 5d447b2..b8dcbc8 100644 --- a/bin/varnishtest/tests/b00008.vtc +++ b/bin/varnishtest/tests/b00008.vtc @@ -22,7 +22,7 @@ varnish v1 -cliok "param.show" varnish v1 -cliok "param.show diag_bitmap" -varnish v1 -cliok "param.set diag_bitmap 0x40" +varnish v1 -cliok "param.set diag_bitmap 0x80" varnish v1 -cliok "param.set diag_bitmap 0x0" diff --git a/bin/varnishtest/tests/c00054.vtc b/bin/varnishtest/tests/c00054.vtc index 3299604..e6e2260 100644 --- a/bin/varnishtest/tests/c00054.vtc +++ b/bin/varnishtest/tests/c00054.vtc @@ -1,4 +1,4 @@ -varnishtest "SLT masking" +varnishtest "bitmap params masking" server s1 { @@ -13,9 +13,14 @@ varnish v1 -cliok "param.set vsl_mask +VCL_trace" varnish v1 -cliok "param.show vsl_mask" varnish v1 -cliok "param.set vsl_mask -WorkThread,-TTL" varnish v1 -cliok "param.show vsl_mask" -varnish v1 -cliok "param.set vsl_mask +WorkThread" +varnish v1 -cliok "param.set vsl_mask +WorkThread,+TTL,+Hash" +varnish v1 -cliok "param.show vsl_mask" varnish v1 -clierr 106 "param.set vsl_mask FooBar" varnish v1 -clierr 106 "param.set vsl_mask -FooBar" +varnish v1 -clierr 106 {param.set vsl_mask \"} + +varnish v1 -cliok "param.set debug +workspace" +varnish v1 -cliok "param.show debug" client c1 { txreq From phk at varnish-cache.org Tue Aug 28 07:42:36 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 09:42:36 +0200 Subject: [master] 0b7cc04 Add a new "feature" parameter and move certain bits from diag_bitmaps there. These bits are legitimate feature-ettes which might make sense in a production environment. Message-ID: commit 0b7cc04c35e917df74cfa976748ae3cae092f65a Author: Poul-Henning Kamp Date: Tue Aug 28 07:41:45 2012 +0000 Add a new "feature" parameter and move certain bits from diag_bitmaps there. These bits are legitimate feature-ettes which might make sense in a production environment. XXX: need doc-change diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 30f8e99..94db4b6 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -1118,6 +1118,13 @@ Tadd(txt *t, const char *p, int l) #define W_TIM_real(w) ((w)->lastused = VTIM_real()) static inline int +FEATURE(enum feature_bits x) +{ + return (cache_param->feature_bits[(unsigned)x>>3] & + (0x80U >> ((unsigned)x & 7))); +} + +static inline int DO_DEBUG(enum debug_bits x) { return (cache_param->debug_bits[(unsigned)x>>3] & diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 8af00f6..ac36308 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -225,7 +225,7 @@ child_main(void) CLI_AddFuncs(debug_cmds); /* Wait for persistent storage to load if asked to */ - if (cache_param->diag_bitmap & 0x00020000) + if (FEATURE(FEATURE_WAIT_SILO)) SMP_Ready(); CLI_Run(); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index ee7dd78..c93749f 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -392,7 +392,7 @@ pan_ic(const char *func, const char *file, int line, const char *cond, pan_backtrace(); - if (!(cache_param->diag_bitmap & 0x2000)) { + if (!FEATURE(FEATURE_SHORT_PANIC)) { req = THR_GetRequest(); if (req != NULL) pan_req(req); @@ -400,10 +400,7 @@ pan_ic(const char *func, const char *file, int line, const char *cond, VSB_printf(pan_vsp, "\n"); VSB_bcat(pan_vsp, "", 1); /* NUL termination */ - if (cache_param->diag_bitmap & 0x4000) - (void)fputs(heritage.panic_str, stderr); - - if (cache_param->diag_bitmap & 0x1000) + if (FEATURE(FEATURE_NO_COREDUMP)) exit(4); else abort(); diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index 6c3abb4..6abe0fc 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -40,6 +40,13 @@ enum debug_bits { DBG_Reserved }; +enum feature_bits { +#define FEATURE_BIT(U, l, p, d, ld) FEATURE_##U, +#include "tbl/feature_bits.h" +#undef FEATURE_BIT + FEATURE_Reserved +}; + struct poolparam { unsigned min_pool; unsigned max_pool; @@ -207,4 +214,5 @@ struct params { uint8_t vsl_mask[256>>3]; uint8_t debug_bits[(DBG_Reserved+7)>>3]; + uint8_t feature_bits[(FEATURE_Reserved+7)>>3]; }; diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index c869897..95d1794 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -88,6 +88,14 @@ static struct vlu *vlu; static struct vsb *child_panic = NULL; +static inline int +MGT_FEATURE(enum feature_bits x) +{ + return (mgt_param.feature_bits[(unsigned)x>>3] & + (0x80U >> ((unsigned)x & 7))); +} + + /*-------------------------------------------------------------------- * Track the highest file descriptor the parent knows is being used. * @@ -213,7 +221,7 @@ MGT_Child_Cli_Fail(void) return; REPORT(LOG_ERR, "Child (%jd) not responding to CLI, killing it.", (intmax_t)child_pid); - if (mgt_param.diag_bitmap & 0x1000) + if (MGT_FEATURE(FEATURE_NO_COREDUMP)) (void)kill(child_pid, SIGKILL); else (void)kill(child_pid, SIGQUIT); diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index aa99683..434082e 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -1049,10 +1049,6 @@ static const struct parspec input_parspec[] = { " 0x00000008 - mutex logging.\n" " 0x00000010 - mutex contests.\n" " 0x00000080 - mutex timing.\n" - " 0x00001000 - do not core-dump child process.\n" - " 0x00002000 - only short panic message.\n" - " 0x00004000 - panic to stderr.\n" - " 0x00020000 - synchronous start of persistence.\n" "\n" "Use 0x notation and do the bitor in your head :-)\n" "\n" diff --git a/bin/varnishd/mgt/mgt_param_bits.c b/bin/varnishd/mgt/mgt_param_bits.c index b238823..a5996a2 100644 --- a/bin/varnishd/mgt/mgt_param_bits.c +++ b/bin/varnishd/mgt/mgt_param_bits.c @@ -115,7 +115,7 @@ bit_tweak(struct cli *cli, uint8_t *p, unsigned l, const char *arg, */ static const char * const VSL_tags[256] = { -# define SLTM(foo,sdesc,ldesc) [SLT_##foo] = #foo, +# define SLTM(foo,sdesc,ldesc) [SLT_##foo] = #foo, # include "tbl/vsl_tags.h" # undef SLTM NULL @@ -158,7 +158,7 @@ tweak_vsl_mask(struct cli *cli, const struct parspec *par, const char *arg) */ static const char * const debug_tags[] = { -# define DEBUG_BIT(U,l,p,d) [DBG_##U] = #l, +# define DEBUG_BIT(U,l,p,d) [DBG_##U] = #l, # include "tbl/debug_bits.h" # undef DEBUG_BIT NULL @@ -193,6 +193,46 @@ tweak_debug(struct cli *cli, const struct parspec *par, const char *arg) } /*-------------------------------------------------------------------- + * The feature parameter + */ + +static const char * const feature_tags[] = { +# define FEATURE_BIT(U,l,p,d, ld) [FEATURE_##U] = #l, +# include "tbl/feature_bits.h" +# undef FEATURE_BIT + NULL +}; + +static void +tweak_feature(struct cli *cli, const struct parspec *par, const char *arg) +{ + const char *s; + unsigned j; + (void)par; + + if (arg != NULL) { + if (!strcmp(arg, "none")) { + memset(mgt_param.feature_bits, + 0, sizeof mgt_param.feature_bits); + } else { + bit_tweak(cli, mgt_param.feature_bits, + FEATURE_Reserved, arg, feature_tags, + "feature bit", "+"); + } + } else { + s = ""; + for (j = 0; j < (unsigned)FEATURE_Reserved; j++) { + if (bit(mgt_param.feature_bits, j, BTST)) { + VCLI_Out(cli, "%s+%s", s, feature_tags[j]); + s = ","; + } + } + if (*s == '\0') + VCLI_Out(cli, "none"); + } +} + +/*-------------------------------------------------------------------- * The parameter table itself */ @@ -211,5 +251,13 @@ const struct parspec VSL_parspec[] = { #include "tbl/debug_bits.h" #undef DEBUG_BIT , 0, "none", "" }, + { "feature", tweak_feature, NULL, 0, 0, + "Enable/Disable various minor features.\n" + "\tnone\t\tDisable all features.\n" + "Use +/- prefix to enable/disable individual feature:\n" +#define FEATURE_BIT(U, l, p, d, ld) "\t" #l "\t" p d "\n" +#include "tbl/feature_bits.h" +#undef FEATURE_BIT + , 0, "none", "" }, { NULL, NULL, NULL } }; diff --git a/bin/varnishtest/tests/c00054.vtc b/bin/varnishtest/tests/c00054.vtc index e6e2260..d3a1072 100644 --- a/bin/varnishtest/tests/c00054.vtc +++ b/bin/varnishtest/tests/c00054.vtc @@ -21,6 +21,7 @@ varnish v1 -clierr 106 {param.set vsl_mask \"} varnish v1 -cliok "param.set debug +workspace" varnish v1 -cliok "param.show debug" +varnish v1 -cliok "param.show feature" client c1 { txreq diff --git a/bin/varnishtest/tests/p00000.vtc b/bin/varnishtest/tests/p00000.vtc index 12fa676..745abf5 100644 --- a/bin/varnishtest/tests/p00000.vtc +++ b/bin/varnishtest/tests/p00000.vtc @@ -8,7 +8,7 @@ server s1 { shell "rm -f ${tmpdir}/_.per" varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -vcl+backend { } -start diff --git a/bin/varnishtest/tests/p00001.vtc b/bin/varnishtest/tests/p00001.vtc index 26ea975..ac95149 100644 --- a/bin/varnishtest/tests/p00001.vtc +++ b/bin/varnishtest/tests/p00001.vtc @@ -8,7 +8,7 @@ server s1 { } -start varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -arg "-pban_lurker_sleep=0" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -vcl+backend { } -start diff --git a/bin/varnishtest/tests/p00002.vtc b/bin/varnishtest/tests/p00002.vtc index e3ea052..dc6e584 100644 --- a/bin/varnishtest/tests/p00002.vtc +++ b/bin/varnishtest/tests/p00002.vtc @@ -8,7 +8,7 @@ server s1 { } -start varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -arg "-pban_lurker_sleep=0" \ -storage "-spersistent,${tmpdir}/_.per1,10m" \ -storage "-spersistent,${tmpdir}/_.per2,10m" \ diff --git a/bin/varnishtest/tests/p00003.vtc b/bin/varnishtest/tests/p00003.vtc index f554536..4af3b14 100644 --- a/bin/varnishtest/tests/p00003.vtc +++ b/bin/varnishtest/tests/p00003.vtc @@ -8,7 +8,7 @@ server s1 { } -start varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -arg "-pban_lurker_sleep=0" \ -vcl+backend { } -start diff --git a/bin/varnishtest/tests/p00004.vtc b/bin/varnishtest/tests/p00004.vtc index 343d7de..f1e4368 100644 --- a/bin/varnishtest/tests/p00004.vtc +++ b/bin/varnishtest/tests/p00004.vtc @@ -10,7 +10,7 @@ server s1 { } -start varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -arg "-pban_lurker_sleep=0" \ -vcl+backend { } -start diff --git a/bin/varnishtest/tests/p00005.vtc b/bin/varnishtest/tests/p00005.vtc index e519cc1..cb0c4e2 100644 --- a/bin/varnishtest/tests/p00005.vtc +++ b/bin/varnishtest/tests/p00005.vtc @@ -17,7 +17,7 @@ varnish v1 \ } -start varnish v1 -cliok "param.set debug +syncvsl" -varnish v1 -cliok "param.set diag_bitmap 0x20000" +varnish v1 -cliok "param.set feature +wait_silo" client c1 { txreq -url "/foo" diff --git a/bin/varnishtest/tests/r00915.vtc b/bin/varnishtest/tests/r00915.vtc index 07a39d9..266c6b7 100644 --- a/bin/varnishtest/tests/r00915.vtc +++ b/bin/varnishtest/tests/r00915.vtc @@ -8,7 +8,7 @@ server s1 { shell "rm -f ${tmpdir}/_.per" varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per,10m" \ -vcl+backend { diff --git a/bin/varnishtest/tests/r00962.vtc b/bin/varnishtest/tests/r00962.vtc index aa0fb10..4331cd0 100644 --- a/bin/varnishtest/tests/r00962.vtc +++ b/bin/varnishtest/tests/r00962.vtc @@ -11,7 +11,7 @@ server s1 { shell "rm -f ${tmpdir}/_.per?" varnish v1 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per1,10m -spersistent,${tmpdir}/_.per2,10m" \ -vcl+backend { sub vcl_fetch { @@ -42,7 +42,7 @@ server s1 { varnish v2 \ - -arg "-pdiag_bitmap=0x20000" \ + -arg "-pfeature=+wait_silo" \ -storage "-spersistent,${tmpdir}/_.per2,10m -spersistent,${tmpdir}/_.per1,10m" \ -vcl+backend { } -start diff --git a/bin/varnishtest/tests/v00010.vtc b/bin/varnishtest/tests/v00010.vtc index 2e9a385..19405cc 100644 --- a/bin/varnishtest/tests/v00010.vtc +++ b/bin/varnishtest/tests/v00010.vtc @@ -37,7 +37,7 @@ varnish v1 -storage "-smalloc,1m" -vcl+backend { } } -start -varnish v1 -cliok "param.set diag_bitmap 0x00001000" +varnish v1 -cliok "param.set feature +no_coredump" # Force the (random) port selected to be used again after restart. varnish v1 -cliok "param.set listen_address ${v1_addr}:${v1_port}" diff --git a/include/Makefile.am b/include/Makefile.am index 7562f6c..15df374 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -7,6 +7,7 @@ nobase_pkginclude_HEADERS = \ tbl/ban_vars.h \ tbl/body_status.h \ tbl/debug_bits.h \ + tbl/feature_bits.h \ tbl/http_headers.h \ tbl/http_response.h \ tbl/locks.h \ diff --git a/include/tbl/feature_bits.h b/include/tbl/feature_bits.h new file mode 100644 index 0000000..9d99449 --- /dev/null +++ b/include/tbl/feature_bits.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2012 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. + * + * Fields in the feature parameter + * + */ + +FEATURE_BIT(SHORT_PANIC, short_panic, "", + "Short panic message.", + "Reduce level of detail for panic messages." +) +FEATURE_BIT(WAIT_SILO, wait_silo, "", + "Wait for persistent silo.", + "Wait for persistent silos to load completely before serving requests." +) +FEATURE_BIT(NO_COREDUMP, no_coredump, "", + "No coredumps.", + "Don't attempt to coredump child process on panics." +) From phk at varnish-cache.org Tue Aug 28 08:21:58 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 10:21:58 +0200 Subject: [master] 13c8fed Slightly better coverage testing. Message-ID: commit 13c8fedd4bae89bda9c78670d0660213dcf8707f Author: Poul-Henning Kamp Date: Tue Aug 28 08:21:49 2012 +0000 Slightly better coverage testing. diff --git a/bin/varnishtest/tests/c00054.vtc b/bin/varnishtest/tests/c00054.vtc index d3a1072..266cc13 100644 --- a/bin/varnishtest/tests/c00054.vtc +++ b/bin/varnishtest/tests/c00054.vtc @@ -22,6 +22,9 @@ varnish v1 -clierr 106 {param.set vsl_mask \"} varnish v1 -cliok "param.set debug +workspace" varnish v1 -cliok "param.show debug" varnish v1 -cliok "param.show feature" +varnish v1 -cliok "param.set feature +short_panic" +varnish v1 -cliok "param.show feature" + client c1 { txreq From phk at varnish-cache.org Tue Aug 28 09:06:32 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 11:06:32 +0200 Subject: [master] a187a0a Elimiante diag_bitmaps and the mutex-profiling/measuring code. Message-ID: commit a187a0ad4f7552a65684649ffddd745c14c1c791 Author: Poul-Henning Kamp Date: Tue Aug 28 09:06:00 2012 +0000 Elimiante diag_bitmaps and the mutex-profiling/measuring code. XXX: doc-change needed. diff --git a/bin/varnishd/cache/cache_lck.c b/bin/varnishd/cache/cache_lck.c index 993bb5e..bd34046 100644 --- a/bin/varnishd/cache/cache_lck.c +++ b/bin/varnishd/cache/cache_lck.c @@ -37,7 +37,6 @@ #include -#include "vtim.h" #include "cache.h" /*The constability of lck depends on platform pthreads implementation */ @@ -48,7 +47,6 @@ struct ilck { pthread_mutex_t mtx; int held; pthread_t owner; - double t0; VTAILQ_ENTRY(ilck) list; const char *w; struct VSC_C_lck *stat; @@ -63,37 +61,13 @@ void __match_proto__() Lck__Lock(struct lock *lck, const char *p, const char *f, int l) { struct ilck *ilck; - int r; - double t0 = 0, t; + + (void)p; + (void)f; + (void)l; CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); - if (!(cache_param->diag_bitmap & 0x98)) { - AZ(pthread_mutex_lock(&ilck->mtx)); - AZ(ilck->held); - ilck->stat->locks++; - ilck->owner = pthread_self(); - ilck->held = 1; - return; - } - if (cache_param->diag_bitmap & 0x80) - t0 = VTIM_real(); - r = pthread_mutex_trylock(&ilck->mtx); - assert(r == 0 || r == EBUSY); - if (r) { - ilck->stat->colls++; - if (cache_param->diag_bitmap & 0x8) - VSL(SLT_Debug, 0, "MTX_CONTEST(%s,%s,%d,%s)", - p, f, l, ilck->w); - AZ(pthread_mutex_lock(&ilck->mtx)); - } else if (cache_param->diag_bitmap & 0x8) { - VSL(SLT_Debug, 0, "MTX_LOCK(%s,%s,%d,%s)", p, f, l, ilck->w); - } - if (cache_param->diag_bitmap & 0x80) { - t = VTIM_real(); - VSL(SLT_Debug, 0, "MTX_LOCKWAIT(%s,%s,%d,%s) %.9fs", - p, f, l, ilck->w, t - t0); - ilck->t0 = t; - } + AZ(pthread_mutex_lock(&ilck->mtx)); AZ(ilck->held); ilck->stat->locks++; ilck->owner = pthread_self(); @@ -105,6 +79,10 @@ Lck__Unlock(struct lock *lck, const char *p, const char *f, int l) { struct ilck *ilck; + (void)p; + (void)f; + (void)l; + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); assert(pthread_equal(ilck->owner, pthread_self())); AN(ilck->held); @@ -121,11 +99,6 @@ Lck__Unlock(struct lock *lck, const char *p, const char *f, int l) */ memset(&ilck->owner, 0, sizeof ilck->owner); AZ(pthread_mutex_unlock(&ilck->mtx)); - if (cache_param->diag_bitmap & 0x80) - VSL(SLT_Debug, 0, "MTX_UNLOCK(%s,%s,%d,%s) %.9fs", - p, f, l, ilck->w, VTIM_real() - ilck->t0); - else if (cache_param->diag_bitmap & 0x8) - VSL(SLT_Debug, 0, "MTX_UNLOCK(%s,%s,%d,%s)", p, f, l, ilck->w); } int __match_proto__() @@ -134,19 +107,18 @@ Lck__Trylock(struct lock *lck, const char *p, const char *f, int l) struct ilck *ilck; int r; + (void)p; + (void)f; + (void)l; + CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC); r = pthread_mutex_trylock(&ilck->mtx); assert(r == 0 || r == EBUSY); - if (cache_param->diag_bitmap & 0x8) - VSL(SLT_Debug, 0, - "MTX_TRYLOCK(%s,%s,%d,%s) = %d", p, f, l, ilck->w, r); if (r == 0) { AZ(ilck->held); ilck->held = 1; ilck->stat->locks++; ilck->owner = pthread_self(); - if (cache_param->diag_bitmap & 0x80) - ilck->t0 = VTIM_real(); } return (r); } diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h index 6abe0fc..7c1ccd5 100644 --- a/bin/varnishd/common/params.h +++ b/bin/varnishd/common/params.h @@ -155,9 +155,6 @@ struct params { /* CLI buffer size */ unsigned cli_buffer; - /* Control diagnostic code */ - unsigned diag_bitmap; - /* Log local socket address to shm */ unsigned log_local_addr; diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 434082e..b0631a3 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -579,22 +579,6 @@ tweak_waiter(struct cli *cli, const struct parspec *par, const char *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); - mgt_param.diag_bitmap = u; - } else { - VCLI_Out(cli, "0x%x", mgt_param.diag_bitmap); - } -} - -/*--------------------------------------------------------------------*/ - -static void tweak_poolparam(struct cli *cli, const struct parspec *par, const char *arg) { volatile struct poolparam *pp, px; @@ -1044,19 +1028,6 @@ static const struct parspec input_parspec[] = { "Select the waiter kernel interface.\n", WIZARD | MUST_RESTART, WAITER_DEFAULT, NULL }, - { "diag_bitmap", tweak_diag_bitmap, 0, 0, 0, - "Bitmap controlling diagnostics code:\n" - " 0x00000008 - mutex logging.\n" - " 0x00000010 - mutex contests.\n" - " 0x00000080 - mutex timing.\n" - "\n" - "Use 0x notation and do the bitor in your head :-)\n" - "\n" - "Note: Mutex timing will add extra overhead and " - "synchronization between threads, consequently changing the " - "locking characteristics.\n", - 0, - "0", "bitmap" }, { "ban_dups", tweak_bool, &mgt_param.ban_dups, 0, 0, "Detect and eliminate duplicate bans.\n", 0, diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc index b8dcbc8..1ce9b64 100644 --- a/bin/varnishtest/tests/b00008.vtc +++ b/bin/varnishtest/tests/b00008.vtc @@ -20,12 +20,6 @@ varnish v1 -clierr 105 "help 1 2 3" varnish v1 -cliok "param.show" -varnish v1 -cliok "param.show diag_bitmap" - -varnish v1 -cliok "param.set diag_bitmap 0x80" - -varnish v1 -cliok "param.set diag_bitmap 0x0" - varnish v1 -start varnish v1 -cliok "help" From phk at varnish-cache.org Tue Aug 28 09:09:36 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 11:09:36 +0200 Subject: [master] 132e912 eliminate unused VSC field Message-ID: commit 132e912d5b1aa06cdd38b915901ae118d1895ea5 Author: Poul-Henning Kamp Date: Tue Aug 28 09:09:24 2012 +0000 eliminate unused VSC field diff --git a/include/tbl/vsc_fields.h b/include/tbl/vsc_fields.h index ea70ffb..1ab16ff 100644 --- a/include/tbl/vsc_fields.h +++ b/include/tbl/vsc_fields.h @@ -73,10 +73,6 @@ VSC_F(locks, uint64_t, 0, 'a', "Lock Operations", "" ) -VSC_F(colls, uint64_t, 0, 'a', - "Collisions", - "" -) #endif From phk at varnish-cache.org Tue Aug 28 12:25:48 2012 From: phk at varnish-cache.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2012 14:25:48 +0200 Subject: [master] 57b4594 Don't overrun the VSL segment looking for the end. Message-ID: commit 57b4594c3ad86afc0f656943cf20070cb8d3af57 Author: Poul-Henning Kamp Date: Tue Aug 28 12:24:29 2012 +0000 Don't overrun the VSL segment looking for the end. diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c index cd6034d..da9e5df 100644 --- a/lib/libvarnishapi/vsl.c +++ b/lib/libvarnishapi/vsl.c @@ -139,9 +139,12 @@ vsl_open(struct VSM_data *vd) vsl->log_end = vsl->vf.e; vsl->log_ptr = vsl->log_start + 1; if (!vsl->d_opt) { - while (*vsl->log_ptr != VSL_ENDMARKER) + while (vsl->log_ptr < vsl->log_end && + *vsl->log_ptr != VSL_ENDMARKER) vsl->log_ptr = VSL_NEXT(vsl->log_ptr); } + if (vsl->log_ptr >= vsl->log_end) + vsl->log_ptr = vsl->log_start + 1; return (0); }