]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add error reference system
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 13 Jun 2018 23:08:30 +0000 (23:08 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 14 Aug 2018 20:02:05 +0000 (20:02 +0000)
* Add zlog_* function to log with a reference code
* Add ability to track reference cards for errors to ferr.[ch]
* Assign some reference code ranges

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/ferr.c
lib/ferr.h
lib/log.h
vtysh/vtysh.c

index 45574520a546227e61eb6153b30cdaeb5a48f9c2..ccf2f853ef2269a04d0b2f7f73b770aa9c5eb918 100644 (file)
 #include "vty.h"
 #include "jhash.h"
 #include "memory.h"
+#include "hash.h"
+#include "command.h"
 
 DEFINE_MTYPE_STATIC(LIB, ERRINFO, "error information")
 
+/*
+ * Thread-specific key for temporary storage of allocated ferr.
+ */
 static pthread_key_t errkey;
 
 static void ferr_free(void *arg)
@@ -46,6 +51,101 @@ static void err_key_fini(void)
        pthread_key_delete(errkey);
 }
 
+/*
+ * Global shared hash table holding reference text for all defined errors.
+ */
+pthread_mutex_t refs_mtx = PTHREAD_MUTEX_INITIALIZER;
+struct hash *refs;
+
+static int ferr_hash_cmp(const void *a, const void *b)
+{
+       const struct ferr_ref *f_a = a;
+       const struct ferr_ref *f_b = b;
+
+       return f_a->code == f_b->code;
+}
+
+static inline unsigned int ferr_hash_key(void *a)
+{
+       struct ferr_ref *f = a;
+
+       return f->code;
+}
+
+void ferr_ref_add(struct ferr_ref *ref)
+{
+       pthread_mutex_lock(&refs_mtx);
+       {
+               hash_get(refs, ref, hash_alloc_intern);
+       }
+       pthread_mutex_unlock(&refs_mtx);
+}
+
+struct ferr_ref *ferr_ref_get(uint32_t code)
+{
+       struct ferr_ref holder;
+       struct ferr_ref *ref;
+
+       holder.code = code;
+       pthread_mutex_lock(&refs_mtx);
+       {
+               ref = hash_lookup(refs, &holder);
+       }
+       pthread_mutex_unlock(&refs_mtx);
+
+       return ref;
+}
+
+void ferr_ref_display(struct vty *vty, uint32_t code)
+{
+       struct ferr_ref *ref = ferr_ref_get(code);
+
+       if (!ref) {
+               vty_out(vty, "Code %d - Unknown\n", code);
+               return;
+       }
+
+       vty_out(vty, "Error Code %d - %s\n", code, ref->title);
+       vty_out(vty, "--------------------------------------\n");
+       vty_out(vty, "\nDescription:\n%s\n\nRecommendation:\n%s\n\n",
+               ref->description, ref->suggestion);
+}
+
+DEFUN_NOSH(show_error_code,
+          show_error_code_cmd,
+          "show error (0-4294967296)",
+          SHOW_STR
+          "Information on errors\n"
+          "Error code to get info about\n")
+{
+       uint32_t arg = strtoul(argv[2]->arg, NULL, 10);
+
+       ferr_ref_display(vty, arg);
+       return CMD_SUCCESS;
+}
+
+void ferr_ref_init(void)
+{
+       pthread_mutex_lock(&refs_mtx);
+       {
+               refs = hash_create(ferr_hash_key, ferr_hash_cmp,
+                                  "Error Reference Texts");
+       }
+       pthread_mutex_unlock(&refs_mtx);
+
+       install_element(VIEW_NODE, &show_error_code_cmd);
+}
+
+void ferr_ref_fini(void)
+{
+       pthread_mutex_lock(&refs_mtx);
+       {
+               hash_free(refs);
+               refs = NULL;
+       }
+       pthread_mutex_unlock(&refs_mtx);
+}
+
 const struct ferr *ferr_get_last(ferr_r errval)
 {
        struct ferr *last_error = pthread_getspecific(errkey);
index 2f100c1b0121ac50efa90cc460a63d16ccac0a1f..5efdc6bd6b274bb54255cfc413ee92c78bf71e98 100644 (file)
@@ -25,6 +25,8 @@
 #include <limits.h>
 #include <errno.h>
 
+#include "vty.h"
+
 /* return type when this error indication stuff is used.
  *
  * guaranteed to have boolean evaluation to "false" when OK, "true" when error
@@ -93,6 +95,34 @@ struct ferr {
        char pathname[PATH_MAX];
 };
 
+/* Numeric ranges assigned to daemons for use as error codes. */
+#define LIB_FERR_START 0x01000001
+#define LIB_FERR_END 0x01FFFFFF
+#define BGP_FERR_START 0x02000000
+#define BGP_FERR_END 0x02FFFFFF
+#define OSPF_FERR_START 0x03000001
+#define OSPF_FERR_END 0x03FFFFFF
+#define ZEBRA_FERR_START 0x04000001
+#define ZEBRA_FERR_END 0x04FFFFFF
+
+struct ferr_ref {
+       /* Unique error code displayed to end user as a reference. -1 means
+        * this is an uncoded error that does not have reference material. */
+       uint32_t code;
+       /* Ultra brief title */
+       const char *title;
+       /* Brief description of error */
+       const char *description;
+       /* Remedial suggestion */
+       const char *suggestion;
+};
+
+void ferr_ref_add(struct ferr_ref *ref);
+struct ferr_ref *ferr_ref_get(uint32_t code);
+void ferr_ref_display(struct vty *, uint32_t code);
+void ferr_ref_init(void);
+void ferr_ref_fini(void);
+
 /* get error details.
  *
  * NB: errval/ferr_r does NOT carry the full error information.  It's only
index 07eb6d5bd5605420387820306630b3ae369d8ee7..a2546298a86b40ab8b17aec781b5607fc5b7a5dc 100644 (file)
--- a/lib/log.h
+++ b/lib/log.h
@@ -85,6 +85,11 @@ extern void zlog_info(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 extern void zlog_notice(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 extern void zlog_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
 
+/* For logs which have error codes associated with them */
+#define zlog_ferr(ferr_id, format, ...)                                        \
+       zlog_err("[EC %d] " format, ferr_id, ##__VA_ARGS__)
+
+
 extern void zlog_thread_info(int log_level);
 
 /* Set logging level for the given destination.  If the log_level
index 48a90a695c960a88633dbeea4de6e37dafe415fa..540e30e447796082c9679c3dfea71db00c7f4257 100644 (file)
@@ -2344,6 +2344,21 @@ DEFUN (vtysh_show_debugging_hashtable,
                               "Hashtable statistics for %s:\n");
 }
 
+DEFUN (vtysh_show_error_code,
+       vtysh_show_error_code_cmd,
+       "show error (0-4294967296)",
+       SHOW_STR
+       "Information on errors\n"
+       "Error code to get info about\n")
+{
+       char cmd[256];
+
+       snprintf(cmd, sizeof(cmd), "do show error %s", argv[2]->arg);
+
+       /* FIXME: Needs to determine which daemon to send to via code ranges */
+       return show_per_daemon(cmd, "");
+}
+
 /* Memory */
 DEFUN (vtysh_show_memory,
        vtysh_show_memory_cmd,
@@ -3780,6 +3795,7 @@ void vtysh_init_vty(void)
 
        /* debugging */
        install_element(VIEW_NODE, &vtysh_show_debugging_cmd);
+       install_element(VIEW_NODE, &vtysh_show_error_code_cmd);
        install_element(VIEW_NODE, &vtysh_show_debugging_hashtable_cmd);
        install_element(ENABLE_NODE, &vtysh_debug_all_cmd);
        install_element(CONFIG_NODE, &vtysh_debug_all_cmd);