diff options
Diffstat (limited to 'src/plugins/tracedump/tracedump.c')
-rw-r--r-- | src/plugins/tracedump/tracedump.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/plugins/tracedump/tracedump.c b/src/plugins/tracedump/tracedump.c index 0f1612c70cd..0c0f3b493b3 100644 --- a/src/plugins/tracedump/tracedump.c +++ b/src/plugins/tracedump/tracedump.c @@ -335,6 +335,143 @@ doublebreak:; vec_free (s); } +/* API message handler */ +static void +vl_api_trace_v2_dump_t_handler (vl_api_trace_v2_dump_t *mp) +{ + vl_api_registration_t *rp; + vl_api_trace_v2_details_t *dmp; + tracedump_main_t *tdmp = &tracedump_main; + vlib_trace_header_t ***client_trace_cache, **th; + int i, j; + u32 client_index; + u32 first_position, max, first_thread_id, last_thread_id; + u32 n_threads = vlib_get_n_threads (); + u8 *s = 0; + + rp = vl_api_client_index_to_registration (mp->client_index); + if (rp == 0) + return; + + client_index = rp->vl_api_registration_pool_index; + + vec_validate_init_empty (tdmp->traces, client_index, 0); + + client_trace_cache = tdmp->traces[client_index]; + + if (mp->clear_cache) + { + toss_client_cache (tdmp, client_index, client_trace_cache); + client_trace_cache = 0; + } + + /* Now, where were we? */ + first_thread_id = last_thread_id = clib_net_to_host_u32 (mp->thread_id); + first_position = clib_net_to_host_u32 (mp->position); + max = clib_net_to_host_u32 (mp->max); + + if (first_thread_id == ~0) + { + first_thread_id = 0; + last_thread_id = n_threads - 1; + } + + /* Don't overflow the existing queue space for shared memory API clients. */ + if (rp->vl_input_queue) + { + svm_queue_t *q = rp->vl_input_queue; + u32 queue_slots_available = q->maxsize - q->cursize; + int chunk = (queue_slots_available > 0) ? queue_slots_available - 1 : 0; + /* split available slots among requested threads */ + if (chunk < max * (last_thread_id - first_thread_id + 1)) + max = chunk / (last_thread_id - first_thread_id + 1); + } + + /* Need a fresh cache for this client? */ + if (vec_len (client_trace_cache) == 0 && first_position != ~0) + { + vlib_worker_thread_barrier_sync (vlib_get_first_main ()); + + /* Make a slot for each worker thread */ + vec_validate (client_trace_cache, n_threads - 1); + i = 0; + + foreach_vlib_main () + { + vlib_trace_main_t *tm = &this_vlib_main->trace_main; + + /* Filter as directed */ + trace_apply_filter (this_vlib_main); + + pool_foreach (th, tm->trace_buffer_pool) + { + vec_add1 (client_trace_cache[i], th[0]); + } + + /* Sort them by increasing time. */ + if (vec_len (client_trace_cache[i])) + vec_sort_with_function (client_trace_cache[i], trace_cmp); + + i++; + } + vlib_worker_thread_barrier_release (vlib_get_first_main ()); + } + + /* Save the cache, one way or the other */ + tdmp->traces[client_index] = client_trace_cache; + + for (i = first_thread_id; i <= last_thread_id; i++) + { + // dump a number of 'max' packets per thead + for (j = first_position; + j < vec_len (client_trace_cache[i]) && j < first_position + max; + j++) + { + th = &client_trace_cache[i][j]; + + vec_reset_length (s); + + s = + format (s, "%U", format_vlib_trace, vlib_get_first_main (), th[0]); + + dmp = vl_msg_api_alloc (sizeof (*dmp) + vec_len (s)); + dmp->_vl_msg_id = + htons (VL_API_TRACE_V2_DETAILS + (tdmp->msg_id_base)); + dmp->context = mp->context; + dmp->thread_id = ntohl (i); + dmp->position = ntohl (j); + dmp->more = j < vec_len (client_trace_cache[i]) - 1; + vl_api_vec_to_api_string (s, &dmp->trace_data); + + vl_api_send_msg (rp, (u8 *) dmp); + } + } + + vec_free (s); +} + +static void +vl_api_trace_clear_cache_t_handler (vl_api_trace_clear_cache_t *mp) +{ + vl_api_registration_t *rp; + tracedump_main_t *tdmp = &tracedump_main; + vlib_trace_header_t ***client_trace_cache; + vl_api_trace_clear_cache_reply_t *rmp; + u32 client_index; + + rp = vl_api_client_index_to_registration (mp->client_index); + if (rp == 0) + return; + + client_index = rp->vl_api_registration_pool_index; + vec_validate_init_empty (tdmp->traces, client_index, 0); + client_trace_cache = tdmp->traces[client_index]; + toss_client_cache (tdmp, client_index, client_trace_cache); + + int rv = 0; + REPLY_MACRO (VL_API_TRACE_CLEAR_CACHE_REPLY); +} + /* API definitions */ #include <tracedump/tracedump.api.c> @@ -353,6 +490,7 @@ tracedump_init (vlib_main_t * vm) tdmp->msg_id_base = setup_message_id_table (); vl_api_set_msg_thread_safe (am, tdmp->msg_id_base + VL_API_TRACE_DUMP, 1); + vl_api_set_msg_thread_safe (am, tdmp->msg_id_base + VL_API_TRACE_V2_DUMP, 1); return error; } |