/*
 * srp_daemon - discover SRP targets over IB
 * Copyright (c) 2005 Topspin Communications.  All rights reserved.
 * Copyright (c) 2006 Cisco Systems, Inc.  All rights reserved.
 * Copyright (c) 2006 Mellanox Technologies Ltd.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * $Author: ishai Rabinovitz [ishai@mellanox.co.il]$
 * Based on Roland Dreier's initial code [rdreier@cisco.com]
 *
 */

#define _GNU_SOURCE

#include <assert.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/types.h>
#include <endian.h>
#include <errno.h>
#include <getopt.h>
#include <dirent.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <sys/syslog.h>
#include <infiniband/umad.h>
#include <infiniband/umad_types.h>
#include <infiniband/umad_sa.h>
#include "srp_ib_types.h"

#include "srp_daemon.h"

#define IBDEV_STR_SIZE 16
#define IBPORT_STR_SIZE 16
#define IGNORE(value) do { if (value) { } } while (0)
#define max_t(type, x, y) ({                    \
	type __max1 = (x);	\
	type __max2 = (y);	\
	__max1 > __max2 ? __max1: __max2; })

#define get_data_ptr(mad) ((void *) ((mad).hdr.data))

enum log_dest { log_to_syslog, log_to_stderr };

static int get_lid(struct umad_resources *umad_res, union umad_gid *gid,
		   uint16_t *lid);

static const int   node_table_response_size = 1 << 18;
static const char *sysfs_path = "/sys";
static enum log_dest s_log_dest = log_to_syslog;
static int wakeup_pipe[2] = { -1, -1 };


void wake_up_main_loop(char ch)
{
	int res;

	assert(wakeup_pipe[1] >= 0);
	res = write(wakeup_pipe[1], &ch, 1);
	IGNORE(res);
}

static void signal_handler(int signo)
{
	wake_up_main_loop(signo);
}

/*
 * Return either the received signal (SIGINT, SIGTERM, ...) or 0 if no signal
 * has been received before the timeout has expired.
 */
static int get_received_signal(time_t tv_sec, suseconds_t tv_usec)
{
	int fd, ret, received_signal = 0;
	fd_set rset;
	struct timeval timeout;
	char buf[16];

	fd = wakeup_pipe[0];
	FD_ZERO(&rset);
	FD_SET(fd, &rset);
	timeout.tv_sec = tv_sec;
	timeout.tv_usec = tv_usec;
	ret = select(fd + 1, &rset, NULL, NULL, &timeout);
	if (ret < 0)
		assert(errno == EINTR);
	while ((ret = read(fd, buf, sizeof(buf))) > 0)
		received_signal = buf[ret - 1];

	return received_signal;
}

static int check_process_uniqueness(struct config_t *conf)
{
	char path[256];
	int fd;

	snprintf(path, sizeof(path), SRP_DAEMON_LOCK_PREFIX "_%s_%d",
		 conf->dev_name, conf->port_num);

	if ((fd = open(path, O_CREAT|O_RDWR,
		       S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR)) < 0) {
		pr_err("cannot open file \"%s\" (errno: %d).\n", path, errno);
		return -1;
	}

	if (0 != lockf(fd, F_TLOCK, 0)) {
		pr_err("failed to lock %s (errno: %d). possibly another "
		       "srp_daemon is locking it\n", path, errno);
		close(fd);
		fd = -1;
	}

	return fd;
}

static int srpd_sys_read_string(const char *dir_name, const char *file_name,
				char *str, int max_len)
{
	char path[256], *s;
	int fd, r;

	snprintf(path, sizeof(path), "%s/%s", dir_name, file_name);

	if ((fd = open(path, O_RDONLY)) < 0)
		return (errno > 0) ? -errno : errno;

	if ((r = read(fd, str, max_len)) < 0) {
		int e = errno;
		close(fd);
		return (e > 0) ? -e : e;
	}

	str[(r < max_len) ? r : max_len - 1] = 0;

	if ((s = strrchr(str, '\n')))
		*s = 0;

	close(fd);
	return 0;
}

static int srpd_sys_read_gid(const char *dir_name, const char *file_name,
			     uint8_t *gid)
{
	char buf[64], *str, *s;
	__be16 *ugid = (__be16 *)gid;
	int r, i;

	if ((r = srpd_sys_read_string(dir_name, file_name, buf, sizeof(buf))) < 0)
		return r;

	for (s = buf, i = 0 ; i < 8; i++) {
		if (!(str = strsep(&s, ": \t\n")))
			return -EINVAL;
		ugid[i] = htobe16(strtoul(str, NULL, 16) & 0xffff);
	}

	return 0;
}

static int srpd_sys_read_uint64(const char *dir_name, const char *file_name,
				uint64_t *u)
{
	char buf[32];
	int r;

	if ((r = srpd_sys_read_string(dir_name, file_name, buf, sizeof(buf))) < 0)
		return r;

	*u = strtoull(buf, NULL, 0);

	return 0;
}




static void usage(const char *argv0)
{
	fprintf(stderr, "Usage: %s [-vVcaeon] [-d <umad device> | -i <infiniband device> [-p <port_num>]] [-t <timeout (ms)>] [-r <retries>] [-R <rescan time>] [-f <rules file>\n", argv0);
	fprintf(stderr, "-v 			Verbose\n");
	fprintf(stderr, "-V 			debug Verbose\n");
	fprintf(stderr, "-c 			prints connection Commands\n");
	fprintf(stderr, "-a 			show All - prints also targets that are already connected\n");
	fprintf(stderr, "-e 			Executes connection commands\n");
	fprintf(stderr, "-o 			runs only Once and stop\n");
	fprintf(stderr, "-d <umad device>	use umad Device \n");
	fprintf(stderr, "-i <infiniband device>	use InfiniBand device \n");
	fprintf(stderr, "-p <port_num>		use Port num \n");
	fprintf(stderr, "-j <dev>:<port_num>	use the IB dev / port_num combination \n");
	fprintf(stderr, "-R <rescan time>	perform complete Rescan every <rescan time> seconds\n");
	fprintf(stderr, "-T <retry timeout>	Retries to connect to existing target after Timeout of <retry timeout> seconds\n");
	fprintf(stderr, "-l <tl_retry timeout>	Transport retry count before failing IO. should be in range [2..7], (default 2)\n");
	fprintf(stderr, "-f <rules file>	use rules File to set to which target(s) to connect (default: " SRP_DAEMON_CONFIG_FILE ")\n");
	fprintf(stderr, "-t <timeout>		Timeout for mad response in milliseconds\n");
	fprintf(stderr, "-r <retries>		number of send Retries for each mad\n");
	fprintf(stderr, "-n 			New connection command format - use also initiator extension\n");
	fprintf(stderr, "--systemd		Enable systemd integration.\n");
	fprintf(stderr, "\nExample: srp_daemon -e -n -i mthca0 -p 1 -R 60\n");
}

static int
check_equal_uint64(char *dir_name, const char *attr, uint64_t val)
{
	uint64_t attr_value;

	if (srpd_sys_read_uint64(dir_name, attr, &attr_value))
		return 0;

	return attr_value == val;
}

static int
check_equal_uint16(char *dir_name, const char *attr, uint16_t val)
{
	uint64_t attr_value;

	if (srpd_sys_read_uint64(dir_name, attr, &attr_value))
		return 0;

	return val == (attr_value & 0xffff);
}

static int recalc(struct resources *res);

static void pr_cmd(char *target_str, int not_connected)
{
	int ret;

	if (config->cmd)
		printf("%s\n", target_str);

	if (config->execute && not_connected) {
		int fd = open(config->add_target_file, O_WRONLY);
		if (fd < 0) {
			pr_err("unable to open %s, maybe ib_srp is not loaded\n", config->add_target_file);
			return;
		}
		ret = write(fd, target_str, strlen(target_str));
		pr_debug("Adding target returned %d\n", ret);
		close(fd);
	}
}

void pr_debug(const char *fmt, ...)
{
	va_list args;

	if (!config->debug_verbose)
		return;

	va_start(args, fmt);
	vprintf(fmt, args);
	va_end(args);
}

void pr_err(const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	switch (s_log_dest) {
	case log_to_syslog:
		vsyslog(LOG_DAEMON | LOG_ERR, fmt, args);
		break;
	case log_to_stderr:
		vfprintf(stderr, fmt, args);
		break;
	}
	va_end(args);
}

static int check_not_equal_str(const char *dir_name, const char *attr,
			       const char *value)
{
	char attr_value[64];
	int len = strlen(value);

	if (len > sizeof(attr_value)) {
		pr_err("string %s is too long\n", value);
		return 1;
	}

	if (srpd_sys_read_string(dir_name, attr, attr_value,
				 sizeof(attr_value)))
		return 0;
	if (strncmp(attr_value, value, len))
		return 1;

	return 0;
}

static int check_not_equal_int(const char *dir_name, const char *attr,
			       int value)
{
	char attr_value[64];

	if (srpd_sys_read_string(dir_name, attr, attr_value,
				 sizeof(attr_value)))
		return 0;
	if (value != atoi(attr_value))
		return 1;

	return 0;
}

