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

📄 initiator_proc_iface.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		pos += print_my_kmemory(buffer + pos);		pos += print_iovs(buffer + pos);		if (pos < offset) {			/* reader already read everything we have to say,			 * send back EOF			 */			result = 0;			begin = pos;		} else {			/* reader had not read everything yet,			 * send back something			 */			result = pos;			begin = 0;		}		/* Start of wanted data */		*start = buffer + (offset - begin);		result -= (offset - begin);		if (result > length)			result = length;	}	TRACE(TRACE_ENTER_LEAVE, "Leave iscsi_initiator_proc_info, result %d\n",	      result);	return result;}#ifdef ISCSI_STATSstatic int __attribute__ ((no_instrument_function))dump_instance_stats(char *page){	int len=0;	struct iscsi_instance_stats *istats;	char ip_string[INET6_ADDRSTRLEN+2], port_string[8];	istats = &(global_hostdata->instance_stats);	len += sprintf(page + len, "Session Login Failure = %d\n",			istats->iscsi_intr_login_failure);	len += sprintf(page + len, "Last Login Failure Target Name= %s\n",			(istats->iscsi_intr_last_tgt_failure_name) ?			istats->iscsi_intr_last_tgt_failure_name: "<NULL>");	len+=sprintf(page+len, "Last Target Failure Address = ");	if (istats->iscsi_intr_last_tgt_failure_address == NULL)		len += sprintf(page + len, "<NULL>\n");	else if (cnv_inet_to_string(istats->iscsi_intr_last_tgt_failure_address,												ip_string, port_string) > 0)		len += sprintf(page +len, "%s:%s\n", ip_string, port_string);	len += sprintf( page + len, "Last Login Failure Time = %ld:%ld\n",			istats->iscsi_intr_last_failure_time.tv_sec,			istats->iscsi_intr_last_failure_time.tv_usec);#if USE_PRINT_DATE	len += print_date(page + len, &(istats->iscsi_intr_last_failure_time));#endif	len += sprintf(page + len, "Last Login Failure Type = ");	switch (istats->iscsi_intr_last_failure_type) {	case ACCEPT_RESPONSE:		len += sprintf(page + len, "ACCEPT_RESPONSE\n");		break;	case REDIRECT_RESPONSE:		len += sprintf(page + len, "REDIRECT_RESPONSE\n");		break;	case AUTH_FAIL_RESPONSE:		len += sprintf(page + len, "AUTH_FAIL_RESPONSE\n");		break;	case AUTHENTICATE_FAIL:		len += sprintf(page + len, "AUTHENTICATE_FAIL\n");		break;	case NEGOTIATE_FAIL:		len += sprintf(page + len, "NEGOTIATE_FAIL\n");		break;	case OTHER_FAIL:		len += sprintf(page + len, "OTHER_FAIL\n");		break;	case UNKNOWN_FAILURE:	default:		if(istats->iscsi_intr_login_failure)			len += sprintf(page +len, "<UNKNOWN FAILURE>\n");		else			len += sprintf(page +len, "<NULL>\n");		break;	}	len += sprintf(page +len, "Login Accept Response = %u\n",		       istats->iscsi_intr_login_accept_rsp);	len += sprintf(page +len, "Login Redirect Response = %u\n",		       istats->iscsi_intr_login_redirect_rsp);	len += sprintf(page +len, "Login Authenticate Fail Response = %u\n",		       istats->iscsi_intr_login_auth_fail_rsp);	len += sprintf(page +len, "Login Authentication Failure = %u\n",		       istats->iscsi_intr_login_auth_fail_rsp);	len += sprintf(page +len, "Login Negotiate Failure = %u\n",		       istats->iscsi_intr_login_negotiate_fails);	len += sprintf(page +len, "Login Other Failure = %u\n",		       istats->iscsi_intr_login_other_fail_rsp);	len += sprintf(page +len, "Normal Logouts = %u\n",		       istats->iscsi_intr_logout_normals);	len += sprintf(page +len, "Other Logouts = %u\n",		       istats->iscsi_intr_logout_others);	return len;}static int __attribute__ ((no_instrument_function))read_proc_file(char *page, char **start, off_t off, int count, int *eof,			   void *data){	unsigned long flags;	int len = 0;	struct proc_data *proc_data = (struct proc_data *) data;	struct session *sess;	struct connection *conn;	/*  When using global session list, be sure nobody else accesses it */	UNH_LOCK(&host_data_lock, flags);	if (proc_data == NULL || proc_data->file != STAT)		goto out;	len = sprintf(page, "%s\n", OUR_NAME);	/* find the session for this target_id */	sess = find_session_by_id(proc_data->sess_id, global_hostdata);	if (sess != NULL) {		/* found the session */		if (proc_data->type & SESSION) {			len += dump_sess_info(sess, page+len);		} else if (proc_data->type & CONNECTION) {			/* find the connection within this session */			for (conn = sess->connection_head;			     conn != NULL;			     conn = conn->next) {				if (conn->connection_id						== proc_data->conn_id) {					len += dump_conn_info(conn, page+len);					break;				}			}		}	}out:	/* release our exclusive access to the global structures */	UNH_UNLOCK(&host_data_lock, flags);	return len;}/* * executed only by command process. * host_data_lock MUST be held by the calling process/thread * Called only by read_proc_file(). * dump_sess_info() dumps the session specific info. * It dumps the session negotiated values and statistics * such as cmd pdus txd, response pdus txd, data bytes txd, * data bytes rxd, error count etc... */static int __attribute__ ((no_instrument_function))dump_sess_info(struct session *sess, char *page){	int len;	struct iscsi_session_stats *sess_stats;	if (sess == NULL)		return 0;	len = print_session_info(sess, page, 0);	sess_stats = sess->sess_stats;	len += print_session_params(sess->oper_param,				    *sess->session_params,				    page + len);	len += sprintf(page +len,			"\nPDUs Transmitted\n------------------\n");	len += sprintf(page +len,			"%12s %12s %12s %12s %12s %12s\n"			"%12u %12u %12u %12u %12u %12u\n",			"NopOut", "SCSICommand", "TaskMgmtReq", "TextReq",			"DataOut", "SNACK",			sess_stats->iscsi_ssn_noptx_pdus,			sess_stats->iscsi_ssn_scsicmd_pdus,			sess_stats->iscsi_ssn_tskmgmtcmd_pdus,			sess_stats->iscsi_ssn_text_pdus,			sess_stats->iscsi_ssn_dataout_pdus,			sess_stats->iscsi_ssn_snack_pdus);	len += sprintf(page +len, "PDUs Received\n------------------\n");	len += sprintf(page +len,			"%12s %12s %12s %12s %12s %12s %12s %12s\n"			"%12u %12u %12u %12u %12u %12u %12u %12u\n",			"NopIn",  "SCSIResp", "TaskMgmtResp", "TextResp",			"DataIn", "R2T", "AsyncMess", "Reject",			sess_stats->iscsi_ssn_noprx_pdus,			sess_stats->iscsi_ssn_rsp_pdus,			sess_stats->iscsi_ssn_tskmgmtrsp_pdus,			sess_stats->iscsi_ssn_textrsp_pdus,			sess_stats->iscsi_ssn_datain_pdus,			sess_stats->iscsi_ssn_r2t_pdus,			sess_stats->iscsi_ssn_async_pdus,			sess_stats->iscsi_ssn_rjt_pdus);	len += sprintf(page +len,			"Data Bytes Txd = %lld\nData Bytes Rxd = %llu\n",			sess_stats->iscsi_ssn_txdata_octets,			sess_stats->iscsi_ssn_rxdata_octets);	len += sprintf(page +len, "Input DataDigest Errors = %u\n",			sess->sess_stats->iscsi_ssn_digest_err);#if USE_CONTROL_FILE	len += sprintf(page +len, "Connection Timeout Error = %u\n",			sess->sess_stats->iscsi_ssn_timeout_err);#endif	return len;}/* * executed only by command process. * host_data_lock MUST be held by the calling process/thread * Called only by read_proc_file(). * dump_conn_info () prints the connection stats * CID, Connection STATE, Protocol Type, Local Address, Port * Remote Address, Port, Remote Address Type, Max Receive Data * Max Send Data, Receive Marker, Send Marker, Header Digest * Data Digest etc.. */static int __attribute__ ((no_instrument_function))dump_conn_info(struct connection *conn, char *buf){	int len;	if (conn == NULL)		return 0 ;	len = print_connection_info(conn, buf, 0);	if(conn->connection_state == CONNECTION_FULL_FEATURE_PHASE ||			conn->connection_state == CONNECTION_CONNECTED) {		len += sprintf(buf + len, "%16s: %s\n", "LUN addressing",			       conn->connection_flags & USE_FLAT_SPACE_LUN			       ? "flat space" : "peripheral device");		len += sprintf(buf +len,				"%16s: %s\n", "Header Digest",				(conn->connection_flags & USE_HEADERDIGEST)					? "CRC32C" : "None");		len += sprintf(buf +len,				"%16s: %s\n", "Data Digest",				(conn->connection_flags & USE_DATADIGEST)					? "CRC32C" : "None");		len += sprintf(buf +len, "%16s: %u Bytes\n",				"Max Send DSL", conn->max_send_length);		len += sprintf(buf +len, "%16s: %u Bytes\n",				"Max Recv DSL", conn->max_recv_length);#if 0		len += sprintf(buf +len, "%16s: %s\n", "Send Marker", "TODO");		len += sprintf(buf +len, "%16s: %s\n", "Receive Marker",				"TODO");#endif		len += sprintf(buf +len, "%16s: %lld\n", "Data Bytes Sent",				conn->iscsi_conn_txdata_octets);		len += sprintf(buf +len, "%16s: %lld\n", "Data Bytes Rcvd",				conn->iscsi_conn_rxdata_octets);	}	return len;}#if USE_CONTROL_FILEstatic int __attribute__ ((no_instrument_function))write_proc_file(struct file *file, const char *buffer, unsigned long count,		void *data){	/* Nothing to do here */	return count;}#endif/* * add_iscsi_proc_entry() routine accepts a void pointer, * the void ptr should be either a session ptr or a connection * ptr. The void ptr is typecast to either of them depending upon * "type". * The session proc entries include a "target#"<num> dir and * stat and ctrl file in it. * The connection proc entries include a "conn#"<cid> dir and * stat and ctrl file in it. * Same read and write routines are used for all files, the operation * is distinguished based on the "data" value in proc_data. */intadd_iscsi_proc_entry(void *ptr, int type){	int ret = -1;	struct proc_dir_entry *dir = NULL, *stat_file = NULL;#if USE_CONTROL_FILE	struct proc_dir_entry *ctrl_file = NULL;#endif	struct session *sess = (struct session *) ptr;	struct connection *conn = (struct connection *) ptr;	char dir_name[32];	struct proc_data *stat_data		= (struct proc_data *) kmalloc(sizeof (struct proc_data),							     GFP_KERNEL);#if USE_CONTROL_FILE	struct proc_data *ctrl_data		= (struct proc_data *) kmalloc(sizeof (struct proc_data),							     GFP_KERNEL);#endif	sprintf(dir_name, "%s-%d",			(type & SESSION) ? TARGET_FNAME : CONNECTION_FNAME,			(type & SESSION) ? sess->scsi_target_id					  : conn->connection_id);	dir = proc_mkdir(dir_name, (type & SESSION)		  ? global_host->hostt->proc_dir : conn->my_session-> proc_dir);	if (dir == NULL) {		TRACE(TRACE_DEBUG, "add_proc: creation of proc dir %s failed\n",		      dir_name);		ret = -ENOMEM;		goto error_out1;	}	/* set the proc dir entry in session structure */	if (type & SESSION) {		sess->proc_dir = dir;		stat_data->sess_id = sess->scsi_target_id;	} else {		/* Create connection specific stat and control files */		conn->proc_dir = dir;		stat_data->sess_id = conn->my_session->scsi_target_id;		stat_data->conn_id = conn->connection_id;	}	stat_data->type = type;	stat_data->file = STAT;	stat_file		= create_proc_read_entry(STAT_FNAME, 0444, dir, read_proc_file,				         (void *) stat_data);	if (stat_file == NULL) {		TRACE(TRACE_DEBUG,		      "add_iscsi_proc_entry: creation of proc file %s failed\n",		      STAT_FNAME);		ret = -ENOMEM;		goto error_out2;	}#if USE_CONTROL_FILE	/* For time being, there is nothing that can be written	 * into a ctrl for connection. For sess level ctrl file,	 * we can only set the scheduling algo.	 */	ctrl_file = create_proc_entry(CONTROL_FNAME, 0644, dir);	if (ctrl_file == NULL) {		TRACE(TRACE_DEBUG,		      "add_iscsi_proc_entry: creation of proc file %s failed\n",		      CONTROL_FNAME);		ret = -ENOMEM;		goto error_out3;	}	ctrl_data->type = type;	ctrl_data->file = CONTROL;	if (type & SESSION) {		ctrl_data->sess_id = sess->iscsi_target_id;	} else {		ctrl_data->sess_id = conn->my_session->iscsi_target_id;		ctrl_data->conn_id = conn->connection_id;	}	ctrl_file->data = (void *) ctrl_data;	ctrl_file->read_proc = read_proc_file;	ctrl_file->write_proc = write_proc_file;	ctrl_file->owner = THIS_MODULE;#endif	ret = 0;	return ret;#if USE_CONTROL_FILEerror_out3:	remove_proc_entry(STAT_FNAME, dir);#endiferror_out2:	remove_proc_entry(dir_name, global_host->hostt->proc_dir);error_out1:	kfree(stat_data);#if USE_CONTROL_FILE	kfree(ctrl_data);#endif	return ret;}/* * remove_iscsi_proc_entry() accepts a void ptr and type, * The void ptr is typecast to either session or connection * based on the type. */voidremove_iscsi_proc_entry(void *ptr, int type){	struct session *sess = (struct session *) ptr;	struct connection *conn = (struct connection *) ptr;	char dir_name[32];	remove_proc_entry(STAT_FNAME,			  (type & SESSION) ? sess->proc_dir : conn->proc_dir);	/*not sure if I have to free the "data" mem. */#if USE_CONTROL_FILE	remove_proc_entry(CONTROL_FNAME,			  (type & SESSION) ? sess->proc_dir : conn->proc_dir);#endif	sprintf(dir_name, "%s-%d",		(type & SESSION) ? TARGET_FNAME : CONNECTION_FNAME,		(type & SESSION) ? sess->scsi_target_id : conn->connection_id);	remove_proc_entry(dir_name, (type & SESSION)		? global_host->hostt->proc_dir : conn->my_session->proc_dir);	if (type & SESSION)		sess->proc_dir = NULL;	else		conn->proc_dir = NULL;	return;}#if USE_PRINT_DATE#define SECS_PER_HOUR (60 * 60)#define SECS_PER_DAY (60 * 60 * 24)#define isleap(year) \	((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))#define TIMEZONE (-5 * 60 * 60)static int __attribute__ ((no_instrument_function))print_date (char *page, const struct timeval *t){	int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year;	static const __u16 mon_yday[2][13] = {           /* Normal years.  */           { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },           /* Leap years.  */           { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }        };        long int days, rem, y;        const __u16 *ip;        days = t->tv_sec / SECS_PER_DAY;        rem = t->tv_sec % SECS_PER_DAY;        rem += TIMEZONE;        while (rem < 0) {                rem += SECS_PER_DAY;                --days;        }        while (rem >= SECS_PER_DAY) {                rem -= SECS_PER_DAY;                ++days;        }        tm_hour = rem / SECS_PER_HOUR;        rem %= SECS_PER_HOUR;        tm_min = rem / 60;        tm_sec = rem % 60;        y = 1970;        while (days < 0 || days >= (isleap (y) ? 366 : 365)) {                long int yg = y + days / 365 - (days % 365 < 0);                days -= ((yg - y) * 365                        + LEAPS_THRU_END_OF (yg - 1)                        - LEAPS_THRU_END_OF (y - 1));                y = yg;        }        tm_year = y - 1900;        if (tm_year != y - 1900)                return ;        ip = mon_yday[isleap(y)];        for (y = 11; days < (long int) ip[y]; --y)                continue;        days -= ip[y];        tm_mon = y;        tm_mday = days + 1;	return sprintf(page,		       "DATE %.2d/%.2d/%d- %.2d:%.2d:%.2d", tm_mday, tm_mon + 1,		       tm_year + 1900, tm_hour, tm_min, tm_sec);}#endif#endif

⌨️ 快捷键说明

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