예제 #1
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * Process ESI requires a success response only
 */
static void
process_esi(int so, isns_pdu_t *esi)
{
	isns_rsp_t	*cmd;
	int		pl_len;

	if (isns_create_pdu(ISNS_ESI_RSP, 0, (isns_pdu_t **)&cmd) != 0) {
		return;
	}

	pl_len = esi->payload_len + ISNS_STATUS_SZ;
	if (pl_len > MAX_PDU_PAYLOAD_SZ) {
		syslog(LOG_ALERT, "process_esi: payload size exceeded");
		isns_free_pdu(cmd);
		return;
	}

	/* change the xid to the request xid */
	cmd->xid = htons(esi->xid);
	cmd->status = htonl(ISNS_RSP_SUCCESSFUL);

	/* copy original data */
	bcopy(esi->payload, cmd->data, esi->payload_len);
	cmd->pdu_len = htons(pl_len);

	if (isns_send(so, (isns_pdu_t *)cmd) < 0) {
		syslog(LOG_ALERT, "process_esi failed to isns_send");
	}

	isns_free_pdu(cmd);
}
예제 #2
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * SCNDereg
 */
static int
isns_scn_dereg(int so, char *node)
{
	isns_pdu_t	*cmd = NULL;
	isns_rsp_t	*rsp = NULL;
	uint32_t	flags = 0;
	int		ret = -1;

	queue_prt(mgmtq, Q_ISNS_DBG, "ISNS_SCN_DEREG");

	if (isns_create_pdu(ISNS_SCN_DEREG, flags, &cmd) != 0) {
		return (-1);
	}

	/* source attribute */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) == -1) {
		goto error;
	}

	/* message key attribute */
	/* iscsi initiator node name */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) != 0) {
		goto error;
	}

	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) == -1) {
		goto error;
	}

	if (isns_send(so, cmd) == -1) {
		syslog(LOG_ERR, "isns_scn_reg fails isns_send");
		goto error;
	}

	if (isns_recv(so, &rsp) == -1) {
		syslog(LOG_ERR, "isns_scn_reg fails isns_recv ");
		goto error;
	}

	/* process response */
	if (process_rsp(cmd, rsp) == 0) {
		ret = 0;
	}

error:
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	return (ret);
}
예제 #3
0
void
isns_process_connection_loss(struct isns_config_s *cfg_p)
{
	struct isns_trans_s *trans_p;
	struct isns_pdu_s *pdu_p, *free_pdu_p;


	DBG("isns_process_connection_loss: entered\n");

	if (cfg_p->curtask_p != NULL) {
		trans_p = cfg_p->curtask_p->var.send_pdu.trans_p;

		if (trans_p->disconnect_cnt == ISNS_MAX_DISCONNECTS_PER_TRANS) {
			isns_complete_trans(trans_p);
			isns_end_task(cfg_p->curtask_p);

			if (cfg_p->pdu_in_p != NULL) {
				isns_free_pdu(cfg_p->pdu_in_p);
				cfg_p->pdu_in_p = NULL;
			}
		} else {
			trans_p->disconnect_cnt++;

			if (trans_p->pdu_rsp_list != NULL) {
				pdu_p = trans_p->pdu_rsp_list;
				while (pdu_p != NULL) {
					free_pdu_p = pdu_p;
					pdu_p = pdu_p->next;
					isns_free_pdu(free_pdu_p);
				}
			}

			isns_taskq_insert_head(cfg_p, cfg_p->curtask_p);
			cfg_p->curtask_p = NULL;

			isns_issue_cmd(cfg_p, ISNS_CMD_PROCESS_TASKQ);
		}
	}	
}
예제 #4
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * DevAttrDereg
 */
