*/
static struct module_func_block cachedb_block = {
"cachedb",
- &cachedb_init, &cachedb_deinit, NULL, NULL, &cachedb_operate,
+ NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
};
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
- if(!modstack_startup(&daemon->mods, daemon->cfg->module_conf,
+ if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
fatal_exit("failed to startup modules");
}
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
+ if(daemon->mods_inited) {
+ modstack_call_deinit(&daemon->mods, daemon->env);
+ }
daemon->env->need_to_validate = 0; /* set by module init below */
- if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
+ if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
- fatal_exit("failed to setup modules");
+ fatal_exit("failed to init modules");
}
+ daemon->mods_inited = 1;
log_edns_known_options(VERB_ALGO, daemon->env);
}
size_t i;
if(!daemon)
return;
- modstack_desetup(&daemon->mods, daemon->env);
- modstack_destartup(&daemon->mods, daemon->env);
+ modstack_call_deinit(&daemon->mods, daemon->env);
+ modstack_call_destartup(&daemon->mods, daemon->env);
+ modstack_free(&daemon->mods);
daemon_remote_delete(daemon->rc);
for(i = 0; i < daemon->num_ports; i++)
listening_ports_free(daemon->ports[i]);
struct module_env* env;
/** stack of module callbacks */
struct module_stack mods;
+ /** The module stack has been inited */
+ int mods_inited;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** access control, which interfaces are allowed to connect */
*/
static struct module_func_block dns64_block = {
"dns64",
- &dns64_init, &dns64_deinit, NULL, NULL, &dns64_operate,
+ NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
&dns64_inform_super, &dns64_clear, &dns64_get_mem
};
*/
static struct module_func_block dynlibmod_block = {
"dynlib",
- &dynlibmod_init, &dynlibmod_deinit, NULL, NULL, &dynlibmod_operate,
+ NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate,
&dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem
};
*/
static struct module_func_block subnetmod_block = {
"subnetcache",
- &subnetmod_init, &subnetmod_deinit, NULL, NULL, &subnetmod_operate,
+ NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
};
*/
static struct module_func_block ipsecmod_block = {
"ipsecmod",
- &ipsecmod_init, &ipsecmod_deinit, NULL, NULL, &ipsecmod_operate,
+ NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
};
*/
static struct module_func_block ipset_block = {
"ipset",
- &ipset_init, &ipset_deinit, &ipset_startup, &ipset_destartup,
+ &ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit,
&ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem
};
*/
static struct module_func_block iter_block = {
"iterator",
- &iter_init, &iter_deinit, NULL, NULL, &iter_operate,
+ NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
&iter_inform_super, &iter_clear, &iter_get_mem
};
ctx->pipe_pid = getpid();
cfg_apply_local_port_policy(cfg, 65536);
config_apply(cfg);
- if(!modstack_startup(&ctx->mods, cfg->module_conf, ctx->env))
+ if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
- if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
+ if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
listen_setup_locks();
log_edns_known_options(VERB_ALGO, ctx->env);
int e = errno;
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
- modstack_desetup(&ctx->mods, ctx->env);
- modstack_destartup(&ctx->mods, ctx->env);
+ modstack_call_deinit(&ctx->mods, ctx->env);
+ modstack_call_destartup(&ctx->mods, ctx->env);
+ modstack_free(&ctx->mods);
listen_desetup_locks();
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
tube_delete(ctx->qq_pipe);
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
- modstack_desetup(&ctx->mods, ctx->env);
- modstack_destartup(&ctx->mods, ctx->env);
+ modstack_call_deinit(&ctx->mods, ctx->env);
+ modstack_call_destartup(&ctx->mods, ctx->env);
+ modstack_free(&ctx->mods);
listen_desetup_locks();
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
}
libworker_delete_event(ctx->event_worker);
- modstack_desetup(&ctx->mods, ctx->env);
- modstack_destartup(&ctx->mods, ctx->env);
+ modstack_call_deinit(&ctx->mods, ctx->env);
+ modstack_call_destartup(&ctx->mods, ctx->env);
+ modstack_free(&ctx->mods);
a = ctx->alloc_list;
while(a) {
na = a->super;
*/
static struct module_func_block pythonmod_block = {
"python",
- &pythonmod_init, &pythonmod_deinit, NULL, NULL, &pythonmod_operate,
+ NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate,
&pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem
};
*/
static struct module_func_block respip_block = {
"respip",
- &respip_init, &respip_deinit, NULL, NULL, &respip_operate,
+ NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
&respip_inform_super, &respip_clear, &respip_get_mem
};
stack->mod = NULL;
}
+void
+modstack_free(struct module_stack* stack)
+{
+ if(!stack)
+ return;
+ stack->num = 0;
+ free(stack->mod);
+ stack->mod = NULL;
+}
+
int
modstack_config(struct module_stack* stack, const char* module_conf)
{
}
int
-modstack_startup(struct module_stack* stack, const char* module_conf,
+modstack_call_startup(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
int i;
}
int
-modstack_setup(struct module_stack* stack, const char* module_conf,
+modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
- int i;
- if(stack->num != 0)
- modstack_desetup(stack, env);
+ int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
while(*module_conf && isspace(*module_conf))
module_conf++;
if(strncmp(stack->mod[i]->name, module_conf,
strlen(stack->mod[i]->name))) {
- log_err("changed module ordering during reload not supported");
- return 0;
+ if(stack->mod[i]->startup || stack->mod[i]->destartup) {
+ log_err("changed module ordering during reload not supported, for module that needs startup");
+ return 0;
+ } else {
+ changed = 1;
+ }
}
module_conf += strlen(stack->mod[i]->name);
+ }
+ if(changed) {
+ modstack_free(stack);
+ if(!modstack_config(stack, module_conf)) {
+ return 0;
+ }
+ }
+
+ for(i=0; i<stack->num; i++) {
verbose(VERB_OPS, "init module %d: %s",
i, stack->mod[i]->name);
fptr_ok(fptr_whitelist_mod_init(stack->mod[i]->init));
}
void
-modstack_desetup(struct module_stack* stack, struct module_env* env)
+modstack_call_deinit(struct module_stack* stack, struct module_env* env)
{
int i;
for(i=0; i<stack->num; i++) {
}
void
-modstack_destartup(struct module_stack* stack, struct module_env* env)
+modstack_call_destartup(struct module_stack* stack, struct module_env* env)
{
int i;
for(i=0; i<stack->num; i++) {
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
(*stack->mod[i]->destartup)(env, i);
}
- stack->num = 0;
- free(stack->mod);
- stack->mod = NULL;
}
int
void modstack_init(struct module_stack* stack);
/**
- * Initialises modules and assignes ids.
+ * Free the stack of modules
+ * @param stack: stack that frees up memory.
+ */
+void modstack_free(struct module_stack* stack);
+
+/**
+ * Initialises modules and assignes ids. Calls module_startup().
* @param stack: Expected empty, filled according to module_conf
* @param module_conf: string what modules to initialize
* @param env: module environment which is inited by the modules.
* environment should have a superalloc, cfg,
* @return on false a module init failed.
*/
-int modstack_startup(struct module_stack* stack, const char* module_conf,
+int modstack_call_startup(struct module_stack* stack, const char* module_conf,
struct module_env* env);
/**
* env.need_to_validate is set by the modules.
* @return on false a module init failed.
*/
-int modstack_setup(struct module_stack* stack, const char* module_conf,
+int modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env);
/**
- * Desetup the modules, deinit.
+ * Deinit the modules.
* @param stack: made empty.
* @param env: module env for module deinit() calls.
*/
-void modstack_desetup(struct module_stack* stack, struct module_env* env);
+void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
/**
* Destartup the modules, close, delete.
* @param stack: made empty.
* @param env: module env for module destartup() calls.
*/
-void modstack_destartup(struct module_stack* stack, struct module_env* env);
+void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
/**
* Find index of module by name.
if(!env.auth_zones)
fatal_exit("out of memory");
memset(&mods, 0, sizeof(mods));
- if(!modstack_startup(&mods, env.cfg->module_conf, &env))
+ if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
fatal_exit("could not modstack_startup");
- if(!modstack_setup(&mods, env.cfg->module_conf, &env))
+ if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
fatal_exit("could not modstack_call_init");
env.mesh = mesh_create(&mods, &env);
if(!env.mesh)
/* desetup test harness */
mesh_delete(env.mesh);
- modstack_desetup(&mods, &env);
- modstack_destartup(&mods, &env);
+ modstack_call_deinit(&mods, &env);
+ modstack_call_destartup(&mods, &env);
+ modstack_free(&mods);
auth_zones_delete(env.auth_zones);
anchors_delete(env.anchors);
config_delete(env.cfg);
const char* name;
/**
- * Initialise the module. Called when restarting or reloading the
- * daemon.
- * This is the place to apply settings from the config file.
+ * Set up the module for start. This is called only once at startup.
+ * Privileged operations like opening device files may be done here.
+ * The function ptr can be NULL, if it is not used.
* @param env: module environment.
* @param id: module id number.
* return: 0 on error
*/
- int (*init)(struct module_env* env, int id);
+ int (*startup)(struct module_env* env, int id);
/**
- * Deinitialise the module, undo stuff done during init().
- * Called before reloading the daemon.
+ * Close down the module for stop. This is called only once before
+ * shutdown to free resources allocated during startup().
+ * Closing privileged ports or files must be done here.
+ * The function ptr can be NULL, if it is not used.
* @param env: module environment.
* @param id: module id number.
*/
- void (*deinit)(struct module_env* env, int id);
+ void (*destartup)(struct module_env* env, int id);
/**
- * Set up the module for start. This is called only once at startup.
- * Privileged operations like opening device files may be done here.
- * The function ptr can be NULL, if it is not used.
+ * Initialise the module. Called when restarting or reloading the
+ * daemon.
+ * This is the place to apply settings from the config file.
* @param env: module environment.
* @param id: module id number.
* return: 0 on error
*/
- int (*startup)(struct module_env* env, int id);
+ int (*init)(struct module_env* env, int id);
/**
- * Close down the module for stop. This is called only once before
- * shutdown to free resources allocated during startup().
- * Closing privileged ports or files must be done here.
- * The function ptr can be NULL, if it is not used.
+ * Deinitialise the module, undo stuff done during init().
+ * Called before reloading the daemon.
* @param env: module environment.
* @param id: module id number.
*/
- void (*destartup)(struct module_env* env, int id);
+ void (*deinit)(struct module_env* env, int id);
/**
* accept a new query, or work further on existing query.
*/
static struct module_func_block val_block = {
"validator",
- &val_init, &val_deinit, NULL, NULL, &val_operate, &val_inform_super,
+ NULL, NULL, &val_init, &val_deinit, &val_operate, &val_inform_super,
&val_clear, &val_get_mem
};