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

📄 iscsi-discovery.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 4 页
字号:
			goto set_address;		}		break;	case ISCSI_STATUS_CLS_INITIATOR_ERR:		/* FIXME: IPv6 */		logmsg(AS_ERROR,		       "discovery login to %u.%u.%u.%u rejected: "		       "initiator error (%02x/%02x), non-retryable, giving up",		       session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3],		       status_class, status_detail);		iscsi_disconnect(session);		free_session(&session);		exit(0);	case ISCSI_STATUS_CLS_TARGET_ERR:		/* FIXME: IPv6 */		logmsg(AS_ERROR,		       "discovery login to %u.%u.%u.%u rejected: "		       "target error (%02x/%02x)",		       session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3],		       status_class, status_detail);		iscsi_disconnect(session);		login_failures++;		goto reconnect;	default:		/* FIXME: IPv6 */		logmsg(AS_ERROR,		       "discovery login to %u.%u.%u.%u failed, response "		       "with unknown status class 0x%x, detail 0x%x",		       session->ip_address[0], session->ip_address[1],		       session->ip_address[2], session->ip_address[3],		       status_class, status_detail);		iscsi_disconnect(session);		login_failures++;		goto reconnect;	}      rediscover:	/* reinitialize */	truncate_buffer(&sendtargets, 0);	truncate_buffer(&info, 0);	/* we're going to do a discovery regardless */	clear_timer(&async_timer);	/* ask for targets */	if (!request_targets(session)) {		goto reconnect;	}	active = 1;	/* set timeouts */	if (long_lived) {		clear_timer(&connection_timer);	} else {		set_timer(&connection_timer,			  session->active_timeout + session->ping_timeout);	}	/* prepare to poll */	memset(&pfd, 0, sizeof (pfd));	pfd.fd = session->socket_fd;	pfd.events = POLLIN | POLLPRI;	while (!iscsi_process_should_exit()) {		/* check timers before blocking */		if (timer_expired(&connection_timer)) {			if (long_lived || !lun_inventory_changed) {				/* long-lived, or never finished the first 				 * exchange (might be long-lived) 				 */				clear_timer(&connection_timer);				debugmsg(1,				       "discovery session to %s:%d  "				       "reconnecting after connection timeout",				       config->address, config->port);				goto reconnect;			} else {				logmsg(AS_NOTICE,				       "discovery session to %s:%d session "				       "logout, connection timer expired",				       config->address, config->port);				iscsi_logout_and_disconnect(session);				free_session(&session);				exit(0);			}		}		if (active) {			/* ignore the async timer, we're in the middle 			 * of a discovery 			 */			timeout = msecs_until(&connection_timer);		} else {			/* to avoid doing LUN probing repeatedly, try to merge 			 * multiple Async PDUs into one rediscovery by 			 * deferring discovery until a timeout expires.			 */			if (timer_expired(&async_timer)) {				debugmsg(4,					 "discovery session to %s:%d async "					 "timer expired, rediscovering",					 config->address, config->port);				clear_timer(&async_timer);				goto rediscover;			} else				timeout =					soonest_msecs(NULL,						  &connection_timer,						  &async_timer);		}		/* block until we receive a PDU, a TCP FIN, a TCP RST, 		 * or a timeout 		 */		debugmsg(4,			 "discovery process  %s:%d polling fd %d, "			 "timeout in %f seconds",			 config->address, config->port, pfd.fd,			 timeout / 1000.0);		pfd.revents = 0;		rc = poll(&pfd, 1, timeout);		debugmsg(7,			 "discovery process to %s:%d returned from poll, rc %d",			 config->address, config->port, rc);		if (rc > 0) {			if (pfd.revents & (POLLIN | POLLPRI)) {				/* put any PDU data into the 				 * sendtargets buffer for now 				 */				data = buffer_data(&sendtargets) +				    data_length(&sendtargets);				end_of_data =				    data + unused_length(&sendtargets);				timeout = msecs_until(&connection_timer);				if (iscsi_recv_pdu				    (session, pdu, ISCSI_DIGEST_NONE, data,				     end_of_data - data, ISCSI_DIGEST_NONE,				     timeout)) {					/*					 * process iSCSI PDU received					 */					rc = process_recvd_pdu(						pdu,						config,						session,						&sendtargets,						&info,						&lun_inventory_changed,						default_port,						process,						&active,						&long_lived,						&async_timer,						data);					if (rc == DISCOVERY_NEED_RECONNECT)						goto reconnect;					/* reset timers after receiving a PDU */					if (long_lived) {						clear_timer(&connection_timer);					} else {						if (active)							set_timer							    (&connection_timer,							     session->							     active_timeout);						else							/*							 * 3 minutes to try 							 * to go long-lived 							 */							set_timer(&connection_timer, 3 * 60);						}				} else {					if (long_lived) {						debugmsg(1,						       "discovery session to  "						       "%s:%d failed to recv a "						       "PDU response, "						       "reconnecting",						       config->address,						       config->port);						goto reconnect;					} else {						debugmsg(1,						       "discovery session to "						       "%s:%d failed to recv a "						       "PDU response, "						       "terminating",						       config->address,						       config->port);						iscsi_disconnect(session);						free_session(&session);						exit(0);					}				}			}			if (pfd.revents & POLLHUP) {				if (long_lived) {					logmsg(AS_NOTICE,					       "discovery session to  %s:%d "					       "reconnecting after hangup",					       config->address, config->port);					goto reconnect;				} else {					logmsg(AS_NOTICE,					       "discovery session to %s:%d "					       "terminating after hangup",					       config->address, config->port);					iscsi_disconnect(session);					free_session(&session);					exit(0);				}			}			if (pfd.revents & POLLNVAL) {				logmsg(AS_NOTICE, "discovery POLLNVAL");				sleep(1);				goto reconnect;			}			if (pfd.revents & POLLERR) {				logmsg(AS_NOTICE, "discovery POLLERR");				sleep(1);				goto reconnect;			}		} else if (rc < 0) {			if (errno == EINTR) {				/* if we got SIGHUP, reconnect and rediscover */				if (rediscover) {					rediscover = 0;					debugmsg(1, "rediscovery requested");					goto reconnect;				}			} else {				errormsg("poll error");				sleep(5);				free_session(&session);				exit(1);			}		}	}	debugmsg(1, "discovery process to %s:%d exiting",		 config->address, config->port);}static voiddiscovery_file_process(struct iscsi_discovery_process *process){	struct iscsi_discovery_file_config *config =	    process->entry->config.file;	struct sigaction action;	int fd;	int luns_changed = 0;	struct string_buffer sendtargets;	struct string_buffer info;	process->pid = getpid();	debugmsg(1,		 "discovery file process %d, pid %d, file %s, "		 "username %s, password %s",		 process->order, process->pid, config->filename,		 config->auth_options.username, config->auth_options.password);	if (!config->filename || !config->filename[0]) {		logmsg(AS_ERROR, "no discovery filename specified");		exit(0);	}	/* set SIGTERM, SIGINT, and SIGPIPE 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);	sigaction(SIGPIPE, &action, NULL);	/* set SIGHUP to loop again and report LUN INVENTORY CHANGED for testing	 */	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,			 "discovery file process %p pid %d file %s exiting\n",			 process, process->pid, config->filename);		exit(0);	}	/* allocate data buffers for SendTargets data and pipe info */	init_string_buffer(&sendtargets, 32 * 1024);	init_string_buffer(&info, 8 * 1024);      repeat:	truncate_buffer(&sendtargets, 0);	truncate_buffer(&info, 0);	if ((fd = open(config->filename, 0))) {		char *data = buffer_data(&sendtargets);		int rc;		int final = 0;		debugmsg(4,			 "discovery process %p pid %d opened discovery file %s",			 process, process->pid, config->filename);		do {			char *start =			    buffer_data(&sendtargets) +			    data_length(&sendtargets);			char *end = start + config->read_size;			/* don't overflow the buffer */			if (end > (start + unused_length(&sendtargets)))				end = start + unused_length(&sendtargets);			data = start;			/* read a chunk of data */			do {				rc = read(fd, data, end - data);				if (rc > 0) {					data += rc;					enlarge_data(&sendtargets, rc);					debugmsg(7,						 "discovery process %p pid %d "						 "read %d bytes from %s",						 process, process->pid, rc,						 config->filename);				} else if (rc < 0) {					errormsg					    ("discovery process %p pid %d "					     "error reading discovery file %s",					     process, process->pid,					     config->filename);					final = 1;					break;				} else {					debugmsg(4,						 "discovery process %p pid %d "						 "read to the end of "						 "discovery file %s",						 process, process->pid,						 config->filename);					end = data;					final = 1;					break;				}			} while (data < end);			/* convert all the whitespace to NULs */			for (data = start; data < end; data++) {				if ((*data == '\n') || (*data == ' ')				    || (*data == '\t'))					*data = '\0';			}			/* process the data */			process_sendtargets_response(&sendtargets, &info, final,						     luns_changed,						     config->address,						     config->port,						     process->pipe_fd);		} while (!final);	} else {		errormsg		    ("discovery process %p pid %d couldn't open "		     "discovery file %s",		     process, process->pid, config->filename);	}	while (config->continuous) {		/* wait for a signal, then repeat */		luns_changed = 1;		debugmsg(7, "discovery file process waiting for signals");		poll(NULL, 0, -1);		if (rediscover) {			rediscover = 0;			goto repeat;		}	}	exit(0);}#ifdef SLP_ENABLEvoidslp_discovery_process(struct iscsi_discovery_process *discovery){	struct iscsi_slp_config *config = discovery->entry->config.slp;	struct sigaction action;	char *pl;	unsigned short flag = 0;	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);	sigaction(SIGPIPE, &action, NULL);	action.sa_handler = sighup_handler;	sigaction(SIGHUP, &action, NULL);	if (iscsi_process_should_exit()) {		debugmsg(1, "slp discovery process %p exiting\n", discovery);		exit(0);	}	discovery->pid = getpid();	pl = generate_predicate_list(discovery, &flag);	while (1) {		if (flag == SLP_MULTICAST_ENABLED) {			discovery->flag = SLP_MULTICAST_ENABLED;			slp_multicast_srv_query(discovery, pl, GENERIC_QUERY);		}		if (flag == SLP_UNICAST_ENABLED) {			discovery->flag = SLP_UNICAST_ENABLED;			slp_unicast_srv_query(discovery, pl, GENERIC_QUERY);		}		sleep(config->poll_interval);	}	exit(0);}#endifvoiddiscovery_process(struct iscsi_discovery_process *discovery){	if (discovery->entry) {		switch (discovery->entry->type) {		case CONFIG_TYPE_DISCOVERY_FILE:			discovery_file_process(discovery);			break;		case CONFIG_TYPE_SENDTARGETS:			sendtargets_discovery_process(discovery);			break;		case CONFIG_TYPE_SLP:#ifdef SLP_ENABLE			slp_discovery_process(discovery);#else			logmsg(AS_ERROR, "this build does not support SLP");			exit(0);#endif			break;		default:			logmsg(AS_ERROR,			       "can't fork unexpected discovery type %d",			       discovery->entry->type);			break;		}	}}

⌨️ 快捷键说明

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