Ejemplo n.º 1
0
int
query_entity_id(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	uint32_t	status;
	isns_simple_t	*qry;
	const char	*eid;

	if (argc == 1 && !strcmp(argv[0], "help")) {
		printf("Query iSNS for own entity ID.\n"
		       "No arguments allowed\n");
		exit(0);
	}
	if (argc != 0)
		isns_fatal("EID query - no arguments accepted\n");

	isns_attr_list_append_string(&query_key,
			ISNS_TAG_ISCSI_NAME,
			isns_config.ic_source_name);
	qry = isns_create_query(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	isns_query_request_attr_tag(qry, ISNS_TAG_ENTITY_IDENTIFIER);

	status = isns_client_call(clnt, &qry);
	if (status != ISNS_SUCCESS) {
		isns_error("Query failed: %s\n", isns_strerror(status));
		return status;
	}

	status = isns_query_response_get_objects(qry, &objects);
	if (status) {
		isns_error("Unable to extract object list from query response: %s\n",
				isns_strerror(status), status);
		return status;
	}

	status = ISNS_NO_SUCH_ENTRY;
	if (objects.iol_count == 0) {
		isns_error("Node %s not registered with iSNS\n",
				isns_config.ic_source_name);
	} else
	if (!isns_object_get_string(objects.iol_data[0],
				ISNS_TAG_ENTITY_IDENTIFIER, &eid)) {
		isns_error("Query for %s returned an object without EID\n",
				isns_config.ic_source_name);
	} else {
		printf("%s\n", eid);
		status = ISNS_SUCCESS;
	}

	isns_object_list_destroy(&objects);
	isns_simple_free(qry);

	return status;
}
Ejemplo n.º 2
0
int
deregister_domain(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
	isns_simple_t	*msg;
	uint32_t	dd_id, status;

	if (!parse_dd_deregistration(argv, argc, &dd_id, &attrs))
		isns_fatal("Unable to parse DD registration\n");

	msg = isns_create_dd_deregistration(clnt, dd_id, &attrs);
	isns_attr_list_destroy(&attrs);

	if (msg == NULL) {
		isns_error("Cannot create message\n");
		return ISNS_INTERNAL_ERROR;
	}

	status = isns_client_call(clnt, &msg);
	if (status != ISNS_SUCCESS) {
		isns_error("Deregistration failed: %s\n",
				isns_strerror(status));
		return status;
	}

	isns_simple_free(msg);
	return status;
}
Ejemplo n.º 3
0
int
query_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_attr_list_t oper_attrs = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	uint32_t	status;
	isns_simple_t	*qry;
	unsigned int	i;

	if (!parse_query(argv, argc, &query_key, &oper_attrs))
		isns_fatal("Unable to parse query\n");

	qry = isns_create_query(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	/* Add the list of attributes we request */
	for (i = 0; i < oper_attrs.ial_count; ++i)
		isns_query_request_attr(qry, oper_attrs.ial_data[i]);
	isns_attr_list_destroy(&oper_attrs);

	status = isns_client_call(clnt, &qry);
	if (status != ISNS_SUCCESS) {
		isns_error("Query failed: %s\n", isns_strerror(status));
		return status;
	}

	status = isns_query_response_get_objects(qry, &objects);
	if (status) {
		isns_error("Unable to extract object list from query response: %s\n",
				isns_strerror(status), status);
		return status;
	}

	isns_object_list_print(&objects, isns_print_stdout);
	isns_object_list_destroy(&objects);
	isns_simple_free(qry);

	return status;
}
Ejemplo n.º 4
0
int
deregister_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
	isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
	isns_simple_t	*dereg;
	uint32_t	status;

	if (!parse_deregistration(argv, argc, &query_key))
		isns_fatal("Unable to parse unregistration\n");

	dereg = isns_create_deregistration(clnt, &query_key);
	isns_attr_list_destroy(&query_key);

	status = isns_client_call(clnt, &dereg);
	if (status != ISNS_SUCCESS) {
		isns_error("Deregistration failed: %s\n",
				isns_strerror(status));
		return status;
	}

#if 0
	status = isns_dereg_msg_response_get_objects(dereg, &objects);
	if (status) {
		isns_error("Unable to extract object list from deregistration response: %s\n",
				isns_strerror(status), status);
		goto done;
	}
	isns_object_list_print(&objects, isns_print_stdout);
#endif

	isns_object_list_destroy(&objects);
	isns_simple_free(dereg);

	return status;
}
Ejemplo n.º 5
0
int
list_objects(isns_client_t *clnt, int argc, char **argv)
{
	isns_attr_list_t	query_keys = ISNS_ATTR_LIST_INIT;
	isns_object_template_t	*query_type = NULL;
	isns_simple_t		*simp;
	int			status, count = 0;

	if (!parse_list(argc, argv, &query_type, &query_keys))
		isns_fatal("Unable to parse parameters\n");

	simp = isns_create_getnext(clnt, query_type, &query_keys);
	while (1) {
		isns_object_t	*obj = NULL;
		isns_simple_t	*followup;

		status = isns_client_call(clnt, &simp);
		if (status)
			break;

		status = isns_getnext_response_get_object(simp, &obj);
		if (status)
			break;

		printf("Object %u:\n", count++);
		isns_object_print(obj, isns_print_stdout);
		isns_object_release(obj);

		followup = isns_create_getnext_followup(clnt,
				simp, &query_keys);
		isns_simple_free(simp);
		simp = followup;
	}

	if (status == ISNS_SOURCE_UNAUTHORIZED
	 && query_type == &isns_policy_template
	 && !opt_local)
		isns_warning("Please use --local trying to list policies\n");

	if (status != ISNS_NO_SUCH_ENTRY) {
		isns_error("GetNext call failed: %s\n",
				isns_strerror(status));
		return status;
	}
	return ISNS_SUCCESS;
}
Ejemplo n.º 6
0
static int
__register_objects(isns_client_t *clnt,
		isns_object_t *key_obj,
		const isns_object_list_t *objects)
{
	isns_source_t	*source = NULL;
	isns_simple_t	*reg;
	uint32_t	status;
	unsigned int	i;

	for (i = 0; i < objects->iol_count && !source; ++i) {
		isns_object_t *obj = objects->iol_data[i];

		if (!isns_object_is_iscsi_node(obj))
			continue;
		source = isns_source_from_object(obj);
	}

	reg = isns_create_registration2(clnt, key_obj, source);
	isns_registration_set_replace(reg, opt_replace);

	/* Add all objects to be registered */
	for (i = 0; i < objects->iol_count; ++i)
		isns_registration_add_object(reg, objects->iol_data[i]);

	status = isns_client_call(clnt, &reg);
	isns_simple_free(reg);

	if (status == ISNS_SUCCESS)
		printf("Successfully registered object(s)\n");
	else
		isns_error("Failed to register object(s): %s\n",
				isns_strerror(status));

	if (source)
		isns_source_release(source);
	return status;
}
Ejemplo n.º 7
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c, n, timeout;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	if (optind != argc - 1)
		isns_fatal("Need timeout argument\n");
	timeout = parse_timeout(argv[optind]);

	isns_read_config(opt_configfile);

	/*
	    ---DevAttrReg[REPLACE]---
	    Source:
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	    Message attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	    Operating attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	      0002  uint32      : Entity protocol = iSCSI (2)
	      0010  ipaddr      : Portal IP address = 192.168.1.2
	      0011  uint32      : Portal TCP/UDP port = 33849/tcp
	      0014  uint32      : ESI port = 56288/tcp
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	      0021  uint32      : iSCSI node type = Initiator
	      0022  string      : iSCSI alias = "blue.pauw.homeunix.net"

	      [...]
    	      response status 0x0003 (Invalid registration)

	   This would fail because we got confused about EID in
	   the replace case.
	 */
	isns_assign_string(&isns_config.ic_source_name,
			"iqn.2005-03.org.open-iscsi:blue");

	for (n = 0; n < 2; ++n) {
		clnt = isns_create_default_client(NULL);
		reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER,
				clnt->ic_source, NULL);
		reg->is_replace = opt_replace;

		/* Message attributes */
		attrs = &reg->is_message_attrs;
		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");

		/* Operating attributes */
		attrs = &reg->is_operating_attrs;

		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");
		U32(ENTITY_PROTOCOL,	2);

		isns_portal_parse(&portal_info, "192.168.1.2:33849/tcp", NULL);
		isns_portal_to_attr_list(&portal_info,
				ISNS_TAG_PORTAL_IP_ADDRESS,
				ISNS_TAG_PORTAL_TCP_UDP_PORT,
				attrs);

		U32(ESI_PORT,		56288);
		STR(ISCSI_NAME,		"iqn.2005-03.org.open-iscsi:blue");
		U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
		STR(ISCSI_ALIAS,	"blue.pauw.homeunix.net");
		isns_simple_print(reg, isns_print_stdout);

		status = isns_client_call(clnt, &reg);

		if (status != ISNS_SUCCESS)
			isns_fatal("Unable to register object: %s\n",
					isns_strerror(status));

		printf("Successfully registered object\n");
		// isns_simple_print(reg, isns_print_stdout);
		isns_simple_free(reg);
		isns_client_destroy(clnt);

		if (n == 0) {
			printf("Sleeping for %d seconds\n", timeout);
			sleep(timeout);
		}
	}

	return 0;
}
Ejemplo n.º 8
0
/*
 * Process an incoming message
 */
