⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iscsi-discovery.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 4 页
字号:
		 * current target record 		 */		while ((text < nul) && (*text != '\0'))			text++;	}	if (record) {		if (final) {			/* if this is the last PDU of the text sequence, 			 * it also ends a target record 			 */			debugmsg(7,				 "processing final sendtargets record %p, "				 "line %s",				 record, record);			if (add_target_record			    (info, record + 11, text, lun_inventory_changed,			     default_address, default_port, fd)) {				num_targets++;				record = NULL;				truncate_buffer(sendtargets, 0);			} else {				logmsg(AS_ERROR, "failed to add target record");				truncate_buffer(sendtargets, 0);				truncate_buffer(info, valid_info);				goto done;			}		} else {			/* remove the parts of the sendtargets buffer we've			 * processed, and move the parts we haven't to the			 * beginning of the buffer.			 */			debugmsg(7,				 "processed %d bytes of sendtargets data, "				 "%d remaining",				 record - buffer_data(sendtargets),				 buffer_data(sendtargets) +				 data_length(sendtargets) - record);			remove_initial(sendtargets,				       record - buffer_data(sendtargets));		}	}      done:	/* send all of the discovered targets to the parent daemon */	if (append_string(info, final ? "!\n" : ".\n")) {		write_buffer(info, fd);		truncate_buffer(info, 0);		if (final) {			record_begin = 0;		}		debugmsg(4, "sent %d targets to parent daemon", num_targets);		return 1;	} else {		logmsg(AS_ERROR, "couldn't send %d targets to parent",		       num_targets);		truncate_buffer(info, 0);		return 0;	}	return 1;}static intadd_async_record(struct string_buffer *info, char *record, int targetoffline,		 int fd){	int length = strlen(record);	size_t original = data_length(info);	debugmsg(7, " adding async record for %s", record);	if (targetoffline) {		/* We have received targetoffline event */		if (length > TARGET_NAME_MAXLEN) {			logmsg(AS_ERROR, "Targetname %s too long, ignoring",			       record);			return 0;		}	}	if (!append_sprintf	    (info, targetoffline ? "ATF=%s\n" : "APF=%s\n", record)) {		logmsg(AS_ERROR, "couldn't report the record\n");		truncate_buffer(info, original);		return 0;	} else if (!append_string(info, ";\n")) {		logmsg(AS_ERROR,		       "failed to terminate target record, ignoring target %s",		       record);		truncate_buffer(info, original);	}	return 1;}static voidclear_timer(struct timeval *timer){	memset(timer, 0, sizeof (*timer));}static intprocess_async_event_text(struct string_buffer *sendtargets,			 struct string_buffer *info, struct timeval *timer,			 int fd){	char *text = buffer_data(sendtargets);	int targetoffline = 0;	int slen = (ntohs(*(short *) (text)));	text = text + 2 + slen;	if (strncmp(text, "X-com.cisco.targetOffline=", 26) == 0) {		targetoffline = 1;		if (!add_async_record(info, text + 26, targetoffline, fd)) {			logmsg(AS_ERROR, "failed to add async record");			return 0;		}		clear_timer(timer);	} else if (strncmp(text, "X-com.cisco.portalOffline=", 26) == 0) {		targetoffline = 0;		if (!add_async_record(info, text + 26, targetoffline, fd)) {			logmsg(AS_ERROR, "failed to add async record");			return 0;		}		clear_timer(timer);	} else {		debugmsg(1, "sendtargets for the other events\n");		return 1;	}	if (append_string(info, "!\n")) {		write_buffer(info, fd);		truncate_buffer(info, 0);		debugmsg(4, "sent async event record to parent daemon\n");		return 1;	} else {		logmsg(AS_ERROR, "couldn't send async event record \n");		return 0;	}}/* set timer to now + seconds */static voidset_timer(struct timeval *timer, int seconds){	if (timer) {		memset(timer, 0, sizeof (*timer));		gettimeofday(timer, NULL);		timer->tv_sec += seconds;	}}static inttimer_expired(struct timeval *timer){	struct timeval now;	/* no timer, can't have expired */	if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0)))		return 0;	memset(&now, 0, sizeof (now));	gettimeofday(&now, NULL);	if (now.tv_sec > timer->tv_sec)		return 1;	if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec))		return 1;	return 0;}static intmsecs_until(struct timeval *timer){	struct timeval now;	int msecs;	long partial;	/* no timer, can't have expired, infinite time til it expires */	if ((timer == NULL) || ((timer->tv_sec == 0) && (timer->tv_usec == 0)))		return -1;	memset(&now, 0, sizeof (now));	gettimeofday(&now, NULL);	/* already expired? */	if (now.tv_sec > timer->tv_sec)		return 0;	if ((now.tv_sec == timer->tv_sec) && (now.tv_usec >= timer->tv_usec))		return 0;	/* not expired yet, do the math */	partial = timer->tv_usec - now.tv_usec;	if (partial < 0) {		partial += 1000 * 1000;		msecs = (partial + 500) / 1000;		msecs += (timer->tv_sec - now.tv_sec - 1) * 1000;	} else {		msecs = (partial + 500) / 1000;		msecs += (timer->tv_sec - now.tv_sec) * 1000;	}	return msecs;}static intsoonest_msecs(struct timeval *t1, struct timeval *t2, struct timeval *t3){	int m1 = msecs_until(t1);	int m2 = msecs_until(t2);	int m3 = msecs_until(t3);	/* infinity is -1, handle it specically */	if ((m1 == -1) && (m2 == -1))		return m3;	if ((m1 == -1) && (m3 == -1))		return m2;	if ((m2 == -1) && (m3 == -1))		return m1;	if (m1 == -1)		return (m2 < m3) ? m2 : m3;	if (m2 == -1)		return (m1 < m3) ? m1 : m3;	if (m3 == -1)		return (m1 < m2) ? m1 : m2;	if (m1 < m2)		return (m1 < m3) ? m1 : m3;	else		return (m2 < m3) ? m2 : m3;}static intalloc_auth_buffers(struct iscsi_session *session){	session->auth_client_block =		(struct iscsi_acl *)malloc(sizeof(*session->auth_client_block));	if (!session->auth_client_block)		goto error;	session->auth_recv_string_block =		(struct auth_str_block *)		malloc(sizeof(*session->auth_recv_string_block));	if (!session->auth_recv_string_block)		goto error;	session->auth_send_string_block =		(struct auth_str_block *)		malloc(sizeof(*session->auth_send_string_block));	if (!session->auth_send_string_block)		goto error;	session->auth_recv_binary_block =		(struct auth_large_binary *)		malloc(sizeof(*session->auth_recv_binary_block));	if (!session->auth_recv_binary_block)		goto error;	session->auth_send_binary_block =		(struct auth_large_binary *)		malloc(sizeof(*session->auth_send_binary_block));	if (!session->auth_send_binary_block)		goto error;	return 0; error:	free(session->auth_client_block);	free(session->auth_recv_string_block);	free(session->auth_send_string_block);	free(session->auth_recv_binary_block);	iscsi_err("Session couldn't allocate authentication stuctures\n");	return -ENOMEM;}static void free_session(struct iscsi_session **session){	free((*session)->auth_client_block);	free((*session)->auth_recv_string_block);	free((*session)->auth_send_string_block);	free((*session)->auth_recv_binary_block);	free((*session)->auth_send_binary_block);	free(*session);	*session = NULL;}static struct iscsi_session *init_new_session(struct iscsi_sendtargets_config *config,		 struct iscsi_discovery_process *process){	struct iscsi_session *session;		session = calloc(1, sizeof (*session));	if (session == NULL) {		logmsg(AS_ERROR,		       "discovery process to %s:%d failed to "		       "allocate a session\n",		       config->address, config->port);		goto done;	}	if (alloc_auth_buffers(session)) {		free(session);		session = NULL;		goto done;	}	/* initialize the session */	session->socket_fd = -1;	session->type = ISCSI_SESSION_TYPE_DISCOVERY;	session->login_timeout =	    config->connection_timeout_options.login_timeout;	session->auth_timeout = config->connection_timeout_options.auth_timeout;	session->active_timeout =	    config->connection_timeout_options.active_timeout;	session->idle_timeout = config->connection_timeout_options.idle_timeout;	session->ping_timeout = config->connection_timeout_options.ping_timeout;	session->send_async_text =	    config->continuous ? config->send_async_text : -1;	/* OUI and uniqifying number */	session->isid[0] = DRIVER_ISID_0;	session->isid[1] = DRIVER_ISID_1;	session->isid[2] = DRIVER_ISID_2;	session->isid[3] = (process->order >> 16) & 0xFF;	session->isid[4] = (process->order >> 8) & 0xFF;	session->isid[5] = (process->order >> 0) & 0xFF;	session->initiator_name = daemon_config.initiator_name;	session->initiator_alias = daemon_config.initiator_alias;	session->header_digest = ISCSI_DIGEST_NONE;	session->data_digest = ISCSI_DIGEST_NONE;	session->max_recv_data_segment_len =	    DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;	session->max_xmit_data_segment_len =	    DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;	session->portal_group_tag = PORTAL_GROUP_TAG_UNKNOWN;	debugmsg(4,		 "sendtargets discovery process %p to %s:%d using "		 "isid 0x%02x%02x%02x%02x%02x%02x",		 process, config->address, config->port, session->isid[0],		 session->isid[1], session->isid[2], session->isid[3],		 session->isid[4], session->isid[5]); done:	return(session);}static intsetup_authentication(struct iscsi_session *session,		     struct iscsi_sendtargets_config *config){	int rc;	rc = 1;		/* if we have any incoming credentials, we insist on authenticating 	 * the target or not logging in at all 	 */	if (config->auth_options.username_in[0]	    || config->auth_options.password_length_in) {		session->bidirectional_auth = 1;		/* sanity check the config */		if ((config->auth_options.username[0] == '\0')		    || (config->auth_options.password_length == 0)) {			logmsg(AS_ERROR,			       "discovery process to %s:%d has incoming "			       "authentication credentials but has no outgoing "			       "credentials configured\n",			       config->address, config->port);			logmsg(AS_ERROR,			       "discovery process to %s:%d exiting, bad "			       "configuration\n",			       config->address, config->port);			rc = 0;			goto done;		}	} else {		/* no or 1-way authentication */		session->bidirectional_auth = 0;	}	/* copy in whatever credentials we have */	strncpy(session->username, config->auth_options.username,		sizeof (session->username));	session->username[sizeof (session->username) - 1] = '\0';	if ((session->password_length = config->auth_options.password_length))		memcpy(session->password, config->auth_options.password,		       session->password_length);	strncpy(session->username_in, config->auth_options.username_in,		sizeof (session->username_in));	session->username_in[sizeof (session->username_in) - 1] = '\0';	if ((session->password_length_in =	     config->auth_options.password_length_in))		memcpy(session->password_in, config->auth_options.password_in,		       session->password_length_in); done:	return(rc);}	static intprocess_recvd_pdu(struct iscsi_hdr *pdu,		  struct iscsi_sendtargets_config *config,		  struct iscsi_session *session,		  struct string_buffer *sendtargets,		  struct string_buffer *info,		  int *lun_inventory_changed,		  char *default_port,		  struct iscsi_discovery_process *process,		  int *active,		  int *long_lived,		  struct timeval *async_timer,		  char *data){	int rc=0;		switch (pdu->opcode) {		case ISCSI_OP_TEXT_RSP:{			struct iscsi_txt_rsp_hdr *text_response =				(struct iscsi_txt_rsp_hdr *) pdu;			int dlength = ntoh24(pdu->dlength);			int final = (text_response->flags & ISCSI_FLAG_FINAL)||				(text_response-> ttt == ISCSI_RSVD_TASK_TAG);			debugmsg(4, "discovery session to %s:%d received text"				 " response, %d data bytes, ttt 0x%x, "				 "final 0x%x",				 config->address,				 config->port,				 dlength,				 ntohl(text_response->ttt),				 text_response->flags & ISCSI_FLAG_FINAL);			/* mark how much more data in the sendtargets 			 * buffer is now valid 			 */			enlarge_data (sendtargets, dlength);			/* process as much as we			 * can right now 			 */			process_sendtargets_response (sendtargets,						      info, final,						      *lun_inventory_changed,						      config->address,						      default_port,						      process->pipe_fd);			if (final) {				/* SendTargets exchange is now complete 				 */				*active = 0;				*lun_inventory_changed = 1;					/* from now on, after any reconnect, 				 * assume LUNs may have changed 				 */			} else {				/* ask for more targets */				if (!iterate_targets(session,						     text_response->ttt)) {					rc = DISCOVERY_NEED_RECONNECT;					goto done;				}			}			break;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -