This implements a new return value from vcl_hit called nuke. of Implement nuke option to invalidate all variants
vary-ants of object (per suggestion from phk), so future lookups won"t find it, instead on an object existing. Logs and update stats. Should be completely harmless to people who don"t use it :)
NUL */ + sp->ihashptr = 0; + sp->nhashptr = sp->vcl->nhashcount * 2; + p = WS_Alloc(sp->http->ws, + sizeof(const char *) * (sp->nhashptr + 1)); + XXXAN(p); + /* Align pointer properly (?) */ + u = (uintptr_t)p; + u &= sizeof(const char *) - 1; + if (u) + p += sizeof(const char *) - u; + sp->hashptr = (void*)p; + + } + + const char *curpos; + const char *startpos; + startpos = hash; + int partlen = 0; + + for(curpos = hash; *curpos; curpos++) { + if (*curpos == "\0") + break; + if (*curpos == "#") { + sp->hashptr[sp->ihashptr] = startpos; + sp->hashptr[sp->ihashptr+1] = startpos + partlen; + sp->ihashptr +=2; + sp->lhashptr += partlen + 1; + partlen = 0; + startpos = curpos + 1; + continue; + } + partlen++; + } + + struct objhead *oh = heritage.hash->lookup(sp, NULL); + if(oh) { + WSP(sp, SLT_Nuke_success, "%s", oh->hash); + VSL_stats->nuke_success++; + LOCK(&oh->mtx); + oh->hash[0] = "\n"; + UNLOCK(&oh->mtx); + heritage.hash->deref(oh); + } else { + VSL_stats->nuke_fail++; + WSP(sp, SLT_Nuke_fail, "%s", hash); + } + + sp->lhashptr = tmp_lhashptr; + sp->ihashptr = tmp_ihashptr; + sp->hashptr = tmp_p; +} + + /*-------------------------------------------------------------------- * Simple stuff */ Index: lib/libvcl/vcc_action.c =================================================================== --- lib/libvcl/vcc_action.c (revision 2877) +++ lib/libvcl/vcc_action.c (working copy) @@ -353,6 +353,29 @@ /*--------------------------------------------------------------------*/ +static void +parse_nuke(struct tokenlist *tl) +{ + vcc_NextToken(tl); + + Fb(tl, 1, "VRT_nuke(sp,"); + + Expect(tl, "("); + vcc_NextToken(tl); + + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + return; + } + + Expect(tl, ")"); + vcc_NextToken(tl); + Fb(tl, 0, ");\n"); + +} + +/*--------------------------------------------------------------------*/ + typedef void action_f(struct tokenlist *tl); static struct action_table { @@ -372,6 +395,7 @@ { "purge_url", parse_purge_url }, { "purge_hash", parse_purge_hash }, { "esi", parse_esi }, + { "nuke", parse_nuke }, { NULL, NULL } }; Index: include/stat_field.h =================================================================== --- include/stat_field.h (revision 2877) +++ include/stat_field.h (working copy) @@ -105,3 +105,6 @@ MAC_STAT(sma_bfree, uint64_t, "i", "SMA bytes free") MAC_STAT(backend_req, uint64_t, "a", "Backend requests made") + +MAC_STAT(nuke_success, uint64_t, "a", "Nukes succeeded") +MAC_STAT(nuke_fail, uint64_t, "a", "Nukes failed") Index: include/shmlog_tags.h =================================================================== --- include/shmlog_tags.h (revision 2877) +++ include/shmlog_tags.h (working copy) @@ -99,3 +99,7 @@ SLTM(ESI_xmlerror) SLTM(Hash) + +SLTM(Nuke_success) +SLTM(Nuke_fail) + a -bash-3.1$ svn diff Index: include/vcl_returns.h =================================================================== --- include/vcl_returns.h (revision 2871) +++ include/vcl_returns.h (working copy) @@ -20,6 +20,7 @@ VCL_RET_MAC(discard, DISCARD, (1 << 8), 8) VCL_RET_MAC(keep, KEEP, (1 << 9), 9) VCL_RET_MAC(restart, RESTART, (1 << 10), 10) +VCL_RET_MAC(nuke, NUKE, (1 << 11), 11) #else #define VCL_RET_ERROR (1 << 0) #define VCL_RET_LOOKUP (1 << 1) @@ -32,7 +33,8 @@ #define VCL_RET_DISCARD (1 << 8) #define VCL_RET_KEEP (1 << 9) #define VCL_RET_RESTART (1 << 10) -#define VCL_RET_MAX 11 +#define VCL_RET_NUKE (1 << 11) +#define VCL_RET_MAX 12 #endif #ifdef VCL_MET_MAC @@ -41,7 +43,7 @@ VCL_MET_MAC(pass,PASS,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS)) VCL_MET_MAC(hash,HASH,(VCL_RET_HASH)) VCL_MET_MAC(miss,MISS,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_FETCH)) -VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER)) +VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_DELIVER|VCL_RET_NUKE)) VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_PASS|VCL_RET_INSERT)) VCL_MET_MAC(deliver,DELIVER,(VCL_RET_ERROR|VCL_RET_RESTART|VCL_RET_DELIVER)) VCL_MET_MAC(prefetch,PREFETCH,(VCL_RET_FETCH|VCL_RET_PASS)) Index: lib/libvcl/vcc_gen_fixed_token.tcl =================================================================== --- lib/libvcl/vcc_gen_fixed_token.tcl (revision 2871) +++ lib/libvcl/vcc_gen_fixed_token.tcl (working copy) @@ -39,7 +39,7 @@ {pass {error restart pass}} {hash {hash}} {miss {error restart pass fetch}} - {hit {error restart pass deliver}} + {hit {error restart pass deliver nuke}} {fetch {error restart pass insert}} {deliver {error restart deliver}} {prefetch {fetch pass}} @@ -61,6 +61,7 @@ discard keep restart + nuke } # Language keywords Index: lib/libvcl/vcc_fixed_token.c =================================================================== --- lib/libvcl/vcc_fixed_token.c (revision 2871) +++ lib/libvcl/vcc_fixed_token.c (working copy) @@ -303,6 +303,7 @@ vsb_cat(sb, "#define VCL_RET_DISCARD (1 << 8)\n"); vsb_cat(sb, "#define VCL_RET_KEEP (1 << 9)\n"); vsb_cat(sb, "#define VCL_RET_RESTART (1 << 10)\n"); + vsb_cat(sb, "#define VCL_RET_NUKE (1 << 11)\n"); vsb_cat(sb, "/*\n"); vsb_cat(sb, " * $Id$\n"); vsb_cat(sb, " *\n"); Index: bin/varnishd/cache_center.c =================================================================== --- bin/varnishd/cache_center.c (revision 2871) +++ bin/varnishd/cache_center.c (working copy) @@ -491,6 +491,18 @@ return (0); } + if (sp->handling == VCL_RET_NUKE) { + /* kill all versions for find and lock all objects */ + LOCK(&sp->obj->objhead->mtx); + sp->obj->objhead->hash[0] = "\n"; + UNLOCK(&sp->obj->objhead->mtx); + sp->handling = VCL_RET_PASS; + } + + /* Drop our object, we won"t need it */ HSH_Deref(sp->obj); sp->obj = NULL;