From f344c66ea358c151a218e986173e60bb0295e003 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Mon, 26 Nov 2018 16:47:22 -0200 Subject: [PATCH] *: remove the configuration lock from all daemons A while ago all FRR configuration commands were converted to use the QOBJ infrastructure to keep track of configuration objects. This means the configuration lock isn't necessary anymore because the QOBJ code detects when someones tries to edit a configuration object that was deleted and react accordingly (log an error and abort the command). The possibility of accessing dangling pointers doesn't exist anymore since vty->index was removed. Summary of the changes: * remove the configuration lock and the vty_config_lockless() function. * rename vty_config_unlock() to vty_config_exit() since we need to clean up a few things when exiting from the configuration mode. * rename vty_config_lock() to vty_config_enter() to remove code duplication that existed between the three different "configuration" commands (terminal, private and exclusive). Configuration commands converted to the new northbound model don't need the configuration lock either since the northbound API also detects when someone tries to edit a configuration object that doesn't exist anymore. Signed-off-by: Renato Westphal --- bgpd/bgp_rpki.c | 2 +- isisd/isis_main.c | 1 - ldpd/ldpd.c | 1 - lib/command.c | 18 +++------------ lib/northbound_cli.c | 30 ++---------------------- lib/vty.c | 54 +++++++++++++++++++++----------------------- lib/vty.h | 12 +++++----- ripd/rip_main.c | 2 -- zebra/main.c | 1 - 9 files changed, 38 insertions(+), 83 deletions(-) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 77bd2eaefa..c5d38f3009 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1282,7 +1282,7 @@ DEFUN_NOSH (rpki_end, { int ret = reset(false); - vty_config_unlock(vty); + vty_config_exit(vty); vty->node = ENABLE_NODE; return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING; } diff --git a/isisd/isis_main.c b/isisd/isis_main.c index c325a3d6fe..2d540348e4 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -203,7 +203,6 @@ int main(int argc, char **argv, char **envp) } } - vty_config_lockless(); /* thread master */ master = frr_init(); diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 1280567f83..771d3b7459 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -335,7 +335,6 @@ main(int argc, char *argv[]) master = frr_init(); - vty_config_lockless(); vrf_init(NULL, NULL, NULL, NULL, NULL); access_list_init(); ldp_vty_init(); diff --git a/lib/command.c b/lib/command.c index bd000c3746..80ba86db37 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1386,19 +1386,7 @@ DEFUN (config_terminal, "Configuration from vty interface\n" "Configuration terminal\n") { - if (vty_config_lock(vty)) - vty->node = CONFIG_NODE; - else { - vty_out(vty, "VTY configuration is locked by other VTY\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - vty->private_config = false; - vty->candidate_config = vty_shared_candidate_config; - if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL) - vty->candidate_config_base = nb_config_dup(running_config); - - return CMD_SUCCESS; + return vty_config_enter(vty, false, false); } /* Enable command */ @@ -1450,7 +1438,7 @@ void cmd_exit(struct vty *vty) break; case CONFIG_NODE: vty->node = ENABLE_NODE; - vty_config_unlock(vty); + vty_config_exit(vty); break; case INTERFACE_NODE: case PW_NODE: @@ -1594,7 +1582,7 @@ DEFUN (config_end, case LINK_PARAMS_NODE: case BFD_NODE: case BFD_PEER_NODE: - vty_config_unlock(vty); + vty_config_exit(vty); vty->node = ENABLE_NODE; break; default: diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 8ae44e72d5..01f577fd5b 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -492,20 +492,7 @@ DEFUN (config_exclusive, "Configuration from vty interface\n" "Configure exclusively from this terminal\n") { - if (vty_config_exclusive_lock(vty)) - vty->node = CONFIG_NODE; - else { - vty_out(vty, "VTY configuration is locked by other VTY\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - vty->private_config = true; - vty->candidate_config = nb_config_dup(running_config); - vty->candidate_config_base = nb_config_dup(running_config); - vty_out(vty, - "Warning: uncommitted changes will be discarded on exit.\n\n"); - - return CMD_SUCCESS; + return vty_config_enter(vty, true, true); } /* Configure using a private candidate configuration. */ @@ -515,20 +502,7 @@ DEFUN (config_private, "Configuration from vty interface\n" "Configure using a private candidate configuration\n") { - if (vty_config_lock(vty)) - vty->node = CONFIG_NODE; - else { - vty_out(vty, "VTY configuration is locked by other VTY\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - vty->private_config = true; - vty->candidate_config = nb_config_dup(running_config); - vty->candidate_config_base = nb_config_dup(running_config); - vty_out(vty, - "Warning: uncommitted changes will be discarded on exit.\n\n"); - - return CMD_SUCCESS; + return vty_config_enter(vty, true, false); } DEFPY (config_commit, diff --git a/lib/vty.c b/lib/vty.c index 811c23c218..9908ada7f0 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -86,10 +86,6 @@ static vector Vvty_serv_thread; /* Current directory. */ char *vty_cwd = NULL; -/* Configure lock. */ -static int vty_config; -static int vty_config_is_lockless = 0; - /* Exclusive configuration lock. */ struct vty *vty_exclusive_lock; @@ -824,7 +820,7 @@ static void vty_end_config(struct vty *vty) case BGP_EVPN_VNI_NODE: case BFD_NODE: case BFD_PEER_NODE: - vty_config_unlock(vty); + vty_config_exit(vty); vty->node = ENABLE_NODE; break; default: @@ -1225,7 +1221,7 @@ static void vty_stop_input(struct vty *vty) case VTY_NODE: case BFD_NODE: case BFD_PEER_NODE: - vty_config_unlock(vty); + vty_config_exit(vty); vty->node = ENABLE_NODE; break; default: @@ -2351,7 +2347,7 @@ void vty_close(struct vty *vty) } /* Check configure. */ - vty_config_unlock(vty); + vty_config_exit(vty); /* OK free vty. */ XFREE(MTYPE_VTY, vty); @@ -2690,18 +2686,33 @@ void vty_log_fixed(char *buf, size_t len) } } -int vty_config_lock(struct vty *vty) +int vty_config_enter(struct vty *vty, bool private_config, bool exclusive) { - if (vty_config_is_lockless) - return 1; - if (vty_config == 0) { - vty->config = 1; - vty_config = 1; + if (exclusive && !vty_config_exclusive_lock(vty)) { + vty_out(vty, "VTY configuration is locked by other VTY\n"); + return CMD_WARNING; + } + + vty->node = CONFIG_NODE; + vty->config = true; + vty->private_config = private_config; + + if (private_config) { + vty->candidate_config = nb_config_dup(running_config); + vty->candidate_config_base = nb_config_dup(running_config); + vty_out(vty, + "Warning: uncommitted changes will be discarded on exit.\n\n"); + } else { + vty->candidate_config = vty_shared_candidate_config; + if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL) + vty->candidate_config_base = + nb_config_dup(running_config); } - return vty->config; + + return CMD_SUCCESS; } -int vty_config_unlock(struct vty *vty) +void vty_config_exit(struct vty *vty) { vty_config_exclusive_unlock(vty); @@ -2714,19 +2725,6 @@ int vty_config_unlock(struct vty *vty) nb_config_free(vty->candidate_config_base); vty->candidate_config_base = NULL; } - - if (vty_config_is_lockless) - return 0; - if (vty_config == 1 && vty->config == 1) { - vty->config = 0; - vty_config = 0; - } - return vty->config; -} - -void vty_config_lockless(void) -{ - vty_config_is_lockless = 1; } int vty_config_exclusive_lock(struct vty *vty) diff --git a/lib/vty.h b/lib/vty.h index 4c434fb2f2..39d63b4bac 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -102,6 +102,9 @@ struct vty { int xpath_index; char xpath[VTY_MAXDEPTH][XPATH_MAXLEN]; + /* In configure mode. */ + bool config; + /* Private candidate configuration mode. */ bool private_config; @@ -149,9 +152,6 @@ struct vty { /* Terminal monitor. */ int monitor; - /* In configure mode. */ - int config; - /* Read and write thread. */ struct thread *t_read; struct thread *t_write; @@ -299,9 +299,9 @@ extern void vty_close(struct vty *); extern char *vty_get_cwd(void); extern void vty_log(const char *level, const char *proto, const char *fmt, struct timestamp_control *, va_list); -extern int vty_config_lock(struct vty *); -extern int vty_config_unlock(struct vty *); -extern void vty_config_lockless(void); +extern int vty_config_enter(struct vty *vty, bool private_config, + bool exclusive); +extern void vty_config_exit(struct vty *); extern int vty_config_exclusive_lock(struct vty *vty); extern void vty_config_exclusive_unlock(struct vty *vty); extern int vty_shell(struct vty *); diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 4ee5994a9d..5db9c4b7e9 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -165,8 +165,6 @@ int main(int argc, char **argv) } } - vty_config_lockless(); - /* Prepare master thread. */ master = frr_init(); diff --git a/zebra/main.c b/zebra/main.c index 5628b5e022..95fe6f9fef 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -387,7 +387,6 @@ int main(int argc, char **argv) } } - vty_config_lockless(); zebrad.master = frr_init(); /* Zebra related initialize. */ -- 2.39.5