*: 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 <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2018-11-26 16:47:22 -02:00
parent 98d8359fe7
commit f344c66ea3
9 changed files with 38 additions and 83 deletions

View File

@ -1282,7 +1282,7 @@ DEFUN_NOSH (rpki_end,
{ {
int ret = reset(false); int ret = reset(false);
vty_config_unlock(vty); vty_config_exit(vty);
vty->node = ENABLE_NODE; vty->node = ENABLE_NODE;
return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING; return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
} }

View File

@ -203,7 +203,6 @@ int main(int argc, char **argv, char **envp)
} }
} }
vty_config_lockless();
/* thread master */ /* thread master */
master = frr_init(); master = frr_init();

View File

@ -335,7 +335,6 @@ main(int argc, char *argv[])
master = frr_init(); master = frr_init();
vty_config_lockless();
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init(); access_list_init();
ldp_vty_init(); ldp_vty_init();

View File

@ -1386,19 +1386,7 @@ DEFUN (config_terminal,
"Configuration from vty interface\n" "Configuration from vty interface\n"
"Configuration terminal\n") "Configuration terminal\n")
{ {
if (vty_config_lock(vty)) return vty_config_enter(vty, false, false);
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;
} }
/* Enable command */ /* Enable command */
@ -1450,7 +1438,7 @@ void cmd_exit(struct vty *vty)
break; break;
case CONFIG_NODE: case CONFIG_NODE:
vty->node = ENABLE_NODE; vty->node = ENABLE_NODE;
vty_config_unlock(vty); vty_config_exit(vty);
break; break;
case INTERFACE_NODE: case INTERFACE_NODE:
case PW_NODE: case PW_NODE:
@ -1594,7 +1582,7 @@ DEFUN (config_end,
case LINK_PARAMS_NODE: case LINK_PARAMS_NODE:
case BFD_NODE: case BFD_NODE:
case BFD_PEER_NODE: case BFD_PEER_NODE:
vty_config_unlock(vty); vty_config_exit(vty);
vty->node = ENABLE_NODE; vty->node = ENABLE_NODE;
break; break;
default: default:

View File

@ -492,20 +492,7 @@ DEFUN (config_exclusive,
"Configuration from vty interface\n" "Configuration from vty interface\n"
"Configure exclusively from this terminal\n") "Configure exclusively from this terminal\n")
{ {
if (vty_config_exclusive_lock(vty)) return vty_config_enter(vty, true, true);
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;
} }
/* Configure using a private candidate configuration. */ /* Configure using a private candidate configuration. */
@ -515,20 +502,7 @@ DEFUN (config_private,
"Configuration from vty interface\n" "Configuration from vty interface\n"
"Configure using a private candidate configuration\n") "Configure using a private candidate configuration\n")
{ {
if (vty_config_lock(vty)) return vty_config_enter(vty, true, false);
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;
} }
DEFPY (config_commit, DEFPY (config_commit,

View File

@ -86,10 +86,6 @@ static vector Vvty_serv_thread;
/* Current directory. */ /* Current directory. */
char *vty_cwd = NULL; char *vty_cwd = NULL;
/* Configure lock. */
static int vty_config;
static int vty_config_is_lockless = 0;
/* Exclusive configuration lock. */ /* Exclusive configuration lock. */
struct vty *vty_exclusive_lock; struct vty *vty_exclusive_lock;
@ -824,7 +820,7 @@ static void vty_end_config(struct vty *vty)
case BGP_EVPN_VNI_NODE: case BGP_EVPN_VNI_NODE:
case BFD_NODE: case BFD_NODE:
case BFD_PEER_NODE: case BFD_PEER_NODE:
vty_config_unlock(vty); vty_config_exit(vty);
vty->node = ENABLE_NODE; vty->node = ENABLE_NODE;
break; break;
default: default:
@ -1225,7 +1221,7 @@ static void vty_stop_input(struct vty *vty)
case VTY_NODE: case VTY_NODE:
case BFD_NODE: case BFD_NODE:
case BFD_PEER_NODE: case BFD_PEER_NODE:
vty_config_unlock(vty); vty_config_exit(vty);
vty->node = ENABLE_NODE; vty->node = ENABLE_NODE;
break; break;
default: default:
@ -2351,7 +2347,7 @@ void vty_close(struct vty *vty)
} }
/* Check configure. */ /* Check configure. */
vty_config_unlock(vty); vty_config_exit(vty);
/* OK free vty. */ /* OK free vty. */
XFREE(MTYPE_VTY, 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) if (exclusive && !vty_config_exclusive_lock(vty)) {
return 1; vty_out(vty, "VTY configuration is locked by other VTY\n");
if (vty_config == 0) { return CMD_WARNING;
vty->config = 1;
vty_config = 1;
} }
return vty->config;
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 CMD_SUCCESS;
} }
int vty_config_unlock(struct vty *vty) void vty_config_exit(struct vty *vty)
{ {
vty_config_exclusive_unlock(vty); vty_config_exclusive_unlock(vty);
@ -2714,19 +2725,6 @@ int vty_config_unlock(struct vty *vty)
nb_config_free(vty->candidate_config_base); nb_config_free(vty->candidate_config_base);
vty->candidate_config_base = NULL; 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) int vty_config_exclusive_lock(struct vty *vty)

View File

@ -102,6 +102,9 @@ struct vty {
int xpath_index; int xpath_index;
char xpath[VTY_MAXDEPTH][XPATH_MAXLEN]; char xpath[VTY_MAXDEPTH][XPATH_MAXLEN];
/* In configure mode. */
bool config;
/* Private candidate configuration mode. */ /* Private candidate configuration mode. */
bool private_config; bool private_config;
@ -149,9 +152,6 @@ struct vty {
/* Terminal monitor. */ /* Terminal monitor. */
int monitor; int monitor;
/* In configure mode. */
int config;
/* Read and write thread. */ /* Read and write thread. */
struct thread *t_read; struct thread *t_read;
struct thread *t_write; struct thread *t_write;
@ -299,9 +299,9 @@ extern void vty_close(struct vty *);
extern char *vty_get_cwd(void); extern char *vty_get_cwd(void);
extern void vty_log(const char *level, const char *proto, const char *fmt, extern void vty_log(const char *level, const char *proto, const char *fmt,
struct timestamp_control *, va_list); struct timestamp_control *, va_list);
extern int vty_config_lock(struct vty *); extern int vty_config_enter(struct vty *vty, bool private_config,
extern int vty_config_unlock(struct vty *); bool exclusive);
extern void vty_config_lockless(void); extern void vty_config_exit(struct vty *);
extern int vty_config_exclusive_lock(struct vty *vty); extern int vty_config_exclusive_lock(struct vty *vty);
extern void vty_config_exclusive_unlock(struct vty *vty); extern void vty_config_exclusive_unlock(struct vty *vty);
extern int vty_shell(struct vty *); extern int vty_shell(struct vty *);

View File

@ -165,8 +165,6 @@ int main(int argc, char **argv)
} }
} }
vty_config_lockless();
/* Prepare master thread. */ /* Prepare master thread. */
master = frr_init(); master = frr_init();

View File

@ -387,7 +387,6 @@ int main(int argc, char **argv)
} }
} }
vty_config_lockless();
zebrad.master = frr_init(); zebrad.master = frr_init();
/* Zebra related initialize. */ /* Zebra related initialize. */