static int is_enabled_by_rules_file(struct target_details *target)
{
	int rule;
	struct config_t *conf = config;

	if (NULL == conf->rules) {
		pr_debug("Allowing SRP target with id_ext %s because not using a rules file\n", target->id_ext);
		return 1;
	}

	rule = -1;
	do {
		rule++;
		if (conf->rules[rule].id_ext[0] != '\0' &&
		    strtoull(target->id_ext, NULL, 16) !=
		    strtoull(conf->rules[rule].id_ext, NULL, 16))
			continue;

		if (conf->rules[rule].ioc_guid[0] != '\0' &&
		    be64toh(target->ioc_prof.guid) !=
		    strtoull(conf->rules[rule].ioc_guid, NULL, 16))
			continue;

		if (conf->rules[rule].dgid[0] != '\0') {
			char tmp = conf->rules[rule].dgid[16];
			conf->rules[rule].dgid[16] = '\0';
			if (strtoull(conf->rules[rule].dgid, NULL, 16) !=
			    target->subnet_prefix) {
				conf->rules[rule].dgid[16] = tmp;
				continue;
			}
			conf->rules[rule].dgid[16] = tmp;
			if (strtoull(&conf->rules[rule].dgid[16], NULL, 16) !=
			    target->h_guid)
				continue;
		}

		if (conf->rules[rule].service_id[0] != '\0' &&
		    strtoull(conf->rules[rule].service_id, NULL, 16) !=
	            target->h_service_id)
			continue;

		if (conf->rules[rule].pkey[0] != '\0' &&
		    (uint16_t)strtoul(conf->rules[rule].pkey, NULL, 16) !=
	            target->pkey)
			continue;

		target->options = conf->rules[rule].options;

		pr_debug("SRP target with id_ext %s %s by rules file\n",
				target->id_ext,
				conf->rules[rule].allow ? "allowed" : "disallowed");
		return conf->rules[rule].allow;

	} while (1);
}


static bool use_imm_data(void)
{
	bool ret = false;
	char flag = 0;
	int cnt;
	int fd = open("/sys/module/ib_srp/parameters/use_imm_data", O_RDONLY);

	if (fd < 0)
		return false;
	cnt = read(fd, &flag, 1);
	if (cnt != 1) {
		close(fd);
		return false;
	}

	if (!strncmp(&flag, "Y", 1))
		ret = true;
	close(fd);
	return ret;
}

static bool imm_data_size_gt_send_size(unsigned int send_size)
{
	bool ret = false;
	unsigned int srp_max_imm_data = 0;
	FILE *fp = fopen("/sys/module/ib_srp/parameters/max_imm_data", "r");
	int cnt;

	if (fp == NULL)
		return ret;

	cnt = fscanf(fp, "%d", &srp_max_imm_data);
	if (cnt <= 0) {
		fclose(fp);
		return ret;
	}

	if (srp_max_imm_data > send_size)
		ret = true;

	fclose(fp);
	return ret;
}

static int add_non_exist_target(struct target_details *target)
{
	char scsi_host_dir[256];
	DIR *dir;
	struct dirent *subdir;
	char *subdir_name_ptr;
	int prefix_len;
	union umad_gid dgid_val;
	char target_config_str[255];
	int len;
	int not_connected = 1;
	unsigned int send_size;

	pr_debug("Found an SRP target with id_ext %s - check if it is already connected\n", target->id_ext);

	strcpy(scsi_host_dir, "/sys/class/scsi_host/");
	dir=opendir(scsi_host_dir);
	if (!dir) {
		perror("opendir - /sys/class/scsi_host/");
		return -1;
	}
	prefix_len = strlen(scsi_host_dir);
	subdir_name_ptr = scsi_host_dir + prefix_len;

	subdir = (void *) 1; /* Dummy value to enter the loop */
	while (subdir) {
	        subdir = readdir(dir);

		if (!subdir)
			continue;

		if (subdir->d_name[0] == '.')
			continue;

		strncpy(subdir_name_ptr, subdir->d_name,
			sizeof(scsi_host_dir) - prefix_len);
		if (!check_equal_uint64(scsi_host_dir, "id_ext",
				        strtoull(target->id_ext, NULL, 16)))
			continue;
		if (!check_equal_uint16(scsi_host_dir, "pkey", target->pkey) &&
		    !config->execute)
			continue;

		if (!check_equal_uint64(scsi_host_dir, "service_id",
					target->h_service_id))
			continue;
		if (!check_equal_uint64(scsi_host_dir, "ioc_guid",
					be64toh(target->ioc_prof.guid)))
			continue;
		if (srpd_sys_read_gid(scsi_host_dir, "orig_dgid",
				      dgid_val.raw)) {
			/*
			 * In case this is an old kernel that does not have
			 * orig_dgid in sysfs, use dgid instead (this is
			 * problematic when there is a dgid redirection
			 * by the CM)
			 */
			if (srpd_sys_read_gid(scsi_host_dir, "dgid",
					      dgid_val.raw))
				continue;
		}
		if (htobe64(target->subnet_prefix) !=
		    dgid_val.global.subnet_prefix)
			continue;
		if (htobe64(target->h_guid) != dgid_val.global.interface_id)
			continue;

		/* If there is no local_ib_device in the scsi host dir (old kernel module), assumes it is equal */
		if (check_not_equal_str(scsi_host_dir, "local_ib_device", config->dev_name))
			continue;

		/* If there is no local_ib_port in the scsi host dir (old kernel module), assumes it is equal */
		if (check_not_equal_int(scsi_host_dir, "local_ib_port", config->port_num))
			continue;

		/* there is a match - this target is already connected */

		/* There is a rare possibility of a race in the following
		   scenario:
			a. A link goes down,
			b. ib_srp decide to remove the corresponding scsi_host.
			c. Before removing it, the link returns
			d. srp_daemon gets trap 64.
			e. srp_daemon thinks that this target is still
			   connected (ib_srp has not removed it yet) so it
			   does not connect to it.
			f. ib_srp continue to remove the scsi_host.
		    As a result there is no connection to a target in the fabric
		    and there will not be a new trap.

		   To solve this race we schedule here another call to check
		   if this target exist in the near future.
		*/



		/* If there is a need to print all we will continue to pr_cmd.
		   not_connected is set to zero to make sure that this target
		   will be printed but not connected.
		*/
		if (config->all) {
			not_connected = 0;
			break;
		}

		pr_debug("This target is already connected - skip\n");
		closedir(dir);

		return 0;

	}

	len = snprintf(target_config_str, sizeof(target_config_str), "id_ext=%s,"
		"ioc_guid=%016llx,"
		"dgid=%016llx%016llx,"
		"pkey=%04x,"
		"service_id=%016llx",
		target->id_ext,
		(unsigned long long) be64toh(target->ioc_prof.guid),
		(unsigned long long) target->subnet_prefix,
		(unsigned long long) target->h_guid,
		target->pkey,
		(unsigned long long) target->h_service_id);
	if (len >= sizeof(target_config_str)) {
		pr_err("Target config string is too long, ignoring target\n");
		closedir(dir);
		return -1;
	}

	if (target->ioc_prof.io_class != htobe16(SRP_REV16A_IB_IO_CLASS)) {
		len += snprintf(target_config_str+len,
				sizeof(target_config_str) - len,
				",io_class=%04hx", be16toh(target->ioc_prof.io_class));

		if (len >= sizeof(target_config_str)) {
			pr_err("Target config string is too long, ignoring target\n");
			closedir(dir);
			return -1;
		}
	}

	if (config->print_initiator_ext) {
		len += snprintf(target_config_str+len,
				sizeof(target_config_str) - len,
				",initiator_ext=%016llx",
				(unsigned long long) target->h_guid);

		if (len >= sizeof(target_config_str)) {
			pr_err("Target config string is too long, ignoring target\n");
			closedir(dir);
			return -1;
		}
	}

	if (config->execute && config->tl_retry_count) {
		len += snprintf(target_config_str + len,
				sizeof(target_config_str) - len,
				",tl_retry_count=%d", config->tl_retry_count);

		if (len >= sizeof(target_config_str)) {
			pr_err("Target config string is too long, ignoring target\n");
			closedir(dir);
			return -1;
		}
	}

	if (target->options) {
		len += snprintf(target_config_str+len,
				sizeof(target_config_str) - len,
				"%s",
				target->options);

		if (len >= sizeof(target_config_str)) {
			pr_err("Target config string is too long, ignoring target\n");
			closedir(dir);
			return -1;
		}
	}

	/*
	 * The SRP initiator stops parsing parameters if it encounters
	 * an unrecognized parameter. Rest parameters will be ignored.
	 * Append 'max_it_iu_size' in the very end of login string to
	 * avoid breaking SRP login.
	 */
	send_size = be32toh(target->ioc_prof.send_size);
	if (use_imm_data() && imm_data_size_gt_send_size(send_size)) {
		len += snprintf(target_config_str+len,
			sizeof(target_config_str) - len,
			",max_it_iu_size=%d", send_size);

		if (len >= sizeof(target_config_str)) {
			pr_err("Target config string is too long, ignoring target\n");
			closedir(dir);
			return -1;
		}
	}

	target_config_str[len] = '\0';

	pr_cmd(target_config_str, not_connected);

	closedir(dir);

	return 1;
}

static int send_and_get(int portid, int agent, struct srp_ib_user_mad *out_mad,
		 struct srp_ib_user_mad *in_mad, int in_mad_size)
{
	struct umad_dm_packet *out_dm_mad = (void *) out_mad->hdr.data;
	struct umad_dm_packet *in_dm_mad = (void *) in_mad->hdr.data;
	int i, len;
	int in_agent;
	int ret;
	static uint32_t tid;
	uint32_t received_tid;

