export counters in a memfd segment
also export per-node error counters directory entries implement object types Change-Id: I8ce8e0a754e1be9de895c44ed9be6533b4ecef0f Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
@ -5884,7 +5884,8 @@ _(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)
|
||||
_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply) \
|
||||
_(MAP_STATS_SEGMENT_REPLY, map_stats_segment_reply)
|
||||
|
||||
#define foreach_standalone_reply_msg \
|
||||
_(SW_INTERFACE_EVENT, sw_interface_event) \
|
||||
@ -22431,6 +22432,92 @@ 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)
|
||||
{
|
||||
@ -22956,6 +23043,7 @@ api_qos_record_enable_disable (vat_main_t * vam)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
q_or_quit (vat_main_t * vam)
|
||||
{
|
||||
@ -22983,6 +23071,80 @@ comment (vat_main_t * vam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
statseg (vat_main_t * vam)
|
||||
{
|
||||
ssvm_private_t *ssvmp = &vam->stat_segment;
|
||||
ssvm_shared_header_t *shared_header = ssvmp->sh;
|
||||
vlib_counter_t **counters;
|
||||
u64 thread0_index1_packets;
|
||||
u64 thread0_index1_bytes;
|
||||
f64 vector_rate, input_rate;
|
||||
uword *p;
|
||||
|
||||
uword *counter_vector_by_name;
|
||||
if (vam->stat_segment_lockp == 0)
|
||||
{
|
||||
errmsg ("Stat segment not mapped...");
|
||||
return -99;
|
||||
}
|
||||
|
||||
/* look up "/if/rx for sw_if_index 1 as a test */
|
||||
|
||||
clib_spinlock_lock (vam->stat_segment_lockp);
|
||||
|
||||
counter_vector_by_name = (uword *) shared_header->opaque[1];
|
||||
|
||||
p = hash_get_mem (counter_vector_by_name, "/if/rx");
|
||||
if (p == 0)
|
||||
{
|
||||
clib_spinlock_unlock (vam->stat_segment_lockp);
|
||||
errmsg ("/if/tx not found?");
|
||||
return -99;
|
||||
}
|
||||
|
||||
/* Fish per-thread vector of combined counters from shared memory */
|
||||
counters = (vlib_counter_t **) p[0];
|
||||
|
||||
if (vec_len (counters[0]) < 2)
|
||||
{
|
||||
clib_spinlock_unlock (vam->stat_segment_lockp);
|
||||
errmsg ("/if/tx vector length %d", vec_len (counters[0]));
|
||||
return -99;
|
||||
}
|
||||
|
||||
/* Read thread 0 sw_if_index 1 counter */
|
||||
thread0_index1_packets = counters[0][1].packets;
|
||||
thread0_index1_bytes = counters[0][1].bytes;
|
||||
|
||||
p = hash_get_mem (counter_vector_by_name, "vector_rate");
|
||||
if (p == 0)
|
||||
{
|
||||
clib_spinlock_unlock (vam->stat_segment_lockp);
|
||||
errmsg ("vector_rate not found?");
|
||||
return -99;
|
||||
}
|
||||
|
||||
vector_rate = *(f64 *) (p[0]);
|
||||
p = hash_get_mem (counter_vector_by_name, "input_rate");
|
||||
if (p == 0)
|
||||
{
|
||||
clib_spinlock_unlock (vam->stat_segment_lockp);
|
||||
errmsg ("input_rate not found?");
|
||||
return -99;
|
||||
}
|
||||
input_rate = *(f64 *) (p[0]);
|
||||
|
||||
clib_spinlock_unlock (vam->stat_segment_lockp);
|
||||
|
||||
print (vam->ofp, "vector_rate %.2f input_rate %.2f",
|
||||
vector_rate, input_rate);
|
||||
print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
|
||||
thread0_index1_packets, thread0_index1_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_cmp (void *a1, void *a2)
|
||||
{
|
||||
@ -23799,7 +23961,8 @@ _(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]")
|
||||
_(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]") \
|
||||
_(map_stats_segment, "<no-args>")
|
||||
|
||||
/* List of command functions, CLI names map directly to functions */
|
||||
#define foreach_cli_function \
|
||||
@ -23822,7 +23985,9 @@ _(quit, "usage: quit") \
|
||||
_(search_node_table, "usage: search_node_table <name>...") \
|
||||
_(set, "usage: set <variable-name> <value>") \
|
||||
_(script, "usage: script <file-name>") \
|
||||
_(statseg, "usage: statseg"); \
|
||||
_(unset, "usage: unset <variable-name>")
|
||||
|
||||
#define _(N,n) \
|
||||
static void vl_api_##n##_t_handler_uni \
|
||||
(vl_api_##n##_t * mp) \
|
||||
|
@ -209,6 +209,9 @@ typedef struct
|
||||
ip4_nbr_counter_t **ip4_nbr_counters;
|
||||
ip6_nbr_counter_t **ip6_nbr_counters;
|
||||
|
||||
ssvm_private_t stat_segment;
|
||||
clib_spinlock_t *stat_segment_lockp;
|
||||
|
||||
socket_client_main_t *socket_client_main;
|
||||
u8 *socket_name;
|
||||
|
||||
|
@ -25,7 +25,6 @@ libvppcom_la_SOURCES += \
|
||||
vcl/vcl_event.c \
|
||||
vcl/vppcom.c \
|
||||
$(libvppinfra_la_SOURCES) \
|
||||
$(libvlib_la_SOURCES) \
|
||||
$(libsvm_la_SOURCES) \
|
||||
$(libvlibmemoryclient_la_SOURCES)
|
||||
|
||||
|
@ -87,13 +87,4 @@ nobase_include_HEADERS += \
|
||||
vlib/unix/plugin.h \
|
||||
vlib/unix/unix.h
|
||||
|
||||
noinst_PROGRAMS += vlib_unix
|
||||
|
||||
vlib_unix_SOURCES = \
|
||||
examples/vlib/main_stub.c \
|
||||
examples/vlib/mc_test.c
|
||||
|
||||
vlib_unix_LDADD = libvlib.la \
|
||||
libvppinfra.la -lpthread -lm -ldl -lrt
|
||||
|
||||
# vi:syntax=automake
|
||||
|
@ -74,15 +74,32 @@ vlib_clear_combined_counters (vlib_combined_counter_main_t * cm)
|
||||
}
|
||||
}
|
||||
|
||||
void *vlib_stats_push_heap (void) __attribute__ ((weak));
|
||||
void *
|
||||
vlib_stats_push_heap (void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
void vlib_stats_pop_heap (void *, void *) __attribute__ ((weak));
|
||||
void
|
||||
vlib_stats_pop_heap (void *notused, void *notused2)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index)
|
||||
{
|
||||
vlib_thread_main_t *tm = vlib_get_thread_main ();
|
||||
int i;
|
||||
void *oldheap = vlib_stats_push_heap ();
|
||||
|
||||
vec_validate (cm->counters, tm->n_vlib_mains - 1);
|
||||
for (i = 0; i < tm->n_vlib_mains; i++)
|
||||
vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES);
|
||||
|
||||
vlib_stats_pop_heap (cm, oldheap);
|
||||
}
|
||||
|
||||
void
|
||||
@ -90,10 +107,13 @@ vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index)
|
||||
{
|
||||
vlib_thread_main_t *tm = vlib_get_thread_main ();
|
||||
int i;
|
||||
void *oldheap = vlib_stats_push_heap ();
|
||||
|
||||
vec_validate (cm->counters, tm->n_vlib_mains - 1);
|
||||
for (i = 0; i < tm->n_vlib_mains; i++)
|
||||
vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES);
|
||||
|
||||
vlib_stats_pop_heap (cm, oldheap);
|
||||
}
|
||||
|
||||
u32
|
||||
|
@ -63,6 +63,7 @@ typedef struct
|
||||
serialized incrementally. */
|
||||
|
||||
char *name; /**< The counter collection's name. */
|
||||
char *stat_segment_name; /**< Name in stat segment directory */
|
||||
} vlib_simple_counter_main_t;
|
||||
|
||||
/** The number of counters (not the number of per-thread counters) */
|
||||
@ -183,6 +184,7 @@ typedef struct
|
||||
vlib_counter_t *value_at_last_serialize; /**< Counter values as of last serialize. */
|
||||
u32 last_incremental_serialize_index; /**< Last counter index serialized incrementally. */
|
||||
char *name; /**< The counter collection's name. */
|
||||
char *stat_segment_name; /**< Name in stat segment directory */
|
||||
} vlib_combined_counter_main_t;
|
||||
|
||||
/** The number of counters (not the number of per-thread counters) */
|
||||
|
@ -140,6 +140,19 @@ VLIB_REGISTER_NODE (misc_drop_buffers_node,static) = {
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
void vlib_stats_register_error_index (u8 *, u64) __attribute__ ((weak));
|
||||
void
|
||||
vlib_stats_register_error_index (u8 * notused, u64 notused2)
|
||||
{
|
||||
};
|
||||
|
||||
void vlib_stats_pop_heap2 (void *, u32, void *) __attribute__ ((weak));
|
||||
void
|
||||
vlib_stats_pop_heap2 (void *notused, u32 notused2, void *notused3)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
/* Reserves given number of error codes for given node. */
|
||||
void
|
||||
vlib_register_errors (vlib_main_t * vm,
|
||||
@ -148,6 +161,8 @@ vlib_register_errors (vlib_main_t * vm,
|
||||
vlib_error_main_t *em = &vm->error_main;
|
||||
vlib_node_t *n = vlib_get_node (vm, node_index);
|
||||
uword l;
|
||||
void *oldheap;
|
||||
void *vlib_stats_push_heap (void) __attribute__ ((weak));
|
||||
|
||||
ASSERT (vlib_get_thread_index () == 0);
|
||||
|
||||
@ -169,9 +184,13 @@ vlib_register_errors (vlib_main_t * vm,
|
||||
clib_memcpy (vec_elt_at_index (em->error_strings_heap, n->error_heap_index),
|
||||
error_strings, n_errors * sizeof (error_strings[0]));
|
||||
|
||||
vec_validate (vm->error_elog_event_types, l - 1);
|
||||
|
||||
/* Switch to the stats segment ... */
|
||||
oldheap = vlib_stats_push_heap ();
|
||||
|
||||
/* Allocate a counter/elog type for each error. */
|
||||
vec_validate (em->counters, l - 1);
|
||||
vec_validate (vm->error_elog_event_types, l - 1);
|
||||
|
||||
/* Zero counters for re-registrations of errors. */
|
||||
if (n->error_heap_index + n_errors <= vec_len (em->counters_last_clear))
|
||||
@ -182,6 +201,22 @@ vlib_register_errors (vlib_main_t * vm,
|
||||
memset (em->counters + n->error_heap_index,
|
||||
0, n_errors * sizeof (em->counters[0]));
|
||||
|
||||
/* Register counter indices in the stat segment directory */
|
||||
{
|
||||
int i;
|
||||
u8 *error_name;
|
||||
|
||||
for (i = 0; i < n_errors; i++)
|
||||
{
|
||||
error_name = format (0, "/err/%s%c", error_strings[i], 0);
|
||||
/* Note: error_name consumed by the following call */
|
||||
vlib_stats_register_error_index (error_name, n->error_heap_index + i);
|
||||
}
|
||||
}
|
||||
|
||||
/* (re)register the em->counters base address, switch back to main heap */
|
||||
vlib_stats_pop_heap2 (em->counters, vm->thread_index, oldheap);
|
||||
|
||||
{
|
||||
elog_event_type_t t;
|
||||
uword i;
|
||||
|
@ -1717,6 +1717,12 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = vlib_call_init_function (vm, map_stat_segment_init)))
|
||||
{
|
||||
clib_error_report (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Register static nodes so that init functions may use them. */
|
||||
vlib_register_all_static_nodes (vm);
|
||||
|
||||
@ -1736,6 +1742,24 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = vlib_call_init_function (vm, vpe_api_init)))
|
||||
{
|
||||
clib_error_report (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = vlib_call_init_function (vm, vlibmemory_init)))
|
||||
{
|
||||
clib_error_report (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = vlib_call_init_function (vm, map_api_segment_init)))
|
||||
{
|
||||
clib_error_report (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* See unix/main.c; most likely already set up */
|
||||
if (vm->init_functions_called == 0)
|
||||
vm->init_functions_called = hash_create (0, /* value bytes */ 0);
|
||||
|
@ -459,6 +459,22 @@ vl_mem_api_init (const char *region_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
map_api_segment_init (vlib_main_t * vm)
|
||||
{
|
||||
api_main_t *am = &api_main;
|
||||
int rv;
|
||||
|
||||
if ((rv = vl_mem_api_init (am->region_name)) < 0)
|
||||
{
|
||||
return clib_error_return (0, "vl_mem_api_init (%s) failed",
|
||||
am->region_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VLIB_INIT_FUNCTION (map_api_segment_init);
|
||||
|
||||
static void
|
||||
send_memclnt_keepalive (vl_api_registration_t * regp, f64 now)
|
||||
{
|
||||
|
@ -287,12 +287,6 @@ vl_api_clnt_process (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
uword *event_data = 0;
|
||||
f64 now;
|
||||
|
||||
if ((rv = vl_mem_api_init (am->region_name)) < 0)
|
||||
{
|
||||
clib_warning ("memory_api_init returned %d, quitting...", rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((error = vl_sock_api_init (vm)))
|
||||
{
|
||||
clib_error_report (error);
|
||||
|
@ -1250,6 +1250,10 @@ vnet_interface_init (vlib_main_t * vm)
|
||||
CLIB_CACHE_LINE_BYTES);
|
||||
im->sw_if_counter_lock[0] = 1; /* should be no need */
|
||||
|
||||
/*
|
||||
* $$$$ add stat segment name(s) if desired
|
||||
* set xxx.stat_segment_name = "whatever"...
|
||||
*/
|
||||
vec_validate (im->sw_if_counters, VNET_N_SIMPLE_INTERFACE_COUNTER - 1);
|
||||
im->sw_if_counters[VNET_INTERFACE_COUNTER_DROP].name = "drops";
|
||||
im->sw_if_counters[VNET_INTERFACE_COUNTER_PUNT].name = "punts";
|
||||
|
19
src/vpp.am
19
src/vpp.am
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
bin_PROGRAMS += bin/vpp
|
||||
bin_PROGRAMS += bin/vpp
|
||||
|
||||
bin_vpp_SOURCES = \
|
||||
vpp/vnet/main.c \
|
||||
@ -19,7 +19,8 @@ bin_vpp_SOURCES = \
|
||||
vpp/app/version.c \
|
||||
vpp/oam/oam.c \
|
||||
vpp/oam/oam_api.c \
|
||||
vpp/stats/stats.c
|
||||
vpp/stats/stats.c \
|
||||
vpp/stats/stat_segment.c
|
||||
|
||||
bin_vpp_SOURCES += \
|
||||
vpp/api/api.c \
|
||||
@ -130,6 +131,20 @@ bin_summary_stats_client_LDADD = \
|
||||
libvppinfra.la \
|
||||
-lpthread -lm -lrt
|
||||
|
||||
noinst_PROGRAMS += bin/stat_client
|
||||
|
||||
bin_stat_client_SOURCES = \
|
||||
vpp/app/stat_client.c \
|
||||
vpp/app/stat_client.h
|
||||
|
||||
bin_stat_client_LDADD = \
|
||||
libvlibmemoryclient.la \
|
||||
libsvm.la \
|
||||
libvppinfra.la \
|
||||
-lpthread -lm -lrt
|
||||
|
||||
|
||||
|
||||
bin_PROGRAMS += bin/vpp_get_metrics
|
||||
|
||||
bin_vpp_get_metrics_SOURCES = \
|
||||
|
343
src/vpp/app/stat_client.c
Normal file
343
src/vpp/app/stat_client.c
Normal file
File diff suppressed because it is too large
Load Diff
70
src/vpp/app/stat_client.h
Normal file
70
src/vpp/app/stat_client.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __included_stat_client_h__
|
||||
#define __included_stat_client_h__
|
||||
|
||||
#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
|
||||
{
|
||||
u64 current_epoch;
|
||||
|
||||
/* Cached pointers to scalar quantities, these wont change */
|
||||
f64 *vector_rate_ptr;
|
||||
f64 *input_rate_ptr;
|
||||
|
||||
volatile int segment_ready;
|
||||
|
||||
/*
|
||||
* Cached pointers to vector quantities,
|
||||
* MUST invalidate when the epoch changes
|
||||
*/
|
||||
vlib_counter_t **intfc_rx_counters;
|
||||
vlib_counter_t **intfc_tx_counters;
|
||||
|
||||
u64 *thread_0_error_counts;
|
||||
u64 source_address_match_error_index;
|
||||
|
||||
/* 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;
|
||||
|
||||
u8 *socket_name;
|
||||
} stat_client_main_t;
|
||||
|
||||
extern stat_client_main_t stat_client_main;
|
||||
|
||||
#endif /* __included_stat_client_h__ */
|
||||
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
425
src/vpp/stats/stat_segment.c
Normal file
425
src/vpp/stats/stat_segment.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -58,6 +58,8 @@ 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
|
||||
@ -472,6 +474,13 @@ 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:
|
||||
* eval: (c-set-style "gnu")
|
||||
|
@ -48,24 +48,25 @@ stats_main_t stats_main;
|
||||
#define foreach_stats_msg \
|
||||
_(WANT_STATS, want_stats) \
|
||||
_(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters) \
|
||||
_(WANT_INTERFACE_SIMPLE_STATS, want_interface_simple_stats) \
|
||||
_(WANT_INTERFACE_SIMPLE_STATS, want_interface_simple_stats) \
|
||||
_(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters) \
|
||||
_(WANT_INTERFACE_COMBINED_STATS, want_interface_combined_stats) \
|
||||
_(WANT_INTERFACE_COMBINED_STATS, want_interface_combined_stats) \
|
||||
_(WANT_PER_INTERFACE_COMBINED_STATS, want_per_interface_combined_stats) \
|
||||
_(WANT_PER_INTERFACE_SIMPLE_STATS, want_per_interface_simple_stats) \
|
||||
_(WANT_PER_INTERFACE_SIMPLE_STATS, want_per_interface_simple_stats) \
|
||||
_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
|
||||
_(WANT_IP4_FIB_STATS, want_ip4_fib_stats) \
|
||||
_(WANT_IP4_FIB_STATS, want_ip4_fib_stats) \
|
||||
_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
|
||||
_(WANT_IP6_FIB_STATS, want_ip6_fib_stats) \
|
||||
_(WANT_IP6_FIB_STATS, want_ip6_fib_stats) \
|
||||
_(WANT_IP4_MFIB_STATS, want_ip4_mfib_stats) \
|
||||
_(WANT_IP6_MFIB_STATS, want_ip6_mfib_stats) \
|
||||
_(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters) \
|
||||
_(WANT_IP4_NBR_STATS, want_ip4_nbr_stats) \
|
||||
_(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)
|
||||
_(WANT_IP4_NBR_STATS, want_ip4_nbr_stats) \
|
||||
_(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)
|
||||
|
||||
#define vl_msg_name_crc_list
|
||||
#include <vpp/stats/stats.api.h>
|
||||
@ -2934,6 +2935,50 @@ 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)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <vlibmemory/api.h>
|
||||
#include <vlibapi/api_helper_macros.h>
|
||||
#include <svm/queue.h>
|
||||
#include <svm/ssvm.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -157,6 +158,15 @@ typedef struct
|
||||
vpe_client_stats_registration_t **regs_tmp;
|
||||
vpe_client_registration_t **clients_tmp;
|
||||
|
||||
/* statistics segment */
|
||||
ssvm_private_t stat_segment;
|
||||
uword *counter_vector_by_name;
|
||||
clib_spinlock_t *stat_segment_lockp;
|
||||
|
||||
/* Pointers to scalar stats maintained by the stat segment process */
|
||||
f64 *input_rate_ptr;
|
||||
f64 *vector_rate_ptr;
|
||||
|
||||
/* convenience */
|
||||
vlib_main_t *vlib_main;
|
||||
vnet_main_t *vnet_main;
|
||||
@ -166,6 +176,25 @@ typedef struct
|
||||
|
||||
extern stats_main_t stats_main;
|
||||
|
||||
#define STAT_SEGMENT_OPAQUE_LOCK 0
|
||||
#define STAT_SEGMENT_OPAQUE_DIR 1
|
||||
#define STAT_SEGMENT_OPAQUE_EPOCH 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STAT_DIR_TYPE_ILLEGAL = 0,
|
||||
STAT_DIR_TYPE_SCALAR_POINTER,
|
||||
STAT_DIR_TYPE_VECTOR_POINTER,
|
||||
STAT_DIR_TYPE_COUNTER_VECTOR,
|
||||
STAT_DIR_TYPE_ERROR_INDEX,
|
||||
} stat_directory_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
stat_directory_type_t type;
|
||||
void *value;
|
||||
} stat_segment_directory_entry_t;
|
||||
|
||||
#endif /* __included_stats_h__ */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user