From 52c0ab4af3ec152c4b78669acf8877ca27d66097 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 30 Oct 2019 10:29:43 -0400 Subject: Add subsys functions for receiving/flushing states and options. These functions are in the subsystem, not in the config_format_t, since they are about how the format is _used_, not about _what it is_. --- src/app/config/config.c | 3 +- src/app/config/statefile.c | 4 +++ src/app/main/subsysmgr.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ src/app/main/subsysmgr.h | 8 +++++ 4 files changed, 90 insertions(+), 1 deletion(-) (limited to 'src/app') diff --git a/src/app/config/config.c b/src/app/config/config.c index 7317a5d2f1..8929349709 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -987,7 +987,8 @@ set_options(or_options_t *new_val, char **msg) global_options = old_options; return -1; } - if (options_act(old_options) < 0) { /* acting on the options failed. die. */ + if (subsystems_set_options(get_options_mgr(), new_val) < 0 || + options_act(old_options) < 0) { /* acting on the options failed. die. */ if (! tor_event_loop_shutdown_is_pending()) { log_err(LD_BUG, "Acting on config options left us in a broken state. Dying."); diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index f6b0915da4..5fdb15ace1 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -316,6 +316,9 @@ or_state_set(or_state_t *new_state) tor_assert(new_state); config_free(get_state_mgr(), global_state); global_state = new_state; + if (subsystems_set_state(get_state_mgr(), global_state) < 0) { + ret = -1; + } if (entry_guards_parse_state(global_state, 1, &err)<0) { log_warn(LD_GENERAL,"%s",err); tor_free(err); @@ -519,6 +522,7 @@ or_state_save(time_t now) /* Call everything else that might dirty the state even more, in order * to avoid redundant writes. */ + (void) subsystems_flush_state(get_state_mgr(), global_state); entry_guards_update_state(global_state); rep_hist_update_state(global_state); circuit_build_times_update_state(get_circuit_build_times(), global_state); diff --git a/src/app/main/subsysmgr.c b/src/app/main/subsysmgr.c index e5c76b8e55..bd9af11444 100644 --- a/src/app/main/subsysmgr.c +++ b/src/app/main/subsysmgr.c @@ -334,3 +334,79 @@ subsystems_register_state_formats(config_mgr_t *mgr) } return 0; } + +/** + * Call all appropriate set_options() methods to tell the various subsystems + * about a new set of torrc options. Return 0 on success, -1 on + * nonrecoverable failure. + **/ +int +subsystems_set_options(const config_mgr_t *mgr, struct or_options_t *options) +{ + /* XXXX This does not yet handle reversible option assignment; I'll + * do that later in this branch. */ + + for (unsigned i = 0; i < n_tor_subsystems; ++i) { + const subsys_fns_t *sys = tor_subsystems[i]; + if (sys_status[i].options_idx >= 0 && sys->set_options) { + void *obj = config_mgr_get_obj_mutable(mgr, options, + sys_status[i].options_idx); + int rv = sys->set_options(obj); + if (rv < 0) { + log_err(LD_CONFIG, "Error when handling option for %s; " + "cannot proceed.", sys->name); + return -1; + } + } + } + return 0; +} + +/** + * Call all appropriate set_state() methods to tell the various subsystems + * about an initial DataDir/state file. Return 0 on success, -1 on + * nonrecoverable failure. + **/ +int +subsystems_set_state(const config_mgr_t *mgr, struct or_state_t *state) +{ + for (unsigned i = 0; i < n_tor_subsystems; ++i) { + const subsys_fns_t *sys = tor_subsystems[i]; + if (sys_status[i].state_idx >= 0 && sys->set_state) { + void *obj = config_mgr_get_obj_mutable(mgr, state, + sys_status[i].state_idx); + int rv = sys->set_state(obj); + if (rv < 0) { + log_err(LD_CONFIG, "Error when handling state for %s; " + "cannot proceed.", sys->name); + return -1; + } + } + } + return 0; +} + +/** + * Call all appropriate flush_state() methods to tell the various subsystems + * to update the state objects in state. Return 0 on success, + * -1 on failure. + **/ +int +subsystems_flush_state(const config_mgr_t *mgr, struct or_state_t *state) +{ + int result = 0; + for (unsigned i = 0; i < n_tor_subsystems; ++i) { + const subsys_fns_t *sys = tor_subsystems[i]; + if (sys_status[i].state_idx >= 0 && sys->flush_state) { + void *obj = config_mgr_get_obj_mutable(mgr, state, + sys_status[i].state_idx); + int rv = sys->flush_state(obj); + if (rv < 0) { + log_warn(LD_CONFIG, "Error when flushing state to state object for %s", + sys->name); + result = -1; + } + } + } + return result; +} diff --git a/src/app/main/subsysmgr.h b/src/app/main/subsysmgr.h index 54193f9649..7e5fe76362 100644 --- a/src/app/main/subsysmgr.h +++ b/src/app/main/subsysmgr.h @@ -34,5 +34,13 @@ void subsystems_thread_cleanup(void); struct config_mgr_t; int subsystems_register_options_formats(struct config_mgr_t *mgr); int subsystems_register_state_formats(struct config_mgr_t *mgr); +struct or_options_t; +struct or_state_t; +int subsystems_set_options(const struct config_mgr_t *mgr, + struct or_options_t *options); +int subsystems_set_state(const struct config_mgr_t *mgr, + struct or_state_t *state); +int subsystems_flush_state(const struct config_mgr_t *mgr, + struct or_state_t *state); #endif /* !defined(TOR_SUBSYSMGR_T) */ -- cgit v1.2.3-54-g00ecf