isns_message_t *
isns_process_message(isns_server_t *srv, isns_message_t *msg)
{
	struct isns_service_ops *ops = srv->is_ops;
	uint16_t	function = msg->im_header.i_function;
	int		status = ISNS_SUCCESS;
	isns_simple_t	*call = NULL, *reply = NULL;
	isns_message_t	*res_msg = NULL;
	isns_db_t	*db = srv->is_db;

	status = isns_simple_decode(msg, &call);
	if (status) {
		isns_debug_message("Failed to decode %s request: %s\n",
				isns_function_name(msg->im_header.i_function),
				isns_strerror(status));
		goto reply;
	}

	isns_simple_print(call, isns_debug_message);

	/* Set policy and privileges based on the
	 * sender's identity. */
	if (!(call->is_policy = isns_policy_bind(msg))) 
		goto err_unauthorized;

	if (!isns_policy_validate_function(call->is_policy, msg))
		goto err_unauthorized;

	/* Checks related to the message source.
	 * Note - some messages do not use a source.
	 */
	if (call->is_source) {
		/* Validate the message source. This checks whether the client
		 * is permitted to use this source node name.
		 * Beware - not all messages include a source.
		 */
		if (!isns_policy_validate_source(call->is_policy, call->is_source))
			goto err_unauthorized;

		/* This may fail if the source node isn't in the DB yet. */
		isns_source_set_node(call->is_source, db);

		/*
		 * 6.2.6.  Registration Period
		 *
		 * The registration SHALL be removed from the iSNS database
		 * if an iSNS Protocol message is not received from the
		 * iSNS client before the registration period has expired.
		 * Receipt of any iSNS Protocol message from the iSNS client
		 * automatically refreshes the Entity Registration Period and
		 * Entity Registration Timestamp.  To prevent a registration
		 * from expiring, the iSNS client should send an iSNS Protocol
		 * message to the iSNS server at intervals shorter than the
		 * registration period.  Such a message can be as simple as a
		 * query for one of its own attributes, using its associated
		 * iSCSI Name or FC Port Name WWPN as the Source attribute.
		 */
		/* Thusly, we update the timestamps of all entities
		 * registered by this source. */
		isns_entity_touch(call->is_source->is_entity);
	}

	/* Handle the requested function. If the function vector is
	 * NULL, silently discard the message. */
	switch (function) {
#define DO(rw, FUNCTION, __function) \
	case FUNCTION:						\
		if (!ops->__function)				\
			goto no_reply;				\
								\
		if (!isns_begin_##rw##_operation(srv, call, &status)) \
			break;					\
		status = ops->__function(srv, call, &reply);	\
		isns_end_##rw##_operation(srv, call, &status);	\
		break

	DO(write, ISNS_DEVICE_ATTRIBUTE_REGISTER, process_registration);
	DO(read,  ISNS_DEVICE_ATTRIBUTE_QUERY, process_query);
	DO(read,  ISNS_DEVICE_GET_NEXT, process_getnext);
	DO(write, ISNS_DEVICE_DEREGISTER, process_deregistration);
	DO(write, ISNS_DD_REGISTER, process_dd_registration);
	DO(write, ISNS_DD_DEREGISTER, process_dd_deregistration);
	DO(read,  ISNS_SCN_REGISTER, process_scn_registration);
	DO(read,  ISNS_SCN_DEREGISTER, process_scn_deregistration);
	DO(read,  ISNS_SCN_EVENT, process_scn_event);
	DO(read,  ISNS_STATE_CHANGE_NOTIFICATION, process_scn);
	DO(read,  ISNS_ENTITY_STATUS_INQUIRY, process_esi);
	DO(read,  ISNS_HEARTBEAT, process_heartbeat);
#undef DO

	default:
		isns_error("Function %s not supported\n",
				isns_function_name(function));
		status = ISNS_MESSAGE_NOT_SUPPORTED;
		break;
	}

reply:
	/* Commit any changes to the DB before we reply */
	if (db)
		isns_db_sync(db);

	/* Send out SCN notifications */
	isns_flush_events();

	if (reply != NULL) {
		reply->is_function |= 0x8000;
		isns_simple_print(reply, isns_debug_message);

		/* Encode the whole thing */
		status = isns_simple_encode_response(reply, msg, &res_msg);
	}

	/* No reply, or error when encoding it:
	 * just send the error, nothing else. */
	if (res_msg == NULL) {
		res_msg = isns_create_reply(msg);
		if (status == ISNS_SUCCESS)
			status = ISNS_INTERNAL_ERROR;
	}

	isns_debug_message("response status 0x%04x (%s)\n",
			status, isns_strerror(status));

	if (status != ISNS_SUCCESS)
		isns_message_set_error(res_msg, status);

no_reply:
	isns_simple_free(call);
	if (reply)
		isns_simple_free(reply);
	return res_msg;

err_unauthorized:
	status = ISNS_SOURCE_UNAUTHORIZED;
	goto reply;
}
Ejemplo n.º 9
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	isns_read_config(opt_configfile);

	isns_assign_string(&isns_config.ic_source_name,
			"iqn.1991-05.com.microsoft:orange");

	clnt = isns_create_default_client(NULL);

	/*
	 * test that we can deregister for SCN events, even though
	 * not registered
	 */
	reg = isns_simple_create(ISNS_SCN_DEREGISTER, clnt->ic_source, NULL);

	/* Message attributes */
	attrs = &reg->is_message_attrs;
	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_error("SCNDereg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully deregistered for SCN events\n");
	isns_simple_free(reg);

	/*
	 * test that we can deregister a device, even though not
	 * registered -- note that the portal group object proceeds
	 * the initiator (name) object in the operating attribute
	 * list
	 */
	reg = isns_simple_create(ISNS_DEVICE_DEREGISTER, clnt->ic_source, NULL);

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevDereg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully deregistered a device\n");
	isns_simple_free(reg);

	/*
	 * test that we can register (w/replace) device attributes
	 */
	reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER,
				 clnt->ic_source, NULL);
	reg->is_replace = opt_replace;

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	U32(SCN_PORT,		3230);
	U32(ESI_PORT,		3230);

	U32(PG_TAG,		1);
	STR(PG_ISCSI_NAME,	"iqn.1991-05.com.microsoft:orange");

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	STR(ISCSI_ALIAS,	"<MS SW iSCSI Initiator>");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevAttrReg failed: %s\n", isns_strerror(status));
	else
		printf("Successfully registered device attributes\n");
	isns_simple_free(reg);

	/*
	 * test that we can call DEVICE GET NEXT to get the next (only)
	 * iscsi Storage Node
	 */
	reg = isns_simple_create(ISNS_DEVICE_GET_NEXT, clnt->ic_source, NULL);
	attrs = &reg->is_message_attrs;
	NIL(ISCSI_NAME);

	attrs = &reg->is_operating_attrs;
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	NIL(ISCSI_NODE_TYPE);

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevGetNext failed: %s\n", isns_strerror(status));
	else
		printf("Successfully got next device node\n");
	isns_simple_free(reg);

	return 0;
}
Ejemplo n.º 10
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	isns_read_config(opt_configfile);

	isns_assign_string(&isns_config.ic_source_name,
			"iqn.1991-05.com.microsoft:orange");

	clnt = isns_create_default_client(NULL);

	reg = isns_simple_create(ISNS_SCN_DEREGISTER, clnt->ic_source, NULL);

	/* Message attributes */
	attrs = &reg->is_message_attrs;
	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_error("SCNDereg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);


	reg = isns_simple_create(ISNS_DEVICE_DEREGISTER, clnt->ic_source, NULL);

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevDereg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER, clnt->ic_source, NULL);
	reg->is_replace = opt_replace;

	attrs = &reg->is_operating_attrs;
	STR(ENTITY_IDENTIFIER,	"troopa.nki.nl");
	U32(ENTITY_PROTOCOL,	2);

	isns_portal_parse(&portal_info, "192.168.1.40:3229/tcp", NULL);
	isns_portal_to_attr_list(&portal_info,
			ISNS_TAG_PORTAL_IP_ADDRESS,
			ISNS_TAG_PORTAL_TCP_UDP_PORT,
			attrs);

	U32(SCN_PORT,		3230);
	U32(ESI_PORT,		3230);

	U32(PG_TAG,		1);
	STR(PG_ISCSI_NAME,	"iqn.1991-05.com.microsoft:orange");

	STR(ISCSI_NAME,		"iqn.1991-05.com.microsoft:orange");
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
	STR(ISCSI_ALIAS,	"<MS SW iSCSI Initiator>");

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevAttrReg failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	reg = isns_simple_create(ISNS_DEVICE_GET_NEXT, clnt->ic_source, NULL);
	attrs = &reg->is_message_attrs;
	NIL(ISCSI_NAME);

	attrs = &reg->is_operating_attrs;
	U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_TARGET_MASK);
	NIL(ISCSI_NODE_TYPE);

	status = isns_client_call(clnt, &reg);
	if (status != ISNS_SUCCESS)
		isns_fatal("DevGetNext failed: %s\n", isns_strerror(status));
	isns_simple_free(reg);

	return 0;
}
Ejemplo n.º 11
0
/*
 * Process a deregistration
 *
 * Normally, you would expect that a deregistration removes the
 * object from the database, and that's the end of the story.
 * Unfortunately, someone added Discovery Domains to the protocol,
 * requiring _some_ information to survive as long as an object
 * is referenced by a discovery domain. Specifically, we need to
 * retain the relationship between key attributes (eg iscsi node
 * name) and the object index.
 *
 * Thus, deregistration consists of the following steps
 *  -	the object is removed from the database's global scope,
 *	so that it's no longer visible to DB lookups.
 *
 *  -	the object is detached from its containing Network
 *	Entity.
 *
 *  -	all attributes except the key attr(s) and the index
 *	attribute are removed.
 */
