<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>