1 /****************************************************************************
2 * Copyright 2002-2005: Level 5 Networks Inc.
3 * Copyright 2005-2008: Solarflare Communications Inc,
4 * 9501 Jeronimo Road, Suite 250,
5 * Irvine, CA 92618, USA
7 * Maintained by Solarflare Communications
8 * <linux-xen-drivers@solarflare.com>
9 * <onload-dev@solarflare.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation, incorporated herein by reference.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 ****************************************************************************
28 * \brief Functions for logging and pretty-printing.
32 /*! \cidoxg_include_ci_tools */
34 #ifndef __CI_TOOLS_LOG_H__
35 #define __CI_TOOLS_LOG_H__
40 /**********************************************************************
44 /* size of internal log buffer */
45 #define CI_LOG_MAX_LINE 512
46 /* uses of ci_log must ensure that all trace messages are shorter than this */
47 #define CI_LOG_MAX_MSG_LENGTH (CI_LOG_MAX_LINE-50)
49 extern void ci_vlog(const char* fmt, va_list args) CI_HF;
50 extern void ci_log(const char* fmt, ...) CI_PRINTF_LIKE(1,2) CI_HF;
52 /*! Set the prefix for log messages.
54 ** Uses the storage pointed to by \em prefix. Therefore \em prefix must
55 ** be allocated on the heap, or statically.
57 extern void ci_set_log_prefix(const char* prefix) CI_HF;
59 typedef void (*ci_log_fn_t)(const char* msg);
60 extern ci_log_fn_t ci_log_fn CI_HV;
63 extern void ci_log_null(const char* msg) CI_HF;
64 extern void ci_log_stderr(const char* msg) CI_HF;
65 extern void ci_log_stdout(const char* msg) CI_HF;
66 extern void ci_log_syslog(const char* msg) CI_HF;
68 /*! Call the following to install special logging behaviours. */
69 extern void ci_log_buffer_till_fail(void) CI_HF;
70 extern void ci_log_buffer_till_exit(void) CI_HF;
72 extern void __ci_log_unique(const char* msg) CI_HF;
73 extern ci_log_fn_t __ci_log_unique_fn CI_HV;
74 ci_inline void ci_log_uniquify(void) {
75 if( ci_log_fn != __ci_log_unique ) {
76 __ci_log_unique_fn = ci_log_fn;
77 ci_log_fn = __ci_log_unique;
81 extern void ci_log_file(const char* msg) CI_HF;
82 extern int ci_log_file_fd CI_HV;
84 extern void __ci_log_nth(const char* msg) CI_HF;
85 extern ci_log_fn_t __ci_log_nth_fn CI_HV;
86 extern int ci_log_nth_n CI_HV; /* default 100 */
87 ci_inline void ci_log_nth(void) {
88 if( ci_log_fn != __ci_log_nth ) {
89 __ci_log_nth_fn = ci_log_fn;
90 ci_log_fn = __ci_log_nth;
94 extern int ci_log_level CI_HV;
96 extern int ci_log_options CI_HV;
97 #define CI_LOG_PID 0x1
98 #define CI_LOG_TID 0x2
99 #define CI_LOG_TIME 0x4
100 #define CI_LOG_DELTA 0x8
102 /**********************************************************************
103 * Used to define which mode we are in
105 #if (defined(_WIN32) && !defined(__KERNEL__))
116 extern ci_log_mode_t ci_log_mode;
119 /**********************************************************************
123 extern char ci_printable_char(char c) CI_HF;
125 extern void (*ci_hex_dump_formatter)(char* buf, const ci_octet* s,
126 int i, int off, int len) CI_HV;
127 extern void ci_hex_dump_format_octets(char*,const ci_octet*,int,int,int) CI_HF;
128 extern void ci_hex_dump_format_dwords(char*,const ci_octet*,int,int,int) CI_HF;
130 extern void ci_hex_dump_row(char* buf, volatile const void* s, int len,
131 ci_ptr_arith_t address) CI_HF;
132 /*!< A row contains up to 16 bytes. Row starts at [address & 15u], so
133 ** therefore [len + (address & 15u)] must be <= 16.
136 extern void ci_hex_dump(ci_log_fn_t, volatile const void*,
137 int len, ci_ptr_arith_t address) CI_HF;
139 extern int ci_hex_dump_to_raw(const char* src_hex, void* buf,
140 unsigned* addr_out_opt, int* skip) CI_HF;
141 /*!< Recovers raw data from a single line of a hex dump. [buf] must be at
142 ** least 16 bytes long. Returns the number of bytes written to [buf] (in
143 ** range 1 -> 16), or -1 if [src_hex] doesn't contain hex data. Does not
144 ** cope with missing bytes at the start of a line.
147 extern int ci_format_eth_addr(char* buf, const void* eth_mac_addr,
149 /*!< This will write 18 characters to <buf> including terminating null.
150 ** Returns number of bytes written excluding null. If [sep] is zero, ':'
154 extern int ci_parse_eth_addr(void* eth_mac_addr,
155 const char* str, char sep) CI_HF;
156 /*!< If [sep] is zero, absolutely any separator is accepted (even
157 ** inconsistent separators). Returns 0 on success, -1 on error.
160 extern int ci_format_ip4_addr(char* buf, unsigned addr_be32) CI_HF;
161 /*!< Formats the IP address (in network endian) in dotted-quad. Returns
162 ** the number of bytes written (up to 15), excluding the null. [buf]
163 ** must be at least 16 bytes long.
166 #if defined(__unix__) && ! defined(__KERNEL__)
167 extern int ci_format_select_set(char* s, int len_s, int nfds, const fd_set*);
168 extern int ci_format_select(char* s, int len_s,
169 int nfds, const fd_set* rds, const fd_set* wrs,
170 const fd_set* exs, struct timeval* timeout);
174 /**********************************************************************
178 extern void (*ci_fail_stop_fn)(void) CI_HV;
180 extern void ci_fail_stop(void) CI_HF;
181 extern void ci_fail_hang(void) CI_HF;
182 extern void ci_fail_bomb(void) CI_HF;
183 extern void ci_backtrace(void) CI_HF;
185 #if defined __linux__ && !defined __KERNEL__
186 extern void ci_fail_abort (void) CI_HF;
191 __ci_fail(const char*, ...) CI_PRINTF_LIKE(1,2) CI_HF;
194 extern void _declspec(noreturn) __ci_fail(const char* fmt, ...);
196 extern void __ci_fail(const char* fmt, ...);
202 do{ ci_log("WARN at %s:%d", __FILE__, __LINE__); }while(0)
205 do{ ci_log("FAIL at %s:%d", __FILE__, __LINE__); __ci_fail x; }while(0)
207 extern void __ci_sys_fail(const char* fn, int rc,
208 const char* file, int line) CI_HF;
209 #define ci_sys_fail(fn, rc) __ci_sys_fail(fn, rc, __FILE__, __LINE__)
211 /**********************************************************************
212 * Logging to buffer (src/citools/log_buffer.c)
215 /*! Divert ci_log() messages to the log buffer
216 * normally they go to the system console */
217 extern void ci_log_buffer_till_fail(void) CI_HF;
219 /*! Dump the contents of the log buffer to the system console */
220 extern void ci_log_buffer_dump(void) CI_HF;
223 /**********************************************************************
224 * Some useful pretty-printing.
228 # define CI_SOCKCALL_FLAGS_FMT "%s%s%s%s%s%s%s%s%s%s%s"
230 # define CI_SOCKCALL_FLAGS_PRI_ARG(x) \
231 (((x) & MSG_OOB ) ? "OOB " :""), \
232 (((x) & MSG_PEEK ) ? "PEEK " :""), \
233 (((x) & MSG_DONTROUTE ) ? "DONTROUTE " :""), \
234 (((x) & MSG_EOR ) ? "EOR " :""), \
235 (((x) & MSG_CTRUNC ) ? "CTRUNC " :""), \
236 (((x) & MSG_TRUNC ) ? "TRUNC " :""), \
237 (((x) & MSG_WAITALL ) ? "WAITALL " :""), \
238 (((x) & MSG_DONTWAIT ) ? "DONTWAIT " :""), \
239 (((x) & MSG_NOSIGNAL ) ? "NOSIGNAL " :""), \
240 (((x) & MSG_ERRQUEUE ) ? "ERRQUEUE " :""), \
241 (((x) & MSG_CONFIRM ) ? "CONFIRM " :"")
245 # define CI_SOCKCALL_FLAGS_FMT "%s%s%s"
247 # define CI_SOCKCALL_FLAGS_PRI_ARG(x) \
248 (((x) & MSG_OOB ) ? "OOB " :""), \
249 (((x) & MSG_PEEK ) ? "PEEK " :""), \
250 (((x) & MSG_DONTROUTE ) ? "DONTROUTE " :"")
254 # define CI_SOCKCALL_FLAGS_FMT "%s%s%s%s%s%s%s%s%s"
256 # define CI_SOCKCALL_FLAGS_PRI_ARG(x) \
257 (((x) & MSG_OOB ) ? "OOB " :""), \
258 (((x) & MSG_PEEK ) ? "PEEK " :""), \
259 (((x) & MSG_DONTROUTE ) ? "DONTROUTE " :""), \
260 (((x) & MSG_EOR ) ? "EOR " :""), \
261 (((x) & MSG_CTRUNC ) ? "CTRUNC " :""), \
262 (((x) & MSG_TRUNC ) ? "TRUNC " :""), \
263 (((x) & MSG_WAITALL ) ? "WAITALL " :""), \
264 (((x) & MSG_DONTWAIT ) ? "DONTWAIT " :""), \
265 (((x) & MSG_NOTIFICATION) ? "NOTIFICATION" :"")
268 #endif /* __CI_TOOLS_LOG_H__ */