static int
isns_dev_attr_dereg(int so, char *node)
{
	isns_pdu_t	*cmd = NULL;
	isns_rsp_t	*rsp = NULL;
	uint32_t	flags = 0;
	int		ret = -1;

	queue_prt(mgmtq, Q_ISNS_DBG, "ISNS_DEV_ATTR_DEREG");

	if (isns_create_pdu(ISNS_DEV_DEREG, flags, &cmd) != 0) {
		return (-1);
	}

	/* add source attribute */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) != 0) {
		goto error;
	}

	/* add delimiter */
	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) != 0) {
		goto error;
	}

	/* add operation attributes */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) != 0) {
		goto error;
	}

	/* send pdu */
	if (isns_send(so, cmd) == -1) {
		syslog(LOG_ERR, "isns_dev_attr_dereg fails isns_send");
		goto error;
	}

	/* get isns response */
	if (isns_recv(so, &rsp) == -1) {
		syslog(LOG_ERR, "isns_dev_attr_dereg fails isns_recv ");
		goto error;
	}

	/* process response */
	if (process_rsp(cmd, rsp) == 0) {
		/*
		 * Keep the num_reg to a non-negative number.
		 * num_reg is used to keep track of whether there was
		 * any registration occurred or not. Deregstration should
		 * be followed by registration but in case dereg occurs
		 * and somehow it is succeeded keeping num_reg to 0 prevent
		 * any negative effect on subsequent registration.
		 */
		if (num_reg > 0) num_reg--;
		ret = 0;
	}

error:
	/* Free all resouces here */
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	return (ret);
}
예제 #5
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * esi_scn_thr() is the thread creates an end point to receive and process
 * ESI & SCN messages.  This thread is created when isns_access is enabled
 * and for the duration of the iscsi daemon
 */
static void *
esi_scn_thr(void *arg)
{
	struct sockaddr		sa, *ai;
	struct sockaddr_in	sin;
	struct sockaddr_in6	sin6;
	int			so, fd, pf;
	socklen_t		len;
	char			strport[NI_MAXSERV];
	isns_pdu_t		*scn = NULL;
	struct timeval timeout;
	fd_set fdset;
	int socket_ready = 0;

	pf = get_addr_family(isns_args.entity);
	if (pf == PF_INET) {
		bzero(&sin, sizeof (sin));
		sin.sin_family = PF_INET;
		sin.sin_port = htons(0);
		sin.sin_addr.s_addr = INADDR_ANY;
		ai = (struct sockaddr *)&sin;
		len = sizeof (sin);
	} else if (pf == PF_INET6) {
		bzero(&sin6, sizeof (sin6));
		sin6.sin6_family = PF_INET6;
		sin6.sin6_port = htons(0);
		sin6.sin6_addr = in6addr_any;
		ai = (struct sockaddr *)&sin6;
		len = sizeof (sin6);
	} else {
		syslog(LOG_ERR, "Bad address family. Exit esi_scn_thr");
		return (NULL);
	}

	/*
	 * create and bind SCN socket
	 * save the scn port info
	 */
	if ((so = socket(pf, SOCK_STREAM, 0)) == -1) {
		syslog(LOG_ALERT, "create isns socket failed");
		return (NULL);
	}

	(void) setsockopt(so, SOL_SOCKET, SO_REUSEADDR, 0, 0);

	if (bind(so, ai, len) < 0) {
		syslog(LOG_ALERT, "esi_scn_thr: bind failed");
		(void) close(so);
		return (NULL);
	}

	/* get scn port info */
	len = sizeof (sa);
	if (getsockname(so, &sa, &len) < 0) {
		syslog(LOG_ALERT, "isns getsockname failed");
		(void) close(so);
		return (NULL);
	}
	if (getnameinfo(&sa, len, NULL, 0, strport, NI_MAXSERV,
	    NI_NUMERICSERV) != 0) {
		syslog(LOG_ALERT, "isns getnameinfo failed");
		(void) close(so);
		return (NULL);
	}
	scn_port = atoi(strport);


	if (listen(so, 5) < 0) {
		syslog(LOG_ALERT, "esi_scn_thr: failed listen");
		(void) close(so);
		return (NULL);
	}

	/* listen for esi or scn messages */
	while (isns_shutdown == False) {
		/* ISNS_ESI_INTERVAL_ATTR_ID is set to 10s */
		timeout.tv_sec = 10;
		timeout.tv_usec = 0;
		FD_ZERO(&fdset);
		FD_SET(so, &fdset);

		socket_ready = select(so + 1, &fdset, NULL, NULL, &timeout);

		/* If disabled bail out, dont care about packets */
		if (isns_enabled() == False) {
			syslog(LOG_INFO,
			    "isns server is disabled, dergister target");
			isns_fini();
			(void) close(so);
			return (NULL);
		}

		if (socket_ready < 0) {
			syslog(LOG_ERR,
			    "esi_scn_thr: select failed, retrying.");
			continue;
		} else if (socket_ready == 0) { /* timeout */
			continue;
		} else {
			/* Socket is ready */
			if ((fd = accept(so, &sa, &len)) < 0) {
				syslog(LOG_ALERT, "esi_scn_thr: failed accept");
				continue;
			}
		}
		if (isns_recv(fd, (isns_rsp_t **)&scn) == 0) {
			/* Just return success for ESI */
			switch (scn->func_id) {
				case ISNS_ESI:
					process_esi(fd, scn);
					break;
				case ISNS_SCN:
					/* call the SCN process function */
					process_scn(fd, scn);
					break;
				default:
					syslog(LOG_ERR,
					    "esi_scn_thr: Invalid funcid %d\n",
					    scn->func_id);
					break;
			}
			/* free response resource */
			isns_free_pdu(scn);
		} else {
			syslog(LOG_ALERT, "esi_scn_thr fails isns_recv ");
		}

		(void) close(fd);
	}
	(void) close(so);
	return (NULL);
}
예제 #6
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * Update an existing iscsi target property
 */
