[openib-general] [PATCH] osm: Dynamic verbosity control per file
Yevgeny Kliteynik
kliteyn at mellanox.co.il
Sun Aug 27 04:30:02 PDT 2006
Hi Hal.
> > 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
Right - will use osm-log.conf
> 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.
You're right, osm_log & osm_log_raw are no longer appear in the
API, but they are not removed from headers - they are now macros,
so the old code will still compile.
> Also, is this functionality needed for OFED 1.1 or is this trunk
> only ?
It doesn't have to get to 1.1.
I'll send a second version of this patch that will address all your
comments, including the addition in the osm man pages.
Thanks,
Yevgeny
On Tue, 2006-08-15 at 18:34 +0300, Hal Rosenstock wrote:
> 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