	for (i = 0; i < config->mad_retries; ++i) {
		/* Skip tid 0 because OpenSM ignores it. */
		if (++tid == 0)
			++tid;
		out_dm_mad->mad_hdr.tid = htobe64(tid);

		ret = umad_send(portid, agent, out_mad, MAD_BLOCK_SIZE,
				config->timeout, 0);
		if (ret < 0) {
			pr_err("umad_send to %u failed\n",
				(uint16_t) be16toh(out_mad->hdr.addr.lid));
			return ret;
		}

		do {
recv:
			len = in_mad_size ? in_mad_size : MAD_BLOCK_SIZE;
			in_agent = umad_recv(portid, (struct ib_user_mad *) in_mad,
					     &len, config->timeout);
			if (in_agent < 0) {
				pr_err("umad_recv from %u failed - %d\n",
					(uint16_t) be16toh(out_mad->hdr.addr.lid),
					in_agent);
				return in_agent;
			}
			if (in_agent != agent) {
				pr_debug("umad_recv returned different agent\n");
				goto recv;
			}

			ret = umad_status(in_mad);
			if (ret) {
				pr_err(
					"bad MAD status (%u) from lid %#x\n",
					ret, be16toh(out_mad->hdr.addr.lid));
				return -ret;
			}

			received_tid = be64toh(in_dm_mad->mad_hdr.tid);
			if (tid != received_tid)
				pr_debug("umad_recv returned different transaction id sent %d got %d\n",
					 tid, received_tid);

		} while ((int32_t)(tid - received_tid) > 0);

		if (len > 0)
			return len;
	}

	return -1;
}

static void initialize_sysfs(void)
{
	char *env;

	env = getenv("SYSFS_PATH");
	if (env) {
		int len;
		char *dup;

		sysfs_path = dup = strndup(env, 256);
		len = strlen(dup);
		while (len > 0 && dup[len - 1] == '/') {
			--len;
			dup[len] = '\0';
		}
	}
}

static int translate_umad_to_ibdev_and_port(char *umad_dev, char **ibdev,
					    char **ibport)
{
	char *class_dev_path;
	char *umad_dev_name;
	int ret;

	*ibdev = NULL;
	*ibport = NULL;

	umad_dev_name = rindex(umad_dev, '/');
	if (!umad_dev_name) {
		pr_err("Couldn't find device name in '%s'\n", umad_dev);
		return -1;
	}

	ret = asprintf(&class_dev_path, "%s/class/infiniband_mad/%s", sysfs_path,
		       umad_dev_name);

	if (ret < 0) {
 		pr_err("out of memory\n");
		return -ENOMEM;
	}

	*ibdev = malloc(IBDEV_STR_SIZE);
	if (!*ibdev) {
 		pr_err("out of memory\n");
		ret = -ENOMEM;
		goto end;
	}

	if (srpd_sys_read_string(class_dev_path, "ibdev", *ibdev,
			    IBDEV_STR_SIZE) < 0) {
		pr_err("Couldn't read ibdev attribute\n");
		ret = -1;
		goto end;
	}

	*ibport = malloc(IBPORT_STR_SIZE);
	if (!*ibport) {
		pr_err("out of memory\n");
		ret = -ENOMEM;
		goto end;
	}
	if (srpd_sys_read_string(class_dev_path, "port", *ibport, IBPORT_STR_SIZE) < 0) {
		pr_err("Couldn't read port attribute\n");
		ret = -1;
		goto end;
	}

	ret = 0;

end:
	if (ret) {
		free(*ibport);
		free(*ibdev);
		*ibdev = NULL;
	}
	free(class_dev_path);

	return ret;
}

static void init_srp_mad(struct srp_ib_user_mad *out_umad, int agent,
			 uint16_t h_dlid, uint16_t h_attr_id, uint32_t h_attr_mod)
{
	struct umad_dm_packet *out_mad;

	memset(out_umad, 0, sizeof *out_umad);

	out_umad->hdr.agent_id   = agent;
	out_umad->hdr.addr.qpn   = htobe32(1);
	out_umad->hdr.addr.qkey  = htobe32(UMAD_QKEY);
	out_umad->hdr.addr.lid   = htobe16(h_dlid);

	out_mad = (void *) out_umad->hdr.data;

	out_mad->mad_hdr.base_version  = UMAD_BASE_VERSION;
	out_mad->mad_hdr.method        = UMAD_METHOD_GET;
	out_mad->mad_hdr.attr_id       = htobe16(h_attr_id);
	out_mad->mad_hdr.attr_mod      = htobe32(h_attr_mod);
}

static void init_srp_dm_mad(struct srp_ib_user_mad *out_mad, int agent, uint16_t h_dlid,
			    uint16_t h_attr_id, uint32_t h_attr_mod)
{
	struct umad_sa_packet *out_dm_mad = get_data_ptr(*out_mad);

	init_srp_mad(out_mad, agent, h_dlid, h_attr_id, h_attr_mod);
	out_dm_mad->mad_hdr.mgmt_class = UMAD_CLASS_DEVICE_MGMT;
	out_dm_mad->mad_hdr.class_version  = 1;
}

static void init_srp_sa_mad(struct srp_ib_user_mad *out_mad, int agent, uint16_t h_dlid,
			    uint16_t h_attr_id, uint32_t h_attr_mod)
{
	struct umad_sa_packet *out_sa_mad = get_data_ptr(*out_mad);

	init_srp_mad(out_mad, agent, h_dlid, h_attr_id, h_attr_mod);
	out_sa_mad->mad_hdr.mgmt_class = UMAD_CLASS_SUBN_ADM;
	out_sa_mad->mad_hdr.class_version  = UMAD_SA_CLASS_VERSION;
}

static int check_sm_cap(struct umad_resources *umad_res, int *mask_match)
{
	struct srp_ib_user_mad		out_mad, in_mad;
	struct umad_sa_packet	       *in_sa_mad;
	struct umad_class_port_info    *cpi;
	int				ret;

	in_sa_mad  = get_data_ptr(in_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_ATTR_CLASS_PORT_INFO, 0);

	ret = send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0);
	if (ret < 0)
		return ret;

	cpi = (void *) in_sa_mad->data;

	*mask_match = !!(be16toh(cpi->cap_mask) & SRP_SM_SUPPORTS_MASK_MATCH);

	return 0;
}

int pkey_index_to_pkey(struct umad_resources *umad_res, int pkey_index,
		       __be16 *pkey)
{
	if (ibv_query_pkey(umad_res->ib_ctx, config->port_num, pkey_index,
			   pkey) < 0)
		return -1;
	if (*pkey)
		pr_debug("discover Targets for P_key %04x (index %d)\n",
			 *pkey, pkey_index);
	return 0;
}

static int pkey_to_pkey_index(struct umad_resources *umad_res, uint16_t h_pkey,
			      uint16_t *pkey_index)
{
	int res = ibv_get_pkey_index(umad_res->ib_ctx, config->port_num,
				     htobe16(h_pkey));
	if (res >= 0)
		*pkey_index = res;
	return res;
}

static int set_class_port_info(struct umad_resources *umad_res, uint16_t dlid, uint16_t h_pkey)
{
	struct srp_ib_user_mad		in_mad, out_mad;
	struct umad_dm_packet	       *out_dm_mad, *in_dm_mad;
	struct umad_class_port_info    *cpi;
	char val[64];
	int i;

	init_srp_dm_mad(&out_mad, umad_res->agent, dlid, UMAD_ATTR_CLASS_PORT_INFO, 0);

	if (pkey_to_pkey_index(umad_res, h_pkey, &out_mad.hdr.addr.pkey_index)
	    < 0) {
		pr_err("set_class_port_info: Unable to find pkey_index for pkey %#x\n", h_pkey);
		return -1;
	}

	out_dm_mad = get_data_ptr(out_mad);
	out_dm_mad->mad_hdr.method = UMAD_METHOD_SET;

	cpi                = (void *) out_dm_mad->data;

	if (srpd_sys_read_string(umad_res->port_sysfs_path, "lid", val, sizeof val) < 0) {
		pr_err("Couldn't read LID\n");
		return -1;
	}

	cpi->trap_lid = htobe16(strtol(val, NULL, 0));

	if (srpd_sys_read_string(umad_res->port_sysfs_path, "gids/0", val, sizeof val) < 0) {
		pr_err("Couldn't read GID[0]\n");
		return -1;
	}

	for (i = 0; i < 8; ++i)
		cpi->trapgid.raw_be16[i] = htobe16(strtol(val + i * 5, NULL, 16));

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	in_dm_mad = get_data_ptr(in_mad);
	if (in_dm_mad->mad_hdr.status) {
		pr_err("Class Port Info set returned status 0x%04x\n",
			be16toh(in_dm_mad->mad_hdr.status));
		return -1;
	}

	return 0;
}

static int get_iou_info(struct umad_resources *umad_res, uint16_t dlid,
			uint16_t h_pkey, struct srp_dm_iou_info *iou_info)
{
	struct srp_ib_user_mad		in_mad, out_mad;
	struct umad_dm_packet	       *in_dm_mad;

	init_srp_dm_mad(&out_mad, umad_res->agent, dlid, SRP_DM_ATTR_IO_UNIT_INFO, 0);
	if (pkey_to_pkey_index(umad_res, h_pkey, &out_mad.hdr.addr.pkey_index)
	    < 0) {
		pr_err("get_iou_info: Unable to find pkey_index for pkey %#x\n", h_pkey);
		return -1;
	}

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	in_dm_mad = get_data_ptr(in_mad);
	if (in_dm_mad->mad_hdr.status) {
		pr_err("IO Unit Info query returned status 0x%04x\n",
			be16toh(in_dm_mad->mad_hdr.status));
		return -1;
	}

	memcpy(iou_info, in_dm_mad->data, sizeof *iou_info);
/*
	pr_debug("iou_info->max_controllers is %d\n", iou_info->max_controllers);
*/
	return 0;
}