int
isns_dev_update(char *targ, uint32_t mods)
{
	int		so;
	int		flags = 0;	/* update only */
	char		*iname = NULL;
	char		*dummy = NULL;
	char		alias[MAXNAMELEN];
	tgt_node_t	*tgt = NULL;
	isns_pdu_t	*cmd;
	isns_rsp_t	*rsp;
	int		ret = -1;

	if (mods == 0)
		return (0);

	if (isns_server_connection_thr_running == False) {
		syslog(LOG_ERR,
		    "isns_dev_update: iSNS discovery is not running."
		    " Check the previous iSNS initialization error.");
		return (-1);
	}

	if ((tgt = find_tgt_by_name(targ, &iname)) != NULL) {
		if (tgt_find_value_str(tgt, XML_ELEMENT_ALIAS, &dummy) ==
		    True) {
			(void) strcpy(alias, dummy);
			free(dummy);
		} else
			(void) strcpy(alias, tgt->x_value);

		if ((so = isns_open(isns_args.server)) < 0) {
			goto error;
		}

		if (isns_create_pdu(ISNS_DEV_ATTR_REG, flags, &cmd)) {
			goto error;
		}
		/* source attr, msg key, delimiter */
		if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
		    STRLEN(iname), iname, 0) != 0) {
			goto error;
		}
		if (isns_append_attr(cmd, ISNS_EID_ATTR_ID,
		    STRLEN(isns_args.entity), isns_args.entity, 0) != 0) {
			goto error;
		}
		if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0)
		    != 0) {
			goto error;
		}

		/*
		 * get current operating attributes, alias & portal group
		 * objects, these should be the only things that get change
		 */
		(void) isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
		    STRLEN(iname), iname, 0);
		(void) isns_append_attr(cmd, ISNS_ISCSI_NODE_TYPE_ATTR_ID,
		    ISNS_NODE_TYP_SZ, NULL, ISNS_TARGET_NODE_TYPE);

		if (mods & ISNS_MOD_ALIAS)
		if (isns_append_attr(cmd, ISNS_ISCSI_ALIAS_ATTR_ID,
		    STRLEN(alias), alias, 0) != 0) {
			goto error;
		}

		if (mods & ISNS_MOD_TPGT)
			if (append_tpgt(tgt, cmd) != 0) {
				goto error;
			}

		if (isns_send(so, (isns_pdu_t *)cmd) < 0) {
			goto error;
		}

		if (isns_recv(so, &rsp) == -1) {
			goto error;
		}

		/* process response, if failed do a isns_reg_all */
		if ((ret = process_rsp(cmd, rsp)) == -1) {
			if (isns_reg_all() != 0 || isns_scn_reg_all() != 0) {
				syslog(LOG_ALERT, "ISNS register failed\n");
				goto error;
			}
			ret = 0;
		} else {
			if (isns_scn_reg(so, iname) == -1) {
				syslog(LOG_ERR, "ISNS SCN register failed\n");
				goto error;
			}
			ret = 0;
		}
	} else {
		syslog(LOG_ERR, "ISNS: fails to update target %s\n", alias);
	}

