20 #include <sys/types.h> 39 if (total_counts == 0)
48 percent = ((f64) vector_rate_histogram[SLEEP_##n##_US]) \ 49 / (f64) total_counts; \ 51 vlib_cli_output (vm, "Sleep %3d us: %llu, %.2f%%",n, \ 52 vector_rate_histogram[SLEEP_##n##_US], \ 67 .path =
"show api histogram",
68 .short_help =
"show api histogram",
91 .path =
"clear api histogram",
92 .short_help =
"clear api histogram",
105 u32 *confused_indices = 0;
111 "Name",
"PID",
"Queue Length",
"Queue VA",
"Health");
120 if (regp->unanswered_pings > 0)
121 health =
"questionable";
125 q = regp->vl_input_queue;
127 vlib_cli_output (vm,
"%20s %8d %14d 0x%016llx %s\n",
128 regp->name, q->consumer_pid, q->cursize,
133 clib_warning (
"NULL client registration index %d",
134 regpp - am->vl_clients);
135 vec_add1 (confused_indices, regpp - am->vl_clients);
144 for (i = 0; i <
vec_len (confused_indices); i++)
151 if (am->missing_clients)
153 am->missing_clients);
198 .short_help =
"Show API information",
208 .path =
"show api clients",
209 .short_help =
"Client information",
220 .path =
"show api trace-status",
221 .short_help =
"Display API trace status",
271 .path =
"show api message-table",
272 .short_help =
"Message Table",
280 int len0, len1, clen;
284 clen = len0 < len1 ? len0 : len1;
285 return (strncmp ((
char *) a0->
name, (
char *) a1->
name, clen));
294 s =
format (s,
"%-50s%9s%9s",
"Name",
"First-ID",
"Last-ID");
324 for (i = 0; i <
vec_len (rp); i++)
338 .path =
"show api plugin",
339 .short_help =
"show api plugin",
364 trace_name =
"TX trace";
369 trace_name =
"RX trace";
378 s =
format (s,
"%s: not yet configured.\n", trace_name);
382 s =
format (s,
"%s: used %d of %d items, %s enabled, %s wrapped\n",
389 __attribute__ ((weak));
397 u32 first_index,
u32 last_index,
398 vl_api_replay_t which)
400 vl_api_trace_file_header_t *hp;
407 u32 nitems, nitems_msgtbl;
408 void **saved_print_handlers = 0;
410 fd = open ((
char *) filename, O_RDONLY);
418 if (fstat (fd, &statb) < 0)
425 if (!(statb.st_mode & S_IFREG) || (statb.st_size < sizeof (*hp)))
432 file_size = statb.st_size;
433 file_size = (file_size + 4095) & ~(4096);
435 hp = mmap (0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
437 if (hp == (vl_api_trace_file_header_t *) MAP_FAILED)
447 nitems = ntohl (hp->nitems);
449 if (last_index == (
u32) ~ 0)
451 last_index = nitems - 1;
454 if (first_index >= nitems || last_index >= nitems)
457 first_index, last_index, nitems - 1);
458 munmap (hp, file_size);
464 "Note: wrapped/incomplete trace, results may vary\n");
472 msg = (
u8 *) (hp + 1);
476 u32 msgtbl_size = ntohl (hp->msgtbl_size);
482 for (i = 0; i < nitems_msgtbl; i++)
488 msgid_vec[msg_index] = msg_index2;
493 for (i = 0; i < first_index; i++)
499 size = clib_host_to_net_u32 (*(
u32 *) msg);
502 msg_id = ntohs (*((
u16 *) msg));
503 if (msg_id <
vec_len (msgid_vec))
504 msg_id = msgid_vec[msg_id];
509 munmap (hp, file_size);
519 for (; i <= last_index; i++)
528 size = clib_host_to_net_u32 (*(
u32 *) msg);
531 msg_id = ntohs (*((
u16 *) msg));
532 if (msg_id <
vec_len (msgid_vec))
534 msg_id = msgid_vec[msg_id];
541 munmap (hp, file_size);
560 void (*endian_fp) (
void *);
565 munmap (hp, file_size);
572 (*endian_fp) (tmpbuf +
sizeof (
uword));
589 u8 *(*print_fp) (
void *,
void *);
592 (*print_fp) (tmpbuf +
sizeof (
uword), vm);
608 u8 *(*print_fp) (
void *,
void *);
614 (*print_fp) (tmpbuf +
sizeof (
uword), vm);
617 s =
format (0,
"static u8 * vl_api_%s_%d[%d] = {",
625 s =
format (s,
"0x%02x,", tmpbuf[
sizeof (
uword) + j]);
627 s =
format (s,
"\n};\n%c", 0);
643 (*handler) (tmpbuf +
sizeof (
uword), vm);
657 _vec_len (tmpbuf) = 0;
661 if (saved_print_handlers)
668 munmap (hp, file_size);
688 u32 nitems = 256 << 10;
692 u8 *chroot_filename = 0;
702 if (
unformat (input,
"nitems %d", &nitems))
715 else if (
unformat (input,
"save %s", &filename))
717 if (strstr ((
char *) filename,
"..")
718 || index ((
char *) filename,
'/'))
725 chroot_filename =
format (0,
"/tmp/%s%c", filename, 0);
729 fp = fopen ((
char *) chroot_filename,
"w");
749 "Error while writing end of buffer trace to file\n");
752 "Error while writing start of buffer trace to file\n");
759 else if (
unformat (input,
"dump %s", &filename))
763 else if (
unformat (input,
"custom-dump %s", &filename))
767 else if (
unformat (input,
"replay %s", &filename))
771 else if (
unformat (input,
"initializers %s", &filename))
779 else if (
unformat (input,
"first %d", &first))
783 else if (
unformat (input,
"last %d", &last))
787 else if (
unformat (input,
"status"))
799 else if (
unformat (input,
"post-mortem-on"))
801 else if (
unformat (input,
"post-mortem-off"))
821 .short_help =
"api trace [on|off][first <n>][last <n>][status][free]" 822 "[post-mortem-on][dump|custom-dump|save|replay <file>]",
840 else if (
unformat (input,
"tx nitems %u", &nitems)
870 else if (
unformat (input,
"debug on"))
874 else if (
unformat (input,
"debug off"))
900 .path =
"set api-trace",
901 .short_help =
"API trace [on][on tx][on rx][off][free][debug on][debug off]",
909 u32 nitems = 256 << 10;
917 if (
unformat (input,
"nitems %d", &nitems))
923 else if (
unformat (input,
"save-api-table %s",
949 if (
unformat (input,
"length %d", &nitems) ||
950 (
unformat (input,
"len %d", &nitems)))
955 clib_warning (
"vlib input queue length %d too small, ignored",
990 for (i =
vec_len (rv) - 1; i >= 0; i--)
1040 int compare_current = 0;
1041 int numeric_sort = 0;
1044 u32 ndifferences = 0;
1048 if (
unformat (input,
"file %s", &filename))
1050 else if (
unformat (input,
"compare-current")
1052 compare_current = 1;
1053 else if (
unformat (input,
"numeric"))
1060 if (numeric_sort && compare_current)
1062 (0,
"Comparison and numeric sorting are incompatible");
1076 for (i = 0; i < nmsgs; i++)
1081 item->msg_index = msg_index;
1082 item->name_and_crc = name_and_crc;
1090 if (compare_current)
1098 for (i = 0; i < nmsgs; i++)
1104 item->msg_index = msg_index;
1105 item->name_and_crc = name_and_crc;
1119 if (compare_current)
1135 for (i = 0; i <
vec_len (table);)
1138 if (i == vec_len (table) - 1)
1146 ((
char *) table[i].name_and_crc,
1147 (
char *) table[i + 1].name_and_crc,
1148 vec_len (table[i].name_and_crc)))
1157 if (i + 1 == vec_len (table)
1158 || strcmp ((
char *) table[i].
name, (
char *) table[i + 1].name))
1162 table[i].name, table[i].which ?
1171 if (ndifferences == 0)
1180 vlib_cli_output (vm,
"%=60s %=8s %=10s",
"Message name",
"MsgID",
"CRC");
1182 for (i = 0; i <
vec_len (table); i++)
1186 item->msg_index, item->crc);
1190 for (i = 0; i <
vec_len (table); i++)
1237 .path =
"show api dump",
1238 .short_help =
"show api dump file <filename> [numeric | compare-current]",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Message range (belonging to a plugin)
static clib_error_t * vl_api_show_plugin_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
#define CLIB_MEM_UNPOISON(a, s)
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
u64 vector_rate_histogram[]
u8 * name
name of the plugin
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
u8 wrapped
trace has wrapped
int size
for sanity checking
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8 * message_bounce
Don't automatically free message buffer vetor.
#define vec_terminate_c_string(V)
(If necessary) NULL terminate a vector containing a c-string.
void vl_sock_api_dump_clients(vlib_main_t *vm, api_main_t *am)
static heap_elt_t * last(heap_header_t *h)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static u8 * extract_crc(u8 *s)
static vlib_cli_command_t cli_show_api_message_table_command
(constructor) VLIB_CLI_COMMAND (cli_show_api_message_table_command)
static int range_compare(vl_api_msg_range_t *a0, vl_api_msg_range_t *a1)
trace_cfg_t * api_trace_cfg
Current trace configuration.
#define vlib_worker_thread_barrier_sync(X)
#define clib_memcpy(d, s, n)
static clib_error_t * api_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
api_trace_command_fn - control the binary API trace / replay feature
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
vl_api_trace_t * rx_trace
Received message trace configuration.
void vl_msg_api_barrier_sync(void)
void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
vl_api_registration_t ** vl_clients
vlib/vpp only: vector of client registrations
#define foreach_histogram_bucket
#define clib_arch_is_little_endian
int replay_in_progress
Replay in progress?
#define clib_error_return(e, args...)
static clib_error_t * vl_api_clear_histogram_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
static clib_error_t * vl_api_client_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
static heap_elt_t * first(heap_header_t *h)
int vl_msg_api_trace_free(api_main_t *am, vl_api_trace_which_t which)
u16 last_msg_id
last assigned message ID
static int table_id_cmp(void *a1, void *a2)
void(** msg_print_handlers)(void *, void *)
Message print function vector.
int replay_enable
This message can be replayed.
static vlib_cli_command_t cli_show_api_plugin_command
(constructor) VLIB_CLI_COMMAND (cli_show_api_plugin_command)
#define vec_dup(V)
Return copy of vector (no header, no alignment)
static void cleanup(void)
#define VLIB_CONFIG_FUNCTION(x, n,...)
static clib_error_t * api_trace_config_fn(vlib_main_t *vm, unformat_input_t *input)
void unserialize_cstring(serialize_main_t *m, char **s)
static vlib_cli_command_t cli_show_api_command
(constructor) VLIB_CLI_COMMAND (cli_show_api_command)
API main structure, used by both vpp and binary API clients.
int vl_msg_api_trace_save(api_main_t *am, vl_api_trace_which_t which, FILE *fp)
u8 enabled
trace is enabled
An API client registration, only in vpp/vlib.
int vl_msg_api_trace_onoff(api_main_t *am, vl_api_trace_which_t which, int onoff)
static clib_error_t * vl_api_trace_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
void serialize_open_vector(serialize_main_t *m, u8 *vector)
#define vec_free(V)
Free vector's memory (no header).
vl_api_msg_range_t * msg_ranges
vector of message ranges
static u8 * extract_name(u8 *s)
clib_error_t * unserialize_open_clib_file(serialize_main_t *m, char *file)
static int table_name_and_crc_cmp(void *a1, void *a2)
#define clib_warning(format, args...)
u32 vl_msg_api_get_msg_index(u8 *name_and_crc)
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
static void vl_msg_api_process_file(vlib_main_t *vm, u8 *filename, u32 first_index, u32 last_index, vl_api_replay_t which)
const char ** msg_names
Message name vector.
void unserialize_close(serialize_main_t *m)
#define VLIB_CLI_COMMAND(x,...)
u8 * save_msg_table_filename
Dump (msg-name, crc) snapshot here at startup.
vl_api_trace_t * tx_trace
Sent message trace configuration.
#define pool_put_index(p, i)
Free pool element with given index.
static clib_error_t * vl_api_message_table_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
static clib_error_t * api_queue_config_fn(vlib_main_t *vm, unformat_input_t *input)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
vl_api_trace_which_t
Trace RX / TX enum.
u8 * vl_api_serialize_message_table(api_main_t *am, u8 *vector)
static clib_error_t * dump_api_table_file_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static vlib_cli_command_t cli_show_api_clients_command
(constructor) VLIB_CLI_COMMAND (cli_show_api_clients_command)
static clib_error_t * vl_api_status_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
u16 first_msg_id
first assigned message ID
void(** msg_endian_handlers)(void *)
Message endian handler vector.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
static vlib_cli_command_t cli_show_api_status_command
(constructor) VLIB_CLI_COMMAND (cli_show_api_status_command)
struct _svm_queue svm_queue_t
static api_main_t * vlibapi_get_main(void)
void(** msg_handlers)(void *)
Message handler vector.
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
u8 * is_mp_safe
Message is mp safe vector.
int msg_print_flag
Print every received message.
static vlib_cli_command_t api_trace_command
(constructor) VLIB_CLI_COMMAND (api_trace_command)
Trace configuration for a single message.
void vl_msg_api_custom_dump_configure(api_main_t *am)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
void vl_msg_api_barrier_release(void)
int vl_msg_api_trace_configure(api_main_t *am, vl_api_trace_which_t which, u32 nitems)
static clib_error_t * vl_api_show_histogram_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_cli_command_t dump_api_table_file
(constructor) VLIB_CLI_COMMAND (dump_api_table_file)
void vl_msg_api_post_mortem_dump_enable_disable(int enable)
static u8 * format_api_msg_range(u8 *s, va_list *args)
u32 nitems
Number of trace records.
u32 vlib_input_queue_length
vpp/vlib input queue length
u8 * format_vl_msg_api_trace_status(u8 *s, va_list *args)
#define CLIB_MEM_POISON(a, s)
static uword pool_elts(void *v)
Number of active elements in a pool.