static int get_ioc_prof(struct umad_resources *umad_res, uint16_t h_dlid, uint16_t h_pkey, int ioc,
			struct srp_dm_ioc_prof *ioc_prof)
{
	struct srp_ib_user_mad		in_mad, out_mad;
	struct umad_dm_packet	       *in_dm_mad;

	init_srp_dm_mad(&out_mad, umad_res->agent, h_dlid, SRP_DM_ATTR_IO_CONTROLLER_PROFILE, ioc);

	if (pkey_to_pkey_index(umad_res, h_pkey, &out_mad.hdr.addr.pkey_index)
	    < 0) {
		pr_err("get_ioc_prof: Unable to find pkey_index for pkey %#x\n",
		       h_pkey);
		return -1;
	}

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	in_dm_mad = get_data_ptr(in_mad);
	if (in_dm_mad->mad_hdr.status) {
		pr_err("IO Controller Profile query returned status 0x%04x for %d\n",
			be16toh(in_dm_mad->mad_hdr.status), ioc);
		return -1;
	}

	memcpy(ioc_prof, in_dm_mad->data, sizeof *ioc_prof);

	return 0;
}

static int get_svc_entries(struct umad_resources *umad_res, uint16_t dlid, uint16_t h_pkey, int ioc,
			   int start, int end, struct srp_dm_svc_entries *svc_entries)
{
	struct srp_ib_user_mad		in_mad, out_mad;
	struct umad_dm_packet	       *in_dm_mad;

	init_srp_dm_mad(&out_mad, umad_res->agent, dlid, SRP_DM_ATTR_SERVICE_ENTRIES,
			(ioc << 16) | (end << 8) | start);

	if (pkey_to_pkey_index(umad_res, h_pkey, &out_mad.hdr.addr.pkey_index)
	    < 0) {
		pr_err("get_svc_entries: Unable to find pkey_index for pkey %#x\n",
		       h_pkey);
		return -1;
	}

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	in_dm_mad = get_data_ptr(in_mad);
	if (in_dm_mad->mad_hdr.status) {
		pr_err("Service Entries query returned status 0x%04x\n",
			be16toh(in_dm_mad->mad_hdr.status));
		return -1;
	}

	memcpy(svc_entries, in_dm_mad->data, sizeof *svc_entries);

	return 0;
}

static int do_port(struct resources *res, uint16_t pkey, uint16_t dlid,
		   uint64_t subnet_prefix, uint64_t h_guid)
{
	struct umad_resources 	       *umad_res = res->umad_res;
	struct srp_dm_iou_info		iou_info;
	struct srp_dm_svc_entries	svc_entries;
	int				i, j, k, ret;

	static const uint64_t topspin_oui = 0x0005ad0000000000ull;
	static const uint64_t oui_mask    = 0xffffff0000000000ull;

	struct target_details *target = (struct target_details *)
		malloc(sizeof(struct target_details));

	target->subnet_prefix = subnet_prefix;
	target->h_guid = h_guid;
	target->options = NULL;

 	pr_debug("enter do_port\n");
	if ((target->h_guid & oui_mask) == topspin_oui &&
	    set_class_port_info(umad_res, dlid, pkey))
		pr_err("Warning: set of ClassPortInfo failed\n");

	ret = get_iou_info(umad_res, dlid, pkey, &iou_info);
	if (ret < 0) {
		pr_err("failed to get iou info for dlid %#x\n", dlid);
		goto out;
	}

	pr_human("IO Unit Info:\n");
	pr_human("    port LID:        %04x\n", dlid);
	pr_human("    port GID:        %016llx%016llx\n",
		 (unsigned long long) target->subnet_prefix,
		 (unsigned long long) target->h_guid);
	pr_human("    change ID:       %04x\n", be16toh(iou_info.change_id));
	pr_human("    max controllers: 0x%02x\n", iou_info.max_controllers);

	if (config->verbose > 0)
		for (i = 0; i < iou_info.max_controllers; ++i) {
			pr_human("    controller[%3d]: ", i + 1);
			switch ((iou_info.controller_list[i / 2] >>
				 (4 * (1 - i % 2))) & 0xf) {
			case SRP_DM_NO_IOC:      pr_human("not installed\n"); break;
			case SRP_DM_IOC_PRESENT: pr_human("present\n");       break;
			case SRP_DM_NO_SLOT:     pr_human("no slot\n");       break;
			default:                 pr_human("<unknown>\n");     break;
			}
		}

	for (i = 0; i < iou_info.max_controllers; ++i) {
		if (((iou_info.controller_list[i / 2] >> (4 * (1 - i % 2))) & 0xf) ==
		    SRP_DM_IOC_PRESENT) {
			pr_human("\n");

			if (get_ioc_prof(umad_res, dlid, pkey, i + 1, &target->ioc_prof))
				continue;

			pr_human("    controller[%3d]\n", i + 1);

			pr_human("        GUID:      %016llx\n",
				 (unsigned long long) be64toh(target->ioc_prof.guid));
			pr_human("        vendor ID: %06x\n", be32toh(target->ioc_prof.vendor_id) >> 8);
			pr_human("        device ID: %06x\n", be32toh(target->ioc_prof.device_id));
			pr_human("        IO class : %04hx\n", be16toh(target->ioc_prof.io_class));
			pr_human("        Maximum size of Send Messages in bytes: %d\n",
				 be32toh(target->ioc_prof.send_size));
			pr_human("        ID:        %s\n", target->ioc_prof.id);
			pr_human("        service entries: %d\n", target->ioc_prof.service_entries);

			for (j = 0; j < target->ioc_prof.service_entries; j += 4) {
				int n;

				n = j + 3;
				if (n >= target->ioc_prof.service_entries)
					n = target->ioc_prof.service_entries - 1;

				if (get_svc_entries(umad_res, dlid, pkey, i + 1,
						    j, n, &svc_entries))
					continue;

				for (k = 0; k <= n - j; ++k) {

					if (sscanf(svc_entries.service[k].name,
						   "SRP.T10:%16s",
						   target->id_ext) != 1)
						continue;

					pr_human("            service[%3d]: %016llx / %s\n",
						 j + k,
						 (unsigned long long) be64toh(svc_entries.service[k].id),
						 svc_entries.service[k].name);

					target->h_service_id = be64toh(svc_entries.service[k].id);
					target->pkey = pkey;
					if (is_enabled_by_rules_file(target)) {
						if (!add_non_exist_target(target) && !config->once) {
							target->retry_time =
								time(NULL) + config->retry_timeout;
							push_to_retry_list(res->sync_res, target);
						}
					}
				}
			}
		}
	}

	pr_human("\n");

out:
	free(target);
	return ret;
}

int get_node(struct umad_resources *umad_res, uint16_t dlid, uint64_t *guid)
{
	struct srp_ib_user_mad		out_mad, in_mad;
	struct umad_sa_packet	       *out_sa_mad, *in_sa_mad;
	struct srp_sa_node_rec	       *node;

	in_sa_mad = get_data_ptr(in_mad);
	out_sa_mad = get_data_ptr(out_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_NODE_REC, 0);

	out_sa_mad->comp_mask     = htobe64(1); /* LID */
	node			  = (void *) out_sa_mad->data;
	node->lid		  = htobe16(dlid);

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	node  = (void *) in_sa_mad->data;
	*guid = be64toh(node->port_guid);

	return 0;
}

static int get_port_info(struct umad_resources *umad_res, uint16_t dlid,
			 uint64_t *subnet_prefix, int *isdm)
{
	struct srp_ib_user_mad		out_mad, in_mad;
	struct umad_sa_packet	       *out_sa_mad, *in_sa_mad;
	struct srp_sa_port_info_rec    *port_info;

	in_sa_mad = get_data_ptr(in_mad);
	out_sa_mad = get_data_ptr(out_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_PORT_INFO_REC, 0);

	out_sa_mad->comp_mask     = htobe64(1); /* LID */
	port_info                 = (void *) out_sa_mad->data;
	port_info->endport_lid	  = htobe16(dlid);

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	port_info = (void *) in_sa_mad->data;
	*subnet_prefix = be64toh(port_info->subnet_prefix);
	*isdm          = !!(be32toh(port_info->capability_mask) & SRP_IS_DM);

	return 0;
}

static int get_shared_pkeys(struct resources *res,
			    uint16_t dest_port_lid,
			    uint16_t *pkeys)
{
	struct umad_resources          *umad_res = res->umad_res;
	uint8_t                        *in_mad_buf;
	struct srp_ib_user_mad		out_mad;
	struct ib_user_mad	       *in_mad;
	struct umad_sa_packet	       *out_sa_mad, *in_sa_mad;
	struct ib_path_rec	       *path_rec;
	ssize_t len;
	int i, num_pkeys = 0;
	__be16 pkey;
	uint16_t local_port_lid = get_port_lid(res->ud_res->ib_ctx,
					       config->port_num, NULL);

	in_mad_buf = malloc(sizeof(struct ib_user_mad) +
			    node_table_response_size);
	if (!in_mad_buf)
		return -ENOMEM;

	in_mad = (void *)in_mad_buf;
	in_sa_mad = (void *)in_mad->data;
	out_sa_mad = get_data_ptr(out_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_PATH_REC, 0);

	/**
	 * Due to OpenSM bug (issue #335016) SM won't return
	 * table of all shared P_Keys, it will return only the first
	 * shared P_Key, So we send path_rec over each P_Key in the P_Key
	 * table. SM will return path record if P_Key is shared or else None.
	 * Once SM bug will be fixed, this loop should be removed.
	 **/
	for (i = 0; ; i++) {
		if (pkey_index_to_pkey(umad_res, i, &pkey))
			break;
		if (!pkey)
			continue;

		/* Mark components: DLID, SLID, PKEY */
		out_sa_mad->comp_mask = htobe64(1 << 4 | 1 << 5 | 1 << 13);
		path_rec = (struct ib_path_rec *)out_sa_mad->data;
		path_rec->slid = htobe16(local_port_lid);
		path_rec->dlid = htobe16(dest_port_lid);
		path_rec->pkey = pkey;

		len = send_and_get(umad_res->portid, umad_res->agent, &out_mad,
				   (struct srp_ib_user_mad *)in_mad,
				   node_table_response_size);
		if (len < 0)
			goto err;

		path_rec = (struct ib_path_rec *)in_sa_mad->data;
		pkeys[num_pkeys++] = be16toh(path_rec->pkey);
	}

	free(in_mad_buf);
	return num_pkeys;
err:
	free(in_mad_buf);
	return -1;
}

