Merge pull request #8527 from opensourcerouting/fixes-20210421

lib: fix zlog assert() & CLI node_exit
This commit is contained in:
Russ White 2021-04-27 15:14:12 -04:00 committed by GitHub
commit 0a9fdfee67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 63 deletions

View File

@ -900,13 +900,31 @@ enum node_type node_parent(enum node_type node)
/* Execute command by argument vline vector. */ /* Execute command by argument vline vector. */
static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter,
struct vty *vty, struct vty *vty,
const struct cmd_element **cmd) const struct cmd_element **cmd,
unsigned int up_level)
{ {
struct list *argv_list; struct list *argv_list;
enum matcher_rv status; enum matcher_rv status;
const struct cmd_element *matched_element = NULL; const struct cmd_element *matched_element = NULL;
unsigned int i;
int xpath_index = vty->xpath_index;
int node = vty->node;
struct graph *cmdgraph = cmd_node_graph(cmdvec, vty->node); /* only happens for legacy split config file load; need to check for
* a match before calling node_exit handlers below
*/
for (i = 0; i < up_level; i++) {
if (node <= CONFIG_NODE)
return CMD_NO_LEVEL_UP;
node = node_parent(node);
if (xpath_index > 0
&& vty_check_node_for_xpath_decrement(node, vty->node))
xpath_index--;
}
struct graph *cmdgraph = cmd_node_graph(cmdvec, node);
status = command_match(cmdgraph, vline, &argv_list, &matched_element); status = command_match(cmdgraph, vline, &argv_list, &matched_element);
if (cmd) if (cmd)
@ -926,12 +944,16 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter,
} }
} }
for (i = 0; i < up_level; i++)
cmd_exit(vty);
// build argv array from argv list // build argv array from argv list
struct cmd_token **argv = XMALLOC( struct cmd_token **argv = XMALLOC(
MTYPE_TMP, argv_list->count * sizeof(struct cmd_token *)); MTYPE_TMP, argv_list->count * sizeof(struct cmd_token *));
struct listnode *ln; struct listnode *ln;
struct cmd_token *token; struct cmd_token *token;
unsigned int i = 0;
i = 0;
for (ALL_LIST_ELEMENTS_RO(argv_list, ln, token)) for (ALL_LIST_ELEMENTS_RO(argv_list, ln, token))
argv[i++] = token; argv[i++] = token;
@ -1012,7 +1034,7 @@ int cmd_execute_command(vector vline, struct vty *vty,
vector_lookup(vline, index)); vector_lookup(vline, index));
ret = cmd_execute_command_real(shifted_vline, FILTER_RELAXED, ret = cmd_execute_command_real(shifted_vline, FILTER_RELAXED,
vty, cmd); vty, cmd, 0);
vector_free(shifted_vline); vector_free(shifted_vline);
vty->node = onode; vty->node = onode;
@ -1021,7 +1043,7 @@ int cmd_execute_command(vector vline, struct vty *vty,
} }
saved_ret = ret = saved_ret = ret =
cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd); cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd, 0);
if (vtysh) if (vtysh)
return saved_ret; return saved_ret;
@ -1038,7 +1060,7 @@ int cmd_execute_command(vector vline, struct vty *vty,
onode)) onode))
vty->xpath_index--; vty->xpath_index--;
ret = cmd_execute_command_real(vline, FILTER_RELAXED, ret = cmd_execute_command_real(vline, FILTER_RELAXED,
vty, cmd); vty, cmd, 0);
if (ret == CMD_SUCCESS || ret == CMD_WARNING if (ret == CMD_SUCCESS || ret == CMD_WARNING
|| ret == CMD_NOT_MY_INSTANCE || ret == CMD_NOT_MY_INSTANCE
|| ret == CMD_WARNING_CONFIG_FAILED) || ret == CMD_WARNING_CONFIG_FAILED)
@ -1069,7 +1091,7 @@ int cmd_execute_command(vector vline, struct vty *vty,
int cmd_execute_command_strict(vector vline, struct vty *vty, int cmd_execute_command_strict(vector vline, struct vty *vty,
const struct cmd_element **cmd) const struct cmd_element **cmd)
{ {
return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd); return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd, 0);
} }
/* /*
@ -1220,6 +1242,7 @@ int command_config_read_one_line(struct vty *vty,
{ {
vector vline; vector vline;
int ret; int ret;
unsigned up_level = 0;
vline = cmd_make_strvec(vty->buf); vline = cmd_make_strvec(vty->buf);
@ -1230,36 +1253,20 @@ int command_config_read_one_line(struct vty *vty,
/* Execute configuration command : this is strict match */ /* Execute configuration command : this is strict match */
ret = cmd_execute_command_strict(vline, vty, cmd); ret = cmd_execute_command_strict(vline, vty, cmd);
// Climb the tree and try the command again at each node /* The logic for trying parent nodes is in cmd_execute_command_real()
if (!(use_daemon && ret == CMD_SUCCESS_DAEMON) * since calling ->node_exit() correctly is a bit involved. This is
&& !(!use_daemon && ret == CMD_ERR_NOTHING_TODO) * also the only reason CMD_NO_LEVEL_UP exists.
&& ret != CMD_SUCCESS && ret != CMD_WARNING */
&& ret != CMD_NOT_MY_INSTANCE && ret != CMD_WARNING_CONFIG_FAILED
&& vty->node != CONFIG_NODE) {
int saved_node = vty->node;
int saved_xpath_index = vty->xpath_index;
while (!(use_daemon && ret == CMD_SUCCESS_DAEMON) while (!(use_daemon && ret == CMD_SUCCESS_DAEMON)
&& !(!use_daemon && ret == CMD_ERR_NOTHING_TODO) && !(!use_daemon && ret == CMD_ERR_NOTHING_TODO)
&& ret != CMD_SUCCESS && ret != CMD_WARNING && ret != CMD_SUCCESS && ret != CMD_WARNING
&& vty->node > CONFIG_NODE) { && ret != CMD_NOT_MY_INSTANCE && ret != CMD_WARNING_CONFIG_FAILED
vty->node = node_parent(vty->node); && ret != CMD_NO_LEVEL_UP)
if (vty->xpath_index > 0 ret = cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd,
&& vty_check_node_for_xpath_decrement(vty->node, ++up_level);
saved_node))
vty->xpath_index--;
ret = cmd_execute_command_strict(vline, vty, cmd);
}
// If climbing the tree did not work then ignore the command and if (ret == CMD_NO_LEVEL_UP)
// stay at the same node ret = CMD_ERR_NO_MATCH;
if (!(use_daemon && ret == CMD_SUCCESS_DAEMON)
&& !(!use_daemon && ret == CMD_ERR_NOTHING_TODO)
&& ret != CMD_SUCCESS && ret != CMD_WARNING) {
vty->node = saved_node;
vty->xpath_index = saved_xpath_index;
}
}
if (ret != CMD_SUCCESS && if (ret != CMD_SUCCESS &&
ret != CMD_WARNING && ret != CMD_WARNING &&

View File

@ -223,6 +223,7 @@ struct cmd_node {
#define CMD_SUSPEND 12 #define CMD_SUSPEND 12
#define CMD_WARNING_CONFIG_FAILED 13 #define CMD_WARNING_CONFIG_FAILED 13
#define CMD_NOT_MY_INSTANCE 14 #define CMD_NOT_MY_INSTANCE 14
#define CMD_NO_LEVEL_UP 15
/* Argc max counts. */ /* Argc max counts. */
#define CMD_ARGC_MAX 256 #define CMD_ARGC_MAX 256

View File

@ -78,23 +78,24 @@ void zlog_fd(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsgs)
struct zlog_msg *msg = msgs[i]; struct zlog_msg *msg = msgs[i];
int prio = zlog_msg_prio(msg); int prio = zlog_msg_prio(msg);
if (prio > zt->prio_min) if (prio <= zt->prio_min) {
continue;
iov[iovpos].iov_base = ts_pos; iov[iovpos].iov_base = ts_pos;
if (iovpos > 0) if (iovpos > 0)
*ts_pos++ = '\n'; *ts_pos++ = '\n';
ts_pos += zlog_msg_ts(msg, ts_pos, sizeof(ts_buf) - 1 ts_pos += zlog_msg_ts(msg, ts_pos,
sizeof(ts_buf) - 1
- (ts_pos - ts_buf), - (ts_pos - ts_buf),
ZLOG_TS_LEGACY | zte->ts_subsec); ZLOG_TS_LEGACY | zte->ts_subsec);
*ts_pos++ = ' '; *ts_pos++ = ' ';
iov[iovpos].iov_len = ts_pos - (char *)iov[iovpos].iov_base; iov[iovpos].iov_len =
ts_pos - (char *)iov[iovpos].iov_base;
iovpos++; iovpos++;
if (zte->record_priority) { if (zte->record_priority) {
iov[iovpos].iov_base = (char *)prionames[prio]; iov[iovpos].iov_base = (char *)prionames[prio];
iov[iovpos].iov_len = strlen(iov[iovpos].iov_base); iov[iovpos].iov_len =
strlen(iov[iovpos].iov_base);
iovpos++; iovpos++;
} }
@ -104,14 +105,21 @@ void zlog_fd(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsgs)
iovpos++; iovpos++;
iov[iovpos].iov_base = (char *)zlog_msg_text(msg, &textlen); iov[iovpos].iov_base =
(char *)zlog_msg_text(msg, &textlen);
iov[iovpos].iov_len = textlen; iov[iovpos].iov_len = textlen;
iovpos++; iovpos++;
}
if (ts_buf + sizeof(ts_buf) - ts_pos < TS_LEN /* conditions that trigger writing:
* - out of space for more timestamps/headers
* - this being the last message in the batch
* - not enough remaining iov entries
*/
if (iovpos > 0 && (ts_buf + sizeof(ts_buf) - ts_pos < TS_LEN
|| i + 1 == nmsgs || i + 1 == nmsgs
|| array_size(iov) - iovpos < 5) { || array_size(iov) - iovpos < 5)) {
iov[iovpos].iov_base = (char *)"\n"; iov[iovpos].iov_base = (char *)"\n";
iov[iovpos].iov_len = 1; iov[iovpos].iov_len = 1;