22 #include <sys/types.h> 23 #include <sys/socket.h> 32 #include <stdatomic.h> 63 struct msghdr msg = { 0 };
67 struct iovec io = {.iov_base = iobuf,.iov_len =
sizeof (iobuf) };
70 char buf[CMSG_SPACE (
sizeof (fd))];
75 msg.msg_control = u.buf;
76 msg.msg_controllen =
sizeof (u.buf);
79 if ((size = recvmsg (sock, &msg, 0)) < 0)
81 perror (
"recvmsg failed");
84 cmsg = CMSG_FIRSTHDR (&msg);
85 if (cmsg && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
87 memmove (&fd, CMSG_DATA (cmsg),
sizeof (fd));
107 if ((sock = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
109 perror (
"Stat client couldn't open socket");
113 struct sockaddr_un un = { 0 };
114 un.sun_family = AF_UNIX;
115 strncpy ((
char *) un.sun_path, socket_name, sizeof (un.sun_path) - 1);
116 if (connect (sock, (
struct sockaddr *) &un,
sizeof (
struct sockaddr_un)) <
123 if ((mfd =
recv_fd (sock)) < 0)
126 fprintf (stderr,
"Receiving file descriptor failed\n");
133 struct stat st = { 0 };
135 if (fstat (mfd, &st) == -1)
138 perror (
"mmap fstat failed");
142 mmap (
NULL, st.st_size, PROT_READ, MAP_SHARED, mfd, 0)) == MAP_FAILED)
145 perror (
"mmap map failed");
237 uint64_t *offset_vector;
256 for (i = 0; i <
vec_len (simple_c); i++)
271 for (i = 0; i <
vec_len (combined_c); i++)
284 for (i = 0; i <
vec_len (offset_vector); i++)
295 uint8_t **name_vector =
300 for (i = 0; i <
vec_len (name_vector); i++)
302 if (offset_vector[i])
314 fprintf (stderr,
"Unknown type: %d\n", ep->
type);
323 for (i = 0; i <
vec_len (res); i++)
328 for (j = 0; j <
vec_len (res[i].simple_counter_vec); j++)
329 vec_free (res[i].simple_counter_vec[j]);
330 vec_free (res[i].simple_counter_vec);
333 for (j = 0; j <
vec_len (res[i].combined_counter_vec); j++)
334 vec_free (res[i].combined_counter_vec[j]);
335 vec_free (res[i].combined_counter_vec);
351 regex_t regex[
vec_len (patterns)];
354 for (i = 0; i <
vec_len (patterns); i++)
356 int rv = regcomp (®ex[i], (
const char *) patterns[i], 0);
359 fprintf (stderr,
"Could not compile regex %s\n", patterns[i]);
367 for (j = 0; j <
vec_len (counter_vec); j++)
369 for (i = 0; i <
vec_len (patterns); i++)
371 int rv = regexec (®ex[i], counter_vec[j].
name, 0,
NULL, 0);
378 if (vec_len (patterns) == 0)
382 for (i = 0; i <
vec_len (patterns); i++)
418 for (i = 0; i <
vec_len (stats); i++)
428 fprintf (stderr,
"Epoch changed while reading, invalid results\n");
458 size_t len = strlen (
string);
462 return string_vector;
505 return strdup (ep->
name);
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
int stat_segment_connect_r(const char *socket_name, stat_client_main_t *sm)
int stat_segment_connect(const char *socket_name)
stat_segment_data_t * stat_segment_dump_entry(uint32_t index)
stat_segment_directory_entry_t * directory_vector
void stat_client_free(stat_client_main_t *sm)
char * stat_segment_index_to_name_r(uint32_t index, stat_client_main_t *sm)
void stat_segment_data_free(stat_segment_data_t *res)
counter_t ** simple_counter_vec
stat_client_main_t stat_client_main
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Combined counter to hold both packets and byte differences.
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
stat_segment_shared_header_t * shared_header
uint32_t * stat_segment_ls_r(uint8_t **patterns, stat_client_main_t *sm)
uint64_t counter_t
64bit counters
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
stat_segment_data_t * stat_segment_dump_entry_r(uint32_t index, stat_client_main_t *sm)
double stat_segment_heartbeat_r(stat_client_main_t *sm)
vl_api_fib_path_type_t type
static void * stat_segment_pointer(void *start, uint64_t offset)
#define vec_dup(V)
Return copy of vector (no header, no alignment)
stat_directory_type_t type
stat_segment_data_t * stat_segment_dump_r(uint32_t *stats, stat_client_main_t *sm)
void stat_segment_disconnect(void)
uint8_t ** stat_segment_string_vector(uint8_t **string_vector, const char *string)
#define vec_free(V)
Free vector's memory (no header).
char * stat_segment_index_to_name(uint32_t index)
#define vec_validate_init_c_string(V, S, L)
Make a vector containing a NULL terminated c-string.
uint32_t * stat_segment_ls(uint8_t **patterns)
static stat_segment_directory_entry_t * get_stat_vector_r(stat_client_main_t *sm)
stat_segment_data_t * stat_segment_dump(uint32_t *stats)
static bool stat_segment_access_end(stat_segment_access_t *sa, stat_client_main_t *sm)
static int recv_fd(int sock)
vlib_counter_t ** combined_counter_vec
uint64_t stat_segment_version(void)
stat_client_main_t * stat_client_get(void)
void stat_segment_vec_free(void *vec)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void stat_segment_access_start(stat_segment_access_t *sa, stat_client_main_t *sm)
int stat_segment_vec_len(void *vec)
static stat_segment_data_t copy_data(stat_segment_directory_entry_t *ep, stat_client_main_t *sm)
uint64_t stat_segment_version_r(stat_client_main_t *sm)
double stat_segment_heartbeat(void)
void stat_segment_disconnect_r(stat_client_main_t *sm)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
stat_directory_type_t type