static int do_dm_port_list(struct resources *res)
{
	struct umad_resources 	       *umad_res = res->umad_res;
	uint8_t                        *in_mad_buf;
	struct srp_ib_user_mad		out_mad;
	struct ib_user_mad	       *in_mad;
	struct umad_sa_packet	       *out_sa_mad, *in_sa_mad;
	struct srp_sa_port_info_rec    *port_info;
	ssize_t len;
	int size;
	int i, j,num_pkeys;
	uint16_t pkeys[SRP_MAX_SHARED_PKEYS];
	uint64_t guid;

	in_mad_buf = malloc(sizeof(struct ib_user_mad) +
			    node_table_response_size);
	if (!in_mad_buf)
		return -ENOMEM;

	in_mad     = (void *) in_mad_buf;
	in_sa_mad  = (void *) in_mad->data;
	out_sa_mad = get_data_ptr(out_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_PORT_INFO_REC, SRP_SM_CAP_MASK_MATCH_ATTR_MOD);

	out_sa_mad->mad_hdr.method = UMAD_SA_METHOD_GET_TABLE;
	out_sa_mad->comp_mask      = htobe64(1 << 7); /* Capability mask */
	out_sa_mad->rmpp_hdr.rmpp_version = UMAD_RMPP_VERSION;
	out_sa_mad->rmpp_hdr.rmpp_type = 1;
	port_info		   = (void *) out_sa_mad->data;
	port_info->capability_mask = htobe32(SRP_IS_DM); /* IsDM */

	len = send_and_get(umad_res->portid, umad_res->agent, &out_mad,
			   (struct srp_ib_user_mad *) in_mad,
			   node_table_response_size);
	if (len < 0) {
		free(in_mad_buf);
		return len;
	}

	size = ib_get_attr_size(in_sa_mad->attr_offset);
	if (!size) {
		if (config->verbose) {
			printf("Query did not find any targets\n");
		}
		free(in_mad_buf);
		return 0;
	}

	for (i = 0; (i + 1) * size <= len - MAD_RMPP_HDR_SIZE; ++i) {
		port_info = (void *) in_sa_mad->data + i * size;
		if (get_node(umad_res, be16toh(port_info->endport_lid), &guid))
			continue;

		num_pkeys = get_shared_pkeys(res, be16toh(port_info->endport_lid),
					     pkeys);
		if (num_pkeys < 0) {
			pr_err("failed to get shared P_Keys with LID %#x\n",
			       be16toh(port_info->endport_lid));
			free(in_mad_buf);
			return num_pkeys;
		}

		for (j = 0; j < num_pkeys; ++j)
			do_port(res, pkeys[j], be16toh(port_info->endport_lid),
				be64toh(port_info->subnet_prefix), guid);
	}

	free(in_mad_buf);
	return 0;
}

void handle_port(struct resources *res, uint16_t pkey, uint16_t lid, uint64_t h_guid)
{
	struct umad_resources *umad_res = res->umad_res;
	uint64_t subnet_prefix;
	int isdm;

	pr_debug("enter handle_port for lid %#x\n", lid);
	if (get_port_info(umad_res, lid, &subnet_prefix, &isdm))
		return;

	if (!isdm)
		return;

	do_port(res, pkey, lid, subnet_prefix, h_guid);
}


static int do_full_port_list(struct resources *res)
{
	struct umad_resources 	       *umad_res = res->umad_res;
	uint8_t                        *in_mad_buf;
	struct srp_ib_user_mad		out_mad;
	struct ib_user_mad	       *in_mad;
	struct umad_sa_packet	       *out_sa_mad, *in_sa_mad;
	struct srp_sa_node_rec	       *node;
	ssize_t len;
	int size;
	int i, j, num_pkeys;
	uint16_t pkeys[SRP_MAX_SHARED_PKEYS];

	in_mad_buf = malloc(sizeof(struct ib_user_mad) +
			    node_table_response_size);
	if (!in_mad_buf)
		return -ENOMEM;

	in_mad     = (void *) in_mad_buf;
	in_sa_mad  = (void *) in_mad->data;
	out_sa_mad = get_data_ptr(out_mad);

	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_NODE_REC, 0);

	out_sa_mad->mad_hdr.method = UMAD_SA_METHOD_GET_TABLE;
	out_sa_mad->comp_mask     = 0; /* Get all end ports */
	out_sa_mad->rmpp_hdr.rmpp_version = UMAD_RMPP_VERSION;
	out_sa_mad->rmpp_hdr.rmpp_type = 1;

	len = send_and_get(umad_res->portid, umad_res->agent, &out_mad,
			   (struct srp_ib_user_mad *) in_mad,
			   node_table_response_size);
	if (len < 0) {
		free(in_mad_buf);
		return len;
	}

	size = be16toh(in_sa_mad->attr_offset) * 8;

	for (i = 0; (i + 1) * size <= len - MAD_RMPP_HDR_SIZE; ++i) {
		node = (void *) in_sa_mad->data + i * size;

		num_pkeys = get_shared_pkeys(res, be16toh(node->lid),
					     pkeys);
		if (num_pkeys < 0) {
			pr_err("failed to get shared P_Keys with LID %#x\n",
			       be16toh(node->lid));
			free(in_mad_buf);
			return num_pkeys;
		}

		for (j = 0; j < num_pkeys; ++j)
			(void) handle_port(res, pkeys[j], be16toh(node->lid),
					   be64toh(node->port_guid));
	}

	free(in_mad_buf);
	return 0;
}

struct config_t *config;

static void print_config(struct config_t *conf)
{
	printf(" configuration report\n");
	printf(" ------------------------------------------------\n");
	printf(" Current pid                		: %u\n", getpid());
	printf(" Device name                		: \"%s\"\n", conf->dev_name);
	printf(" IB port                    		: %u\n", conf->port_num);
	printf(" Mad Retries                		: %d\n", conf->mad_retries);
	printf(" Number of outstanding WR   		: %u\n", conf->num_of_oust);
	printf(" Mad timeout (msec)	     		: %u\n", conf->timeout);
	printf(" Prints add target command  		: %d\n", conf->cmd);
 	printf(" Executes add target command		: %d\n", conf->execute);
 	printf(" Print also connected targets 		: %d\n", conf->all);
 	printf(" Report current targets and stop 	: %d\n", conf->once);
	if (conf->rules_file)
		printf(" Reads rules from 			: %s\n", conf->rules_file);
	if (conf->print_initiator_ext)
		printf(" Print initiator_ext\n");
	else
		printf(" Do not print initiator_ext\n");
	if (conf->recalc_time)
		printf(" Performs full target rescan every %d seconds\n", conf->recalc_time);
	else
		printf(" No full target rescan\n");
	if (conf->retry_timeout)
		printf(" Retries to connect to existing target after %d seconds\n", conf->retry_timeout);
	else
		printf(" Do not retry to connect to existing targets\n");
	printf(" ------------------------------------------------\n");
}

static char *copy_till_comma(char *d, char *s, int len, int base)
{
	int i=0;

	while (strchr(", \t\n", *s) == NULL) {
		if (i == len)
			return NULL;
		if ((base == 16 && isxdigit(*s)) || (base == 10 && isdigit(*s))) {
			*d=*s;
			++d;
			++s;
			++i;
		} else
			return NULL;
	}
	*d='\0';

	if (*s == '\n')
		return s;

	++s;
	return s;
}

static char *parse_main_option(struct rule *rule, char *ptr)
{
	struct option_info {
		const char *name;
		size_t offset;
		size_t len;
		int base;
	};
#define OPTION_INFO(n, base) { #n "=", offsetof(struct rule, n),	\
			sizeof(((struct rule *)NULL)->n), base}
	static const struct option_info opt_info[] = {
		OPTION_INFO(id_ext, 16),
		OPTION_INFO(ioc_guid, 16),
		OPTION_INFO(dgid, 16),
		OPTION_INFO(service_id, 16),
		OPTION_INFO(pkey, 16),
	};
	int i, optnamelen;
	char *ptr2 = NULL;

	for (i = 0; i < sizeof(opt_info) / sizeof(opt_info[0]); i++) {
		optnamelen = strlen(opt_info[i].name);
		if (strncmp(ptr, opt_info[i].name, optnamelen) == 0) {
			ptr2 = copy_till_comma((char *)rule
					       + opt_info[i].offset,
					       ptr + optnamelen,
					       opt_info[i].len - 1,
					       opt_info[i].base);
			break;
		}
	}

	return ptr2;
}

/*
 * Return values:
 *  -1 if the output buffer is not large enough.
 *   0 if an unsupported option has been encountered.
 * > 0 if parsing succeeded.
 */
