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 70 BEGIN_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 *********/ 101 typedef 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 */ 127 typedef 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 */ 155 osm_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 */ 180 void 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 */ 208 void 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 */ 227 static 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 */ 261 static 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 */ 301 ib_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 */ 343 int 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 */ 363 ib_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 370 void 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 373 void 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 */ 385 static 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 */ 414 static 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 */ 449 static 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 474 static 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 485 extern void osm_log_msg_box(osm_log_t *log, osm_log_level_t level, 486 const char *func_name, const char *msg); 487 extern 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); 490 extern 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 */ 579 boolean_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 591 END_C_DECLS 592 #endif /* _OSM_LOG_H_ */ 593