1/* 2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2012 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#define STRICT_OSM_LOG_V2_FORMAT __attribute__((format(printf, 4, 5))) 57#else 58#define STRICT_OSM_LOG_FORMAT 59#define STRICT_OSM_LOG_V2_FORMAT 60#endif 61 62#ifdef __cplusplus 63# define BEGIN_C_DECLS extern "C" { 64# define END_C_DECLS } 65#else /* !__cplusplus */ 66# define BEGIN_C_DECLS 67# define END_C_DECLS 68#endif /* __cplusplus */ 69 70BEGIN_C_DECLS 71#define LOG_ENTRY_SIZE_MAX 4096 72#define BUF_SIZE LOG_ENTRY_SIZE_MAX 73#define __func__ __FUNCTION__ 74#ifdef FILE_ID 75#define OSM_LOG_ENTER( OSM_LOG_PTR ) \ 76 osm_log_v2( OSM_LOG_PTR, OSM_LOG_FUNCS, FILE_ID, \ 77 "%s: [\n", __func__); 78#define OSM_LOG_EXIT( OSM_LOG_PTR ) \ 79 osm_log_v2( OSM_LOG_PTR, OSM_LOG_FUNCS, FILE_ID, \ 80 "%s: ]\n", __func__); 81#define OSM_LOG_IS_ACTIVE_V2( OSM_LOG_PTR, OSM_LOG_FUNCS ) \ 82 osm_log_is_active_v2( OSM_LOG_PTR, OSM_LOG_FUNCS, FILE_ID) 83#else 84#define OSM_LOG_ENTER( OSM_LOG_PTR ) \ 85 osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \ 86 "%s: [\n", __func__); 87#define OSM_LOG_EXIT( OSM_LOG_PTR ) \ 88 osm_log( OSM_LOG_PTR, OSM_LOG_FUNCS, \ 89 "%s: ]\n", __func__); 90#endif 91 92/****h* OpenSM/Log 93* NAME 94* Log 95* 96* DESCRIPTION 97* 98* AUTHOR 99* 100*********/ 101typedef uint8_t osm_log_level_t; 102 103#define OSM_LOG_NONE 0x00 104#define OSM_LOG_ERROR 0x01 105#define OSM_LOG_INFO 0x02 106#define OSM_LOG_VERBOSE 0x04 107#define OSM_LOG_DEBUG 0x08 108#define OSM_LOG_FUNCS 0x10 109#define OSM_LOG_FRAMES 0x20 110#define OSM_LOG_ROUTING 0x40 111#define OSM_LOG_ALL 0x7f 112#define OSM_LOG_SYS 0x80 113 114/* 115 DEFAULT - turn on ERROR and INFO only 116*/ 117#define OSM_LOG_DEFAULT_LEVEL OSM_LOG_ERROR | OSM_LOG_INFO 118 119/****s* OpenSM: Log/osm_log_t 120* NAME 121* osm_log_t 122* 123* DESCRIPTION 124* 125* SYNOPSIS 126*/ 127typedef struct osm_log { 128 osm_log_level_t level; 129 cl_spinlock_t lock; 130 unsigned long count; 131 unsigned long max_size; 132 boolean_t flush; 133 FILE *out_port; 134 boolean_t accum_log_file; 135 boolean_t daemon; 136 char *log_file_name; 137 char *log_prefix; 138 osm_log_level_t per_mod_log_tbl[256]; 139} osm_log_t; 140/*********/ 141 142#define OSM_LOG_MOD_NAME_MAX 32 143 144/****f* OpenSM: Log/osm_get_log_per_module 145 * NAME 146 * osm_get_log_per_module 147 * 148 * DESCRIPTION 149 * This looks up the given file ID in the per module log table. 150 * NOTE: this code is not thread safe. Need to grab the lock before 151 * calling it. 152 * 153 * SYNOPSIS 154 */ 155osm_log_level_t osm_get_log_per_module(IN osm_log_t * p_log, 156 IN const int file_id); 157/* 158 * PARAMETERS 159 * p_log 160 * [in] Pointer to a Log object to construct. 161 * 162 * file_id 163 * [in] File ID for module 164 * 165 * RETURN VALUES 166 * The log level from the per module logging structure for this file ID. 167 *********/ 168 169/****f* OpenSM: Log/osm_set_log_per_module 170 * NAME 171 * osm_set_log_per_module 172 * 173 * DESCRIPTION 174 * This sets log level for the given file ID in the per module log table. 175 * NOTE: this code is not thread safe. Need to grab the lock before 176 * calling it. 177 * 178 * SYNOPSIS 179 */ 180void osm_set_log_per_module(IN osm_log_t * p_log, IN const int file_id, 181 IN osm_log_level_t level); 182/* 183 * PARAMETERS 184 * p_log 185 * [in] Pointer to a Log object to construct. 186 * 187 * file_id 188 * [in] File ID for module 189 * 190 * level 191 * [in] Log level of the module 192 * 193 * RETURN VALUES 194 * This function does not return a value. 195 *********/ 196 197/****f* OpenSM: Log/osm_reset_log_per_module 198 * NAME 199 * osm_reset_log_per_module 200 * 201 * DESCRIPTION 202 * This resets log level for the entire per module log table. 203 * NOTE: this code is not thread safe. Need to grab the lock before 204 * calling it. 205 * 206 * SYNOPSIS 207 */ 208void osm_reset_log_per_module(IN osm_log_t * p_log); 209/* 210 * PARAMETERS 211 * p_log 212 * [in] Pointer to a Log object to construct. 213 * 214 * RETURN VALUES 215 * This function does not return a value. 216 *********/ 217 218/****f* OpenSM: Log/osm_log_construct 219* NAME 220* osm_log_construct 221* 222* DESCRIPTION 223* This function constructs a Log object. 224* 225* SYNOPSIS 226*/ 227static inline void osm_log_construct(IN osm_log_t * p_log) 228{ 229 cl_spinlock_construct(&p_log->lock); 230} 231 232/* 233* PARAMETERS 234* p_log 235* [in] Pointer to a Log object to construct. 236* 237* RETURN VALUE 238* This function does not return a value. 239* 240* NOTES 241* Allows calling osm_log_init, osm_log_init_v2, osm_log_destroy 242* 243* Calling osm_log_construct is a prerequisite to calling any other 244* method except osm_log_init or osm_log_init_v2. 245* 246* SEE ALSO 247* Log object, osm_log_init, osm_log_init_v2, 248* osm_log_destroy 249*********/ 250 251/****f* OpenSM: Log/osm_log_destroy 252* NAME 253* osm_log_destroy 254* 255* DESCRIPTION 256* The osm_log_destroy function destroys the object, releasing 257* all resources. 258* 259* SYNOPSIS 260*/ 261static inline void osm_log_destroy(IN osm_log_t * p_log) 262{ 263 cl_spinlock_destroy(&p_log->lock); 264 if (p_log->out_port != stdout) { 265 fclose(p_log->out_port); 266 p_log->out_port = stdout; 267 } 268 closelog(); 269} 270 271/* 272* PARAMETERS 273* p_log 274* [in] Pointer to the object to destroy. 275* 276* RETURN VALUE 277* This function does not return a value. 278* 279* NOTES 280* Performs any necessary cleanup of the specified 281* Log object. 282* Further operations should not be attempted on the destroyed object. 283* This function should only be called after a call to 284* osm_log_construct, osm_log_init, or osm_log_init_v2. 285* 286* SEE ALSO 287* Log object, osm_log_construct, 288* osm_log_init, osm_log_init_v2 289*********/ 290 291/****f* OpenSM: Log/osm_log_init_v2 292* NAME 293* osm_log_init_v2 294* 295* DESCRIPTION 296* The osm_log_init_v2 function initializes a 297* Log object for use. 298* 299* SYNOPSIS 300*/ 301ib_api_status_t osm_log_init_v2(IN osm_log_t * p_log, IN boolean_t flush, 302 IN uint8_t log_flags, IN const char *log_file, 303 IN unsigned long max_size, 304 IN boolean_t accum_log_file); 305/* 306* PARAMETERS 307* p_log 308* [in] Pointer to the log object. 309* 310* flush 311* [in] Set to TRUE directs the log to flush all log messages 312* immediately. This severely degrades log performance, 313* and is normally used for debugging only. 314* 315* log_flags 316* [in] The log verbosity level to be used. 317* 318* log_file 319* [in] if not NULL defines the name of the log file. Otherwise 320* it is stdout. 321* 322* RETURN VALUES 323* CL_SUCCESS if the Log object was initialized 324* successfully. 325* 326* NOTES 327* Allows calling other Log methods. 328* 329* SEE ALSO 330* Log object, osm_log_construct, 331* osm_log_destroy 332*********/ 333 334/****f* OpenSM: Log/osm_log_reopen_file 335* NAME 336* osm_log_reopen_file 337* 338* DESCRIPTION 339* The osm_log_reopen_file function reopens the log file 340* 341* SYNOPSIS 342*/ 343int osm_log_reopen_file(osm_log_t * p_log); 344/* 345* PARAMETERS 346* p_log 347* [in] Pointer to the log object. 348* 349* RETURN VALUES 350* 0 on success or nonzero value otherwise. 351*********/ 352 353/****f* OpenSM: Log/osm_log_init 354* NAME 355* osm_log_init 356* 357* DESCRIPTION 358* The osm_log_init function initializes a 359* Log object for use. It is a wrapper for osm_log_init_v2(). 360* 361* SYNOPSIS 362*/ 363ib_api_status_t osm_log_init(IN osm_log_t * p_log, IN boolean_t flush, 364 IN uint8_t log_flags, IN const char *log_file, 365 IN boolean_t accum_log_file); 366/* 367 * Same as osm_log_init_v2() but without max_size parameter 368 */ 369 370void osm_log(IN osm_log_t * p_log, IN osm_log_level_t verbosity, 371 IN const char *p_str, ...) STRICT_OSM_LOG_FORMAT; 372 373void osm_log_v2(IN osm_log_t * p_log, IN osm_log_level_t verbosity, 374 IN const int file_id, IN const char *p_str, ...) STRICT_OSM_LOG_V2_FORMAT; 375 376/****f* OpenSM: Log/osm_log_get_level 377* NAME 378* osm_log_get_level 379* 380* DESCRIPTION 381* Returns the current log level. 382* 383* SYNOPSIS 384*/ 385static inline osm_log_level_t osm_log_get_level(IN const osm_log_t * p_log) 386{ 387 return p_log->level; 388} 389 390/* 391* PARAMETERS 392* p_log 393* [in] Pointer to the log object. 394* 395* RETURN VALUES 396* Returns the current log level. 397* 398* NOTES 399* 400* SEE ALSO 401* Log object, osm_log_construct, 402* osm_log_destroy 403*********/ 404 405/****f* OpenSM: Log/osm_log_set_level 406* NAME 407* osm_log_set_level 408* 409* DESCRIPTION 410* Sets the current log level. 411* 412* SYNOPSIS 413*/ 414static inline void osm_log_set_level(IN osm_log_t * p_log, 415 IN osm_log_level_t level) 416{ 417 p_log->level = level; 418 osm_log(p_log, OSM_LOG_ALL, "Setting log level to: 0x%02x\n", level); 419} 420 421/* 422* PARAMETERS 423* p_log 424* [in] Pointer to the log object. 425* 426* level 427* [in] New level to set. 428* 429* RETURN VALUES 430* This function does not return a value. 431* 432* NOTES 433* 434* SEE ALSO 435* Log object, osm_log_construct, 436* osm_log_destroy 437*********/ 438 439/****f* OpenSM: Log/osm_log_is_active 440* NAME 441* osm_log_is_active 442* 443* DESCRIPTION 444* Returns TRUE if the specified log level would be logged. 445* FALSE otherwise. 446* 447* SYNOPSIS 448*/ 449static inline boolean_t osm_log_is_active(IN const osm_log_t * p_log, 450 IN osm_log_level_t level) 451{ 452 return ((p_log->level & level) != 0); 453} 454 455/* 456* PARAMETERS 457* p_log 458* [in] Pointer to the log object. 459* 460* level 461* [in] Level to check. 462* 463* RETURN VALUES 464* Returns TRUE if the specified log level would be logged. 465* FALSE otherwise. 466* 467* NOTES 468* 469* SEE ALSO 470* Log object, osm_log_construct, 471* osm_log_destroy 472*********/ 473 474static inline boolean_t osm_log_is_active_v2(IN const osm_log_t * p_log, 475 IN osm_log_level_t level, 476 IN const int file_id) 477{ 478 if ((p_log->level & level) != 0) 479 return 1; 480 if ((level & p_log->per_mod_log_tbl[file_id])) 481 return 1; 482 return 0; 483} 484 485extern void osm_log_msg_box(osm_log_t *log, osm_log_level_t level, 486 const char *func_name, const char *msg); 487extern void osm_log_msg_box_v2(osm_log_t *log, osm_log_level_t level, 488 const int file_id, const char *func_name, 489 const char *msg); 490extern void osm_log_raw(IN osm_log_t * p_log, IN osm_log_level_t verbosity, 491 IN const char *p_buf); 492 493#ifdef FILE_ID 494#define OSM_LOG(log, level, fmt, ...) do { \ 495 if (osm_log_is_active_v2(log, (level), FILE_ID)) \ 496 osm_log_v2(log, level, FILE_ID, "%s: " fmt, __func__, ## __VA_ARGS__); \ 497 } while (0) 498 499#define OSM_LOG_MSG_BOX(log, level, msg) \ 500 osm_log_msg_box_v2(log, level, FILE_ID, __func__, msg) 501#else 502#define OSM_LOG(log, level, fmt, ...) do { \ 503 if (osm_log_is_active(log, (level))) \ 504 osm_log(log, level, "%s: " fmt, __func__, ## __VA_ARGS__); \ 505 } while (0) 506 507#define OSM_LOG_MSG_BOX(log, level, msg) \ 508 osm_log_msg_box(log, level, __func__, msg) 509#endif 510 511#define DBG_CL_LOCK 0 512 513#define CL_PLOCK_EXCL_ACQUIRE( __exp__ ) \ 514{ \ 515 if (DBG_CL_LOCK) \ 516 printf("cl_plock_excl_acquire: Acquiring %p file %s, line %d\n", \ 517 __exp__,__FILE__, __LINE__); \ 518 cl_plock_excl_acquire( __exp__ ); \ 519 if (DBG_CL_LOCK) \ 520 printf("cl_plock_excl_acquire: Acquired %p file %s, line %d\n", \ 521 __exp__,__FILE__, __LINE__); \ 522} 523 524#define CL_PLOCK_ACQUIRE( __exp__ ) \ 525{ \ 526 if (DBG_CL_LOCK) \ 527 printf("cl_plock_acquire: Acquiring %p file %s, line %d\n", \ 528 __exp__,__FILE__, __LINE__); \ 529 cl_plock_acquire( __exp__ ); \ 530 if (DBG_CL_LOCK) \ 531 printf("cl_plock_acquire: Acquired %p file %s, line %d\n", \ 532 __exp__,__FILE__, __LINE__); \ 533} 534 535#define CL_PLOCK_RELEASE( __exp__ ) \ 536{ \ 537 if (DBG_CL_LOCK) \ 538 printf("cl_plock_release: Releasing %p file %s, line %d\n", \ 539 __exp__,__FILE__, __LINE__); \ 540 cl_plock_release( __exp__ ); \ 541 if (DBG_CL_LOCK) \ 542 printf("cl_plock_release: Released %p file %s, line %d\n", \ 543 __exp__,__FILE__, __LINE__); \ 544} 545 546#define DBG_CL_SPINLOCK 0 547#define CL_SPINLOCK_RELEASE( __exp__ ) \ 548{ \ 549 if (DBG_CL_SPINLOCK) \ 550 printf("cl_spinlock_release: Releasing %p file %s, line %d\n", \ 551 __exp__,__FILE__, __LINE__); \ 552 cl_spinlock_release( __exp__ ); \ 553 if (DBG_CL_SPINLOCK) \ 554 printf("cl_spinlock_release: Released %p file %s, line %d\n", \ 555 __exp__,__FILE__, __LINE__); \ 556} 557 558#define CL_SPINLOCK_ACQUIRE( __exp__ ) \ 559{ \ 560 if (DBG_CL_SPINLOCK) \ 561 printf("cl_spinlock_acquire: Acquiring %p file %s, line %d\n", \ 562 __exp__,__FILE__, __LINE__); \ 563 cl_spinlock_acquire( __exp__ ); \ 564 if (DBG_CL_SPINLOCK) \ 565 printf("cl_spinlock_acquire: Acquired %p file %s, line %d\n", \ 566 __exp__,__FILE__, __LINE__); \ 567} 568 569/****f* OpenSM: Helper/osm_is_debug 570* NAME 571* osm_is_debug 572* 573* DESCRIPTION 574* The osm_is_debug function returns TRUE if the opensm was compiled 575* in debug mode, and FALSE otherwise. 576* 577* SYNOPSIS 578*/ 579boolean_t osm_is_debug(void); 580/* 581* PARAMETERS 582* None 583* 584* RETURN VALUE 585* TRUE if compiled in debug version. FALSE otherwise. 586* 587* NOTES 588* 589*********/ 590 591END_C_DECLS 592#endif /* _OSM_LOG_H_ */ 593