*: 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);
vty_config_unlock(vty);
vty_config_exit(vty);
vty->node = ENABLE_NODE;
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 */
master = frr_init();

View file

@ -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();

View file

@ -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:

View file

@ -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,

View file

@ -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;
}
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);
@ -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)

View file

@ -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 *);

View file

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

View file

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