int
isns_process_deregistration(isns_server_t *srv, isns_simple_t *call, isns_simple_t **result)
{
	isns_object_list_t	objects = ISNS_OBJECT_LIST_INIT;
	isns_simple_t		*reply = NULL;
	isns_db_t		*db = srv->is_db;
	int			status, dereg_status;
	unsigned int		i;

	/* Get the objects to deregister */
	status = isns_deregistration_get_objects(call, db, &objects);
	if (status != ISNS_SUCCESS)
		goto done;

	/*
	 * 5.6.5.4
	 *
	 * For messages that change the contents of the iSNS database,
	 * the iSNS server MUST verify that the Source Attribute
	 * identifies either a Control Node or a Storage Node that is
	 * a part of the Network Entity containing the added, deleted,
	 * or modified objects.
	 */
	/*
	 * Implementation note: this can be implemented either by
	 * explicitly checking the object's owner in isns_db_remove
	 * (which is what we do right now), or by matching only
	 * those objects that have the right owner anyway.
	 *
	 * The latter sounds like a better choice if the client
	 * uses NIL attributes, because it limits the scope of
	 * the operation; but then the RFC doesn't say whether
	 * this kind of deregistration would be valid at all.
	 */

	/* Success: create a new simple message, and
	 * send it in our reply. */
	reply = __isns_create_deregistration(srv->is_source, NULL);
	if (reply == NULL) {
		status = ISNS_INTERNAL_ERROR;
		goto done;
	}

	dereg_status = ISNS_SUCCESS;
	for (i = 0; i < objects.iol_count; ++i) {
		isns_object_t	*obj = objects.iol_data[i];

		/* Policy: check that the client is permitted
		 * to deregister this object */
		if (!isns_policy_validate_object_access(call->is_policy,
					call->is_source, obj,
					call->is_function))
			status = ISNS_SOURCE_UNAUTHORIZED;

		if (status == ISNS_SUCCESS)
			status = isns_db_remove(db, obj);
		if (status != ISNS_SUCCESS) {
			/*
			 * 5.7.5.4
			 *
			 * In the event of an error, this response message
			 * contains the appropriate status code as well
			 * as a list of objects from the original DevDereg
			 * message that were not successfully deregistered
			 * from the iSNS database.  This list of objects
			 * is contained in the Operating Attributes
			 * of the DevDeregRsp message.	Note that an
			 * attempted deregistration of a non-existent
			 * object does not constitute an isns_error, and
			 * non-existent entries SHALL not be returned
			 * in the DevDeregRsp message.
			 */
			/*
			 * Implementation: right now this doesn't work
			 * at all, because isns_msg_set_error will
			 * discard the entire message except for the
			 * status word.
			 */
			isns_debug_message("Failed to deregister object: %s (0x%04x)\n",
				isns_strerror(status), status);

			isns_object_extract_all(obj, &reply->is_operating_attrs);
			dereg_status = status;
			continue;
		}

		/*
		 * 5.7.5.4
		 * If all Nodes and Portals associated with a Network
		 * Entity are deregistered, then the Network Entity
		 * SHALL also be removed.
		 * [...]
		 * If both the Portal and iSCSI Storage Node objects
		 * associated with a Portal Group object are removed,
		 * then that Portal Group object SHALL also be removed.
		 * The Portal Group object SHALL remain registered
		 * as long as either of its associated Portal or
		 * iSCSI Storage Node objects remain registered.  If a
		 * deleted Storage Node or Portal object is subsequently
		 * re-registered, then a relationship between the re-
		 * registered object and an existing Portal or Storage
		 * Node object registration, indicated by the PG object,
		 * SHALL be restored.
		 */
		/* isns_db_remove takes care of removing dead entities,
		 * and dead portal groups.
		 */
	}

	if (status == ISNS_SUCCESS)
		status = dereg_status;

done:
	isns_object_list_destroy(&objects);
	*result = reply;
	return status;
}