]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib, vtysh: Allow notification across multiple lines of failure
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 11 Oct 2018 13:43:32 +0000 (09:43 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 11 Oct 2018 13:46:40 +0000 (09:46 -0400)
When reading in config files and we have failures on multiple
lines actually note the actual failure lines and return them.
This fixes an issue where we stopped counting errors after
the first one and we got missleading line numbers that
did not correspond to the actual problem.

This is fixed:
sharpd@donna ~/frr> sudo /usr/lib/frr/pimd --log=stdout -A 127.0.0.1 -f /etc/frr/pimd.conf
2018/10/11 09:41:01 PIM: VRF Created: default(0)
2018/10/11 09:41:01 PIM: pim_vrf_enable: for default
2018/10/11 09:41:01 PIM: zclient_lookup_sched_now: zclient lookup immediate connection scheduled
2018/10/11 09:41:01 PIM: zclient_lookup_new: zclient lookup socket initialized
2018/10/11 09:41:01 PIM: pimd 6.1-dev starting: vty@2611
2018/10/11 09:41:01 PIM: [EC 100663304] ERROR: No such command on config line 2: inteface lo
2018/10/11 09:41:01 PIM: [EC 100663304] ERROR: No such command on config line 3: ip igmp
2018/10/11 09:41:01 PIM: [EC 100663304] ERROR: No such command on config line 4: ip igmp join 224.1.1.1 13.13.13.2
^C2018/10/11 09:45:09 PIM: Terminating on signal SIGINT
2018/10/11 09:45:09 PIM: VRF Deletion: default(0)

Fixes: #3161
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/command.c
lib/command.h
lib/vty.c
lib/vty.h
vtysh/vtysh.c

index 60c5f4e75b1d1a223635c7e24c6c0d0fbd2cc1c6..6fe4ae2d8f2cbbd9d0d154c287cb754f0498312b 100644 (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)
index 8e51641b88cfab90b2ced915b9f2f052f1caa91c..fbff1e67f4331c098f2e737d209989403e1ef3d4 100644 (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);
 /*
index f812dd4279a02fcda1c4c0332bcfd8e384a67840..a73cc23b978c43e281ee23743ffb02edfa6806cf 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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);
index b55abf22043f4956617b05ce4aab9084e3807b47..efe91a568b67cbc5102e6ae8924b167ae090dbb3 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
 #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;
index 6a92b9081377f32f5ad3bff15e39fb91abb722af..8ed11f1876170b5f38d879491e072587d026beb4 100644 (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: