diff options
author | 2018-06-14 14:42:14 +0200 | |
---|---|---|
committer | 2018-06-15 12:16:32 +0000 | |
commit | e906aacc1089ce86158486ec52d37a8470359ec2 (patch) | |
tree | a0fea12e785a4b1add2ffe6713b0b05b69df384c /src/vpp | |
parent | 1ec0ea85c3f57f4638e32a00396057f80d958ec9 (diff) |
STATS: Separate socket for fd exchange.
stats { interval <no> socket-name <name> | default }
Where the default socket is in /run/vpp/stats.sock
Change-Id: Idd501b328c662804d4ccd58034b0ea6b8aa1f89a
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp')
-rw-r--r-- | src/vpp/app/stat_client.c | 124 | ||||
-rw-r--r-- | src/vpp/app/stat_client.h | 7 | ||||
-rw-r--r-- | src/vpp/stats/stats.api | 8 | ||||
-rw-r--r-- | src/vpp/stats/stats.c | 114 | ||||
-rw-r--r-- | src/vpp/stats/stats.h | 5 |
5 files changed, 96 insertions, 162 deletions
diff --git a/src/vpp/app/stat_client.c b/src/vpp/app/stat_client.c index b3dee5331ca..0ee78d200af 100644 --- a/src/vpp/app/stat_client.c +++ b/src/vpp/app/stat_client.c @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------ - * api_format.c + * stat_client.c * * Copyright (c) 2018 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,60 +19,42 @@ #include <vpp/app/stat_client.h> -#include <vpp/api/vpe_msg_enum.h> - -#define vl_typedefs /* define message structures */ -#include <vpp/api/vpe_all_api_h.h> -#undef vl_typedefs - -#define vl_endianfun /* define endian fcns */ -#include <vpp/api/vpe_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) fformat (handle, __VA_ARGS__) -#define vl_printfun -#include <vpp/api/vpe_all_api_h.h> -#undef vl_printfun - stat_client_main_t stat_client_main; -static void vl_api_map_stats_segment_reply_t_handler - (vl_api_map_stats_segment_reply_t * mp) +static int +stat_segment_connect (stat_client_main_t * sm) { - stat_client_main_t *sm = &stat_client_main; ssvm_private_t *ssvmp = &sm->stat_segment; ssvm_shared_header_t *shared_header; - socket_client_main_t *scm = sm->socket_client_main; - int rv = ntohl (mp->retval); - int my_fd, retval; - clib_error_t *error; - - if (rv != 0) + clib_socket_t s = { 0 }; + clib_error_t *err; + int fd = -1, retval; + + s.config = (char *) sm->socket_name; + s.flags = CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET; + err = clib_socket_init (&s); + if (err) { - fformat (stderr, "ERROR mapping stats segment: %d", rv); + clib_error_report (err); exit (1); } - - /* - * Check the socket for the magic fd - */ - error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5); - if (error) + err = clib_socket_recvmsg (&s, 0, 0, &fd, 1); + if (err) { - clib_error_report (error); - exit (1); + clib_error_report (err); + return -1; } + clib_socket_close (&s); memset (ssvmp, 0, sizeof (*ssvmp)); - ssvmp->fd = my_fd; + ssvmp->fd = fd; /* Note: this closes memfd.fd */ retval = ssvm_slave_init_memfd (ssvmp); if (retval) { clib_warning ("WARNING: segment map returned %d", retval); - exit (1); + return -1; } fformat (stdout, "Stat segment mapped OK...\n"); @@ -84,60 +66,6 @@ static void vl_api_map_stats_segment_reply_t_handler sm->stat_segment_lockp = (clib_spinlock_t *) (shared_header->opaque[0]); sm->segment_ready = 1; - /* No need to keep the socket API connection open */ - close (sm->socket_client_main->socket_fd); -} - -#define foreach_api_reply_msg \ -_(MAP_STATS_SEGMENT_REPLY, map_stats_segment_reply) - -static void -vpp_api_hookup (void) -{ -#define _(N,n) \ - vl_msg_api_set_handlers(VL_API_##N, #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); - foreach_api_reply_msg; -#undef _ -} - -static int -connect_to_vpp (stat_client_main_t * sm) -{ - int rv; - vl_api_map_stats_segment_t *mp; - api_main_t *am = &api_main; - - sm->socket_client_main = &socket_client_main; - - rv = vl_socket_client_connect ((char *) sm->socket_name, - "stat_client", - 0 /* default socket rx, tx buffer */ ); - if (rv) - { - fformat (stderr, "Error connecting to vpp...\n"); - exit (1); - } - - /* Hook up reply handler */ - vpp_api_hookup (); - - /* Map the stats segment */ - mp = vl_socket_client_msg_alloc (sizeof (*mp)); - mp->_vl_msg_id = ntohs (VL_API_MAP_STATS_SEGMENT); - mp->client_index = am->my_client_index; - mp->context = 0xdeaddabe; - - /* Send the message */ - vl_socket_client_write (); - - /* Wait for a reply, process it.. */ - vl_socket_client_read (5 /* timeout in seconds */ ); - return 0; } @@ -399,24 +327,23 @@ stat_poll_loop (stat_client_main_t * sm) } } - int main (int argc, char **argv) { unformat_input_t _argv, *a = &_argv; stat_client_main_t *sm = &stat_client_main; - u8 *socket_name; + u8 *stat_segment_name; int rv; clib_mem_init (0, 128 << 20); unformat_init_command_line (a, argv); - socket_name = (u8 *) API_SOCKET_FILE; + stat_segment_name = (u8 *) STAT_SEGMENT_SOCKET_FILE; while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT) { - if (unformat (a, "socket-name %s", &socket_name)) + if (unformat (a, "socket-name %s", &stat_segment_name)) ; else { @@ -425,14 +352,13 @@ main (int argc, char **argv) } } - sm->socket_name = socket_name; - - rv = connect_to_vpp (sm); + sm->socket_name = stat_segment_name; + rv = stat_segment_connect (sm); if (rv) { fformat (stderr, "Couldn't connect to vpp, does %s exist?\n", - socket_name); + stat_segment_name); exit (1); } diff --git a/src/vpp/app/stat_client.h b/src/vpp/app/stat_client.h index 87e5409ed6f..97bd3f9bb0b 100644 --- a/src/vpp/app/stat_client.h +++ b/src/vpp/app/stat_client.h @@ -18,10 +18,6 @@ #include <vlib/vlib.h> #include <vppinfra/socket.h> #include <svm/ssvm.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vlibmemory/socket_api.h> -#include <vlibmemory/socket_client.h> #include <vpp/stats/stats.h> typedef struct @@ -50,9 +46,6 @@ typedef struct /* mapped stats segment object */ ssvm_private_t stat_segment; - /* Socket client object */ - socket_client_main_t *socket_client_main; - /* Spinlock for the stats segment */ clib_spinlock_t *stat_segment_lockp; diff --git a/src/vpp/stats/stats.api b/src/vpp/stats/stats.api index bd1c3f634fe..72e03b0b40c 100644 --- a/src/vpp/stats/stats.api +++ b/src/vpp/stats/stats.api @@ -58,8 +58,6 @@ service { rpc want_udp_encap_stats returns want_udp_encap_stats_reply events vnet_udp_encap_counters; - rpc map_stats_segment - returns map_stats_segment_reply; }; /** \brief Want Stats, enable/disable ALL stats updates @@ -474,12 +472,6 @@ manual_print manual_endian define vnet_udp_encap_counters vl_api_udp_encap_counter_t c[count]; }; -autoreply define map_stats_segment -{ - u32 client_index; - u32 context; -}; - /* * Local Variables: diff --git a/src/vpp/stats/stats.c b/src/vpp/stats/stats.c index 31cfc336aca..452871febdc 100644 --- a/src/vpp/stats/stats.c +++ b/src/vpp/stats/stats.c @@ -65,8 +65,7 @@ _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters) \ _(WANT_IP6_NBR_STATS, want_ip6_nbr_stats) \ _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \ _(STATS_GET_POLLER_DELAY, stats_get_poller_delay) \ -_(WANT_UDP_ENCAP_STATS, want_udp_encap_stats) \ -_(MAP_STATS_SEGMENT, map_stats_segment) +_(WANT_UDP_ENCAP_STATS, want_udp_encap_stats) #define vl_msg_name_crc_list #include <vpp/stats/stats.api.h> @@ -2258,14 +2257,74 @@ stats_set_poller_delay (u32 poller_delay_sec) } } +/* + * Accept connection on the socket and exchange the fd for the shared + * memory segment. + */ +static clib_error_t * +stats_socket_accept_ready (clib_file_t * uf) +{ + stats_main_t *sm = &stats_main; + ssvm_private_t *ssvmp = &sm->stat_segment; + clib_error_t *err; + clib_socket_t client = { 0 }; + + err = clib_socket_accept (sm->socket, &client); + if (err) + { + clib_error_report (err); + return err; + } + + /* Send the fd across and close */ + err = clib_socket_sendmsg (&client, 0, 0, &ssvmp->fd, 1); + if (err) + clib_error_report (err); + clib_socket_close (&client); + + return 0; +} + +static void +stats_segment_socket_init (void) +{ + stats_main_t *sm = &stats_main; + clib_error_t *error; + clib_socket_t *s = clib_mem_alloc (sizeof (clib_socket_t)); + + s->config = (char *) sm->socket_name; + s->flags = CLIB_SOCKET_F_IS_SERVER | CLIB_SOCKET_F_SEQPACKET | + CLIB_SOCKET_F_ALLOW_GROUP_WRITE | CLIB_SOCKET_F_PASSCRED; + if ((error = clib_socket_init (s))) + { + clib_error_report (error); + return; + } + + clib_file_t template = { 0 }; + clib_file_main_t *fm = &file_main; + template.read_function = stats_socket_accept_ready; + template.file_descriptor = s->fd; + template.description = + format (0, "stats segment listener %s", STAT_SEGMENT_SOCKET_FILE); + clib_file_add (fm, &template); + + sm->socket = s; +} + static clib_error_t * stats_config (vlib_main_t * vm, unformat_input_t * input) { + stats_main_t *sm = &stats_main; u32 sec; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "interval %u", &sec)) + if (unformat (input, "socket-name %s", &sm->socket_name)) + ; + else if (unformat (input, "default")) + sm->socket_name = format (0, "%s", STAT_SEGMENT_SOCKET_FILE); + else if (unformat (input, "interval %u", &sec)) { int rv = stats_set_poller_delay (sec); if (rv) @@ -2274,7 +2333,6 @@ stats_config (vlib_main_t * vm, unformat_input_t * input) "`stats_set_poller_delay' API call failed, rv=%d:%U", (int) rv, format_vnet_api_errno, rv); } - return 0; } else { @@ -2282,6 +2340,10 @@ stats_config (vlib_main_t * vm, unformat_input_t * input) format_unformat_error, input); } } + + if (sm->socket_name) + stats_segment_socket_init (); + return 0; } @@ -2989,50 +3051,6 @@ stats_memclnt_delete_callback (u32 client_index) #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler -#define vl_api_map_stats_segment_t_print vl_noop_handler - -static void -vl_api_map_stats_segment_t_handler (vl_api_map_stats_segment_t * mp) -{ - vl_api_map_stats_segment_reply_t *rmp; - stats_main_t *sm = &stats_main; - ssvm_private_t *ssvmp = &sm->stat_segment; - vl_api_registration_t *regp; - api_main_t *am = &api_main; - clib_file_t *cf; - vl_api_shm_elem_config_t *config = 0; - vl_shmem_hdr_t *shmem_hdr; - int rv = 0; - - regp = vl_api_client_index_to_registration (mp->client_index); - if (regp == 0) - { - clib_warning ("API client disconnected"); - return; - } - if (regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER) - rv = VNET_API_ERROR_INVALID_REGISTRATION; - - rmp = vl_msg_api_alloc (sizeof (*rmp)); - rmp->_vl_msg_id = htons (VL_API_MAP_STATS_SEGMENT_REPLY); - rmp->context = mp->context; - rmp->retval = htonl (rv); - - vl_api_send_msg (regp, (u8 *) rmp); - - if (rv != 0) - return; - - /* - * We need the reply message to make it out the back door - * before we send the magic fd message so force a flush - */ - cf = vl_api_registration_file (regp); - cf->write_function (cf); - - /* Send the magic "here's your sign (aka fd)" socket message */ - vl_sock_api_send_fd_msg (cf->file_descriptor, ssvmp->fd); -} static clib_error_t * stats_init (vlib_main_t * vm) diff --git a/src/vpp/stats/stats.h b/src/vpp/stats/stats.h index 262304e81ed..3b6f781eee3 100644 --- a/src/vpp/stats/stats.h +++ b/src/vpp/stats/stats.h @@ -29,6 +29,9 @@ #include <svm/queue.h> #include <svm/ssvm.h> +/* Default socket to exchange segment fd */ +#define STAT_SEGMENT_SOCKET_FILE "/run/vpp/stats.sock" + typedef struct { volatile u32 lock; @@ -162,6 +165,8 @@ typedef struct ssvm_private_t stat_segment; uword *counter_vector_by_name; clib_spinlock_t *stat_segment_lockp; + clib_socket_t *socket; + u8 *socket_name; /* Pointers to scalar stats maintained by the stat thread */ f64 *input_rate_ptr; |