Commit 202417a5 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Don't put the cli in VRT_CTX, but give it a vsb for complaints

during initialization.

Use vmod_debug to test this.
parent b79f5293
......@@ -197,6 +197,8 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
struct VCL_conf const *cnf;
struct vrt_ctx ctx;
unsigned hand = 0;
struct vsb *vsb;
int i;
ASSERT_CLI();
......@@ -237,26 +239,39 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
INIT_OBJ(&ctx, VRT_CTX_MAGIC);
ctx.method = VCL_MET_INIT;
ctx.handling = &hand;
ctx.cli = cli;
ctx.vcl = vcl->conf;
if (vcl->conf->event_vcl(&ctx, VCL_EVENT_LOAD)) {
vsb = VSB_new_auto();
AN(vsb);
ctx.msg = vsb;
i = vcl->conf->event_vcl(&ctx, VCL_EVENT_LOAD);
AZ(VSB_finish(vsb));
if (i) {
VCLI_Out(cli, "VCL \"%s\" Failed to initialize", name);
if (VSB_len(vsb))
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_DISCARD));
(void)dlclose(vcl->dlh);
FREE_OBJ(vcl);
VSB_delete(vsb);
return (1);
}
VSB_clear(vsb);
(void)vcl->conf->init_func(&ctx);
AZ(VSB_finish(vsb));
if (hand == VCL_RET_FAIL) {
VCLI_Out(cli, "VCL \"%s\" vcl_init{} failed", name);
if (VSB_len(vsb))
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
ctx.method = VCL_MET_FINI;
(void)vcl->conf->fini_func(&ctx);
AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_DISCARD));
(void)dlclose(vcl->dlh);
FREE_OBJ(vcl);
VSB_delete(vsb);
return (1);
}
VSB_delete(vsb);
vcl_set_state(vcl, state);
assert(hand == VCL_RET_OK);
VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
......@@ -392,6 +407,8 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv)
struct vcls *vcl;
struct vrt_ctx ctx;
unsigned hand = 0;
struct vsb *vsb;
int i;
ASSERT_CLI();
AZ(priv);
......@@ -400,16 +417,23 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv)
AN(vcl->warm); // MGT ensures this
INIT_OBJ(&ctx, VRT_CTX_MAGIC);
ctx.handling = &hand;
ctx.cli = cli;
if (vcl->conf->event_vcl(&ctx, VCL_EVENT_USE)) {
vsb = VSB_new_auto();
AN(vsb);
ctx.msg = vsb;
i = vcl->conf->event_vcl(&ctx, VCL_EVENT_USE);
AZ(VSB_finish(vsb));
if (i) {
VCLI_Out(cli, "VCL \"%s\" Failed to activate", av[2]);
if (VSB_len(vsb) > 0)
VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
VCLI_SetResult(cli, CLIS_CANT);
return;
} else {
Lck_Lock(&vcl_mtx);
vcl_active = vcl;
Lck_Unlock(&vcl_mtx);
}
Lck_Lock(&vcl_mtx);
vcl_active = vcl;
Lck_Unlock(&vcl_mtx);
VSB_delete(vsb);
return;
}
static void __match_proto__(cli_func_t)
......
......@@ -72,15 +72,15 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
ASSERT_CLI();
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(ctx->cli);
AN(ctx->msg);
AN(hdl);
AZ(*hdl);
dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (dlhdl == NULL) {
VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(ctx->cli, "dlopen() failed: %s\n", dlerror());
VCLI_Out(ctx->cli, "Check child process permissions.\n");
VSB_printf(ctx->msg, "Loading VMOD %s from %s:\n", nm, path);
VSB_printf(ctx->msg, "dlopen() failed: %s\n", dlerror());
VSB_printf(ctx->msg, "Check child process permissions.\n");
return (1);
}
......@@ -98,9 +98,9 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
if (d == NULL ||
d->file_id == NULL ||
strcmp(d->file_id, file_id)) {
VCLI_Out(ctx->cli,
VSB_printf(ctx->msg,
"Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(ctx->cli,
VSB_printf(ctx->msg,
"This is no longer the same file seen by"
" the VCL-compiler.\n");
(void)dlclose(v->hdl);
......@@ -116,9 +116,9 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
d->proto == NULL ||
d->spec == NULL ||
d->abi == NULL) {
VCLI_Out(ctx->cli,
VSB_printf(ctx->msg,
"Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(ctx->cli, "VMOD data is mangled.\n");
VSB_printf(ctx->msg, "VMOD data is mangled.\n");
(void)dlclose(v->hdl);
FREE_OBJ(v);
return (1);
......
varnishtest "Test std & debug vmod"
server s1 {
rxreq
txresp
} -start
varnish v1 -vcl+backend { } -start
varnish v1 -errvcl "Planned failure in vcl_init" {
import ${vmod_debug};
backend default {
.host = "${s1_addr}";
}
sub vcl_init {
debug.init_fail();
return (fail);
}
}
client c1 {
txreq
rxresp
expect resp.status == 200
} -run
......@@ -54,7 +54,7 @@ struct busyobj;
struct vsl_log;
struct http;
struct ws;
struct cli;
struct vsb;
struct director;
struct VCL_conf;
struct suckaddr;
......@@ -93,7 +93,7 @@ struct vrt_ctx {
unsigned method;
unsigned *handling;
struct cli *cli; // Only in ...init()
struct vsb *msg; // Only in ...init()
struct vsl_log *vsl;
struct VCL_conf *vcl;
struct ws *ws;
......
......@@ -101,3 +101,7 @@ $Function INT vre_limit()
$Function VOID register_exp_callback(PRIV_VCL)
Register the vmod to receive expiry callbacks
$Function VOID init_fail()
Function to fail vcl_init{}
......@@ -34,6 +34,7 @@
#include "cache/cache.h"
#include "vrt.h"
#include "vsb.h"
#include "vcc_if.h"
struct priv_vcl {
......@@ -220,6 +221,14 @@ vmod_register_exp_callback(VRT_CTX, struct vmod_priv *priv)
VSL(SLT_Debug, 0, "exp_cb: registered");
}
VCL_VOID __match_proto__()
vmod_init_fail(VRT_CTX)
{
AN(ctx->msg);
VSB_printf(ctx->msg, "Planned failure in vcl_init{}");
}
static void __match_proto__(vmod_priv_free_f)
priv_vcl_free(void *priv)
{
......
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