#include <ucontext.h>
#endif
+#ifdef HAVE_LIBUNWIND
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#include <dlfcn.h>
+#endif
+
DEFINE_MTYPE_STATIC(LIB, ZLOG, "Logging")
static int logfile_fd = -1; /* Used in signal handler. */
return str_append(s, len, t);
}
-#if defined(SA_SIGINFO) || defined(HAVE_STACK_TRACE)
+#if defined(SA_SIGINFO) \
+ || defined(HAVE_PRINTSTACK) \
+ || defined(HAVE_GLIBC_BACKTRACE)
static char *hex_append(char *s, int len, unsigned long x)
{
char buf[30];
Needs to be enhanced to support syslog logging. */
void zlog_backtrace_sigsafe(int priority, void *program_counter)
{
-#ifdef HAVE_STACK_TRACE
+#ifdef HAVE_LIBUNWIND
+ char buf[100];
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unw_word_t ip, off, sp;
+ Dl_info dlinfo;
+
+ unw_getcontext(&uc);
+ unw_init_local(&cursor, &uc);
+ while (unw_step(&cursor) > 0) {
+ char name[128] = "?";
+
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ if (unw_is_signal_frame(&cursor))
+ dprintf(2, " ---- signal ----\n");
+
+ if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off)) {
+ snprintf(name, sizeof(name), "%s+%#lx",
+ buf, (long)off);
+ }
+ dprintf(2, "%-30s %16lx %16lx", name, (long)ip, (long)sp);
+ if (dladdr((void *)ip, &dlinfo)) {
+ dprintf(2, " %s (mapped at %p)",
+ dlinfo.dli_fname, dlinfo.dli_fbase);
+ }
+ dprintf(2, "\n");
+
+ }
+#elif defined(HAVE_GLIBC_BACKTRACE) || defined(HAVE_PRINTSTACK)
static const char pclabel[] = "Program counter: ";
void *array[64];
int size;
void zlog_backtrace(int priority)
{
-#ifndef HAVE_GLIBC_BACKTRACE
- zlog(priority, "No backtrace available on this platform.");
-#else
+#ifdef HAVE_LIBUNWIND
+ char buf[100];
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unw_word_t ip, off, sp;
+ Dl_info dlinfo;
+
+ unw_getcontext(&uc);
+ unw_init_local(&cursor, &uc);
+ zlog(priority, "Backtrace:");
+ while (unw_step(&cursor) > 0) {
+ char name[128] = "?";
+
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ if (unw_is_signal_frame(&cursor))
+ zlog(priority, " ---- signal ----");
+
+ if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off))
+ snprintf(name, sizeof(name), "%s+%#lx",
+ buf, (long)off);
+
+ if (dladdr((void *)ip, &dlinfo))
+ zlog(priority, "%-30s %16lx %16lx %s (mapped at %p)",
+ name, (long)ip, (long)sp,
+ dlinfo.dli_fname, dlinfo.dli_fbase);
+ else
+ zlog(priority, "%-30s %16lx %16lx",
+ name, (long)ip, (long)sp);
+ }
+#elif defined(HAVE_GLIBC_BACKTRACE)
void *array[20];
int size, i;
char **strings;
size = backtrace(array, array_size(array));
if (size <= 0 || (size_t)size > array_size(array)) {
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Cannot get backtrace, returned invalid # of frames %d "
"(valid range is between 1 and %lu)",
size, (unsigned long)(array_size(array)));
}
zlog(priority, "Backtrace for %d stack frames:", size);
if (!(strings = backtrace_symbols(array, size))) {
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"Cannot get backtrace symbols (out of memory?)");
for (i = 0; i < size; i++)
zlog(priority, "[bt %d] %p", i, array[i]);
zlog(priority, "[bt %d] %s", i, strings[i]);
free(strings);
}
-#endif /* HAVE_GLIBC_BACKTRACE */
+#else /* !HAVE_GLIBC_BACKTRACE && !HAVE_LIBUNWIND */
+ zlog(priority, "No backtrace available on this platform.");
+#endif
}
void zlog(int priority, const char *format, ...)
void memory_oom(size_t size, const char *name)
{
- flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
"out of memory: failed to allocate %zu bytes for %s"
"object",
size, name);
save_errno = errno;
umask(oldumask);
if (zl->fp == NULL) {
+
+ pthread_mutex_unlock(&loglock);
+
flog_err_sys(
- LIB_ERR_SYSTEM_CALL,
+ EC_LIB_SYSTEM_CALL,
"Log rotate failed: cannot open file %s for append: %s",
zl->filename, safe_strerror(save_errno));
ret = -1;
+
+ pthread_mutex_lock(&loglock);
} else {
logfile_fd = fileno(zl->fp);
zl->maxlvl[ZLOG_DEST_FILE] = level;
DESC_ENTRY(ZEBRA_ROUTE_ADD),
DESC_ENTRY(ZEBRA_ROUTE_DELETE),
DESC_ENTRY(ZEBRA_ROUTE_NOTIFY_OWNER),
- DESC_ENTRY(ZEBRA_IPV4_ROUTE_ADD),
- DESC_ENTRY(ZEBRA_IPV4_ROUTE_DELETE),
- DESC_ENTRY(ZEBRA_IPV6_ROUTE_ADD),
- DESC_ENTRY(ZEBRA_IPV6_ROUTE_DELETE),
DESC_ENTRY(ZEBRA_REDISTRIBUTE_ADD),
DESC_ENTRY(ZEBRA_REDISTRIBUTE_DELETE),
DESC_ENTRY(ZEBRA_REDISTRIBUTE_DEFAULT_ADD),
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER),
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER),
DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE),
- DESC_ENTRY(ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD),
DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE),
DESC_ENTRY(ZEBRA_MPLS_LABELS_DELETE),
DESC_ENTRY(ZEBRA_IPMR_ROUTE_STATS),
DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT),
+ DESC_ENTRY(ZEBRA_LABEL_MANAGER_CONNECT_ASYNC),
DESC_ENTRY(ZEBRA_GET_LABEL_CHUNK),
DESC_ENTRY(ZEBRA_RELEASE_LABEL_CHUNK),
DESC_ENTRY(ZEBRA_ADVERTISE_ALL_VNI),
DESC_ENTRY(ZEBRA_IP_PREFIX_ROUTE_DEL),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_ADD),
DESC_ENTRY(ZEBRA_REMOTE_MACIP_DEL),
+ DESC_ENTRY(ZEBRA_DUPLICATE_ADDR_DETECTION),
DESC_ENTRY(ZEBRA_PW_ADD),
DESC_ENTRY(ZEBRA_PW_DELETE),
DESC_ENTRY(ZEBRA_PW_SET),
DESC_ENTRY(ZEBRA_IPSET_DESTROY),
DESC_ENTRY(ZEBRA_IPSET_ENTRY_ADD),
DESC_ENTRY(ZEBRA_IPSET_ENTRY_DELETE),
+ DESC_ENTRY(ZEBRA_VXLAN_FLOOD_CONTROL),
};
#undef DESC_ENTRY
unsigned int i;
if (zroute >= array_size(route_types)) {
- flog_err(LIB_ERR_DEVELOPMENT, "unknown zebra route type: %u",
- zroute);
+ flog_err(EC_LIB_DEVELOPMENT, "unknown zebra route type: %u",
+ zroute);
return &unknown;
}
if (zroute == route_types[zroute].type)
return &route_types[i];
}
}
- flog_err(LIB_ERR_DEVELOPMENT,
- "internal error: cannot find route type %u in table!",
- zroute);
+ flog_err(EC_LIB_DEVELOPMENT,
+ "internal error: cannot find route type %u in table!", zroute);
return &unknown;
}
const char *zserv_command_string(unsigned int command)
{
if (command >= array_size(command_types)) {
- flog_err(LIB_ERR_DEVELOPMENT, "unknown zserv command type: %u",
- command);
+ flog_err(EC_LIB_DEVELOPMENT, "unknown zserv command type: %u",
+ command);
return unknown.string;
}
return command_types[command].string;
return ZEBRA_ROUTE_BABEL;
else if (strmatch(s, "sharp"))
return ZEBRA_ROUTE_SHARP;
+ else if (strmatch(s, "openfabric"))
+ return ZEBRA_ROUTE_OPENFABRIC;
}
if (afi == AFI_IP6) {
if (strmatch(s, "kernel"))
return ZEBRA_ROUTE_BABEL;
else if (strmatch(s, "sharp"))
return ZEBRA_ROUTE_SHARP;
+ else if (strmatch(s, "openfabric"))
+ return ZEBRA_ROUTE_OPENFABRIC;
}
return -1;
}