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

📄 iscsi-linux.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * iSCSI driver for Linux * Copyright (C) 2002 Cisco Systems, Inc. * maintained by linux-iscsi-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * See the file COPYING included with this distribution for more details. * * $Id: iscsi-linux.c,v 1.19 2005/01/11 03:47:09 mikenc Exp $ * */#include <stdarg.h>#include <fcntl.h>#include <errno.h>#include <signal.h>#include <unistd.h>#include <netinet/in.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/utsname.h>#include "iscsi-sfnet.h"#include "iscsi-ioctl.h"#include "iscsi-version.h"#include "iscsi-hooks.h"#include "iscsi-login.h"const char *progname = "iscsid";/* set by signal handlers */static int stop_requested = 0;static int reload_config = 0;#define ISCSI_DEVICE "/dev/iscsictl"static int control_fd = -1;voidsigusr1_handler(int unused){	daemon_config.debug_level++;	debugmsg(1, "received sigusr1, debug level now %d",		 daemon_config.debug_level);}voidsigusr2_handler(int unused){	if (daemon_config.debug_level > 0)		daemon_config.debug_level--;	debugmsg(1, "received sigusr2, debug level now %d",		 daemon_config.debug_level);}voidsigterm_handler(int unused){	debugmsg(1, "received sigterm", getpid());	stop_requested = 1;}voidsighup_handler(int unused){	debugmsg(1, "received sighup", getpid());	reload_config = 1;}/* Note: test and clear semantics */intiscsi_should_reload_config(void){	int ret = reload_config;	reload_config = 0;#ifdef RESET_LUN_PROBING	/* see if it works better to have the kernel module automatically reset	 * whenever the queue empties, and have it ensure the same session is	 * never queued more than once. It's easier to track this in the kernel,	 * and we avoid hanging the daemon if a kernel module bug prevents this	 * reset from ever succeeding.	 */	if (ret) {		/* reset LUN probing now, so that the re-probes we do after		 * reloading the config occur in a reasonable order.		 */		while (ioctl(control_fd, ISCSI_RESET_PROBING, NULL) <= 0) {			if (stop_requested)				exit(0);			usleep(10 * 1000);		}		debugmsg(1, "reset LUN probing before reloading config");	}#endif	return ret;}intiscsi_process_should_exit(void){	return stop_requested;}intopen_control_device(void){	int ctlfd;	ctlfd = open(ISCSI_DEVICE, O_RDWR);	if (ctlfd < 0) {		errormsg("cannot open %s", ISCSI_DEVICE);		return -1;	}	return ctlfd;}/* initialize the daemon_config to it's default state, * process the command line, and do any other initialization needed * for the main daemon process. */voidiscsi_daemon_starting(int argc, char **argv){	int c;	struct sigaction action;	struct utsname host_info;	int retry_count;	/* signal handling */	memset(&action, 0x0, sizeof (action));	action.sa_sigaction = NULL;	action.sa_flags = 0;	action.sa_handler = sigusr1_handler;	sigaction(SIGUSR1, &action, 0);	action.sa_handler = sigusr2_handler;	sigaction(SIGUSR2, &action, 0);	action.sa_handler = sighup_handler;	sigaction(SIGHUP, &action, 0);	action.sa_handler = sigterm_handler;	sigaction(SIGTERM, &action, 0);	sigaction(SIGINT, &action, 0);	openlog(progname, LOG_PID, LOG_DAEMON);	/* configure default files */	daemon_config.pid_file = "/var/run/iscsid.pid";	daemon_config.config_file = "/etc/iscsi.conf";	daemon_config.initiator_name_file = "/etc/initiatorname.iscsi";	/* dup it so that the memory is writable */	/* determine InitiatorName or exit */	daemon_config.initiator_name =	    get_iscsi_initiatorname(daemon_config.initiator_name_file);	if (daemon_config.initiator_name == NULL) {		logmsg(AS_NOTICE, "daemon exiting due to configuration error");		exit(1);	}	/* optional InitiatorAlias */	memset(&host_info, 0, sizeof (host_info));	if (uname(&host_info) >= 0) {		daemon_config.initiator_alias = strdup(host_info.nodename);	}	daemon_config.debug_level = 0;	/* process any command line arguments */	while ((c = getopt(argc, argv, "d:nvf:s:")) >= 0) {		switch (c) {		case 'd':			if (optarg) {				daemon_config.debug_level = atoi(optarg);			} else				daemon_config.debug_level++;			debugmsg(1, "iSCSI debug level %d",				 daemon_config.debug_level);			break;		case 'f':			if (optarg) {				daemon_config.config_file = strdup(optarg);				debugmsg(1, "using configuration file %s",					 daemon_config.config_file);			}			break;		case 'n':			daemon_config.foreground = 1;			debugmsg(1, "daemon will stay in foreground");			break;		case 'v':			printf("iscsid version %s (%s)\n",			       ISCSI_DRIVER_VERSION, ISCSI_DATE);			exit(0);		default:			logmsg(LOG_ERR,			       "iscsid - unexpected option %d, '%c', exiting",			       c, c);			exit(1);		}	}	debugmsg(1, "InitiatorName=%s", daemon_config.initiator_name);	debugmsg(1, "InitiatorAlias=%s", daemon_config.initiator_alias);	/* log the version, so that we can tell if the daemon and kernel module 	 * match based on what shows up in the syslog.  Tarballs releases 	 * always install both, but Linux distributors may put the kernel module	 * in a different RPM from the daemon and utils, and users may try to 	 * mix and match in ways that don't work.	 */	logmsg(LOG_NOTICE, "version %s variant (%s)",	       ISCSI_DRIVER_VERSION, ISCSI_DATE);	/* ensure the control device exists, and open it for all of the 	 * child processes to use 	 */	retry_count=0;	for (;;) {		control_fd = open_control_device();		if (control_fd >= 0)			break;		logmsg(AS_ERROR,		       "could not open control device %s.  "		       "Make sure iscsi is loaded",		       ISCSI_DEVICE);		if (stop_requested)			exit(0);		sleep(10);		retry_count++;		if (retry_count > 2) { /* 20 seconds max */			exit(0);		}	}	retry_count=0;#ifdef RESET_LUN_PROBING	/* reset the LUN probing, to handle cases where the daemon restarts 	 * without reloading the kernel module 	 */	retry_count=0;	while (ioctl(control_fd, ISCSI_RESET_PROBING, NULL) <= 0) {		debugmsg(1,			 "failed to reset LUN probing while daemon starting\n");		if (stop_requested)			exit(0);		usleep(10 * 1000);		retry_count++;		if (retry_count > 50) { /* 500ms max */			exit(0);		}	}	debugmsg(1, "reset LUN probing while daemon starting");#endif}voidiscsi_daemon_stopping(void){	close(control_fd);	/* nothing to do at the moment */}voidiscsi_init_config_defaults(struct iscsi_config_defaults *defaults){	/* enabled/disabled */	defaults->enabled = 1;	/* discovery defaults */	defaults->continuous_sendtargets = 1;	/* auto detect */	defaults->send_async_text = 1;#ifdef SLP_ENABLE	defaults->slp_multicast = 1;#else	defaults->slp_multicast = 0;#endif	defaults->slp_scopes = NULL;	defaults->slp_poll_interval = 5 * 60;	/* 5 minutes */	/* auth options */	defaults->auth_options.authmethod = CHAP_AUTHENTICATION;	defaults->auth_options.password_length = 0;	defaults->auth_options.password_length_in = 0;	/* connection timeouts */	defaults->connection_timeout_options.login_timeout = 15;	defaults->connection_timeout_options.auth_timeout = 45;	defaults->connection_timeout_options.active_timeout = 5;	defaults->connection_timeout_options.idle_timeout = 60;	defaults->connection_timeout_options.ping_timeout = 5;	/* error timeouts */	defaults->error_timeout_options.abort_timeout = 10;	defaults->error_timeout_options.reset_timeout = 30;	/* session timeouts */	defaults->session_timeout_options.replacement_timeout = 0;		/* tcp options */	defaults->tcp_options.window_size = 256 * 1024;	/* iSCSI operational parameters */	defaults->iscsi_options.InitialR2T = 0;	defaults->iscsi_options.ImmediateData = 1;	defaults->iscsi_options.MaxRecvDataSegmentLength = 128 * 1024;	defaults->iscsi_options.FirstBurstLength = 256 * 1024;	defaults->iscsi_options.MaxBurstLength = (16 * 1024 * 1024) - 1024;	defaults->iscsi_options.DefaultTime2Wait = 0;					/* we only use session reinstatement (ERL 0) */	defaults->iscsi_options.DefaultTime2Retain = 0;					/* we only use session reinstatement (ERL 0) */	defaults->iscsi_options.HeaderDigest = CONFIG_DIGEST_PREFER_OFF;	defaults->iscsi_options.DataDigest = CONFIG_DIGEST_PREFER_OFF;}static intioctl_establish_session(struct iscsi_session_config *config, int probe_luns,			int config_number, int update){	int rc, ret = 0;	struct iscsi_portal_config *portal = config->portal;	struct iscsi_session_ioctl *ioctld = NULL;	struct sockaddr_in *addr;	/* allocate an ioctl structure with enough space for 	 * all of the portal info 	 */	ioctld = calloc(1, sizeof (*ioctld));	if (ioctld == NULL) {		logmsg(AS_ERROR, "failed to allocate %d bytes for ioctl data"				 " structure", sizeof (*ioctld));		return 1;	}	ioctld->ioctl_version = ISCSI_SESSION_IOCTL_VERSION;	ioctld->config_number = config_number;	ioctld->update = update;	ioctld->portal.login_timeout =	    portal->connection_timeout_options.login_timeout;	ioctld->portal.auth_timeout =	    portal->connection_timeout_options.auth_timeout;	ioctld->portal.active_timeout =	    portal->connection_timeout_options.active_timeout;	ioctld->portal.idle_timeout =	    portal->connection_timeout_options.idle_timeout;	ioctld->portal.ping_timeout =	    portal->connection_timeout_options.ping_timeout;	ioctld->portal.replacement_timeout =	    portal->session_timeout_options.replacement_timeout;	ioctld->portal.abort_timeout =	    portal->error_timeout_options.abort_timeout;	ioctld->portal.reset_timeout =	    portal->error_timeout_options.reset_timeout;	ioctld->portal.initial_r2t =	    portal->iscsi_options.InitialR2T;	ioctld->portal.immediate_data =	    portal->iscsi_options.ImmediateData;	ioctld->portal.max_recv_data_segment_len =	    portal->iscsi_options.MaxRecvDataSegmentLength;	ioctld->portal.first_burst_len =	    portal->iscsi_options.FirstBurstLength;	ioctld->portal.max_burst_len =	    portal->iscsi_options.MaxBurstLength;	ioctld->portal.def_time2wait =	    portal->iscsi_options.DefaultTime2Wait;	ioctld->portal.def_time2retain =	    portal->iscsi_options.DefaultTime2Retain;	switch (portal->iscsi_options.HeaderDigest) {	case CONFIG_DIGEST_NEVER:		ioctld->portal.header_digest = ISCSI_DIGEST_NONE;		break;	case CONFIG_DIGEST_ALWAYS:		ioctld->portal.header_digest = ISCSI_DIGEST_CRC32C;		break;	case CONFIG_DIGEST_PREFER_ON:		ioctld->portal.header_digest =		    ISCSI_DIGEST_CRC32C_NONE;		break;	case CONFIG_DIGEST_PREFER_OFF:		ioctld->portal.header_digest =		    ISCSI_DIGEST_NONE_CRC32C;		break;	}	switch (portal->iscsi_options.DataDigest) {	case CONFIG_DIGEST_NEVER:		ioctld->portal.data_digest = ISCSI_DIGEST_NONE;		break;	case CONFIG_DIGEST_ALWAYS:		ioctld->portal.data_digest = ISCSI_DIGEST_CRC32C;		break;	case CONFIG_DIGEST_PREFER_ON:		ioctld->portal.data_digest = ISCSI_DIGEST_CRC32C_NONE;		break;	case CONFIG_DIGEST_PREFER_OFF:		ioctld->portal.data_digest = ISCSI_DIGEST_NONE_CRC32C;		break;	}	ioctld->portal.tcp_window_size = portal->tcp_options.window_size;	/*	 * tmp hack - rest of daemon needs to be fixed for	 * endien and ipv6 junk	 */	addr = (struct sockaddr_in *)&ioctld->portal.addr;	addr->sin_family = AF_INET;	memcpy(&addr->sin_addr.s_addr, portal->descriptor->ip,	       portal->descriptor->ip_length);	addr->sin_port = htons(portal->descriptor->port);	ioctld->portal.tag = portal->descriptor->tag;	if (config->target->auth_options.username[0]	    && config->target->auth_options.password_length) {		ioctld->password_length =		    config->target->auth_options.password_length;		strncpy(ioctld->username, config->target->auth_options.username,			sizeof (ioctld->username));		ioctld->username[sizeof (ioctld->username) - 1] = '\0';		memcpy(ioctld->password, config->target->auth_options.password,		       MIN(config->target->auth_options.password_length,			   sizeof (ioctld->password)));		ioctld->password[sizeof (ioctld->password) - 1] = '\0';

⌨️ 快捷键说明

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