Commit 3c2d14c6 authored by Dridi Boukelmoune's avatar Dridi Boukelmoune Committed by Lasse Karstensen

Allow VMODs to fail a warm-up

It is also possible to convey a message to the CLI. In case of a failure
the VCL is cooled down. VCL_Load may now fail with either CLIS_PARAM or
CLIS_CANT.
parent 37abc301
...@@ -438,7 +438,7 @@ vcl_setup_event(VRT_CTX, enum vcl_event_e ev) ...@@ -438,7 +438,7 @@ vcl_setup_event(VRT_CTX, enum vcl_event_e ev)
assert(ev == VCL_EVENT_LOAD || ev == VCL_EVENT_WARM || assert(ev == VCL_EVENT_LOAD || ev == VCL_EVENT_WARM ||
ev == VCL_EVENT_USE); ev == VCL_EVENT_USE);
if (ev == VCL_EVENT_LOAD) if (ev != VCL_EVENT_USE)
AN(ctx->msg); AN(ctx->msg);
return (ctx->vcl->conf->event_vcl(ctx, ev)); return (ctx->vcl->conf->event_vcl(ctx, ev));
...@@ -457,14 +457,18 @@ vcl_failsafe_event(VRT_CTX, enum vcl_event_e ev) ...@@ -457,14 +457,18 @@ vcl_failsafe_event(VRT_CTX, enum vcl_event_e ev)
WRONG("A VMOD cannot fail COLD or DISCARD events"); WRONG("A VMOD cannot fail COLD or DISCARD events");
} }
static void static int
vcl_set_state(VRT_CTX, const char *state) vcl_set_state(VRT_CTX, const char *state)
{ {
struct vcl *vcl; struct vcl *vcl;
int i = 0;
ASSERT_CLI(); ASSERT_CLI();
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(ctx->handling); AN(ctx->handling);
AN(ctx->vcl);
AN(state);
assert(ctx->msg != NULL || *state == '0');
vcl = ctx->vcl; vcl = ctx->vcl;
AN(vcl->temp); AN(vcl->temp);
...@@ -494,16 +498,36 @@ vcl_set_state(VRT_CTX, const char *state) ...@@ -494,16 +498,36 @@ vcl_set_state(VRT_CTX, const char *state)
/* The VCL must first reach a stable cold state */ /* The VCL must first reach a stable cold state */
else if (vcl->temp != VCL_TEMP_COOLING) { else if (vcl->temp != VCL_TEMP_COOLING) {
vcl->temp = VCL_TEMP_WARM; vcl->temp = VCL_TEMP_WARM;
(void)vcl_setup_event(ctx, VCL_EVENT_WARM); i = vcl_setup_event(ctx, VCL_EVENT_WARM);
vcl_BackendEvent(vcl, VCL_EVENT_WARM); if (i == 0)
vcl_BackendEvent(vcl, VCL_EVENT_WARM);
else
AZ(vcl->conf->event_vcl(ctx, VCL_EVENT_COLD));
} }
break; break;
default: default:
WRONG("Wrong enum state"); WRONG("Wrong enum state");
} }
return (i);
} }
static int static void
vcl_cancel_load(VRT_CTX, struct cli *cli, const char *name, const char *step)
{
struct vcl *vcl = ctx->vcl;
AZ(VSB_finish(ctx->msg));
VCLI_SetResult(cli, CLIS_CANT);
VCLI_Out(cli, "VCL \"%s\" Failed %s", name, step);
if (VSB_len(ctx->msg))
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(ctx->msg));
AZ(vcl->conf->event_vcl(ctx, VCL_EVENT_DISCARD));
vcl_KillBackends(vcl);
VCL_Close(&vcl);
VSB_delete(ctx->msg);
}
static void
VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state) VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
{ {
struct vcl *vcl; struct vcl *vcl;
...@@ -516,8 +540,9 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state) ...@@ -516,8 +540,9 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
vcl = vcl_find(name); vcl = vcl_find(name);
if (vcl != NULL) { if (vcl != NULL) {
VCLI_SetResult(cli, CLIS_PARAM);
VCLI_Out(cli, "Config '%s' already loaded", name); VCLI_Out(cli, "Config '%s' already loaded", name);
return (1); return;
} }
vsb = VSB_new_auto(); vsb = VSB_new_auto();
...@@ -526,9 +551,10 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state) ...@@ -526,9 +551,10 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
vcl = VCL_Open(fn, vsb); vcl = VCL_Open(fn, vsb);
if (vcl == NULL) { if (vcl == NULL) {
AZ(VSB_finish(vsb)); AZ(VSB_finish(vsb));
VCLI_SetResult(cli, CLIS_PARAM);
VCLI_Out(cli, "%s", VSB_data(vsb)); VCLI_Out(cli, "%s", VSB_data(vsb));
VSB_delete(vsb); VSB_delete(vsb);
return (1); return;
} }
vcl->loaded_name = strdup(name); vcl->loaded_name = strdup(name);
...@@ -545,19 +571,18 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state) ...@@ -545,19 +571,18 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
VSB_clear(vsb); VSB_clear(vsb);
ctx.msg = vsb; ctx.msg = vsb;
i = vcl_setup_event(&ctx, VCL_EVENT_LOAD); i = vcl_setup_event(&ctx, VCL_EVENT_LOAD);
AZ(VSB_finish(vsb));
if (i) { if (i) {
VCLI_Out(cli, "VCL \"%s\" Failed initialization", name); vcl_cancel_load(&ctx, cli, name, "initialization");
if (VSB_len(vsb)) return;
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb)); }
vcl_failsafe_event(&ctx, VCL_EVENT_DISCARD); VSB_clear(vsb);
vcl_KillBackends(vcl); i = vcl_set_state(&ctx, state);
VCL_Close(&vcl); if (i) {
VSB_delete(vsb); assert(*state == '1');
return (1); vcl_cancel_load(&ctx, cli, name, "warmup");
return;
} }
VSB_delete(vsb); VSB_delete(vsb);
vcl_set_state(&ctx, state);
bprintf(vcl->state, "%s", state + 1); bprintf(vcl->state, "%s", state + 1);
assert(hand == VCL_RET_OK); assert(hand == VCL_RET_OK);
VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name); VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
...@@ -568,7 +593,6 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state) ...@@ -568,7 +593,6 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
Lck_Unlock(&vcl_mtx); Lck_Unlock(&vcl_mtx);
VSC_C_main->n_vcl++; VSC_C_main->n_vcl++;
VSC_C_main->n_vcl_avail++; VSC_C_main->n_vcl_avail++;
return (0);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -616,7 +640,7 @@ VCL_Poll(void) ...@@ -616,7 +640,7 @@ VCL_Poll(void)
INIT_OBJ(&ctx, VRT_CTX_MAGIC); INIT_OBJ(&ctx, VRT_CTX_MAGIC);
ctx.vcl = vcl; ctx.vcl = vcl;
ctx.handling = &hand; ctx.handling = &hand;
vcl_set_state(&ctx, "0"); (void)vcl_set_state(&ctx, "0");
} }
if (vcl->discard && vcl->temp == VCL_TEMP_COLD) if (vcl->discard && vcl->temp == VCL_TEMP_COLD)
VCL_Nuke(vcl); VCL_Nuke(vcl);
...@@ -652,8 +676,7 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv) ...@@ -652,8 +676,7 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv)
AZ(priv); AZ(priv);
ASSERT_CLI(); ASSERT_CLI();
if (VCL_Load(cli, av[2], av[3], av[4])) VCL_Load(cli, av[2], av[3], av[4]);
VCLI_SetResult(cli, CLIS_PARAM);
} }
static void __match_proto__(cli_func_t) static void __match_proto__(cli_func_t)
...@@ -663,6 +686,8 @@ ccf_config_state(struct cli *cli, const char * const *av, void *priv) ...@@ -663,6 +686,8 @@ ccf_config_state(struct cli *cli, const char * const *av, void *priv)
unsigned hand; unsigned hand;
INIT_OBJ(&ctx, VRT_CTX_MAGIC); INIT_OBJ(&ctx, VRT_CTX_MAGIC);
ctx.msg = VSB_new_auto();
AN(ctx.msg);
ctx.handling = &hand; ctx.handling = &hand;
(void)cli; (void)cli;
...@@ -672,8 +697,18 @@ ccf_config_state(struct cli *cli, const char * const *av, void *priv) ...@@ -672,8 +697,18 @@ ccf_config_state(struct cli *cli, const char * const *av, void *priv)
AN(av[3]); AN(av[3]);
ctx.vcl = vcl_find(av[2]); ctx.vcl = vcl_find(av[2]);
AN(ctx.vcl); // MGT ensures this AN(ctx.vcl); // MGT ensures this
vcl_set_state(&ctx, av[3]); if (vcl_set_state(&ctx, av[3]) == 0) {
bprintf(ctx.vcl->state, "%s", av[3] + 1); bprintf(ctx.vcl->state, "%s", av[3] + 1);
VSB_delete(ctx.msg);
return;
}
AZ(VSB_finish(ctx.msg));
VCLI_SetResult(cli, CLIS_CANT);
VCLI_Out(cli, "Failed <vcl.state %s %s>", ctx.vcl->loaded_name,
av[3] + 1);
if (VSB_len(ctx.msg))
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(ctx.msg));
VSB_delete(ctx.msg);
} }
static void __match_proto__(cli_func_t) static void __match_proto__(cli_func_t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment