]>
Commit | Line | Data |
---|---|---|
cc73685d CB |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
f1a4a029 ÇO |
3 | #ifndef __LXC_LOG_H |
4 | #define __LXC_LOG_H | |
0ad19a3f | 5 | |
b10cb59b CB |
6 | #ifndef _GNU_SOURCE |
7 | #define _GNU_SOURCE 1 | |
8 | #endif | |
76d0127f | 9 | #include <errno.h> |
cb8c5720 CLG |
10 | #include <stdarg.h> |
11 | #include <stdio.h> | |
12 | #include <sys/time.h> | |
13 | #include <string.h> | |
65441ac9 | 14 | #include <strings.h> |
fabf7361 | 15 | #include <stdbool.h> |
76d0127f | 16 | #include <syslog.h> |
c57dbb96 | 17 | #include <time.h> |
cb8c5720 | 18 | |
07d1f84a | 19 | #include "compiler.h" |
858377e4 | 20 | #include "conf.h" |
538337ee | 21 | #include "config.h" |
858377e4 | 22 | |
eabbb2f0 MN |
23 | #ifndef O_CLOEXEC |
24 | #define O_CLOEXEC 02000000 | |
25 | #endif | |
26 | ||
27 | #ifndef F_DUPFD_CLOEXEC | |
28 | #define F_DUPFD_CLOEXEC 1030 | |
29 | #endif | |
30 | ||
59eac805 CB |
31 | #define LXC_LOG_PREFIX_SIZE 32 |
32 | #define LXC_LOG_BUFFER_SIZE 4096 | |
eabbb2f0 | 33 | |
76d0127f | 34 | /* predefined lxc log priorities. */ |
4a85ce2a | 35 | enum lxc_loglevel { |
4b73005c CB |
36 | LXC_LOG_LEVEL_TRACE, |
37 | LXC_LOG_LEVEL_DEBUG, | |
38 | LXC_LOG_LEVEL_INFO, | |
39 | LXC_LOG_LEVEL_NOTICE, | |
40 | LXC_LOG_LEVEL_WARN, | |
41 | LXC_LOG_LEVEL_ERROR, | |
42 | LXC_LOG_LEVEL_CRIT, | |
43 | LXC_LOG_LEVEL_ALERT, | |
44 | LXC_LOG_LEVEL_FATAL, | |
45 | LXC_LOG_LEVEL_NOTSET, | |
cb8c5720 CLG |
46 | }; |
47 | ||
48 | /* location information of the logging event */ | |
49 | struct lxc_log_locinfo { | |
eba1ae76 CB |
50 | const char *file; |
51 | const char *func; | |
52 | int line; | |
cb8c5720 CLG |
53 | }; |
54 | ||
55 | #define LXC_LOG_LOCINFO_INIT \ | |
56 | { .file = __FILE__, .func = __func__, .line = __LINE__ } | |
57 | ||
58 | /* brief logging event object */ | |
59 | struct lxc_log_event { | |
eba1ae76 CB |
60 | const char *category; |
61 | int priority; | |
62 | struct timespec timestamp; | |
63 | struct lxc_log_locinfo *locinfo; | |
64 | const char *fmt; | |
65 | va_list *vap; | |
cb8c5720 CLG |
66 | }; |
67 | ||
68 | /* log appender object */ | |
69 | struct lxc_log_appender { | |
eba1ae76 | 70 | const char *name; |
5fd8380b | 71 | int (*append)(const struct lxc_log_appender *, struct lxc_log_event *); |
cb8c5720 CLG |
72 | |
73 | /* | |
74 | * appenders can be stacked | |
75 | */ | |
eba1ae76 | 76 | struct lxc_log_appender *next; |
cb8c5720 CLG |
77 | }; |
78 | ||
79 | /* log category object */ | |
80 | struct lxc_log_category { | |
eba1ae76 CB |
81 | const char *name; |
82 | int priority; | |
83 | struct lxc_log_appender *appender; | |
84 | const struct lxc_log_category *parent; | |
cb8c5720 CLG |
85 | }; |
86 | ||
858377e4 | 87 | #ifndef NO_LXC_CONF |
c422f3af | 88 | extern bool lxc_log_use_global_fd; |
858377e4 SH |
89 | #endif |
90 | ||
cb8c5720 CLG |
91 | /* |
92 | * Returns true if the chained priority is equal to or higher than | |
93 | * given priority. | |
94 | */ | |
eba1ae76 CB |
95 | static inline int lxc_log_priority_is_enabled(const struct lxc_log_category *category, |
96 | int priority) | |
cb8c5720 | 97 | { |
eba1ae76 | 98 | while (category->priority == LXC_LOG_LEVEL_NOTSET && category->parent) |
cb8c5720 CLG |
99 | category = category->parent; |
100 | ||
858377e4 SH |
101 | int cmp_prio = category->priority; |
102 | #ifndef NO_LXC_CONF | |
103 | if (!lxc_log_use_global_fd && current_config && | |
eba1ae76 | 104 | current_config->loglevel != LXC_LOG_LEVEL_NOTSET) |
858377e4 SH |
105 | cmp_prio = current_config->loglevel; |
106 | #endif | |
107 | ||
108 | return priority >= cmp_prio; | |
cb8c5720 CLG |
109 | } |
110 | ||
111 | /* | |
112 | * converts a priority to a literal string | |
113 | */ | |
eba1ae76 | 114 | static inline const char *lxc_log_priority_to_string(int priority) |
cb8c5720 CLG |
115 | { |
116 | switch (priority) { | |
eba1ae76 CB |
117 | case LXC_LOG_LEVEL_TRACE: |
118 | return "TRACE"; | |
119 | case LXC_LOG_LEVEL_DEBUG: | |
120 | return "DEBUG"; | |
121 | case LXC_LOG_LEVEL_INFO: | |
122 | return "INFO"; | |
123 | case LXC_LOG_LEVEL_NOTICE: | |
124 | return "NOTICE"; | |
125 | case LXC_LOG_LEVEL_WARN: | |
126 | return "WARN"; | |
127 | case LXC_LOG_LEVEL_ERROR: | |
128 | return "ERROR"; | |
129 | case LXC_LOG_LEVEL_CRIT: | |
130 | return "CRIT"; | |
131 | case LXC_LOG_LEVEL_ALERT: | |
132 | return "ALERT"; | |
133 | case LXC_LOG_LEVEL_FATAL: | |
134 | return "FATAL"; | |
cb8c5720 | 135 | } |
eba1ae76 CB |
136 | |
137 | return "NOTSET"; | |
cb8c5720 | 138 | } |
76d0127f | 139 | |
eba1ae76 | 140 | static inline const char *lxc_syslog_priority_to_string(int priority) |
76d0127f CB |
141 | { |
142 | switch (priority) { | |
eba1ae76 CB |
143 | case LOG_DAEMON: |
144 | return "daemon"; | |
145 | case LOG_LOCAL0: | |
146 | return "local0"; | |
147 | case LOG_LOCAL1: | |
148 | return "local1"; | |
149 | case LOG_LOCAL2: | |
150 | return "local2"; | |
151 | case LOG_LOCAL3: | |
152 | return "local3"; | |
153 | case LOG_LOCAL4: | |
154 | return "local4"; | |
155 | case LOG_LOCAL5: | |
156 | return "local5"; | |
157 | case LOG_LOCAL6: | |
158 | return "local6"; | |
159 | case LOG_LOCAL7: | |
160 | return "local7"; | |
76d0127f | 161 | } |
eba1ae76 CB |
162 | |
163 | return "NOTSET"; | |
76d0127f CB |
164 | } |
165 | ||
cb8c5720 CLG |
166 | /* |
167 | * converts a literal priority to an int | |
168 | */ | |
eba1ae76 | 169 | static inline int lxc_log_priority_to_int(const char *name) |
cb8c5720 | 170 | { |
eba1ae76 CB |
171 | if (strcasecmp("TRACE", name) == 0) |
172 | return LXC_LOG_LEVEL_TRACE; | |
173 | if (strcasecmp("DEBUG", name) == 0) | |
174 | return LXC_LOG_LEVEL_DEBUG; | |
175 | if (strcasecmp("INFO", name) == 0) | |
176 | return LXC_LOG_LEVEL_INFO; | |
177 | if (strcasecmp("NOTICE", name) == 0) | |
178 | return LXC_LOG_LEVEL_NOTICE; | |
179 | if (strcasecmp("WARN", name) == 0) | |
180 | return LXC_LOG_LEVEL_WARN; | |
181 | if (strcasecmp("ERROR", name) == 0) | |
182 | return LXC_LOG_LEVEL_ERROR; | |
183 | if (strcasecmp("CRIT", name) == 0) | |
184 | return LXC_LOG_LEVEL_CRIT; | |
185 | if (strcasecmp("ALERT", name) == 0) | |
186 | return LXC_LOG_LEVEL_ALERT; | |
187 | if (strcasecmp("FATAL", name) == 0) | |
188 | return LXC_LOG_LEVEL_FATAL; | |
4b73005c CB |
189 | |
190 | return LXC_LOG_LEVEL_NOTSET; | |
cb8c5720 CLG |
191 | } |
192 | ||
eba1ae76 | 193 | static inline int lxc_syslog_priority_to_int(const char *name) |
76d0127f | 194 | { |
eba1ae76 CB |
195 | if (strcasecmp("daemon", name) == 0) |
196 | return LOG_DAEMON; | |
197 | if (strcasecmp("local0", name) == 0) | |
198 | return LOG_LOCAL0; | |
199 | if (strcasecmp("local1", name) == 0) | |
200 | return LOG_LOCAL1; | |
201 | if (strcasecmp("local2", name) == 0) | |
202 | return LOG_LOCAL2; | |
203 | if (strcasecmp("local3", name) == 0) | |
204 | return LOG_LOCAL3; | |
205 | if (strcasecmp("local4", name) == 0) | |
206 | return LOG_LOCAL4; | |
207 | if (strcasecmp("local5", name) == 0) | |
208 | return LOG_LOCAL5; | |
209 | if (strcasecmp("local6", name) == 0) | |
210 | return LOG_LOCAL6; | |
211 | if (strcasecmp("local7", name) == 0) | |
212 | return LOG_LOCAL7; | |
76d0127f CB |
213 | |
214 | return -EINVAL; | |
215 | } | |
216 | ||
eba1ae76 CB |
217 | static inline void __lxc_log_append(const struct lxc_log_appender *appender, |
218 | struct lxc_log_event *event) | |
cb8c5720 | 219 | { |
eba1ae76 CB |
220 | va_list va; |
221 | va_list *va_keep = event->vap; | |
5fd8380b | 222 | |
cb8c5720 | 223 | while (appender) { |
5fd8380b MN |
224 | va_copy(va, *va_keep); |
225 | event->vap = &va; | |
cb8c5720 CLG |
226 | appender->append(appender, event); |
227 | appender = appender->next; | |
5fd8380b | 228 | va_end(va); |
cb8c5720 CLG |
229 | } |
230 | } | |
231 | ||
eba1ae76 CB |
232 | static inline void __lxc_log(const struct lxc_log_category *category, |
233 | struct lxc_log_event *event) | |
cb8c5720 CLG |
234 | { |
235 | while (category) { | |
236 | __lxc_log_append(category->appender, event); | |
237 | category = category->parent; | |
238 | } | |
239 | } | |
240 | ||
241 | /* | |
e6a19d26 | 242 | * Helper macro to define log functions. |
cb8c5720 | 243 | */ |
eba1ae76 CB |
244 | #define lxc_log_priority_define(acategory, LEVEL) \ |
245 | \ | |
53675a8d | 246 | __lxc_unused __attribute__ ((format (printf, 2, 3))) \ |
eba1ae76 CB |
247 | static inline void LXC_##LEVEL(struct lxc_log_locinfo *, const char *, ...); \ |
248 | \ | |
53675a8d | 249 | __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \ |
eba1ae76 CB |
250 | const char* format, ...) \ |
251 | { \ | |
252 | if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \ | |
253 | va_list va_ref; \ | |
b7051eb7 | 254 | int saved_errno; \ |
eba1ae76 CB |
255 | struct lxc_log_event evt = { \ |
256 | .category = (acategory)->name, \ | |
257 | .priority = LXC_LOG_LEVEL_##LEVEL, \ | |
258 | .fmt = format, \ | |
259 | .locinfo = locinfo \ | |
260 | }; \ | |
261 | \ | |
262 | /* clock_gettime() is explicitly marked as MT-Safe \ | |
263 | * without restrictions. So let's use it for our \ | |
264 | * logging stamps. \ | |
265 | */ \ | |
b7051eb7 | 266 | saved_errno = errno; \ |
eba1ae76 CB |
267 | (void)clock_gettime(CLOCK_REALTIME, &evt.timestamp); \ |
268 | \ | |
269 | va_start(va_ref, format); \ | |
270 | evt.vap = &va_ref; \ | |
271 | __lxc_log(acategory, &evt); \ | |
272 | va_end(va_ref); \ | |
b7051eb7 | 273 | errno = saved_errno; \ |
eba1ae76 | 274 | } \ |
cb8c5720 CLG |
275 | } |
276 | ||
277 | /* | |
278 | * Helper macro to define and use static categories. | |
279 | */ | |
59eac805 | 280 | #define lxc_log_category_define(name, parent) \ |
18780b90 CB |
281 | extern struct lxc_log_category lxc_log_category_##parent; \ |
282 | struct lxc_log_category lxc_log_category_##name = { \ | |
59eac805 CB |
283 | #name, \ |
284 | LXC_LOG_LEVEL_NOTSET, \ | |
285 | NULL, \ | |
286 | &lxc_log_category_##parent \ | |
cb8c5720 CLG |
287 | }; |
288 | ||
289 | #define lxc_log_define(name, parent) \ | |
290 | lxc_log_category_define(name, parent) \ | |
291 | \ | |
292 | lxc_log_priority_define(&lxc_log_category_##name, TRACE) \ | |
293 | lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \ | |
294 | lxc_log_priority_define(&lxc_log_category_##name, INFO) \ | |
295 | lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \ | |
296 | lxc_log_priority_define(&lxc_log_category_##name, WARN) \ | |
297 | lxc_log_priority_define(&lxc_log_category_##name, ERROR) \ | |
298 | lxc_log_priority_define(&lxc_log_category_##name, CRIT) \ | |
299 | lxc_log_priority_define(&lxc_log_category_##name, ALERT) \ | |
300 | lxc_log_priority_define(&lxc_log_category_##name, FATAL) | |
301 | ||
302 | #define lxc_log_category_priority(name) \ | |
303 | (lxc_log_priority_to_string(lxc_log_category_##name.priority)) | |
304 | ||
9d465140 | 305 | /* |
306 | * Helper macro to define errno string. | |
307 | */ | |
607e3fca CB |
308 | #if HAVE_STRERROR_R |
309 | #ifndef HAVE_DECL_STRERROR_R | |
310 | #ifdef STRERROR_R_CHAR_P | |
311 | char *strerror_r(int errnum, char *buf, size_t buflen); | |
312 | #else | |
313 | int strerror_r(int errnum, char *buf, size_t buflen); | |
314 | #endif | |
315 | #endif | |
316 | ||
317 | #ifdef STRERROR_R_CHAR_P | |
318 | #define lxc_log_strerror_r \ | |
52539fcc | 319 | char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \ |
607e3fca CB |
320 | char *ptr = NULL; \ |
321 | { \ | |
a7547c5c | 322 | int __saved_errno = errno; \ |
607e3fca | 323 | ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \ |
a7547c5c | 324 | errno = __saved_errno; \ |
607e3fca CB |
325 | if (!ptr) \ |
326 | ptr = errno_buf; \ | |
327 | } | |
328 | #else | |
329 | #define lxc_log_strerror_r \ | |
52539fcc | 330 | char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \ |
607e3fca CB |
331 | char *ptr = errno_buf; \ |
332 | { \ | |
a7547c5c | 333 | int __saved_errno = errno; \ |
607e3fca | 334 | (void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \ |
a7547c5c | 335 | errno = __saved_errno; \ |
607e3fca CB |
336 | } |
337 | #endif | |
d6457631 CB |
338 | #elif ENFORCE_THREAD_SAFETY |
339 | #error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed | |
9d465140 | 340 | #else |
52539fcc CB |
341 | #define lxc_log_strerror_r \ |
342 | char *ptr = NULL; \ | |
343 | { \ | |
344 | ptr = strerror(errno); \ | |
607e3fca | 345 | } |
9d465140 | 346 | #endif |
347 | ||
cb8c5720 CLG |
348 | /* |
349 | * top categories | |
350 | */ | |
cb8c5720 CLG |
351 | #define TRACE(format, ...) do { \ |
352 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
353 | LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \ | |
354 | } while (0) | |
355 | ||
356 | #define DEBUG(format, ...) do { \ | |
357 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
358 | LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \ | |
359 | } while (0) | |
360 | ||
361 | #define INFO(format, ...) do { \ | |
362 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
363 | LXC_INFO(&locinfo, format, ##__VA_ARGS__); \ | |
364 | } while (0) | |
365 | ||
366 | #define NOTICE(format, ...) do { \ | |
367 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
368 | LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \ | |
369 | } while (0) | |
370 | ||
371 | #define WARN(format, ...) do { \ | |
372 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
373 | LXC_WARN(&locinfo, format, ##__VA_ARGS__); \ | |
374 | } while (0) | |
375 | ||
376 | #define ERROR(format, ...) do { \ | |
377 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
378 | LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \ | |
379 | } while (0) | |
380 | ||
381 | #define CRIT(format, ...) do { \ | |
382 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
383 | LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \ | |
384 | } while (0) | |
385 | ||
386 | #define ALERT(format, ...) do { \ | |
387 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
388 | LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \ | |
389 | } while (0) | |
390 | ||
391 | #define FATAL(format, ...) do { \ | |
392 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
393 | LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \ | |
394 | } while (0) | |
395 | ||
64a2547c | 396 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 | 397 | #define SYSTRACE(format, ...) \ |
9a719a64 | 398 | TRACE("%m - " format, ##__VA_ARGS__) |
a1d652c2 | 399 | #else |
9d465140 | 400 | #define SYSTRACE(format, ...) \ |
401 | do { \ | |
402 | lxc_log_strerror_r; \ | |
403 | TRACE("%s - " format, ptr, ##__VA_ARGS__); \ | |
404 | } while (0) | |
a1d652c2 | 405 | #endif |
9d465140 | 406 | |
64a2547c | 407 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 RK |
408 | #define SYSDEBUG(format, ...) \ |
409 | DEBUG("%m - " format, ##__VA_ARGS__) | |
410 | #else | |
9d465140 | 411 | #define SYSDEBUG(format, ...) \ |
412 | do { \ | |
413 | lxc_log_strerror_r; \ | |
414 | DEBUG("%s - " format, ptr, ##__VA_ARGS__); \ | |
415 | } while (0) | |
a1d652c2 RK |
416 | #endif |
417 | ||
9d465140 | 418 | |
64a2547c | 419 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 RK |
420 | #define SYSINFO(format, ...) \ |
421 | INFO("%m - " format, ##__VA_ARGS__) | |
422 | #else | |
9d465140 | 423 | #define SYSINFO(format, ...) \ |
424 | do { \ | |
425 | lxc_log_strerror_r; \ | |
426 | INFO("%s - " format, ptr, ##__VA_ARGS__); \ | |
427 | } while (0) | |
a1d652c2 | 428 | #endif |
9d465140 | 429 | |
64a2547c | 430 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 RK |
431 | #define SYSNOTICE(format, ...) \ |
432 | NOTICE("%m - " format, ##__VA_ARGS__) | |
433 | #else | |
9d465140 | 434 | #define SYSNOTICE(format, ...) \ |
435 | do { \ | |
436 | lxc_log_strerror_r; \ | |
437 | NOTICE("%s - " format, ptr, ##__VA_ARGS__); \ | |
438 | } while (0) | |
a1d652c2 | 439 | #endif |
9d465140 | 440 | |
64a2547c | 441 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 RK |
442 | #define SYSWARN(format, ...) \ |
443 | WARN("%m - " format, ##__VA_ARGS__) | |
444 | #else | |
9d465140 | 445 | #define SYSWARN(format, ...) \ |
446 | do { \ | |
447 | lxc_log_strerror_r; \ | |
448 | WARN("%s - " format, ptr, ##__VA_ARGS__); \ | |
449 | } while (0) | |
a1d652c2 | 450 | #endif |
9d465140 | 451 | |
64a2547c | 452 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1d652c2 RK |
453 | #define SYSERROR(format, ...) \ |
454 | ERROR("%m - " format, ##__VA_ARGS__) | |
455 | #else | |
9d465140 | 456 | #define SYSERROR(format, ...) \ |
457 | do { \ | |
458 | lxc_log_strerror_r; \ | |
459 | ERROR("%s - " format, ptr, ##__VA_ARGS__); \ | |
460 | } while (0) | |
a1d652c2 | 461 | #endif |
cb8c5720 | 462 | |
64a2547c | 463 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1162a6c CB |
464 | #define CMD_SYSERROR(format, ...) \ |
465 | fprintf(stderr, "%s: %d: %s - %m - " format "\n", __FILE__, __LINE__, \ | |
df706de4 | 466 | __func__, ##__VA_ARGS__); |
a1d652c2 | 467 | #else |
a1162a6c CB |
468 | #define CMD_SYSERROR(format, ...) \ |
469 | do { \ | |
470 | lxc_log_strerror_r; \ | |
471 | fprintf(stderr, "%s: %d: %s - %s - " format "\n", __FILE__, \ | |
472 | __LINE__, __func__, ptr, ##__VA_ARGS__); \ | |
bb9623e7 | 473 | } while (0) |
a1d652c2 | 474 | #endif |
bb9623e7 | 475 | |
64a2547c | 476 | #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD |
a1162a6c CB |
477 | #define CMD_SYSINFO(format, ...) \ |
478 | printf("%s: %d: %s - %m - " format "\n", __FILE__, __LINE__, __func__, \ | |
479 | ##__VA_ARGS__); | |
a1d652c2 | 480 | #else |
a1162a6c CB |
481 | #define CMD_SYSINFO(format, ...) \ |
482 | do { \ | |
483 | lxc_log_strerror_r; \ | |
484 | printf("%s: %d: %s - %s - " format "\n", __FILE__, __LINE__, \ | |
485 | __func__, ptr, ##__VA_ARGS__); \ | |
20029ee3 | 486 | } while (0) |
a1d652c2 | 487 | #endif |
20029ee3 | 488 | |
d7d1e27a CB |
489 | #define log_error_errno(__ret__, __errno__, format, ...) \ |
490 | ({ \ | |
491 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
492 | errno = (__errno__); \ | |
493 | SYSERROR(format, ##__VA_ARGS__); \ | |
494 | __internal_ret__; \ | |
d47ff01b CB |
495 | }) |
496 | ||
da42ac7b CB |
497 | #define syswarn(__ret__, format, ...) \ |
498 | ({ \ | |
499 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
500 | SYSWARN(format, ##__VA_ARGS__); \ | |
501 | __internal_ret__; \ | |
502 | }) | |
503 | ||
3a9daa04 CB |
504 | #define systrace(__ret__, format, ...) \ |
505 | ({ \ | |
506 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
507 | SYSTRACE(format, ##__VA_ARGS__); \ | |
508 | __internal_ret__; \ | |
509 | }) | |
510 | ||
0da35ac7 CB |
511 | #define sysinfo(__ret__, format, ...) \ |
512 | ({ \ | |
513 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
514 | SYSINFO(format, ##__VA_ARGS__); \ | |
515 | __internal_ret__; \ | |
516 | }) | |
517 | ||
c965e801 CB |
518 | #define syswarn_set(__ret__, format, ...) \ |
519 | ({ \ | |
520 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
3a9daa04 | 521 | errno = labs(__ret__); \ |
c965e801 CB |
522 | SYSWARN(format, ##__VA_ARGS__); \ |
523 | __internal_ret__; \ | |
524 | }) | |
525 | ||
d7d1e27a CB |
526 | #define log_error(__ret__, format, ...) \ |
527 | ({ \ | |
528 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
529 | ERROR(format, ##__VA_ARGS__); \ | |
530 | __internal_ret__; \ | |
2a63b5cb CB |
531 | }) |
532 | ||
d7d1e27a CB |
533 | #define log_trace_errno(__ret__, __errno__, format, ...) \ |
534 | ({ \ | |
535 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
536 | errno = __errno__; \ | |
537 | SYSTRACE(format, ##__VA_ARGS__); \ | |
538 | __internal_ret__; \ | |
2b0c5846 CB |
539 | }) |
540 | ||
d7d1e27a CB |
541 | #define log_trace(__ret__, format, ...) \ |
542 | ({ \ | |
543 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
544 | TRACE(format, ##__VA_ARGS__); \ | |
545 | __internal_ret__; \ | |
2b0c5846 CB |
546 | }) |
547 | ||
d7d1e27a CB |
548 | #define log_warn_errno(__ret__, __errno__, format, ...) \ |
549 | ({ \ | |
550 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
551 | errno = __errno__; \ | |
552 | SYSWARN(format, ##__VA_ARGS__); \ | |
553 | __internal_ret__; \ | |
23a917e5 CB |
554 | }) |
555 | ||
d7d1e27a CB |
556 | #define log_warn(__ret__, format, ...) \ |
557 | ({ \ | |
558 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
559 | WARN(format, ##__VA_ARGS__); \ | |
560 | __internal_ret__; \ | |
ffeeed8b CB |
561 | }) |
562 | ||
d7d1e27a CB |
563 | #define log_debug_errno(__ret__, __errno__, format, ...) \ |
564 | ({ \ | |
565 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
566 | errno = __errno__; \ | |
567 | SYSDEBUG(format, ##__VA_ARGS__); \ | |
568 | __internal_ret__; \ | |
900b6606 CB |
569 | }) |
570 | ||
d7d1e27a CB |
571 | #define log_debug(__ret__, format, ...) \ |
572 | ({ \ | |
573 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
574 | DEBUG(format, ##__VA_ARGS__); \ | |
575 | __internal_ret__; \ | |
2b0c5846 CB |
576 | }) |
577 | ||
d7d1e27a CB |
578 | #define log_info_errno(__ret__, __errno__, format, ...) \ |
579 | ({ \ | |
580 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
581 | errno = __errno__; \ | |
582 | SYSINFO(format, ##__VA_ARGS__); \ | |
583 | __internal_ret__; \ | |
803e4123 CB |
584 | }) |
585 | ||
d7d1e27a CB |
586 | #define log_info(__ret__, format, ...) \ |
587 | ({ \ | |
588 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
589 | INFO(format, ##__VA_ARGS__); \ | |
590 | __internal_ret__; \ | |
0d66e29a CB |
591 | }) |
592 | ||
81d90ee5 CB |
593 | /* These are the logging return helpers to be used. */ |
594 | #define syserror(format, ...) \ | |
595 | ({ \ | |
596 | SYSERROR(format, ##__VA_ARGS__); \ | |
597 | (-errno); \ | |
598 | }) | |
599 | ||
600 | #define syserror_set(__ret__, format, ...) \ | |
601 | ({ \ | |
602 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
603 | errno = labs(__ret__); \ | |
604 | SYSERROR(format, ##__VA_ARGS__); \ | |
605 | __internal_ret__; \ | |
606 | }) | |
607 | ||
608 | #define syserror_ret(__ret__, format, ...) \ | |
609 | ({ \ | |
610 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
611 | SYSERROR(format, ##__VA_ARGS__); \ | |
612 | __internal_ret__; \ | |
613 | }) | |
614 | ||
615 | #define sysdebug(format, ...) \ | |
616 | ({ \ | |
617 | SYSDEBUG(format, ##__VA_ARGS__); \ | |
618 | (-errno); \ | |
619 | }) | |
620 | ||
621 | #define sysdebug_set(__ret__, format, ...) \ | |
622 | ({ \ | |
623 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
624 | errno = labs(__ret__); \ | |
625 | SYSDEBUG(format, ##__VA_ARGS__); \ | |
626 | __internal_ret__; \ | |
627 | }) | |
628 | ||
629 | #define sysdebug_ret(__ret__, format, ...) \ | |
630 | ({ \ | |
631 | typeof(__ret__) __internal_ret__ = (__ret__); \ | |
632 | SYSDEBUG(format, ##__VA_ARGS__); \ | |
633 | __internal_ret__; \ | |
634 | }) | |
635 | ||
18780b90 | 636 | extern int lxc_log_fd; |
07d1f84a CB |
637 | |
638 | __hidden extern int lxc_log_syslog(int facility); | |
639 | __hidden extern void lxc_log_syslog_enable(void); | |
640 | __hidden extern void lxc_log_syslog_disable(void); | |
641 | __hidden extern int lxc_log_set_level(int *dest, int level); | |
642 | __hidden extern int lxc_log_get_level(void); | |
de96cd60 CB |
643 | static inline bool lxc_log_trace(void) |
644 | { | |
645 | return lxc_log_get_level() <= LXC_LOG_LEVEL_TRACE; | |
646 | } | |
07d1f84a CB |
647 | __hidden extern bool lxc_log_has_valid_level(void); |
648 | __hidden extern int lxc_log_set_file(int *fd, const char *fname); | |
649 | __hidden extern const char *lxc_log_get_file(void); | |
650 | __hidden extern void lxc_log_set_prefix(const char *prefix); | |
651 | __hidden extern const char *lxc_log_get_prefix(void); | |
652 | __hidden extern void lxc_log_options_no_override(void); | |
c422f3af | 653 | __hidden extern int lxc_log_get_fd(void); |
07d1f84a CB |
654 | |
655 | #endif /* __LXC_LOG_H */ |