error:
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	if (iname)
		free(iname);
	isns_close(so);
	return (ret);
}
예제 #7
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * Register all iscsi target nodes from the XML database
 * Alway use the ISNS_FLAG_REPLACE_REG flag
 */
int
isns_reg_all()
{
	int so;
	uint32_t	flags = ISNS_FLAG_REPLACE_REG;
	isns_pdu_t	*cmd = NULL;
	isns_rsp_t	*rsp = NULL;
	char		*n = NULL;
	char		*a = NULL;
	char		alias[MAXNAMELEN];
	char		iname[MAXNAMELEN];
	tgt_node_t	*tgt = NULL;
	int		ret = -1;
	int		tgt_cnt = 0;

	if (isns_server_connection_thr_running == False) {
		syslog(LOG_ERR,
		    "isns_reg_all: iSNS discovery is not running."
		    " Check the previous iSNS initialization error.");
		return (-1);
	}

	/*
	 * get the 1st target and use it for the source attribute
	 */
	if ((tgt = tgt_node_next_child(targets_config, XML_ELEMENT_TARG, tgt))
	    == NULL) {
		return (0);
	}
	if (tgt->x_value == NULL) {
		syslog(LOG_ALERT, "ISNS: target with NULL local name\n");
		return (-1);
	}
	if (tgt_find_value_str(tgt, XML_ELEMENT_INAME, &n)
	    == FALSE) {
		syslog(LOG_ALERT, "ISNS: no XML_ELEMENT_INAME found\n");
		return (-1);
	}
	(void) strcpy(iname, n);
	free(n);
	if ((so = isns_open(isns_args.server)) == -1) {
		syslog(LOG_ALERT, "ISNS: fails to connect to %s\n",
		    isns_args.server);
		return (-1);
	}

	if (isns_create_pdu(ISNS_DEV_ATTR_REG, flags, &cmd) != 0) {
		goto error;
	}

	/* source attribute */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(iname), iname, 0) != 0) {
		goto error;
	}

	/* add message key attribute */
	if (isns_append_attr(cmd, ISNS_EID_ATTR_ID,
	    STRLEN(isns_args.entity), isns_args.entity, 0) != 0) {
		goto error;
	}

	/* add delimiter */
	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) != 0) {
		goto error;
	}

	/* entity id */
	if (isns_append_attr(cmd, ISNS_EID_ATTR_ID,
	    STRLEN(isns_args.entity), isns_args.entity, 0) != 0) {
		goto error;
	}

	/* entity type */
	if (isns_append_attr(cmd, ISNS_ENTITY_PROTOCOL_ATTR_ID,
	    ISNS_ENTITY_TYP_SZ, NULL, ISNS_ENTITY_PROTOCOL_ISCSI) != 0) {
		goto error;
	}

	/* portal ip-addr */
	if (isns_append_attr(cmd, ISNS_PORTAL_IP_ADDR_ATTR_ID,
	    eid_ip.ai_addrlen, (void *)&eid_ip.ip_adr,
	    eid_ip.ip_len) != 0) {
		goto error;
	}

	/* portal port */
	if (isns_append_attr(cmd, ISNS_PORTAL_PORT_ATTR_ID,
	    ISNS_PORT_SZ, NULL, iscsi_port) != 0) {
		goto error;
	}

	/* ESI interval */
	if (isns_append_attr(cmd, ISNS_ESI_INTERVAL_ATTR_ID,
	    ISNS_ESI_TICK_SZ, NULL, 10) != 0) {
		goto error;
	}


	/* scn port */
	if (isns_append_attr(cmd, ISNS_SCN_PORT_ATTR_ID,
	    ISNS_PORT_SZ, NULL, scn_port) != 0) {
		goto error;
	}

	/* esi port */
	if (isns_append_attr(cmd, ISNS_ESI_PORT_ATTR_ID,
	    ISNS_PORT_SZ, NULL, scn_port) != 0) {
		goto error;
	}

	/*
	 * Open targets_config and devAttrReg all nodes
	 */
	tgt = NULL;
	while ((tgt = tgt_node_next_child(targets_config, XML_ELEMENT_TARG,
	    tgt)) != NULL) {
		if (tgt->x_value == NULL) {
			syslog(LOG_ALERT, "ISNS: target with NULL name\n");
			continue;
		}
		/* use this value as alias if alias is not set */
		(void) strcpy(alias, tgt->x_value);

		if (tgt_find_value_str(tgt, XML_ELEMENT_INAME, &n)
		    == FALSE) {
			continue;
		}
		(void) strcpy(iname, n);
		free(n);

		/* find alias */
		if (tgt_find_value_str(tgt, XML_ELEMENT_ALIAS, &a)
		    == TRUE) {
			(void) strcpy(alias, a);
			free(a);
		}

		tgt_cnt++;		/* increment target count */

		/* operation attributes */
		if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
		    STRLEN(iname), iname, 0) != 0) {
			goto error;
		}
		if (isns_append_attr(cmd, ISNS_ISCSI_NODE_TYPE_ATTR_ID,
		    4, NULL, ISNS_TARGET_NODE_TYPE) != 0) {
			goto error;
		}
		if (isns_append_attr(cmd, ISNS_ISCSI_ALIAS_ATTR_ID,
		    STRLEN(alias), alias, 0) != 0) {
			goto error;
		}

		if (append_tpgt(tgt, cmd) != 0) {
			goto error;
		}

	}

	/* send pdu */
	if (isns_send(so, cmd) == -1) {
		goto error;
	}

	/* get isns response */
	if (isns_recv(so, &rsp) == -1) {
		goto error;
	}

	/* process response */
	if (process_rsp(cmd, rsp) == 0) {
		ret = 0;
		num_reg = tgt_cnt;
		queue_prt(mgmtq, Q_ISNS_DBG, "DevAttrRegAll successful");
	} else {
		syslog(LOG_ALERT, "DevAttrReg failed");
	}

