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

📄 iscsid.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 5 页
字号:
	return portal;}static char discovery_buffer[256 * 1024];static intfind_host_no(struct iscsi_session_config *config){	char isid[7], tpgt[10];	char *tname = config->target->TargetName;	struct sysfs_attribute *attr1, *attr2, *attr3;	struct sysfs_class_device *cldev;	struct dlist *dev_list;	struct sysfs_class *sfclass;	int host_num = -1;	sprintf(isid, "%02x%02x%02x%02x%02x%02x", config->isid[0],		config->isid[1], config->isid[2], config->isid[3],		config->isid[4], config->isid[5]);	sprintf(tpgt, "%hu", config->portal->descriptor->tag);	if(!(sfclass = sysfs_open_class(ISCSI_TRANSPORT_CLASS))) {		errormsg(" error opening iscsi_transport_class in sysfs\n");		return host_num;	}	if(!(dev_list = sysfs_get_class_devices(sfclass))) {		errormsg("error opening iscsi_transport_class in sysfs\n");		sysfs_close_class(sfclass);		return host_num;	}	dlist_for_each_data(dev_list, cldev, struct sysfs_class_device) {		attr1 = sysfs_get_classdev_attr(cldev, "isid");		attr2 = sysfs_get_classdev_attr(cldev, "target_name");		attr3 = sysfs_get_classdev_attr(cldev, "tpgt");		if (!strncmp(attr1->value, isid, strlen(isid)) &&		    !strncmp(attr2->value, tname, strlen(tname)) &&		    !strncmp(attr3->value, tpgt, strlen(tpgt))) {			sscanf(cldev->name + 6, "%d", &host_num);			break;		}	}	if (host_num == -1) {		errormsg("Session for target %s with isid %s, target portal"			 "group tag %s does not exist", tname, isid, tpgt);	}	sysfs_close_class(sfclass);	return host_num;}voidoffline_warn(char *offline, struct iscsi_session_config *config){	int host_no;	host_no = find_host_no(config);	if (host_no > -1)		logmsg(AS_ERROR, "%s has been received on Host %d on %s. Set "		       "ConnFailTimeout to a low value like 5 secs through "		       "sysfs. Unmount all the mounted devices of this host if "		       "any. Shutdown Host number %d through sysfs.\n", offline,		       host_no, config->portal->descriptor->address, host_no);}static voidupdate_async_data(struct iscsi_discovery_process *discovery,		  struct iscsi_config *config,		  struct iscsi_target_list *targets){	char *input, *line, *eol;	char *address = NULL;	int count;	int tgtoffline = 0;	int portoffline = 0;	struct iscsi_target *target = NULL, *existing_target = NULL;	input = discovery_buffer;	for (;;) {		/* read discovery info into the buffer, always leaving the		 * last byte for a NUL terminator		 */		count =		    read(discovery->pipe_fd, input,			 sizeof (discovery_buffer) - 1 - (input -							  discovery_buffer));		if (count > 0) {			char *data = input;			input += count;			*input = '\0';			debugmsg(7, "discovery %p pipe %d, %d bytes input '%s'"				 , discovery, discovery->pipe_fd, count, data);			discovery->in_progress = 1;		} else if (count == 0) {			/* end of file, guess we're done */			debugmsg(7, "discovery %p pipe at end of file",				 discovery, discovery->pipe_fd);			close(discovery->pipe_fd);			discovery->pipe_fd = -1;			discovery->in_progress = 0;			discovery_processes.changed = 1;			/* so that we remove the discovery process */			return;		} else if (errno != EINTR) {			/* some sort of non-retryable error */			errormsg("error reading from discovery process %p",				 discovery);			/* FIXME: maybe we should kill or restart			 * the discovery process.			 */			return;		}		/* scan the input for line boundaries, and process each line */		line = discovery_buffer;		while (line < input) {			if ((eol = strchr(line, '\n'))) {				*eol = '\0';				debugmsg(7, "processing pipe line %p: %s",					 line, line);				if (eol == line) {					/* ignore blank lines */				} else if (strcmp(line, ";") == 0) {					/* The target record has been					 * terminated we are done processing					 * the record					 */				} else if (strcmp(line, "!") == 0) {					/* This means the end of data in pipe					 * we are done with reading data					 */					if (tgtoffline)						/*						 * target offline occured need						 * to orphan the target						 */						delete_target(existing_target,							      targets);					if (portoffline)						process_targets_for_portal						    (address, targets, config);					return;				} else if (strncmp(line, "PF=", 3) == 0) {					char *port;					address = line + 3;					if ((port = strrchr(line, ':'))) {						*port = '\0';						port++;					}					debugmsg(1, "Failing over all targets "						 "using portal %s\n", address);					portoffline = 1;				} else if (strncmp(line, "TF=", 3) == 0) {					char *name = line + 3;					debugmsg(1, " Deleting target %s\n",						 name);					tgtoffline = 1;					/* start of a target description. If					 * the target has already been					 * discovered, we will need to delete					 * it					 */					if ((existing_target =					     find_target(name, targets))) {						target = existing_target;						/* track which discovery						 * process owns this target						 */						if (target->discovery						    == NULL) {							target->discovery =								discovery;							target->discovered = 1;						} else if (target->discovery ==							   discovery) {							target->discovered = 1;							/* we found it again */						}					}				} else {					debugmsg(1, " Could not read %s\n",						 line);				}				/* on to the next line */				line = eol + 1;			} else {				/* move any remaining input to the beginning of 				 * the buffer, and wait for more input				 */				size_t bytes = input - line;				debugmsg(7, "deferring partial pipe line %p: "					 "%s", line, line);				memmove(discovery_buffer, line, bytes);				line = input = discovery_buffer + bytes;				break;			}		}		if (line >= input)			input = discovery_buffer;	}}static voidmark_targets_undiscovered(struct iscsi_discovery_process *discovery,			  struct iscsi_target_list *targets){	struct iscsi_target *target;	for (target = targets->head; target; target = target->next) {		if (target->discovery == discovery) {			debugmsg(3, "discovery %p expecting to rediscover "				 "target %p name %s", discovery, target,				 target->TargetName);			target->discovered = 0;		}	}}static struct iscsi_auth_config *get_discovery_auth_options(struct iscsi_discovery_process *discovery){	struct iscsi_auth_config *discovery_auth_options = NULL;	if (discovery->entry) {		switch (discovery->entry->type) {		case CONFIG_TYPE_SENDTARGETS:			{				struct iscsi_sendtargets_config *sendtargets =					discovery->entry->config.sendtargets;				debugmsg(7, "discovery %p will propagate "					 "authentication options to "					 "discovered targets", discovery);				discovery_auth_options =					&sendtargets->auth_options;				break;			}		case CONFIG_TYPE_SLP:			{				struct iscsi_slp_config *slp =					discovery->entry->config.slp;				debugmsg(7, "discovery %p will propagate "					 "authentication options to "					 "discovered targets", discovery);				discovery_auth_options = &slp->auth_options;				break;			}		case CONFIG_TYPE_DISCOVERY_FILE:			{				struct iscsi_discovery_file_config *file =					discovery->entry->config.file;				debugmsg(7, "discovery %p will propagate "					 "authentication options to "					 "discovered targets", discovery);				discovery_auth_options = &file->auth_options;				break;			}		}	}	return discovery_auth_options;}static voiddiscovery_finished(struct iscsi_discovery_process *discovery,	       struct iscsi_target_list *targets){	int orphans = 0;	struct iscsi_target *target;	discovery->in_progress = 0;	/* orphan any of our targets that we didn't rediscover this round, so	 * that some other discovery process can claim them.	 */	for (target = targets->head; target; target = target->next) {		if ((target->discovery == discovery) && !target->discovered) {			debugmsg(3, "discovery process %p orphaning "				 "undiscovered target %p name %s", discovery,				 target, target->TargetName);			target->discovery = NULL;			orphans = 1;		}	}	if (orphans) {		struct iscsi_discovery_process *other;		/* trigger rediscover for all other discovery processes, in the		 * hopes that one of them will claim the targets we orphaned.		 */		for (other = discovery_processes.head; other; other = other->			     next) {			if (other != discovery)				trigger_rediscovery(other);		}	}}static voidadd_new_target(struct iscsi_target *new_target,	       struct iscsi_portal_descriptor *first_portal,	       struct iscsi_config *config,	       struct iscsi_auth_config *discovery_auth_options,	       struct iscsi_target_list *targets){	struct iscsi_target_config *target_config;	new_target->new_portals = first_portal;	/* create the per-target configuration */	target_config = create_target_config(new_target->TargetName,					     first_portal, config,					     discovery_auth_options);	if (target_config) {		/* replace any unprocessed new config with the latest one */		if (new_target->new_config) {			debugmsg(6, "freeing unused new target config %p "				 "for new target %p", new_target->new_config,				 new_target);			free_target_config(new_target->new_config);		}		new_target->new_config = target_config;		targets->check_configs = 1;		debugmsg(6, "new target %p has new target config %p and "			 "portals %p", new_target, target_config, first_portal);	} else {		logmsg(AS_ERROR, "failed to allocate new target config for "		       "new target %p", new_target);	}	/* add the target to the list */	add_target(targets, new_target);}static voidupdate_existing_target(struct iscsi_target *existing_target,		       struct iscsi_target *target,		       struct iscsi_target_list *targets,		       struct iscsi_discovery_process *discovery,		       struct iscsi_auth_config *discovery_auth_options,		       struct iscsi_config *config,		       struct iscsi_portal_descriptor *first_portal){	int make_config = 0;	struct iscsi_auth_config *auth_options = NULL;	struct iscsi_portal_descriptor *port = NULL;	struct iscsi_target_config *target_config;	/* this target already exists, possibly update it */	if (!same_portal_descriptors(first_portal,				     existing_target->current_portals)) {		debugmsg(1, "target %p portal descriptors have changed\n",			 existing_target);		make_config = 1;		/* stay with any existing auth credentials unless the		 * discovery overrides.		 */		if (existing_target->new_config)			auth_options = &existing_target->new_config->				auth_options;		else if (existing_target->current_config)			auth_options = &existing_target->current_config->				auth_options;		else			auth_options = NULL;	} else {		for (port = existing_target->current_portals; port; port =			     port->next)			debugmsg(7, "target %p portal descriptors have not "				 "changed\n", existing_target);	}	/* make a new config if we need to propagate different auth credentials	 * to prevent flapping if the same target is found by multiple	 * discovery processes, we only let the first process to discover the	 * target pass along auth credentials.	 * A config reload resets this, so that new credentials can be obtained	 * after a reload. Also, when the owning process stops discovering that	 * target, it will orphan it so that any other discovery processes that	 * still find it can propagate discovery credentials to it.	 */	if (discovery && ((target->discovery == NULL)			  || (target->discovery == discovery))) {		/* check if the credentials need to change */		if (existing_target->current_config		    && discovery_auth_options) {			if (memcmp(&existing_target->current_config->				   auth_options, discovery_auth_options,				   sizeof (existing_target->current_config->					   auth_options))) {				debugmsg(1, "target %p discovered by %p needs "					 "to update to new auth credentials "					 "from discovery %p\n",					 existing_target,					 existing_target->discovery,					 discovery);				auth_options = discovery_auth_options;				make_config = 1;			} else				debugmsg(7, "target %p discovered by %p does "					 "not need to update to auth "					 "credentials from discovery %p\n",					 existing_target,					 existing_target->discovery,					 discovery);		}		/* ensure that only this discovery process gets to propagate		 * credentials to this target		 */		target->discovery = discovery;	} else		if (discovery_auth_options) {			debugmsg(3, "target %p discovered by %p ignoring auth "				 "credentials from discovery %p", target,				 target->discovery, discovery);		}	if (make_config) {		target_config =	create_target_config(existing_target->						     TargetName, first_portal,						     config, auth_options);		if (target_config) {			/* update the new_config */			if (existing_target->new_config) {				debugmsg(6, "freeing unused new target config "					 "%p for target %p",					 existing_target->new_config,					 existing_target);				free_target_config(existing_target->						   new_config);			}			existing_target->new_config = target_config;			/* update the new portals */			if (existing_target->new_portals) {				debugmsg(6, "freeing unused new portal "					 "descriptors %p for target %p",					 existing_target->new_portals,					 existing_target);				free_portal_descriptors(existing_target->							new_portals);			}			existing_target->new_portals = first_portal;			targets->check_configs = 1;			debugmsg(1, "existing target %p has new target config "				 "%p and new portals %p", existing_target,				 target_config, first_portal);		} else {

⌨️ 快捷键说明

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