<span style="font-family: courier new,monospace;">Hi Hal<br><br>This patch adds new verbosity functionality.<br><br>1. Verbosity configuration file<br>-------------------------------<br><br>The user is able to set verbosity level per source code file
<br>by supplying verbosity configuration file using the following<br>command line arguments:<br><br> -b filename<br> --verbosity_file filename<br><br>By default, the OSM will use the following file: /etc/opensmlog.conf
<br>Verbosity configuration file should contain zero or more lines of<br>the following pattern:<br><br> filename verbosity_level<br><br>where 'filename' is the name of the source code file that the<br>'verbosity_level' refers to, and the 'verbosity_level' itself
<br>should be specified as an integer number (decimal or hexadecimal).<br><br>One reserved filename is 'all' - it represents general verbosity<br>level, that is used for all the files that are not specified in<br>the verbosity configuration file.
<br>If 'all' is not specified, the verbosity level set in the<br>command line will be used instead.<br>Note: The 'all' file verbosity level will override any other<br>general level that was specified by the command line arguments.
<br><br>Sending a SIGHUP signal to the OSM will cause it to reload<br>the verbosity configuration file.<br><br><br>2. Logging source code filename and line number<br>-----------------------------------------------<br><br>
If command line option -S or --log_source_info is specified,<br>OSM will add source code filename and line number to every<br>log message that is written to the log file.<br>By default, the OSM will not log this additional info.
<br><br><br>Yevgeny<br><br>Signed-off-by: Yevgeny Kliteynik <<a href="mailto:kliteyn@mellanox.co.il">kliteyn@mellanox.co.il</a>><br><br>Index: include/opensm/osm_subnet.h<br>===================================================================
<br>--- include/opensm/osm_subnet.h (revision 8614)<br>+++ include/opensm/osm_subnet.h (working copy)<br>@@ -285,6 +285,8 @@ typedef struct _osm_subn_opt<br> osm_qos_options_t qos_sw0_options;<br> osm_qos_options_t qos_swe_options;
<br> osm_qos_options_t qos_rtr_options;<br>+ boolean_t src_info;<br>+ char * verbosity_file;<br> } osm_subn_opt_t;<br> /*<br> * FIELDS<br>@@ -463,6 +465,27 @@ typedef struct _osm_subn_opt
<br> * qos_rtr_options<br> * QoS options for router ports<br> *<br>+* src_info<br>+* If TRUE - the source code filename and line number will be <br>+* added to each log message.<br>+* Default value - FALSE.
<br>+*<br>+* verbosity_file<br>+* OSM log configuration file - the file that describes <br>+* verbosity level per source code file. <br>+* The file may containg zero or more lines of the following<br>
+* pattern:<br>+* filename verbosity_level<br>+* where 'filename' is the name of the source code file that <br>+* the 'verbosity_level' refers to.<br>+* Filename "all" represents general verbosity level, that is
<br>+* used for all the files that are not specified in the <br>+* verbosity file.<br>+* If "all" is not specified, the general verbosity level will<br>+* be used instead.<br>+* Note: the "all" file verbosity level will override any other
<br>+* general level that was specified by the command line arguments. <br>+*<br> * SEE ALSO<br> * Subnet object<br> *********/<br>Index: include/opensm/osm_base.h<br>===================================================================
<br>--- include/opensm/osm_base.h (revision 8614)<br>+++ include/opensm/osm_base.h (working copy)<br>@@ -222,6 +222,22 @@ BEGIN_C_DECLS<br> #endif<br> /***********/<br> <br>+/****d* OpenSM: Base/OSM_DEFAULT_VERBOSITY_FILE
<br>+* NAME<br>+* OSM_DEFAULT_VERBOSITY_FILE<br>+*<br>+* DESCRIPTION<br>+* Specifies the default verbosity config file name<br>+*<br>+* SYNOPSIS<br>+*/<br>+#ifdef __WIN__<br>+#define OSM_DEFAULT_VERBOSITY_FILE strcat(GetOsmPath(), "
opensmlog.conf")<br>+#else<br>+#define OSM_DEFAULT_VERBOSITY_FILE "/etc/opensmlog.conf"<br>+#endif<br>+/***********/<br>+<br> /****d* OpenSM: Base/OSM_DEFAULT_PARTITION_CONFIG_FILE<br> * NAME<br> * OSM_DEFAULT_PARTITION_CONFIG_FILE
<br>Index: include/opensm/osm_log.h<br>===================================================================<br>--- include/opensm/osm_log.h (revision 8652)<br>+++ include/opensm/osm_log.h (working copy)<br>@@ -57,6 +57,7 @@
<br> #include <complib/cl_log.h><br> #include <complib/cl_spinlock.h><br> #include <opensm/osm_base.h><br>+#include <opensm/st.h><br> #include <iba/ib_types.h><br> #include <stdio.h><br>
<br>@@ -123,9 +124,45 @@ typedef struct _osm_log<br> cl_spinlock_t lock;<br> boolean_t flush;<br> FILE* out_port;<br>+ boolean_t src_info;<br>+ st_table * table;
<br> } osm_log_t;<br> /*********/<br> <br>+/****f* OpenSM: Log/osm_log_read_verbosity_file<br>+* NAME<br>+* osm_log_read_verbosity_file<br>+*<br>+* DESCRIPTION<br>+* This function reads the verbosity configuration file
<br>+* and constructs a verbosity data structure.<br>+*<br>+* SYNOPSIS<br>+*/<br>+void<br>+osm_log_read_verbosity_file(<br>+ IN osm_log_t* p_log,<br>+ IN const char * const verbosity_file);<br>+/*<br>+* PARAMETERS
<br>+* p_log<br>+* [in] Pointer to a Log object to construct.<br>+* <br>+* verbosity_file<br>+* [in] verbosity configuration file<br>+*<br>+* RETURN VALUE<br>+* None<br>+*<br>+* NOTES<br>+* If the verbosity configuration file is not found, default
<br>+* verbosity value is used for all files.<br>+* If there is an error in some line of the verbosity<br>+* configuration file, the line is ignored.<br>+*<br>+*********/<br>+<br>+<br> /****f* OpenSM: Log/osm_log_construct
<br> * NAME<br> * osm_log_construct<br>@@ -201,9 +238,13 @@ osm_log_destroy(<br> * osm_log_init<br> *********/<br> <br>-/****f* OpenSM: Log/osm_log_init<br>+#define osm_log_init(p_log, flush, log_flags, log_file, accum_log_file) \
<br>+ osm_log_init_ext(p_log, flush, (log_flags), log_file, \<br>+ accum_log_file, FALSE, OSM_DEFAULT_VERBOSITY_FILE)<br>+<br>+/****f* OpenSM: Log/osm_log_init_ext<br> * NAME<br>-* osm_log_init<br>+* osm_log_init_ext
<br> *<br> * DESCRIPTION<br> * The osm_log_init function initializes a<br>@@ -211,50 +252,15 @@ osm_log_destroy(<br> *<br> * SYNOPSIS<br> */<br>-static inline ib_api_status_t<br>-osm_log_init(<br>+ib_api_status_t<br>+osm_log_init_ext(
<br> IN osm_log_t* const p_log,<br> IN const boolean_t flush,<br> IN const uint8_t log_flags,<br> IN const char *log_file,<br>- IN const boolean_t accum_log_file )<br>-{<br>- p_log->level = log_flags;<br>- p_log->flush = flush;
<br>-<br>- if (log_file == NULL || !strcmp(log_file, "-") ||<br>- !strcmp(log_file, "stdout"))<br>- {<br>- p_log->out_port = stdout;<br>- }<br>- else if (!strcmp(log_file, "stderr"))
<br>- {<br>- p_log->out_port = stderr;<br>- }<br>- else<br>- {<br>- if (accum_log_file)<br>- p_log->out_port = fopen(log_file, "a+");<br>- else<br>- p_log->out_port = fopen(log_file, "w+");
<br>-<br>- if (!p_log->out_port)<br>- {<br>- if (accum_log_file)<br>- printf("Cannot open %s for appending. Permission denied\n", log_file);<br>- else<br>- printf("Cannot open %s for writing. Permission denied\n", log_file);
<br>-<br>- return(IB_UNKNOWN_ERROR);<br>- }<br>- }<br>- openlog("OpenSM", LOG_CONS | LOG_PID, LOG_USER);<br>-<br>- if (cl_spinlock_init( &p_log->lock ) == CL_SUCCESS) <br>- return IB_SUCCESS;
<br>- else<br>- return IB_ERROR;<br>-}<br>+ IN const boolean_t accum_log_file,<br>+ IN const boolean_t src_info,<br>+ IN const char *verbosity_file);<br> /*<br> * PARAMETERS<br> * p_log<br>@@ -271,6 +277,16 @@ osm_log_init(
<br> * log_file<br> * [in] if not NULL defines the name of the log file. Otherwise it is stdout.<br> *<br>+* accum_log_file<br>+* [in] Whether the log file should be accumulated.<br>+*<br>+* src_info<br>+* [in] Set to TRUE directs the log to add filename and line number
<br>+* to each log message.<br>+*<br>+* verbosity_file<br>+* [in] Log configuration file location.<br>+*<br> * RETURN VALUES<br> * CL_SUCCESS if the Log object was initialized<br> * successfully.<br>@@ -283,26 +299,32 @@ osm_log_init(
<br> * osm_log_destroy<br> *********/<br> <br>-/****f* OpenSM: Log/osm_log_get_level<br>+#define osm_log_get_level(p_log) \<br>+ osm_log_get_level_ext(p_log, __FILE__)<br>+<br>+/****f* OpenSM: Log/osm_log_get_level_ext
<br> * NAME<br>-* osm_log_get_level<br>+* osm_log_get_level_ext<br> *<br> * DESCRIPTION<br>-* Returns the current log level.<br>+* Returns the current log level for the file.<br>+* If the file is not specified in the log config file,
<br>+* the general verbosity level will be returned.<br> *<br> * SYNOPSIS<br> */<br>-static inline osm_log_level_t<br>-osm_log_get_level(<br>- IN const osm_log_t* const p_log )<br>-{<br>- return( p_log->level );
<br>-}<br>+osm_log_level_t<br>+osm_log_get_level_ext(<br>+ IN const osm_log_t* const p_log,<br>+ IN const char* const p_filename );<br> /*<br> * PARAMETERS<br> * p_log<br> * [in] Pointer to the log object.
<br> *<br>+* p_filename<br>+* [in] Source code file name.<br>+*<br> * RETURN VALUES<br> * Returns the current log level.<br> *<br>@@ -310,7 +332,7 @@ osm_log_get_level(<br> *<br> * SEE ALSO<br> * Log object, osm_log_construct,
<br>-* osm_log_destroy<br>+* osm_log_destroy, osm_log_get_level<br> *********/<br> <br> /****f* OpenSM: Log/osm_log_set_level<br>@@ -318,7 +340,7 @@ osm_log_get_level(<br> * osm_log_set_level<br> *<br> * DESCRIPTION
<br>-* Sets the current log level.<br>+* Sets the current general log level.<br> *<br> * SYNOPSIS<br> */<br>@@ -338,7 +360,7 @@ osm_log_set_level(<br> * [in] New level to set.<br> *<br> * RETURN VALUES<br>-* Returns the current log level.
<br>+* None.<br> *<br> * NOTES<br> *<br>@@ -347,9 +369,12 @@ osm_log_set_level(<br> * osm_log_destroy<br> *********/<br> <br>-/****f* OpenSM: Log/osm_log_is_active<br>+#define osm_log_is_active(p_log, level) \<br>+ osm_log_is_active_ext(p_log, __FILE__, level)
<br>+<br>+/****f* OpenSM: Log/osm_log_is_active_ext<br> * NAME<br>-* osm_log_is_active<br>+* osm_log_is_active_ext<br> *<br> * DESCRIPTION<br> * Returns TRUE if the specified log level would be logged.<br>@@ -357,18 +382,19 @@ osm_log_set_level(
<br> *<br> * SYNOPSIS<br> */<br>-static inline boolean_t<br>-osm_log_is_active(<br>+boolean_t<br>+osm_log_is_active_ext(<br> IN const osm_log_t* const p_log,<br>- IN const osm_log_level_t level )<br>-{<br>- return( (p_log->level & level) != 0 );
<br>-}<br>+ IN const char* const p_filename,<br>+ IN const osm_log_level_t level );<br> /*<br> * PARAMETERS<br> * p_log<br> * [in] Pointer to the log object.<br> *<br>+* p_filename<br>+* [in] Source code file name.
<br>+*<br> * level<br> * [in] Level to check.<br> *<br>@@ -383,17 +409,125 @@ osm_log_is_active(<br> * osm_log_destroy<br> *********/<br> <br>+<br>+#define osm_log(p_log, verbosity, p_str, args...) \<br>+ osm_log_ext(p_log, verbosity, __FILE__, __LINE__, p_str , ## args)
<br>+<br>+/****f* OpenSM: Log/osm_log_ext<br>+* NAME<br>+* osm_log_ext<br>+*<br>+* DESCRIPTION<br>+* Logs the formatted specified message.<br>+*<br>+* SYNOPSIS<br>+*/<br> void<br>-osm_log(<br>+osm_log_ext(<br> IN osm_log_t* const p_log,
<br> IN const osm_log_level_t verbosity,<br>+ IN const char *p_filename,<br>+ IN int line,<br> IN const char *p_str, ... );<br>+/*<br>+* PARAMETERS<br>+* p_log<br>+* [in] Pointer to the log object.
<br>+*<br>+* verbosity<br>+* [in] Current message verbosity level<br>+<br>+ p_filename<br>+ [in] Name of the file that is logging this message<br>+<br>+ line<br>+ [in] Line number in the file that is logging this message
<br>+<br>+ p_str<br>+ [in] Format string of the message<br>+*<br>+* RETURN VALUES<br>+* None.<br>+*<br>+* NOTES<br>+*<br>+* SEE ALSO<br>+* Log object, osm_log_construct,<br>+* osm_log_destroy<br>+*********/
<br> <br>+#define osm_log_raw(p_log, verbosity, p_buff) \<br>+ osm_log_raw_ext(p_log, verbosity, __FILE__, p_buff)<br>+<br>+/****f* OpenSM: Log/osm_log_raw_ext<br>+* NAME<br>+* osm_log_ext<br>+*<br>+* DESCRIPTION<br>
+* Logs the specified message.<br>+*<br>+* SYNOPSIS<br>+*/<br> void<br>-osm_log_raw(<br>+osm_log_raw_ext(<br> IN osm_log_t* const p_log,<br> IN const osm_log_level_t verbosity,<br>+ IN const char * p_filename,
<br> IN const char *p_buf );<br>+/*<br>+* PARAMETERS<br>+* p_log<br>+* [in] Pointer to the log object.<br>+*<br>+* verbosity<br>+* [in] Current message verbosity level<br>+<br>+ p_filename<br>+ [in] Name of the file that is logging this message
<br>+<br>+ p_buf<br>+ [in] Message string<br>+*<br>+* RETURN VALUES<br>+* None.<br>+*<br>+* NOTES<br>+*<br>+* SEE ALSO<br>+* Log object, osm_log_construct,<br>+* osm_log_destroy<br>+*********/<br>+<br>+
<br>+/****f* OpenSM: Log/osm_log_flush<br>+* NAME<br>+* osm_log_flush<br>+*<br>+* DESCRIPTION<br>+* Flushes the log.<br>+*<br>+* SYNOPSIS<br>+*/<br>+static inline void<br>+osm_log_flush(<br>+ IN osm_log_t* const p_log)
<br>+{<br>+ fflush(p_log->out_port);<br>+}<br>+/*<br>+* PARAMETERS<br>+* p_log<br>+* [in] Pointer to the log object.<br>+*<br>+* RETURN VALUES<br>+* None.<br>+*<br>+* NOTES<br>+*<br>+* SEE ALSO<br>+*<br>+*********/
<br>+<br> <br> #define DBG_CL_LOCK 0<br> <br>Index: opensm/osm_subnet.c<br>===================================================================<br>--- opensm/osm_subnet.c (revision 8614)<br>+++ opensm/osm_subnet.c (working copy)
<br>@@ -493,6 +493,8 @@ osm_subn_set_default_opt(<br> p_opt->ucast_dump_file = NULL;<br> p_opt->updn_guid_file = NULL;<br> p_opt->exit_on_fatal = TRUE;<br>+ p_opt->src_info = FALSE;<br>+ p_opt->verbosity_file = OSM_DEFAULT_VERBOSITY_FILE;
<br> subn_set_default_qos_options(&p_opt->qos_options);<br> subn_set_default_qos_options(&p_opt->qos_hca_options);<br> subn_set_default_qos_options(&p_opt->qos_sw0_options);<br>@@ -959,6 +961,13 @@ osm_subn_parse_conf_file(
<br> "honor_guid2lid_file",<br> p_key, p_val, &p_opts->honor_guid2lid_file);<br> <br>+ __osm_subn_opts_unpack_boolean(<br>+ "log_source_info",<br>+ p_key, p_val, &p_opts->src_info);
<br>+<br>+ __osm_subn_opts_unpack_charp(<br>+ "verbosity_file", p_key, p_val, &p_opts->verbosity_file);<br>+<br> subn_parse_qos_options("qos",<br> p_key, p_val, &p_opts->qos_options);
<br> <br>@@ -1182,7 +1191,11 @@ osm_subn_write_conf_file(<br> "# No multicast routing is performed if TRUE\n"<br> "disable_multicast %s\n\n"<br> "# If TRUE opensm will exit on fatal initialization issues\n"
<br>- "exit_on_fatal %s\n\n",<br>+ "exit_on_fatal %s\n\n"<br>+ "# If TRUE OpenSM will log filename and line numbers\n"<br>+ "log_source_info %s\n\n"<br>+ "# Verbosity configuration file to be used\n"
<br>+ "verbosity_file %s\n\n",<br> p_opts->log_flags,<br> p_opts->force_log_flush ? "TRUE" : "FALSE",<br> p_opts->log_file,<br>@@ -1190,7 +1203,9 @@ osm_subn_write_conf_file(
<br> p_opts->dump_files_dir,<br> p_opts->no_multicast_option ? "TRUE" : "FALSE",<br> p_opts->disable_multicast ? "TRUE" : "FALSE",<br>- p_opts->exit_on_fatal ? "TRUE" : "FALSE"
<br>+ p_opts->exit_on_fatal ? "TRUE" : "FALSE",<br>+ p_opts->src_info ? "TRUE" : "FALSE",<br>+ p_opts->verbosity_file<br> );<br> <br> fprintf(<br>Index: opensm/osm_opensm.c
<br>===================================================================<br>--- opensm/osm_opensm.c (revision 8614)<br>+++ opensm/osm_opensm.c (working copy)<br>@@ -180,8 +180,10 @@ osm_opensm_init(<br> /* Can't use log macros here, since we're initializing the log. */
<br> osm_opensm_construct( p_osm );<br> <br>- status = osm_log_init( &p_osm->log, p_opt->force_log_flush,<br>- p_opt->log_flags, p_opt->log_file, p_opt->accum_log_file );<br>
+ status = osm_log_init_ext( &p_osm->log, p_opt->force_log_flush,<br>+ p_opt->log_flags, p_opt->log_file,<br>+ p_opt->accum_log_file, p_opt->src_info,
<br>+ p_opt->verbosity_file);<br> if( status != IB_SUCCESS )<br> return ( status );<br> <br>Index: opensm/libopensm.map<br>===================================================================
<br>--- opensm/libopensm.map (revision 8614)<br>+++ opensm/libopensm.map (working copy)<br>@@ -1,6 +1,11 @@<br>-OPENSM_1.0 {<br>+OPENSM_2.0 {<br> global:<br>- osm_log;<br>+ osm_log_init_ext;<br>+ osm_log_ext;
<br>+ osm_log_raw_ext;<br>+ osm_log_get_level_ext;<br>+ osm_log_is_active_ext;<br>+ osm_log_read_verbosity_file;<br> osm_is_debug;<br> osm_mad_pool_construct;<br> osm_mad_pool_destroy;
<br>@@ -39,7 +44,6 @@ OPENSM_1.0 {<br> osm_dump_dr_path;<br> osm_dump_smp_dr_path;<br> osm_dump_pkey_block;<br>- osm_log_raw;<br> osm_get_sm_state_str;<br> osm_get_sm_signal_str;
<br> osm_get_disp_msg_str;<br>@@ -51,5 +55,11 @@ OPENSM_1.0 {<br> osm_get_lsa_str;<br> osm_get_sm_mgr_signal_str;<br> osm_get_sm_mgr_state_str;<br>+ st_init_strtable;<br>+ st_delete;
<br>+ st_insert;<br>+ st_lookup;<br>+ st_foreach;<br>+ st_free_table;<br> local: *;<br> };<br>Index: opensm/osm_log.c<br>===================================================================<br>
--- opensm/osm_log.c (revision 8614)<br>+++ opensm/osm_log.c (working copy)<br>@@ -80,17 +80,365 @@ static char *month_str[] = {<br> };<br> #endif /* ndef WIN32 */<br> <br>+<br>+/***************************************************************************
<br>+ ***************************************************************************/<br>+<br>+#define OSM_VERBOSITY_ALL "all"<br>+<br>+static void<br>+__osm_log_free_verbosity_table(<br>+ IN osm_log_t* p_log);
<br>+static void<br>+__osm_log_print_verbosity_table(<br>+ IN osm_log_t* const p_log);<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/
<br>+<br>+osm_log_level_t<br>+osm_log_get_level_ext(<br>+ IN const osm_log_t* const p_log,<br>+ IN const char* const p_filename )<br>+{<br>+ osm_log_level_t * p_curr_file_level = NULL;<br>+<br>+ if (!p_filename || !p_log->table)
<br>+ return p_log->level;<br>+<br>+ if ( st_lookup( p_log->table, <br>+ (st_data_t) p_filename, <br>+ (st_data_t*) &p_curr_file_level) )<br>+ return *p_curr_file_level;
<br>+ else<br>+ return p_log->level;<br>+}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br>
+<br>+ib_api_status_t<br>+osm_log_init_ext(<br>+ IN osm_log_t* const p_log,<br>+ IN const boolean_t flush,<br>+ IN const uint8_t log_flags,<br>+ IN const char *log_file,<br>+ IN const boolean_t accum_log_file,
<br>+ IN const boolean_t src_info,<br>+ IN const char *verbosity_file)<br>+{<br>+ p_log->level = log_flags;<br>+ p_log->flush = flush;<br>+ p_log->src_info = src_info;<br>+ p_log->table = NULL;
<br>+<br>+ if (log_file == NULL || !strcmp(log_file, "-") ||<br>+ !strcmp(log_file, "stdout"))<br>+ {<br>+ p_log->out_port = stdout;<br>+ }<br>+ else if (!strcmp(log_file, "stderr"))
<br>+ {<br>+ p_log->out_port = stderr;<br>+ }<br>+ else<br>+ {<br>+ if (accum_log_file)<br>+ p_log->out_port = fopen(log_file, "a+");<br>+ else<br>+ p_log->out_port = fopen(log_file, "w+");
<br>+<br>+ if (!p_log->out_port)<br>+ {<br>+ if (accum_log_file)<br>+ printf("Cannot open %s for appending. Permission denied\n", log_file);<br>+ else<br>+ printf("Cannot open %s for writing. Permission denied\n", log_file);
<br>+<br>+ return(IB_UNKNOWN_ERROR);<br>+ }<br>+ }<br>+ openlog("OpenSM", LOG_CONS | LOG_PID, LOG_USER);<br>+<br>+ if (cl_spinlock_init( &p_log->lock ) != CL_SUCCESS)<br>+ return IB_ERROR;<br>
+ <br>+ osm_log_read_verbosity_file(p_log,verbosity_file);<br>+ return IB_SUCCESS;<br>+}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/
<br>+<br>+void<br>+osm_log_read_verbosity_file(<br>+ IN osm_log_t* p_log,<br>+ IN const char * const verbosity_file)<br>+{<br>+ FILE *infile;<br>+ char line[500];<br>+ struct stat buf;<br>+ boolean_t table_empty = TRUE;
<br>+ char * tmp_str = NULL;<br>+<br>+ if (p_log->table)<br>+ {<br>+ /*<br>+ * Free the existing table.<br>+ * Note: if the verbosity config file will not be found, this will<br>+ * effectivly reset the existing verbosity configuration and set
<br>+ * all the files to the same verbosity level<br>+ */<br>+ __osm_log_free_verbosity_table(p_log);<br>+ }<br>+<br>+ if (!verbosity_file)<br>+ return;<br>+<br>+ if ( stat(verbosity_file, &buf) != 0 )
<br>+ {<br>+ /*<br>+ * Verbosity configuration file doesn't exist.<br>+ */<br>+ if (strcmp(verbosity_file,OSM_DEFAULT_VERBOSITY_FILE) == 0)<br>+ {<br>+ /*<br>+ * Verbosity configuration file wasn't explicitly specified.
<br>+ * No need to issue any error message.<br>+ */<br>+ return;<br>+ }<br>+ else<br>+ {<br>+ /*<br>+ * Verbosity configuration file was explicitly specified.<br>+ */
<br>+ osm_log(p_log, OSM_LOG_SYS, <br>+ "ERROR: Verbosity configuration file (%s) doesn't exist.\n",<br>+ verbosity_file);<br>+ osm_log(p_log, OSM_LOG_SYS, <br>+ " Using general verbosity value.\n");
<br>+ return;<br>+ }<br>+ }<br>+<br>+ infile = fopen(verbosity_file, "r");<br>+ if ( infile == NULL )<br>+ {<br>+ osm_log(p_log, OSM_LOG_SYS, <br>+ "ERROR: Failed opening verbosity configuration file (%s).\n",
<br>+ verbosity_file);<br>+ osm_log(p_log, OSM_LOG_SYS, <br>+ " Using general verbosity value.\n");<br>+ return;<br>+ }<br>+<br>+ p_log->table = st_init_strtable();
<br>+ if (p_log->table == NULL)<br>+ {<br>+ osm_log(p_log, OSM_LOG_SYS, "ERROR: Verbosity table initialization failed.\n");<br>+ return;<br>+ }<br>+<br>+ /* <br>+ * Read the file line by line, parse the lines, and
<br>+ * add each line to p_log->table.<br>+ */<br>+ while ( fgets(line, sizeof(line), infile) != NULL )<br>+ {<br>+ char * str = line;<br>+ char * name = NULL;<br>+ char * value = NULL;<br>+ osm_log_level_t * p_log_level_value = NULL;
<br>+ int res;<br>+<br>+ name = strtok_r(str," \t\n",&tmp_str);<br>+ if (name == NULL || strlen(name) == 0) {<br>+ /*<br>+ * empty line - ignore it<br>+ */<br>+ continue;
<br>+ }<br>+ value = strtok_r(NULL," \t\n",&tmp_str);<br>+ if (value == NULL || strlen(value) == 0)<br>+ {<br>+ /*<br>+ * No verbosity value - wrong syntax.<br>+ * This line will be ignored.
<br>+ */<br>+ continue;<br>+ }<br>+<br>+ /*<br>+ * If the conversion will fail, the log_level_value will get 0,<br>+ * so the only way to check that the syntax is correct is to<br>+ * scan value for any non-digit (which we're not doing here).
<br>+ */<br>+ p_log_level_value = malloc (sizeof(osm_log_level_t));<br>+ if (!p_log_level_value)<br>+ {<br>+ osm_log(p_log, OSM_LOG_SYS, "ERROR: malloc failed.\n");<br>+ p_log->table = NULL;
<br>+ fclose(infile);<br>+ return;<br>+ }<br>+ *p_log_level_value = strtoul(value, NULL, 0);<br>+<br>+ if (strcasecmp(name,OSM_VERBOSITY_ALL) == 0)<br>+ {<br>+ osm_log_set_level(p_log, *p_log_level_value);
<br>+ free(p_log_level_value);<br>+ }<br>+ else<br>+ {<br>+ res = st_insert( p_log->table,<br>+ (st_data_t) strdup(name),<br>+ (st_data_t) p_log_level_value);
<br>+ if (res != 0)<br>+ {<br>+ /* <br>+ * Something is wrong with the verbosity table.<br>+ * We won't try to free the table, because there's <br>+ * clearly something corrupted there.
<br>+ */<br>+ osm_log(p_log, OSM_LOG_SYS, "ERROR: Failed adding verbosity table element.\n");<br>+ p_log->table = NULL;<br>+ fclose(infile);<br>+ return;
<br>+ }<br>+ table_empty = FALSE;<br>+ }<br>+<br>+ }<br>+<br>+ if (table_empty)<br>+ __osm_log_free_verbosity_table(p_log);<br>+<br>+ fclose(infile);<br>+<br>+ __osm_log_print_verbosity_table(p_log);
<br>+}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br>+<br>+static int<br>+__osm_log_print_verbosity_table_element(
<br>+ IN st_data_t key,<br>+ IN st_data_t val,<br>+ IN st_data_t arg)<br>+{<br>+ osm_log( (osm_log_t* const) arg, <br>+ OSM_LOG_INFO, <br>+ "[verbosity] File: %s, Level: 0x%x\n",
<br>+ (char *) key, *((osm_log_level_t *) val));<br>+ <br>+ return ST_CONTINUE;<br>+}<br>+<br>+static void<br>+__osm_log_print_verbosity_table(<br>+ IN osm_log_t* const p_log)<br>+{<br>+ osm_log( p_log, OSM_LOG_INFO,
<br>+ "[verbosity] Verbosity table loaded\n" );<br>+ osm_log( p_log, OSM_LOG_INFO, <br>+ "[verbosity] General level: 0x%x\n",osm_log_get_level_ext(p_log,NULL));<br>+ <br>+ if (p_log->table)
<br>+ {<br>+ st_foreach( p_log->table,<br>+ __osm_log_print_verbosity_table_element,<br>+ (st_data_t) p_log );<br>+ }<br>+ osm_log_flush(p_log);<br>+}<br>+<br>+/***************************************************************************
<br>+ ***************************************************************************/<br>+<br>+static int<br>+__osm_log_free_verbosity_table_element(<br>+ IN st_data_t key,<br>+ IN st_data_t val,<br>+ IN st_data_t arg)
<br>+{<br>+ free( (char *) key );<br>+ free( (osm_log_level_t *) val );<br>+ return ST_DELETE;<br>+}<br>+<br>+static void<br>+__osm_log_free_verbosity_table(<br>+ IN osm_log_t* p_log)<br>+{<br>+ if (!p_log->table)
<br>+ return;<br>+<br>+ st_foreach( p_log->table,<br>+ __osm_log_free_verbosity_table_element,<br>+ (st_data_t) NULL);<br>+<br>+ st_free_table(p_log->table);<br>+ p_log->table = NULL;
<br>+}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br>+<br>+static inline const char *<br>+__osm_log_get_base_name(
<br>+ IN const char * const p_filename)<br>+{<br>+#ifdef WIN32<br>+ char dir_separator = '\\';<br>+#else<br>+ char dir_separator = '/';<br>+#endif<br>+ char * tmp_ptr;<br>+<br>+ if (!p_filename)<br>+ return NULL;
<br>+<br>+ tmp_ptr = strrchr(p_filename,dir_separator);<br>+<br>+ if (!tmp_ptr)<br>+ return p_filename;<br>+ return tmp_ptr+1;<br>+}<br>+<br>+/***************************************************************************
<br>+ ***************************************************************************/<br>+<br>+boolean_t<br>+osm_log_is_active_ext(<br>+ IN const osm_log_t* const p_log,<br>+ IN const char* const p_filename,
<br>+ IN const osm_log_level_t level )<br>+{<br>+ osm_log_level_t tmp_lvl;<br>+ tmp_lvl = level & <br>+ osm_log_get_level_ext(p_log,__osm_log_get_base_name(p_filename));<br>+ return ( tmp_lvl != 0 );
<br>+}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br>+<br> static int log_exit_count = 0;<br> <br>
void<br>-osm_log(<br>+osm_log_ext(<br> IN osm_log_t* const p_log,<br> IN const osm_log_level_t verbosity,<br>+ IN const char *p_filename,<br>+ IN int line,<br> IN const char *p_str, ... )<br> {<br>
char buffer[LOG_ENTRY_SIZE_MAX];<br> va_list args;<br> int ret;<br>+ osm_log_level_t file_verbosity;<br> <br> #ifdef WIN32<br> SYSTEMTIME st;<br>@@ -108,69 +456,89 @@ osm_log(<br> localtime_r(&tim, &result);
<br> #endif /* WIN32 */<br> <br>- /* If this is a call to syslog - always print it */<br>- if ( verbosity & OSM_LOG_SYS )<br>+ /*<br>+ * Extract only the file name out of the full path<br>+ */<br>+ p_filename = __osm_log_get_base_name(p_filename);
<br>+ /*<br>+ * Get the verbosity level for this file.<br>+ * If the file is not specified in the log config file,<br>+ * the general verbosity level will be returned.<br>+ */<br>+ file_verbosity = osm_log_get_level_ext(p_log, p_filename);
<br>+<br>+ if ( ! (verbosity & OSM_LOG_SYS) &&<br>+ ! (file_verbosity & verbosity) )<br> {<br>- /* this is a call to the syslog */<br>+ /*<br>+ * This is not a syslog message (which is always printed)
<br>+ * and doesn't have the required verbosity level.<br>+ */<br>+ return;<br>+ }<br>+<br> va_start( args, p_str );<br> vsprintf( buffer, p_str, args );<br> va_end(args);<br>- cl_log_event("OpenSM", LOG_INFO, buffer , NULL, 0);
<br> <br>+ <br>+ if ( verbosity & OSM_LOG_SYS )<br>+ {<br>+ /* this is a call to the syslog */<br>+ cl_log_event("OpenSM", LOG_INFO, buffer , NULL, 0);<br> /* SYSLOG should go to stdout too */
<br> if (p_log->out_port != stdout)<br> {<br>- printf("%s\n", buffer);<br>+ printf("%s", buffer);<br> fflush( stdout );<br> }<br>+ }<br>+ /* SYSLOG also goes to to the log file */
<br>+<br>+ cl_spinlock_acquire( &p_log->lock );<br> <br>- /* send it also to the log file */<br> #ifdef WIN32<br> GetLocalTime(&st);<br>- fprintf( p_log->out_port, "[%02d:%02d:%02d:%03d][%04X] -> %s",
<br>+ if (p_log->src_info) <br>+ {<br>+ ret = fprintf( p_log->out_port, "[%02d:%02d:%02d:%03d][%04X] [%s:%d] -> %s",<br> st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
<br>- pid, buffer);<br>-#else<br>- fprintf( p_log->out_port, "%s %02d %02d:%02d:%02d %06d [%04X] -> %s\n",<br>- (result.tm_mon < 12 ? month_str[result.tm_mon] : "???"),
<br>- result.tm_mday, result.tm_hour,<br>- result.tm_min, result.tm_sec,<br>- usecs, pid, buffer);<br>- fflush( p_log->out_port );<br>-#endif <br>+ pid, p_filename, line, buffer);
<br> }<br>-<br>- /* SYS messages go to the log anyways */<br>- if (p_log->level & verbosity)<br>+ else<br> {<br>- <br>- va_start( args, p_str );<br>- vsprintf( buffer, p_str, args );<br>- va_end(args);
<br>- <br>- /* regular log to default out_port */<br>- cl_spinlock_acquire( &p_log->lock );<br>-#ifdef WIN32<br>- GetLocalTime(&st);<br> ret = fprintf( p_log->out_port, "[%02d:%02d:%02d:%03d][%04X] -> %s",
<br> st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,<br> pid, buffer);<br>- <br>+ }<br> #else<br> pid = pthread_self();<br> tim = time(NULL);<br>+ if (p_log->src_info)
<br>+ {<br>+ ret = fprintf( p_log->out_port, "%s %02d %02d:%02d:%02d %06d [%04X] [%s:%d] -> %s",<br>+ ((result.tm_mon < 12) && (result.tm_mon >= 0) ?<br>+ month_str[
result.tm_mon] : "???"),<br>+ result.tm_mday, result.tm_hour,<br>+ result.tm_min, result.tm_sec,<br>+ usecs, pid, p_filename, line, buffer);<br>+ }<br>
+ else<br>+ {<br> ret = fprintf( p_log->out_port, "%s %02d %02d:%02d:%02d %06d [%04X] -> %s",<br> ((result.tm_mon < 12) && (result.tm_mon >= 0) ? <br> month_str[
result.tm_mon] : "???"),<br> result.tm_mday, result.tm_hour,<br> result.tm_min, result.tm_sec,<br> usecs, pid, buffer);<br>-#endif /* WIN32 */<br>- <br>
+ }<br>+#endif<br> /*<br>- Flush log on errors too.<br>+ * Flush log on errors and SYSLOGs too.<br> */<br>- if( p_log->flush || (verbosity & OSM_LOG_ERROR) )<br>+ if ( p_log->flush || <br>
+ (verbosity & OSM_LOG_ERROR) ||<br>+ (verbosity & OSM_LOG_SYS) )<br> fflush( p_log->out_port );<br> <br> cl_spinlock_release( &p_log->lock );<br>@@ -183,15 +551,30 @@ osm_log(
<br> }<br> }<br> }<br>-}<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br> <br> void<br>
-osm_log_raw(<br>+osm_log_raw_ext(<br> IN osm_log_t* const p_log,<br> IN const osm_log_level_t verbosity,<br>+ IN const char * p_filename,<br> IN const char *p_buf )<br> {<br>- if( p_log->level & verbosity )
<br>+ osm_log_level_t file_verbosity;<br>+ /*<br>+ * Extract only the file name out of the full path<br>+ */<br>+ p_filename = __osm_log_get_base_name(p_filename);<br>+ /*<br>+ * Get the verbosity level for this file.
<br>+ * If the file is not specified in the log config file,<br>+ * the general verbosity level will be returned.<br>+ */<br>+ file_verbosity = osm_log_get_level_ext(p_log, p_filename);<br>+<br>+ if ( file_verbosity & verbosity )
<br> {<br> cl_spinlock_acquire( &p_log->lock );<br> printf( "%s", p_buf );<br>@@ -205,6 +588,9 @@ osm_log_raw(<br> }<br> }<br> <br>+/***************************************************************************
<br>+ ***************************************************************************/<br>+<br> boolean_t<br> osm_is_debug(void)<br> {<br>@@ -214,3 +600,7 @@ osm_is_debug(void)<br> return FALSE;<br> #endif /* defined( _DEBUG_ ) */
<br> }<br>+<br>+/***************************************************************************<br>+ ***************************************************************************/<br>+<br>Index: opensm/main.c<br>===================================================================
<br>--- opensm/main.c (revision 8652)<br>+++ opensm/main.c (working copy)<br>@@ -296,6 +296,33 @@ show_usage(void)<br> " -d3 - Disable multicast support\n"<br> " -d10 - Put OpenSM in testability mode\n"
<br> " Without -d, no debug options are enabled\n\n" );<br>+ printf( "-S\n"<br>+ "--log_source_info\n"<br>+ " This option tells SM to add source code filename\n"
<br>+ " and line number to every log message.\n"<br>+ " By default, the SM will not log this additional info.\n\n");<br>+ printf( "-b\n"<br>+ "--verbosity_file <file name>\n"
<br>+ " This option specifies name of the verbosity\n"<br>+ " configuration file, which describes verbosity level\n"<br>+ " per source code file. The file may contain zero or\n"
<br>+ " more lines of the following pattern:\n"<br>+ " filename verbosity_level\n"<br>+ " where 'filename' is the name of the source code file\n"
<br>+ " that the 'verbosity_level' refers to, and the \n"<br>+ " 'verbosity_level' itself should be specified as a\n"<br>+ " number (decimal or hexadecimal).\n"
<br>+ " Filename 'all' represents general verbosity level,\n"<br>+ " that is used for all the files that are not specified\n" <br>+ " in the verbosity file.\n"
<br>+ " Note: The 'all' file verbosity level will override any\n"<br>+ " other general level that was specified by the command\n" <br>+ " line arguments.\n"
<br>+ " By default, the SM will use the following file:\n"<br>+ " %s\n"<br>+ " Sending a SIGHUP signal to the SM will cause it to\n"<br>
+ " re-read the verbosity configuration file.\n"<br>+ "\n\n", OSM_DEFAULT_VERBOSITY_FILE);<br> printf( "-h\n"<br> "--help\n"<br> " Display this usage info then exit.\n\n" );
<br>@@ -527,7 +554,7 @@ main(<br> boolean_t cache_options = FALSE;<br> char *ignore_guids_file_name = NULL;<br> uint32_t val;<br>- const char * const short_option = "i:f:ed:g:l:s:t:a:R:U:P:NQvVhorcyx";
<br>+ const char * const short_option = "i:f:ed:g:l:s:t:a:R:U:P:b:SNQvVhorcyx";<br> <br> /*<br> In the array below, the 2nd parameter specified the number<br>@@ -565,6 +592,8 @@ main(<br> { "cache-options", 0, NULL, 'c'},
<br> { "stay_on_fatal", 0, NULL, 'y'},<br> { "honor_guid2lid", 0, NULL, 'x'},<br>+ { "log_source_info",0,NULL, 'S'},<br>+ { "verbosity_file",1, NULL, 'b'},
<br> { NULL, 0, NULL, 0 } /* Required at the end of the array */<br> };<br> <br>@@ -808,6 +837,16 @@ main(<br> printf (" Honor guid2lid file, if possible\n");<br> break;<br> <br>
+ case 'S':<br>+ opt.src_info = TRUE;<br>+ printf(" Logging source code filename and line number\n");<br>+ break;<br>+<br>+ case 'b':<br>+ opt.verbosity_file = optarg;<br>+ printf(" Verbosity Configuration File: %s\n", optarg);
<br>+ break;<br>+<br> case 'h':<br> case '?':<br> case ':':<br>@@ -920,9 +959,13 @@ main(<br> <br> if (osm_hup_flag) {<br> osm_hup_flag = 0;<br>- /* a HUP signal should only start a new heavy sweep */
<br>+ /* <br>+ * A HUP signal should cause OSM to re-read the log<br>+ * configuration file and start a new heavy sweep <br>+ */<br> osm.subn.force_immediate_heavy_sweep = TRUE;<br> osm_opensm_sweep( &osm );
<br>+ osm_log_read_verbosity_file(&osm.log,opt.verbosity_file);<br> }<br> }<br> }<br>Index: opensm/Makefile.am<br>===================================================================<br>--- opensm/Makefile.am (revision 8614)
<br>+++ opensm/Makefile.am (working copy)<br>@@ -43,7 +43,7 @@ else<br> libopensm_version_script =<br> endif<br> <br>-libopensm_la_SOURCES = osm_log.c osm_mad_pool.c osm_helper.c<br>+libopensm_la_SOURCES = osm_log.c osm_mad_pool.c osm_helper.c
st.c<br> libopensm_la_LDFLAGS = -version-info $(opensm_api_version) \<br> -export-dynamic $(libopensm_version_script)<br> libopensm_la_DEPENDENCIES = $(srcdir)/libopensm.map<br>@@ -90,7 +90,7 @@ opensm_SOURCES = main.c
osm_console.c os<br> osm_trap_rcv.c osm_trap_rcv_ctrl.c \<br> osm_ucast_mgr.c osm_ucast_updn.c osm_ucast_file.c \<br> osm_vl15intf.c osm_vl_arb_rcv.c \<br>- osm_vl_arb_rcv_ctrl.c st.c<br>
+ osm_vl_arb_rcv_ctrl.c<br> if OSMV_OPENIB<br> opensm_CFLAGS = -Wall $(OSMV_CFLAGS) -fno-strict-aliasing -DVENDOR_RMPP_SUPPORT -DDUAL_SIDED_RMPP $(DBGFLAGS) -D_XOPEN_SOURCE=600 -D_BSD_SOURCE=1<br> opensm_CXXFLAGS = -Wall $(OSMV_CFLAGS) -DVENDOR_RMPP_SUPPORT -DDUAL_SIDED_RMPP $(DBGFLAGS) -D_XOPEN_SOURCE=600 -D_BSD_SOURCE=1
<br>Index: doc/verbosity-config.txt<br>===================================================================<br>--- doc/verbosity-config.txt (revision 0)<br>+++ doc/verbosity-config.txt (revision 0)<br>@@ -0,0 +1,43 @@
<br>+<br>+This patch adds new verbosity functionality.<br>+<br>+1. Verbosity configuration file<br>+-------------------------------<br>+<br>+The user is able to set verbosity level per source code file<br>+by supplying verbosity configuration file using the following
<br>+command line arguments:<br>+<br>+ -b filename <br>+ --verbosity_file filename<br>+<br>+By default, the OSM will use the following file: /etc/opensmlog.conf<br>+Verbosity configuration file should contain zero or more lines of
<br>+the following pattern:<br>+<br>+ filename verbosity_level<br>+<br>+where 'filename' is the name of the source code file that the <br>+'verbosity_level' refers to, and the 'verbosity_level' itself <br>+should be specified as an integer number (decimal or hexadecimal).
<br>+<br>+One reserved filename is 'all' - it represents general verbosity <br>+level, that is used for all the files that are not specified in<br>+the verbosity configuration file.<br>+If 'all' is not specified, the verbosity level set in the
<br>+command line will be used instead. <br>+Note: The 'all' file verbosity level will override any other <br>+general level that was specified by the command line arguments.<br>+<br>+Sending a SIGHUP signal to the OSM will cause it to reload
<br>+the verbosity configuration file.<br>+<br>+<br>+2. Logging source code filename and line number<br>+-----------------------------------------------<br>+<br>+If command line option -S or --log_source_info is specified,
<br>+OSM will add source code filename and line number to every <br>+log message that is written to the log file.<br>+By default, the OSM will not log this additional info.<br>+ <br><br><br></span>