summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2018-06-14 14:42:14 +0200
committerDave Barach <openvpp@barachs.net>2018-06-15 12:16:32 +0000
commite906aacc1089ce86158486ec52d37a8470359ec2 (patch)
treea0fea12e785a4b1add2ffe6713b0b05b69df384c
parent1ec0ea85c3f57f4638e32a00396057f80d958ec9 (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>
-rw-r--r--src/vat/api_format.c92
-rw-r--r--src/vpp/app/stat_client.c124
-rw-r--r--src/vpp/app/stat_client.h7
-rw-r--r--src/vpp/stats/stats.api8
-rw-r--r--src/vpp/stats/stats.c114
-rw-r--r--src/vpp/stats/stats.h5
6 files changed, 98 insertions, 252 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index b9f08048651..f2d10b78de5 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -5930,8 +5930,7 @@ _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
_(SESSION_RULES_DETAILS, session_rules_details) \
_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply) \
-_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
-_(MAP_STATS_SEGMENT_REPLY, map_stats_segment_reply)
+_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
#define foreach_standalone_reply_msg \
_(SW_INTERFACE_EVENT, sw_interface_event) \
@@ -22531,92 +22530,6 @@ api_app_namespace_add_del (vat_main_t * vam)
return ret;
}
-static void vl_api_map_stats_segment_reply_t_handler
- (vl_api_map_stats_segment_reply_t * mp)
-{
-#if VPP_API_TEST_BUILTIN == 0
- vat_main_t *vam = &vat_main;
- ssvm_private_t *ssvmp = &vam->stat_segment;
- ssvm_shared_header_t *shared_header;
- socket_client_main_t *scm = vam->socket_client_main;
- int rv = ntohl (mp->retval);
- int my_fd, retval;
- clib_error_t *error;
-
- vam->retval = rv;
-
- if (rv != 0)
- {
- vam->result_ready = 1;
- return;
- }
-
- /*
- * Check the socket for the magic fd
- */
- error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5);
- if (error)
- {
- clib_error_report (error);
- vam->retval = -99;
- vam->result_ready = 1;
- return;
- }
-
- memset (ssvmp, 0, sizeof (*ssvmp));
- ssvmp->fd = my_fd;
-
- /* Note: this closes memfd.fd */
- retval = ssvm_slave_init_memfd (ssvmp);
- if (retval)
- {
- clib_warning ("WARNING: segment map returned %d", retval);
- vam->retval = -99;
- vam->result_ready = 1;
- return;
- }
- else
- errmsg ("stat segment mapped OK...");
-
- ASSERT (ssvmp && ssvmp->sh);
-
- /* Pick up the segment lock from the shared memory header */
- shared_header = ssvmp->sh;
- vam->stat_segment_lockp = (clib_spinlock_t *) (shared_header->opaque[0]);
- vam->retval = 0;
- vam->result_ready = 1;
-#endif
-}
-
-static void vl_api_map_stats_segment_reply_t_handler_json
- (vl_api_map_stats_segment_reply_t * mp)
-{
-#if VPP_API_TEST_BUILTIN == 0
- vat_main_t *vam = &vat_main;
- clib_warning ("not implemented");
- vam->retval = -99;
- vam->result_ready = 1;
-#endif
-}
-
-static int
-api_map_stats_segment (vat_main_t * vam)
-{
-#if VPP_API_TEST_BUILTIN == 0
- vl_api_map_stats_segment_t *mp;
- int ret;
-
- M (MAP_STATS_SEGMENT, mp);
- S (mp);
- W (ret);
-
- return ret;
-#else
- errmsg ("api unavailable");
- return -99;
-#endif
-}
-
static int
api_sock_init_shm (vat_main_t * vam)
{
@@ -24063,8 +23976,7 @@ _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
_(output_acl_set_interface, \
"<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
" [l2-table <nn>] [del]") \
-_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]") \
-_(map_stats_segment, "<no-args>")
+_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
/* List of command functions, CLI names map directly to functions */
#define foreach_cli_function \
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;