X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibapi%2Fapi_shared.c;h=28e9f481650e903a34123d522df0d4ab4f33dfc8;hb=2dbee9361e74d03727a8b618ba80a5e28c006011;hp=9579fe1c60fc43803fba9fb3b6ef8ef6848f9ad6;hpb=9683c1eceb8529ef5133670efd4a465eb5a740c8;p=vpp.git diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c index 9579fe1c60f..28e9f481650 100644 --- a/src/vlibapi/api_shared.c +++ b/src/vlibapi/api_shared.c @@ -32,7 +32,7 @@ #include /* *INDENT-OFF* */ -api_main_t api_main = +api_main_t api_global_main = { .region_name = "/unset", .api_uid = -1, @@ -40,10 +40,20 @@ api_main_t api_main = }; /* *INDENT-ON* */ +/* Please use vlibapi_get_main() to access my_api_main */ +__thread api_main_t *my_api_main = &api_global_main; + +void +vl_msg_api_set_global_main (void *am_arg) +{ + ASSERT (am_arg); + my_api_main = (api_main_t *) am_arg; +} + void vl_msg_api_increment_missing_client_counter (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); am->missing_clients++; } @@ -189,6 +199,29 @@ vl_msg_api_trace_free (api_main_t * am, vl_api_trace_which_t which) return 0; } +u8 * +vl_api_serialize_message_table (api_main_t * am, u8 * vector) +{ + serialize_main_t _sm, *sm = &_sm; + hash_pair_t *hp; + u32 nmsg = hash_elts (am->msg_index_by_name_and_crc); + + serialize_open_vector (sm, vector); + + /* serialize the count */ + serialize_integer (sm, nmsg, sizeof (u32)); + + /* *INDENT-OFF* */ + hash_foreach_pair (hp, am->msg_index_by_name_and_crc, + ({ + serialize_likely_small_unsigned_integer (sm, hp->value[0]); + serialize_cstring (sm, (char *) hp->key); + })); + /* *INDENT-ON* */ + + return serialize_close_vector (sm); +} + int vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp) { @@ -223,15 +256,23 @@ vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp) } /* Write the file header */ - fh.nitems = vec_len (tp->traces); - fh.endian = tp->endian; fh.wrapped = tp->wrapped; + fh.nitems = clib_host_to_net_u32 (vec_len (tp->traces)); + u8 *m = vl_api_serialize_message_table (am, 0); + fh.msgtbl_size = clib_host_to_net_u32 (vec_len (m)); if (fwrite (&fh, sizeof (fh), 1, fp) != 1) { return (-10); } + /* Write the message table */ + if (fwrite (m, vec_len (m), 1, fp) != 1) + { + return (-14); + } + vec_free (m); + /* No-wrap case */ if (tp->wrapped == 0) { @@ -398,6 +439,26 @@ msg_handler_internal (api_main_t * am, u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); u8 *(*print_fp) (void *, void *); + if (PREDICT_FALSE (am->elog_trace_api_messages)) + { + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "api-msg: %s", + .format_args = "T4", + }; + /* *INDENT-ON* */ + struct + { + u32 c; + } *ed; + ed = ELOG_DATA (am->elog_main, e); + if (id < vec_len (am->msg_names)) + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); + else + ed->c = elog_string (am->elog_main, "BOGUS"); + } + if (id < vec_len (am->msg_handlers) && am->msg_handlers[id]) { if (trace_it) @@ -436,42 +497,56 @@ msg_handler_internal (api_main_t * am, if (free_it) vl_msg_api_free (the_msg); -} - -static u32 -elog_id_for_msg_name (vlib_main_t * vm, const char *msg_name) -{ - uword *p, r; - static uword *h; - u8 *name_copy; - if (!h) - h = hash_create_string (0, sizeof (uword)); - - p = hash_get_mem (h, msg_name); - if (p) - return p[0]; - r = elog_string (&vm->elog_main, "%s", msg_name); - - name_copy = format (0, "%s%c", msg_name, 0); - - hash_set_mem (h, name_copy, r); + if (PREDICT_FALSE (am->elog_trace_api_messages)) + { + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "api-msg-done(%s): %s", + .format_args = "t4T4", + .n_enum_strings = 2, + .enum_strings = + { + "barrier", + "mp-safe", + } + }; + /* *INDENT-ON* */ - return r; + struct + { + u32 barrier; + u32 c; + } *ed; + ed = ELOG_DATA (am->elog_main, e); + if (id < vec_len (am->msg_names)) + { + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); + ed->barrier = !am->is_mp_safe[id]; + } + else + { + ed->c = elog_string (am->elog_main, "BOGUS"); + ed->barrier = 0; + } + } } /* This is only to be called from a vlib/vnet app */ void -vl_msg_api_handler_with_vm_node (api_main_t * am, +vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, void *the_msg, vlib_main_t * vm, - vlib_node_runtime_t * node) + vlib_node_runtime_t * node, u8 is_private) { u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); u8 *(*handler) (void *, void *, void *); u8 *(*print_fp) (void *, void *); + svm_region_t *old_vlib_rp; + void *save_shmem_hdr; int is_mp_safe = 1; - if (PREDICT_FALSE (vm->elog_trace_api_messages)) + if (PREDICT_FALSE (am->elog_trace_api_messages)) { /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = @@ -484,11 +559,11 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, { u32 c; } *ed; - ed = ELOG_DATA (&vm->elog_main, e); + ed = ELOG_DATA (am->elog_main, e); if (id < vec_len (am->msg_names)) - ed->c = elog_id_for_msg_name (vm, (const char *) am->msg_names[id]); + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); else - ed->c = elog_id_for_msg_name (vm, "BOGUS"); + ed->c = elog_string (am->elog_main, "BOGUS"); } if (id < vec_len (am->msg_handlers) && am->msg_handlers[id]) @@ -518,7 +593,19 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, vl_msg_api_barrier_trace_context (am->msg_names[id]); vl_msg_api_barrier_sync (); } + if (is_private) + { + old_vlib_rp = am->vlib_rp; + save_shmem_hdr = am->shmem_hdr; + am->vlib_rp = vlib_rp; + am->shmem_hdr = (void *) vlib_rp->user_ctx; + } (*handler) (the_msg, vm, node); + if (is_private) + { + am->vlib_rp = old_vlib_rp; + am->shmem_hdr = save_shmem_hdr; + } if (!is_mp_safe) vl_msg_api_barrier_release (); } @@ -534,7 +621,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, if (!(am->message_bounce[id])) vl_msg_api_free (the_msg); - if (PREDICT_FALSE (vm->elog_trace_api_messages)) + if (PREDICT_FALSE (am->elog_trace_api_messages)) { /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = @@ -555,11 +642,11 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, u32 barrier; u32 c; } *ed; - ed = ELOG_DATA (&vm->elog_main, e); + ed = ELOG_DATA (am->elog_main, e); if (id < vec_len (am->msg_names)) - ed->c = elog_id_for_msg_name (vm, (const char *) am->msg_names[id]); + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); else - ed->c = elog_id_for_msg_name (vm, "BOGUS"); + ed->c = elog_string (am->elog_main, "BOGUS"); ed->barrier = is_mp_safe; } } @@ -567,7 +654,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, void vl_msg_api_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -578,7 +665,7 @@ vl_msg_api_handler (void *the_msg) void vl_msg_api_handler_no_free (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace && am->rx_trace->enabled) /* trace_it */ , @@ -588,7 +675,7 @@ vl_msg_api_handler_no_free (void *the_msg) void vl_msg_api_handler_no_trace_no_free (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ , 0 /* free_it */ ); } @@ -605,7 +692,7 @@ vl_msg_api_handler_no_trace_no_free (void *the_msg) void vl_msg_api_trace_only (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -616,7 +703,7 @@ vl_msg_api_trace_only (void *the_msg) void vl_msg_api_cleanup_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers))) @@ -636,7 +723,7 @@ vl_msg_api_cleanup_handler (void *the_msg) void vl_msg_api_replay_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); @@ -663,7 +750,7 @@ vl_msg_api_get_msg_length (void *msg_arg) void vl_msg_api_socket_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -684,7 +771,7 @@ _(is_mp_safe) void vl_msg_api_config (vl_msg_api_msg_config_t * c) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); /* * This happens during the java core tests if the message @@ -767,7 +854,7 @@ vl_msg_api_clean_handlers (int msg_id) void vl_msg_api_set_cleanup_handler (int msg_id, void *fp) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); ASSERT (msg_id > 0); vec_validate (am->msg_cleanup_handlers, msg_id); @@ -814,7 +901,7 @@ vl_msg_api_post_mortem_dump_enable_disable (int enable) void vl_msg_api_post_mortem_dump (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); FILE *fp; char filename[64]; int rv; @@ -849,7 +936,7 @@ vl_msg_api_post_mortem_dump (void) void vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); /* Mild idiot proofing */ if (msg_id_host_byte_order > 10000) @@ -863,7 +950,7 @@ vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order) int vl_msg_api_pd_handler (void *mp, int rv) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); int (*fp) (void *, int); u16 msg_id; @@ -884,7 +971,7 @@ vl_msg_api_pd_handler (void *mp, int rv) void vl_msg_api_set_first_available_msg_id (u16 first_avail) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); am->first_available_msg_id = first_avail; } @@ -892,7 +979,7 @@ vl_msg_api_set_first_available_msg_id (u16 first_avail) u16 vl_msg_api_get_msg_ids (const char *name, int n) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u8 *name_copy; vl_api_msg_range_t *rp; uword *p; @@ -964,7 +1051,7 @@ vl_msg_api_add_version (api_main_t * am, const char *string, u32 vl_msg_api_get_msg_index (u8 * name_and_crc) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); uword *p; if (am->msg_index_by_name_and_crc) @@ -976,30 +1063,47 @@ vl_msg_api_get_msg_index (u8 * name_and_crc) return ~0; } +void * +vl_msg_push_heap_w_region (svm_region_t * vlib_rp) +{ + pthread_mutex_lock (&vlib_rp->mutex); + return svm_push_data_heap (vlib_rp); +} + void * vl_msg_push_heap (void) { - api_main_t *am = &api_main; - pthread_mutex_lock (&am->vlib_rp->mutex); - return svm_push_data_heap (am->vlib_rp); + api_main_t *am = vlibapi_get_main (); + return vl_msg_push_heap_w_region (am->vlib_rp); } void -vl_msg_pop_heap (void *oldheap) +vl_msg_pop_heap_w_region (svm_region_t * vlib_rp, void *oldheap) { - api_main_t *am = &api_main; svm_pop_heap (oldheap); - pthread_mutex_unlock (&am->vlib_rp->mutex); + pthread_mutex_unlock (&vlib_rp->mutex); +} + +void +vl_msg_pop_heap (void *oldheap) +{ + api_main_t *am = vlibapi_get_main (); + vl_msg_pop_heap_w_region (am->vlib_rp, oldheap); } +/* Must be nul terminated */ int -vl_api_to_api_string (u32 len, const char *buf, vl_api_string_t * str) +vl_api_c_string_to_api_string (const char *buf, vl_api_string_t * str) { - clib_memcpy_fast (str->buf, buf, len); + /* copy without nul terminator */ + u32 len = strlen (buf); + if (len > 0) + clib_memcpy_fast (str->buf, buf, len); str->length = htonl (len); return len + sizeof (u32); } +/* Must NOT be nul terminated */ int vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str) { @@ -1009,30 +1113,74 @@ vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str) return len + sizeof (u32); } -/* Return a pointer to the API string (not nul terminated */ -u8 * -vl_api_from_api_string (vl_api_string_t * astr) -{ - return astr->buf; -} - u32 vl_api_string_len (vl_api_string_t * astr) { return clib_net_to_host_u32 (astr->length); } +u8 * +vl_api_format_string (u8 * s, va_list * args) +{ + vl_api_string_t *a = va_arg (*args, vl_api_string_t *); + vec_add (s, a->buf, clib_net_to_host_u32 (a->length)); + return s; +} + /* * Returns a new vector. Remember to free it after use. + * NOT nul terminated. */ u8 * -vl_api_from_api_to_vec (vl_api_string_t * astr) +vl_api_from_api_to_new_vec (vl_api_string_t * astr) { u8 *v = 0; vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length)); return v; } +/* + * Returns a new vector. Remember to free it after use. + * Nul terminated. + */ +char * +vl_api_from_api_to_new_c_string (vl_api_string_t * astr) +{ + char *v = 0; + if (clib_net_to_host_u32 (astr->length) > 0) + { + vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length)); + vec_add1 (v, 0); + } + return v; +} + +void +vl_api_set_elog_main (elog_main_t * m) +{ + api_main_t *am = vlibapi_get_main (); + am->elog_main = m; +} + +int +vl_api_set_elog_trace_api_messages (int enable) +{ + int rv; + api_main_t *am = vlibapi_get_main (); + + rv = am->elog_trace_api_messages; + am->elog_trace_api_messages = enable; + return rv; +} + +int +vl_api_get_elog_trace_api_messages (void) +{ + api_main_t *am = vlibapi_get_main (); + + return am->elog_trace_api_messages; +} + /* * fd.io coding-style-patch-verification: ON *