Commit b3690c63 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Make it possible for VCL initializtion to fail gracefully, particularly

so VMOD loading can emit sensible diagnostics.
parent bac89d86
......@@ -170,10 +170,15 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
FREE_OBJ(vcl);
return (1);
}
if (vcl->conf->init_vcl(cli)) {
VCLI_Out(cli, "VCL \"%s\" Failed to initialize", name);
(void)dlclose(vcl->dlh);
FREE_OBJ(vcl);
return (1);
}
REPLACE(vcl->name, name);
VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
vcl->conf->init_vcl(cli);
VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
(void)vcl->conf->init_func(NULL);
Lck_Lock(&vcl_mtx);
if (vcl_active == NULL)
......
......@@ -60,12 +60,12 @@ struct vmod {
static VTAILQ_HEAD(,vmod) vmods = VTAILQ_HEAD_INITIALIZER(vmods);
void
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
int
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
const char *path, struct cli *cli)
{
struct vmod *v;
void *x;
const int *i;
void *x, *y, *z;
ASSERT_CLI();
......@@ -76,31 +76,46 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
ALLOC_OBJ(v, VMOD_MAGIC);
AN(v);
VTAILQ_INSERT_TAIL(&vmods, v, list);
VSC_C_main->vmods++;
REPLACE(v->nm, nm);
REPLACE(v->path, path);
v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL);
if (! v->hdl) {
char buf[1024];
sprintf(buf, "dlopen failed (child process lacks permission?): %.512s", dlerror());
VAS_Fail(__func__, __FILE__, __LINE__, buf, 0, 0);
v->hdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (v->hdl == NULL) {
VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
VCLI_Out(cli, "Check child process permissions.\n");
FREE_OBJ(v);
return (1);
}
x = dlsym(v->hdl, "Vmod_Name");
y = dlsym(v->hdl, "Vmod_Len");
z = dlsym(v->hdl, "Vmod_Func");
if (x == NULL || y == NULL || z == NULL) {
VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(cli, "VMOD symbols not found\n");
VCLI_Out(cli, "Check relative pathnames.\n");
(void)dlclose(v->hdl);
FREE_OBJ(v);
return (1);
}
AN(x);
/* XXX: check that name is correct */
AN(y);
AN(z);
if (strcmp(x, nm)) {
VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", x);
VCLI_Out(cli, "Check relative pathnames ?.\n");
(void)dlclose(v->hdl);
FREE_OBJ(v);
return (1);
}
x = dlsym(v->hdl, "Vmod_Len");
AN(x);
i = x;
v->funclen = *i;
v->funclen = *(const int *)y;
v->funcs = z;
x = dlsym(v->hdl, "Vmod_Func");
AN(x);
v->funcs = x;
REPLACE(v->nm, nm);
REPLACE(v->path, path);
VSC_C_main->vmods++;
VTAILQ_INSERT_TAIL(&vmods, v, list);
}
assert(len == v->funclen);
......@@ -108,6 +123,7 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
v->ref++;
*hdl = v;
return (0);
}
void
......
......@@ -385,7 +385,7 @@ start_child(struct cli *cli)
mgt_cli_start_child(child_cli_in, child_VCLI_Out);
child_pid = pid;
if (mgt_push_vcls_and_start(&u, &p)) {
REPORT(LOG_ERR, "Pushing vcls failed: %s", p);
REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p);
free(p);
child_state = CH_RUNNING;
mgt_stop_child();
......
......@@ -183,8 +183,8 @@ void VRT_init_dir(struct cli *, struct director **, const char *name,
void VRT_fini_dir(struct cli *, struct director *);
/* VMOD/Modules related */
void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
const char *path);
int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
const char *path, struct cli *cli);
void VRT_Vmod_Fini(void **hdl);
struct vmod_priv;
......
......@@ -712,7 +712,7 @@ fo.write("""
struct sess;
struct cli;
typedef void vcl_init_f(struct cli *);
typedef int vcl_init_f(struct cli *);
typedef void vcl_fini_f(struct cli *);
typedef int vcl_func_f(struct sess *sp);
""")
......
......@@ -310,9 +310,10 @@ static void
EmitInitFunc(const struct vcc *tl)
{
Fc(tl, 0, "\nstatic void\nVGC_Init(struct cli *cli)\n{\n\n");
Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n");
AZ(VSB_finish(tl->fi));
VSB_cat(tl->fc, VSB_data(tl->fi));
Fc(tl, 0, "\treturn(0);\n");
Fc(tl, 0, "}\n");
}
......@@ -321,7 +322,7 @@ EmitFiniFunc(const struct vcc *tl)
{
unsigned u;
Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
Fc(tl, 0, "\nstatic int\nVGC_Fini(struct cli *cli)\n{\n\n");
/*
* We do this here, so we are sure they happen before any
......@@ -332,6 +333,7 @@ EmitFiniFunc(const struct vcc *tl)
AZ(VSB_finish(tl->ff));
VSB_cat(tl->fc, VSB_data(tl->ff));
Fc(tl, 0, "\treturn(0);\n");
Fc(tl, 0, "}\n");
}
......
......@@ -102,13 +102,15 @@ vcc_ParseImport(struct vcc *tl)
Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
Fi(tl, 0, "\tVRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
Fi(tl, 0, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
Fi(tl, 0, "\t &Vmod_Func_%.*s,\n", PF(mod));
Fi(tl, 0, "\t sizeof(Vmod_Func_%.*s),\n", PF(mod));
Fi(tl, 0, "\t \"%.*s\",\n", PF(mod));
Fi(tl, 0, "\t ");
EncString(tl->fi, fn, NULL, 0);
Fi(tl, 0, ");\n");
Fi(tl, 0, ",\n\t ");
Fi(tl, 0, "cli))\n");
Fi(tl, 0, "\t\treturn(1);\n");
SkipToken(tl, ';');
......
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