diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/agentx.c | 7 | ||||
| -rw-r--r-- | lib/agg_table.h | 5 | ||||
| -rw-r--r-- | lib/command.h | 8 | ||||
| -rw-r--r-- | lib/filter.c | 33 | ||||
| -rw-r--r-- | lib/frr_pthread.c | 5 | ||||
| -rw-r--r-- | lib/frr_zmq.c | 22 | ||||
| -rw-r--r-- | lib/hash.c | 14 | ||||
| -rw-r--r-- | lib/if.c | 22 | ||||
| -rw-r--r-- | lib/ldp_sync.c | 2 | ||||
| -rw-r--r-- | lib/libfrr_trace.c | 4 | ||||
| -rw-r--r-- | lib/libfrr_trace.h | 240 | ||||
| -rw-r--r-- | lib/linklist.c | 9 | ||||
| -rw-r--r-- | lib/memory.c | 5 | ||||
| -rw-r--r-- | lib/nexthop.c | 8 | ||||
| -rw-r--r-- | lib/nexthop_group.c | 20 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 8 | ||||
| -rw-r--r-- | lib/plist.c | 32 | ||||
| -rw-r--r-- | lib/routemap.c | 56 | ||||
| -rw-r--r-- | lib/sockunion.c | 12 | ||||
| -rw-r--r-- | lib/spf_backoff.c | 9 | ||||
| -rw-r--r-- | lib/subdir.am | 8 | ||||
| -rw-r--r-- | lib/table.c | 10 | ||||
| -rw-r--r-- | lib/table.h | 5 | ||||
| -rw-r--r-- | lib/thread.c | 49 | ||||
| -rw-r--r-- | lib/thread.h | 19 | ||||
| -rw-r--r-- | lib/trace.h | 80 | ||||
| -rw-r--r-- | lib/workqueue.c | 4 | ||||
| -rw-r--r-- | lib/zassert.h | 2 | ||||
| -rw-r--r-- | lib/zclient.c | 50 | ||||
| -rw-r--r-- | lib/zlog.c | 29 |
30 files changed, 575 insertions, 202 deletions
diff --git a/lib/agentx.c b/lib/agentx.c index 7c4bdcbe27..603d8d6172 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -107,7 +107,7 @@ static void agentx_events_update(void) struct thread *thr; int fd, thr_fd; - THREAD_OFF(timeout_thr); + thread_cancel(&timeout_thr); FD_ZERO(&fds); snmp_select_info(&maxfd, &fds, &timeout, &block); @@ -130,7 +130,7 @@ static void agentx_events_update(void) if (thr_fd == fd) { struct listnode *nextln = listnextnode(ln); if (!FD_ISSET(fd, &fds)) { - thread_cancel(thr); + thread_cancel(&thr); list_delete_node(events, ln); } ln = nextln; @@ -151,7 +151,8 @@ static void agentx_events_update(void) */ while (ln) { struct listnode *nextln = listnextnode(ln); - thread_cancel(listgetdata(ln)); + thr = listgetdata(ln); + thread_cancel(&thr); list_delete_node(events, ln); ln = nextln; } diff --git a/lib/agg_table.h b/lib/agg_table.h index e98476f1b7..e0c06449ee 100644 --- a/lib/agg_table.h +++ b/lib/agg_table.h @@ -161,6 +161,11 @@ agg_node_get_prefix(const struct agg_node *node) return &node->p; } +static inline unsigned int agg_node_get_lock_count(const struct agg_node *node) +{ + return node->lock; +} + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pRN" (struct agg_node *) #endif diff --git a/lib/command.h b/lib/command.h index 677d4b2dad..bb007b0868 100644 --- a/lib/command.h +++ b/lib/command.h @@ -462,6 +462,14 @@ struct cmd_node { #define EVPN_TYPE_3_HELP_STR "Multicast (Type-3) route\n" #define EVPN_TYPE_4_HELP_STR "Ethernet Segment (Type-4) route\n" #define EVPN_TYPE_5_HELP_STR "Prefix (Type-5) route\n" +#define EVPN_TYPE_ALL_LIST "<ead|1|macip|2|multicast|3|es|4|prefix|5>" +#define EVPN_TYPE_ALL_LIST_HELP_STR \ + EVPN_TYPE_1_HELP_STR EVPN_TYPE_1_HELP_STR \ + EVPN_TYPE_2_HELP_STR EVPN_TYPE_2_HELP_STR \ + EVPN_TYPE_3_HELP_STR EVPN_TYPE_3_HELP_STR \ + EVPN_TYPE_4_HELP_STR EVPN_TYPE_4_HELP_STR \ + EVPN_TYPE_5_HELP_STR EVPN_TYPE_5_HELP_STR + /* Prototypes. */ extern void install_node(struct cmd_node *node); diff --git a/lib/filter.c b/lib/filter.c index e6add0462b..f5ae9ee2b7 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -576,14 +576,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", - inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) vty_out(vty, - ", wildcard bits %s", - inet_ntoa( - filter->addr_mask)); + ", wildcard bits %pI4", + &filter->addr_mask); vty_out(vty, "\n"); } } @@ -625,14 +623,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", - inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) vty_out(vty, - ", wildcard bits %s", - inet_ntoa( - filter->addr_mask)); + ", wildcard bits %pI4", + &filter->addr_mask); vty_out(vty, "\n"); } } @@ -722,29 +718,28 @@ static void config_write_access_cisco(struct vty *vty, struct filter *mfilter) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any"); else if (filter->addr_mask.s_addr == INADDR_ANY) - vty_out(vty, " host %s", inet_ntoa(filter->addr)); + vty_out(vty, " host %pI4", &filter->addr); else { - vty_out(vty, " %s", inet_ntoa(filter->addr)); - vty_out(vty, " %s", inet_ntoa(filter->addr_mask)); + vty_out(vty, " %pI4", &filter->addr); + vty_out(vty, " %pI4", &filter->addr_mask); } if (filter->mask_mask.s_addr == 0xffffffff) vty_out(vty, " any"); else if (filter->mask_mask.s_addr == INADDR_ANY) - vty_out(vty, " host %s", inet_ntoa(filter->mask)); + vty_out(vty, " host %pI4", &filter->mask); else { - vty_out(vty, " %s", inet_ntoa(filter->mask)); - vty_out(vty, " %s", inet_ntoa(filter->mask_mask)); + vty_out(vty, " %pI4", &filter->mask); + vty_out(vty, " %pI4", &filter->mask_mask); } vty_out(vty, "\n"); } else { if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) - vty_out(vty, " %s", - inet_ntoa(filter->addr_mask)); + vty_out(vty, " %pI4", &filter->addr_mask); vty_out(vty, "\n"); } } diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index da9594ed80..3f0179fbc1 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -28,6 +28,7 @@ #include "memory.h" #include "linklist.h" #include "zlog.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread") DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives") @@ -167,6 +168,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr) sigfillset(&blocksigs); pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs); + frrtrace(1, frr_libfrr, frr_pthread_run, fpt->name); + fpt->rcu_thread = rcu_thread_prepare(); ret = pthread_create(&fpt->thread, attr, frr_pthread_inner, fpt); @@ -204,6 +207,8 @@ void frr_pthread_notify_running(struct frr_pthread *fpt) int frr_pthread_stop(struct frr_pthread *fpt, void **result) { + frrtrace(1, frr_libfrr, frr_pthread_stop, fpt->name); + int ret = (*fpt->attr.stop)(fpt, result); memset(&fpt->thread, 0x00, sizeof(fpt->thread)); return ret; diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 565936a410..cc11d76700 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -190,10 +190,8 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master, cb->read.cancelled = false; if (events & ZMQ_POLLIN) { - if (cb->read.thread) { - thread_cancel(cb->read.thread); - cb->read.thread = NULL; - } + thread_cancel(&cb->read.thread); + funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd, &cb->read.thread, funcname, schedfrom, fromln); @@ -298,10 +296,8 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master, cb->write.cancelled = false; if (events & ZMQ_POLLOUT) { - if (cb->write.thread) { - thread_cancel(cb->write.thread); - cb->write.thread = NULL; - } + thread_cancel(&cb->write.thread); + funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd, &cb->write.thread, funcname, schedfrom, fromln); @@ -317,10 +313,8 @@ void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core) if (!cb || !*cb) return; core->cancelled = true; - if (core->thread) { - thread_cancel(core->thread); - core->thread = NULL; - } + thread_cancel(&core->thread); + if ((*cb)->read.cancelled && !(*cb)->read.thread && (*cb)->write.cancelled && (*cb)->write.thread) XFREE(MTYPE_ZEROMQ_CB, *cb); @@ -344,8 +338,8 @@ void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core, return; if (events & event && core->thread && !core->cancelled) { struct thread_master *tm = core->thread->master; - thread_cancel(core->thread); - core->thread = NULL; + thread_cancel(&core->thread); + thread_add_event(tm, (event == ZMQ_POLLIN ? frrzmq_read_msg : frrzmq_write_msg), cbp, cb->fd, &core->thread); diff --git a/lib/hash.c b/lib/hash.c index 85982774ac..ed429b77d0 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -29,6 +29,7 @@ #include "command.h" #include "libfrr.h" #include "frr_pthread.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, HASH, "Hash") DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket") @@ -138,6 +139,8 @@ static void hash_expand(struct hash *hash) void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *)) { + frrtrace(2, frr_libfrr, hash_get, hash, data); + unsigned int key; unsigned int index; void *newdata; @@ -172,6 +175,8 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *)) hash->index[index] = bucket; hash->count++; + frrtrace(3, frr_libfrr, hash_insert, hash, data, key); + int oldlen = bucket->next ? bucket->next->len : 0; int newlen = oldlen + 1; @@ -206,7 +211,7 @@ unsigned int string_hash_make(const char *str) void *hash_release(struct hash *hash, void *data) { - void *ret; + void *ret = NULL; unsigned int key; unsigned int index; struct hash_bucket *bucket; @@ -236,11 +241,14 @@ void *hash_release(struct hash *hash, void *data) ret = bucket->data; XFREE(MTYPE_HASH_BACKET, bucket); hash->count--; - return ret; + break; } pp = bucket; } - return NULL; + + frrtrace(3, frr_libfrr, hash_release, hash, data, ret); + + return ret; } void hash_iterate(struct hash *hash, void (*func)(struct hash_bucket *, void *), @@ -826,7 +826,7 @@ DEFUN (show_address, p = ifc->address; if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + vty_out (vty, "%pFX\n", p); } } return CMD_SUCCESS; @@ -858,7 +858,7 @@ DEFUN (show_address_vrf_all, p = ifc->address; if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + vty_out (vty, "%pFX\n", p); } } } @@ -929,10 +929,9 @@ connected_log(struct connected *connected, char *str) p = connected->address; vrf = vrf_lookup_by_id(ifp->vrf_id); - snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %s/%d ", + snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %pFX ", str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, - prefix_family_str(p), - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + prefix_family_str(p), p); p = connected->destination; if (p) { @@ -949,14 +948,12 @@ nbr_connected_log(struct nbr_connected *connected, char *str) struct prefix *p; struct interface *ifp; char logbuf[BUFSIZ]; - char buf[BUFSIZ]; ifp = connected->ifp; p = connected->address; - snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str, - ifp->name, prefix_family_str(p), - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %pFX ", str, + ifp->name, prefix_family_str(p), p); zlog_info("%s", logbuf); } @@ -1109,8 +1106,8 @@ ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp) if (rn) { route_unlock_node (rn); - zlog_info ("ifaddr_ipv4_add(): address %s is already added", - inet_ntoa (*ifaddr)); + zlog_info("ifaddr_ipv4_add(): address %pI4 is already added", + ifaddr); return; } rn->info = ifp; @@ -1129,8 +1126,7 @@ ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp) rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p); if (! rn) { - zlog_info ("ifaddr_ipv4_delete(): can't find address %s", - inet_ntoa (*ifaddr)); + zlog_info("%s: can't find address %pI4", __func__, ifaddr); return; } rn->info = NULL; diff --git a/lib/ldp_sync.c b/lib/ldp_sync.c index 9657f0b1df..c9d7eb37cf 100644 --- a/lib/ldp_sync.c +++ b/lib/ldp_sync.c @@ -79,7 +79,7 @@ bool ldp_sync_if_down(struct ldp_sync_info *ldp_sync_info) * update state */ if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + THREAD_OFF(ldp_sync_info->t_holddown); if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP) ldp_sync_info->state = diff --git a/lib/libfrr_trace.c b/lib/libfrr_trace.c new file mode 100644 index 0000000000..2f300e6ee1 --- /dev/null +++ b/lib/libfrr_trace.c @@ -0,0 +1,4 @@ +#define TRACEPOINT_CREATE_PROBES +#define TRACEPOINT_DEFINE + +#include "libfrr_trace.h" diff --git a/lib/libfrr_trace.h b/lib/libfrr_trace.h new file mode 100644 index 0000000000..7215007ffb --- /dev/null +++ b/lib/libfrr_trace.h @@ -0,0 +1,240 @@ +/* Tracing + * + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(_LIBFRR_TRACE_H_) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define _LIBFRR_TRACE_H_ + +#include "trace.h" + +#ifdef HAVE_LTTNG + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER frr_libfrr + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./libfrr_trace.h" + +#include <lttng/tracepoint.h> + +#include "hash.h" +#include "thread.h" +#include "memory.h" +#include "linklist.h" +#include "table.h" + +/* clang-format off */ + +TRACEPOINT_EVENT( + frr_libfrr, + hash_get, + TP_ARGS(struct hash *, hash, void *, data), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_get, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_libfrr, + hash_insert, + TP_ARGS(struct hash *, hash, void *, data, unsigned int, key), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, key, hash->size) + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_insert, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_libfrr, + hash_release, + TP_ARGS(struct hash *, hash, void *, data, void *, released_item), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ctf_integer_hex(intptr_t, released_item, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO) + +#define THREAD_SCHEDULE_ARGS \ + TP_ARGS(struct thread_master *, master, const char *, funcname, \ + const char *, schedfrom, int, fromln, struct thread **, \ + thread_ptr, int, fd, int, val, void *, arg, long, time) + +TRACEPOINT_EVENT_CLASS( + frr_libfrr, + thread_operation, + THREAD_SCHEDULE_ARGS, + TP_FIELDS( + ctf_string(threadmaster_name, master->name) + ctf_string(function_name, funcname ? funcname : "(unknown function)") + ctf_string(scheduled_from, schedfrom ? schedfrom : "(unknown file)") + ctf_integer(int, scheduled_on_line, fromln) + ctf_integer_hex(intptr_t, thread_addr, thread_ptr ? *thread_ptr : NULL) + ctf_integer(int, file_descriptor, fd) + ctf_integer(int, event_value, val) + ctf_integer_hex(intptr_t, argument_ptr, arg) + ctf_integer(long, timer, time) + ) +) + +#define THREAD_OPERATION_TRACEPOINT_INSTANCE(name) \ + TRACEPOINT_EVENT_INSTANCE(frr_libfrr, thread_operation, name, \ + THREAD_SCHEDULE_ARGS) \ + TRACEPOINT_LOGLEVEL(frr_libfrr, name, TRACE_INFO) + +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_timer) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call) + +TRACEPOINT_EVENT( + frr_libfrr, + frr_pthread_run, + TP_ARGS( + char *, name + ), + TP_FIELDS( + ctf_string(frr_pthread_name, name) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + frr_pthread_stop, + TP_ARGS( + char *, name + ), + TP_FIELDS( + ctf_string(frr_pthread_name, name) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + memalloc, + TP_ARGS( + struct memtype *, mt, void *, ptr, size_t, size + ), + TP_FIELDS( + ctf_string(memtype, mt->name) + ctf_integer(size_t, size, size) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + memfree, + TP_ARGS( + struct memtype *, mt, void *, ptr + ), + TP_FIELDS( + ctf_string(memtype, mt->name) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_add, + TP_ARGS( + struct list *, list, const void *, ptr + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_remove, + TP_ARGS( + struct list *, list, const void *, ptr + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_delete_node, + TP_ARGS( + struct list *, list, const void *, node + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, node, node) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_sort, + TP_ARGS( + struct list *, list + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + route_node_get, + TP_ARGS( + struct route_table *, table, char *, prefix + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, table, table) + ctf_string(prefix, prefix) + ) +) + +/* clang-format on */ + +#include <lttng/tracepoint-event.h> +#include <lttng/tracelog.h> + +#endif /* HAVE_LTTNG */ + +#endif /* _LIBFRR_TRACE_H_ */ diff --git a/lib/linklist.c b/lib/linklist.c index 84dc6e1419..43c2002231 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -23,6 +23,7 @@ #include "linklist.h" #include "memory.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List") DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node") @@ -66,6 +67,8 @@ static void listnode_free(struct list *list, struct listnode *node) struct listnode *listnode_add(struct list *list, void *val) { + frrtrace(2, frr_libfrr, list_add, list, val); + struct listnode *node; assert(val != NULL); @@ -281,6 +284,8 @@ void listnode_move_to_tail(struct list *l, struct listnode *n) void listnode_delete(struct list *list, const void *val) { + frrtrace(2, frr_libfrr, list_remove, list, val); + struct listnode *node = listnode_lookup(list, val); if (node) @@ -360,6 +365,8 @@ struct listnode *listnode_lookup_nocheck(struct list *list, void *data) void list_delete_node(struct list *list, struct listnode *node) { + frrtrace(2, frr_libfrr, list_delete_node, list, node); + if (node->prev) node->prev->next = node->next; else @@ -374,6 +381,8 @@ void list_delete_node(struct list *list, struct listnode *node) void list_sort(struct list *list, int (*cmp)(const void **, const void **)) { + frrtrace(1, frr_libfrr, list_sort, list); + struct listnode *ln, *nn; int i = -1; void *data; diff --git a/lib/memory.c b/lib/memory.c index 2c902d123b..f715044ea3 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -29,6 +29,7 @@ #include "memory.h" #include "log.h" +#include "libfrr_trace.h" static struct memgroup *mg_first = NULL; struct memgroup **mg_insert = &mg_first; @@ -77,6 +78,8 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr) static inline void mt_count_free(struct memtype *mt, void *ptr) { + frrtrace(2, frr_libfrr, memfree, mt, ptr); + assert(mt->n_alloc); atomic_fetch_sub_explicit(&mt->n_alloc, 1, memory_order_relaxed); @@ -89,6 +92,8 @@ static inline void mt_count_free(struct memtype *mt, void *ptr) static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size) { + frrtrace(3, frr_libfrr, memalloc, mt, ptr, size); + if (__builtin_expect(ptr == NULL, 0)) { if (size) { /* malloc(0) is allowed to return NULL */ diff --git a/lib/nexthop.c b/lib/nexthop.c index f1575649b1..b2fa945690 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -431,13 +431,13 @@ const char *nexthop2str(const struct nexthop *nexthop, char *str, int size) break; case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - snprintf(str, size, "%s if %u", inet_ntoa(nexthop->gate.ipv4), - nexthop->ifindex); + snprintfrr(str, size, "%pI4 if %u", &nexthop->gate.ipv4, + nexthop->ifindex); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - snprintf(str, size, "%s if %u", inet6_ntoa(nexthop->gate.ipv6), - nexthop->ifindex); + snprintfrr(str, size, "%pI6 if %u", &nexthop->gate.ipv6, + nexthop->ifindex); break; case NEXTHOP_TYPE_BLACKHOLE: snprintf(str, size, "blackhole"); diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 4afb1d642a..dee98ad8d7 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -975,7 +975,6 @@ void nexthop_group_write_nexthop_simple(struct vty *vty, const struct nexthop *nh, char *altifname) { - char buf[100]; char *ifname; vty_out(vty, "nexthop "); @@ -990,19 +989,16 @@ void nexthop_group_write_nexthop_simple(struct vty *vty, vty_out(vty, "%s", ifname); break; case NEXTHOP_TYPE_IPV4: - vty_out(vty, "%s", inet_ntoa(nh->gate.ipv4)); + vty_out(vty, "%pI4", &nh->gate.ipv4); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, "%s %s", inet_ntoa(nh->gate.ipv4), ifname); + vty_out(vty, "%pI4 %s", &nh->gate.ipv4, ifname); break; case NEXTHOP_TYPE_IPV6: - vty_out(vty, "%s", - inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf))); + vty_out(vty, "%pI6", &nh->gate.ipv6); break; case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out(vty, "%s %s", - inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)), - ifname); + vty_out(vty, "%pI6 %s", &nh->gate.ipv6, ifname); break; case NEXTHOP_TYPE_BLACKHOLE: break; @@ -1056,10 +1052,14 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) ifindex2ifname(nh->ifindex, nh->vrf_id)); break; case NEXTHOP_TYPE_IPV4: - json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4)); + json_object_string_add( + j, "nexthop", + inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf))); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4)); + json_object_string_add( + j, "nexthop", + inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf))); json_object_string_add(j, "vrfId", ifindex2ifname(nh->ifindex, nh->vrf_id)); break; diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index a7f3a1b305..7048df99fb 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -89,7 +89,7 @@ static int nb_cli_classic_commit(struct vty *vty) static void nb_cli_pending_commit_clear(struct vty *vty) { - THREAD_TIMER_OFF(vty->t_pending_commit); + THREAD_OFF(vty->t_pending_commit); vty->backoff_cmd_count = 0; XFREE(MTYPE_TMP, vty->pending_cmds_buf); vty->pending_cmds_buflen = 0; @@ -154,7 +154,7 @@ static int nb_cli_schedule_command(struct vty *vty) vty->pending_cmds_buflen); /* Schedule the commit operation. */ - THREAD_TIMER_OFF(vty->t_pending_commit); + THREAD_OFF(vty->t_pending_commit); thread_add_timer_msec(master, nb_cli_pending_commit_cb, vty, 100, &vty->t_pending_commit); @@ -312,7 +312,7 @@ int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, void nb_cli_confirmed_commit_clean(struct vty *vty) { - THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout); + thread_cancel(&vty->t_confirmed_commit_timeout); nb_config_free(vty->confirmed_commit_rollback); vty->confirmed_commit_rollback = NULL; } @@ -377,7 +377,7 @@ static int nb_cli_commit(struct vty *vty, bool force, "%% Resetting confirmed-commit timeout to %u minute(s)\n\n", confirmed_timeout); - THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout); + thread_cancel(&vty->t_confirmed_commit_timeout); thread_add_timer(master, nb_cli_confirmed_commit_timeout, vty, confirmed_timeout * 60, diff --git a/lib/plist.c b/lib/plist.c index 981e86e2ac..4588dfe1d3 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -901,14 +901,11 @@ static void __attribute__((unused)) prefix_list_print(struct prefix_list *plist) printf("any %s\n", prefix_list_type_str(pentry)); else { struct prefix *p; - char buf[BUFSIZ]; p = &pentry->prefix; - printf(" seq %lld %s %s/%d", (long long)pentry->seq, - prefix_list_type_str(pentry), - inet_ntop(p->family, p->u.val, buf, BUFSIZ), - p->prefixlen); + printf(" seq %lld %s %pFX", (long long)pentry->seq, + prefix_list_type_str(pentry), p); if (pentry->ge) printf(" ge %d", pentry->ge); if (pentry->le) @@ -1014,12 +1011,8 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi, vty_out(vty, "any"); else { struct prefix *p = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, "%s/%d", - inet_ntop(p->family, p->u.val, buf, - BUFSIZ), - p->prefixlen); + vty_out(vty, "%pFX", p); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); @@ -1121,12 +1114,8 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi, vty_out(vty, "any"); else { struct prefix *pf = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, "%s/%d", - inet_ntop(pf->family, pf->u.val, buf, - BUFSIZ), - pf->prefixlen); + vty_out(vty, "%pFX", pf); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); @@ -1491,11 +1480,8 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, for (pentry = plist->head; pentry; pentry = pentry->next) { struct prefix *p = &pentry->prefix; char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - snprintf(buf_a, sizeof(buf_a), "%s/%d", - inet_ntop(p->family, p->u.val, buf_b, BUFSIZ), - p->prefixlen); + snprintf(buf_a, sizeof(buf_a), "%pFX", p); json_object_int_add(json_list, "seq", pentry->seq); json_object_string_add(json_list, "seqPrefixListType", @@ -1526,13 +1512,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, for (pentry = plist->head; pentry; pentry = pentry->next) { struct prefix *p = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, " seq %" PRId64 " %s %s/%d", - pentry->seq, - prefix_list_type_str(pentry), - inet_ntop(p->family, p->u.val, buf, BUFSIZ), - p->prefixlen); + vty_out(vty, " seq %" PRId64 " %s %pFX", pentry->seq, + prefix_list_type_str(pentry), p); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); diff --git a/lib/routemap.c b/lib/routemap.c index fb70860024..0eb54a4794 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -2377,7 +2377,6 @@ route_map_result_t route_map_apply(struct route_map *map, route_map_result_t ret = RMAP_PERMITMATCH; struct route_map_index *index = NULL; struct route_map_rule *set = NULL; - char buf[PREFIX_STRLEN]; bool skip_match_clause = false; if (recursion > RMAP_RECURSION_LIMIT) { @@ -2403,16 +2402,14 @@ route_map_result_t route_map_apply(struct route_map *map, if (index) { if (rmap_debug) zlog_debug( - "Best match route-map: %s, sequence: %d for pfx: %s, result: %s", - map->name, index->pref, - prefix2str(prefix, buf, sizeof(buf)), + "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s", + map->name, index->pref, prefix, route_map_cmd_result_str(match_ret)); } else { if (rmap_debug) zlog_debug( - "No best match sequence for pfx: %s in route-map: %s, result: %s", - prefix2str(prefix, buf, sizeof(buf)), - map->name, + "No best match sequence for pfx: %pFX in route-map: %s, result: %s", + prefix, map->name, route_map_cmd_result_str(match_ret)); /* * No index matches this prefix. Return deny unless, @@ -2437,9 +2434,8 @@ route_map_result_t route_map_apply(struct route_map *map, prefix, type, object); if (rmap_debug) { zlog_debug( - "Route-map: %s, sequence: %d, prefix: %s, result: %s", - map->name, index->pref, - prefix2str(prefix, buf, sizeof(buf)), + "Route-map: %s, sequence: %d, prefix: %pFX, result: %s", + map->name, index->pref, prefix, route_map_cmd_result_str(match_ret)); } } else @@ -2549,12 +2545,10 @@ route_map_result_t route_map_apply(struct route_map *map, } route_map_apply_end: - if (rmap_debug) { - zlog_debug("Route-map: %s, prefix: %s, result: %s", - (map ? map->name : "null"), - prefix2str(prefix, buf, sizeof(buf)), + if (rmap_debug) + zlog_debug("Route-map: %s, prefix: %pFX, result: %s", + (map ? map->name : "null"), prefix, route_map_result_str(ret)); - } return (ret); } @@ -3156,8 +3150,6 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, struct list *rmap_index_list = NULL; struct listnode *ln = NULL, *nln = NULL; struct route_map_index *index = NULL; - struct prefix *p = NULL, *pp = NULL; - char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN]; uint8_t len = 54; vty_out(vty, "%s:\n", frr_protonameinst); @@ -3171,22 +3163,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, "____________________"); for (rn = route_top(rm_pfx_tbl4); rn; rn = route_next(rn)) { - p = &rn->p; - - vty_out(vty, " %s/%d (%d)\n", - inet_ntop(p->family, &p->u.prefix, buf, - SU_ADDRSTRLEN), - p->prefixlen, rn->lock); + vty_out(vty, " %pRN (%d)\n", rn, + route_node_get_lock_count(rn)); vty_out(vty, "(P) "); prn = rn->parent; if (prn) { - pp = &prn->p; - vty_out(vty, "%s/%d\n", - inet_ntop(pp->family, - &pp->u.prefix, pbuf, - SU_ADDRSTRLEN), - pp->prefixlen); + vty_out(vty, "%pRN\n", prn); } vty_out(vty, "\n"); @@ -3215,22 +3198,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, "____________________"); for (rn = route_top(rm_pfx_tbl6); rn; rn = route_next(rn)) { - p = &rn->p; - - vty_out(vty, " %s/%d (%d)\n", - inet_ntop(p->family, &p->u.prefix, buf, - SU_ADDRSTRLEN), - p->prefixlen, rn->lock); + vty_out(vty, " %pRN (%d)\n", rn, + route_node_get_lock_count(rn)); vty_out(vty, "(P) "); prn = rn->parent; if (prn) { - pp = &prn->p; - vty_out(vty, "%s/%d\n", - inet_ntop(pp->family, - &pp->u.prefix, pbuf, - SU_ADDRSTRLEN), - pp->prefixlen); + vty_out(vty, "%pRN\n", prn); } vty_out(vty, "\n"); diff --git a/lib/sockunion.c b/lib/sockunion.c index d77229797c..c999845659 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -587,15 +587,11 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su) switch (su->sa.sa_family) { case AF_INET: - printf("%s\n", inet_ntoa(su->sin.sin_addr)); + printf("%pI4\n", &su->sin.sin_addr); + break; + case AF_INET6: + printf("%pI6\n", &su->sin6.sin6_addr); break; - case AF_INET6: { - char buf[SU_ADDRSTRLEN]; - - printf("%s\n", inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, - sizeof(buf))); - } break; - #ifdef AF_LINK case AF_LINK: { struct sockaddr_dl *sdl; diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c index acb208e5e7..ac6dd29f06 100644 --- a/lib/spf_backoff.c +++ b/lib/spf_backoff.c @@ -110,8 +110,8 @@ void spf_backoff_free(struct spf_backoff *backoff) if (!backoff) return; - THREAD_TIMER_OFF(backoff->t_holddown); - THREAD_TIMER_OFF(backoff->t_timetolearn); + thread_cancel(&backoff->t_holddown); + thread_cancel(&backoff->t_timetolearn); XFREE(MTYPE_SPF_BACKOFF_NAME, backoff->name); XFREE(MTYPE_SPF_BACKOFF, backoff); @@ -121,7 +121,6 @@ static int spf_backoff_timetolearn_elapsed(struct thread *thread) { struct spf_backoff *backoff = THREAD_ARG(thread); - backoff->t_timetolearn = NULL; backoff->state = SPF_BACKOFF_LONG_WAIT; backoff_debug("SPF Back-off(%s) TIMETOLEARN elapsed, move to state %s", backoff->name, spf_backoff_state2str(backoff->state)); @@ -132,7 +131,7 @@ static int spf_backoff_holddown_elapsed(struct thread *thread) { struct spf_backoff *backoff = THREAD_ARG(thread); - THREAD_TIMER_OFF(backoff->t_timetolearn); + THREAD_OFF(backoff->t_timetolearn); timerclear(&backoff->first_event_time); backoff->state = SPF_BACKOFF_QUIET; backoff_debug("SPF Back-off(%s) HOLDDOWN elapsed, move to state %s", @@ -166,7 +165,7 @@ long spf_backoff_schedule(struct spf_backoff *backoff) break; case SPF_BACKOFF_SHORT_WAIT: case SPF_BACKOFF_LONG_WAIT: - THREAD_TIMER_OFF(backoff->t_holddown); + thread_cancel(&backoff->t_holddown); thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed, backoff, backoff->holddown, &backoff->t_holddown); diff --git a/lib/subdir.am b/lib/subdir.am index 55f127b019..ed3c30799d 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -3,7 +3,7 @@ # lib_LTLIBRARIES += lib/libfrr.la lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version -lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(LIBM) +lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST_LIBS) $(LIBM) lib_libfrr_la_SOURCES = \ lib/agg_table.c \ @@ -46,6 +46,7 @@ lib_libfrr_la_SOURCES = \ lib/lib_errors.c \ lib/lib_vty.c \ lib/libfrr.c \ + lib/libfrr_trace.c \ lib/linklist.c \ lib/log.c \ lib/log_filter.c \ @@ -204,6 +205,7 @@ pkginclude_HEADERS += \ lib/lib_errors.h \ lib/lib_vty.h \ lib/libfrr.h \ + lib/libfrr_trace.h \ lib/libospf.h \ lib/linklist.h \ lib/log.h \ @@ -251,6 +253,7 @@ pkginclude_HEADERS += \ lib/table.h \ lib/termtable.h \ lib/thread.h \ + lib/trace.h \ lib/typerb.h \ lib/typesafe.h \ lib/vector.h \ @@ -401,7 +404,7 @@ lib_grammar_sandbox_LDADD = \ lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY lib_clippy_CFLAGS = $(PYTHON_CFLAGS) -lib_clippy_LDADD = $(PYTHON_LIBS) +lib_clippy_LDADD = $(PYTHON_LIBS) $(UST_LIBS) lib_clippy_LDFLAGS = -export-dynamic lib_clippy_SOURCES = \ lib/clippy.c \ @@ -411,6 +414,7 @@ lib_clippy_SOURCES = \ lib/command_py.c \ lib/defun_lex.l \ lib/graph.c \ + lib/libfrr_trace.c \ lib/memory.c \ lib/vector.c \ # end diff --git a/lib/table.c b/lib/table.c index 86347cbacd..89e32182b5 100644 --- a/lib/table.c +++ b/lib/table.c @@ -27,6 +27,7 @@ #include "table.h" #include "memory.h" #include "sockunion.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table") DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node") @@ -119,7 +120,8 @@ static void route_table_free(struct route_table *rt) node = node->parent; tmp_node->table->count--; - tmp_node->lock = 0; /* to cause assert if unlocked after this */ + tmp_node->lock = + 0; /* to cause assert if unlocked after this */ rn_hash_node_del(&rt->hash, tmp_node); route_node_free(rt, tmp_node); @@ -275,6 +277,12 @@ struct route_node *route_node_lookup_maynull(struct route_table *table, struct route_node *route_node_get(struct route_table *table, union prefixconstptr pu) { + if (frrtrace_enabled(frr_libfrr, route_node_get)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(pu, buf, sizeof(buf)); + frrtrace(2, frr_libfrr, route_node_get, table, buf); + } + struct route_node search; struct prefix *p = &search.p; diff --git a/lib/table.h b/lib/table.h index 9cd9503376..5d620d332b 100644 --- a/lib/table.h +++ b/lib/table.h @@ -262,6 +262,11 @@ static inline void route_unlock_node(struct route_node *node) route_node_delete(node); } +static inline unsigned int route_node_get_lock_count(struct route_node *node) +{ + return node->lock; +} + /* * route_table_iter_next * diff --git a/lib/thread.c b/lib/thread.c index db35a3f031..1765de9573 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -35,6 +35,7 @@ #include "frratomic.h" #include "frr_pthread.h" #include "lib_errors.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread") DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master") @@ -787,6 +788,13 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, struct thread *thread = NULL; struct thread **thread_array; + if (dir == THREAD_READ) + frrtrace(9, frr_libfrr, schedule_read, m, funcname, schedfrom, + fromln, t_ptr, fd, 0, arg, 0); + else + frrtrace(9, frr_libfrr, schedule_write, m, funcname, schedfrom, + fromln, t_ptr, fd, 0, arg, 0); + assert(fd >= 0 && fd < m->fd_limit); frr_with_mutex(&m->mtx) { if (t_ptr && *t_ptr) @@ -861,6 +869,9 @@ funcname_thread_add_timer_timeval(struct thread_master *m, assert(type == THREAD_TIMER); assert(time_relative); + frrtrace(9, frr_libfrr, schedule_timer, m, funcname, schedfrom, fromln, + t_ptr, 0, 0, arg, (long)time_relative->tv_sec); + frr_with_mutex(&m->mtx) { if (t_ptr && *t_ptr) /* thread is already scheduled; don't reschedule */ @@ -939,6 +950,9 @@ struct thread *funcname_thread_add_event(struct thread_master *m, { struct thread *thread = NULL; + frrtrace(9, frr_libfrr, schedule_event, m, funcname, schedfrom, fromln, + t_ptr, 0, val, arg, 0); + assert(m != NULL); frr_with_mutex(&m->mtx) { @@ -1163,19 +1177,30 @@ void thread_cancel_event(struct thread_master *master, void *arg) * * @param thread task to cancel */ -void thread_cancel(struct thread *thread) +void thread_cancel(struct thread **thread) { - struct thread_master *master = thread->master; + struct thread_master *master; + + if (thread == NULL || *thread == NULL) + return; + + master = (*thread)->master; + + frrtrace(9, frr_libfrr, thread_cancel, master, thread->funcname, + thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd, + thread->u.val, thread->arg, thread->u.sands.tv_sec); assert(master->owner == pthread_self()); frr_with_mutex(&master->mtx) { struct cancel_req *cr = XCALLOC(MTYPE_TMP, sizeof(struct cancel_req)); - cr->thread = thread; + cr->thread = *thread; listnode_add(master->cancel_req, cr); do_thread_cancel(master); } + + *thread = NULL; } /** @@ -1206,6 +1231,17 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread, void *eventobj) { assert(!(thread && eventobj) && (thread || eventobj)); + + if (thread && *thread) + frrtrace(9, frr_libfrr, thread_cancel_async, master, + (*thread)->funcname, (*thread)->schedfrom, + (*thread)->schedfrom_line, NULL, (*thread)->u.fd, + (*thread)->u.val, (*thread)->arg, + (*thread)->u.sands.tv_sec); + else + frrtrace(9, frr_libfrr, thread_cancel_async, master, NULL, NULL, + 0, NULL, 0, 0, eventobj, 0); + assert(master->owner != pthread_self()); frr_with_mutex(&master->mtx) { @@ -1227,6 +1263,9 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread, while (!master->canceled) pthread_cond_wait(&master->cancel_cond, &master->mtx); } + + if (thread) + *thread = NULL; } /* ------------------------------------------------------------------------- */ @@ -1581,6 +1620,10 @@ void thread_call(struct thread *thread) GETRUSAGE(&before); thread->real = before.real; + frrtrace(9, frr_libfrr, thread_call, thread->master, thread->funcname, + thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd, + thread->u.val, thread->arg, thread->u.sands.tv_sec); + pthread_setspecific(thread_current, thread); (*thread->func)(thread); pthread_setspecific(thread_current, NULL); diff --git a/lib/thread.h b/lib/thread.h index c22b2105cd..e2b7763c51 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -147,18 +147,15 @@ struct cpu_thread_history { #define THREAD_FD(X) ((X)->u.fd) #define THREAD_VAL(X) ((X)->u.val) -#define THREAD_OFF(thread) \ - do { \ - if (thread) { \ - thread_cancel(thread); \ - thread = NULL; \ - } \ +/* + * Please consider this macro deprecated, and do not use it in new code. + */ +#define THREAD_OFF(thread) \ + do { \ + if ((thread)) \ + thread_cancel(&(thread)); \ } while (0) -#define THREAD_READ_OFF(thread) THREAD_OFF(thread) -#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread) -#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread) - #define debugargdef const char *funcname, const char *schedfrom, int fromln #define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__) @@ -207,7 +204,7 @@ extern void funcname_thread_execute(struct thread_master *, debugargdef); #undef debugargdef -extern void thread_cancel(struct thread *); +extern void thread_cancel(struct thread **event); extern void thread_cancel_async(struct thread_master *, struct thread **, void *); extern void thread_cancel_event(struct thread_master *, void *); diff --git a/lib/trace.h b/lib/trace.h new file mode 100644 index 0000000000..73fc10a556 --- /dev/null +++ b/lib/trace.h @@ -0,0 +1,80 @@ +/* Tracing macros + * + * Wraps tracepoint macros for different tracing systems to allow switching + * between them at compile time. + * + * This should not be included directly by source files wishing to provide + * tracepoints. Instead, write a header that defines LTTng tracepoints and + * which includes this header, and include your new header in your source. USDT + * probes do not need tracepoint definitions, but are less capable than LTTng + * tracepoints. + * + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _TRACE_H_ +#define _TRACE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +/* + * Provided here: + * - frrtrace(n, provider, name, ...args...) + * - frrtrace_enabled(provider, name) + * - frrtracelog(level, msg, ...) + * + * Use frrtrace() to define tracepoints. n is the number of arguments; this is + * needed because USDT probe definitions use DTRACE_PROBEn macros, so the + * number of args must be passed in order to expand the correct macro. + * + * frrtrace_enabled() maps to tracepoint_enabled() under LTTng and is always + * true when using USDT. In the future it could be mapped to USDT semaphores + * but this is not implemented at present. + * + * frrtracelog() maps to tracelog() under LTTng and should only be used in zlog + * core code, to propagate zlog messages to LTTng. It expands to nothing + * otherwise. + */ + +#if defined(HAVE_LTTNG) + +#define frrtrace(nargs, provider, name, ...) \ + tracepoint(provider, name, ## __VA_ARGS__) +#define frrtrace_enabled(...) tracepoint_enabled(__VA_ARGS__) +#define frrtracelog(...) tracelog(__VA_ARGS__) + +#elif defined(HAVE_USDT) + +#include "sys/sdt.h" + +#define frrtrace(nargs, provider, name, ...) \ + DTRACE_PROBE##nargs(provider, name, ## __VA_ARGS__) +#define frrtrace_enabled(...) true +#define frrtracelog(...) + +#else + +#define frrtrace(nargs, provider, name, ...) (void)0 +#define frrtrace_enabled(...) false +#define frrtracelog(...) (void)0 + +#endif + +#endif /* _TRACE_H_ */ diff --git a/lib/workqueue.c b/lib/workqueue.c index 54090d0d0f..f8e4677220 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -104,7 +104,7 @@ void work_queue_free_and_null(struct work_queue **wqp) struct work_queue *wq = *wqp; if (wq->thread != NULL) - thread_cancel(wq->thread); + thread_cancel(&(wq->thread)); while (!work_queue_empty(wq)) { struct work_queue_item *item = work_queue_last_item(wq); @@ -215,7 +215,7 @@ void workqueue_cmd_init(void) void work_queue_plug(struct work_queue *wq) { if (wq->thread) - thread_cancel(wq->thread); + thread_cancel(&(wq->thread)); wq->thread = NULL; diff --git a/lib/zassert.h b/lib/zassert.h index e50a88f407..e6b254ee8d 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -27,6 +27,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) __attribute__((noreturn)); +#undef __ASSERT_FUNCTION + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __ASSERT_FUNCTION __func__ #elif defined(__GNUC__) diff --git a/lib/zclient.c b/lib/zclient.c index 914b02749e..d0144279e5 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1116,13 +1116,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { /* limit the number of nexthops if necessary */ if (api->nexthop_num > MULTIPATH_NUM) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); flog_err( EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u nexthops (maximum is %u)", - __func__, buf, api->nexthop_num, MULTIPATH_NUM); + "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)", + __func__, &api->prefix, api->nexthop_num, + MULTIPATH_NUM); return -1; } @@ -1139,15 +1137,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) /* MPLS labels for BGP-LU or Segment Routing */ if (api_nh->label_num > MPLS_MAX_LABELS) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); - - flog_err(EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u labels (maximum is %u)", - __func__, buf, - api_nh->label_num, - MPLS_MAX_LABELS); + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: prefix %pFX: can't encode %u labels (maximum is %u)", + __func__, &api->prefix, + api_nh->label_num, MPLS_MAX_LABELS); return -1; } @@ -1162,13 +1156,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) { /* limit the number of nexthops if necessary */ if (api->backup_nexthop_num > MULTIPATH_NUM) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); flog_err( EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u backup nexthops (maximum is %u)", - __func__, buf, api->backup_nexthop_num, + "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)", + __func__, &api->prefix, api->backup_nexthop_num, MULTIPATH_NUM); return -1; } @@ -1185,15 +1176,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) /* MPLS labels for BGP-LU or Segment Routing */ if (api_nh->label_num > MPLS_MAX_LABELS) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); - - flog_err(EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: backup: can't encode %u labels (maximum is %u)", - __func__, buf, - api_nh->label_num, - MPLS_MAX_LABELS); + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)", + __func__, &api->prefix, + api_nh->label_num, MPLS_MAX_LABELS); return -1; } @@ -2319,13 +2306,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { /* carp interfaces on OpenBSD with 0.0.0.0/0 as * "peer" */ - char buf[PREFIX_STRLEN]; flog_err( EC_LIB_ZAPI_ENCODE, - "warning: interface %s address %s with peer flag set, but no peer address!", - ifp->name, - prefix2str(ifc->address, buf, - sizeof(buf))); + "warning: interface %s address %pFX with peer flag set, but no peer address!", + ifp->name, ifc->address); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } } diff --git a/lib/zlog.c b/lib/zlog.c index 8dfd20371b..e77feec5f2 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -52,6 +52,7 @@ #include "printfrr.h" #include "frrcu.h" #include "zlog.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message") DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer") @@ -450,6 +451,34 @@ void vzlog(int prio, const char *fmt, va_list ap) { struct zlog_tls *zlog_tls = zlog_tls_get(); +#ifdef HAVE_LTTNG + va_list copy; + va_copy(copy, ap); + char *msg = vasprintfrr(MTYPE_LOG_MESSAGE, fmt, copy); + + switch (prio) { + case LOG_ERR: + frrtracelog(TRACE_ERR, msg); + break; + case LOG_WARNING: + frrtracelog(TRACE_WARNING, msg); + break; + case LOG_DEBUG: + frrtracelog(TRACE_DEBUG, msg); + break; + case LOG_NOTICE: + frrtracelog(TRACE_DEBUG, msg); + break; + case LOG_INFO: + default: + frrtracelog(TRACE_INFO, msg); + break; + } + + va_end(copy); + XFREE(MTYPE_LOG_MESSAGE, msg); +#endif + if (zlog_tls) vzlog_tls(zlog_tls, prio, fmt, ap); else |