error:
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	isns_close(so);
	return (ret);
}
예제 #8
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * SCNReg
 * See RFC 4171 Section 5.6.5.5
 */
static int
isns_scn_reg(int so, char *node)
{
	isns_pdu_t	*cmd;
	isns_rsp_t	*rsp;
	uint32_t	flags = 0;
	uint32_t	bitmap = 0;
	int		ret = -1;

	queue_prt(mgmtq, Q_ISNS_DBG, "ISNS_SCN_REG");

	if (isns_create_pdu(ISNS_SCN_REG, flags, &cmd) != 0) {
		return (-1);
	}

	/* source attribute */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) == -1) {
		goto error;
	}

	/* message key attribute */
	/* iscsi initiator node name */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) != 0) {
		goto error;
	}

	/* delimiter */
	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) == -1) {
		goto error;
	}

	/* SCN bitmap */
	bitmap = ISNS_INIT_SELF_INFO_ONLY | ISNS_OBJ_REMOVED |
	    ISNS_OBJ_ADDED | ISNS_OBJ_UPDATED;
	if (isns_append_attr(cmd, ISNS_ISCSI_SCN_BITMAP_ATTR_ID,
	    ISNS_SCN_BITMAP_SZ, NULL, bitmap) == -1) {
		goto error;
	}

	if (isns_send(so, cmd) == -1) {
		syslog(LOG_ERR, "isns_scn_reg fails isns_send");
		goto error;
	}

	if (isns_recv(so, &rsp) == -1) {
		syslog(LOG_ERR, "isns_scn_reg fails isns_recv ");
		goto error;
	}

	/* process response */
	if (process_rsp(cmd, rsp) == 0) {
		ret = 0;
	}

