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