static int parse_other_option(struct rule *rule, char *ptr)
{
	static const char *const opt[] = {
		"allow_ext_sg=",
		"ch_count=",
		"cmd_sg_entries=",
		"comp_vector=",
		"max_cmd_per_lun=",
		"max_sect=",
		"queue_size=",
		"sg_tablesize=",
		"tl_retry_count=",
	};

	char *ptr2 = NULL, *optr, option[17];
	int i, optnamelen, len, left;

	optr = rule->options;
	left = sizeof(rule->options);
	len = strlen(optr);
	optr += len;
	left -= len;
	for (i = 0; i < sizeof(opt)/sizeof(opt[0]); ++i) {
		optnamelen = strlen(opt[i]);
		if (strncmp(ptr, opt[i], optnamelen) != 0)
			continue;
		ptr2 = copy_till_comma(option, ptr + optnamelen,
				       sizeof(option) - 1, 10);
		if (!ptr2)
			return -1;
		len = snprintf(optr, left, ",%s%s", opt[i], option);
		optr += len;
		left -= len;
		if (left <= 0)
			return -1;
		break;
	}
	return ptr2 ? ptr2 - ptr : 0;
}

static int get_rules_file(struct config_t *conf)
{
	int line_number = 1, len, line_number_for_output, ret = -1;
	char line[255];
	char *ptr, *ptr2;
	struct rule *rule;
	FILE *infile = fopen(conf->rules_file, "r");

	if (infile == NULL) {
		pr_debug("Could not find rules file %s, going with default\n",
			 conf->rules_file);
		return 0;
	}

	while (fgets(line, sizeof(line), infile) != NULL) {
		if (line[0] != '#' && line[0] != '\n')
			line_number++;
	}

	if (fseek(infile, 0L, SEEK_SET) != 0) {
		pr_err("internal error while seeking %s\n", conf->rules_file);
		goto out;
	}

	conf->rules = malloc(sizeof(struct rule) * line_number);

	rule = &conf->rules[0] - 1;
	line_number_for_output = 0;
	while (fgets(line, sizeof(line), infile) != NULL) {
		line_number_for_output++;
		if (line[0] == '#' || line[0] == '\n')
			continue;

		rule++;
		switch (line[0]) {
		case 'a':
		case 'A':
			rule->allow = 1;
			break;
		case 'd':
		case 'D':
			rule->allow = 0;
			break;
		default:
			pr_err("Bad syntax in rules file %s line %d:"
			       " line should start with 'a' or 'd'\n",
			       conf->rules_file, line_number_for_output);
			goto out;
		}

		rule->id_ext[0] = '\0';
		rule->ioc_guid[0] = '\0';
		rule->dgid[0] = '\0';
		rule->service_id[0] = '\0';
		rule->pkey[0] = '\0';
		rule->options[0] = '\0';

		ptr = &line[1];
		while (*ptr == ' ' || *ptr == '\t')
			ptr++;

		while (*ptr != '\n') {
			ptr2 = parse_main_option(rule, ptr);
			if (!ptr2 && rule->allow) {
				len = parse_other_option(rule, ptr);
				if (len < 0) {
					pr_err("Buffer overflow triggered by"
					       " rules file %s line %d\n",
					       conf->rules_file,
					       line_number_for_output);
					goto out;
				}
				ptr2 = len ? ptr + len : NULL;
			}

			if (ptr2 == NULL) {
				pr_err("Bad syntax in rules file %s line %d\n",
				       conf->rules_file, line_number_for_output);
				goto out;
			}
			ptr = ptr2;

			while (*ptr == ' ' || *ptr == '\t')
				ptr++;
		}
	}
	rule++;
	rule->id_ext[0] = '\0';
	rule->ioc_guid[0] = '\0';
	rule->dgid[0] = '\0';
	rule->service_id[0] = '\0';
	rule->pkey[0] = '\0';
	rule->options[0] = '\0';
	rule->allow = 1;
	ret = 0;

out:
	fclose(infile);

	return ret;
}

static int set_conf_dev_and_port(char *umad_dev, struct config_t *conf)
{
	int ret;

	if (umad_dev) {
		char *ibport;

		ret = translate_umad_to_ibdev_and_port(umad_dev,
						       &conf->dev_name,
						       &ibport);
		if (ret) {
			pr_err("Fail to translate umad to ibdev and port\n");
			goto out;
		}
		conf->port_num = atoi(ibport);
		if (conf->port_num == 0) {
			pr_err("Bad port number %s\n", ibport);
			ret = -1;
		}
		free(ibport);
	} else {
		umad_ca_t ca;
		umad_port_t port;

		ret = umad_get_ca(NULL, &ca);
		if (ret) {
			pr_err("Failed to get default CA\n");
			goto out;
		}

		ret = umad_get_port(ca.ca_name, 0, &port);
		if (ret) {
			pr_err("Failed to get default port for CA %s\n",
			       ca.ca_name);
			umad_release_ca(&ca);
			goto out;
		}
		conf->dev_name = strdup(ca.ca_name);
		conf->port_num = port.portnum;
		umad_release_port(&port);
		umad_release_ca(&ca);
		pr_debug("Using device %s port %d\n", conf->dev_name,
			 conf->port_num);
	}
out:
	return ret;
}

static const struct option long_opts[] = {
	{ "systemd",        0, NULL, 'S' },
	{}
};
static const char short_opts[] = "caveod:i:j:p:t:r:R:T:l:Vhnf:";

/* Check if the --systemd options was passed in very early so we can setup
 * logging properly.
 */
static bool is_systemd(int argc, char *argv[])
{
	while (1) {
		int c;

		c = getopt_long(argc, argv, short_opts, long_opts, NULL);
		if (c == -1)
			break;
		if (c == 'S')
			return true;

	}
	return false;
}

static int get_config(struct config_t *conf, int argc, char *argv[])
{
	/* set defaults */
	char* umad_dev = NULL;
	int ret;

	conf->port_num			= 1;
	conf->num_of_oust		= 10;
	conf->dev_name	 		= NULL;
	conf->cmd	 		= 0;
	conf->once	 		= 0;
	conf->execute	 		= 0;
	conf->all	 		= 0;
	conf->verbose	 		= 0;
	conf->debug_verbose    		= 0;
	conf->timeout	 		= 5000;
	conf->mad_retries 		= 3;
	conf->recalc_time 		= 0;
	conf->retry_timeout 		= 20;
	conf->add_target_file  		= NULL;
	conf->print_initiator_ext	= 0;
	conf->rules_file		= SRP_DAEMON_CONFIG_FILE;
	conf->rules			= NULL;
	conf->tl_retry_count		= 0;

	optind = 1;
	while (1) {
		int c;

		c = getopt_long(argc, argv, short_opts, long_opts, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'd':
			umad_dev = optarg;
			break;
		case 'i':
			conf->dev_name = strdup(optarg);
			if (!conf->dev_name) {
				pr_err("Fail to alloc space for dev_name\n");
				return -ENOMEM;
			}
			break;
		case 'p':
			conf->port_num = atoi(optarg);
			if (conf->port_num == 0) {
				pr_err("Bad port number %s\n", optarg);
				return -1;
			}
			break;
		case 'j': {
			char dev[32];
			int port_num;

			if (sscanf(optarg, "%31[^:]:%d", dev, &port_num) != 2) {
				pr_err("Bad dev:port specification %s\n",
				       optarg);
				return -1;
			}
			conf->dev_name = strdup(dev);
			conf->port_num = port_num;
			}
			break;
		case 'c':
			++conf->cmd;
			break;
		case 'o':
			++conf->once;
			break;
		case 'a':
			++conf->all;
			break;
		case 'e':
			++conf->execute;
			break;
		case 'v':
			++conf->verbose;
			break;
		case 'V':
			++conf->debug_verbose;
			break;
		case 'n':
			++conf->print_initiator_ext;
			break;
		case 't':
			conf->timeout = atoi(optarg);
			if (conf->timeout == 0) {
				pr_err("Bad timeout - %s\n", optarg);
				return -1;
			}
			break;
		case 'r':
			conf->mad_retries = atoi(optarg);
			if (conf->mad_retries == 0) {
				pr_err("Bad number of retries - %s\n", optarg);
				return -1;
			}
			break;
		case 'R':
			conf->recalc_time = atoi(optarg);
			if (conf->recalc_time == 0) {
				pr_err("Bad Rescan time window - %s\n", optarg);
				return -1;
			}
			break;
		case 'T':
			conf->retry_timeout = atoi(optarg);
			if (conf->retry_timeout == 0 && strcmp(optarg, "0")) {
				pr_err("Bad retry Timeout value- %s.\n", optarg);
				return -1;
			}
			break;
		case 'f':
			conf->rules_file = optarg;
			break;
		case 'l':
			conf->tl_retry_count = atoi(optarg);
			if (conf->tl_retry_count < 2 ||
			    conf->tl_retry_count > 7) {
				pr_err("Bad tl_retry_count argument (%d), "
				       "must be 2 <= tl_retry_count <= 7\n",
				       conf->tl_retry_count);
				return -1;
			}
			break;
		case 'S':
			break;
		case 'h':
		default:
			usage(argv[0]);
			return -1;
		}
	}

	initialize_sysfs();

	if (conf->dev_name == NULL) {
		ret = set_conf_dev_and_port(umad_dev, conf);
	        if (ret) {
	                pr_err("Failed to build config\n");
	                return ret;
	        }
	}
	ret = asprintf(&conf->add_target_file,
		       "%s/class/infiniband_srp/srp-%s-%d/add_target", sysfs_path,
		       conf->dev_name, conf->port_num);
	if (ret < 0) {
		pr_err("error while allocating add_target\n");
		return ret;
	}

	if (get_rules_file(conf))
		return -1;

	return 0;
}

