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));
114 if ((sock = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
116 perror (
"Stat client couldn't open socket");
120 struct sockaddr_un un = { 0 };
121 un.sun_family = AF_UNIX;
122 strncpy ((
char *) un.sun_path, socket_name, sizeof (un.sun_path) - 1);
123 if (connect (sock, (
struct sockaddr *) &un,
sizeof (
struct sockaddr_un)) <
130 if ((mfd =
recv_fd (sock)) < 0)
133 fprintf (stderr,
"Receiving file descriptor failed\n");
140 struct stat st = { 0 };
142 if (fstat (mfd, &st) == -1)
145 perror (
"mmap fstat failed");
149 mmap (
NULL, st.st_size, PROT_READ, MAP_SHARED, mfd, 0)) == MAP_FAILED)
152 perror (
"mmap map failed");
209 uint64_t *offset_vector;
228 for (i = 0; i <
vec_len (simple_c); i++)
243 for (i = 0; i <
vec_len (combined_c); i++)
261 uint8_t **name_vector =
266 for (i = 0; i <
vec_len (name_vector); i++)
268 if (offset_vector[i])
280 fprintf (stderr,
"Unknown type: %d\n", ep->
type);
289 for (i = 0; i <
vec_len (res); i++)
294 for (j = 0; j <
vec_len (res[i].simple_counter_vec); j++)
295 vec_free (res[i].simple_counter_vec[j]);
296 vec_free (res[i].simple_counter_vec);
299 for (j = 0; j <
vec_len (res[i].combined_counter_vec); j++)
300 vec_free (res[i].combined_counter_vec[j]);
301 vec_free (res[i].combined_counter_vec);
345 regex_t regex[
vec_len (patterns)];
348 for (i = 0; i <
vec_len (patterns); i++)
350 int rv = regcomp (®ex[i], (
const char *) patterns[i], 0);
353 fprintf (stderr,
"Could not compile regex %s\n", patterns[i]);
361 for (j = 0; j <
vec_len (counter_vec); j++)
363 for (i = 0; i <
vec_len (patterns); i++)
365 int rv = regexec (®ex[i], counter_vec[j].
name, 0,
NULL, 0);
372 if (vec_len (patterns) == 0)
376 for (i = 0; i <
vec_len (patterns); i++)
412 for (i = 0; i <
vec_len (stats); i++)
422 fprintf (stderr,
"Epoch changed while reading, invalid results\n");
452 size_t len = strlen (
string);
456 return string_vector;
491 name = strdup (ep->
name);
static stat_segment_directory_entry_t * get_stat_vector(void)
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)
void stat_segment_data_free(stat_segment_data_t *res)
counter_t ** simple_counter_vec
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
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.
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)
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
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)
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