Blame Dsap/src/dsap.c

Packit 857059
 /* BEGIN_ICS_COPYRIGHT4 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT4   ****************************************/
Packit 857059
/*!
Packit 857059
Packit 857059
  \file dsap_module.c
Packit 857059
 
Packit 857059
  $Revision: 1.5 $
Packit 857059
  $Date: 2015/01/27 23:00:24 $
Packit 857059
Packit 857059
  \brief Provider initialization and cleanup functions.
Packit 857059
*/
Packit 857059
Packit 857059
#include <ctype.h>
Packit 857059
Packit 857059
Packit 857059
/*
Packit 857059
  ICS IBT stuff
Packit 857059
*/
Packit 857059
#include "iba/ibt.h"
Packit 857059
#include "iba/public/isemaphore.h"
Packit 857059
#include "opasadb_debug.h"
Packit 857059
Packit 857059
/*
Packit 857059
  Module stuff
Packit 857059
*/
Packit 857059
#include "dsap.h"
Packit 857059
Packit 857059
// Module parameters
Packit 857059
Packit 857059
Packit 857059
uint32 dsap_dbg_level = _DBG_LVL_NOTICE;
Packit 857059
Packit 857059
#define LOG_FILE_LENGTH 256
Packit 857059
static char dsap_log_file[LOG_FILE_LENGTH] = {0};
Packit 857059
static FILE *omgt_log_file = NULL;
Packit 857059
Packit 857059
/*
Packit 857059
 * Parameter handling - replaces module parameters.
Packit 857059
 *
Packit 857059
 * name   - variable name of the parameter.
Packit 857059
 * desc   - human readable description
Packit 857059
 * type   - enumerated type of the parameter (integer, unsigned, boolean, etc.)
Packit 857059
 * length - for string parameters, the max length of the string. 
Packit 857059
 * ptr    - pointer to the variable.
Packit 857059
 * parser - points to a function to handle special parameters.
Packit 857059
 * printer - points to a function that can print special parameters.
Packit 857059
 */
