[PATCH 2/4] Add a BAN_Shutdown() routine that is called before STV_Close(), and makes sure that the ban lists will not change until we exit.
Martin Blix Grydeland
martin at varnish-software.com
Wed Nov 21 11:23:17 CET 2012
This is to give persistent stevedores a chance to clean up their ban
lists without having to worry about the lists changing under them.
---
bin/varnishd/cache/cache.h | 3 +-
bin/varnishd/cache/cache_ban.c | 66 ++++++++++++++++++++++++++++++++++++---
bin/varnishd/cache/cache_main.c | 1 +
bin/varnishd/cache/cache_vrt.c | 10 +++---
4 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 727073b..2571f89 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -746,8 +746,9 @@ struct ban *BAN_New(void);
int BAN_AddTest(struct cli *, struct ban *, const char *, const char *,
const char *);
void BAN_Free(struct ban *b);
-void BAN_Insert(struct ban *b);
+int BAN_Insert(struct ban *b);
void BAN_Init(void);
+void BAN_Shutdown(void);
void BAN_NewObjCore(struct objcore *oc);
void BAN_DestroyObj(struct objcore *oc);
int BAN_CheckObject(struct object *o, struct req *sp);
diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c
index 47a8518..66369d8 100644
--- a/bin/varnishd/cache/cache_ban.c
+++ b/bin/varnishd/cache/cache_ban.c
@@ -105,6 +105,7 @@ static struct ban *ban_magic;
static pthread_t ban_thread;
static struct ban * volatile ban_start;
static bgthread_t ban_lurker;
+static int ban_shutdown = 0;
/*--------------------------------------------------------------------
* BAN string defines & magic markers
@@ -406,9 +407,14 @@ BAN_AddTest(struct cli *cli, struct ban *b, const char *a1, const char *a2,
* as a separate variable from the VTAILQ, to avoid depending on the
* internals of the VTAILQ macros. We tacitly assume that a pointer
* write is always atomic in doing so.
+ *
+ * Returns:
+ * 0: Ban successfully inserted
+ * -1: Ban not inserted due to shutdown in progress. The ban has been
+ * deleted.
*/
-void
+int
BAN_Insert(struct ban *b)
{
struct ban *bi, *be;
@@ -417,6 +423,11 @@ BAN_Insert(struct ban *b)
CHECK_OBJ_NOTNULL(b, BAN_MAGIC);
+ if (ban_shutdown) {
+ BAN_Free(b);
+ return (-1);
+ }
+
AZ(VSB_finish(b->vsb));
ln = VSB_len(b->vsb);
assert(ln >= 0);
@@ -435,6 +446,12 @@ BAN_Insert(struct ban *b)
b->vsb = NULL;
Lck_Lock(&ban_mtx);
+ if (ban_shutdown) {
+ /* Check again, we might have raced */
+ Lck_Unlock(&ban_mtx);
+ BAN_Free(b);
+ return (-1);
+ }
VTAILQ_INSERT_HEAD(&ban_head, b, list);
ban_start = b;
VSC_C_main->bans++;
@@ -452,12 +469,12 @@ BAN_Insert(struct ban *b)
Lck_Unlock(&ban_mtx);
if (be == NULL)
- return;
+ return (0);
/* Hunt down duplicates, and mark them as gone */
bi = b;
Lck_Lock(&ban_mtx);
- while(bi != be) {
+ while(!ban_shutdown && bi != be) {
bi = VTAILQ_NEXT(bi, list);
if (bi->flags & BAN_F_GONE)
continue;
@@ -468,6 +485,8 @@ BAN_Insert(struct ban *b)
}
be->refcount--;
Lck_Unlock(&ban_mtx);
+
+ return (0);
}
/*--------------------------------------------------------------------
@@ -551,6 +570,7 @@ BAN_Reload(const uint8_t *ban, unsigned len)
double t0, t1, t2 = 9e99;
ASSERT_CLI();
+ AZ(ban_shutdown);
t0 = ban_time(ban);
assert(len == ban_len(ban));
@@ -628,6 +648,7 @@ BAN_Compile(void)
{
ASSERT_CLI();
+ AZ(ban_shutdown);
/* Notify stevedores */
STV_BanInfo(BI_NEW, ban_magic->spec, ban_len(ban_magic->spec));
@@ -874,6 +895,8 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass)
ban_time(b->spec), b->refcount);
while (1) {
Lck_Lock(&ban_mtx);
+ if (ban_shutdown)
+ break;
oc = VTAILQ_FIRST(&b->objcore);
if (oc == NULL)
break;
@@ -957,6 +980,8 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, unsigned pass)
ban_time(b->spec));
}
Lck_Unlock(&ban_mtx);
+ if (ban_shutdown)
+ break;
VTIM_sleep(cache_param->ban_lurker_sleep);
if (b == b0)
break;
@@ -975,7 +1000,7 @@ ban_lurker(struct worker *wrk, void *priv)
VSL_Setup(&vsl, NULL, 0);
(void)priv;
- while (1) {
+ while (!ban_shutdown) {
ban_sleep = 1.0;
/* Clear any gone last bans */
@@ -1004,8 +1029,14 @@ ban_lurker(struct worker *wrk, void *priv)
WRK_SumStat(wrk);
}
+ if (ban_shutdown)
+ break;
+
VTIM_sleep(ban_sleep);
}
+
+ pthread_exit(0);
+
NEEDLESS_RETURN(NULL);
}
@@ -1048,7 +1079,11 @@ ccf_ban(struct cli *cli, const char * const *av, void *priv)
BAN_Free(b);
return;
}
- BAN_Insert(b);
+ if (BAN_Insert(b) < 0) {
+ VCLI_Out(cli, "Shutdown in progress");
+ VCLI_SetResult(cli, CLIS_CANT);
+ return;
+ }
}
static void
@@ -1160,3 +1195,24 @@ BAN_Init(void)
VSC_C_main->bans_gone++;
BAN_Insert(ban_magic);
}
+
+/*--------------------------------------------------------------------
+ * Shutdown of the ban system.
+ *
+ * When this function returns, no new bans will be accepted, and no
+ * bans will be dropped (ban lurker thread stopped), so that no
+ * STV_BanInfo calls will be executed.
+ */
+
+void
+BAN_Shutdown(void)
+{
+ void *status;
+
+ Lck_Lock(&ban_mtx);
+ ban_shutdown = 1;
+ Lck_Unlock(&ban_mtx);
+
+ AZ(pthread_join(ban_thread, &status));
+ AZ(status);
+}
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 468401b..13c6612 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -232,6 +232,7 @@ child_main(void)
CLI_Run();
+ BAN_Shutdown();
STV_close();
printf("Child dies\n");
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index ed7ae59..914531e 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -459,10 +459,9 @@ VRT_ban(const struct req *req, char *cmds, ...)
good = 1;
}
if (!good)
- /* XXX: report error how ? */
- BAN_Free(b);
+ BAN_Free(b); /* XXX: report error how ? */
else
- BAN_Insert(b);
+ (void)BAN_Insert(b); /* XXX: report error how ? */
}
/*--------------------------------------------------------------------*/
@@ -506,10 +505,9 @@ VRT_ban_string(const struct req *req, const char *str)
break;
}
if (!good)
- /* XXX: report error how ? */
- BAN_Free(b);
+ BAN_Free(b); /* XXX: report error how ? */
else
- BAN_Insert(b);
+ (void)BAN_Insert(b); /* XXX: report error how ? */
VAV_Free(av);
}
--
1.7.9.5
More information about the varnish-dev
mailing list