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

📄 ctldev.c

📁 iscsi企业级target.很好用
💻 C
字号:
/* * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org> * * This code is licenced under the GPL. */#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include "iscsid.h"#define CTL_DEVICE	"/dev/ietctl"extern int ctrl_fd;struct session_file_operations {	int (*target_op) (int fd, u32 tid, void *arg);	int (*session_op) (int fd, u32 tid, u64 sid, void *arg);	int (*connection_op) (int fd, u32 tid, u64 sid, u32 cid, void *arg);};static int ctrdev_open(void){	FILE *f;	char devname[256];	char buf[256];	int devn;	int ctlfd;	if (!(f = fopen("/proc/devices", "r"))) {		perror("Cannot open control path to the driver\n");		return -1;	}	devn = 0;	while (!feof(f)) {		if (!fgets(buf, sizeof (buf), f)) {			break;		}		if (sscanf(buf, "%d %s", &devn, devname) != 2) {			continue;		}		if (!strcmp(devname, "ietctl")) {			break;		}		devn = 0;	}	fclose(f);	if (!devn) {		printf		    ("cannot find iscsictl in /proc/devices - "		     "make sure the module is loaded\n");		return -1;	}	unlink(CTL_DEVICE);	if (mknod(CTL_DEVICE, (S_IFCHR | 0600), (devn << 8))) {		printf("cannot create %s %d\n", CTL_DEVICE, errno);		return -1;	}	ctlfd = open(CTL_DEVICE, O_RDWR);	if (ctlfd < 0) {		printf("cannot open %s %d\n", CTL_DEVICE, errno);		return -1;	}	return ctlfd;}static int iscsi_target_create(u32 *tid, char *name){	int err;	struct target_info info;	memset(&info, 0, sizeof(info));	memcpy(info.name, name, sizeof(info.name) - 1);	info.tid = *tid;	if ((err = ioctl(ctrl_fd, ADD_TARGET, &info)) < 0)		log_warning("can't create a target %d %u\n", errno, info.tid);	*tid = info.tid;	return err;}static int iscsi_target_destroy(u32 tid){	struct target_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	return ioctl(ctrl_fd, DEL_TARGET, &info);}static int iscsi_lunit_create(u32 tid, u32 lun, char *args){	int err;	struct volume_info info;	char *p;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.lun = lun;	while (isspace(*args))		args++;	if ((p = strchr(args, '\n')))		*p = '\0';	strncpy(info.args, args, sizeof(info.args) - 1);	if ((err = ioctl(ctrl_fd, ADD_VOLUME, &info)) < 0)		fprintf(stderr, "%s %d %d", __FUNCTION__, errno, err);	return err;}static int iscsi_lunit_destroy(u32 tid, u32 lun){	int err;	struct volume_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.lun = lun;	if ((err = ioctl(ctrl_fd, DEL_VOLUME, &info)) < 0)		fprintf(stderr, "%s %d %d", __FUNCTION__, errno, err);	return err;}static int iscsi_conn_destroy(u32 tid, u64 sid, u32 cid){	int err;	struct conn_info info;	info.tid = tid;	info.sid = sid;	info.cid = cid;	if ((err = ioctl(ctrl_fd, DEL_CONN, &info)) < 0)		err = errno;	return err;}static int __conn_close(int fd, u32 tid, u64 sid, u32 cid, void *arg){	return ki->conn_destroy(tid, sid, cid);}static int __target_del(int fd, u32 tid, void *arg){	return ki->target_destroy(tid);}static int proc_session_parse(int fd, struct session_file_operations *ops, void *arg){	FILE *f;	char buf[8192], *p;	u32 tid, cid;	u64 sid;	int err;	if ((f = fopen(PROC_SESSION, "r")) == NULL) {		fprintf(stderr, "Can't open %s\n", PROC_SESSION);		return errno;	}	while (fgets(buf, sizeof(buf), f)) {		p = buf;		while (isspace((int) *p))			p++;		if (!strncmp(p, "tid:", 4)) {			if (sscanf(p, "tid:%u", &tid) != 1)				break;			if (ops->target_op)				if ((err = ops->target_op(fd, tid, arg)) < 0)					goto out;		} else if (!strncmp(p, "sid:", 4)) {			if (sscanf(p, "sid:%" SCNu64, &sid) != 1)				break;			if (ops->session_op)				if ((err = ops->session_op(fd, tid, sid, arg)) < 0)					goto out;		} else if (!strncmp(p, "cid:", 4)) {			if (sscanf(p, "cid:%u", &cid) != 1)				break;			if (ops->connection_op)				if ((err = ops->connection_op(fd, tid, sid, cid, arg)) < 0)					goto out;		}	}	err = 0;out:	fclose(f);	return err;}static int session_retry (int fd, u32 tid, u64 sid, void *arg){	return -EAGAIN;}static int conn_retry (int fd, u32 tid, u64 sid, u32 cid, void *arg){	return -EAGAIN;}struct session_file_operations conn_close_ops = {	.connection_op = __conn_close,};struct session_file_operations shutdown_wait_ops = {	.session_op = session_retry,	.connection_op = conn_retry,};struct session_file_operations target_del_ops = {	.target_op = __target_del,};int server_stop(void){	proc_session_parse(ctrl_fd, &conn_close_ops, NULL);	while (proc_session_parse(ctrl_fd, &shutdown_wait_ops, NULL) < 0)		sleep(1);	proc_session_parse(ctrl_fd, &target_del_ops, NULL);	return 0;}struct session_conn_close_arg {	u32 tid;	u64 sid;};static int session_conn_close(int fd, u32 tid, u64 sid, u32 cid, void *opaque){	struct session_conn_close_arg *arg = (struct session_conn_close_arg *) opaque;	int err;	if (arg->tid == tid && arg->sid == sid)		err = ki->conn_destroy(tid, sid, cid);	return 0;}struct session_file_operations session_conns_close_ops = {	.connection_op = session_conn_close,};int session_conns_close(u32 tid, u64 sid){	int err;	struct session_conn_close_arg arg = {tid, sid};	err = proc_session_parse(ctrl_fd, &session_conns_close_ops, &arg);	return err;}static int iscsi_param_get(u32 tid, u64 sid, struct iscsi_param *param){	int err, i;	struct iscsi_param_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.sid = sid;	if ((err = ioctl(ctrl_fd, ISCSI_PARAM_GET, &info)) < 0)		log_error("Can't set session param %d %d\n", info.tid, errno);	for (i = 0; i < session_key_last; i++)		param[i].val = info.session_param[i];	return err;}static int iscsi_param_set(u32 tid, u64 sid, int type, u32 partial, struct iscsi_param *param){	int i, err;	struct iscsi_param_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.sid = sid;	info.param_type = type;	info.partial = partial;	if (info.param_type == key_session)		for (i = 0; i < session_key_last; i++)			info.session_param[i] = param[i].val;	else		for (i = 0; i < target_key_last; i++)			info.target_param[i] = param[i].val;	if ((err = ioctl(ctrl_fd, ISCSI_PARAM_SET, &info)) < 0)		fprintf(stderr, "%d %d %u " "%" PRIu64 " %d %u\n",			err, errno, tid, sid, type, partial);	return err;}static int iscsi_session_create(u32 tid, u64 sid, u32 exp_cmd_sn, u32 max_cmd_sn, char *name){	struct session_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.sid = sid;	info.exp_cmd_sn = exp_cmd_sn;	info.max_cmd_sn = max_cmd_sn;	strncpy(info.initiator_name, name, sizeof(info.initiator_name) - 1);	return ioctl(ctrl_fd, ADD_SESSION, &info);}static int iscsi_session_destroy(u32 tid, u64 sid){	struct session_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.sid = sid;	return ioctl(ctrl_fd, DEL_SESSION, &info);}static int iscsi_conn_create(u32 tid, u64 sid, u32 cid, u32 stat_sn, u32 exp_stat_sn,			     int fd, u32 hdigest, u32 ddigest){	struct conn_info info;	memset(&info, 0, sizeof(info));	info.tid = tid;	info.sid = sid;	info.cid = cid;	info.stat_sn = stat_sn;	info.exp_stat_sn = exp_stat_sn;	info.fd = fd;	info.header_digest = hdigest;	info.data_digest = ddigest;	return ioctl(ctrl_fd, ADD_CONN, &info);}struct iscsi_kernel_interface ioctl_ki = {	.ctldev_open = ctrdev_open,	.lunit_create = iscsi_lunit_create,	.lunit_destroy = iscsi_lunit_destroy,	.param_get = iscsi_param_get,	.param_set = iscsi_param_set,	.target_create = iscsi_target_create,	.target_destroy = iscsi_target_destroy,	.session_create = iscsi_session_create,	.session_destroy = iscsi_session_destroy,	.conn_create = iscsi_conn_create,	.conn_destroy = iscsi_conn_destroy,};struct iscsi_kernel_interface *ki = &ioctl_ki;

⌨️ 快捷键说明

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