Merge pull request #3163 from donaldsharp/more_vty_errors

lib, vtysh: Allow notification across multiple lines of failure
This commit is contained in:
David Lamparter 2018-10-19 12:11:21 +02:00 committed by GitHub
commit e79ab0ca33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 17 deletions

View File

@ -1281,7 +1281,8 @@ int cmd_execute(struct vty *vty, const char *cmd,
* as to why no command could be executed.
*/
int command_config_read_one_line(struct vty *vty,
const struct cmd_element **cmd, int use_daemon)
const struct cmd_element **cmd,
uint32_t line_num, int use_daemon)
{
vector vline;
int saved_node;
@ -1322,8 +1323,16 @@ int command_config_read_one_line(struct vty *vty,
}
}
if (ret != CMD_SUCCESS && ret != CMD_WARNING)
memcpy(vty->error_buf, vty->buf, VTY_BUFSIZ);
if (ret != CMD_SUCCESS && ret != CMD_WARNING) {
struct vty_error *ve = XCALLOC(MTYPE_TMP, sizeof(*ve));
memcpy(ve->error_buf, vty->buf, VTY_BUFSIZ);
ve->line_num = line_num;
if (!vty->error)
vty->error = list_new();
listnode_add(vty->error, ve);
}
cmd_free_strvec(vline);
@ -1337,10 +1346,9 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num)
*line_num = 0;
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
if (!error_ret)
++(*line_num);
++(*line_num);
ret = command_config_read_one_line(vty, NULL, 0);
ret = command_config_read_one_line(vty, NULL, *line_num, 0);
if (ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_ERR_NOTHING_TODO)

View File

@ -419,7 +419,7 @@ extern char **cmd_complete_command(vector, struct vty *, int *status);
extern const char *cmd_prompt(enum node_type);
extern int command_config_read_one_line(struct vty *vty,
const struct cmd_element **,
int use_config_node);
uint32_t line_num, int use_config_node);
extern int config_from_file(struct vty *, FILE *, unsigned int *line_num);
extern enum node_type node_parent(enum node_type);
/*

View File

@ -1695,7 +1695,6 @@ struct vty *vty_new()
new->lbuf = buffer_new(0);
new->obuf = buffer_new(0); /* Use default buffer size. */
new->buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ);
new->error_buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ);
new->max = VTY_BUFSIZ;
return new;
@ -2278,6 +2277,13 @@ void vty_serv_sock(const char *addr, unsigned short port, const char *path)
#endif /* VTYSH */
}
static void vty_error_delete(void *arg)
{
struct vty_error *ve = arg;
XFREE(MTYPE_TMP, ve);
}
/* Close vty interface. Warning: call this only from functions that
will be careful not to access the vty afterwards (since it has
now been freed). This is safest from top-level functions (called
@ -2329,8 +2335,10 @@ void vty_close(struct vty *vty)
if (vty->buf)
XFREE(MTYPE_VTY, vty->buf);
if (vty->error_buf)
XFREE(MTYPE_VTY, vty->error_buf);
if (vty->error) {
vty->error->del = vty_error_delete;
list_delete(&vty->error);
}
/* Check configure. */
vty_config_unlock(vty);
@ -2368,6 +2376,8 @@ static void vty_read_file(FILE *confp)
{
int ret;
struct vty *vty;
struct vty_error *ve;
struct listnode *node;
unsigned int line_num = 0;
vty = vty_new();
@ -2417,11 +2427,13 @@ static void vty_read_file(FILE *confp)
break;
}
nl = strchr(vty->error_buf, '\n');
if (nl)
*nl = '\0';
flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s", message,
line_num, vty->error_buf);
for (ALL_LIST_ELEMENTS_RO(vty->error, node, ve)) {
nl = strchr(ve->error_buf, '\n');
if (nl)
*nl = '\0';
flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s",
message, ve->line_num, ve->error_buf);
}
}
vty_close(vty);

View File

@ -33,6 +33,11 @@
#define VTY_BUFSIZ 4096
#define VTY_MAXHIST 20
struct vty_error {
char error_buf[VTY_BUFSIZ];
uint32_t line_num;
};
/* VTY struct. */
struct vty {
/* File descripter of this vty. */
@ -71,7 +76,7 @@ struct vty {
char *buf;
/* Command input error buffer */
char *error_buf;
struct list *error;
/* Command cursor point */
int cp;

View File

@ -856,7 +856,7 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
lineno++;
ret = command_config_read_one_line(vty, &cmd, 1);
ret = command_config_read_one_line(vty, &cmd, lineno, 1);
switch (ret) {
case CMD_WARNING: