예제 #1
0
파일: isns_client.c 프로젝트: imp/slist
/*
 * This thread sit's in a loop and ensures that it keeps checking for
 * connection to isns_server. Once the connection works it registers
 * with the isns and bails out.
 * We expect the isns server to be fault taulerant and has persistence
 * for the registered entries.
 */
static void *
isns_server_connection_thr(void *arg)
{
	Boolean_t registered_targets = False;
	char server[MAXHOSTNAMELEN + 1] = {0};

	while (isns_shutdown == False &&
	    connection_thr_bail_out == False) {
		/* current server */
		(void) strcpy(server, isns_args.server);

		if (is_isns_server_up(server) == 0) {
			if (registered_targets == False) {
				/*
				 * register all targets, what happens if
				 * no targets are created yet? this should
				 * not be a failure, when new target gets
				 * created, update gets call. what if SCN
				 * register fails?
				 */
				if (isns_reg_all() == 0) {
					/* scn register all targets */
					if (isns_op_all(ISNS_SCN_REG) != 0) {
						syslog(LOG_ERR,
						    "SCN registrations"
						    " failed\n");
						(void) isns_op_all(
						    ISNS_DEV_DEREG);
						registered_targets = False;
					} else {
						registered_targets = True;
						break;
					}
				}
			}
		} else {
			syslog(LOG_INFO,
			    "isns server %s is not reachable",
			    server);
			registered_targets = False;
		}
		(void) sleep(ISNS_SLEEP_SECS);
		/* If isns was disabled, deregister and close the thread */
		if (isns_enabled() == False) {
			syslog(LOG_INFO,
			    "isns server is disabled, dergister target");
			isns_fini();
			break;
		}

	}
	queue_message_set(mgmtq, 0, msg_pthread_join,
	    (void *)(uintptr_t)pthread_self());

	return (NULL);
}
예제 #2
0
파일: isns_client.c 프로젝트: imp/slist
static int
isns_populate_and_update_server_info(Boolean_t update) {
	char		*isns_srv, *isns_port;
	int retcode = 0;

	/* get isns server info */
	(void) tgt_find_value_str(main_config, XML_ELEMENT_ISNS_SERV,
	    &isns_srv);
	if (isns_srv == NULL) {
		syslog(LOG_INFO,
		    "The server has not been setup, "
		    "but enabling the isns access");
		retcode = -1;
		return (retcode);
	}
	isns_port = strchr(isns_srv, ':');
	if (isns_port == NULL) {
		isns_args.isns_port = ISNS_DEFAULT_SERVER_PORT;
	} else {
		isns_args.isns_port = strtoul(isns_port + 1, NULL, 0);
		if (isns_args.isns_port == 0) {
			isns_args.isns_port = ISNS_DEFAULT_SERVER_PORT;
		}
		*isns_port = '\0';
	}

	if (update == True) {
		/* isns_server changed */
		if (strcmp(isns_srv, isns_args.server) != 0) {
			/* de-reg from old iSNS server if it is setup */
			syslog(LOG_INFO,
			    "Detected a new isns server, deregistering"
			    " %s", isns_args.server);
			(void) isns_dereg_all();
			(void) strcpy(isns_args.server, isns_srv);
			/* Register with the new server */
			if (isns_reg_all() == 0) {
				/* scn register all targets */
				if (isns_op_all(ISNS_SCN_REG) != 0) {
					syslog(LOG_ERR,
					    "SCN registrations failed\n");
					(void) isns_op_all(ISNS_DEV_DEREG);
					retcode = -1;
				}
			}
		}
	} else {
		(void) strcpy(isns_args.server, isns_srv);
	}
	free(isns_srv);
	return (retcode);
}
예제 #3
0
static char *
remove_tpgt(tgt_node_t *x)
{
	char		*msg		= NULL;
	char		*prop		= NULL;
	tgt_node_t	*node		= NULL;
	tgt_node_t	*c		= NULL;
	Boolean_t	change_made	= False;

	if (tgt_find_value_str(x, XML_ELEMENT_NAME, &prop) == False) {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME);
		return (msg);
	}
	while ((node = tgt_node_next(main_config, XML_ELEMENT_TPGT, node)) !=
	    NULL) {
		if (strcmp(node->x_value, prop) == 0)
			break;
	}
	free(prop);
	if (node == NULL) {
		xml_rtn_msg(&msg, ERR_TPGT_NOT_FOUND);
		return (msg);
	}
	if (tgt_find_value_str(x, XML_ELEMENT_IPADDR, &prop) == True) {
		if (prop == NULL) {
			xml_rtn_msg(&msg, ERR_SYNTAX_EMPTY_IPADDR);
			return (msg);
		}
		c = tgt_node_alloc(XML_ELEMENT_IPADDR, String, prop);
		if (tgt_node_remove(node, c, MatchBoth) == False) {
			xml_rtn_msg(&msg, ERR_INVALID_IP);
			goto error;
		}
		tgt_node_free(c);
		free(prop);
		change_made = True;
	}
	if ((change_made != True) &&
	    (tgt_find_value_str(x, XML_ELEMENT_ALL, &prop) == True)) {
		tgt_node_remove(main_config, node, MatchBoth);
		change_made = True;
	}

	if (change_made == True) {
		/* Isns re-register all target */
		if (isns_enabled() == True)
			isns_reg_all();
		if (mgmt_config_save2scf() == True)
			xml_rtn_msg(&msg, ERR_SUCCESS);
	} else {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_OPERAND);
	}

	return (msg);

