diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 8dd041a2..cfc5091e 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -9,7 +9,12 @@ static uint32_t hook_prio = CB_PRIO_PASSIVE; static int num_changes; static int cur_change; -static int startup_save_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module, +uint32_t core_hook_prio(void) +{ + return hook_prio--; +} + +int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { if (systemf("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) @@ -18,11 +23,6 @@ static int startup_save_hook(sr_session_ctx_t *session, uint32_t sub_id, const c return SR_ERR_OK; } -uint32_t core_hook_prio(void) -{ - return hook_prio--; -} - /* * Run on UPDATE to see how many modules have changes in the inbound changeset * Run on DONE, after the last module callback has run, to activate changes. @@ -66,7 +66,6 @@ static const struct srx_module_requirement core_reqs[] = { int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) { - sr_session_ctx_t *startup; int rc = SR_ERR_SYS; openlog("confd", LOG_USER, 0); @@ -80,6 +79,11 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) if (!confd.conn) goto err; + /* The startup datastore is used for the core_startup_save() hook */ + rc = sr_session_start(confd.conn, SR_DS_STARTUP, &confd.startup); + if (rc) + goto err; + confd.aug = aug_init(NULL, "", 0); if (!confd.aug) goto err; @@ -93,18 +97,6 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) /* YOUR_INIT GOES HERE */ - /* Set up hook to save startup-config to persistent backend store */ - rc = sr_session_start(confd.conn, SR_DS_STARTUP, &startup); - if (rc) - goto err; - - rc = sr_module_change_subscribe(startup, "ietf-system", "/ietf-system:system//.", - startup_save_hook, NULL, CB_PRIO_PASSIVE, SR_SUBSCR_PASSIVE | SR_SUBSCR_DONE_ONLY, &confd.sub); - if (rc) { - ERROR("failed setting up startup-config hook: %s", sr_strerror(rc)); - goto err; - } - rc = srx_require_modules(confd.conn, core_reqs); if (rc) goto err; diff --git a/src/confd/src/core.h b/src/confd/src/core.h index b0970268..2e913fa3 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -62,7 +62,8 @@ static inline void print_val(sr_val_t *val) goto fail struct confd { - sr_session_ctx_t *session; + sr_session_ctx_t *session; /* running datastore */ + sr_session_ctx_t *startup; /* startup datastore */ sr_conn_ctx_t *conn; sr_subscription_ctx_t *sub; @@ -70,23 +71,39 @@ struct confd { struct dagger netdag; }; -uint32_t core_hook_prio(void); - -int core_commit_done(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *xpath, sr_event_t event, unsigned request_id, void *priv); +uint32_t core_hook_prio (void); +int core_commit_done (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *); +int core_startup_save (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *); static inline int register_change(sr_session_ctx_t *session, const char *module, const char *xpath, int flags, sr_module_change_cb cb, void *arg, sr_subscription_ctx_t **sub) { int hook_flags = SR_SUBSCR_UPDATE | SR_SUBSCR_DONE_ONLY | SR_SUBSCR_PASSIVE; - int rc = sr_module_change_subscribe(session, module, xpath, cb, arg, + struct confd *confd = (struct confd *)arg; + int rc; + + rc = sr_module_change_subscribe(session, module, xpath, cb, arg, CB_PRIO_PRIMARY, flags | SR_SUBSCR_DEFAULT, sub); - if (rc) + if (rc) { ERROR("failed subscribing to changes of %s: %s", xpath, sr_strerror(rc)); - else if (!flags) - sr_module_change_subscribe(session, module, xpath, core_commit_done, NULL, + return rc; + } + + /* + * For standard subscribtions we hook into the callback chain + * for all modules to figure out, per changeset, which of the + * callbacks is the last one. This is where we want to call the + * global commit-done hook for candidate -> running changes and + * the startup-save hook for running -> startup copying. + */ + if (!flags) { + sr_module_change_subscribe(confd->session, module, xpath, core_commit_done, NULL, core_hook_prio(), hook_flags, sub); - return rc; + sr_module_change_subscribe(confd->startup, module, xpath, core_startup_save, NULL, + core_hook_prio(), hook_flags, sub); + } + + return 0; } static inline int register_oper(sr_session_ctx_t *session, const char *module, const char *xpath,