Packit 857059
typedef struct parameter {
Packit 857059
	char name[32];
Packit 857059
	char desc[256];
Packit 857059
	char type;
Packit 857059
	int  length;
Packit 857059
	void *ptr;
Packit 857059
	int (*parser)(char *str, void *ptr);
Packit 857059
	char *(*printer)(void *ptr);
Packit 857059
} parameter_t;
Packit 857059
Packit 857059
static parameter_t	parameters[] = {
Packit 857059
	{	.name="NoSubscribe",
Packit 857059
		.type='b',
Packit 857059
		.desc="Do not subscribe to SM for notifications.",
Packit 857059
		.length = 0,
Packit 857059
		.ptr=(void*)&dsap_no_subscribe},
Packit 857059
	{	.name="ScanFrequency",
Packit 857059
		.type='u',
Packit 857059
		.desc="Number of seconds between unconditional sweeps.",
Packit 857059
		.length = 0,
Packit 857059
		.ptr=(void*)&dsap_scan_frequency},
Packit 857059
	{	.name="UnsubscribedScanFrequency",
Packit 857059
		.type='u',
Packit 857059
		.desc="Number of seconds between sweeps when not receiving "
Packit 857059
		      "notifications.",
Packit 857059
		.length = 0,
Packit 857059
		.ptr=(void*)&dsap_unsub_scan_frequency},
Packit 857059
	{	.name="Dbg",
Packit 857059
		.type='x',
Packit 857059
		.desc="Debug logging controls. Uses syslog log levels, ranging"
Packit 857059
		      " from 1 (least)\n\tto 7 (trace level).",
Packit 857059
		.length = 0,
Packit 857059
		.ptr=(void*)&dsap_dbg_level},
Packit 857059
	{	.name="Publish",
Packit 857059
		.type='b',
Packit 857059
		.desc="Publish paths to shared memory. Defaults to true.",
Packit 857059
		.length = 0,
Packit 857059
		.ptr=(void*)&dsap_publish},
Packit 857059
	{	.name="SID", 
Packit 857059
		.type='S', 
Packit 857059
		.desc="Service ID that identifies a virtual fabric to include "
Packit 857059
		      "in the cache.\n\tCan be specified multiple times.", 
Packit 857059
		.parser=dsap_service_id_range_parser, 
Packit 857059
		.printer=dsap_service_id_range_printer, 
Packit 857059
		.ptr=(void*)&sid_range_args},
Packit 857059
	{	.name="LogFile",
Packit 857059
		.type='s',
Packit 857059
		.desc="Write log messages to a file instead of the system log"
Packit 857059
		      "\n\tor stderr.",
Packit 857059
		.length = LOG_FILE_LENGTH,
Packit 857059
		.ptr=(void*)&dsap_log_file},
Packit 857059
	{	.name="dsap_default_fabric",
Packit 857059
		.type='S',
Packit 857059
		.desc="normal = do not match SIDs to the default fabric unless"
Packit 857059
		      " they don't\n\t match any other fabric.\n\tnone = never"
Packit 857059
		      " match SIDs to the default fabric.\n\t Defaults to "
Packit 857059
		      "normal.",
Packit 857059
		.parser=dsap_default_fabric_parser,
Packit 857059
		.printer=dsap_default_fabric_printer,
Packit 857059
		.ptr=(void*)&dsap_default_fabric },
Packit 857059
	{"", "", 0, 0, NULL} 
Packit 857059
};
Packit 857059
Packit 857059
static void dsap_dump_params(parameter_t *params) 
Packit 857059
{
Packit 857059
	int i=0;
Packit 857059
Packit 857059
	while (params[i].ptr != NULL) {
Packit 857059
		switch (params[i].type) {
Packit 857059
		case 'S':
Packit 857059
			acm_log(0, "%s = %s\n", params[i].name,
Packit 857059
				params[i].printer(params[i].ptr));
Packit 857059
			break;
Packit 857059
		case 'X':
Packit 857059
			acm_log(0, "%s = 0x%016"PRIx64"\n", params[i].name,
Packit 857059
				(*(uint64 *) params[i].ptr));
Packit 857059
			break;
Packit 857059
		case 'x':
Packit 857059
			acm_log(0, "%s = 0x%x\n", params[i].name,
Packit 857059
				(*(uint32 *) params[i].ptr));
Packit 857059
			break;
Packit 857059
		case 'u':
Packit 857059
			acm_log(0, "%s = %u\n", params[i].name,
Packit 857059
				(*(uint32 *) params[i].ptr));
Packit 857059
			break;
Packit 857059
		case 'i':
Packit 857059
			acm_log(0, "%s = %i\n", params[i].name,
Packit 857059
				(*(int32 *) params[i].ptr));
Packit 857059
			break;
Packit 857059
		case 'b':
Packit 857059
			acm_log(0, "%s = %s\n", params[i].name,
Packit 857059
				(*(uint32 *) params[i].ptr) ? "yes" : "no");
Packit 857059
			break;
Packit 857059
		case 's':
Packit 857059
			acm_log(0, "%s = %s\n", params[i].name,
Packit 857059
				(char *)params[i].ptr);
Packit 857059
			break;
Packit 857059
		default:
Packit 857059
			acm_log(0, "%s = Unhandled parameter type.\n",
Packit 857059
				params[i].name);
Packit 857059
			break;
Packit 857059
		} 
Packit 857059
		i++;
Packit 857059
	} 
Packit 857059
}
Packit 857059
Packit 857059
static char *dsap_trim(char *buffer)
Packit 857059
{
Packit 857059
	char *p;
Packit 857059
	int j = strlen(buffer) - 1;
Packit 857059
Packit 857059
	/* Trim trailing whitespace. */
Packit 857059
	while (j>0 && isspace(buffer[j])) {
Packit 857059
		buffer[j] = 0;
Packit 857059
		j--;
Packit 857059
	}
Packit 857059
Packit 857059
	p=buffer;
Packit 857059
	/* Trim leading whitespce.*/
Packit 857059
	j=0;
Packit 857059
	while (buffer[j]!=0 && isspace(buffer[j])) j++;
Packit 857059
Packit 857059
	p=&buffer[j];
Packit 857059
	if (*p == '#' || *p == '\n' || *p == 0)
Packit 857059
		return NULL;
Packit 857059
Packit 857059
	return p;
Packit 857059
}
Packit 857059
Packit 857059
static int dsap_parse_record(parameter_t *params, char *buffer) 
Packit 857059
{
Packit 857059
	char *k, *v, *l;
Packit 857059
	int i=0;
Packit 857059
Packit 857059
	k=strtok_r(buffer, "=", &l);
Packit 857059
	v=strtok_r(NULL, "=", &l);
Packit 857059
Packit 857059
	if (!k || !v) {
Packit 857059
		acm_log(0, "Config syntax error: %s\n", buffer);
Packit 857059
		return -1;
Packit 857059
	}
Packit 857059
Packit 857059
	/* strip white space */
Packit 857059
	k=dsap_trim(k);
Packit 857059
	v=dsap_trim(v);
Packit 857059
	if (!k || !v) {
Packit 857059
		acm_log(0, "Config syntax error: %s\n", buffer);
Packit 857059
		return -1;
Packit 857059
	}
Packit 857059
Packit 857059
	while (params[i].ptr != NULL && (k != NULL && v != NULL)) {
Packit 857059
		if (strncasecmp(k, params[i].name, strlen(k)) == 0) {
Packit 857059
			switch (params[i].type) {
Packit 857059
			case 'S':
Packit 857059
				return params[i].parser(v, params[i].ptr);
Packit 857059
			case 'X':
Packit 857059
				(*(uint64 *) params[i].ptr) =
Packit 857059
					strtoull(v, NULL, 0);
Packit 857059
				return 0;
Packit 857059
			case 'x':
Packit 857059
			case 'u':
Packit 857059
				(*(uint32 *) params[i].ptr) =
Packit 857059
					strtoul(v, NULL, 0);
Packit 857059
				return 0;
Packit 857059
			case 'i':
Packit 857059
				(*(int32 *) params[i].ptr) = 
Packit 857059
					strtol(v, NULL, 0);
Packit 857059
				return 0;
Packit 857059
			case 's':
Packit 857059
				strncpy((char *) params[i].ptr, v,
Packit 857059
					params[i].length);
Packit 857059
				((char *) params[i].ptr)[params[i].length - 1] = 0;
Packit 857059
				return 0;
Packit 857059
			case 'b':
Packit 857059
				if (strcmp(v,"yes")==0 || 
Packit 857059
				    strcmp(v,"y") == 0 || 
Packit 857059
				    strcmp(v,"true") == 0 || 
Packit 857059
				    strcmp(v,"t") == 0) 
Packit 857059
					(*(uint32 *) params[i].ptr) = 1;
Packit 857059
				else 
Packit 857059
					(*(uint32 *) params[i].ptr) =
Packit 857059
						strtol(v, NULL, 0);
Packit 857059
				return 0;
Packit 857059
			default:
Packit 857059
				acm_log(0, "Unrecognized token in config.\n");
Packit 857059
			}
Packit 857059
		}
Packit 857059
		i++;
Packit 857059
	} 
Packit 857059
Packit 857059
	return -1;
Packit 857059
}
Packit 857059
Packit 857059
static int dsap_parse_settings(char *filename, parameter_t *params)
Packit 857059
{
Packit 857059
	int err = 0;
Packit 857059
	char *ptr;
Packit 857059
	char record[1024];
Packit 857059
	FILE *f;
Packit 857059
Packit 857059
	acm_log(2, "\n");
Packit 857059
	f = fopen(filename,"r");
Packit 857059
	if (!f) {
Packit 857059
		acm_log(0, "Unable to open config file %s.\n", filename);
Packit 857059
		err=-1;
Packit 857059
	}
Packit 857059
Packit 857059
	while(!err && fgets(record, 1024, f)) {
Packit 857059
		ptr = dsap_trim(record);
Packit 857059
		if (ptr) {
Packit 857059
			if ((err = dsap_parse_record(params, record)))
Packit 857059
				acm_log(0, "Invalid Config Option: %s\n", ptr);
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	if (f) fclose(f);
Packit 857059
	return err;
Packit 857059
}
Packit 857059
Packit 857059
/* Get dsap's own configuration parameters */
Packit 857059
void dsap_get_config(char *filename)
Packit 857059
{
Packit 857059
	if (dsap_parse_settings(filename, parameters))
Packit 857059
		return;
Packit 857059
Packit 857059
	if (dsap_dbg_level > 7) dsap_dbg_level = 7;
Packit 857059
Packit 857059
	if (strlen(dsap_log_file) > 0) {
Packit 857059
		op_log_set_file(dsap_log_file);
Packit 857059
		op_log_set_level(dsap_dbg_level);
Packit 857059
	}
Packit 857059
Packit 857059
	dsap_dump_params(parameters);
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
/*!
Packit 857059
  \brief Cleanup function called when the provider is unloaded.
Packit 857059
*/
Packit 857059
Packit 857059
void dsap_cleanup(void)
Packit 857059
{
Packit 857059
	acm_log(2, "\n");
Packit 857059
Packit 857059
	dsap_scanner_cleanup();
Packit 857059
	dsap_topology_cleanup();
Packit 857059
Packit 857059
	if (omgt_log_file) 
Packit 857059
		fclose(omgt_log_file);
Packit 857059
}
Packit 857059
Packit 857059
/*!
Packit 857059
  \brief Init function called when the provider is loaded.
Packit 857059
*/
Packit 857059
Packit 857059
FSTATUS
Packit 857059
dsap_init(void)
Packit 857059
{
Packit 857059
	FSTATUS fstatus = FERROR;
Packit 857059
Packit 857059
	acm_log(2, "\n");
Packit 857059
Packit 857059
Packit 857059
	fstatus = dsap_topology_init();
Packit 857059
	if (fstatus != FSUCCESS)
Packit 857059
		goto exit;
Packit 857059
Packit 857059
	fstatus = dsap_scanner_init();
Packit 857059
	if (FSUCCESS != fstatus)
Packit 857059
		goto exit;
Packit 857059
Packit 857059
	/* Guard against scans without timeout */
Packit 857059
	if (dsap_unsub_scan_frequency == 0)
Packit 857059
		dsap_unsub_scan_frequency = 10;
Packit 857059
Packit 857059
	fstatus = dsap_scanner_start();
Packit 857059
Packit 857059
exit:
Packit 857059
	return fstatus;
Packit 857059
}
Packit 857059
void dsap_omgt_log_init(struct omgt_port *omgt_port)
Packit 857059
{
Packit 857059
	if (strlen(dsap_log_file) > 0) {
Packit 857059
		omgt_log_file = op_log_get_file();
Packit 857059
		omgt_set_err(omgt_port, omgt_log_file);
Packit 857059
		if (dsap_dbg_level >= 7)
Packit 857059
			omgt_set_dbg(omgt_port, omgt_log_file);
Packit 857059
	}
Packit 857059
}