error:
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	return (ret);
}
예제 #9
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * DevAttrQry for iscsi initiator
 * See RFC 4171 Sect. 5.6.5.2 for query detail
 */
static int
isns_dev_attr_qry(int so, char *target, char *initiator)
{
	isns_pdu_t	*cmd;
	isns_rsp_t	*rsp;
	uint32_t	flags = 0;
	int		ret = -1;
	size_t		remain;
	isns_tlv_t	*tlv;
	uint8_t		*ptr;

	queue_prt(mgmtq, Q_ISNS_DBG, "ISNS_DEV_ATTR_QRY");

	if (isns_create_pdu(ISNS_DEV_ATTR_QRY, flags, &cmd) != 0) {
		return (-1);
	}

	/* source attribute */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(target), target, 0) == -1) {
		goto error;
	}

	/* message key attribute */
	/* iscsi initiator node type */
	if (isns_append_attr(cmd, ISNS_ISCSI_NODE_TYPE_ATTR_ID,
	    ISNS_NODE_TYP_SZ, NULL, ISNS_INITIATOR_NODE_TYPE) == -1) {
		goto error;
	}

	/* delimiter */
	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) == -1) {
		goto error;
	}

	/*
	 * operating attributes
	 * Query Iscsi initiator with zero length TLV operating
	 * attribute
	 */

	/* iscsi name */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    0, NULL, 0) != 0) {
		goto error;
	}

	if (isns_send(so, cmd) == -1) {
		syslog(LOG_ERR, "isns_dev_attr_qry fails isns_send");
		goto error;
	}

	/* recv response */
	if (isns_recv(so, &rsp) == -1) {
		syslog(LOG_ERR, "isns_dev_attr_qry fails isns_recv ");
		goto error;
	}

	/* process response */
	if ((ret = process_rsp(cmd, rsp)) == 0) {
		/* compare initiator name to the response, success if found */
		/* subtract out status word */
		remain = rsp->pdu_len - ISNS_STATUS_SZ;
		ptr = rsp->data;

		while (remain > 0) {
			/* LINTED */
			tlv = (isns_tlv_t *)ptr;

			/* debug only */
			print_ntoh_tlv(tlv);

			/* process tag-len-value */
			ntoh_tlv(tlv);
			/*
			 * let's process the data, only interested
			 * in iscsi name, skip everything else for
			 * now.
			 */
			if (tlv->attr_id == ISNS_ISCSI_NAME_ATTR_ID) {
				if (strncmp((char *)tlv->attr_value, initiator,
				    tlv->attr_len) == 0) {
					break;
				}
			}
			/* next tlv */
			remain -= ISNS_ATTR_SZ(tlv->attr_len);
			ptr += ISNS_ATTR_SZ(tlv->attr_len);
		}
		ret = (remain > 0) ? 1 : 0;
	}

error:
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	return (ret);
}
예제 #10
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * Register a new node, need to find another node that is already registered
 * DevAttrReg
 * RFC 4171 Section 5.6.5.5 indicated SCN-port-tag (23) needed to be
 * included in the registration
 * Also need to register ESI-port-tag (20) see Section 6.3.5
 */
