1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5219820Sjeff *
6219820Sjeff * This software is available to you under a choice of one of two
7219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
8219820Sjeff * General Public License (GPL) Version 2, available from the file
9219820Sjeff * COPYING in the main directory of this source tree, or the
10219820Sjeff * OpenIB.org BSD license below:
11219820Sjeff *
12219820Sjeff *     Redistribution and use in source and binary forms, with or
13219820Sjeff *     without modification, are permitted provided that the following
14219820Sjeff *     conditions are met:
15219820Sjeff *
16219820Sjeff *      - Redistributions of source code must retain the above
17219820Sjeff *        copyright notice, this list of conditions and the following
18219820Sjeff *        disclaimer.
19219820Sjeff *
20219820Sjeff *      - Redistributions in binary form must reproduce the above
21219820Sjeff *        copyright notice, this list of conditions and the following
22219820Sjeff *        disclaimer in the documentation and/or other materials
23219820Sjeff *        provided with the distribution.
24219820Sjeff *
25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32219820Sjeff * SOFTWARE.
33219820Sjeff *
34219820Sjeff */
35219820Sjeff
36219820Sjeff/*
37219820Sjeff * Abstract:
38219820Sjeff * 	Declaration of osm_log_t.
39219820Sjeff *	This object represents the log file.
40219820Sjeff *	This object is part of the OpenSM family of objects.
41219820Sjeff */
42219820Sjeff
43219820Sjeff#ifndef _OSM_LOG_H_
44219820Sjeff#define _OSM_LOG_H_
45219820Sjeff
46219820Sjeff#ifndef __WIN__
47219820Sjeff#include <syslog.h>
48219820Sjeff#endif
49219820Sjeff#include <complib/cl_spinlock.h>
50219820Sjeff#include <opensm/osm_base.h>
51219820Sjeff#include <iba/ib_types.h>
52219820Sjeff#include <stdio.h>
53219820Sjeff
54219820Sjeff#ifdef __GNUC__
55219820Sjeff#define STRICT_OSM_LOG_FORMAT __attribute__((format(printf, 3, 4)))
56219820Sjeff#else
57219820Sjeff#define STRICT_OSM_LOG_FORMAT
58219820Sjeff#endif
59219820Sjeff
60219820Sjeff#ifdef __cplusplus
61219820Sjeff#  define BEGIN_C_DECLS extern "C" {
62219820Sjeff#  define END_C_DECLS   }
63219820Sjeff#else				/* !__cplusplus */
64219820Sjeff#  define BEGIN_C_DECLS
65219820Sjeff#  define END_C_DECLS
66219820Sjeff#endif				/* __cplusplus */
67219820Sjeff
68219820SjeffBEGIN_C_DECLS
69219820Sjeff#define LOG_ENTRY_SIZE_MAX		4096
70219820Sjeff#define BUF_SIZE			LOG_ENTRY_SIZE_MAX
71219820Sjeff#define __func__ __FUNCTION__
72219820Sjeff#define OSM_LOG_ENTER( OSM_LOG_PTR ) \
73219820Sjeff	osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \
74219820Sjeff		 "%s: [\n", __func__);
75219820Sjeff#define OSM_LOG_EXIT( OSM_LOG_PTR ) \
76219820Sjeff	osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \
77219820Sjeff		 "%s: ]\n", __func__);
78219820Sjeff/****h* OpenSM/Log
79219820Sjeff* NAME
80219820Sjeff*	Log
81219820Sjeff*
82219820Sjeff* DESCRIPTION
83219820Sjeff*
84219820Sjeff* AUTHOR
85219820Sjeff*
86219820Sjeff*********/
87219820Sjefftypedef uint8_t osm_log_level_t;
88219820Sjeff
89219820Sjeff#define OSM_LOG_NONE	0x00
90219820Sjeff#define OSM_LOG_ERROR	0x01
91219820Sjeff#define OSM_LOG_INFO	0x02
92219820Sjeff#define OSM_LOG_VERBOSE	0x04
93219820Sjeff#define OSM_LOG_DEBUG	0x08
94219820Sjeff#define OSM_LOG_FUNCS	0x10
95219820Sjeff#define OSM_LOG_FRAMES	0x20
96219820Sjeff#define OSM_LOG_ROUTING	0x40
97219820Sjeff#define OSM_LOG_ALL	0x7f
98219820Sjeff#define OSM_LOG_SYS	0x80
99219820Sjeff
100219820Sjeff/*
101219820Sjeff	DEFAULT - turn on ERROR and INFO only
102219820Sjeff*/
103219820Sjeff#define OSM_LOG_DEFAULT_LEVEL		OSM_LOG_ERROR | OSM_LOG_INFO
104219820Sjeff
105219820Sjeff/****s* OpenSM: MAD Wrapper/osm_log_t
106219820Sjeff* NAME
107219820Sjeff*	osm_log_t
108219820Sjeff*
109219820Sjeff* DESCRIPTION
110219820Sjeff*
111219820Sjeff* SYNOPSIS
112219820Sjeff*/
113219820Sjefftypedef struct osm_log {
114219820Sjeff	osm_log_level_t level;
115219820Sjeff	cl_spinlock_t lock;
116219820Sjeff	unsigned long count;
117219820Sjeff	unsigned long max_size;
118219820Sjeff	boolean_t flush;
119219820Sjeff	FILE *out_port;
120219820Sjeff	boolean_t accum_log_file;
121219820Sjeff	boolean_t daemon;
122219820Sjeff	char *log_file_name;
123219820Sjeff} osm_log_t;
124219820Sjeff/*********/
125219820Sjeff
126219820Sjeff/****f* OpenSM: Log/osm_log_construct
127219820Sjeff* NAME
128219820Sjeff*	osm_log_construct
129219820Sjeff*
130219820Sjeff* DESCRIPTION
131219820Sjeff*	This function constructs a Log object.
132219820Sjeff*
133219820Sjeff* SYNOPSIS
134219820Sjeff*/
135219820Sjeffstatic inline void osm_log_construct(IN osm_log_t * const p_log)
136219820Sjeff{
137219820Sjeff	cl_spinlock_construct(&p_log->lock);
138219820Sjeff}
139219820Sjeff
140219820Sjeff/*
141219820Sjeff* PARAMETERS
142219820Sjeff*	p_log
143219820Sjeff*		[in] Pointer to a Log object to construct.
144219820Sjeff*
145219820Sjeff* RETURN VALUE
146219820Sjeff*	This function does not return a value.
147219820Sjeff*
148219820Sjeff* NOTES
149219820Sjeff*	Allows calling osm_log_init, osm_log_init_v2, osm_log_destroy
150219820Sjeff*
151219820Sjeff*	Calling osm_log_construct is a prerequisite to calling any other
152219820Sjeff*	method except osm_log_init or osm_log_init_v2.
153219820Sjeff*
154219820Sjeff* SEE ALSO
155219820Sjeff*	Log object, osm_log_init, osm_log_init_v2,
156219820Sjeff*	osm_log_destroy
157219820Sjeff*********/
158219820Sjeff
159219820Sjeff/****f* OpenSM: Log/osm_log_destroy
160219820Sjeff* NAME
161219820Sjeff*	osm_log_destroy
162219820Sjeff*
163219820Sjeff* DESCRIPTION
164219820Sjeff*	The osm_log_destroy function destroys the object, releasing
165219820Sjeff*	all resources.
166219820Sjeff*
167219820Sjeff* SYNOPSIS
168219820Sjeff*/
169219820Sjeffstatic inline void osm_log_destroy(IN osm_log_t * const p_log)
170219820Sjeff{
171219820Sjeff	cl_spinlock_destroy(&p_log->lock);
172219820Sjeff	if (p_log->out_port != stdout) {
173219820Sjeff		fclose(p_log->out_port);
174219820Sjeff		p_log->out_port = stdout;
175219820Sjeff	}
176219820Sjeff	closelog();
177219820Sjeff}
178219820Sjeff
179219820Sjeff/*
180219820Sjeff* PARAMETERS
181219820Sjeff*	p_log
182219820Sjeff*		[in] Pointer to the object to destroy.
183219820Sjeff*
184219820Sjeff* RETURN VALUE
185219820Sjeff*	This function does not return a value.
186219820Sjeff*
187219820Sjeff* NOTES
188219820Sjeff*	Performs any necessary cleanup of the specified
189219820Sjeff*	Log object.
190219820Sjeff*	Further operations should not be attempted on the destroyed object.
191219820Sjeff*	This function should only be called after a call to
192219820Sjeff*	osm_log_construct, osm_log_init, or osm_log_init_v2.
193219820Sjeff*
194219820Sjeff* SEE ALSO
195219820Sjeff*	Log object, osm_log_construct,
196219820Sjeff*	osm_log_init, osm_log_init_v2
197219820Sjeff*********/
198219820Sjeff
199219820Sjeff/****f* OpenSM: Log/osm_log_init_v2
200219820Sjeff* NAME
201219820Sjeff*	osm_log_init_v2
202219820Sjeff*
203219820Sjeff* DESCRIPTION
204219820Sjeff*	The osm_log_init_v2 function initializes a
205219820Sjeff*	Log object for use.
206219820Sjeff*
207219820Sjeff* SYNOPSIS
208219820Sjeff*/
209219820Sjeffib_api_status_t
210219820Sjeffosm_log_init_v2(IN osm_log_t * const p_log,
211219820Sjeff		IN const boolean_t flush,
212219820Sjeff		IN const uint8_t log_flags,
213219820Sjeff		IN const char *log_file,
214219820Sjeff		IN const unsigned long max_size,
215219820Sjeff		IN const boolean_t accum_log_file);
216219820Sjeff/*
217219820Sjeff* PARAMETERS
218219820Sjeff*	p_log
219219820Sjeff*		[in] Pointer to the log object.
220219820Sjeff*
221219820Sjeff*	flush
222219820Sjeff*		[in] Set to TRUE directs the log to flush all log messages
223219820Sjeff*		immediately.  This severely degrades log performance,
224219820Sjeff*		and is normally used for debugging only.
225219820Sjeff*
226219820Sjeff*	log_flags
227219820Sjeff*		[in] The log verbosity level to be used.
228219820Sjeff*
229219820Sjeff*	log_file
230219820Sjeff*		[in] if not NULL defines the name of the log file. Otherwise
231219820Sjeff*		it is stdout.
232219820Sjeff*
233219820Sjeff* RETURN VALUES
234219820Sjeff*	CL_SUCCESS if the Log object was initialized
235219820Sjeff*	successfully.
236219820Sjeff*
237219820Sjeff* NOTES
238219820Sjeff*	Allows calling other Log methods.
239219820Sjeff*
240219820Sjeff* SEE ALSO
241219820Sjeff*	Log object, osm_log_construct,
242219820Sjeff*	osm_log_destroy
243219820Sjeff*********/
244219820Sjeff
245219820Sjeff/****f* OpenSM: Log/osm_log_reopen_file
246219820Sjeff* NAME
247219820Sjeff*	osm_log_reopen_file
248219820Sjeff*
249219820Sjeff* DESCRIPTION
250219820Sjeff*	The osm_log_reopen_file function reopens the log file
251219820Sjeff*
252219820Sjeff* SYNOPSIS
253219820Sjeff*/
254219820Sjeffint osm_log_reopen_file(osm_log_t * p_log);
255219820Sjeff/*
256219820Sjeff* PARAMETERS
257219820Sjeff*	p_log
258219820Sjeff*		[in] Pointer to the log object.
259219820Sjeff*
260219820Sjeff* RETURN VALUES
261219820Sjeff*	0 on success or nonzero value otherwise.
262219820Sjeff*********/
263219820Sjeff
264219820Sjeff/****f* OpenSM: Log/osm_log_init
265219820Sjeff* NAME
266219820Sjeff*	osm_log_init
267219820Sjeff*
268219820Sjeff* DESCRIPTION
269219820Sjeff*	The osm_log_init function initializes a
270219820Sjeff*	Log object for use. It is a wrapper for osm_log_init_v2().
271219820Sjeff*
272219820Sjeff* SYNOPSIS
273219820Sjeff*/
274219820Sjeffib_api_status_t
275219820Sjeffosm_log_init(IN osm_log_t * const p_log,
276219820Sjeff	     IN const boolean_t flush,
277219820Sjeff	     IN const uint8_t log_flags,
278219820Sjeff	     IN const char *log_file, IN const boolean_t accum_log_file);
279219820Sjeff/*
280219820Sjeff * Same as osm_log_init_v2() but without max_size parameter
281219820Sjeff */
282219820Sjeff
283219820Sjeffvoid
284219820Sjeffosm_log(IN osm_log_t * const p_log,
285219820Sjeff	IN const osm_log_level_t verbosity,
286219820Sjeff	IN const char *p_str, ...) STRICT_OSM_LOG_FORMAT;
287219820Sjeff
288219820Sjeff/****f* OpenSM: Log/osm_log_get_level
289219820Sjeff* NAME
290219820Sjeff*	osm_log_get_level
291219820Sjeff*
292219820Sjeff* DESCRIPTION
293219820Sjeff*	Returns the current log level.
294219820Sjeff*
295219820Sjeff* SYNOPSIS
296219820Sjeff*/
297219820Sjeffstatic inline osm_log_level_t
298219820Sjeffosm_log_get_level(IN const osm_log_t * const p_log)
299219820Sjeff{
300219820Sjeff	return (p_log->level);
301219820Sjeff}
302219820Sjeff
303219820Sjeff/*
304219820Sjeff* PARAMETERS
305219820Sjeff*	p_log
306219820Sjeff*		[in] Pointer to the log object.
307219820Sjeff*
308219820Sjeff* RETURN VALUES
309219820Sjeff*	Returns the current log level.
310219820Sjeff*
311219820Sjeff* NOTES
312219820Sjeff*
313219820Sjeff* SEE ALSO
314219820Sjeff*	Log object, osm_log_construct,
315219820Sjeff*	osm_log_destroy
316219820Sjeff*********/
317219820Sjeff
318219820Sjeff/****f* OpenSM: Log/osm_log_set_level
319219820Sjeff* NAME
320219820Sjeff*	osm_log_set_level
321219820Sjeff*
322219820Sjeff* DESCRIPTION
323219820Sjeff*	Sets the current log level.
324219820Sjeff*
325219820Sjeff* SYNOPSIS
326219820Sjeff*/
327219820Sjeffstatic inline void
328219820Sjeffosm_log_set_level(IN osm_log_t * const p_log, IN const osm_log_level_t level)
329219820Sjeff{
330219820Sjeff	p_log->level = level;
331219820Sjeff	osm_log(p_log, OSM_LOG_ALL, "Setting log level to: 0x%02x\n", level);
332219820Sjeff}
333219820Sjeff
334219820Sjeff/*
335219820Sjeff* PARAMETERS
336219820Sjeff*	p_log
337219820Sjeff*		[in] Pointer to the log object.
338219820Sjeff*
339219820Sjeff*	level
340219820Sjeff*		[in] New level to set.
341219820Sjeff*
342219820Sjeff* RETURN VALUES
343219820Sjeff*	Returns the current log level.
344219820Sjeff*
345219820Sjeff* NOTES
346219820Sjeff*
347219820Sjeff* SEE ALSO
348219820Sjeff*	Log object, osm_log_construct,
349219820Sjeff*	osm_log_destroy
350219820Sjeff*********/
351219820Sjeff
352219820Sjeff/****f* OpenSM: Log/osm_log_is_active
353219820Sjeff* NAME
354219820Sjeff*	osm_log_is_active
355219820Sjeff*
356219820Sjeff* DESCRIPTION
357219820Sjeff*	Returns TRUE if the specified log level would be logged.
358219820Sjeff*	FALSE otherwise.
359219820Sjeff*
360219820Sjeff* SYNOPSIS
361219820Sjeff*/
362219820Sjeffstatic inline boolean_t
363219820Sjeffosm_log_is_active(IN const osm_log_t * const p_log,
364219820Sjeff		  IN const osm_log_level_t level)
365219820Sjeff{
366219820Sjeff	return ((p_log->level & level) != 0);
367219820Sjeff}
368219820Sjeff
369219820Sjeff/*
370219820Sjeff* PARAMETERS
371219820Sjeff*	p_log
372219820Sjeff*		[in] Pointer to the log object.
373219820Sjeff*
374219820Sjeff*	level
375219820Sjeff*		[in] Level to check.
376219820Sjeff*
377219820Sjeff* RETURN VALUES
378219820Sjeff*	Returns TRUE if the specified log level would be logged.
379219820Sjeff*	FALSE otherwise.
380219820Sjeff*
381219820Sjeff* NOTES
382219820Sjeff*
383219820Sjeff* SEE ALSO
384219820Sjeff*	Log object, osm_log_construct,
385219820Sjeff*	osm_log_destroy
386219820Sjeff*********/
387219820Sjeff
388219820Sjeffextern void osm_log_msg_box(osm_log_t *log, osm_log_level_t level,
389219820Sjeff			    const char *func_name, const char *msg);
390219820Sjeffextern void osm_log_raw(IN osm_log_t * const p_log,
391219820Sjeff	    IN const osm_log_level_t verbosity, IN const char *p_buf);
392219820Sjeff
393219820Sjeff#define OSM_LOG(log, level, fmt, arg...) do { \
394219820Sjeff		if (osm_log_is_active(log, (level))) \
395219820Sjeff			osm_log(log, level, "%s: " fmt, __func__, ##arg); \
396219820Sjeff	} while (0)
397219820Sjeff
398219820Sjeff#define OSM_LOG_MSG_BOX(log, level, msg) \
399219820Sjeff		osm_log_msg_box(log, level, __func__, msg)
400219820Sjeff
401219820Sjeff#define DBG_CL_LOCK 0
402219820Sjeff
403219820Sjeff#define CL_PLOCK_EXCL_ACQUIRE( __exp__ )  \
404219820Sjeff{											    		\
405219820Sjeff   if (DBG_CL_LOCK)                      \
406219820Sjeff     printf("cl_plock_excl_acquire: Acquiring %p file %s, line %d\n", \
407219820Sjeff          __exp__,__FILE__, __LINE__);            \
408219820Sjeff   cl_plock_excl_acquire( __exp__ );      \
409219820Sjeff   if (DBG_CL_LOCK)                      \
410219820Sjeff     printf("cl_plock_excl_acquire: Acquired %p file %s, line %d\n", \
411219820Sjeff          __exp__,__FILE__, __LINE__);            \
412219820Sjeff}
413219820Sjeff
414219820Sjeff#define CL_PLOCK_ACQUIRE( __exp__ )  \
415219820Sjeff{											    		\
416219820Sjeff   if (DBG_CL_LOCK)                      \
417219820Sjeff     printf("cl_plock_acquire: Acquiring %p file %s, line %d\n", \
418219820Sjeff          __exp__,__FILE__, __LINE__);            \
419219820Sjeff   cl_plock_acquire( __exp__ );      \
420219820Sjeff   if (DBG_CL_LOCK)                      \
421219820Sjeff     printf("cl_plock_acquire: Acquired %p file %s, line %d\n", \
422219820Sjeff          __exp__,__FILE__, __LINE__);            \
423219820Sjeff}
424219820Sjeff
425219820Sjeff#define CL_PLOCK_RELEASE( __exp__ )  \
426219820Sjeff{											    		\
427219820Sjeff   if (DBG_CL_LOCK)                      \
428219820Sjeff     printf("cl_plock_release: Releasing %p file %s, line %d\n", \
429219820Sjeff          __exp__,__FILE__, __LINE__);            \
430219820Sjeff   cl_plock_release( __exp__ );      \
431219820Sjeff   if (DBG_CL_LOCK)                      \
432219820Sjeff     printf("cl_plock_release: Released  %p file %s, line %d\n", \
433219820Sjeff          __exp__,__FILE__, __LINE__);            \
434219820Sjeff}
435219820Sjeff
436219820Sjeff#define DBG_CL_SPINLOCK 0
437219820Sjeff#define CL_SPINLOCK_RELEASE( __exp__ )  \
438219820Sjeff{											    		\
439219820Sjeff   if (DBG_CL_SPINLOCK)                      \
440219820Sjeff     printf("cl_spinlock_release: Releasing %p file %s, line %d\n", \
441219820Sjeff          __exp__,__FILE__, __LINE__);            \
442219820Sjeff   cl_spinlock_release( __exp__ );      \
443219820Sjeff   if (DBG_CL_SPINLOCK)                      \
444219820Sjeff     printf("cl_spinlock_release: Released  %p file %s, line %d\n", \
445219820Sjeff          __exp__,__FILE__, __LINE__);            \
446219820Sjeff}
447219820Sjeff
448219820Sjeff#define CL_SPINLOCK_ACQUIRE( __exp__ )  \
449219820Sjeff{											    		\
450219820Sjeff   if (DBG_CL_SPINLOCK)                      \
451219820Sjeff     printf("cl_spinlock_acquire: Acquiring %p file %s, line %d\n", \
452219820Sjeff          __exp__,__FILE__, __LINE__);            \
453219820Sjeff   cl_spinlock_acquire( __exp__ );      \
454219820Sjeff   if (DBG_CL_SPINLOCK)                      \
455219820Sjeff     printf("cl_spinlock_acquire: Acquired %p file %s, line %d\n", \
456219820Sjeff          __exp__,__FILE__, __LINE__);            \
457219820Sjeff}
458219820Sjeff
459219820Sjeff/****f* OpenSM: Helper/osm_is_debug
460219820Sjeff* NAME
461219820Sjeff*	osm_is_debug
462219820Sjeff*
463219820Sjeff* DESCRIPTION
464219820Sjeff*	The osm_is_debug function returns TRUE if the opensm was compiled
465219820Sjeff*	in debug mode, and FALSE otherwise.
466219820Sjeff*
467219820Sjeff* SYNOPSIS
468219820Sjeff*/
469219820Sjeffboolean_t osm_is_debug(void);
470219820Sjeff/*
471219820Sjeff* PARAMETERS
472219820Sjeff*	None
473219820Sjeff*
474219820Sjeff* RETURN VALUE
475219820Sjeff*	TRUE if compiled in debug version. FALSE otherwise.
476219820Sjeff*
477219820Sjeff* NOTES
478219820Sjeff*
479219820Sjeff*********/
480219820Sjeff
481219820SjeffEND_C_DECLS
482219820Sjeff#endif				/* _OSM_LOG_H_ */
483