static void free_config(struct config_t *conf)
{
	free(conf->dev_name);
	free(conf->add_target_file);
	free(conf->rules);
	free(conf);
}

static void umad_resources_init(struct umad_resources *umad_res)
{
	umad_res->portid = -1;
	umad_res->agent = -1;
	umad_res->port_sysfs_path = NULL;
}

static void umad_resources_destroy(struct umad_resources *umad_res)
{
	if (umad_res->port_sysfs_path)
		free(umad_res->port_sysfs_path);

	if (umad_res->portid >= 0) {
		if (umad_res->agent >= 0)
			umad_unregister(umad_res->portid, umad_res->agent);
		umad_close_port(umad_res->portid);
	}

	umad_done();
}

static int check_link_layer(const char *port_sysfs_path)
{
	const char expected_link_layer[] = "InfiniBand";
	char link_layer[sizeof(expected_link_layer)];
	int ret;

	ret = srpd_sys_read_string(port_sysfs_path, "link_layer", link_layer,
				   sizeof(link_layer));
	if (ret < 0) {
		pr_err("Couldn't read link layer\n");
		return ret;
	}

	if (strcmp(link_layer, expected_link_layer)) {
		pr_err("Unsupported link layer %s\n", link_layer);
		return -EINVAL;
	}

	return 0;
}

static int umad_resources_create(struct umad_resources *umad_res)
{

	int ret;

	ret = asprintf(&umad_res->port_sysfs_path, "%s/class/infiniband/%s/ports/%d",
		       sysfs_path, config->dev_name, config->port_num);

	if (ret < 0) {
		umad_res->port_sysfs_path = NULL;
		return -ENOMEM;
	}

	ret = check_link_layer(umad_res->port_sysfs_path);
	if (ret)
		return ret;

	umad_res->portid = umad_open_port(config->dev_name, config->port_num);
	if (umad_res->portid < 0) {
		pr_err("umad_open_port failed for device %s port %d\n",
		       config->dev_name, config->port_num);
		return -ENXIO;
	}

	umad_res->agent = umad_register(umad_res->portid, UMAD_CLASS_SUBN_ADM,
					   UMAD_SA_CLASS_VERSION,
					   UMAD_RMPP_VERSION, NULL);
	if (umad_res->agent < 0) {
		pr_err("umad_register failed\n");
		return umad_res->agent;
	}

	return 0;
}

static void *run_thread_retry_to_connect(void *res_in)
{
	struct resources *res = (struct resources *)res_in;
	struct target_details *target;
	time_t sleep_time;

	pthread_mutex_lock(&res->sync_res->retry_mutex);
	while (!res->sync_res->stop_threads) {
		if (retry_list_is_empty(res->sync_res))
			pthread_cond_wait(&res->sync_res->retry_cond,
					  &res->sync_res->retry_mutex);
		while (!res->sync_res->stop_threads &&
		       (target = pop_from_retry_list(res->sync_res)) != NULL) {
			pthread_mutex_unlock(&res->sync_res->retry_mutex);
			sleep_time = target->retry_time - time(NULL);

			if (sleep_time > 0)
				srp_sleep(sleep_time, 0);

			add_non_exist_target(target);
			free(target);
			pthread_mutex_lock(&res->sync_res->retry_mutex);
		}
	}
	/* empty retry_list */
	while ((target = pop_from_retry_list(res->sync_res)))
		free(target);
	pthread_mutex_unlock(&res->sync_res->retry_mutex);

	pr_debug("retry_to_connect thread ended\n");

	pthread_exit(NULL);
}

static void free_res(struct resources *res)
{
	void *status;

	if (!res)
		return;

	if (res->sync_res) {
		pthread_mutex_lock(&res->sync_res->retry_mutex);
		res->sync_res->stop_threads = 1;
		pthread_cond_signal(&res->sync_res->retry_cond);
		pthread_mutex_unlock(&res->sync_res->retry_mutex);
	}

	if (res->ud_res)
		modify_qp_to_err(res->ud_res->qp);

	if (res->reconnect_thread) {
		pthread_kill(res->reconnect_thread, SIGINT);
		pthread_join(res->reconnect_thread, &status);
	}
	if (res->async_ev_thread) {
		pthread_kill(res->async_ev_thread, SIGINT);
		pthread_join(res->async_ev_thread, &status);
	}
	if (res->trap_thread) {
		pthread_kill(res->trap_thread, SIGINT);
		pthread_join(res->trap_thread, &status);
	}
	if (res->sync_res)
		sync_resources_cleanup(res->sync_res);
	if (res->ud_res)
		ud_resources_destroy(res->ud_res);
	if (res->umad_res)
		umad_resources_destroy(res->umad_res);
	free(res);
}

static struct resources *alloc_res(void)
{
	struct all_resources {
		struct resources	res;
		struct ud_resources	ud_res;
		struct umad_resources	umad_res;
		struct sync_resources	sync_res;
	};

	struct all_resources *res;
	int ret;

	res = calloc(1, sizeof(*res));
	if (!res)
		goto err;

	umad_resources_init(&res->umad_res);
	ret = umad_resources_create(&res->umad_res);
	if (ret)
		goto err;
	res->res.umad_res = &res->umad_res;

	ud_resources_init(&res->ud_res);
	ret = ud_resources_create(&res->ud_res);
	if (ret)
		goto err;
	res->res.ud_res = &res->ud_res;
	res->umad_res.ib_ctx = res->ud_res.ib_ctx;

	ret = sync_resources_init(&res->sync_res);
	if (ret)
		goto err;
	res->res.sync_res = &res->sync_res;

	if (!config->once) {
		ret = pthread_create(&res->res.trap_thread, NULL,
				     run_thread_get_trap_notices, &res->res);
		if (ret)
			goto err;

		ret = pthread_create(&res->res.async_ev_thread, NULL,
				     run_thread_listen_to_events, &res->res);
		if (ret)
			goto err;
	}

	if (config->retry_timeout && !config->once) {
		ret = pthread_create(&res->res.reconnect_thread, NULL,
				     run_thread_retry_to_connect, &res->res);
		if (ret)
			goto err;
	}

	return &res->res;
err:
	if (res)
		free_res(&res->res);
	return NULL;
}

/* *c = *a - *b. See also the BSD macro timersub(). */
static void ts_sub(const struct timespec *a, const struct timespec *b,
		   struct timespec *res)
{
	res->tv_sec = a->tv_sec - b->tv_sec;
	res->tv_nsec = a->tv_nsec - b->tv_nsec;
	if (res->tv_nsec < 0) {
		res->tv_sec--;
		res->tv_nsec += 1000 * 1000 * 1000;
	}
}

static void cleanup_wakeup_fd(void)
{
	struct sigaction sa = {};

	sigemptyset(&sa.sa_mask);
	sa.sa_handler = SIG_DFL;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SRP_CATAS_ERR, &sa, NULL);

	close(wakeup_pipe[1]);
	close(wakeup_pipe[0]);
	wakeup_pipe[0] = -1;
	wakeup_pipe[1] = -1;
}

static int setup_wakeup_fd(void)
{
	struct sigaction sa = {};
	int ret;

	ret = pipe2(wakeup_pipe, O_NONBLOCK | O_CLOEXEC);
	if (ret < 0) {
		pr_err("could not create pipe\n");
		return -1;
	}

	sigemptyset(&sa.sa_mask);
	sa.sa_handler = signal_handler;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SRP_CATAS_ERR, &sa, NULL);
	return 0;
}

static int ibsrpdm(int argc, char *argv[])
{
	char* umad_dev = NULL;
	struct resources *res;
	int ret;

	s_log_dest = log_to_stderr;

	config = calloc(1, sizeof(*config));
	config->num_of_oust = 10;
	config->timeout = 5000;
	config->mad_retries = 3;
	config->all = 1;
	config->once = 1;

	while (1) {
		int c;

		c = getopt(argc, argv, "cd:h:v");
		if (c == -1)
			break;

		switch (c) {
		case 'c':
			++config->cmd;
			break;
		case 'd':
			umad_dev = optarg;
			break;
		case 'v':
			++config->debug_verbose;
			break;
		case 'h':
		default:
			fprintf(stderr,
				"Usage: %s [-vc] [-d <umad device>]\n",
				argv[0]);
			return 1;
		}
	}

	initialize_sysfs();

	ret = set_conf_dev_and_port(umad_dev, config);
	if (ret) {
		pr_err("Failed to build config\n");
		goto out;
	}

	ret = umad_init();
	if (ret != 0)
		goto out;

	res = alloc_res();
	if (!res) {
		ret = 1;
		pr_err("Resource allocation failed\n");
		goto umad_done;
	}
	ret = recalc(res);
	if (ret)
		pr_err("Querying SRP targets failed\n");

	free_res(res);
umad_done:
	umad_done();
out:
	free_config(config);

	return ret;
}

