Line data Source code
1 : /* 2 : * stat_client.h - Library for access to VPP statistics segment 3 : * 4 : * Copyright (c) 2018 Cisco and/or its affiliates. 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at: 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : #ifndef included_stat_client_h 18 : #define included_stat_client_h 19 : 20 : #define STAT_VERSION_MAJOR 1 21 : #define STAT_VERSION_MINOR 2 22 : 23 : #include <stdint.h> 24 : #include <unistd.h> 25 : #include <vlib/counter_types.h> 26 : #include <time.h> 27 : #include <stdbool.h> 28 : #include <vlib/stats/shared.h> 29 : 30 : /* Default socket to exchange segment fd */ 31 : /* TODO: Get from runtime directory */ 32 : #define STAT_SEGMENT_SOCKET_FILE "/run/vpp/stats.sock" 33 : #define STAT_SEGMENT_SOCKET_FILENAME "stats.sock" 34 : 35 : typedef struct 36 : { 37 : char *name; 38 : stat_directory_type_t type; 39 : bool via_symlink; 40 : union 41 : { 42 : double scalar_value; 43 : counter_t *error_vector; 44 : counter_t **simple_counter_vec; 45 : vlib_counter_t **combined_counter_vec; 46 : uint8_t **name_vector; 47 : }; 48 : } stat_segment_data_t; 49 : 50 : typedef struct 51 : { 52 : uint64_t current_epoch; 53 : vlib_stats_shared_header_t *shared_header; 54 : vlib_stats_entry_t *directory_vector; 55 : ssize_t memory_size; 56 : uint64_t timeout; 57 : } stat_client_main_t; 58 : 59 : extern stat_client_main_t stat_client_main; 60 : 61 : stat_client_main_t *stat_client_get (void); 62 : void stat_client_free (stat_client_main_t * sm); 63 : int stat_segment_connect_r (const char *socket_name, stat_client_main_t * sm); 64 : int stat_segment_connect (const char *socket_name); 65 : void stat_segment_disconnect_r (stat_client_main_t * sm); 66 : void stat_segment_disconnect (void); 67 : uint8_t **stat_segment_string_vector (uint8_t ** string_vector, 68 : const char *string); 69 : int stat_segment_vec_len (void *vec); 70 : void stat_segment_vec_free (void *vec); 71 : uint32_t *stat_segment_ls_r (uint8_t ** patterns, stat_client_main_t * sm); 72 : uint32_t *stat_segment_ls (uint8_t ** pattern); 73 : stat_segment_data_t *stat_segment_dump_r (uint32_t * stats, 74 : stat_client_main_t * sm); 75 : stat_segment_data_t *stat_segment_dump (uint32_t * counter_vec); 76 : stat_segment_data_t *stat_segment_dump_entry_r (uint32_t index, 77 : stat_client_main_t * sm); 78 : stat_segment_data_t *stat_segment_dump_entry (uint32_t index); 79 : 80 : void stat_segment_data_free (stat_segment_data_t * res); 81 : double stat_segment_heartbeat_r (stat_client_main_t * sm); 82 : double stat_segment_heartbeat (void); 83 : 84 : char *stat_segment_index_to_name_r (uint32_t index, stat_client_main_t * sm); 85 : char *stat_segment_index_to_name (uint32_t index); 86 : uint64_t stat_segment_version (void); 87 : uint64_t stat_segment_version_r (stat_client_main_t * sm); 88 : 89 : typedef struct 90 : { 91 : uint64_t epoch; 92 : } stat_segment_access_t; 93 : 94 : static inline uint64_t 95 0 : _time_now_nsec (void) 96 : { 97 : struct timespec ts; 98 0 : clock_gettime (CLOCK_REALTIME, &ts); 99 0 : return 1e9 * ts.tv_sec + ts.tv_nsec; 100 : } 101 : 102 : static inline void * 103 0 : stat_segment_adjust (stat_client_main_t * sm, void *data) 104 : { 105 0 : char *csh = (char *) sm->shared_header; 106 0 : char *p = csh + ((char *) data - (char *) sm->shared_header->base); 107 0 : if (p > csh && p + sizeof (p) < csh + sm->memory_size) 108 0 : return (void *) p; 109 0 : return 0; 110 : } 111 : 112 : /* 113 : * Returns 0 on success, -1 on failure (timeout) 114 : */ 115 : static inline int 116 0 : stat_segment_access_start (stat_segment_access_t * sa, 117 : stat_client_main_t * sm) 118 : { 119 0 : vlib_stats_shared_header_t *shared_header = sm->shared_header; 120 : uint64_t max_time; 121 : 122 0 : sa->epoch = shared_header->epoch; 123 0 : if (sm->timeout) 124 : { 125 0 : max_time = _time_now_nsec () + sm->timeout; 126 0 : while (shared_header->in_progress != 0 && _time_now_nsec () < max_time) 127 : ; 128 : } 129 : else 130 : { 131 0 : while (shared_header->in_progress != 0) 132 : ; 133 : } 134 0 : sm->directory_vector = (vlib_stats_entry_t *) stat_segment_adjust ( 135 0 : sm, (void *) sm->shared_header->directory_vector); 136 0 : if (sm->timeout) 137 0 : return _time_now_nsec () < max_time ? 0 : -1; 138 0 : return 0; 139 : } 140 : 141 : /* 142 : * set maximum number of nano seconds to wait for in_progress state 143 : */ 144 : static inline void 145 : stat_segment_set_timeout_nsec (stat_client_main_t * sm, uint64_t timeout) 146 : { 147 : sm->timeout = timeout; 148 : } 149 : 150 : /* 151 : * set maximum number of nano seconds to wait for in_progress state 152 : * this function can be called directly by module using shared stat 153 : * segment 154 : */ 155 : static inline void 156 : stat_segment_set_timeout (uint64_t timeout) 157 : { 158 : stat_client_main_t *sm = &stat_client_main; 159 : stat_segment_set_timeout_nsec (sm, timeout); 160 : } 161 : 162 : 163 : static inline bool 164 0 : stat_segment_access_end (stat_segment_access_t * sa, stat_client_main_t * sm) 165 : { 166 0 : vlib_stats_shared_header_t *shared_header = sm->shared_header; 167 : 168 0 : if (shared_header->epoch != sa->epoch || shared_header->in_progress) 169 0 : return false; 170 0 : return true; 171 : } 172 : 173 : #endif /* included_stat_client_h */ 174 : 175 : /* 176 : * fd.io coding-style-patch-verification: ON 177 : * 178 : * Local Variables: 179 : * eval: (c-set-style "gnu") 180 : * End: 181 : */