session: support multiple worker binds
[vpp.git] / src / vcl / vcl_debug.h
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef SRC_VCL_VCL_DEBUG_H_
17 #define SRC_VCL_VCL_DEBUG_H_
18
19 #include <vppinfra/elog.h>
20
21 #define VCL_ELOG        0
22
23 #define VDBG(_lvl, _fmt, _args...)                                      \
24   if (vcm->debug > _lvl)                                                \
25     clib_warning ("vcl<w%u>: " _fmt, __vcl_worker_index, ##_args)
26
27 #define foreach_vcl_dbg_evt                                             \
28   _(INIT, "vcl init track")                                             \
29   _(TIMEOUT, "vcl timeout")                                             \
30   _(DETACH, "vcl detach")                                               \
31   _(SESSION_INIT, "init session track")                                 \
32   _(SESSION_TIMEOUT, "session timeout")                                 \
33   _(CREATE, "session create")                                           \
34   _(CLOSE, "session close")                                             \
35   _(BIND, "session bind")                                               \
36   _(UNBIND, "session unbind")                                           \
37   _(ACCEPT, "session accept")                                           \
38   _(EPOLL_CREATE, "epoll session create")                               \
39   _(EPOLL_CTLADD, "epoll ctl add")                                      \
40   _(EPOLL_CTLDEL, "epoll ctl del")                                      \
41
42 typedef enum vcl_dbg_evt_
43 {
44 #define _(sym, str) VCL_EVT_##sym,
45   foreach_vcl_dbg_evt
46 #undef _
47 } vcl_dbg_evt_e;
48
49 #if VCL_ELOG
50
51 #define VCL_DECLARE_ETD(_s, _e, _size)                                  \
52   struct { u32 data[_size]; } * ed;                                     \
53   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track)            \
54
55 #define VCL_EVT_INIT_HANDLER(_vcm, ...)                                 \
56 {                                                                       \
57   _vcm->elog_track.name = (char *) format (0, "P:%d:C:%d%c", getpid (), \
58                                           _vcm->my_client_index, 0);    \
59   elog_track_register (&_vcm->elog_main, &_vcm->elog_track);            \
60   ELOG_TYPE_DECLARE (e) =                                               \
61   {                                                                     \
62         .format = "connect_vpp:rv:%d",                                  \
63         .format_args = "i4",                                            \
64   };                                                                    \
65   struct { u32 data; } *ed;                                             \
66   ed = ELOG_TRACK_DATA (&_vcm->elog_main, e, _vcm->elog_track);         \
67   ed->data = (u32) rv;                                                  \
68 }
69
70 #define VCL_EVT_SESSION_INIT_HANDLER(_s, _s_index, ...)                 \
71 {                                                                       \
72   _s->elog_track.name = (char *) format (0, "CI:%d:S:%d%c",             \
73                                          vcm->my_client_index,          \
74                                          _s_index, 0);                  \
75   elog_track_register (&vcm->elog_main, &_s->elog_track);               \
76 }
77
78 #define VCL_EVT_BIND_HANDLER(_s, ...)                                   \
79 {                                                                       \
80   if (_s->lcl_addr.is_ip4)                                              \
81     {                                                                   \
82       ELOG_TYPE_DECLARE (_e) =                                          \
83       {                                                                 \
84         .format = "bind local:%s:%d.%d.%d.%d:%d ",                      \
85         .format_args = "t1i1i1i1i1i2",                                  \
86         .n_enum_strings = 2,                                            \
87         .enum_strings = {"TCP", "UDP",},                                \
88       };                                                                \
89       CLIB_PACKED (struct {                                             \
90         u8 proto;                                                       \
91         u8 addr[4];                                                     \
92         u16 port;                                                       \
93       }) *ed;                                                           \
94       ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);       \
95       ed->proto = _s->proto;                                            \
96       ed->addr[0] = _s->lcl_addr.ip46.ip4.as_u8[0];                     \
97       ed->addr[1] = _s->lcl_addr.ip46.ip4.as_u8[1];                     \
98       ed->addr[2] = _s->lcl_addr.ip46.ip4.as_u8[2];                     \
99       ed->addr[3] = _s->lcl_addr.ip46.ip4.as_u8[3];                     \
100       ed->port = clib_net_to_host_u16 (_s->lcl_port);                   \
101     }                                                                   \
102   else                                                                  \
103     {                                                                   \
104       /* TBD */                                                         \
105     }                                                                   \
106 }
107
108 #define VCL_EVT_ACCEPT_HANDLER(_s, _ls, _s_idx, ...)                    \
109 {                                                                       \
110   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
111   ELOG_TYPE_DECLARE (_e) =                                              \
112   {                                                                     \
113     .format = "accept: listen_handle:%x from_handle:%x",                \
114     .format_args = "i8i8",                                              \
115   };                                                                    \
116   struct { u64 handle[2];  } *ed;                                       \
117   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
118   ed->handle[0] = _ls->vpp_handle;                                      \
119   ed->handle[1] = _s->vpp_handle;                                       \
120   if (_s->peer_addr.is_ip4)                                             \
121     {                                                                   \
122       ELOG_TYPE_DECLARE (_e) =                                          \
123       {                                                                 \
124         .format = "accept:S:%x addr:%d.%d.%d.%d:%d",                    \
125         .format_args = "i8i1i1i1i1i2",                                  \
126       };                                                                \
127       CLIB_PACKED (struct {                                             \
128         u32 s_idx;                                                      \
129         u8 addr[4];                                                     \
130         u16 port;                                                       \
131       }) * ed;                                                          \
132       ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);       \
133       ed->s_idx = _s_idx;                                               \
134       ed->addr[0] = _s->peer_addr.ip46.ip4.as_u8[0];                    \
135       ed->addr[1] = _s->peer_addr.ip46.ip4.as_u8[1];                    \
136       ed->addr[2] = _s->peer_addr.ip46.ip4.as_u8[2];                    \
137       ed->addr[3] = _s->peer_addr.ip46.ip4.as_u8[3];                    \
138       ed->port = clib_net_to_host_u16 (_s->peer_port);                  \
139     }                                                                   \
140   else                                                                  \
141     {                                                                   \
142       /* TBD */                                                         \
143     }                                                                   \
144 }
145
146 #define VCL_EVT_CREATE_HANDLER(_s, _proto, _state, _is_nb, _s_idx, ...) \
147 {                                                                       \
148   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
149   ELOG_TYPE_DECLARE (_e) =                                              \
150   {                                                                     \
151     .format = "create:proto:%d state:%d is_nonblk:%d idx: %d",          \
152     .format_args = "i4i4i4i4",                                          \
153   };                                                                    \
154   VCL_DECLARE_ETD (_s, _e, 4);                                          \
155   ed->data[0] = _proto;                                                 \
156   ed->data[1] = _state;                                                 \
157   ed->data[2] = _is_nb;                                                 \
158   ed->data[3] = _s_idx;                                                 \
159 }
160
161 #define VCL_EVT_CLOSE_HANDLER(_s, _rv, ...)                             \
162 {                                                                       \
163   ELOG_TYPE_DECLARE (_e) =                                              \
164   {                                                                     \
165     .format = "session_close:rv:%d",                                    \
166     .format_args = "i4",                                                \
167   };                                                                    \
168   VCL_DECLARE_ETD (_s, _e, 1);                                          \
169   ed->data[0] = _rv;                                                    \
170 }
171
172 #define VCL_EVT_SESSION_TIMEOUT_HANDLER(_s, _state, ...)                \
173 {                                                                       \
174   ELOG_TYPE_DECLARE (_e) =                                              \
175   {                                                                     \
176     .format = "ERR: timeout state:%d",                                  \
177     .format_args = "i4",                                                \
178   };                                                                    \
179   VCL_DECLARE_ETD (_s, _e, 1);                                          \
180   ed->data[0] = _state;                                                 \
181 }
182
183 #define VCL_EVT_TIMEOUT_HANDLER(_vcm, _state, ...)                      \
184 {                                                                       \
185   ELOG_TYPE_DECLARE (_e) =                                              \
186   {                                                                     \
187     .format = "ERR: timeout state:%d",                                  \
188     .format_args = "i4",                                                \
189   };                                                                    \
190   struct { u32 data; } * ed;                                            \
191   ed = ELOG_TRACK_DATA (&_vcm->elog_main, _e, _vcm->elog_track);        \
192   ed->data[0] = _state;                                                 \
193 }
194
195 #define VCL_EVT_DETACH_HANDLER(_vcm, ...)                               \
196 {                                                                       \
197   ELOG_TYPE_DECLARE (_e) =                                              \
198   {                                                                     \
199     .format = "app_detach:C:%d",                                        \
200     .format_args = "i4",                                                \
201   };                                                                    \
202   struct { u32 data; } * ed;                                            \
203   ed = ELOG_TRACK_DATA (&_vcm->elog_main, _e, _vcm->elog_track);        \
204   ed->data = _vcm->my_client_index;                                     \
205 }
206
207 #define VCL_EVT_UNBIND_HANDLER(_s, ...)                                 \
208 {                                                                       \
209   ELOG_TYPE_DECLARE (_e) =                                              \
210   {                                                                     \
211     .format = "unbind: handle:%x",                                      \
212     .format_args = "i8",                                                \
213   };                                                                    \
214   struct { u64 data; } * ed;                                            \
215   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
216   ed->data = _s->vpp_handle;                                            \
217 }
218
219 #define VCL_EVT_EPOLL_CREATE_HANDLER(_s, _s_idx, ...)                   \
220 {                                                                       \
221   VCL_EVT_SESSION_INIT_HANDLER (_s, _s_idx);                            \
222   ELOG_TYPE_DECLARE (_e) =                                              \
223   {                                                                     \
224     .format = "create epoll vep_idx: %d",                               \
225     .format_args = "i4",                                                \
226   };                                                                    \
227   VCL_DECLARE_ETD (_s, _e, 1);                                          \
228   ed->data[0] = _s_idx;                                                 \
229 }
230
231 #define VCL_EVT_EPOLL_CTLADD_HANDLER(_s, _evts, _evt_data, ...)         \
232 {                                                                       \
233   ELOG_TYPE_DECLARE (_e) =                                              \
234   {                                                                     \
235     .format = "epoll_ctladd: events:%x data:%x",                        \
236     .format_args = "i4",                                                \
237   };                                                                    \
238   struct {                                                              \
239     u32 events;                                                         \
240     u64 event_data;                                                     \
241   } * ed;                                                               \
242   ed = ELOG_TRACK_DATA (&vcm->elog_main, _e, _s->elog_track);           \
243   ed->events = _evts;                                                   \
244   ed->event_data = _evt_data;                                           \
245 }
246
247 #define VCL_EVT_EPOLL_CTLDEL_HANDLER(_s, _vep_idx, ...)                 \
248 {                                                                       \
249   ELOG_TYPE_DECLARE (_e) =                                              \
250   {                                                                     \
251     .format = "epoll_ctldel: vep:%d",                                   \
252     .format_args = "i4",                                                \
253   };                                                                    \
254   VCL_DECLARE_ETD (_s, _e, 1);                                          \
255   ed->data[0] = _vep_idx;                                               \
256 }
257
258 #define vcl_elog_init(_vcm)                                             \
259 {                                                                       \
260   _vcm->elog_main.lock = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, \
261                                                  CLIB_CACHE_LINE_BYTES);\
262   _vcm->elog_main.lock[0] = 0;                                          \
263   _vcm->elog_main.event_ring_size = _vcm->cfg.event_ring_size;          \
264   elog_init (&_vcm->elog_main, _vcm->elog_main.event_ring_size);        \
265   elog_enable_disable (&_vcm->elog_main, 1);                            \
266 }
267
268 #define vcl_elog_stop(_vcm)                                             \
269 {                                                                       \
270   clib_error_t *error = 0;                                              \
271   char *chroot_file = (char *) format (0, "%s/%d-%d-vcl-elog%c",        \
272                                        _vcm->cfg.event_log_path,        \
273                                        _vcm->my_client_index,           \
274                                        getpid (), 0);                   \
275   error = elog_write_file (&_vcm->elog_main, chroot_file,               \
276                            1 /* flush ring */ );                        \
277   if (error)                                                            \
278     clib_error_report (error);                                          \
279   clib_warning ("[%d] Event Log:'%s' ", getpid (), chroot_file);        \
280   vec_free (chroot_file);                                               \
281 }
282
283 #define CONCAT_HELPER(_a, _b) _a##_b
284 #define CC(_a, _b) CONCAT_HELPER(_a, _b)
285 #define vcl_evt(_evt, _args...) CC(_evt, _HANDLER)(_args)
286 #else
287 #define vcl_evt(_evt, _args...)
288 #define vcl_elog_init(_vcm)
289 #define vcl_elog_stop(_vcm)
290 #endif
291
292 #endif /* SRC_VCL_VCL_DEBUG_H_ */
293
294 /*
295  * fd.io coding-style-patch-verification: ON
296  *
297  * Local Variables:
298  * eval: (c-set-style "gnu")
299  * End:
300  */