1/*
2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36/*
37 * Abstract:
38 * 	Declaration of osm_log_t.
39 *	This object represents the log file.
40 *	This object is part of the OpenSM family of objects.
41 */
42
43#ifndef _OSM_LOG_H_
44#define _OSM_LOG_H_
45
46#ifndef __WIN__
47#include <syslog.h>
48#endif
49#include <complib/cl_spinlock.h>
50#include <opensm/osm_base.h>
51#include <iba/ib_types.h>
52#include <stdio.h>
53
54#ifdef __GNUC__
55#define STRICT_OSM_LOG_FORMAT __attribute__((format(printf, 3, 4)))
56#else
57#define STRICT_OSM_LOG_FORMAT
58#endif
59
60#ifdef __cplusplus
61#  define BEGIN_C_DECLS extern "C" {
62#  define END_C_DECLS   }
63#else				/* !__cplusplus */
64#  define BEGIN_C_DECLS
65#  define END_C_DECLS
66#endif				/* __cplusplus */
67
68BEGIN_C_DECLS
69#define LOG_ENTRY_SIZE_MAX		4096
70#define BUF_SIZE			LOG_ENTRY_SIZE_MAX
71#define __func__ __FUNCTION__
72#define OSM_LOG_ENTER( OSM_LOG_PTR ) \
73	osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \
74		 "%s: [\n", __func__);
75#define OSM_LOG_EXIT( OSM_LOG_PTR ) \
76	osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \
77		 "%s: ]\n", __func__);
78/****h* OpenSM/Log
79* NAME
80*	Log
81*
82* DESCRIPTION
83*
84* AUTHOR
85*
86*********/
87typedef uint8_t osm_log_level_t;
88
89#define OSM_LOG_NONE	0x00
90#define OSM_LOG_ERROR	0x01
91#define OSM_LOG_INFO	0x02
92#define OSM_LOG_VERBOSE	0x04
93#define OSM_LOG_DEBUG	0x08
94#define OSM_LOG_FUNCS	0x10
95#define OSM_LOG_FRAMES	0x20
96#define OSM_LOG_ROUTING	0x40
97#define OSM_LOG_ALL	0x7f
98#define OSM_LOG_SYS	0x80
99
100/*
101	DEFAULT - turn on ERROR and INFO only
102*/
103#define OSM_LOG_DEFAULT_LEVEL		OSM_LOG_ERROR | OSM_LOG_INFO
104
105/****s* OpenSM: MAD Wrapper/osm_log_t
106* NAME
107*	osm_log_t
108*
109* DESCRIPTION
110*
111* SYNOPSIS
112*/
113typedef struct osm_log {
114	osm_log_level_t level;
115	cl_spinlock_t lock;
116	unsigned long count;
117	unsigned long max_size;
118	boolean_t flush;
119	FILE *out_port;
120	boolean_t accum_log_file;
121	boolean_t daemon;
122	char *log_file_name;
123} osm_log_t;
124/*********/
125
126/****f* OpenSM: Log/osm_log_construct
127* NAME
128*	osm_log_construct
129*
130* DESCRIPTION
131*	This function constructs a Log object.
132*
133* SYNOPSIS
134*/
135static inline void osm_log_construct(IN osm_log_t * const p_log)
136{
137	cl_spinlock_construct(&p_log->lock);
138}
139
140/*
141* PARAMETERS
142*	p_log
143*		[in] Pointer to a Log object to construct.
144*
145* RETURN VALUE
146*	This function does not return a value.
147*
148* NOTES
149*	Allows calling osm_log_init, osm_log_init_v2, osm_log_destroy
150*
151*	Calling osm_log_construct is a prerequisite to calling any other
152*	method except osm_log_init or osm_log_init_v2.
153*
154* SEE ALSO
155*	Log object, osm_log_init, osm_log_init_v2,
156*	osm_log_destroy
157*********/
158
159/****f* OpenSM: Log/osm_log_destroy
160* NAME
161*	osm_log_destroy
162*
163* DESCRIPTION
164*	The osm_log_destroy function destroys the object, releasing
165*	all resources.
166*
167* SYNOPSIS
168*/
169static inline void osm_log_destroy(IN osm_log_t * const p_log)
170{
171	cl_spinlock_destroy(&p_log->lock);
172	if (p_log->out_port != stdout) {
173		fclose(p_log->out_port);
174		p_log->out_port = stdout;
175	}
176	closelog();
177}
178
179/*
180* PARAMETERS
181*	p_log
182*		[in] Pointer to the object to destroy.
183*
184* RETURN VALUE
185*	This function does not return a value.
186*
187* NOTES
188*	Performs any necessary cleanup of the specified
189*	Log object.
190*	Further operations should not be attempted on the destroyed object.
191*	This function should only be called after a call to
192*	osm_log_construct, osm_log_init, or osm_log_init_v2.
193*
194* SEE ALSO
195*	Log object, osm_log_construct,
196*	osm_log_init, osm_log_init_v2
197*********/
198
199/****f* OpenSM: Log/osm_log_init_v2
200* NAME
201*	osm_log_init_v2
202*
203* DESCRIPTION
204*	The osm_log_init_v2 function initializes a
205*	Log object for use.
206*
207* SYNOPSIS
208*/
209ib_api_status_t
210osm_log_init_v2(IN osm_log_t * const p_log,
211		IN const boolean_t flush,
212		IN const uint8_t log_flags,
213		IN const char *log_file,
214		IN const unsigned long max_size,
215		IN const boolean_t accum_log_file);
216/*
217* PARAMETERS
218*	p_log
219*		[in] Pointer to the log object.
220*
221*	flush
222*		[in] Set to TRUE directs the log to flush all log messages
223*		immediately.  This severely degrades log performance,
224*		and is normally used for debugging only.
225*
226*	log_flags
227*		[in] The log verbosity level to be used.
228*
229*	log_file
230*		[in] if not NULL defines the name of the log file. Otherwise
231*		it is stdout.
232*
233* RETURN VALUES
234*	CL_SUCCESS if the Log object was initialized
235*	successfully.
236*
237* NOTES
238*	Allows calling other Log methods.
239*
240* SEE ALSO
241*	Log object, osm_log_construct,
242*	osm_log_destroy
243*********/
244
245/****f* OpenSM: Log/osm_log_reopen_file
246* NAME
247*	osm_log_reopen_file
248*
249* DESCRIPTION
250*	The osm_log_reopen_file function reopens the log file
251*
252* SYNOPSIS
253*/
254int osm_log_reopen_file(osm_log_t * p_log);
255/*
256* PARAMETERS
257*	p_log
258*		[in] Pointer to the log object.
259*
260* RETURN VALUES
261*	0 on success or nonzero value otherwise.
262*********/
263
264/****f* OpenSM: Log/osm_log_init
265* NAME
266*	osm_log_init
267*
268* DESCRIPTION
269*	The osm_log_init function initializes a
270*	Log object for use. It is a wrapper for osm_log_init_v2().
271*
272* SYNOPSIS
273*/
274ib_api_status_t
275osm_log_init(IN osm_log_t * const p_log,
276	     IN const boolean_t flush,
277	     IN const uint8_t log_flags,
278	     IN const char *log_file, IN const boolean_t accum_log_file);
279/*
280 * Same as osm_log_init_v2() but without max_size parameter
281 */
282
283void
284osm_log(IN osm_log_t * const p_log,
285	IN const osm_log_level_t verbosity,
286	IN const char *p_str, ...) STRICT_OSM_LOG_FORMAT;
287
288/****f* OpenSM: Log/osm_log_get_level
289* NAME
290*	osm_log_get_level
291*
292* DESCRIPTION
293*	Returns the current log level.
294*
295* SYNOPSIS
296*/
297static inline osm_log_level_t
298osm_log_get_level(IN const osm_log_t * const p_log)
299{
300	return (p_log->level);
301}
302
303/*
304* PARAMETERS
305*	p_log
306*		[in] Pointer to the log object.
307*
308* RETURN VALUES
309*	Returns the current log level.
310*
311* NOTES
312*
313* SEE ALSO
314*	Log object, osm_log_construct,
315*	osm_log_destroy
316*********/
317
318/****f* OpenSM: Log/osm_log_set_level
319* NAME
320*	osm_log_set_level
321*
322* DESCRIPTION
323*	Sets the current log level.
324*
325* SYNOPSIS
326*/
327static inline void
328osm_log_set_level(IN osm_log_t * const p_log, IN const osm_log_level_t level)
329{
330	p_log->level = level;
331	osm_log(p_log, OSM_LOG_ALL, "Setting log level to: 0x%02x\n", level);
332}
333
334/*
335* PARAMETERS
336*	p_log
337*		[in] Pointer to the log object.
338*
339*	level
340*		[in] New level to set.
341*
342* RETURN VALUES
343*	Returns the current log level.
344*
345* NOTES
346*
347* SEE ALSO
348*	Log object, osm_log_construct,
349*	osm_log_destroy
350*********/
351
352/****f* OpenSM: Log/osm_log_is_active
353* NAME
354*	osm_log_is_active
355*
356* DESCRIPTION
357*	Returns TRUE if the specified log level would be logged.
358*	FALSE otherwise.
359*
360* SYNOPSIS
361*/
362static inline boolean_t
363osm_log_is_active(IN const osm_log_t * const p_log,
364		  IN const osm_log_level_t level)
365{
366	return ((p_log->level & level) != 0);
367}
368
369/*
370* PARAMETERS
371*	p_log
372*		[in] Pointer to the log object.
373*
374*	level
375*		[in] Level to check.
376*
377* RETURN VALUES
378*	Returns TRUE if the specified log level would be logged.
379*	FALSE otherwise.
380*
381* NOTES
382*
383* SEE ALSO
384*	Log object, osm_log_construct,
385*	osm_log_destroy
386*********/
387
388extern void osm_log_msg_box(osm_log_t *log, osm_log_level_t level,
389			    const char *func_name, const char *msg);
390extern void osm_log_raw(IN osm_log_t * const p_log,
391	    IN const osm_log_level_t verbosity, IN const char *p_buf);
392
393#define OSM_LOG(log, level, fmt, arg...) do { \
394		if (osm_log_is_active(log, (level))) \
395			osm_log(log, level, "%s: " fmt, __func__, ##arg); \
396	} while (0)
397
398#define OSM_LOG_MSG_BOX(log, level, msg) \
399		osm_log_msg_box(log, level, __func__, msg)
400
401#define DBG_CL_LOCK 0
402
403#define CL_PLOCK_EXCL_ACQUIRE( __exp__ )  \
404{											    		\
405   if (DBG_CL_LOCK)                      \
406     printf("cl_plock_excl_acquire: Acquiring %p file %s, line %d\n", \
407          __exp__,__FILE__, __LINE__);            \
408   cl_plock_excl_acquire( __exp__ );      \
409   if (DBG_CL_LOCK)                      \
410     printf("cl_plock_excl_acquire: Acquired %p file %s, line %d\n", \
411          __exp__,__FILE__, __LINE__);            \
412}
413
414#define CL_PLOCK_ACQUIRE( __exp__ )  \
415{											    		\
416   if (DBG_CL_LOCK)                      \
417     printf("cl_plock_acquire: Acquiring %p file %s, line %d\n", \
418          __exp__,__FILE__, __LINE__);            \
419   cl_plock_acquire( __exp__ );      \
420   if (DBG_CL_LOCK)                      \
421     printf("cl_plock_acquire: Acquired %p file %s, line %d\n", \
422          __exp__,__FILE__, __LINE__);            \
423}
424
425#define CL_PLOCK_RELEASE( __exp__ )  \
426{											    		\
427   if (DBG_CL_LOCK)                      \
428     printf("cl_plock_release: Releasing %p file %s, line %d\n", \
429          __exp__,__FILE__, __LINE__);            \
430   cl_plock_release( __exp__ );      \
431   if (DBG_CL_LOCK)                      \
432     printf("cl_plock_release: Released  %p file %s, line %d\n", \
433          __exp__,__FILE__, __LINE__);            \
434}
435
436#define DBG_CL_SPINLOCK 0
437#define CL_SPINLOCK_RELEASE( __exp__ )  \
438{											    		\
439   if (DBG_CL_SPINLOCK)                      \
440     printf("cl_spinlock_release: Releasing %p file %s, line %d\n", \
441          __exp__,__FILE__, __LINE__);            \
442   cl_spinlock_release( __exp__ );      \
443   if (DBG_CL_SPINLOCK)                      \
444     printf("cl_spinlock_release: Released  %p file %s, line %d\n", \
445          __exp__,__FILE__, __LINE__);            \
446}
447
448#define CL_SPINLOCK_ACQUIRE( __exp__ )  \
449{											    		\
450   if (DBG_CL_SPINLOCK)                      \
451     printf("cl_spinlock_acquire: Acquiring %p file %s, line %d\n", \
452          __exp__,__FILE__, __LINE__);            \
453   cl_spinlock_acquire( __exp__ );      \
454   if (DBG_CL_SPINLOCK)                      \
455     printf("cl_spinlock_acquire: Acquired %p file %s, line %d\n", \
456          __exp__,__FILE__, __LINE__);            \
457}
458
459/****f* OpenSM: Helper/osm_is_debug
460* NAME
461*	osm_is_debug
462*
463* DESCRIPTION
464*	The osm_is_debug function returns TRUE if the opensm was compiled
465*	in debug mode, and FALSE otherwise.
466*
467* SYNOPSIS
468*/
469boolean_t osm_is_debug(void);
470/*
471* PARAMETERS
472*	None
473*
474* RETURN VALUE
475*	TRUE if compiled in debug version. FALSE otherwise.
476*
477* NOTES
478*
479*********/
480
481END_C_DECLS
482#endif				/* _OSM_LOG_H_ */
483