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