/* * 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); }
/* * 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); }
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); } } }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }