diff options
Diffstat (limited to 'nest/proto.c')
-rw-r--r-- | nest/proto.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/nest/proto.c b/nest/proto.c index d4a333d0..415471c4 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -874,6 +874,28 @@ proto_copy_config(struct proto_config *dest, struct proto_config *src) dest->protocol->copy_config(dest, src); } +void +proto_clone_config(struct symbol *sym, struct proto_config *parent) +{ + struct proto_config *cf = proto_config_new(parent->protocol, SYM_PROTO); + proto_copy_config(cf, parent); + cf->name = sym->name; + cf->proto = NULL; + cf->parent = parent; + + sym->class = cf->class; + sym->def = cf; +} + +static void +proto_undef_clone(struct symbol *sym, struct proto_config *cf) +{ + rem_node(&cf->n); + + sym->class = SYM_VOID; + sym->def = NULL; +} + /** * protos_preconfig - pre-configuration processing * @c: new configuration @@ -973,6 +995,24 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty { p = oc->proto; sym = cf_find_symbol(new, oc->name); + + /* Handle dynamic protocols */ + if (!sym && oc->parent && !new->shutdown) + { + struct symbol *parsym = cf_find_symbol(new, oc->parent->name); + if (parsym && parsym->class == SYM_PROTO) + { + /* This is hack, we would like to share config, but we need to copy it now */ + new_config = new; + cfg_mem = new->mem; + conf_this_scope = new->root_scope; + sym = cf_get_symbol(oc->name); + proto_clone_config(sym, parsym->def); + new_config = NULL; + cfg_mem = NULL; + } + } + if (sym && sym->class == SYM_PROTO && !new->shutdown) { /* Found match, let's check if we can smoothly switch to new configuration */ @@ -984,6 +1024,12 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty if (! force_reconfig && proto_reconfigure(p, oc, nc, type)) continue; + if (nc->parent) + { + proto_undef_clone(sym, nc); + goto remove; + } + /* Unsuccessful, we will restart it */ if (!p->disabled && !nc->disabled) log(L_INFO "Restarting protocol %s", p->name); @@ -997,6 +1043,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty } else if (!new->shutdown) { + remove: log(L_INFO "Removing protocol %s", p->name); p->down_code = PDC_CF_REMOVE; p->cf_new = NULL; @@ -1105,6 +1152,15 @@ proto_rethink_goal(struct proto *p) } } +struct proto * +proto_spawn(struct proto_config *cf, uint disabled) +{ + struct proto *p = proto_init(cf, TAIL(proto_list)); + p->disabled = disabled; + proto_rethink_goal(p); + return p; +} + /** * DOC: Graceful restart recovery |