static int
isns_dev_attr_reg(int so, tgt_node_t *tgt, char *node, char *alias)
{
	isns_pdu_t	*cmd = NULL;
	isns_rsp_t	*rsp = NULL;
	uint32_t	flags = 0;
	int		ret = 0;
	Boolean_t	found = False;
	tgt_node_t	*src = NULL;
	char		*src_nm = NULL;

	queue_prt(mgmtq, Q_ISNS_DBG, "ISNS_DEV_ATTR_REG");

	if ((so = isns_open(isns_args.server)) == -1) {
		return (-1);
	}

	if (num_reg == 0) {
		flags |= ISNS_FLAG_REPLACE_REG;
	}

	if (isns_create_pdu(ISNS_DEV_ATTR_REG, flags, &cmd) != 0) {
		return (-1);
	}

	if (num_reg == 0) {
		/* add new node to source attribute */
		if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
		    STRLEN(node), node, 0) != 0) {
			goto error;
		}
	} else {
		/* find a registered node to use */
		do {
			src = find_next_tgt(src, &src_nm);
			if (src == NULL) {
				syslog(LOG_ALERT, "ISNS out of sync\n");
				goto error;
			}
			if (tgt == src) {
				free(src_nm);
				src_nm = NULL;
				continue;
			} else {
				found = True;
			}
		} while (found == False);

		if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
		    STRLEN(src_nm), src_nm, 0) != 0) {
			goto error;
		}
	}

	/* add message key attribute */
	if (isns_append_attr(cmd, ISNS_EID_ATTR_ID,
	    STRLEN(isns_args.entity), isns_args.entity, 0) != 0) {
		goto error;
	}

	/* add delimiter */
	if (isns_append_attr(cmd, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0) != 0) {
		goto error;
	}

	/* add operation attributes */

	/* entity id */
	if (isns_append_attr(cmd, ISNS_EID_ATTR_ID,
	    STRLEN(isns_args.entity), isns_args.entity, 0) != 0) {
		goto error;
	}

	/* entity type */
	if (isns_append_attr(cmd, ISNS_ENTITY_PROTOCOL_ATTR_ID,
	    ISNS_ENTITY_TYP_SZ, NULL, ISNS_ENTITY_PROTOCOL_ISCSI) != 0) {
		goto error;
	}

	/*
	 * Register entity portal properties the 1st time
	 */
	if (num_reg == 0) {
		/* portal ip-addr */
		if (isns_append_attr(cmd, ISNS_PORTAL_IP_ADDR_ATTR_ID,
		    eid_ip.ai_addrlen, (void *)&eid_ip.ip_adr,
		    eid_ip.ip_len) != 0) {
			goto error;
		}

		/* portal port */
		if (isns_append_attr(cmd, ISNS_PORTAL_PORT_ATTR_ID,
		    ISNS_PORT_SZ, NULL, iscsi_port) != 0) {
			goto error;
		}

		/* ESI interval */
		if (isns_append_attr(cmd, ISNS_ESI_INTERVAL_ATTR_ID,
		    ISNS_ESI_TICK_SZ, NULL, 10) != 0) {
			goto error;
		}

		/* scn port */
		if (isns_append_attr(cmd, ISNS_SCN_PORT_ATTR_ID,
		    ISNS_PORT_SZ, NULL, scn_port) != 0) {
			goto error;
		}

		/* esi port */
		if (isns_append_attr(cmd, ISNS_ESI_PORT_ATTR_ID,
		    ISNS_PORT_SZ, NULL, scn_port) != 0) {
			goto error;
		}
	}

	/* iscsi node name */
	if (isns_append_attr(cmd, ISNS_ISCSI_NAME_ATTR_ID,
	    STRLEN(node), node, 0) != 0) {
		goto error;
	}

	/* iscsi node type */
	if (isns_append_attr(cmd, ISNS_ISCSI_NODE_TYPE_ATTR_ID,
	    ISNS_NODE_TYP_SZ, NULL, ISNS_TARGET_NODE_TYPE) != 0) {
		goto error;
	}

	/* iscsi node alias */
	if (isns_append_attr(cmd, ISNS_ISCSI_ALIAS_ATTR_ID,
	    STRLEN(alias), alias, 0) != 0) {
		goto error;
	}

	/* PGT */
	if (append_tpgt(tgt, cmd) != 0) {
		goto error;
	}

	/* send pdu */
	if (isns_send(so, cmd) == -1) {
		goto error;
	}

	/* get isns response */
	if (isns_recv(so, &rsp) == -1) {
		goto error;
	}

	/* process response */
	if ((ret = process_rsp(cmd, rsp)) == 0) {
		num_reg++;
	}

error:
	/* Free all resouces here */
	if (cmd)
		isns_free_pdu(cmd);
	if (rsp)
		isns_free_pdu(rsp);
	if (src_nm)
		free(src_nm);
	return (ret);
}