2 * Copyright (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
3 * Copyright (C) 2007 - 2009 Vladislav Bolkhovitin
4 * Copyright (C) 2007 - 2009 ID7 Ltd.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
29 #define CTL_DEVICE "/dev/iscsi-scst-ctl"
31 int kernel_open(int *max_data_seg_len)
39 struct iscsi_kern_register_info reg = { 0 };
41 if (!(f = fopen("/proc/devices", "r"))) {
43 perror("Cannot open control path to the driver");
49 if (!fgets(buf, sizeof (buf), f)) {
52 if (sscanf(buf, "%d %s", &devn, devname) != 2) {
55 if (!strcmp(devname, "iscsi-scst-ctl")) {
64 printf("cannot find iscsictl in /proc/devices - "
65 "make sure the module is loaded\n");
70 if (mknod(CTL_DEVICE, (S_IFCHR | 0600), (devn << 8))) {
72 printf("cannot create %s %d\n", CTL_DEVICE, errno);
76 ctlfd = open(CTL_DEVICE, O_RDWR);
79 printf("cannot open %s %d\n", CTL_DEVICE, errno);
83 reg.version = (uintptr_t)ISCSI_SCST_INTERFACE_VERSION;
85 err = ioctl(ctlfd, REGISTER_USERD, ®);
88 log_error("Unable to register: %s. Incompatible version of the "
89 "kernel module?\n", strerror(errno));
92 log_debug(0, "MAX_DATA_SEG_LEN %d", err);
93 *max_data_seg_len = err;
107 int kernel_target_create(u32 *tid, char *name)
110 struct iscsi_kern_target_info info;
112 memset(&info, 0, sizeof(info));
114 memcpy(info.name, name, sizeof(info.name) - 1);
116 if ((err = ioctl(ctrl_fd, ADD_TARGET, &info)) < 0) {
118 log_error("Can't create target %u: %s\n", *tid,
126 int kernel_target_destroy(u32 tid)
128 struct iscsi_kern_target_info info;
131 memset(&info, 0, sizeof(info));
134 res = ioctl(ctrl_fd, DEL_TARGET, &info);
137 log_error("Can't destroy target %d %u\n", errno, tid);
143 int kernel_conn_destroy(u32 tid, u64 sid, u32 cid)
146 struct iscsi_kern_conn_info info;
152 if ((err = ioctl(ctrl_fd, DEL_CONN, &info)) < 0) {
154 log_error("Can't destroy conn (errno %d, tid %u, sid 0x%"
155 PRIx64 ", cid %u\n", errno, tid, sid, cid);
161 int kernel_param_get(u32 tid, u64 sid, int type, struct iscsi_param *param)
164 struct iscsi_kern_param_info info;
166 memset(&info, 0, sizeof(info));
169 info.param_type = type;
171 if ((err = ioctl(ctrl_fd, ISCSI_PARAM_GET, &info)) < 0) {
173 log_debug(1, "Can't get session param for session 0x%" PRIu64
174 " (tid %u, err %d): %s\n", sid, tid, err, strerror(errno));
177 if (type == key_session)
178 for (i = 0; i < session_key_last; i++)
179 param[i].val = info.session_param[i];
181 for (i = 0; i < target_key_last; i++)
182 param[i].val = info.target_param[i];
187 int kernel_param_set(u32 tid, u64 sid, int type, u32 partial,
188 struct iscsi_param *param)
191 struct iscsi_kern_param_info info;
193 memset(&info, 0, sizeof(info));
196 info.param_type = type;
197 info.partial = partial;
199 if (info.param_type == key_session)
200 for (i = 0; i < session_key_last; i++)
201 info.session_param[i] = param[i].val;
203 for (i = 0; i < target_key_last; i++)
204 info.target_param[i] = param[i].val;
206 if ((err = ioctl(ctrl_fd, ISCSI_PARAM_SET, &info)) < 0) {
208 log_error("Can't set session param for session 0x%" PRIu64
209 " (tid %u, type %d, partial %d, err %d): %s\n", sid,
210 tid, type, partial, err, strerror(errno));
216 int kernel_session_create(u32 tid, u64 sid, u32 exp_cmd_sn,
217 char *name, char *user)
219 struct iscsi_kern_session_info info;
222 memset(&info, 0, sizeof(info));
226 info.exp_cmd_sn = exp_cmd_sn;
227 strncpy(info.initiator_name, name, sizeof(info.initiator_name) - 1);
228 strncpy(info.user_name, user, sizeof(info.user_name) - 1);
230 res = ioctl(ctrl_fd, ADD_SESSION, &info);
233 log_error("Can't create sess 0x%" PRIu64 " (tid %d, "
234 "initiator %s): %s\n", sid, tid, name, strerror(errno));
240 int kernel_session_destroy(u32 tid, u64 sid)
242 struct iscsi_kern_session_info info;
245 memset(&info, 0, sizeof(info));
250 res = ioctl(ctrl_fd, DEL_SESSION, &info);
253 log_error("Can't destroy sess 0x%" PRIu64 " (tid %d): %s\n",
254 sid, tid, strerror(errno));
260 int kernel_conn_create(u32 tid, u64 sid, u32 cid, u32 stat_sn, u32 exp_stat_sn,
261 int fd, u32 hdigest, u32 ddigest)
263 struct iscsi_kern_conn_info info;
266 memset(&info, 0, sizeof(info));
271 info.stat_sn = stat_sn;
272 info.exp_stat_sn = exp_stat_sn;
274 info.header_digest = hdigest;
275 info.data_digest = ddigest;
277 res = ioctl(ctrl_fd, ADD_CONN, &info);
280 log_error("Can't create conn %x (sess 0x%" PRIu64 ", tid %d): %s\n",
281 cid, sid, tid, strerror(errno));