diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-06-14 01:08:30 +0200 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-08-14 22:02:05 +0200 |
commit | 7b526b616873cf360e690955e2ab36c2d9f04507 (patch) | |
tree | a7ccaad148df14e41604537dbdce156ff2b1c844 /lib | |
parent | doc: Add missing flowspec.rst to distribution tar file (diff) | |
download | frr-7b526b616873cf360e690955e2ab36c2d9f04507.tar.xz frr-7b526b616873cf360e690955e2ab36c2d9f04507.zip |
lib: add error reference system
* 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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ferr.c | 100 | ||||
-rw-r--r-- | lib/ferr.h | 30 | ||||
-rw-r--r-- | lib/log.h | 5 |
3 files changed, 135 insertions, 0 deletions
diff --git a/lib/ferr.c b/lib/ferr.c index 45574520a..ccf2f853e 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -24,9 +24,14 @@ #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); diff --git a/lib/ferr.h b/lib/ferr.h index 2f100c1b0..5efdc6bd6 100644 --- a/lib/ferr.h +++ b/lib/ferr.h @@ -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 @@ -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 |