From 053a0e44edb21713e0825f9c09ba4af12e686b38 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Tue, 13 Nov 2018 15:52:38 -0800 Subject: [PATCH] vcl/session: apps with process workers Allow apps to register child processes as app workers. In particular, on fork vcl now registers the child process with vpp as a new worker. Change-Id: I52a65fbc3292962b1f6e1fe0f6153f739e6e0d4a Signed-off-by: Florin Coras --- src/plugins/unittest/session_test.c | 5 ++ src/vcl/vcl_bapi.c | 38 +++++------ src/vcl/vcl_cfg.c | 15 +++-- src/vcl/vcl_debug.h | 11 ++- src/vcl/vcl_private.h | 19 +++++- src/vcl/vppcom.c | 79 +++++++++++++++++----- src/vnet/session/application.c | 111 +++++++++++++++++++++++++------ src/vnet/session/application.h | 10 ++- src/vnet/session/application_interface.c | 2 +- src/vnet/session/application_interface.h | 1 + src/vnet/session/session_api.c | 3 + src/vnet/session/session_cli.c | 10 +-- src/vnet/session/session_lookup.c | 4 +- 13 files changed, 236 insertions(+), 72 deletions(-) diff --git a/src/plugins/unittest/session_test.c b/src/plugins/unittest/session_test.c index 182a8e806ea..e24516668ff 100644 --- a/src/plugins/unittest/session_test.c +++ b/src/plugins/unittest/session_test.c @@ -216,6 +216,7 @@ session_test_basic (vlib_main_t * vm, unformat_input_t * input) vnet_app_detach_args_t detach_args = { .app_index = server_index, + .api_client_index = ~0, }; vnet_application_detach (&detach_args); return 0; @@ -393,6 +394,7 @@ session_test_endpoint_cfg (vlib_main_t * vm, unformat_input_t * input) vnet_app_detach_args_t detach_args = { .app_index = server_index, + .api_client_index = ~0, }; vnet_application_detach (&detach_args); detach_args.app_index = client_index; @@ -463,6 +465,7 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input) vnet_app_detach_args_t detach_args = { .app_index = 0, + .api_client_index = ~0, }; ip4_address_t intf_addr = { @@ -1562,6 +1565,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) vec_free (args.table_args.tag); vnet_app_detach_args_t detach_args = { .app_index = server_index, + .api_client_index = ~0, }; vnet_application_detach (&detach_args); @@ -1677,6 +1681,7 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input) vnet_app_detach_args_t detach_args = { .app_index = server_index, + .api_client_index = ~0, }; vnet_application_detach (&detach_args); diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c index ea8f2ce5651..7dd601cf737 100644 --- a/src/vcl/vcl_bapi.c +++ b/src/vcl/vcl_bapi.c @@ -148,17 +148,13 @@ vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t * format_api_error, ntohl (mp->retval)); goto failed; } - wrk_index = clib_net_to_host_u32 (mp->wrk_index); - if (mp->context != wrk_index) - { - clib_warning ("VCL<%d>: wrk numbering doesn't match ours: %u, vpp: %u", - getpid (), mp->context, wrk_index); - goto failed; - } + wrk_index = mp->context; + wrk = vcl_worker_get (wrk_index); + wrk->vpp_wrk_index = clib_net_to_host_u32 (mp->wrk_index); + if (!mp->is_add) return; - wrk = vcl_worker_get (wrk_index); wrk->app_event_queue = uword_to_pointer (mp->app_event_queue_address, svm_msg_q_t *); @@ -193,6 +189,7 @@ vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t * goto failed; } vcm->app_state = STATE_APP_READY; + VDBG (0, "worker %u vpp-worker %u added", wrk_index, wrk->vpp_wrk_index); return; failed: @@ -432,7 +429,7 @@ vcl_send_app_worker_add_del (u8 is_add) mp->_vl_msg_id = ntohs (VL_API_APP_WORKER_ADD_DEL); mp->client_index = vcm->my_client_index; - mp->app_api_index = clib_host_to_net_u32 (vcm->my_client_index); + mp->app_api_index = clib_host_to_net_u32 (vcm->main_api_client_index); mp->context = wrk_index; mp->is_add = is_add; if (!is_add) @@ -444,6 +441,7 @@ vcl_send_app_worker_add_del (u8 is_add) void vppcom_send_connect_sock (vcl_session_t * session) { + vcl_worker_t *wrk = vcl_worker_get_current (); vl_api_connect_sock_t *cmp; cmp = vl_msg_api_alloc (sizeof (*cmp)); @@ -451,7 +449,7 @@ vppcom_send_connect_sock (vcl_session_t * session) cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK); cmp->client_index = vcm->my_client_index; cmp->context = session->session_index; - cmp->wrk_index = vcl_get_worker_index (); + cmp->wrk_index = wrk->vpp_wrk_index; cmp->is_ip4 = session->transport.is_ip4; clib_memcpy_fast (cmp->ip, &session->transport.rmt_ip, sizeof (cmp->ip)); cmp->port = session->transport.rmt_port; @@ -479,6 +477,7 @@ vppcom_send_disconnect_session (u64 vpp_handle) void vppcom_send_bind_sock (vcl_session_t * session) { + vcl_worker_t *wrk = vcl_worker_get_current (); vl_api_bind_sock_t *bmp; /* Assumes caller has acquired spinlock: vcm->sessions_lockp */ @@ -488,7 +487,7 @@ vppcom_send_bind_sock (vcl_session_t * session) bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK); bmp->client_index = vcm->my_client_index; bmp->context = session->session_index; - bmp->wrk_index = vcl_get_worker_index (); + bmp->wrk_index = wrk->vpp_wrk_index; bmp->is_ip4 = session->transport.is_ip4; clib_memcpy_fast (bmp->ip, &session->transport.lcl_ip, sizeof (bmp->ip)); bmp->port = session->transport.lcl_port; @@ -500,6 +499,7 @@ vppcom_send_bind_sock (vcl_session_t * session) void vppcom_send_unbind_sock (u64 vpp_handle) { + vcl_worker_t *wrk = vcl_worker_get_current (); vl_api_unbind_sock_t *ump; ump = vl_msg_api_alloc (sizeof (*ump)); @@ -507,7 +507,7 @@ vppcom_send_unbind_sock (u64 vpp_handle) ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK); ump->client_index = vcm->my_client_index; - ump->wrk_index = vcl_get_worker_index (); + ump->wrk_index = wrk->vpp_wrk_index; ump->handle = vpp_handle; vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump); } @@ -556,15 +556,13 @@ vppcom_connect_to_vpp (char *app_name) if (vl_socket_client_connect ((char *) vcl_cfg->vpp_api_socket_name, app_name, 0 /* default rx/tx buffer */ )) { - clib_warning ("VCL<%d>: app (%s) socket connect failed!", - getpid (), app_name); + VERR ("app (%s) socket connect failed!", app_name); return VPPCOM_ECONNREFUSED; } if (vl_socket_client_init_shm (0)) { - clib_warning ("VCL<%d>: app (%s) init shm failed!", - getpid (), app_name); + VERR ("app (%s) init shm failed!", app_name); return VPPCOM_ECONNREFUSED; } } @@ -573,14 +571,13 @@ vppcom_connect_to_vpp (char *app_name) if (!vcl_cfg->vpp_api_filename) vcl_cfg->vpp_api_filename = format (0, "/vpe-api%c", 0); - VDBG (0, "VCL<%d>: app (%s) connecting to VPP api (%s)...", getpid (), + VDBG (0, "app (%s) connecting to VPP api (%s)...", app_name, vcl_cfg->vpp_api_filename); if (vl_client_connect_to_vlib ((char *) vcl_cfg->vpp_api_filename, app_name, vcm->cfg.vpp_api_q_length) < 0) { - clib_warning ("VCL<%d>: app (%s) connect failed!", getpid (), - app_name); + VERR ("app (%s) connect failed!", app_name); return VPPCOM_ECONNREFUSED; } @@ -590,8 +587,7 @@ vppcom_connect_to_vpp (char *app_name) vcm->my_client_index = (u32) am->my_client_index; vcm->app_state = STATE_APP_CONN_VPP; - VDBG (0, "VCL<%d>: app (%s) is connected to VPP!", getpid (), app_name); - + VDBG (0, "app (%s) is connected to VPP!", app_name); vcl_evt (VCL_EVT_INIT, vcm); return VPPCOM_OK; } diff --git a/src/vcl/vcl_cfg.c b/src/vcl/vcl_cfg.c index e39e5177908..3e92941d720 100644 --- a/src/vcl/vcl_cfg.c +++ b/src/vcl/vcl_cfg.c @@ -22,6 +22,7 @@ static vppcom_main_t _vppcom_main = { .debug = VPPCOM_DEBUG_INIT, .is_init = 0, + .main_api_client_index = ~0, .my_client_index = ~0 }; @@ -170,6 +171,7 @@ vppcom_cfg_heapsize (char *conf_fname) goto defaulted; } } + free (argv[i]); } defaulted: @@ -231,8 +233,7 @@ vppcom_cfg_read_file (char *conf_fname) if (fstat (fd, &s) < 0) { - VCFG_DBG (0, - "VCL<%d>: failed to stat `%s', using default configuration", + VCFG_DBG (0, "VCL<%d>: failed to stat `%s' using default configuration", getpid (), conf_fname); goto file_done; } @@ -254,17 +255,21 @@ vppcom_cfg_read_file (char *conf_fname) if (unformat (line_input, "vcl {")) { vc_cfg_input = 1; + unformat_free (line_input); continue; } if (vc_cfg_input) { - if (unformat (line_input, "heapsize %lu", &vcl_cfg->heapsize)) + if (unformat (line_input, "heapsize %U", unformat_memory_size, + &vcl_cfg->heapsize)) { VCFG_DBG (0, "VCL<%d>: configured heapsize %lu", getpid (), vcl_cfg->heapsize); } - if (unformat (line_input, "max-workers %u", &vcl_cfg->max_workers)) + else + if (unformat + (line_input, "max-workers %u", &vcl_cfg->max_workers)) { VCFG_DBG (0, "VCL<%d>: configured max-workers %u", getpid (), vcl_cfg->max_workers); @@ -490,6 +495,7 @@ vppcom_cfg_read_file (char *conf_fname) vc_cfg_input = 0; VCFG_DBG (0, "VCL<%d>: completed parsing vppcom config!", getpid ()); + unformat_free (line_input); goto input_done; } else @@ -501,6 +507,7 @@ vppcom_cfg_read_file (char *conf_fname) &line_input->buffer[line_input->index]); } } + unformat_free (line_input); } } diff --git a/src/vcl/vcl_debug.h b/src/vcl/vcl_debug.h index 7b284166503..48ff21af1de 100644 --- a/src/vcl/vcl_debug.h +++ b/src/vcl/vcl_debug.h @@ -23,7 +23,16 @@ #define VDBG(_lvl, _fmt, _args...) \ if (VCL_DBG_ON && vcm->debug > _lvl) \ - clib_warning ("vcl: " _fmt, __vcl_worker_index, ##_args) + clib_warning ("vcl<%d:%d>: " _fmt, vcm->current_pid, \ + __vcl_worker_index, ##_args) + +#define VWRN(_fmt, _args...) \ +clib_warning ("vcl<%d:%d>: " _fmt, vcm->current_pid, \ + __vcl_worker_index, ##_args) + +#define VERR(_fmt, _args...) \ + clib_warning ("vcl<%d:%d>: ERROR " _fmt, vcm->current_pid, \ + __vcl_worker_index, ##_args) #define foreach_vcl_dbg_evt \ _(INIT, "vcl init track") \ diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index d1a40b933a7..7bb0dbc5a66 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -219,8 +219,12 @@ typedef struct vcl_worker_ /* Session pool */ vcl_session_t *sessions; + /** Worker/thread index in current process */ u32 wrk_index; + /** Worker index in vpp*/ + u32 vpp_wrk_index; + /** Message queues epoll fd. Initialized only if using mqs with eventfds */ int mqs_epfd; @@ -272,15 +276,26 @@ typedef struct vppcom_main_t_ u32 debug; pthread_t main_cpu; - /** VPP binary api input queue */ - svm_queue_t *vl_input_queue; + /** Main process pid */ + pid_t main_pid; + + /** Current pid, may be different from main_pid if forked child */ + pid_t current_pid; + + /** Main process api client index. It's used by vpp to identify the app */ + u32 main_api_client_index; /** API client handle */ u32 my_client_index; + /** VPP binary api input queue */ + svm_queue_t *vl_input_queue; + /** State of the connection, shared between msg RX thread and main thread */ volatile app_state_t app_state; + u8 *app_name; + /** VCL configuration */ vppcom_cfg_t cfg; diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 99547377523..669f04fe1e3 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -688,6 +688,52 @@ vppcom_session_disconnect (u32 session_handle) return VPPCOM_OK; } +static void +vcl_cleanup_bapi (void) +{ + api_main_t *am = &api_main; + + am->my_client_index = ~0; + am->my_registration = 0; + am->vl_input_queue = 0; + am->msg_index_by_name_and_crc = 0; + + vl_client_api_unmap (); +} + +void +vcl_app_fork_child_handler (void) +{ + u8 *child_name; + int rv; + + vcm->current_pid = getpid (); + vcl_set_worker_index (0); + + VDBG (0, "initializing forked child"); + child_name = format (0, "%v-child-%u%c", vcm->app_name, getpid (), 0); + + vcl_cleanup_bapi (); + vppcom_api_hookup (); + vcm->app_state = STATE_APP_START; + rv = vppcom_connect_to_vpp ((char *) child_name); + vec_free (child_name); + if (rv) + { + VERR ("couldn't connect to VPP!"); + return; + } + + vcm->app_state = STATE_APP_ADDING_WORKER; + vcl_send_app_worker_add_del (1 /* is_add */ ); + if (vcl_wait_for_app_state_change (STATE_APP_READY)) + { + VERR ("failed to add worker to vpp"); + return; + } + VDBG (0, "forked child main worker initialized"); +} + /* * VPPCOM Public API functions */ @@ -704,12 +750,15 @@ vppcom_app_create (char *app_name) vcl_cfg = &vcm->cfg; vcm->main_cpu = pthread_self (); + vcm->main_pid = vcm->current_pid = getpid (); + vcm->app_name = format (0, "%s", app_name); vppcom_init_error_string_table (); svm_fifo_segment_main_init (vcl_cfg->segment_baseva, 20 /* timeout in secs */ ); pool_init_fixed (vcm->workers, vcl_cfg->max_workers); clib_spinlock_init (&vcm->workers_lock); vcl_worker_alloc_and_init (); + pthread_atfork (NULL, NULL, vcl_app_fork_child_handler); } if (vcm->my_client_index == ~0) @@ -721,31 +770,28 @@ vppcom_app_create (char *app_name) rv = vppcom_connect_to_vpp (app_name); if (rv) { - clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!", - getpid ()); + VERR ("couldn't connect to VPP!"); return rv; } - - VDBG (0, "VCL<%d>: sending session enable", getpid ()); + vcm->main_api_client_index = vcm->my_client_index; + VDBG (0, "sending session enable"); rv = vppcom_app_session_enable (); if (rv) { - clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() " - "failed!", getpid ()); + VERR ("vppcom_app_session_enable() failed!"); return rv; } - VDBG (0, "VCL<%d>: sending app attach", getpid ()); + VDBG (0, "sending app attach"); rv = vppcom_app_attach (); if (rv) { - clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!", - getpid ()); + VERR ("vppcom_app_attach() failed!"); return rv; } - VDBG (0, "VCL<%d>: app_name '%s', my_client_index %d (0x%x)", - getpid (), app_name, vcm->my_client_index, vcm->my_client_index); + VDBG (0, "app_name '%s', my_client_index %d (0x%x)", + app_name, vcm->my_client_index, vcm->my_client_index); } return VPPCOM_OK; @@ -760,8 +806,8 @@ vppcom_app_destroy (void) if (vcm->my_client_index == ~0) return; - VDBG (0, "VCL<%d>: detaching from VPP, my_client_index %d (0x%x)", - getpid (), vcm->my_client_index, vcm->my_client_index); + VDBG (0, "detaching from VPP, my_client_index %d (0x%x)", + vcm->my_client_index, vcm->my_client_index); vcl_evt (VCL_EVT_DETACH, vcm); vppcom_app_send_detach (); @@ -770,11 +816,12 @@ vppcom_app_destroy (void) rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED); vcm->cfg.app_timeout = orig_app_timeout; if (PREDICT_FALSE (rv)) - VDBG (0, "VCL<%d>: application detach timed out! returning %d (%s)", - getpid (), rv, vppcom_retval_str (rv)); + VDBG (0, "application detach timed out! returning %d (%s)", + rv, vppcom_retval_str (rv)); vcl_elog_stop (vcm); vl_client_disconnect_from_vlib (); + vec_free (vcm->app_name); vcm->my_client_index = ~0; vcm->app_state = STATE_APP_START; } @@ -798,7 +845,7 @@ vppcom_session_create (u8 proto, u8 is_nonblocking) vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state, is_nonblocking, session_index); - VDBG (0, "VCL<%d>: sid %u", getpid (), session->session_index); + VDBG (0, "created sid %u", session->session_index); return vcl_session_handle (session); } diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 1d7b3ad1125..72c57688e42 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -112,11 +112,11 @@ app_get_name_from_reg_index (application_t * app) return app_name; } -static u8 * +static const u8 * app_get_name (application_t * app) { if (!app->name) - return app_get_name_from_reg_index (app); + app->name = app_get_name_from_reg_index (app); return app->name; } @@ -174,18 +174,27 @@ application_api_queue_is_full (application_t * app) } /** - * Returns app name - * - * Since the name is not stored per app, we generate it on the fly. It is - * the caller's responsibility to free the vector + * Returns app name for app-index */ -u8 * +const u8 * application_name_from_index (u32 app_index) { application_t *app = application_get (app_index); if (!app) return 0; - return app_get_name_from_reg_index (app); + return app_get_name (app); +} + +static void +application_api_table_add (u32 app_index, u32 api_client_index) +{ + hash_set (app_main.app_by_api_client_index, api_client_index, app_index); +} + +static void +application_api_table_del (u32 api_client_index) +{ + hash_unset (app_main.app_by_api_client_index, api_client_index); } static void @@ -213,7 +222,7 @@ application_lookup (u32 api_client_index) uword *p; p = hash_get (app_main.app_by_api_client_index, api_client_index); if (p) - return application_get (p[0]); + return application_get_if_valid (p[0]); return 0; } @@ -440,6 +449,50 @@ application_free (application_t * app) pool_put (app_main.app_pool, app); } +void +application_detach_process (application_t * app, u32 api_client_index) +{ + vnet_app_worker_add_del_args_t _args = { 0 }, *args = &_args; + app_worker_map_t *wrk_map; + u32 *wrks = 0, *wrk_index; + app_worker_t *app_wrk; + + if (api_client_index == ~0) + { + application_free (app); + return; + } + + APP_DBG ("Detaching for app %v index %u api client index %u", app->name, + app->app_index, app->api_client_index); + + /* *INDENT-OFF* */ + pool_foreach (wrk_map, app->worker_maps, ({ + app_wrk = app_worker_get (wrk_map->wrk_index); + if (app_wrk->api_index == api_client_index) + vec_add1 (wrks, app_wrk->wrk_index); + })); + /* *INDENT-ON* */ + + if (!vec_len (wrks)) + { + clib_warning ("no workers for app %u api_index %u", app->app_index, + api_client_index); + return; + } + + args->app_index = app->app_index; + args->api_index = api_client_index; + vec_foreach (wrk_index, wrks) + { + app_wrk = app_worker_get (wrk_index[0]); + args->wrk_index = app_wrk->wrk_map_index; + args->is_add = 0; + vnet_app_worker_add_del (args); + } + vec_free (wrks); +} + app_worker_t * application_get_worker (application_t * app, u32 wrk_map_index) { @@ -456,6 +509,12 @@ application_get_default_worker (application_t * app) return application_get_worker (app, 0); } +u32 +application_n_workers (application_t * app) +{ + return pool_elts (app->worker_maps); +} + app_worker_t * application_listener_select_worker (stream_session_t * ls, u8 is_local) { @@ -609,6 +668,7 @@ app_worker_alloc_and_init (application_t * app, app_worker_t ** wrk) app_wrk->listeners_table = hash_create (0, sizeof (u64)); app_wrk->event_queue = segment_manager_event_queue (sm); app_wrk->app_is_builtin = application_is_builtin (app); + app_wrk->api_index = app->api_client_index; /* * Segment manager for local sessions @@ -815,7 +875,8 @@ application_stop_listen (u32 app_index, u32 app_wrk_index, app_listener = app_listener_get (app, listener->listener_db_index); if (!clib_bitmap_get (app_listener->workers, app_wrk_index)) { - clib_warning ("worker not listening on handle %lu", handle); + clib_warning ("worker %u not listening on handle %lu", app_wrk_index, + handle); return 0; } @@ -899,6 +960,15 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) { if ((rv = app_worker_alloc_and_init (app, &app_wrk))) return clib_error_return_code (0, rv, 0, "app wrk init: %d", rv); + + /* Map worker api index to the app */ + if (a->api_index != app->api_client_index + && app->api_client_index != APP_INVALID_INDEX) + { + app_wrk->api_index = a->api_index; + application_api_table_add (app->app_index, a->api_index); + } + sm = segment_manager_get (app_wrk->first_segment_manager); fs = segment_manager_get_segment_w_lock (sm, 0); a->segment = &fs->ssvm; @@ -914,11 +984,15 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) "App %u does not have worker %u", app->app_index, a->wrk_index); app_wrk = app_worker_get (wrk_map->wrk_index); - app_worker_map_free (app, wrk_map); if (!app_wrk) return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0, "No worker %u", a->wrk_index); + if (app->api_client_index != app_wrk->api_index) + application_api_table_del (app_wrk->api_index); app_worker_free (app_wrk); + app_worker_map_free (app, wrk_map); + if (application_n_workers (app) == 0) + application_free (app); } return 0; } @@ -1916,7 +1990,8 @@ format_app_worker_listener (u8 * s, va_list * args) int verbose = va_arg (*args, int); stream_session_t *listener; application_t *app; - u8 *app_name, *str; + const u8 *app_name; + u8 *str; if (!app_wrk) { @@ -1930,7 +2005,7 @@ format_app_worker_listener (u8 * s, va_list * args) } app = application_get (app_wrk->app_index); - app_name = app_get_name_from_reg_index (app); + app_name = app_get_name (app); listener = listen_session_get_from_handle (handle); str = format (0, "%U", format_stream_session, listener, verbose); @@ -1944,7 +2019,6 @@ format_app_worker_listener (u8 * s, va_list * args) else s = format (s, "%-40s%-25s%=10u", str, app_name, app_wrk->wrk_map_index); - vec_free (app_name); return s; } @@ -1983,8 +2057,9 @@ app_worker_format_connects (app_worker_t * app_wrk, int verbose) svm_fifo_segment_private_t *fifo_segment; vlib_main_t *vm = vlib_get_main (); segment_manager_t *sm; - u8 *app_name, *s = 0; + const u8 *app_name; application_t *app; + u8 *s = 0; /* Header */ if (!app_wrk) @@ -2001,7 +2076,7 @@ app_worker_format_connects (app_worker_t * app_wrk, int verbose) if (app_wrk->connects_seg_manager == (u32) ~ 0) return; - app_name = app_get_name_from_reg_index (app); + app_name = app_get_name (app); /* Across all fifo segments */ sm = segment_manager_get (app_wrk->connects_seg_manager); @@ -2039,7 +2114,6 @@ app_worker_format_connects (app_worker_t * app_wrk, int verbose) })); /* *INDENT-ON* */ - vec_free (app_name); } static void @@ -2200,8 +2274,7 @@ format_application (u8 * s, va_list * args) application_t *app = va_arg (*args, application_t *); CLIB_UNUSED (int verbose) = va_arg (*args, int); segment_manager_properties_t *props; - const u8 *app_ns_name; - u8 *app_name; + const u8 *app_ns_name, *app_name; if (app == 0) { diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 3888cf7f463..9c68433d5e9 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -101,6 +101,9 @@ typedef struct app_worker_ /** Hash table of the app's local connects */ uword *local_connects; + /** API index for the worker. Needed for multi-process apps */ + u32 api_index; + u8 app_is_builtin; } app_worker_t; @@ -121,7 +124,8 @@ typedef struct application_ /** App index in app pool */ u32 app_index; - /** Binary API connection index, ~0 if internal */ + /** Binary API connection index of app process that created the app, + * ~0 if internal */ u32 api_client_index; /** Flags */ @@ -210,6 +214,7 @@ typedef struct _vnet_app_worker_add_del_args { u32 app_index; /**< App for which a new worker is requested */ u32 wrk_index; /**< Index to delete or return value if add */ + u32 api_index; /**< Binary API client index */ ssvm_private_t *segment; /**< First segment in segment manager */ svm_msg_q_t *evt_q; /**< Worker message queue */ u8 is_add; /**< Flag set if addition */ @@ -251,6 +256,7 @@ int application_stop_listen (u32 app_index, u32 app_or_wrk, application_t *application_alloc (void); int application_alloc_and_init (app_init_args_t * args); void application_free (application_t * app); +void application_detach_process (application_t * app, u32 api_client_index); application_t *application_get (u32 index); application_t *application_get_if_valid (u32 index); application_t *application_lookup (u32 api_client_index); @@ -268,7 +274,7 @@ int application_is_builtin (application_t * app); int application_is_builtin_proxy (application_t * app); u32 application_session_table (application_t * app, u8 fib_proto); u32 application_local_session_table (application_t * app); -u8 *application_name_from_index (u32 app_or_wrk); +const u8 *application_name_from_index (u32 app_or_wrk); u8 application_has_local_scope (application_t * app); u8 application_has_global_scope (application_t * app); u8 application_use_mq_for_ctrl (application_t * app); diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c index 89f74621aa9..3cd8c2f5eb3 100644 --- a/src/vnet/session/application_interface.c +++ b/src/vnet/session/application_interface.c @@ -554,7 +554,7 @@ vnet_application_detach (vnet_app_detach_args_t * a) } app_interface_check_thread_and_barrier (vnet_application_detach, a); - application_free (app); + application_detach_process (app, a->api_client_index); return 0; } diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index dc4c46906c4..10edfdef35a 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -33,6 +33,7 @@ typedef struct _vnet_app_attach_args_t typedef struct _vnet_app_detach_args_t { u32 app_index; + u32 api_client_index; } vnet_app_detach_args_t; typedef struct _vnet_bind_args_t diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 8315c19a7ac..58877010326 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -856,6 +856,7 @@ vl_api_application_detach_t_handler (vl_api_application_detach_t * mp) if (app) { a->app_index = app->app_index; + a->api_client_index = mp->client_index; rv = vnet_application_detach (a); } @@ -1359,6 +1360,7 @@ vl_api_app_worker_add_del_t_handler (vl_api_app_worker_add_del_t * mp) vnet_app_worker_add_del_args_t args = { .app_index = app->app_index, .wrk_index = clib_net_to_host_u32 (mp->wrk_index), + .api_index = mp->client_index, .is_add = mp->is_add }; error = vnet_app_worker_add_del (&args); @@ -1732,6 +1734,7 @@ application_reaper_cb (u32 client_index) if (app) { a->app_index = app->app_index; + a->api_client_index = client_index; vnet_application_detach (a); } return 0; diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c index 651abe17597..3fe49917feb 100755 --- a/src/vnet/session/session_cli.c +++ b/src/vnet/session/session_cli.c @@ -205,10 +205,12 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { session_manager_main_t *smm = &session_manager_main; - u8 *str = 0, one_session = 0, do_listeners = 0, sst, *app_name; - int verbose = 0, i; + u8 *str = 0, one_session = 0, do_listeners = 0, sst; stream_session_t *pool, *s; u32 transport_proto = ~0; + app_worker_t *app_wrk; + int verbose = 0, i; + const u8 *app_name; if (!smm->is_enabled) { @@ -248,10 +250,10 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, if (s->session_state != SESSION_STATE_LISTENING || s->session_type != sst) continue; - app_name = application_name_from_index (s->app_wrk_index); + app_wrk = app_worker_get (s->app_wrk_index); + app_name = application_name_from_index (app_wrk->app_index); vlib_cli_output (vm, "%U%-25v%", format_stream_session, s, 1, app_name); - vec_free (app_name); })); /* *INDENT-ON* */ return 0; diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 927922e7e64..c410dab121f 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -1302,9 +1302,10 @@ format_ip4_session_lookup_kvp (u8 * s, va_list * args) clib_bihash_kv_16_8_t *kvp = va_arg (*args, clib_bihash_kv_16_8_t *); u32 is_local = va_arg (*args, u32), app_wrk_index, session_index; v4_connection_key_t *key = (v4_connection_key_t *) kvp->key; - u8 *app_name, *str = 0; stream_session_t *session; app_worker_t *app_wrk; + const u8 *app_name; + u8 *str = 0; if (!is_local) { @@ -1327,7 +1328,6 @@ format_ip4_session_lookup_kvp (u8 * s, va_list * args) clib_net_to_host_u16 (key->src_port)); s = format (s, "%-30v%-30v", str, app_name); } - vec_free (app_name); return s; } -- 2.16.6