error:
	if (c != NULL)
		tgt_node_free(c);
	if (prop != NULL)
		free(prop);
	return (msg);
}
예제 #4
0
/*
 * []----
 * | modify_tpgt -- add an IP-address to a target portal group
 * []----
 */
static char *
modify_tpgt(tgt_node_t *x)
{
	struct addrinfo	*res	= NULL;
	char		*msg	= NULL;
	char		*name	= NULL;
	char		*ip_str	= NULL;
	tgt_node_t	*tnode	= NULL;
	tgt_node_t	*list	= NULL;

	(void) pthread_rwlock_wrlock(&targ_config_mutex);
	if (tgt_find_value_str(x, XML_ELEMENT_NAME, &name) == False) {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME);
		goto error;
	}
	if (tgt_find_value_str(x, XML_ELEMENT_IPADDR, &ip_str) == False) {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_IPADDR);
		goto error;
	}
	if ((getaddrinfo(ip_str, NULL, NULL, &res) != 0) || (res == NULL)) {
		xml_rtn_msg(&msg, ERR_INVALID_IP);
		goto error;
	}
	while ((tnode = tgt_node_next_child(main_config, XML_ELEMENT_TPGT,
	    tnode)) != NULL) {
		if (strcmp(tnode->x_value, name) == 0)
			break;
	}
	if (tnode == NULL) {
		xml_rtn_msg(&msg, ERR_TPGT_NOT_FOUND);
		goto error;
	}

	if ((list = tgt_node_next(tnode, XML_ELEMENT_IPADDRLIST, NULL))
	    == NULL) {
		list = tgt_node_alloc(XML_ELEMENT_IPADDRLIST, String, "");
		if (list == NULL) {
			xml_rtn_msg(&msg, ERR_NO_MEM);
			goto error;
		}
		tgt_node_add(tnode, list);
	}
	if (modify_element(XML_ELEMENT_IPADDR, ip_str, list, MatchBoth) ==
	    False) {
		xml_rtn_msg(&msg, ERR_NO_MEM);
		goto error;
	}

	if (mgmt_config_save2scf() == True) {
		xml_rtn_msg(&msg, ERR_SUCCESS);
	} else {
		/* tpgt change should be updated to smf */
		xml_rtn_msg(&msg, ERR_INTERNAL_ERROR);
	}

	/*
	 * Re-register all targets, currently there's no method to
	 * update TPGT for individual target
	 */
	if (isns_enabled() == True) {
		(void) isns_reg_all();
	}

error:
	if (name)
		free(name);
	if (ip_str)
		free(ip_str);
	if (res)
		freeaddrinfo(res);
	(void) pthread_rwlock_unlock(&targ_config_mutex);
	return (msg);
}
예제 #5
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);
}