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

📄 iscsi-discovery.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 4 页
字号:
		case ISCSI_OP_ASYNC_MSG:{			struct iscsi_async_msg_hdr *async_hdr =				(struct iscsi_async_msg_hdr *) pdu;			int dlength = ntoh24(pdu->dlength);			short senselen;			char logbuf[128];			int i;										/*			 * If we receive an async message stating			 * the target wants to close the connection,			 * then don't try to reconnect anymore.			 * This is reasonable, so we don't log			 * anything here.			 */			if ((async_hdr->async_event ==			      ISCSI_ASYNC_MSG_REQUEST_LOGOUT)||			     (async_hdr->async_event ==			      ISCSI_ASYNC_MSG_DROPPING_CONNECTION)||			     (async_hdr->async_event ==			      ISCSI_ASYNC_MSG_DROPPING_ALL_CONNECTIONS)) {				*long_lived=0;				break;			}										/*			 * Log info about the async message.			 */			logmsg(AS_NOTICE,			       "Received Async Msg from target, Event = %d, "			       "Code = %d, Data Len = %d\n",			       async_hdr->async_event,			       async_hdr->async_vcode, dlength);										/*			 * If there was data, print out the first 8 bytes			 */			if (dlength > 0) {				memset(logbuf, 0, sizeof(logbuf));				for (i=0; i<8 && i<dlength; ++i) {					sprintf(logbuf+i*5, "0x%02x ",						data[i]);				}				logmsg (AS_NOTICE, " Data[0]-[%d]: %s\n",					i<dlength ? dlength-1 : i-1,					logbuf);			}																	if (dlength > (sizeof (short))) {				senselen = (ntohs(*(short *) (data)));												debugmsg(1, " senselen = %d\n", senselen);				if (dlength > senselen + 2) {					debugmsg(1,						 " recvd async event : %s\n",						 data + 2 + senselen);				}			}			*long_lived = 1;										/*			 * Arrange for a rediscovery to  occur in the near			 * future.  We use a timer so that we merge			 * multiple events that occur in rapid succession,			 * and only rediscover once for each  burst of			 * Async events.			 */			set_timer(async_timer, 1);			if (*active) {				debugmsg(4,					 "discovery process %p received Async "					 "event while active", process);			} else {				debugmsg(4,					 "discovery process %p received Async "					 "event while idle", process);			}			process_async_event_text(sendtargets, info,						 async_timer,						 process->pipe_fd);			break;		}		case ISCSI_OP_NOOP_IN:{			struct iscsi_nop_in_hdr *nop =				(struct iscsi_nop_in_hdr *) pdu;			/*			 * The iSCSI spec doesn't allow Nops on			 * discovery sessions, but some targets			 * use them anyway.  If we receive one, we			 * can safely assume that the target			 * supports long-lived discovery sessions			 * (otherwise it wouldn't be sending nops			 * to verify the connection is still			 * working).			 */			*long_lived = 1;			debugmsg(4,"discovery session to %s:%d  received"				 " Nop-in with itt %u, ttt %u, dlength %u",				 config->address, config->port,				 ntohl(nop->itt), ntohl(nop->ttt),				 ntoh24(nop->dlength));			if (nop->ttt != ISCSI_RSVD_TASK_TAG) {				/* reply to the  Nop-in */				if (!send_nop_reply(session, nop, data,						    session->active_timeout)) {					logmsg (AS_ERROR,						"discovery session to %s:%d "						"failed to send Nop reply, "						"ttt %u, reconnecting",						 config->address,						 config->port,						 ntohl(nop->ttt));					rc = DISCOVERY_NEED_RECONNECT;					goto done;				}			}			break;		}		case ISCSI_OP_REJECT:{			struct iscsi_reject_hdr *reject =				(struct iscsi_reject_hdr *) pdu;			int dlength = ntoh24(pdu->dlength);										logmsg(AS_ERROR, "reject, dlength=%d, "			       "data[0]=0x%x\n",			       dlength, data[0]);			logmsg(AS_ERROR,			       "Received a reject from the target "			       "with reason code = 0x%x\n",			       reject->reason);			/*			 * Just attempt to reconnect if we receive a reject			 */			rc = DISCOVERY_NEED_RECONNECT;			goto done;			break;		}		default:{			logmsg(AS_NOTICE,			       "discovery session to %s:%d received "			       "unexpected opcode 0x%x",			       config->address, config->port, pdu->opcode);			rc = DISCOVERY_NEED_RECONNECT;			goto done;		}	} done:	return(rc);}	/* * Make a best effort to logout the session, then disconnect the * socket. */static voidiscsi_logout_and_disconnect(struct iscsi_session * session){	struct iscsi_logout_hdr logout_req;	struct iscsi_logout_rsp_hdr logout_resp;	int rc;		/*	 * Build logout request header	 */	memset(&logout_req, 0, sizeof (logout_req));	logout_req.opcode = ISCSI_OP_LOGOUT_CMD | ISCSI_OP_IMMEDIATE;	logout_req.flags = ISCSI_FLAG_FINAL |		(ISCSI_LOGOUT_REASON_CLOSE_SESSION & ISCSI_FLAG_LOGOUT_REASON_MASK);	logout_req.itt = htonl(session->itt);	if (++session->itt == ISCSI_RSVD_TASK_TAG)		session->itt = 1;	logout_req.cmdsn = htonl(session->cmd_sn);	logout_req.expstatsn = htonl(++session->exp_stat_sn);		/*	 * Send the logout request	 */	rc = iscsi_send_pdu(session, (struct iscsi_hdr *)&logout_req,			    ISCSI_DIGEST_NONE, NULL, ISCSI_DIGEST_NONE, 3);	if (!rc) {		logmsg(AS_ERROR,		       "iscsid: iscsi_logout - failed to send logout PDU.\n");		goto done;	}		/*	 * Read the logout response	 */	memset(&logout_resp, 0, sizeof(logout_resp));	rc = iscsi_recv_pdu(session, (struct iscsi_hdr *)&logout_resp,			    ISCSI_DIGEST_NONE, NULL, 0, ISCSI_DIGEST_NONE, 1);	if (!rc) {		logmsg(AS_ERROR,		       "iscsid: logout - failed to receive logout resp\n");		goto done;	}	if (logout_resp.response != ISCSI_LOGOUT_SUCCESS) {		logmsg(AS_ERROR, "iscsid: logout failed - response = 0x%x\n",		       logout_resp.response);	}	 done:    	/*	 * Close the socket.	 */	iscsi_disconnect(session);}static voidsendtargets_discovery_process(struct iscsi_discovery_process *process){	struct iscsi_sendtargets_config *config =	    process->entry->config.sendtargets;	struct sigaction action;	struct iscsi_session *session;	struct hostent *hostn = NULL;	struct pollfd pfd;	struct iscsi_hdr pdu_buffer;	struct iscsi_hdr *pdu = &pdu_buffer;	char *data = NULL;	char *end_of_data;	int long_lived = (config->continuous > 0) ? 1 : 0;	int lun_inventory_changed = 0;	int active = 0;	struct timeval connection_timer, async_timer;	int timeout;	int rc;	struct string_buffer sendtargets;	struct string_buffer info;	uint8_t status_class = 0, status_detail = 0;	unsigned int login_failures = 0;	int login_delay = 0;	char ip_address[16];	char default_port[12];	int ip_length = 0;	int port = config->port;	/* initial setup */	process->pid = getpid();	debugmsg(1,		 "sendtargets discovery process %p starting, address %s:%d, "		 "continuous %d",		 process, config->address, config->port, config->continuous);	memset(&pdu_buffer, 0, sizeof (pdu_buffer));	clear_timer(&connection_timer);	clear_timer(&async_timer);	/* set SIGTERM, SIGINT to kill the process */	memset(&action, 0, sizeof (struct sigaction));	action.sa_sigaction = NULL;	action.sa_flags = 0;	action.sa_handler = SIG_DFL;	sigaction(SIGTERM, &action, NULL);	sigaction(SIGINT, &action, NULL);	/* set SIGPIPE to be ignored, so that we get EPIPE */	action.sa_handler = SIG_IGN;	sigaction(SIGPIPE, &action, NULL);	/* set SIGHUP to request a rediscovery */	action.sa_handler = sighup_handler;	sigaction(SIGHUP, &action, NULL);	/* check if a signal arrived before we reset the handler */	if (iscsi_process_should_exit()) {		debugmsg(1,			 "sendtargets discovery process %p,address %d:%d "			 "exiting\n",			 process, config->address, config->port);		exit(0);	}	/* allocate data buffers for SendTargets data and discovery pipe info */	init_string_buffer(&sendtargets, 32 * 1024);	init_string_buffer(&info, 8 * 1024);	/* allocate a new session, and initialize default values */	session = init_new_session(config, process);	if (session == NULL) {		exit(1);	}	/* resolve the DiscoveryAddress to an IP address */	while (!hostn) {		hostn = gethostbyname(config->address);		if (hostn) {			/* save the resolved address */			port = config->port;			ip_length = hostn->h_length;			memcpy(&ip_address, hostn->h_addr,			       MIN(sizeof (ip_address), hostn->h_length));			/* FIXME: IPv6 */			debugmsg(4, "resolved %s to %u.%u.%u.%u\n",				 config->address, ip_address[0], ip_address[1],				 ip_address[2], ip_address[3]);		} else {			errormsg("cannot resolve host name %s",				 config->address);			sleep(1);		}		if (iscsi_process_should_exit()) {			free_session(&session);			exit(0);		}	}	sprintf(default_port, "%d", config->port);	debugmsg(4,		 "discovery timeouts: login %d, auth %d, active %d, "		 "idle %d, ping %d",		 session->login_timeout, session->auth_timeout,		 session->active_timeout, session->idle_timeout,		 session->ping_timeout);	/* setup authentication variables for the session*/	rc = setup_authentication(session, config);	if (rc == 0) {		free_session(&session);		exit(0);	}		      set_address:	/*	 * copy the saved address to the session,	 * undoing any temporary redirect	 */	session->port = port;	session->ip_length = ip_length;	memcpy(session->ip_address, ip_address,	       MIN(sizeof (session->ip_address), ip_length));      reconnect:	iscsi_disconnect(session);	session->cmd_sn = 1;	session->itt = 1;	session->portal_group_tag = PORTAL_GROUP_TAG_UNKNOWN;	/*	 * if we're violating the protocol anyway, there's no reason	 * to be picky about sending keys.	 */	session->vendor_specific_keys = long_lived;	/* slowly back off the frequency of login attempts */	if (login_failures == 0)		login_delay = 0;	else if (login_failures < 10)		login_delay = 1;	/* 10 seconds at 1 sec each */	else if (login_failures < 20)		login_delay = 2;	/* 20 seconds at 2 sec each */	else if (login_failures < 26)		login_delay = 5;	/* 30 seconds at 5 sec each */	else if (login_failures < 34)		login_delay = 15;	/* 60 seconds at 15 sec each */	else		login_delay = 60;	/* after 2 minutes, try once a minute */	if (login_delay) {		debugmsg(4,			 "discovery session to %s:%d sleeping for %d "			 "seconds before next login attempt",			 config->address, config->port, login_delay);		sleep(login_delay);	}	if (!iscsi_connect(session)) {		/* FIXME: IPv6 */		logmsg(AS_ERROR, "Connection to Discovery Address %u.%u.%u.%u "		       "failed", session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3]);		login_failures++;		/* If a temporary redirect sent us to something unreachable, 		 * we want to go back to the original IP address, so make sure 		 * we reset the session's IP.		 */		goto set_address;	}	logmsg(AS_NOTICE, "Connected to Discovery Address %u.%u.%u.%u",	       session->ip_address[0], session->ip_address[1],	       session->ip_address[2], session->ip_address[3]);	debugmsg(4, "discovery session to %s:%d starting iSCSI login on fd %d",		 config->address, config->port, session->socket_fd);	status_class = 0;	status_detail = 0;	switch (iscsi_login		(session, buffer_data(&sendtargets),		 unused_length(&sendtargets), &status_class, &status_detail)) {	case LOGIN_OK:		break;	case LOGIN_IO_ERROR:	case LOGIN_WRONG_PORTAL_GROUP:	case LOGIN_REDIRECTION_FAILED:		/* try again */		/* FIXME: IPv6 */		logmsg(AS_NOTICE, "retrying discovery login to %u.%u.%u.%u",		       session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3]);		iscsi_disconnect(session);		login_failures++;		goto set_address;	default:	case LOGIN_FAILED:	case LOGIN_NEGOTIATION_FAILED:	case LOGIN_AUTHENTICATION_FAILED:	case LOGIN_VERSION_MISMATCH:	case LOGIN_INVALID_PDU:		/* FIXME: IPv6 */		logmsg(AS_ERROR,		       "discovery login to %u.%u.%u.%u failed, giving up",		       session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3]);		iscsi_disconnect(session);		free_session(&session);		exit(0);	}	/* check the login status */	switch (status_class) {	case ISCSI_STATUS_CLS_SUCCESS:		/* FIXME: IPv6 */		debugmsg(4, "discovery login success to %u.%u.%u.%u",			 session->ip_address[0], session->ip_address[1],			 session->ip_address[2], session->ip_address[3]);		login_failures = 0;		break;	case ISCSI_STATUS_CLS_REDIRECT:		switch (status_detail) {			/* the session IP address was changed by the login			 * library, so just try again with this portal			 * config but the new address.			 */		case ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP:			/* FIXME: IPv6 */			logmsg(AS_NOTICE,			       "discovery login temporarily redirected to "			       "%u.%u.%u.%u port %d\n",			       session->ip_address[0], session->ip_address[1],			       session->ip_address[2], session->ip_address[3],			       session->port);			goto reconnect;		case ISCSI_LOGIN_STATUS_TGT_MOVED_PERM:			/* FIXME: IPv6 */			logmsg(AS_NOTICE,			       "discovery login permanently redirected to "			       "%u.%u.%u.%u port %d\n",			       session->ip_address[0], session->ip_address[1],			       session->ip_address[2], session->ip_address[3],			       session->port);			/* make the new address permanent */			ip_length = session->ip_length;			memcpy(ip_address, session->ip_address,			       MIN(sizeof (ip_address), session->ip_length));			port = session->port;			goto reconnect;		default:			logmsg(AS_ERROR,			       "discovery login rejected: redirection type "			       "0x%x not supported\n",			       status_detail);

⌨️ 快捷键说明

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