#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)
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);
#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
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
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
"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,
/* 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);