25 #include <sys/types.h> 78 u16 msg_id = ntohs(*((
u16 *)msg));
101 this_trace = old_trace;
106 *this_trace = msg_copy;
139 if (tp == 0 || tp->
nitems == 0)
169 if (!tp || tp->
nitems == 0)
187 vl_api_trace_file_header_t fh;
220 if (fwrite(&fh,
sizeof(fh), 1, fp) != 1) {
261 for (i = 0; i < tp->
curindex; i++) {
316 memset(tp, 0,
sizeof(*tp));
337 u16 id = ntohs(*((
u16 *)the_msg));
338 u8 *(*print_fp)(
void *,
void *);
346 fformat (stdout,
"[%d]: %s\n",
id,
350 fformat(stdout,
" [no registered print fn]\n");
352 (*print_fp)(the_msg, stdout);
372 #define ELOG_API_MESSAGE_HANDLERS 0 374 #if ELOG_API_MESSAGE_HANDLERS > 0 389 name_copy =
format (0,
"%s%c", msg_name, 0);
402 u16 id = ntohs(*((
u16 *)the_msg));
403 u8 *(*handler)(
void *,
void *,
void *);
405 #if ELOG_API_MESSAGE_HANDLERS > 0 408 .format =
"api-msg: %s",
411 struct {
u32 c; } * ed;
429 (*handler)(the_msg, vm, node);
442 #if ELOG_API_MESSAGE_HANDLERS > 0 445 .format =
"api-msg-done: %s",
448 struct {
u32 c; } * ed;
506 u16 id = ntohs(*((
u16 *)the_msg));
525 u16 id = ntohs(*((
u16 *)the_msg));
549 #define foreach_msg_api_vector \ 552 _(msg_cleanup_handlers) \ 553 _(msg_endian_handlers) \ 554 _(msg_print_handlers) \ 565 #define _(a) vec_validate (am->a, c->id); 587 void *endian,
void *print,
int size,
int traced)
668 u32 first_index,
u32 last_index,
671 vl_api_trace_file_header_t * hp;
676 u8 endian_swap_needed = 0;
680 void **saved_print_handlers = 0;
682 fd = open ((
char *) filename, O_RDONLY);
689 if (fstat(fd, &statb) < 0) {
694 if (! (statb.st_mode & S_IFREG) || (statb.st_size < sizeof (*hp))) {
699 file_size = statb.st_size;
700 file_size = (file_size + 4095) & ~(4096);
702 hp = mmap (0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
704 if (hp == (vl_api_trace_file_header_t *)MAP_FAILED) {
713 endian_swap_needed = 1;
715 if (endian_swap_needed)
716 nitems = ntohl(hp->nitems);
720 if (last_index == (
u32) ~0) {
721 last_index = nitems - 1;
724 if (first_index >= nitems || last_index >= nitems) {
726 first_index, last_index, nitems-1);
731 "Note: wrapped/incomplete trace, results may vary\n");
741 for (i = 0; i < first_index; i++) {
747 msg_id = ntohs(*((
u16 *)msg));
749 msg_id = *((
u16 *)msg);
760 for (; i <= last_index; i++) {
770 msg_id = ntohs(*((
u16 *)msg));
772 msg_id = *((
u16 *)msg);
784 memset (tmpbuf, 0xf,
sizeof(
uword));
793 || endian_swap_needed) {
794 void (*endian_fp)(
void *);
801 (*endian_fp)(tmpbuf+
sizeof(
uword));
806 msg_idp = (
u16 *)(tmpbuf+
sizeof(
uword));
815 u8 *(*print_fp)(
void *,
void *);
818 (*print_fp)(tmpbuf+
sizeof(
uword), vm);
831 u8 *(*print_fp)(
void *,
void *);
837 (*print_fp)(tmpbuf+
sizeof(
uword), vm);
840 s =
format (0,
"static u8 * vl_api_%s_%d[%d] = {",
847 s =
format (s,
"0x%02x,", tmpbuf[
sizeof(
uword)+j]);
849 s =
format (s,
"\n};\n%c", 0);
858 void (*handler)(
void *);
864 (*handler)(tmpbuf+
sizeof(
uword));
876 _vec_len(tmpbuf) = 0;
880 if (saved_print_handlers) {
886 munmap (hp, file_size);
900 trace_name =
"TX trace";
905 trace_name =
"RX trace";
913 s =
format (s,
"%s: not yet configured.\n", trace_name);
917 s =
format (s,
"%s: used %d of %d items, %s enabled, %s wrapped\n",
920 tp->
wrapped ?
"has" :
"has not");
931 u32 nitems = 256<<10;
942 if (
unformat (input,
"nitems %d", &nitems))
946 }
else if (
unformat (input,
"off")) {
948 }
else if (
unformat (input,
"save %s", &filename)) {
949 u8 * chroot_filename;
950 if (strstr((
char *)filename,
"..")
951 || index((
char *)filename,
'/'))
958 chroot_filename =
format (0,
"/tmp/%s%c", filename, 0);
962 fp = fopen ((
char *)chroot_filename,
"w");
975 }
else if (
unformat (input,
"dump %s", &filename)) {
977 }
else if (
unformat (input,
"custom-dump %s", &filename)) {
979 }
else if (
unformat (input,
"replay %s", &filename)) {
981 }
else if (
unformat (input,
"initializers %s", &filename)) {
983 }
else if (
unformat (input,
"tx")) {
985 }
else if (
unformat (input,
"first %d", &first)) {
987 }
else if (
unformat (input,
"last %d", &last)) {
989 }
else if (
unformat (input,
"status")) {
992 }
else if (
unformat (input,
"free")) {
995 }
else if (
unformat (input,
"post-mortem-on"))
997 else if (
unformat (input,
"post-mortem-off"))
1007 .path =
"api trace",
1009 "api trace [on|off][dump|save|replay <file>][status][free][post-mortem-on]",
1016 u32 nitems = 256<<10;
1022 if (
unformat (input,
"nitems %d", &nitems))
1046 snprintf (filename,
sizeof(filename),
"/tmp/api_post_mortem.%d",
1049 fp = fopen (filename,
"w");
1051 rv = write (2,
"Couldn't create ", 16);
1052 rv = write (2, filename, strlen(filename));
1053 rv = write (2,
"\n", 1);
1059 rv = write (2,
"Failed to save post-mortem API trace to ", 40);
1060 rv = write (2, filename, strlen(filename));
1061 rv = write (2,
"\n", 1);
1073 if (msg_id_host_byte_order > 10000)
1074 clib_warning (
"msg_id_host_byte_order endian issue? %d arg vs %d",
1075 msg_id_host_byte_order,
1076 clib_net_to_host_u16 (msg_id_host_byte_order));
1084 int (*fp)(
void *, int);
1088 msg_id = clib_net_to_host_u16(*((
u16 *)mp));
1090 msg_id = *((
u16 *)mp);
1119 name_copy =
format (0,
"%s%c", name, 0);
1123 clib_warning (
"WARNING: duplicate message range registration for '%s'",
1129 if (n < 0 || n > 1024) {
1131 (
"WARNING: bad number of message-IDs (%d) requested by '%s'",
1142 rp->
name = name_copy;
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void vl_msg_api_set_first_available_msg_id(u16 first_avail)
int vl_msg_api_trace_onoff(api_main_t *am, vl_api_trace_which_t which, int onoff)
int vl_msg_api_trace_save(api_main_t *am, vl_api_trace_which_t which, FILE *fp)
void vl_msg_api_set_handlers(int id, char *name, void *handler, void *cleanup, void *endian, void *print, int size, int traced)
int vl_msg_api_trace_free(api_main_t *am, vl_api_trace_which_t which)
sll srl srl sll sra u16x4 i
void vl_msg_api_set_cleanup_handler(int msg_id, void *fp)
int vl_msg_api_pd_handler(void *mp, int rv)
void vl_msg_api_handler(void *the_msg)
static void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
static u8 post_mortem_dump_enabled
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
vl_api_trace_t * vl_msg_api_trace_get(api_main_t *am, vl_api_trace_which_t which)
static void vl_msg_api_process_file(vlib_main_t *vm, u8 *filename, u32 first_index, u32 last_index, vl_api_replay_t which)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static clib_error_t * api_config_fn(vlib_main_t *vm, unformat_input_t *input)
#define hash_set_mem(h, key, value)
int vl_msg_api_trace_configure(api_main_t *am, vl_api_trace_which_t which, u32 nitems)
void(** msg_cleanup_handlers)(void *)
void vl_noop_handler(void *mp)
trace_cfg_t * api_trace_cfg
void vl_msg_api_handler_no_trace_no_free(void *the_msg)
clib_error_t * vl_api_init(vlib_main_t *vm)
void vl_msg_api_cleanup_handler(void *the_msg)
vl_api_trace_t * rx_trace
always_inline heap_elt_t * last(heap_header_t *h)
#define VLIB_INIT_FUNCTION(x)
void vl_msg_api_config(vl_msg_api_msg_config_t *c)
void vl_msg_api_free(void *)
#define clib_arch_is_little_endian
static clib_error_t * api_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define clib_warning(format, args...)
int vl_msg_api_tx_trace_enabled(api_main_t *am)
void vl_msg_api_trace_only(void *the_msg)
#define hash_create_string(elts, value_bytes)
void vl_msg_api_queue_handler(unix_shared_memory_queue_t *q)
void vl_msg_api_handler_with_vm_node(api_main_t *am, void *the_msg, vlib_main_t *vm, vlib_node_runtime_t *node)
always_inline heap_elt_t * first(heap_header_t *h)
int vl_msg_api_rx_trace_enabled(api_main_t *am)
void(** msg_print_handlers)(void *, void *)
#define vec_dup(V)
Return copy of vector (no header, no alignment)
#define VLIB_CONFIG_FUNCTION(x, n,...)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
u8 * format_vl_msg_api_trace_status(u8 *s, va_list *args)
#define clib_arch_is_big_endian
int unix_shared_memory_queue_sub(unix_shared_memory_queue_t *q, u8 *elem, int nowait)
#define VL_API_LITTLE_ENDIAN
#define vec_free(V)
Free vector's memory (no header).
void vl_msg_api_barrier_release(void)
vl_api_msg_range_t * msg_ranges
void vl_msg_api_post_mortem_dump(void)
#define clib_memcpy(a, b, c)
#define ELOG_TYPE_DECLARE(f)
#define VLIB_CLI_COMMAND(x,...)
void vl_msg_api_socket_handler(void *the_msg)
vl_api_trace_t * tx_trace
static u32 elog_id_for_msg_name(mc_main_t *m, char *msg_name)
always_inline void msg_handler_internal(api_main_t *am, void *the_msg, int trace_it, int do_it, int free_it)
#define VL_API_BIG_ENDIAN
void vl_msg_api_replay_handler(void *the_msg)
void vl_msg_api_handler_no_free(void *the_msg)
void vl_msg_api_increment_missing_client_counter(void)
void vl_msg_api_register_pd_handler(void *fp, u16 msg_id_host_byte_order)
void(** msg_endian_handlers)(void *)
u32 elog_string(elog_main_t *em, char *fmt,...)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int(** pd_msg_handlers)(void *, int)
#define foreach_msg_api_vector
#define hash_get_mem(h, key)
u16 first_available_msg_id
void(** msg_handlers)(void *)
void vl_msg_api_trace(api_main_t *am, vl_api_trace_t *tp, void *msg)
u16 vl_msg_api_get_msg_ids(char *name, int n)
#define clib_error_return(e, args...)
uword * msg_range_by_name
struct _unix_shared_memory_queue unix_shared_memory_queue_t
void vl_msg_api_custom_dump_configure(api_main_t *am)
void vl_msg_api_barrier_sync(void)