int main(int argc, char *argv[])
{
	int			ret;
	struct resources       *res;
	uint16_t                lid, sm_lid;
	uint16_t 		pkey;
	union umad_gid 		gid;
	struct target_details  *target;
	int			subscribed;
	int			lockfd = -1;
	int			received_signal = 0;
	bool                    systemd;

#ifndef __CHECKER__
	/*
	 * Hide these checks for sparse because these checks fail with
	 * older versions of sparse.
	 */
	BUILD_ASSERT(sizeof(struct ib_path_rec) == 64);
	BUILD_ASSERT(sizeof(struct ib_inform_info) == 36);
	BUILD_ASSERT(sizeof(struct ib_mad_notice_attr) == 80);
	BUILD_ASSERT(offsetof(struct ib_mad_notice_attr, generic.trap_num) ==
		     4);
	BUILD_ASSERT(offsetof(struct ib_mad_notice_attr, vend.dev_id) == 4);
	BUILD_ASSERT(offsetof(struct ib_mad_notice_attr, ntc_64_67.gid) == 16);
	BUILD_ASSERT(offsetof(struct ib_mad_notice_attr,
			      ntc_144.new_cap_mask) == 16);
#endif
	BUILD_ASSERT(sizeof(struct srp_sa_node_rec) == 108);
	BUILD_ASSERT(sizeof(struct srp_sa_port_info_rec) == 58);
	BUILD_ASSERT(sizeof(struct srp_dm_iou_info) == 132);
	BUILD_ASSERT(sizeof(struct srp_dm_ioc_prof) == 128);

	if (strcmp(argv[0] + max_t(int, 0, strlen(argv[0]) - strlen("ibsrpdm")),
		   "ibsrpdm") == 0) {
		ret = ibsrpdm(argc, argv);
		goto out;
	}

	systemd = is_systemd(argc, argv);

	if (systemd)
		openlog(NULL, LOG_NDELAY | LOG_CONS | LOG_PID, LOG_DAEMON);
	else
		openlog("srp_daemon", LOG_PID, LOG_DAEMON);

	config = calloc(1, sizeof(*config));
	if (!config) {
 		pr_err("out of memory\n");
		ret = ENOMEM;
		goto close_log;
	}

	if (get_config(config, argc, argv)) {
		ret = EINVAL;
		goto free_config;
	}

	if (config->verbose)
		print_config(config);

	if (!config->once) {
		lockfd = check_process_uniqueness(config);
		if (lockfd < 0) {
			ret = EPERM;
			goto free_config;
		}
	}

	ret = setup_wakeup_fd();
	if (ret)
		goto cleanup_wakeup;

catas_start:
	subscribed = 0;

	ret = umad_init();
	if (ret < 0) {
		pr_err("umad_init failed\n");
		goto close_lockfd;
	}

	res = alloc_res();
	if (!res && received_signal == SRP_CATAS_ERR)
		pr_err("Device has not yet recovered from catas error\n");
	if (!res)
		goto clean_umad;

	/*
	 * alloc_res() fails while the HCA is recovering from a catastrophic
	 * error. Clear 'received_signal' after alloc_res() has succeeded to
	 * finish the alloc_res() retry loop.
	 */
	if (received_signal == SRP_CATAS_ERR) {
		pr_err("Device recovered from catastrophic error\n");
		received_signal = 0;
	}

	if (config->once) {
		ret = recalc(res);
		goto free_res;
	}

	while (received_signal == 0) {
		pthread_mutex_lock(&res->sync_res->mutex);
		if (__rescan_scheduled(res->sync_res)) {
			uint16_t port_lid;

			pthread_mutex_unlock(&res->sync_res->mutex);

			pr_debug("Starting a recalculation\n");
			port_lid = get_port_lid(res->ud_res->ib_ctx,
						config->port_num, &sm_lid);
			if (port_lid > 0 && port_lid < 0xc000 &&
			    (port_lid != res->ud_res->port_attr.lid ||
			     sm_lid != res->ud_res->port_attr.sm_lid)) {

				if (res->ud_res->ah) {
					ibv_destroy_ah(res->ud_res->ah);
					res->ud_res->ah = NULL;
				}
				ret = create_ah(res->ud_res);
				if (ret) {
					received_signal = get_received_signal(10, 0);
					goto kill_threads;
				}
			}

			if (res->ud_res->ah) {
				if (register_to_traps(res, 1))
					pr_err("Fail to register to traps, maybe there "
					       "is no SM running on fabric or IB port is down\n");
				else
					subscribed = 1;
			}

			clear_traps_list(res->sync_res);
			schedule_rescan(res->sync_res, config->recalc_time ?
					config->recalc_time : -1);

			/* empty retry_list */
			pthread_mutex_lock(&res->sync_res->retry_mutex);
			while ((target = pop_from_retry_list(res->sync_res)))
				free(target);
			pthread_mutex_unlock(&res->sync_res->retry_mutex);

			recalc(res);
		} else if (pop_from_list(res->sync_res, &lid, &gid, &pkey)) {
			pthread_mutex_unlock(&res->sync_res->mutex);
			if (lid) {
				uint64_t guid;
				ret = get_node(res->umad_res, lid, &guid);
				if (ret)
					/* unexpected error - do a full rescan */
					schedule_rescan(res->sync_res, 0);
				else
					handle_port(res, pkey, lid, guid);
			} else {
				ret = get_lid(res->umad_res, &gid, &lid);
				if (ret < 0)
					/* unexpected error - do a full rescan */
					schedule_rescan(res->sync_res, 0);
				else {
					pr_debug("lid is %#x\n", lid);

					srp_sleep(0, 100);
					handle_port(res, pkey, lid,
						    be64toh(ib_gid_get_guid(&gid)));
				}
			}
		} else {
			static const struct timespec zero;
			struct timespec now, delta;
			struct timespec recalc = {
				.tv_sec = config->recalc_time
			};
			struct timeval timeout;

			clock_gettime(CLOCK_MONOTONIC, &now);
			ts_sub(&res->sync_res->next_recalc_time, &now, &delta);
			pthread_mutex_unlock(&res->sync_res->mutex);

			if (ts_cmp(&zero, &delta, <=) &&
			    ts_cmp(&delta, &recalc, <))
				recalc = delta;
			timeout.tv_sec = recalc.tv_sec;
			timeout.tv_usec = recalc.tv_nsec / 1000 + 1;

			received_signal = get_received_signal(timeout.tv_sec,
							timeout.tv_usec) ? :
				received_signal;
		}
	}

	ret = 0;

kill_threads:
	switch (received_signal) {
	case SIGINT:
		pr_err("Got SIGINT\n");
		break;
	case SIGTERM:
		pr_err("Got SIGTERM\n");
		break;
	case SRP_CATAS_ERR:
		pr_err("Got SIG SRP_CATAS_ERR\n");
		break;
	case 0:
		break;
	default:
		pr_err("Got SIG???\n");
		break;
	}

	if (subscribed && received_signal != SRP_CATAS_ERR) {
		pr_err("Deregistering traps ...\n");
		register_to_traps(res, 0);
		pr_err("Finished trap deregistration.\n");
	}
free_res:
	free_res(res);
	/* Discard the SIGINT triggered by the free_res() implementation. */
	get_received_signal(0, 0);
clean_umad:
	umad_done();
	if (received_signal == SRP_CATAS_ERR) {
		/*
		 * Device got a catastrophic error. Let's wait a grace
		 * period and try to probe the device by attempting to
		 * allocate IB resources. Once it recovers, we will
		 * start all over again.
		 */
		received_signal = get_received_signal(10, 0) ? :
			received_signal;
		if (received_signal == SRP_CATAS_ERR)
			goto catas_start;
	}
close_lockfd:
	if (lockfd >= 0)
		close(lockfd);
cleanup_wakeup:
	cleanup_wakeup_fd();
free_config:
	free_config(config);
close_log:
	closelog();
out:
	exit(ret ? 1 : 0);
}

static int recalc(struct resources *res)
{
	struct umad_resources *umad_res = res->umad_res;
	int  mask_match;
	char val[7];
	int ret;

	ret = srpd_sys_read_string(umad_res->port_sysfs_path, "sm_lid", val, sizeof val);
	if (ret < 0) {
		pr_err("Couldn't read SM LID\n");
		return ret;
	}

	umad_res->sm_lid = strtol(val, NULL, 0);
	if (umad_res->sm_lid == 0) {
		pr_err("SM LID is 0, maybe no SM is running\n");
		return -1;
	}

	ret = check_sm_cap(umad_res, &mask_match);
	if (ret < 0)
		return ret;

	if (mask_match) {
		pr_debug("Advanced SM, performing a capability query\n");
		ret = do_dm_port_list(res);
	} else {
		pr_debug("Old SM, performing a full node query\n");
		ret = do_full_port_list(res);
	}

	return ret;
}

static int get_lid(struct umad_resources *umad_res, union umad_gid *gid,
		   uint16_t *lid)
{
	struct srp_ib_user_mad		out_mad, in_mad;
	struct umad_sa_packet		*in_sa_mad  = get_data_ptr(in_mad);
	struct umad_sa_packet		*out_sa_mad = get_data_ptr(out_mad);
	struct ib_path_rec		*path_rec   = (struct ib_path_rec *) out_sa_mad->data;

	memset(&in_mad, 0, sizeof(in_mad));
	init_srp_sa_mad(&out_mad, umad_res->agent, umad_res->sm_lid,
		        UMAD_SA_ATTR_PATH_REC, 0);

	out_sa_mad->comp_mask = htobe64( 4 | 8 | 64 | 512 | 4096 );

	path_rec->sgid = *gid;
	path_rec->dgid = *gid;
	path_rec->reversible_numpath = 1;
	path_rec->hop_flow_raw = htobe32(1 << 31); /* rawtraffic=1 hoplimit = 0 */

	if (send_and_get(umad_res->portid, umad_res->agent, &out_mad, &in_mad, 0) < 0)
		return -1;

	path_rec = (struct ib_path_rec *) in_sa_mad->data;

	*lid = be16toh(path_rec->dlid);

	return 0;
}
