summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordmitry_yus <dmitry_yus@d7303112-9cec-0310-bdd2-e83a94d6c2b6>2005-04-09 02:33:23 +0000
committerdmitry_yus <dmitry_yus@d7303112-9cec-0310-bdd2-e83a94d6c2b6>2005-04-09 02:33:23 +0000
commita4b4adc25d2b02baee7049fa4c24120cfb5d1000 (patch)
treeb4ad4a18dfaa6942e4d8f553e7c1793ac180e4ec
parentd92ebb97cbe99d52735163c70dd2b3458c2e4330 (diff)
downloadopen-iscsi-a4b4adc25d2b02baee7049fa4c24120cfb5d1000.tar.gz
kernel ipc cleanup. added and implemented iscsi_ipc callback structure
receive pool for control PDU's per-connection added git-svn-id: svn://svn.berlios.de/open-iscsi@222 d7303112-9cec-0310-bdd2-e83a94d6c2b6
-rw-r--r--include/iscsi_iftrans.h16
-rw-r--r--kernel/iscsi_if.c10
-rw-r--r--kernel/iscsi_tcp.c49
-rw-r--r--usr/Makefile2
-rw-r--r--usr/discovery.c35
-rw-r--r--usr/initiator.c495
-rw-r--r--usr/initiator.h64
-rw-r--r--usr/io.c49
-rw-r--r--usr/ioctl.c472
-rw-r--r--usr/iscsiadm.c22
-rw-r--r--usr/iscsid.c19
-rw-r--r--usr/iscsid.h9
-rw-r--r--usr/login.c4
-rw-r--r--usr/mgmt_ipc.c (renamed from usr/ipc.c)86
-rw-r--r--usr/mgmt_ipc.h (renamed from usr/ipc.h)68
-rw-r--r--usr/netlink.c400
16 files changed, 725 insertions, 1075 deletions
diff --git a/include/iscsi_iftrans.h b/include/iscsi_iftrans.h
index fcea0c3..75248ef 100644
--- a/include/iscsi_iftrans.h
+++ b/include/iscsi_iftrans.h
@@ -38,7 +38,7 @@
* @stop_cnx: suspend connection
* @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
*
- * API provided by generic iSCSI Data Path module
+ * API provided by iSCSI Initiator Data Path module
*/
struct iscsi_transport {
struct module *owner;
@@ -68,12 +68,16 @@ struct iscsi_transport {
};
/*
- * up calls
+ * transport registration upcalls
*/
-int iscsi_register_transport(struct iscsi_transport *t);
-int iscsi_unregister_transport(struct iscsi_transport *t);
-int iscsi_control_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
+extern int iscsi_register_transport(struct iscsi_transport *t);
+extern int iscsi_unregister_transport(struct iscsi_transport *t);
+
+/*
+ * control plane "up" calls
+ */
+extern void iscsi_cnx_error(iscsi_cnx_t cp_cnx, enum iscsi_err error);
+extern int iscsi_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
-void iscsi_control_cnx_error(iscsi_cnx_t cp_cnx, enum iscsi_err error);
#endif /* ISCSI_IFTRANS_H */
diff --git a/kernel/iscsi_if.c b/kernel/iscsi_if.c
index 49c6adb..76cee24 100644
--- a/kernel/iscsi_if.c
+++ b/kernel/iscsi_if.c
@@ -266,7 +266,7 @@ iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
return 0;
}
-int iscsi_control_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
+int iscsi_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
char *data, uint32_t data_size)
{
struct nlmsghdr *nlh;
@@ -285,7 +285,7 @@ int iscsi_control_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
skb = mempool_zone_get_skb(&cnx->z_pdu);
if (!skb) {
- iscsi_control_cnx_error(cp_cnx, ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(cp_cnx, ISCSI_ERR_CNX_FAILED);
printk("iscsi%d: can not deliver control PDU: OOM\n",
cnx->host->host_no);
return -ENOMEM;
@@ -307,9 +307,9 @@ int iscsi_control_recv_pdu(iscsi_cnx_t cp_cnx, struct iscsi_hdr *hdr,
return rc;
}
-EXPORT_SYMBOL_GPL(iscsi_control_recv_pdu);
+EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
-void iscsi_control_cnx_error(iscsi_cnx_t cp_cnx, enum iscsi_err error)
+void iscsi_cnx_error(iscsi_cnx_t cp_cnx, enum iscsi_err error)
{
struct nlmsghdr *nlh;
struct sk_buff *skb;
@@ -342,7 +342,7 @@ void iscsi_control_cnx_error(iscsi_cnx_t cp_cnx, enum iscsi_err error)
printk("iscsi%d: detected cnx error (%d)\n", cnx->host->host_no, error);
}
-EXPORT_SYMBOL_GPL(iscsi_control_cnx_error);
+EXPORT_SYMBOL_GPL(iscsi_cnx_error);
static int
iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
diff --git a/kernel/iscsi_tcp.c b/kernel/iscsi_tcp.c
index f5a1b67..d5fc5fc 100644
--- a/kernel/iscsi_tcp.c
+++ b/kernel/iscsi_tcp.c
@@ -157,8 +157,8 @@ iscsi_hdr_extract(struct iscsi_conn *conn)
printk("iscsi_tcp: PDU gather failed! "
"copylen %d conn->in.copy %d\n",
copylen, conn->in.copy);
- iscsi_control_cnx_error(conn->handle,
- ISCSI_ERR_PDU_GATHER_FAILED);
+ iscsi_cnx_error(conn->handle,
+ ISCSI_ERR_PDU_GATHER_FAILED);
return 0;
}
debug_tcp("PDU gather #2 %d bytes!\n", copylen);
@@ -572,8 +572,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
if (!conn->in.datalen) {
struct iscsi_mgmt_task *mtask;
- rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL, 0);
+ rc = iscsi_recv_pdu(conn->handle, hdr, NULL, 0);
mtask = (struct iscsi_mgmt_task *)
session->imm_cmds[conn->in.itt -
ISCSI_IMM_ITT_OFFSET];
@@ -604,8 +603,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
if (!conn->in.datalen) {
- rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL, 0);
+ rc = iscsi_recv_pdu(conn->handle, hdr, NULL, 0);
if (conn->login_mtask != mtask) {
spin_lock(&session->lock);
__kfifo_put(session->immpool.queue,
@@ -637,8 +635,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
} else if (conn->in.itt == ISCSI_RESERVED_TAG) {
if (conn->in.opcode == ISCSI_OP_NOOP_IN &&
!conn->in.datalen) {
- rc = iscsi_control_recv_pdu(
- conn->handle, hdr, NULL, 0);
+ rc = iscsi_recv_pdu(conn->handle, hdr, NULL, 0);
} else {
rc = ISCSI_ERR_BAD_OPCODE;
}
@@ -841,8 +838,8 @@ iscsi_data_recv(struct iscsi_conn *conn)
goto exit;
}
- rc = iscsi_control_recv_pdu(conn->handle,
- conn->in.hdr, conn->data, conn->in.datalen);
+ rc = iscsi_recv_pdu(conn->handle, conn->in.hdr, conn->data,
+ conn->in.datalen);
if (mtask && conn->login_mtask != mtask) {
spin_lock(&session->lock);
@@ -892,7 +889,7 @@ more:
if (rc == -EAGAIN)
goto nomore;
else {
- iscsi_control_cnx_error(conn->handle, rc);
+ iscsi_cnx_error(conn->handle, rc);
return 0;
}
}
@@ -904,7 +901,7 @@ more:
if (!rc && conn->in.datalen) {
conn->in_progress = IN_PROGRESS_DATA_RECV;
} else if (rc) {
- iscsi_control_cnx_error(conn->handle, rc);
+ iscsi_cnx_error(conn->handle, rc);
return 0;
}
}
@@ -922,7 +919,7 @@ more:
conn->in.ctask->sent;
goto again;
}
- iscsi_control_cnx_error(conn->handle, rc);
+ iscsi_cnx_error(conn->handle, rc);
return 0;
}
conn->in.copy -= conn->in.padding;
@@ -991,7 +988,7 @@ iscsi_tcp_state_change(struct sock *sk)
session->state = ISCSI_STATE_FAILED;
}
spin_unlock_bh(&session->conn_lock);
- iscsi_control_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
}
old_state_change = conn->old_state_change;
@@ -1076,7 +1073,7 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
conn->suspend = 1;
} else if (res == -EPIPE) {
conn->suspend = 1;
- iscsi_control_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
}
return res;
@@ -1123,7 +1120,7 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
conn->suspend = 1;
} else if (res == -EPIPE) {
conn->suspend = 1;
- iscsi_control_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
}
return res;
@@ -2181,7 +2178,7 @@ iscsi_conn_stop(iscsi_cnx_t cnxh, int flag)
}
static int
-iscsi_send_pdu(iscsi_cnx_t cnxh, struct iscsi_hdr *hdr, char *data,
+iscsi_conn_send_pdu(iscsi_cnx_t cnxh, struct iscsi_hdr *hdr, char *data,
uint32_t data_size)
{
struct iscsi_conn *conn = iscsi_ptr(cnxh);
@@ -2339,12 +2336,11 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
conn->tmabort_state = TMABORT_INITIAL;
- rc = iscsi_send_pdu(iscsi_handle(conn),
+ rc = iscsi_conn_send_pdu(iscsi_handle(conn),
(struct iscsi_hdr *)hdr, NULL, 0);
if (rc) {
session->state = ISCSI_STATE_FAILED;
- iscsi_control_cnx_error(conn->handle,
- ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
debug_scsi("abort sent failure [itt 0x%x]", ctask->itt);
} else {
conn->tmabort_timer.expires = 3*HZ + jiffies; /*3 secs*/
@@ -2399,8 +2395,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
}
spin_unlock_bh(&session->lock);
session->state = ISCSI_STATE_FAILED;
- iscsi_control_cnx_error(conn->handle,
- ISCSI_ERR_CNX_FAILED);
+ iscsi_cnx_error(conn->handle, ISCSI_ERR_CNX_FAILED);
continue;
}
@@ -2600,7 +2595,7 @@ iscsi_session_destroy(iscsi_snx_t snxh)
}
static int
-iscsi_set_param(iscsi_cnx_t cnxh, enum iscsi_param param, uint32_t value)
+iscsi_conn_set_param(iscsi_cnx_t cnxh, enum iscsi_param param, uint32_t value)
{
struct iscsi_conn *conn = iscsi_ptr(cnxh);
struct iscsi_session *session = conn->session;
@@ -2716,7 +2711,7 @@ iscsi_set_param(iscsi_cnx_t cnxh, enum iscsi_param param, uint32_t value)
}
static int
-iscsi_get_param(iscsi_cnx_t cnxh, enum iscsi_param param, uint32_t *value)
+iscsi_conn_get_param(iscsi_cnx_t cnxh, enum iscsi_param param, uint32_t *value)
{
struct iscsi_conn *conn = iscsi_ptr(cnxh);
struct iscsi_session *session = conn->session;
@@ -2784,11 +2779,11 @@ struct iscsi_transport iscsi_tcp_transport = {
.create_cnx = iscsi_conn_create,
.bind_cnx = iscsi_conn_bind,
.destroy_cnx = iscsi_conn_destroy,
- .set_param = iscsi_set_param,
- .get_param = iscsi_get_param,
+ .set_param = iscsi_conn_set_param,
+ .get_param = iscsi_conn_get_param,
.start_cnx = iscsi_conn_start,
.stop_cnx = iscsi_conn_stop,
- .send_pdu = iscsi_send_pdu,
+ .send_pdu = iscsi_conn_send_pdu,
};
static int __init
diff --git a/usr/Makefile b/usr/Makefile
index ba1dd42..1bebd58 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -6,7 +6,7 @@ COMMON_SRCS = io.o auth.o login.o log.o md5.o sha1.o idbm.o
all: $(PROGRAMS)
-iscsid: $(COMMON_SRCS) iscsid.o ipc.o netlink.o initiator.o actor.o queue.o
+iscsid: $(COMMON_SRCS) iscsid.o mgmt_ipc.o netlink.o initiator.o actor.o queue.o
$(CC) $^ -ldb -o $@
iscsiadm: $(COMMON_SRCS) strings.o discovery.o iscsiadm.o
diff --git a/usr/discovery.c b/usr/discovery.c
index 371023c..08aa454 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -68,7 +68,7 @@ send_nop_reply(iscsi_session_t *session, struct iscsi_nopin *nop,
log_debug(4, "sending nop reply for ttt %u, cmdsn %u, dlength %d",
ntohl(out.ttt), ntohl(out.cmdsn), ntoh24(out.dlength));
- return iscsi_send_pdu(&session->cnx[0], (struct iscsi_hdr *)&out,
+ return iscsi_io_send_pdu(&session->cnx[0], (struct iscsi_hdr *)&out,
ISCSI_DIGEST_NONE, data, ISCSI_DIGEST_NONE, timeout);
}
@@ -117,7 +117,7 @@ request_targets(iscsi_session_t *session)
if (++session->itt == ISCSI_RESERVED_TAG)
session->itt = 1;
- if (!iscsi_send_pdu(&session->cnx[0], hdr, ISCSI_DIGEST_NONE, data,
+ if (!iscsi_io_send_pdu(&session->cnx[0], hdr, ISCSI_DIGEST_NONE, data,
ISCSI_DIGEST_NONE, session->cnx[0].active_timeout)) {
log_error("failed to send SendTargets PDU");
return 0;
@@ -148,7 +148,7 @@ iterate_targets(iscsi_session_t *session, uint32_t ttt)
if (++session->itt == ISCSI_RESERVED_TAG)
session->itt = 1;
- if (!iscsi_send_pdu(&session->cnx[0], pdu, ISCSI_DIGEST_NONE, data,
+ if (!iscsi_io_send_pdu(&session->cnx[0], pdu, ISCSI_DIGEST_NONE, data,
ISCSI_DIGEST_NONE, session->cnx[0].active_timeout)) {
log_error("failed to send empty text PDU");
return 0;
@@ -1024,7 +1024,7 @@ iscsi_logout_and_disconnect(iscsi_session_t * session)
/*
* Send the logout request
*/
- rc = iscsi_send_pdu(&session->cnx[0], (struct iscsi_hdr *)&logout_req,
+ rc = iscsi_io_send_pdu(&session->cnx[0],(struct iscsi_hdr *)&logout_req,
ISCSI_DIGEST_NONE, NULL, ISCSI_DIGEST_NONE, 3);
if (!rc) {
log_error(
@@ -1036,8 +1036,9 @@ iscsi_logout_and_disconnect(iscsi_session_t * session)
* Read the logout response
*/
memset(&logout_resp, 0, sizeof(logout_resp));
- rc = iscsi_recv_pdu(&session->cnx[0], (struct iscsi_hdr *)&logout_resp,
- ISCSI_DIGEST_NONE, NULL, 0, ISCSI_DIGEST_NONE, 1);
+ rc = iscsi_io_recv_pdu(&session->cnx[0],
+ (struct iscsi_hdr *)&logout_resp, ISCSI_DIGEST_NONE, NULL,
+ 0, ISCSI_DIGEST_NONE, 1);
if (!rc) {
log_error("iscsid: logout - failed to receive logout resp");
goto done;
@@ -1051,7 +1052,7 @@ done:
/*
* Close the socket.
*/
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
}
int
@@ -1142,7 +1143,7 @@ set_address:
reconnect:
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
session->cmdsn = 1;
session->itt = 1;
@@ -1175,7 +1176,7 @@ reconnect:
sleep(login_delay);
}
- if (!iscsi_connect(&session->cnx[0])) {
+ if (!iscsi_io_connect(&session->cnx[0])) {
/* FIXME: IPv6 */
log_error("connection to discovery address %u.%u.%u.%u "
"failed", session->cnx[0].ip_address[0],
@@ -1219,7 +1220,7 @@ reconnect:
session->cnx[0].ip_address[1],
session->cnx[0].ip_address[2],
session->cnx[0].ip_address[3]);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
login_failures++;
goto set_address;
@@ -1236,7 +1237,7 @@ reconnect:
session->cnx[0].ip_address[1],
session->cnx[0].ip_address[2],
session->cnx[0].ip_address[3]);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
return 1;
}
@@ -1303,7 +1304,7 @@ reconnect:
session->cnx[0].ip_address[2],
session->cnx[0].ip_address[3],
status_class, status_detail);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
return 1;
case ISCSI_STATUS_CLS_TARGET_ERR:
/* FIXME: IPv6 */
@@ -1315,7 +1316,7 @@ reconnect:
session->cnx[0].ip_address[2],
session->cnx[0].ip_address[3],
status_class, status_detail);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
login_failures++;
goto reconnect;
default:
@@ -1328,7 +1329,7 @@ reconnect:
session->cnx[0].ip_address[2],
session->cnx[0].ip_address[3],
status_class, status_detail);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
login_failures++;
goto reconnect;
}
@@ -1433,7 +1434,7 @@ reconnect:
data + unused_length(&sendtargets);
timeout = msecs_until(&connection_timer);
- if (iscsi_recv_pdu(&session->cnx[0],
+ if (iscsi_io_recv_pdu(&session->cnx[0],
pdu, ISCSI_DIGEST_NONE, data,
end_of_data - data, ISCSI_DIGEST_NONE,
timeout)) {
@@ -1490,7 +1491,7 @@ reconnect:
"terminating",
config->address,
config->port);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
return 1;
}
}
@@ -1507,7 +1508,7 @@ reconnect:
"discovery session to %s:%d "
"terminating after hangup",
config->address, config->port);
- iscsi_disconnect(&session->cnx[0]);
+ iscsi_io_disconnect(&session->cnx[0]);
return 1;
}
}
diff --git a/usr/initiator.c b/usr/initiator.c
index 0769bf2..bad4c3a 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -34,7 +34,8 @@
#include "iscsid.h"
#include "iscsi_if.h"
#include "iscsi_ifev.h"
-#include "ipc.h"
+#include "mgmt_ipc.h"
+#include "iscsi_ipc.h"
#include "idbm.h"
#include "log.h"
@@ -42,6 +43,67 @@ static void __session_mainloop(void *data);
static char sysfs_file[PATH_MAX];
+static int
+__recvpool_alloc(iscsi_conn_t *conn)
+{
+ int i;
+
+ for (i = 0; i < RECVPOOL_MAX; i++) {
+ conn->recvpool[i] = calloc(1, ipc->ctldev_bufmax);
+ if (!conn->recvpool[i]) {
+ int j;
+ for (j = 0; j < i; j++)
+ free(conn->recvpool[j]);
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static void
+__recvpool_free(iscsi_conn_t *conn)
+{
+ int i;
+
+ for (i = 0; i < RECVPOOL_MAX; i++) {
+ if (!conn->recvpool[i]) {
+ log_error("recvpool leak: %d bytes",
+ ipc->ctldev_bufmax);
+ } else
+ free(conn->recvpool[i]);
+ }
+}
+
+void* recvpool_get(iscsi_conn_t *conn, int ev_size)
+{
+ int i;
+
+ if (ev_size > ipc->ctldev_bufmax)
+ return NULL;
+
+ for (i = 0; i < RECVPOOL_MAX; i++) {
+ if (conn->recvpool[i]) {
+ void *handle = conn->recvpool[i];
+ conn->recvpool[i] = NULL;
+ return handle;
+ }
+ }
+ return NULL;
+}
+
+void recvpool_put(iscsi_conn_t *conn, void *handle)
+{
+ int i;
+
+ for (i = 0; i < RECVPOOL_MAX; i++) {
+ if (!conn->recvpool[i]) {
+ conn->recvpool[i] = handle;
+ break;
+ }
+ }
+}
+
/*
* To sync caches before actual scsi_remove_host() we
* need manually walk through the sysfs scsi host and delete
@@ -78,10 +140,10 @@ __login_response_status(iscsi_conn_t *conn,
case LOGIN_IO_ERROR:
case LOGIN_WRONG_PORTAL_GROUP:
case LOGIN_REDIRECTION_FAILED:
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
return CNX_LOGIN_RETRY;
default:
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
log_error("cnx %d giving up on login attempts", conn->id);
break;
}
@@ -112,11 +174,11 @@ __check_iscsi_status_class(iscsi_session_t *session, int cid,
log_error("cnx %d login rejected: redirection "
"type 0x%x not supported",
conn->id, status_detail);
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
return CNX_LOGIN_RETRY;
}
case ISCSI_STATUS_CLS_INITIATOR_ERR:
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
switch (status_detail) {
case ISCSI_LOGIN_STATUS_AUTH_FAILED:
@@ -162,7 +224,7 @@ __check_iscsi_status_class(iscsi_session_t *session, int cid,
case ISCSI_STATUS_CLS_TARGET_ERR:
log_error("cnx %d login rejected: target error "
"(%02x/%02x)\n", conn->id, status_class, status_detail);
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
/*
* We have no idea what the problem is. But spec says initiator
* may retry later.
@@ -172,7 +234,7 @@ __check_iscsi_status_class(iscsi_session_t *session, int cid,
log_error("cnx %d login response with unknown status "
"class 0x%x, detail 0x%x\n", conn->id, status_class,
status_detail);
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
break;
}
@@ -257,6 +319,11 @@ __session_cnx_create(iscsi_session_t *session, int cid)
iscsi_conn_t *conn = &session->cnx[cid];
cnx_rec_t *cnx = &session->nrec.cnx[cid];
+ if (__recvpool_alloc(conn)) {
+ log_error("cannot allocate recvpool for cnx cid %d", cid);
+ return -ENOMEM;
+ }
+
/* connection's timeouts */
conn->id = cid;
conn->login_timeout = cnx->timeo.login_timeout;
@@ -309,7 +376,9 @@ __session_cnx_create(iscsi_session_t *session, int cid)
void
session_cnx_destroy(iscsi_session_t *session, int cid)
{
- /* nothing to do right now */
+ iscsi_conn_t *conn = &session->cnx[cid];
+
+ __recvpool_free(conn);
}
static iscsi_session_t*
@@ -392,13 +461,15 @@ __session_cnx_cleanup(iscsi_conn_t *conn)
{
iscsi_session_t *session = conn->session;
- if (ksession_cnx_destroy(session->ctrl_fd, conn)) {
+ if (ipc->destroy_cnx(session->transport_handle, conn->handle,
+ conn->id)) {
log_error("can not safely destroy connection %d", conn->id);
return;
}
session_cnx_destroy(session, conn->id);
- if (ksession_destroy(session->ctrl_fd, session)) {
+ if (ipc->destroy_session(session->transport_handle, session->handle,
+ session->id)) {
log_error("can not safely destroy session %d", session->id);
return;
}
@@ -407,13 +478,13 @@ __session_cnx_cleanup(iscsi_conn_t *conn)
}
static void
-__session_ipc_login_cleanup(queue_task_t *qtask, ipc_err_e err, int cnx_cleanup)
+__session_mgmt_ipc_login_cleanup(queue_task_t *qtask, mgmt_ipc_err_e err, int cnx_cleanup)
{
iscsi_conn_t *conn = qtask->conn;
iscsi_session_t *session = conn->session;
if (cnx_cleanup) {
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
__session_cnx_cleanup(conn);
} else {
session_cnx_destroy(session, conn->id);
@@ -422,9 +493,9 @@ __session_ipc_login_cleanup(queue_task_t *qtask, ipc_err_e err, int cnx_cleanup)
}
qtask->u.login.rsp.err = err;
- write(qtask->u.login.ipc_fd, &qtask->u.login.rsp,
+ write(qtask->u.login.mgmt_ipc_fd, &qtask->u.login.rsp,
sizeof(qtask->u.login.rsp));
- close(qtask->u.login.ipc_fd);
+ close(qtask->u.login.mgmt_ipc_fd);
free(qtask);
}
@@ -443,7 +514,7 @@ __send_nopin_rsp(iscsi_conn_t *conn, struct iscsi_nopin *rhdr, char *data)
hdr.ttt = rhdr->ttt;
hdr.itt = ISCSI_RESERVED_TAG;
- return iscsi_send_pdu(conn, (struct iscsi_hdr*)&hdr,
+ return iscsi_io_send_pdu(conn, (struct iscsi_hdr*)&hdr,
ISCSI_DIGEST_NONE, data, ISCSI_DIGEST_NONE, 0);
}
@@ -495,8 +566,8 @@ __session_cnx_recv_pdu(queue_item_t *item)
if (iscsi_login_rsp(session, c)) {
log_debug(1, "login_rsp ret (%d)", c->ret);
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
+ __session_mgmt_ipc_login_cleanup(c->qtask,
+ MGMT_IPC_ERR_LOGIN_FAILURE, 1);
return;
}
@@ -504,17 +575,91 @@ __session_cnx_recv_pdu(queue_item_t *item)
/* more nego. needed! */
conn->state = STATE_IN_LOGIN;
if (iscsi_login_req(session, c)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
+ __session_mgmt_ipc_login_cleanup(c->qtask,
+ MGMT_IPC_ERR_LOGIN_FAILURE, 1);
return;
}
} else {
+ int i, rc;
+ uint32_t one = 1, zero = 0;
+ struct cnxparam {
+ int param;
+ uint32_t *value;
+ int cnx_only; } cnxtbl[ISCSI_PARAM_MAX] = {
+
+ {
+ .param = ISCSI_PARAM_MAX_RECV_DLENGTH,
+ .value = &conn->max_recv_dlength,
+ .cnx_only = 1,
+ }, {
+ .param = ISCSI_PARAM_MAX_XMIT_DLENGTH,
+ .value = &conn->max_xmit_dlength,
+ .cnx_only = 1,
+ }, {
+ .param = ISCSI_PARAM_HDRDGST_EN,
+ .value = &conn->hdrdgst_en,
+ .cnx_only = 1,
+ }, {
+ .param = ISCSI_PARAM_DATADGST_EN,
+ .value = &conn->datadgst_en,
+ .cnx_only = 1,
+ }, {
+ .param = ISCSI_PARAM_INITIAL_R2T_EN,
+ .value = &session->initial_r2t_en,
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_MAX_R2T,
+ .value = &one, /* FIXME: session->max_r2t */
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_IMM_DATA_EN,
+ .value = &session->imm_data_en,
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_FIRST_BURST,
+ .value = &session->first_burst,
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_MAX_BURST,
+ .value = &session->max_burst,
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_PDU_INORDER_EN,
+ .value = &session->pdu_inorder_en,
+ .cnx_only = 0,
+ }, {
+ .param =ISCSI_PARAM_DATASEQ_INORDER_EN,
+ .value = &session->dataseq_inorder_en,
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_ERL,
+ .value = &zero, /* FIXME: session->erl */
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_IFMARKER_EN,
+ .value = &zero,/* FIXME: session->ifmarker_en */
+ .cnx_only = 0,
+ }, {
+ .param = ISCSI_PARAM_OFMARKER_EN,
+ .value = &zero,/* FIXME: session->ofmarker_en */
+ .cnx_only = 0,
+ }
+
+ /*
+ * FIXME: set these timeouts via set_param() API
+ *
+ * rec->session.timeo
+ * rec->session.timeo
+ * rec->session.err_timeo
+ */
+ };
+
/* almost! entered full-feature phase */
if (__login_response_status(conn, c->ret) !=
CNX_LOGIN_SUCCESS) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
+ __session_mgmt_ipc_login_cleanup(c->qtask,
+ MGMT_IPC_ERR_LOGIN_FAILURE, 1);
return;
}
@@ -522,140 +667,67 @@ __session_cnx_recv_pdu(queue_item_t *item)
if (__check_iscsi_status_class(session, conn->id,
c->status_class, c->status_detail) !=
CNX_LOGIN_SUCCESS) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
+ __session_mgmt_ipc_login_cleanup(c->qtask,
+ MGMT_IPC_ERR_LOGIN_FAILURE, 1);
return;
}
/* Entered full-feature phase! */
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_MAX_RECV_DLENGTH,
- conn->max_recv_dlength)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_MAX_XMIT_DLENGTH,
- conn->max_xmit_dlength)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_HDRDGST_EN, conn->hdrdgst_en)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_DATADGST_EN, conn->datadgst_en)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (conn->id == 0) {
- /* setup session's op. parameters just once */
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_INITIAL_R2T_EN,
- session->initial_r2t_en)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_MAX_R2T,
- 1 /* FIXME: session->max_r2t */)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_IMM_DATA_EN,
- session->imm_data_en)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_FIRST_BURST,
- session->first_burst)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_MAX_BURST,
- session->max_burst)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_PDU_INORDER_EN,
- session->pdu_inorder_en)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_DATASEQ_INORDER_EN,
- session->dataseq_inorder_en)) {
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_ERL,
- 0 /* FIXME: session->erl */)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_IFMARKER_EN,
- 0 /* FIXME: session->ifmarker_en */)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
+ for (i = 0; i < ISCSI_PARAM_MAX; i++) {
+ if (conn->id != 0 && !cnxtbl[i].cnx_only)
+ continue;
+ if (ipc->set_param(
+ session->transport_handle,
+ conn->handle, cnxtbl[i].param,
+ *cnxtbl[i].value, &rc) || rc) {
+ log_error("can't set operational "
+ "parameter %d for cnx with "
+ "id = %d, retcode %d (%d)",
+ cnxtbl[i].param, conn->id,
+ rc, errno);
+ __session_mgmt_ipc_login_cleanup(
+ c->qtask,
+ MGMT_IPC_ERR_LOGIN_FAILURE, 1);
return;
}
- if (ksession_set_param(session->ctrl_fd, conn,
- ISCSI_PARAM_OFMARKER_EN,
- 0 /* FIXME: session->ofmarker_en */)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_LOGIN_FAILURE, 1);
- return;
- }
-
- /*
- * FIXME: set these timeouts via set_param() API
- *
- * rec->session.timeo
- * rec->session.timeo
- * rec->session.err_timeo
- */
+ log_debug(3, "set operational parameter %d "
+ "to %u", cnxtbl[i].param,
+ *cnxtbl[i].value);
}
- if (ksession_start_cnx(session->ctrl_fd, conn)) {
- __session_ipc_login_cleanup(c->qtask,
- IPC_ERR_INTERNAL, 1);
+ if (ipc->start_cnx(session->transport_handle,
+ conn->handle, &rc) || rc) {
+ __session_mgmt_ipc_login_cleanup(c->qtask,
+ MGMT_IPC_ERR_INTERNAL, 1);
+ log_error("can't start connection 0x%p with "
+ "id = %d, retcode %d (%d)",
+ (void*)conn->handle, conn->id, rc,
+ errno);
return;
}
conn->state = STATE_LOGGED_IN;
if (session->r_stage == R_STAGE_NO_CHANGE) {
- c->qtask->u.login.rsp.err = IPC_OK;
- write(c->qtask->u.login.ipc_fd,
+ c->qtask->u.login.rsp.err = MGMT_IPC_OK;
+ write(c->qtask->u.login.mgmt_ipc_fd,
&c->qtask->u.login.rsp,
sizeof(c->qtask->u.login.rsp));
- close(c->qtask->u.login.ipc_fd);
+ close(c->qtask->u.login.mgmt_ipc_fd);
free(c->qtask);
- } else
+ log_debug(3, "connection 0x%p is operational "
+ "now", (void*)conn->handle);
+ } else {
session->r_stage = R_STAGE_NO_CHANGE;
+ log_debug(3, "connection 0x%p is operational "
+ "after recovery", (void*)conn->handle);
+ }
}
} else if (conn->state == STATE_LOGGED_IN) {
struct iscsi_hdr hdr;
/* read incomming PDU */
- if (!iscsi_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE, conn->data,
+ if (!iscsi_io_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE,conn->data,
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH,
ISCSI_DIGEST_NONE, 0)) {
return;
@@ -675,7 +747,7 @@ __session_cnx_recv_pdu(queue_item_t *item)
static void
__session_cnx_poll(queue_item_t *item)
{
- ipc_err_e err = IPC_OK;
+ mgmt_ipc_err_e err = MGMT_IPC_OK;
queue_task_t *qtask = item->context;
iscsi_conn_t *conn = qtask->conn;
iscsi_login_context_t *c = &conn->login_context;
@@ -683,7 +755,7 @@ __session_cnx_poll(queue_item_t *item)
int rc;
if (conn->state == STATE_XPT_WAIT) {
- rc = iscsi_tcp_poll(conn);
+ rc = iscsi_io_tcp_poll(conn);
if (rc == 0) {
/* timedout: poll again */
queue_produce(session->queue, EV_CNX_POLL, qtask, 0, 0);
@@ -699,30 +771,47 @@ __session_cnx_poll(queue_item_t *item)
/* do not allocate new connection in case of reopen */
if (session->r_stage == R_STAGE_NO_CHANGE) {
if (conn->id == 0 &&
- ksession_create(session->ctrl_fd,
- session)) {
- err = IPC_ERR_INTERNAL;
+ ipc->create_session(
+ session->transport_handle,
+ (ulong_t)session,
+ session->nrec.session.initial_cmdsn,
+ &session->handle, &session->id)) {
+ log_error("can't create session (%d)",
+ errno);
+ err = MGMT_IPC_ERR_INTERNAL;
goto cleanup;
}
+ log_debug(3, "created new iSCSI session, "
+ "handle 0x%p", (void*)session->handle);
- if (ksession_cnx_create(session->ctrl_fd,
- session, conn)) {
- err = IPC_ERR_INTERNAL;
+ if (ipc->create_cnx(session->transport_handle,
+ session->handle, (ulong_t)conn,
+ session->id, conn->id, &conn->handle)) {
+ err = MGMT_IPC_ERR_INTERNAL;
goto s_cleanup;
}
+ log_debug(3, "created new iSCSI connection, "
+ "handle 0x%p", (void*)conn->handle);
}
- if (ksession_cnx_bind(session->ctrl_fd, session,
- conn)) {
- err = IPC_ERR_INTERNAL;
+ if (ipc->bind_cnx(session->transport_handle,
+ session->handle, conn->handle, conn->socket_fd,
+ (conn->id == 0), &rc) || rc) {
+ log_error("can't bind a cnx with id = %d, "
+ "retcode %d (%d)", conn->id, rc,
+ errno);
+ err = MGMT_IPC_ERR_INTERNAL;
goto c_cleanup;
}
+ log_debug(3, "bound iSCSI connection (handle 0x%p) to "
+ "session (handle 0x%p)", (void*)conn->handle,
+ (void*)session->handle);
conn->kernel_io = 1;
- conn->send_pdu_begin = ksession_send_pdu_begin;
- conn->send_pdu_end = ksession_send_pdu_end;
- conn->recv_pdu_begin = ksession_recv_pdu_begin;
- conn->recv_pdu_end = ksession_recv_pdu_end;
+ conn->send_pdu_begin = ipc->send_pdu_begin;
+ conn->send_pdu_end = ipc->send_pdu_end;
+ conn->recv_pdu_begin = ipc->recv_pdu_begin;
+ conn->recv_pdu_end = ipc->recv_pdu_end;
conn->send_pdu_timer_add = __send_pdu_timer_add;
conn->send_pdu_timer_remove = __send_pdu_timer_remove;
@@ -732,19 +821,19 @@ __session_cnx_poll(queue_item_t *item)
c->bufsize = sizeof(conn->data);
if (iscsi_login_begin(session, c)) {
- err = IPC_ERR_LOGIN_FAILURE;
+ err = MGMT_IPC_ERR_LOGIN_FAILURE;
goto c_cleanup;
}
conn->state = STATE_IN_LOGIN;
if (iscsi_login_req(session, c)) {
- err = IPC_ERR_LOGIN_FAILURE;
+ err = MGMT_IPC_ERR_LOGIN_FAILURE;
goto c_cleanup;
}
} else {
actor_delete(&conn->connect_timer);
/* error during connect */
- err = IPC_ERR_TCP_FAILURE;
+ err = MGMT_IPC_ERR_TCP_FAILURE;
goto cleanup;
}
}
@@ -752,15 +841,17 @@ __session_cnx_poll(queue_item_t *item)
return;
c_cleanup:
- if (ksession_cnx_destroy(session->ctrl_fd, conn)) {
+ if (ipc->destroy_cnx(session->transport_handle, conn->handle,
+ conn->id)) {
log_error("can not safely destroy connection %d", conn->id);
}
s_cleanup:
- if (ksession_destroy(session->ctrl_fd, session)) {
+ if (ipc->destroy_session(session->transport_handle, session->handle,
+ session->id)) {
log_error("can not safely destroy session %d", session->id);
}
cleanup:
- __session_ipc_login_cleanup(qtask, err, 0);
+ __session_mgmt_ipc_login_cleanup(qtask, err, 0);
}
static void
@@ -787,20 +878,23 @@ __session_cnx_reopen(iscsi_conn_t *conn, int do_stop)
session->reopen_qtask.conn = conn;
if (do_stop) {
- if (ksession_stop_cnx(session->ctrl_fd, conn,
+ if (ipc->stop_cnx(session->transport_handle, conn->handle,
STOP_CNX_RECOVER)) {
- log_error("can not safely stop connection %d",
- conn->id);
+ log_error("can't stop connection 0x%p with "
+ "id = %d (%d)", (void*)conn->handle,
+ conn->id, errno);
return -1;
}
- iscsi_disconnect(conn);
+ log_debug(3, "connection 0x%p is stopped for recovery",
+ (void*)conn->handle);
+ iscsi_io_disconnect(conn);
}
- rc = iscsi_tcp_connect(conn, 1);
+ rc = iscsi_io_tcp_connect(conn, 1);
if (rc < 0 && errno != EINPROGRESS) {
log_error("cannot make a connection to %s:%d (%d)",
inet_ntoa(conn->addr.sin_addr), conn->port, errno);
- return IPC_ERR_TCP_FAILURE;
+ return MGMT_IPC_ERR_TCP_FAILURE;
}
conn->state = STATE_XPT_WAIT;
@@ -810,7 +904,7 @@ __session_cnx_reopen(iscsi_conn_t *conn, int do_stop)
actor_timer(&conn->connect_timer, conn->login_timeout*1000,
__connect_timedout, &session->reopen_qtask);
- return IPC_OK;
+ return MGMT_IPC_OK;
}
static void
@@ -825,8 +919,8 @@ __session_cnx_timer(queue_item_t *item)
log_debug(6, "cnx_timer popped at XPT_WAIT: login");
/* timeout during initial connect.
* clean connection. write ipc rsp */
- __session_ipc_login_cleanup(qtask,
- IPC_ERR_TCP_TIMEOUT, 0);
+ __session_mgmt_ipc_login_cleanup(qtask,
+ MGMT_IPC_ERR_TCP_TIMEOUT, 0);
} else if (session->r_stage == R_STAGE_SESSION_REOPEN) {
log_debug(6, "cnx_timer popped at XPT_WAIT: reopen");
/* timeout during reopen connect.
@@ -839,20 +933,22 @@ __session_cnx_timer(queue_item_t *item)
}
}
} else if (conn->state == STATE_IN_LOGIN) {
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
if (session->r_stage == R_STAGE_NO_CHANGE) {
log_debug(6, "cnx_timer popped at IN_LOGIN");
/* send pdu timeout. clean connection. write rsp */
- if (ksession_cnx_destroy(session->ctrl_fd, conn)) {
+ if (ipc->destroy_cnx(session->transport_handle,
+ conn->handle, conn->id)) {
log_error("can not safely destroy "
"connection %d", conn->id);
}
- if (ksession_destroy(session->ctrl_fd, session)) {
+ if (ipc->destroy_session(session->transport_handle,
+ session->handle, session->id)) {
log_error("can not safely destroy session %d",
session->id);
}
- __session_ipc_login_cleanup(qtask,
- IPC_ERR_PDU_TIMEOUT, 0);
+ __session_mgmt_ipc_login_cleanup(qtask,
+ MGMT_IPC_ERR_PDU_TIMEOUT, 0);
} else if (session->r_stage == R_STAGE_SESSION_REOPEN) {
if (--session->reopen_cnt > 0) {
if (__session_cnx_reopen(conn, 1))
@@ -924,12 +1020,16 @@ __session_cnx_error(queue_item_t *item)
__session_cnx_cleanup(conn);
return;
} else {
- if (ksession_stop_cnx(session->ctrl_fd, conn, STOP_CNX_TERM)) {
- log_error("can not safely stop connection %d",
- conn->id);
+ if (ipc->stop_cnx(session->transport_handle, conn->handle,
+ STOP_CNX_TERM)) {
+ log_error("can't stop connection 0x%p with "
+ "id = %d (%d)", (void*)conn->handle,
+ conn->id, errno);
return;
}
- iscsi_disconnect(conn);
+ log_debug(3, "connection 0x%p is stopped for termination",
+ (void*)conn->handle);
+ iscsi_io_disconnect(conn);
}
__session_cnx_cleanup(conn);
@@ -981,8 +1081,10 @@ __get_transport_by_name(char *transport_name)
struct iscsi_uevent ev;
int i;
- if (ktrans_list(control_fd, &ev))
+ if (ipc->trans_list(&ev)) {
+ log_error("can't retreive transport list (%d)", errno);
return 0;
+ }
for (i = 0; i < ISCSI_TRANSPORT_MAX; i++) {
if (ev.r.t_list.elements[i].handle) {
@@ -1003,33 +1105,33 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
uint64_t transport_handle;
if (!rec->active_cnx)
- return IPC_ERR_INVAL;
+ return MGMT_IPC_ERR_INVAL;
transport_handle = __get_transport_by_name(rec->transport_name);
if (!transport_handle)
- return IPC_ERR_TRANS_NOT_FOUND;
+ return MGMT_IPC_ERR_TRANS_NOT_FOUND;
session = __session_create(rec, transport_handle);
if (!session)
- return IPC_ERR_LOGIN_FAILURE;
+ return MGMT_IPC_ERR_LOGIN_FAILURE;
/* FIXME: login all connections! marked as "automatic" */
/* create leading connection */
if (__session_cnx_create(session, 0)) {
__session_destroy(session);
- return IPC_ERR_LOGIN_FAILURE;
+ return MGMT_IPC_ERR_LOGIN_FAILURE;
}
conn = &session->cnx[0];
qtask->conn = conn;
- rc = iscsi_tcp_connect(conn, 1);
+ rc = iscsi_io_tcp_connect(conn, 1);
if (rc < 0 && errno != EINPROGRESS) {
log_error("cannot make a connection to %s:%d (%d)",
inet_ntoa(conn->addr.sin_addr), conn->port, errno);
session_cnx_destroy(session, 0);
__session_destroy(session);
- return IPC_ERR_TCP_FAILURE;
+ return MGMT_IPC_ERR_TCP_FAILURE;
}
conn->state = STATE_XPT_WAIT;
@@ -1038,7 +1140,7 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
actor_timer(&conn->connect_timer, conn->login_timeout*1000,
__connect_timedout, qtask);
- return IPC_OK;
+ return MGMT_IPC_OK;
}
int
@@ -1050,7 +1152,7 @@ session_logout_task(iscsi_session_t *session, queue_task_t *qtask)
conn = &session->cnx[0];
if (conn->state != STATE_LOGGED_IN &&
conn->state != STATE_CLEANUP_WAIT) {
- return IPC_ERR_INTERNAL;
+ return MGMT_IPC_ERR_INTERNAL;
}
/* FIXME: implement Logout Request */
@@ -1058,28 +1160,37 @@ session_logout_task(iscsi_session_t *session, queue_task_t *qtask)
__session_delete_luns(session);
/* stop if connection is logged in */
- if (conn->state == STATE_LOGGED_IN &&
- ksession_stop_cnx(session->ctrl_fd, conn, STOP_CNX_TERM)) {
- return IPC_ERR_INTERNAL;
+ if (conn->state == STATE_LOGGED_IN) {
+ if (ipc->stop_cnx(session->transport_handle, conn->handle,
+ STOP_CNX_TERM)) {
+ log_error("can't stop connection 0x%p with "
+ "id = %d (%d)", (void*)conn->handle,
+ conn->id, errno);
+ return MGMT_IPC_ERR_INTERNAL;
+ }
+ log_debug(3, "connection 0x%p is stopped for termination",
+ (void*)conn->handle);
}
- iscsi_disconnect(conn);
+ iscsi_io_disconnect(conn);
- if (ksession_cnx_destroy(session->ctrl_fd, conn)) {
- return IPC_ERR_INTERNAL;
+ if (ipc->destroy_cnx(session->transport_handle, conn->handle,
+ conn->id)) {
+ return MGMT_IPC_ERR_INTERNAL;
}
session_cnx_destroy(session, conn->id);
- if (ksession_destroy(session->ctrl_fd, session)) {
- return IPC_ERR_INTERNAL;
+ if (ipc->destroy_session(session->transport_handle, session->handle,
+ session->id)) {
+ return MGMT_IPC_ERR_INTERNAL;
}
__session_destroy(session);
- qtask->u.login.rsp.err = IPC_OK;
- write(qtask->u.login.ipc_fd, &qtask->u.login.rsp,
+ qtask->u.login.rsp.err = MGMT_IPC_OK;
+ write(qtask->u.login.mgmt_ipc_fd, &qtask->u.login.rsp,
sizeof(qtask->u.login.rsp));
- close(qtask->u.login.ipc_fd);
+ close(qtask->u.login.mgmt_ipc_fd);
free(qtask);
- return IPC_OK;
+ return MGMT_IPC_OK;
}
diff --git a/usr/initiator.h b/usr/initiator.h
index 7f55e29..dad4aff 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -2,7 +2,7 @@
* iSCSI Initiator
*
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
- * maintained by open-iscsi@@googlegroups.com
+ * maintained by open-iscsi@googlegroups.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
@@ -27,7 +27,7 @@
#include "iscsi_if.h"
#include "iscsi_ifev.h"
#include "auth.h"
-#include "ipc.h"
+#include "mgmt_ipc.h"
#include "config.h"
#include "actor.h"
#include "queue.h"
@@ -113,14 +113,15 @@ typedef struct iscsi_login_context {
struct iscsi_session;
struct iscsi_conn;
-typedef void (*send_pdu_begin_f)(int ctrl_fd, struct iscsi_session *session,
- struct iscsi_conn *conn, int hdr_size, int data_size);
-typedef int (*send_pdu_end_f)(int ctrl_fd, struct iscsi_session *session,
- struct iscsi_conn *conn);
-typedef int (*recv_pdu_begin_f)(int ctrl_fd, struct iscsi_conn *conn,
- ulong_t recv_handle, ulong_t *pdu_handle, int *pdu_size);
-typedef int (*recv_pdu_end_f)(int ctrl_fd, struct iscsi_conn *conn,
- ulong_t pdu_handle);
+typedef void (*send_pdu_begin_f) (uint64_t transport_handle, ulong_t dp_cnx,
+ int hdr_size, int data_size);
+typedef int (*send_pdu_end_f) (uint64_t transport_handle, ulong_t dp_cnx,
+ int *retcode);
+typedef int (*recv_pdu_begin_f) (uint64_t transport_handle, ulong_t dp_cnx,
+ ulong_t recv_handle, ulong_t *pdu_handle,
+ int *pdu_size);
+typedef int (*recv_pdu_end_f) (uint64_t transport_handle, ulong_t dp_cnx,
+ ulong_t pdu_handle);
typedef void (*send_pdu_timer_add_f)(struct iscsi_conn *conn, int timeout);
typedef void (*send_pdu_timer_remove_f)(struct iscsi_conn *conn);
@@ -146,6 +147,9 @@ typedef struct iscsi_conn {
send_pdu_timer_add_f send_pdu_timer_add;
send_pdu_timer_remove_f send_pdu_timer_remove;
+#define RECVPOOL_MAX 32
+ void* recvpool[RECVPOOL_MAX];
+
/* login state machine */
int current_stage;
int next_stage;
@@ -185,12 +189,12 @@ typedef struct queue_task {
struct ipcreq_login {
iscsiadm_req_t req;
iscsiadm_rsp_t rsp;
- int ipc_fd;
+ int mgmt_ipc_fd;
} login;
struct ipcreq_logout {
iscsiadm_req_t req;
iscsiadm_rsp_t rsp;
- int ipc_fd;
+ int mgmt_ipc_fd;
} logout;
/* iSCSI requests originated via CTL */
struct ctlreq_recv_pdu {
@@ -316,13 +320,13 @@ extern int iscsi_login_rsp(iscsi_session_t *session, iscsi_login_context_t *c);
#define IRRELEVANT_DATASEQUENCEINORDER 0x80
/* io.c */
-extern int iscsi_tcp_poll(iscsi_conn_t *conn);
-extern int iscsi_tcp_connect(iscsi_conn_t *conn, int non_blocking);
-extern int iscsi_connect(iscsi_conn_t *conn);
-extern void iscsi_disconnect(iscsi_conn_t *conn);
-extern int iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
+extern int iscsi_io_tcp_poll(iscsi_conn_t *conn);
+extern int iscsi_io_tcp_connect(iscsi_conn_t *conn, int non_blocking);
+extern int iscsi_io_connect(iscsi_conn_t *conn);
+extern void iscsi_io_disconnect(iscsi_conn_t *conn);
+extern int iscsi_io_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
int hdr_digest, char *data, int data_digest, int timeout);
-extern int iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
+extern int iscsi_io_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
int hdr_digest, char *data, int max_data_length, int data_digest,
int timeout);
@@ -330,27 +334,7 @@ extern int iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
extern int session_login_task(node_rec_t *rec, queue_task_t *qtask);
extern int session_logout_task(iscsi_session_t *session, queue_task_t *qtask);
extern iscsi_session_t* session_find_by_rec(node_rec_t *rec);
-
-/* transport API Ioctl/IPC/NETLINK/etc */
-extern int ksession_create(int ctrl_fd, iscsi_session_t *session);
-extern int ksession_destroy(int ctrl_fd, iscsi_session_t *session);
-extern int ksession_cnx_create(int ctrl_fd, iscsi_session_t *session,
- iscsi_conn_t *conn);
-extern int ksession_cnx_destroy(int ctrl_fd, iscsi_conn_t *conn);
-extern int ksession_cnx_bind(int ctrl_fd, iscsi_session_t *session,
- iscsi_conn_t *conn);
-extern void ksession_send_pdu_begin(int ctrl_fd, iscsi_session_t *session,
- iscsi_conn_t *conn, int hdr_size, int data_size);
-extern int ksession_send_pdu_end(int ctrl_fd, iscsi_session_t *session,
- iscsi_conn_t *conn);
-extern int ksession_set_param(int ctrl_fd, iscsi_conn_t *conn,
- enum iscsi_param param, uint32_t value);
-extern int ksession_stop_cnx(int ctrl_fd, iscsi_conn_t *conn, int flag);
-extern int ksession_start_cnx(int ctrl_fd, iscsi_conn_t *conn);
-extern int ksession_recv_pdu_begin(int ctrl_fd, iscsi_conn_t *conn,
- ulong_t recv_handle, ulong_t *pdu_handle, int *pdu_size);
-extern int ksession_recv_pdu_end(int ctrl_fd, iscsi_conn_t *conn,
- ulong_t pdu_handle);
-extern int ktrans_list(int ctrl_fd, struct iscsi_uevent *ev);
+extern void* recvpool_get(iscsi_conn_t *conn, int ev_size);
+extern void recvpool_put(iscsi_conn_t *conn, void *handle);
#endif /* INITIATOR_H */
diff --git a/usr/io.c b/usr/io.c
index b0a2cf7..8f8b937 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -32,6 +32,7 @@
#include "iscsi_proto.h"
#include "initiator.h"
+#include "iscsi_ipc.h"
#include "log.h"
#define LOG_CONN_CLOSED(conn) \
@@ -63,7 +64,7 @@ set_non_blocking(int fd)
}
int
-iscsi_tcp_connect(iscsi_conn_t *conn, int non_blocking)
+iscsi_io_tcp_connect(iscsi_conn_t *conn, int non_blocking)
{
int rc, onearg;
@@ -137,7 +138,7 @@ iscsi_tcp_connect(iscsi_conn_t *conn, int non_blocking)
}
int
-iscsi_tcp_poll(iscsi_conn_t *conn)
+iscsi_io_tcp_poll(iscsi_conn_t *conn)
{
int rc;
struct pollfd pdesc;
@@ -165,7 +166,7 @@ iscsi_tcp_poll(iscsi_conn_t *conn)
}
int
-iscsi_connect(iscsi_conn_t *conn)
+iscsi_io_connect(iscsi_conn_t *conn)
{
int rc, ret;
struct sigaction action;
@@ -186,7 +187,7 @@ iscsi_connect(iscsi_conn_t *conn)
/* perform blocking TCP connect operation when no async request
* associated. SendTargets Discovery know to work in such a mode.
*/
- rc = iscsi_tcp_connect(conn, 0);
+ rc = iscsi_io_tcp_connect(conn, 0);
if (timedout) {
log_debug(1, "socket %d connect timed out", conn->socket_fd);
ret = 0;
@@ -218,7 +219,7 @@ done:
}
void
-iscsi_disconnect(iscsi_conn_t *conn)
+iscsi_io_disconnect(iscsi_conn_t *conn)
{
if (conn->socket_fd >= 0) {
log_debug(1, "disconnecting conn %p, fd %d", conn,
@@ -244,7 +245,7 @@ iscsi_log_text(struct iscsi_hdr *pdu, char *data)
}
int
-iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
+iscsi_io_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
int hdr_digest, char *data, int data_digest, int timeout)
{
int rc, ret = 0;
@@ -338,7 +339,7 @@ iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
pad_bytes = 0;
if (conn->kernel_io) {
- conn->send_pdu_begin(session->ctrl_fd, session, conn,
+ conn->send_pdu_begin(session->transport_handle, conn->handle,
end - header, ntoh24(hdr->dlength) + pad_bytes);
conn->send_pdu_timer_add(conn, timeout);
}
@@ -347,7 +348,10 @@ iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
vec[0].iov_base = header;
vec[0].iov_len = end - header;
- rc = ctldev_writev(session->ctrl_fd, 0, vec, 1);
+ if (!conn->kernel_io)
+ rc = writev(session->ctrl_fd, vec, 1);
+ else
+ rc = ipc->writev(0, vec, 1);
if (timedout) {
log_error("socket %d write timed out",
conn->socket_fd);
@@ -372,7 +376,10 @@ iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
vec[1].iov_base = (void *) &pad;
vec[1].iov_len = pad_bytes;
- rc = ctldev_writev(session->ctrl_fd, 0, vec, 2);
+ if (!conn->kernel_io)
+ rc = writev(session->ctrl_fd, vec, 2);
+ else
+ rc = ipc->writev(0, vec, 2);
if (timedout) {
log_error("socket %d write timed out",
conn->socket_fd);
@@ -394,7 +401,8 @@ iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
}
if (conn->kernel_io) {
- if (conn->send_pdu_end(session->ctrl_fd, session, conn)) {
+ if (conn->send_pdu_end(session->transport_handle, conn->handle,
+ &rc)) {
ret = 0;
goto done;
}
@@ -412,7 +420,7 @@ iscsi_send_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
}
int
-iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
+iscsi_io_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
int hdr_digest, char *data, int max_data_length, int data_digest,
int timeout)
{
@@ -447,7 +455,7 @@ iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
timedout = 0;
alarm(timeout);
} else {
- if (conn->recv_pdu_begin(session->ctrl_fd, conn,
+ if (conn->recv_pdu_begin(session->ctrl_fd, conn->handle,
conn->recv_handle, &pdu_handle, &pdu_size)) {
failed = 1;
goto done;
@@ -456,8 +464,11 @@ iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
/* read a response header */
do {
- rlen = ctldev_read(session->ctrl_fd, header,
- sizeof (*hdr) - h_bytes);
+ if (!conn->kernel_io)
+ rlen = read(session->ctrl_fd, header,
+ sizeof (*hdr) - h_bytes);
+ else
+ rlen = ipc->read(header, sizeof (*hdr) - h_bytes);
if (timedout) {
log_error("socket %d header read timed out",
conn->socket_fd);
@@ -510,8 +521,11 @@ iscsi_recv_pdu(iscsi_conn_t *conn, struct iscsi_hdr *hdr,
/* read the rest into our buffer */
d_bytes = 0;
while (d_bytes < dlength) {
- rlen = ctldev_read(session->ctrl_fd, data + d_bytes,
- dlength - d_bytes);
+ if (!conn->kernel_io)
+ rlen = read(session->ctrl_fd, data + d_bytes,
+ dlength - d_bytes);
+ else
+ rlen = ipc->read(data + d_bytes, dlength - d_bytes);
if (timedout) {
log_error("socket %d data read timed out",
conn->socket_fd);
@@ -603,7 +617,8 @@ done:
sigaction(SIGALRM, &old, NULL);
} else {
/* finalyze receive transaction */
- if (conn->recv_pdu_end(session->ctrl_fd, conn, pdu_handle)) {
+ if (conn->recv_pdu_end(session->ctrl_fd, (ulong_t)conn,
+ pdu_handle)) {
failed = 1;
}
conn->send_pdu_timer_remove(conn);
diff --git a/usr/ioctl.c b/usr/ioctl.c
deleted file mode 100644
index 2a34fea..0000000
--- a/usr/ioctl.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * iSCSI Ioctl and SysFS control
- *
- * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
- * maintained by open-iscsi@@googlegroups.com
- *
- * 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.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "iscsi_u.h"
-#include "iscsid.h"
-#include "log.h"
-
-#define CTL_DEVICE "/dev/iscsictl"
-#define SYSFS_ROOT "/sysfs/class/iscsi"
-
-static int ctrl_fd;
-
-int
-ctldev_read(iscsi_conn_t *conn, char *data, int count)
-{
- return read(ctrl_fd, data, count);
-}
-
-int
-ctldev_writev(iscsi_conn_t *conn, struct iovec *iovp, int count)
-{
- return writev(ctrl_fd, iovp, count);
-}
-
-int
-ksession_create(iscsi_session_t *session)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_CREATE_SESSION;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.c_session.session_handle = (ulong_t)session;
- ev.u.c_session.sid = session->id;
- ev.u.c_session.initial_cmdsn = session->nrec.session.initial_cmdsn;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_CREATE_SESSION, &ev)) < 0) {
- log_error("can't create session with id = %d (%d)",
- session->id, errno);
- return rc;
- }
-
- session->handle = ev.r.handle;
- log_debug(3, "created new iSCSI session, handle 0x%p",
- (void*)session->handle);
-
- return 0;
-}
-
-int
-ksession_destroy(iscsi_session_t *session)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_DESTROY_SESSION;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.d_session.session_handle = session->handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_DESTROY_SESSION, &ev)) < 0) {
- log_error("can't destroy session with id = %d (%d)",
- session->id, errno);
- return rc;
- }
-
- log_warning("destroyed iSCSI session, handle 0x%p",
- (void*)session->handle);
-
- return 0;
-}
-
-int
-ksession_cnx_create(iscsi_session_t *session, iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_CREATE_CNX;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.c_cnx.session_handle = session->handle;
- ev.u.c_cnx.cnx_handle = (ulong_t)conn;
- ev.u.c_cnx.socket_fd = conn->socket_fd;
- ev.u.c_cnx.cid = conn->id;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_CREATE_CNX, &ev)) < 0) {
- log_error("can't create cnx with id = %d (%d)",
- conn->id, errno);
- return rc;
- }
-
- conn->handle = ev.r.handle;
- log_debug(3, "created new iSCSI connection, handle 0x%p",
- (void*)conn->handle);
- return 0;
-}
-
-int
-ksession_cnx_destroy(iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_DESTROY_CNX;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.d_cnx.cnx_handle = conn->handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_DESTROY_CNX, &ev)) < 0) {
- log_error("can't destroy cnx with id = %d (%d)",
- conn->id, errno);
- return rc;
- }
-
- log_warning("destroyed iSCSI connection, handle 0x%p",
- (void*)conn->handle);
- return 0;
-}
-
-int
-ksession_cnx_bind(iscsi_session_t *session, iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_BIND_CNX;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.b_cnx.session_handle = session->handle;
- ev.u.b_cnx.cnx_handle = conn->handle;
- ev.u.b_cnx.is_leading = (conn->id == 0);
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_BIND_CNX, &ev)) < 0) {
- log_error("can't bind a cnx with id = %d (%d), retcode %d",
- conn->id, errno, ev.r.retcode);
- return rc;
- }
-
- log_debug(3, "binded iSCSI connection (handle 0x%p) to "
- "session (handle 0x%p)", (void*)conn->handle,
- (void*)session->handle);
- return 0;
-}
-
-int
-ksession_send_pdu_begin(iscsi_session_t *session, iscsi_conn_t *conn,
- int hdr_size, int data_size)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_SEND_PDU_BEGIN;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.sp_begin.cnx_handle = conn->handle;
- ev.u.sp_begin.hdr_size = hdr_size;
- ev.u.sp_begin.data_size = data_size;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_SEND_PDU_BEGIN, &ev)) < 0) {
- log_error("can't initiate send PDU operation for cnx with "
- "id = %d (%d), retcode %d",
- conn->id, errno, ev.r.retcode);
- return rc;
- }
-
- log_debug(3, "send PDU began for hdr %d bytes and data %d bytes",
- hdr_size, data_size);
- return 0;
-}
-
-int
-ksession_send_pdu_end(iscsi_session_t *session, iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_SEND_PDU_END;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.sp_end.cnx_handle = conn->handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_SEND_PDU_END, &ev)) < 0) {
- log_error("can't finish send PDU operation for cnx with "
- "id = %d (%d), retcode %d",
- conn->id, errno, ev.r.retcode);
- return rc;
- }
-
- log_debug(3, "send PDU finished for cnx (handle %p)",
- (void*)conn->handle);
- return 0;
-}
-
-int
-ksession_set_param(iscsi_conn_t *conn, iscsi_param_e param, uint32_t value)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_SET_PARAM;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.set_param.cnx_handle = (ulong_t)conn->handle;
- ev.u.set_param.param = param;
- ev.u.set_param.value = value;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_SET_PARAM, &ev)) < 0) {
- log_error("can't set operational parameter %d for cnx with "
- "id = %d (%d)", param, conn->id, errno);
- return rc;
- }
-
- log_debug(3, "set operational parameter %d to %u",
- param, value);
-
- return 0;
-}
-
-int
-ksession_stop_cnx(iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_STOP_CNX;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.stop_cnx.cnx_handle = conn->handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_STOP_CNX, &ev)) < 0) {
- log_error("can't stop connection 0x%p with "
- "id = %d (%d)", (void*)conn->handle,
- conn->id, errno);
- return rc;
- }
-
- log_debug(3, "connection 0x%p is stopped now",
- (void*)conn->handle);
- return 0;
-}
-
-int
-ksession_start_cnx(iscsi_conn_t *conn)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_START_CNX;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.start_cnx.cnx_handle = conn->handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_START_CNX, &ev)) < 0) {
- log_error("can't start connection 0x%p with "
- "id = %d (%d)", (void*)conn->handle,
- conn->id, errno);
- return rc;
- }
-
- log_debug(3, "connection 0x%p is operational now",
- (void*)conn->handle);
- return 0;
-}
-
-int
-ksession_recv_pdu_begin(iscsi_conn_t *conn, ulong_t recv_handle,
- ulong_t *pdu_handle, int *pdu_size)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_RECV_PDU_BEGIN;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.rp_begin.cpcnx_handle = (ulong_t)conn;
- ev.u.rp_begin.recv_handle = recv_handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_RECV_PDU_BEGIN, &ev)) < 0) {
- log_error("can't initiate recv PDU operation for cnx with "
- "id = %d (%d)", conn->id, errno);
- return rc;
- }
-
- *pdu_handle = ev.r.rp_begin.pdu_handle;
- *pdu_size = ev.r.rp_begin.pdu_size;
-
- log_debug(3, "recv PDU began, pdu handle 0x%p size %d",
- (void*)*pdu_handle, *pdu_size);
- return 0;
-}
-
-int
-ksession_recv_pdu_end(iscsi_conn_t *conn, ulong_t pdu_handle)
-{
- int rc;
- iscsi_uevent_t ev;
-
- memset(&ev, 0, sizeof(iscsi_uevent_t));
-
- ev.type = ISCSI_UEVENT_RECV_PDU_END;
- ev.provider_id = 0; /* FIXME: hardcoded */
- ev.u.rp_end.cpcnx_handle = (ulong_t)conn;
- ev.u.rp_end.pdu_handle = pdu_handle;
-
- if ((rc = ioctl(ctrl_fd, ISCSI_UEVENT_RECV_PDU_END, &ev)) < 0) {
- log_error("can't finish recv PDU operation for cnx with "
- "id = %d (%d)", conn->id, errno);
- return rc;
- }
-
- log_debug(3, "recv PDU finished for pdu handle 0x%p",
- (void*)pdu_handle);
- return 0;
-}
-
-int
-ctldev_handle(int fd)
-{
- int rc;
- iscsi_uevent_t ev;
- struct qelem *item;
- iscsi_session_t *session = NULL;
- iscsi_conn_t *conn = NULL;
-
- if ((rc = ioctl(fd, ISCSI_UEVENT_RECV_REQ, &ev)) < 0) {
- log_error("can't fetch recv event information "
- "(%d), retcode %d", errno, rc);
- return rc;
- }
-
- /* verify connection */
- item = provider[0].sessions.q_forw;
- while (item != &provider[0].sessions) {
- int i;
- session = (iscsi_session_t *)item;
- for (i=0; i<ISCSI_CNX_MAX; i++) {
- if (&session->cnx[i] == (iscsi_conn_t*)
- ev.r.recv_req.cnx_handle) {
- conn = &session->cnx[i];
- break;
- }
- }
- item = item->q_forw;
- }
-
- if (ev.type == ISCSI_KEVENT_RECV_PDU) {
- if (conn == NULL) {
- log_error("could not verify connection 0x%p for "
- "event RECV_PDU", conn);
- return -ENXIO;
- }
-
- /* produce an event, so session manager will handle */
- queue_produce(session->queue, EV_CNX_RECV_PDU, conn,
- sizeof(ulong_t), (void*)&ev.r.recv_req.recv_handle);
- actor_schedule(&session->mainloop);
-
- } else if (ev.type == ISCSI_KEVENT_CNX_ERROR) {
- if (conn == NULL) {
- log_error("could not verify connection 0x%p for "
- "event CNX_ERR", conn);
- return -ENXIO;
- }
-
- /* produce an event, so session manager will handle */
- queue_produce(session->queue, EV_CNX_ERROR, conn,
- sizeof(ulong_t), (void*)&ev.r.recv_req.recv_handle);
- actor_schedule(&session->mainloop);
-
- } else {
- log_error("unknown kernel event %d", ev.type);
- }
-
- return 0;
-}
-
-int ctldev_open(void)
-{
- FILE *f = NULL;
- char devname[256];
- char buf[256];
- int devn;
- int ctlfd;
-
- f = fopen("/proc/devices", "r");
- if (!f) {
- log_error("cannot open control path to the driver");
- 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, "iscsictl")) {
- break;
- }
- devn = 0;
- }
-
- fclose(f);
- if (!devn) {
- log_error("cannot find iscsictl in /proc/devices - "
- "make sure the module is loaded");
- return -1;
- }
-
- unlink(CTL_DEVICE);
- if (mknod(CTL_DEVICE, (S_IFCHR | 0600), (devn << 8))) {
- log_error("cannot create %s %d", CTL_DEVICE, errno);
- return -1;
- }
-
- ctlfd = open(CTL_DEVICE, O_RDWR);
- if (ctlfd < 0) {
- log_error("cannot open %s %d", CTL_DEVICE, errno);
- return -1;
- }
-
- log_debug(1, CTL_DEVICE " is opened!");
-
- return ctlfd;
-}
-
-void
-ctldev_close(int fd)
-{
- close(fd);
-}
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 9223be0..499ab19 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -35,9 +35,10 @@
#include "initiator.h"
#include "iscsiadm.h"
#include "log.h"
-#include "ipc.h"
+#include "mgmt_ipc.h"
#include "idbm.h"
+struct iscsi_ipc *ipc = NULL; /* dummy */
static char program_name[] = "iscsiadm";
char initiator_name[TARGET_NAME_MAXLEN];
@@ -220,19 +221,6 @@ iscsid_connect(void)
return fd;
}
-int
-ctldev_read(int ctrl_fd, char *data, int count)
-{
- return read(ctrl_fd, data, count);
-}
-
-int
-ctldev_writev(int ctrl_fd, enum iscsi_uevent_e type, struct iovec *iovp,
- int count)
-{
- return writev(ctrl_fd, iovp, count);
-}
-
static int
iscsid_request(int fd, iscsiadm_req_t *req)
{
@@ -292,7 +280,7 @@ session_login(int rid, node_rec_t *rec)
iscsiadm_rsp_t rsp;
memset(&req, 0, sizeof(req));
- req.command = IPC_SESSION_LOGIN;
+ req.command = MGMT_IPC_SESSION_LOGIN;
req.u.session.rid = rid;
return do_iscsid(&req, &rsp);
@@ -305,7 +293,7 @@ session_logout(int rid, node_rec_t *rec)
iscsiadm_rsp_t rsp;
memset(&req, 0, sizeof(req));
- req.command = IPC_SESSION_LOGOUT;
+ req.command = MGMT_IPC_SESSION_LOGOUT;
req.u.session.rid = rid;
return do_iscsid(&req, &rsp);
@@ -323,7 +311,7 @@ session_activelist(idbm_t *db)
iscsiadm_rsp_t rsp;
memset(&req, 0, sizeof(req));
- req.command = IPC_SESSION_ACTIVELIST;
+ req.command = MGMT_IPC_SESSION_ACTIVELIST;
rc = do_iscsid(&req, &rsp);
if (rc)
diff --git a/usr/iscsid.c b/usr/iscsid.c
index bb717e9..6ed3fa5 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -32,7 +32,8 @@
#include "iscsid.h"
#include "actor.h"
-#include "ipc.h"
+#include "mgmt_ipc.h"
+#include "iscsi_ipc.h"
#include "log.h"
#define POLL_CTRL 0
@@ -45,7 +46,7 @@ struct iscsi_daemon_config *dconfig = &daemon_config;
iscsi_provider_t provider[ISCSI_TRANSPORT_MAX];
static char program_name[] = "iscsid";
-int control_fd, ipc_fd;
+int control_fd, mgmt_ipc_fd;
static struct pollfd poll_array[POLL_MAX];
static struct option const long_options[] = {
@@ -86,7 +87,7 @@ void event_loop(void)
poll_array[POLL_CTRL].fd = control_fd;
poll_array[POLL_CTRL].events = POLLIN;
- poll_array[POLL_IPC].fd = ipc_fd;
+ poll_array[POLL_IPC].fd = mgmt_ipc_fd;
poll_array[POLL_IPC].events = POLLIN;
while (1) {
@@ -108,10 +109,10 @@ void event_loop(void)
log_debug(6, "detected poll event %d", res);
if (poll_array[POLL_CTRL].revents)
- ctldev_handle(control_fd);
+ ipc->ctldev_handle();
if (poll_array[POLL_IPC].revents)
- ipc_handle(ipc_fd);
+ mgmt_ipc_handle(mgmt_ipc_fd);
}
}
@@ -123,7 +124,7 @@ int trans_sync(void)
int i, found = 0;
struct iscsi_uevent ev;
- if (ktrans_list(control_fd, &ev))
+ if (ipc->trans_list(&ev))
return -1;
for (i = 0; i < ISCSI_TRANSPORT_MAX; i++) {
@@ -221,7 +222,7 @@ int main(int argc, char *argv[])
/* initialize logger */
log_init(program_name);
- if ((ipc_fd = ipc_listen()) < 0) {
+ if ((mgmt_ipc_fd = mgmt_ipc_listen()) < 0) {
exit(-1);
}
@@ -244,7 +245,7 @@ int main(int argc, char *argv[])
exit(0);
}
- if ((control_fd = ctldev_open()) < 0) {
+ if ((control_fd = ipc->ctldev_open()) < 0) {
exit(-1);
}
@@ -263,7 +264,7 @@ int main(int argc, char *argv[])
dup2(0, 2);
setsid();
} else {
- if ((control_fd = ctldev_open()) < 0) {
+ if ((control_fd = ipc->ctldev_open()) < 0) {
exit(-1);
}
}
diff --git a/usr/iscsid.h b/usr/iscsid.h
index b009a1d..8ce7202 100644
--- a/usr/iscsid.h
+++ b/usr/iscsid.h
@@ -36,13 +36,8 @@ typedef struct iscsi_pdu {
unsigned int datasize;
} iscsi_pdu_t;
-/* ctldev: Ioctl/IPC/NETLINK/etc */
-extern int ctldev_open(void);
-extern void ctldev_close(int fd);
-extern int ctldev_handle(int fd);
-extern int ctldev_writev(int fd, enum iscsi_uevent_e type, struct iovec *iov,
- int count);
-extern int ctldev_read(int fd, char *data, int count);
+/* IPC API */
+extern struct iscsi_ipc *ipc;
/* iscsid.c: daemon config */
struct iscsi_daemon_config {
diff --git a/usr/login.c b/usr/login.c
index 3b2f0a2..6adf419 100644
--- a/usr/login.c
+++ b/usr/login.c
@@ -1352,7 +1352,7 @@ iscsi_login_req(iscsi_session_t *session, iscsi_login_context_t *c)
}
/* send a PDU to the target */
- if (!iscsi_send_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE,
+ if (!iscsi_io_send_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE,
c->data, ISCSI_DIGEST_NONE, c->timeout)) {
/*
* FIXME: caller might want us to distinguish I/O
@@ -1383,7 +1383,7 @@ iscsi_login_rsp(iscsi_session_t *session, iscsi_login_context_t *c)
iscsi_conn_t *conn = &session->cnx[c->cid];
/* read the target's response into the same buffer */
- if (!iscsi_recv_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE, c->data,
+ if (!iscsi_io_recv_pdu(conn, &c->pdu, ISCSI_DIGEST_NONE, c->data,
c->max_data_length, ISCSI_DIGEST_NONE,
c->timeout)) {
/*
diff --git a/usr/ipc.c b/usr/mgmt_ipc.c
index 93473d1..af84822 100644
--- a/usr/ipc.c
+++ b/usr/mgmt_ipc.c
@@ -2,7 +2,7 @@
* iSCSI Administrator Utility Socket Interface
*
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
- * maintained by open-iscsi@@googlegroups.com
+ * maintained by open-iscsi@googlegroups.com
*
* Originally based on:
* (C) 2004 FUJITA Tomonori <tomof@acm.org>
@@ -32,11 +32,11 @@
#include "iscsid.h"
#include "idbm.h"
-#include "ipc.h"
+#include "mgmt_ipc.h"
#include "log.h"
int
-ipc_listen(void)
+mgmt_ipc_listen(void)
{
int fd, err;
struct sockaddr_un addr;
@@ -70,43 +70,43 @@ ipc_listen(void)
}
void
-ipc_close(int fd)
+mgmt_ipc_close(int fd)
{
}
-static ipc_err_e
-ipc_node_read(int rid, node_rec_t *rec)
+static mgmt_ipc_err_e
+mgmt_ipc_node_read(int rid, node_rec_t *rec)
{
idbm_t *db;
db = idbm_init(CONFIG_FILE);
if (!db) {
- return IPC_ERR_IDBM_FAILURE;
+ return MGMT_IPC_ERR_IDBM_FAILURE;
}
if (idbm_node_read(db, rid, rec)) {
log_error("node record [%06x] not found!", rid);
- return IPC_ERR_NOT_FOUND;
+ return MGMT_IPC_ERR_NOT_FOUND;
}
idbm_terminate(db);
return 0;
}
-static ipc_err_e
-ipc_session_login(queue_task_t *qtask, int rid)
+static mgmt_ipc_err_e
+mgmt_ipc_session_login(queue_task_t *qtask, int rid)
{
- ipc_err_e rc;
+ mgmt_ipc_err_e rc;
node_rec_t rec;
- if ((rc = ipc_node_read(rid, &rec)))
+ if ((rc = mgmt_ipc_node_read(rid, &rec)))
return rc;
return session_login_task(&rec, qtask);
}
-static ipc_err_e
-ipc_session_activelist(queue_task_t *qtask, iscsiadm_rsp_t *rsp)
+static mgmt_ipc_err_e
+mgmt_ipc_session_activelist(queue_task_t *qtask, iscsiadm_rsp_t *rsp)
{
iscsi_session_t *session;
struct qelem *item;
@@ -121,42 +121,42 @@ ipc_session_activelist(queue_task_t *qtask, iscsiadm_rsp_t *rsp)
item = item->q_forw;
}
- return IPC_OK;
+ return MGMT_IPC_OK;
}
-static ipc_err_e
-ipc_session_logout(queue_task_t *qtask, int rid)
+static mgmt_ipc_err_e
+mgmt_ipc_session_logout(queue_task_t *qtask, int rid)
{
- ipc_err_e rc;
+ mgmt_ipc_err_e rc;
node_rec_t rec;
iscsi_session_t *session;
- if ((rc = ipc_node_read(rid, &rec)))
+ if ((rc = mgmt_ipc_node_read(rid, &rec)))
return rc;
if (!(session = session_find_by_rec(&rec))) {
log_error("session with corresponding record [%06x] "
"not found!", rid);
- return IPC_ERR_NOT_FOUND;
+ return MGMT_IPC_ERR_NOT_FOUND;
}
return session_logout_task(session, qtask);
}
-static ipc_err_e
-ipc_conn_add(queue_task_t *qtask, int rid, int cid)
+static mgmt_ipc_err_e
+mgmt_ipc_conn_add(queue_task_t *qtask, int rid, int cid)
{
- return IPC_ERR;
+ return MGMT_IPC_ERR;
}
-static ipc_err_e
-ipc_conn_remove(queue_task_t *qtask, int rid, int cid)
+static mgmt_ipc_err_e
+mgmt_ipc_conn_remove(queue_task_t *qtask, int rid, int cid)
{
- return IPC_ERR;
+ return MGMT_IPC_ERR;
}
int
-ipc_handle(int accept_fd)
+mgmt_ipc_handle(int accept_fd)
{
struct sockaddr addr;
struct ucred cred;
@@ -178,12 +178,12 @@ ipc_handle(int accept_fd)
len = sizeof(cred);
if ((rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
(void *)&cred, &len)) < 0) {
- rsp.err = IPC_ERR_TCP_FAILURE;
+ rsp.err = MGMT_IPC_ERR_TCP_FAILURE;
goto err;
}
if (cred.uid || cred.gid) {
- rsp.err = IPC_ERR_TCP_FAILURE;
+ rsp.err = MGMT_IPC_ERR_TCP_FAILURE;
rc = -EPERM;
goto err;
}
@@ -199,29 +199,31 @@ ipc_handle(int accept_fd)
qtask = calloc(1, sizeof(queue_task_t));
if (!qtask) {
- rsp.err = IPC_ERR_NOMEM;
+ rsp.err = MGMT_IPC_ERR_NOMEM;
rc = -ENOMEM;
goto err;
}
memcpy(&qtask->u.login.req, &req, sizeof(iscsiadm_req_t));
- qtask->u.login.ipc_fd = fd;
+ qtask->u.login.mgmt_ipc_fd = fd;
switch(req.command) {
- case IPC_SESSION_LOGIN:
- rsp.err = ipc_session_login(qtask, req.u.session.rid);
+ case MGMT_IPC_SESSION_LOGIN:
+ rsp.err = mgmt_ipc_session_login(qtask, req.u.session.rid);
break;
- case IPC_SESSION_LOGOUT:
- rsp.err = ipc_session_logout(qtask, req.u.session.rid);
+ case MGMT_IPC_SESSION_LOGOUT:
+ rsp.err = mgmt_ipc_session_logout(qtask, req.u.session.rid);
break;
- case IPC_SESSION_ACTIVELIST:
- rsp.err = ipc_session_activelist(qtask, &rsp);
+ case MGMT_IPC_SESSION_ACTIVELIST:
+ rsp.err = mgmt_ipc_session_activelist(qtask, &rsp);
immrsp = 1;
break;
- case IPC_CONN_ADD:
- rsp.err = ipc_conn_add(qtask, req.u.conn.rid, req.u.conn.cid);
+ case MGMT_IPC_CONN_ADD:
+ rsp.err = mgmt_ipc_conn_add(qtask, req.u.conn.rid,
+ req.u.conn.cid);
break;
- case IPC_CONN_REMOVE:
- rsp.err = ipc_conn_remove(qtask,req.u.conn.rid,req.u.conn.cid);
+ case MGMT_IPC_CONN_REMOVE:
+ rsp.err = mgmt_ipc_conn_remove(qtask, req.u.conn.rid,
+ req.u.conn.cid);
break;
default:
log_error("unknown request: %s(%d) %u",
@@ -229,7 +231,7 @@ ipc_handle(int accept_fd)
break;
}
- if (rsp.err == IPC_OK && !immrsp)
+ if (rsp.err == MGMT_IPC_OK && !immrsp)
return 0;
err:
diff --git a/usr/ipc.h b/usr/mgmt_ipc.h
index 19c4901..7c2f7da 100644
--- a/usr/ipc.h
+++ b/usr/mgmt_ipc.h
@@ -1,8 +1,8 @@
/*
- * iSCSI Daemon/Admin IPC
+ * iSCSI Daemon/Admin Management IPC
*
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
- * maintained by open-iscsi@@googlegroups.com
+ * maintained by open-iscsi@googlegroups.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
@@ -16,37 +16,37 @@
*
* See the file COPYING included with this distribution for more details.
*/
-#ifndef IPC_H
-#define IPC_H
+#ifndef MGMT_IPC_H
+#define MGMT_IPC_H
#include "types.h"
#define ISCSIADM_NAMESPACE "ISCSIADM_ABSTRACT_NAMESPACE"
-typedef enum ipc_err {
- IPC_OK = 0,
- IPC_ERR = 1,
- IPC_ERR_NOT_FOUND = 2,
- IPC_ERR_NOMEM = 3,
- IPC_ERR_TCP_FAILURE = 4,
- IPC_ERR_LOGIN_FAILURE = 5,
- IPC_ERR_IDBM_FAILURE = 6,
- IPC_ERR_INVAL = 7,
- IPC_ERR_TCP_TIMEOUT = 8,
- IPC_ERR_INTERNAL = 9,
- IPC_ERR_LOGOUT_FAILURE = 10,
- IPC_ERR_PDU_TIMEOUT = 11,
- IPC_ERR_TRANS_NOT_FOUND = 12,
-} ipc_err_e;
+typedef enum mgmt_ipc_err {
+ MGMT_IPC_OK = 0,
+ MGMT_IPC_ERR = 1,
+ MGMT_IPC_ERR_NOT_FOUND = 2,
+ MGMT_IPC_ERR_NOMEM = 3,
+ MGMT_IPC_ERR_TCP_FAILURE = 4,
+ MGMT_IPC_ERR_LOGIN_FAILURE = 5,
+ MGMT_IPC_ERR_IDBM_FAILURE = 6,
+ MGMT_IPC_ERR_INVAL = 7,
+ MGMT_IPC_ERR_TCP_TIMEOUT = 8,
+ MGMT_IPC_ERR_INTERNAL = 9,
+ MGMT_IPC_ERR_LOGOUT_FAILURE = 10,
+ MGMT_IPC_ERR_PDU_TIMEOUT = 11,
+ MGMT_IPC_ERR_TRANS_NOT_FOUND = 12,
+} mgmt_ipc_err_e;
typedef enum iscsiadm_cmd {
- IPC_UNKNOWN = 0,
- IPC_SESSION_LOGIN = 1,
- IPC_SESSION_LOGOUT = 2,
- IPC_SESSION_ACTIVELIST = 3,
- IPC_SESSION_ACTIVESTAT = 4,
- IPC_CONN_ADD = 5,
- IPC_CONN_REMOVE = 6,
+ MGMT_IPC_UNKNOWN = 0,
+ MGMT_IPC_SESSION_LOGIN = 1,
+ MGMT_IPC_SESSION_LOGOUT = 2,
+ MGMT_IPC_SESSION_ACTIVELIST = 3,
+ MGMT_IPC_SESSION_ACTIVESTAT = 4,
+ MGMT_IPC_CONN_ADD = 5,
+ MGMT_IPC_CONN_REMOVE = 6,
} iscsiadm_cmd_e;
/* IPC Request */
@@ -68,20 +68,20 @@ typedef struct iscsiadm_req {
/* IPC Response */
typedef struct iscsiadm_rsp {
iscsiadm_cmd_e command;
- ipc_err_e err;
+ mgmt_ipc_err_e err;
union {
struct msg_activelist {
-#define IPC_ACTIVELIST_MAX 64
- int sids[IPC_ACTIVELIST_MAX];
- int rids[IPC_ACTIVELIST_MAX];
+#define MGMT_IPC_ACTIVELIST_MAX 64
+ int sids[MGMT_IPC_ACTIVELIST_MAX];
+ int rids[MGMT_IPC_ACTIVELIST_MAX];
int cnt;
} activelist;
} u;
} iscsiadm_rsp_t;
-int ipc_handle(int accept_fd);
-int ipc_listen(void);
-void ipc_close(int fd);
+int mgmt_ipc_handle(int accept_fd);
+int mgmt_ipc_listen(void);
+void mgmt_ipc_close(int fd);
-#endif /* IPC_H */
+#endif /* MGMT_IPC_H */
diff --git a/usr/netlink.c b/usr/netlink.c
index 004fde7..0598240 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -31,7 +31,9 @@
#include "iscsi_ifev.h"
#include "iscsid.h"
#include "log.h"
+#include "iscsi_ipc.h"
+static int ctrl_fd;
static struct sockaddr_nl src_addr, dest_addr;
static void *xmitbuf = NULL;
static int xmitlen = 0;
@@ -41,6 +43,8 @@ static void *nlm_sendbuf;
static void *nlm_recvbuf;
static void *pdu_sendbuf;
+static int ctldev_handle(void);
+
#define NLM_BUF_DEFAULT_MAX \
(NLMSG_SPACE(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH + \
sizeof(struct iscsi_hdr)))
@@ -48,23 +52,27 @@ static void *pdu_sendbuf;
#define PDU_SENDBUF_DEFAULT_MAX \
(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH + sizeof(struct iscsi_hdr))
-int
-ctldev_read(int ctrl_fd, char *data, int count)
+static int
+kread(char *data, int count)
{
+ log_debug(7, "in %s", __FUNCTION__);
+
memcpy(data, recvbuf + recvlen, count);
recvlen += count;
return count;
}
static int
-nl_read(int ctrl_fd, struct nlmsghdr *nl, int flags)
+nl_read(int ctrl_fd, char *data, int size, int flags)
{
int rc;
struct iovec iov;
struct msghdr msg;
- iov.iov_base = nl;
- iov.iov_len = sizeof(*nl);
+ log_debug(7, "in %s", __FUNCTION__);
+
+ iov.iov_base = data;
+ iov.iov_len = size;
memset(&msg, 0, sizeof(msg));
msg.msg_name= (void*)&src_addr;
@@ -84,6 +92,8 @@ nlpayload_read(int ctrl_fd, char *data, int count, int flags)
struct iovec iov;
struct msghdr msg;
+ log_debug(7, "in %s", __FUNCTION__);
+
iov.iov_base = nlm_recvbuf;
iov.iov_len = NLMSG_SPACE(count);
memset(iov.iov_base, 0, iov.iov_len);
@@ -126,9 +136,8 @@ nlpayload_read(int ctrl_fd, char *data, int count, int flags)
return rc;
}
-int
-ctldev_writev(int ctrl_fd, enum iscsi_uevent_e type, struct iovec *iovp,
- int count)
+static int
+kwritev(enum iscsi_uevent_e type, struct iovec *iovp, int count)
{
int i, rc;
struct nlmsghdr *nlh;
@@ -136,6 +145,8 @@ ctldev_writev(int ctrl_fd, enum iscsi_uevent_e type, struct iovec *iovp,
struct iovec iov;
int datalen = 0;
+ log_debug(7, "in %s", __FUNCTION__);
+
for (i = 0; i < count; i++) {
datalen += iovp[i].iov_len;
}
@@ -209,7 +220,7 @@ ctldev_writev(int ctrl_fd, enum iscsi_uevent_e type, struct iovec *iovp,
}
/*
- * __ksession_call() should never block. Therefore
+ * __kipc_call() should never block. Therefore
* Netlink's xmit logic is serialized. This means we do not allocate on
* xmit path. Instead we reuse nlm_sendbuf buffer.
*
@@ -231,17 +242,19 @@ ctldev_writev(int ctrl_fd, enum iscsi_uevent_e type, struct iovec *iovp,
* cleanup. (Dima)
*/
static int
-__ksession_call(int ctrl_fd, void *iov_base, int iov_len)
+__kipc_call(void *iov_base, int iov_len)
{
int rc;
struct iovec iov;
struct iscsi_uevent *ev = iov_base;
enum iscsi_uevent_e type = ev->type;
+ log_debug(7, "in %s", __FUNCTION__);
+
iov.iov_base = iov_base;
iov.iov_len = iov_len;
- rc = ctldev_writev(ctrl_fd, type, &iov, 1);
+ rc = kwritev(type, &iov, 1);
do {
if ((rc = nlpayload_read(ctrl_fd, (void*)ev,
@@ -265,7 +278,7 @@ __ksession_call(int ctrl_fd, void *iov_base, int iov_len)
* - CNX_ERROR
* - RECV_PDU
*/
- ctldev_handle(ctrl_fd);
+ ctldev_handle();
} else {
if ((rc = nlpayload_read(ctrl_fd, (void*)ev,
sizeof(*ev), 0)) < 0) {
@@ -278,149 +291,141 @@ __ksession_call(int ctrl_fd, void *iov_base, int iov_len)
return rc;
}
-int
-ksession_create(int ctrl_fd, iscsi_session_t *session)
+static int
+kcreate_session(uint64_t transport_handle, ulong_t cp_snx,
+ uint32_t initial_cmdsn, ulong_t *out_handle, int *out_sid)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_CREATE_SESSION;
- ev.transport_handle = session->transport_handle;
- ev.u.c_session.session_handle = (ulong_t)session;
- ev.u.c_session.initial_cmdsn = session->nrec.session.initial_cmdsn;
+ ev.transport_handle = transport_handle;
+ ev.u.c_session.session_handle = cp_snx;
+ ev.u.c_session.initial_cmdsn = initial_cmdsn;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't create session with id = %d (%d)",
- session->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
if (!ev.r.c_session_ret.handle || ev.r.c_session_ret.sid < 0)
return -EIO;
- session->handle = ev.r.c_session_ret.handle;
- session->id = ev.r.c_session_ret.sid;
- log_debug(3, "created new iSCSI session, handle 0x%p",
- (void*)session->handle);
+ *out_handle = ev.r.c_session_ret.handle;
+ *out_sid = ev.r.c_session_ret.sid;
return 0;
}
-int
-ksession_destroy(int ctrl_fd, iscsi_session_t *session)
+static int
+kdestroy_session(uint64_t transport_handle, ulong_t dp_snx, int sid)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_DESTROY_SESSION;
- ev.transport_handle = session->transport_handle;
- ev.u.d_session.session_handle = session->handle;
- ev.u.d_session.sid = session->id;
+ ev.transport_handle = transport_handle;
+ ev.u.d_session.session_handle = dp_snx;
+ ev.u.d_session.sid = sid;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't destroy session with id = %d (%d)",
- session->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- log_warning("destroyed iSCSI session, handle 0x%p",
- (void*)session->handle);
-
return 0;
}
-int
-ksession_cnx_create(int ctrl_fd, iscsi_session_t *session, iscsi_conn_t *conn)
+static int
+kcreate_cnx(uint64_t transport_handle, ulong_t dp_snx, ulong_t cp_cnx,
+ uint32_t sid, uint32_t cid, ulong_t *out_handle)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_CREATE_CNX;
- ev.transport_handle = session->transport_handle;
- ev.u.c_cnx.session_handle = session->handle;
- ev.u.c_cnx.cnx_handle = (ulong_t)conn;
- ev.u.c_cnx.cid = conn->id;
- ev.u.c_cnx.sid = session->id;
-
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't create cnx with id = %d (%d)",
- conn->id, errno);
+ ev.transport_handle = transport_handle;
+ ev.u.c_cnx.session_handle = dp_snx;
+ ev.u.c_cnx.cnx_handle = cp_cnx;
+ ev.u.c_cnx.cid = cid;
+ ev.u.c_cnx.sid = sid;
+
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
if (!ev.r.handle)
return -EIO;
- conn->handle = ev.r.handle;
- log_debug(3, "created new iSCSI connection, handle 0x%p",
- (void*)conn->handle);
+ *out_handle = ev.r.handle;
return 0;
}
-int
-ksession_cnx_destroy(int ctrl_fd, iscsi_conn_t *conn)
+static int
+kdestroy_cnx(uint64_t transport_handle, ulong_t dp_cnx, int cid)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_DESTROY_CNX;
- ev.transport_handle = conn->session->transport_handle;
- ev.u.d_cnx.cnx_handle = conn->handle;
- ev.u.d_cnx.cid = conn->id;
+ ev.transport_handle = transport_handle;
+ ev.u.d_cnx.cnx_handle = dp_cnx;
+ ev.u.d_cnx.cid = cid;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't destroy cnx with id = %d (%d)",
- conn->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- log_warning("destroyed iSCSI connection, handle 0x%p",
- (void*)conn->handle);
return 0;
}
-int
-ksession_cnx_bind(int ctrl_fd, iscsi_session_t *session, iscsi_conn_t *conn)
+static int
+kbind_cnx(uint64_t transport_handle, ulong_t dp_snx, ulong_t dp_cnx,
+ uint32_t transport_fd, int is_leading, int *retcode)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_BIND_CNX;
- ev.transport_handle = session->transport_handle;
- ev.u.b_cnx.session_handle = session->handle;
- ev.u.b_cnx.cnx_handle = conn->handle;
- ev.u.b_cnx.transport_fd = conn->socket_fd;
- ev.u.b_cnx.is_leading = (conn->id == 0);
-
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't bind a cnx with id = %d (%d)",
- conn->id, errno);
+ ev.transport_handle = transport_handle;
+ ev.u.b_cnx.session_handle = dp_snx;
+ ev.u.b_cnx.cnx_handle = dp_cnx;
+ ev.u.b_cnx.transport_fd = transport_fd;
+ ev.u.b_cnx.is_leading = is_leading;
+
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- if (!ev.r.retcode) {
- log_debug(3, "bound iSCSI connection (handle 0x%p) to "
- "session (handle 0x%p)", (void*)conn->handle,
- (void*)session->handle);
- } else {
- log_error("can't bind a cnx with id = %d, retcode %d",
- conn->id, ev.r.retcode);
- }
- return ev.r.retcode;
+
+ *retcode = ev.r.retcode;
+
+ return 0;
}
-void ksession_send_pdu_begin(int ctrl_fd, iscsi_session_t *session,
- iscsi_conn_t *conn, int hdr_size, int data_size)
+static void
+ksend_pdu_begin(uint64_t transport_handle, ulong_t dp_cnx,
+ int hdr_size, int data_size)
{
struct iscsi_uevent *ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
if (xmitbuf) {
log_error("send's begin state machine bug?");
exit(-EIO);
@@ -432,8 +437,8 @@ void ksession_send_pdu_begin(int ctrl_fd, iscsi_session_t *session,
ev = xmitbuf;
memset(ev, 0, sizeof(*ev));
ev->type = ISCSI_UEVENT_SEND_PDU;
- ev->transport_handle = session->transport_handle;
- ev->u.send_pdu.cnx_handle = conn->handle;
+ ev->transport_handle = transport_handle;
+ ev->u.send_pdu.cnx_handle = dp_cnx;
ev->u.send_pdu.hdr_size = hdr_size;
ev->u.send_pdu.data_size = data_size;
@@ -441,19 +446,21 @@ void ksession_send_pdu_begin(int ctrl_fd, iscsi_session_t *session,
hdr_size, data_size);
}
-int
-ksession_send_pdu_end(int ctrl_fd, iscsi_session_t *session, iscsi_conn_t *conn)
+static int
+ksend_pdu_end(uint64_t transport_handle, ulong_t dp_cnx, int *retcode)
{
int rc;
struct iscsi_uevent *ev;
struct iovec iov;
+ log_debug(7, "in %s", __FUNCTION__);
+
if (!xmitbuf) {
log_error("send's end state machine bug?");
exit(-EIO);
}
ev = xmitbuf;
- if (ev->u.send_pdu.cnx_handle != conn->handle) {
+ if (ev->u.send_pdu.cnx_handle != dp_cnx) {
log_error("send's end state machine corruption?");
exit(-EIO);
}
@@ -461,119 +468,104 @@ ksession_send_pdu_end(int ctrl_fd, iscsi_session_t *session, iscsi_conn_t *conn)
iov.iov_base = xmitbuf;
iov.iov_len = xmitlen;
- if ((rc = __ksession_call(ctrl_fd, xmitbuf, xmitlen)) < 0)
+ if ((rc = __kipc_call(xmitbuf, xmitlen)) < 0)
goto err;
- if (ev->r.retcode)
+ if (ev->r.retcode) {
+ *retcode = ev->r.retcode;
goto err;
+ }
if (ev->type != ISCSI_UEVENT_SEND_PDU) {
log_error("bad event: bug on send_pdu_end?");
exit(-EIO);
}
- log_debug(3, "send PDU finished for cnx (handle %p)",
- (void*)conn->handle);
+ log_debug(3, "send PDU finished for cnx (handle %p)", (void*)dp_cnx);
xmitbuf = NULL;
return 0;
err:
- log_error("can't finish send PDU operation for cnx with "
- "id = %d (%d), retcode %d",
- conn->id, errno, ev->r.retcode);
xmitbuf = NULL;
xmitlen = 0;
return rc;
}
-int
-ksession_set_param(int ctrl_fd, iscsi_conn_t *conn, enum iscsi_param param,
- uint32_t value)
+static int
+kset_param(uint64_t transport_handle, ulong_t dp_cnx,
+ enum iscsi_param param, uint32_t value, int *retcode)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_SET_PARAM;
- ev.transport_handle = conn->session->transport_handle;
- ev.u.set_param.cnx_handle = (ulong_t)conn->handle;
+ ev.transport_handle = transport_handle;
+ ev.u.set_param.cnx_handle = dp_cnx;
ev.u.set_param.param = param;
ev.u.set_param.value = value;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't set operational parameter %d for cnx with "
- "id = %d (%d)", param, conn->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- if (!ev.r.retcode) {
- log_debug(3, "set operational parameter %d to %u",
- param, value);
- } else {
- log_error("can't set operational parameter %d for cnx with "
- "id = %d, retcode %d", param, conn->id, ev.r.retcode);
- }
- return ev.r.retcode;
+ *retcode = ev.r.retcode;
+
+ return 0;
}
-int
-ksession_stop_cnx(int ctrl_fd, iscsi_conn_t *conn, int flag)
+static int
+kstop_cnx(uint64_t transport_handle, ulong_t dp_cnx, int flag)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_STOP_CNX;
- ev.transport_handle = conn->session->transport_handle;
- ev.u.stop_cnx.cnx_handle = conn->handle;
+ ev.transport_handle = transport_handle;
+ ev.u.stop_cnx.cnx_handle = dp_cnx;
ev.u.stop_cnx.flag = flag;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't stop connection 0x%p with "
- "id = %d (%d)", (void*)conn->handle,
- conn->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- log_debug(3, "connection 0x%p is stopped now",
- (void*)conn->handle);
return 0;
}
-int
-ksession_start_cnx(int ctrl_fd, iscsi_conn_t *conn)
+static int
+kstart_cnx(uint64_t transport_handle, ulong_t dp_cnx, int *retcode)
{
int rc;
struct iscsi_uevent ev;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(&ev, 0, sizeof(struct iscsi_uevent));
ev.type = ISCSI_UEVENT_START_CNX;
- ev.transport_handle = conn->session->transport_handle;
- ev.u.start_cnx.cnx_handle = conn->handle;
+ ev.transport_handle = transport_handle;
+ ev.u.start_cnx.cnx_handle = dp_cnx;
- if ((rc = __ksession_call(ctrl_fd, &ev, sizeof(ev))) < 0) {
- log_error("can't start connection 0x%p with "
- "id = %d (%d)", (void*)conn->handle,
- conn->id, errno);
+ if ((rc = __kipc_call(&ev, sizeof(ev))) < 0) {
return rc;
}
- if (!ev.r.retcode) {
- log_debug(3, "connection 0x%p is operational now",
- (void*)conn->handle);
- } else {
- log_error("can't start connection 0x%p with "
- "id = %d, retcode %d", (void*)conn->handle,
- conn->id, ev.r.retcode);
- }
- return ev.r.retcode;
+
+ *retcode = ev.r.retcode;
+ return 0;
}
-int
-ksession_recv_pdu_begin(int ctrl_fd, iscsi_conn_t *conn, ulong_t recv_handle,
- ulong_t *pdu_handle, int *pdu_size)
+static int
+krecv_pdu_begin(uint64_t transport_handle, ulong_t dp_cnx,
+ ulong_t recv_handle, ulong_t *pdu_handle, int *pdu_size)
{
+ log_debug(7, "in %s", __FUNCTION__);
+
if (recvbuf) {
log_error("recv's begin state machine bug?");
return -EIO;
@@ -588,9 +580,11 @@ ksession_recv_pdu_begin(int ctrl_fd, iscsi_conn_t *conn, ulong_t recv_handle,
return 0;
}
-int
-ksession_recv_pdu_end(int ctrl_fd, iscsi_conn_t *conn, ulong_t pdu_handle)
+static int
+krecv_pdu_end(uint64_t transport_handle, ulong_t cp_cnx, ulong_t pdu_handle)
{
+ log_debug(7, "in %s", __FUNCTION__);
+
if (!recvbuf) {
log_error("recv's end state machine bug?");
return -EIO;
@@ -599,30 +593,31 @@ ksession_recv_pdu_end(int ctrl_fd, iscsi_conn_t *conn, ulong_t pdu_handle)
log_debug(3, "recv PDU finished for pdu handle 0x%p",
(void*)pdu_handle);
- free((void*)pdu_handle);
+ recvpool_put((void*)cp_cnx, (void*)pdu_handle);
recvbuf = NULL;
return 0;
}
-int
-ktrans_list(int ctrl_fd, struct iscsi_uevent *ev)
+static int
+ktrans_list(struct iscsi_uevent *ev)
{
int rc;
+ log_debug(7, "in %s", __FUNCTION__);
+
memset(ev, 0, sizeof(struct iscsi_uevent));
ev->type = ISCSI_UEVENT_TRANS_LIST;
- if ((rc = __ksession_call(ctrl_fd, ev, sizeof(*ev))) < 0) {
- log_error("can't retreive transport list (%d)", errno);
+ if ((rc = __kipc_call(ev, sizeof(*ev))) < 0) {
return rc;
}
return 0;
}
-int
-ctldev_handle(int ctrl_fd)
+static int
+ctldev_handle()
{
int rc;
struct iscsi_uevent *ev;
@@ -630,30 +625,19 @@ ctldev_handle(int ctrl_fd)
iscsi_session_t *session = NULL;
iscsi_conn_t *conn = NULL;
ulong_t recv_handle;
- struct nlmsghdr nlh;
+ char nlm_ev[NLMSG_SPACE(sizeof(struct iscsi_uevent))];
+ struct nlmsghdr *nlh;
int ev_size;
- if ((rc = nl_read(ctrl_fd, &nlh, MSG_PEEK)) < 0) {
- log_error("can not read nlmsghdr, error %d", rc);
- return rc;
- }
+ log_debug(7, "in %s", __FUNCTION__);
- ev_size = nlh.nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
- recv_handle = (ulong_t)calloc(1, ev_size);
- if (!recv_handle) {
- log_error("can not allocate memory for receive handle");
- return -ENOMEM;
- }
-
- log_debug(6, "message real length is %d bytes, recv_handle %p",
- nlh.nlmsg_len, (void*)recv_handle);
-
- if ((rc = nlpayload_read(ctrl_fd, (void*)recv_handle,
- ev_size, 0)) < 0) {
- log_error("can not read from NL socket, error %d", rc);
+ if ((rc = nl_read(ctrl_fd, nlm_ev,
+ NLMSG_SPACE(sizeof(struct iscsi_uevent)), MSG_PEEK)) < 0) {
+ log_error("can not read nlm_ev, error %d", rc);
return rc;
}
- ev = (struct iscsi_uevent *)recv_handle;
+ nlh = (struct nlmsghdr *)nlm_ev;
+ ev = (struct iscsi_uevent *)NLMSG_DATA(nlm_ev);
/* verify connection */
item = provider[0].sessions.q_forw;
@@ -661,8 +645,13 @@ ctldev_handle(int ctrl_fd)
int i;
session = (iscsi_session_t *)item;
for (i=0; i<ISCSI_CNX_MAX; i++) {
- if (&session->cnx[i] == (iscsi_conn_t*)
- iscsi_ptr(ev->r.recv_req.cnx_handle) ||
+ if (ev->type == ISCSI_KEVENT_RECV_PDU &&
+ &session->cnx[i] == (iscsi_conn_t*)
+ iscsi_ptr(ev->r.recv_req.cnx_handle)) {
+ conn = &session->cnx[i];
+ break;
+ }
+ if (ev->type == ISCSI_KEVENT_CNX_ERROR &&
&session->cnx[i] == (iscsi_conn_t*)
iscsi_ptr(ev->r.cnxerror.cnx_handle)) {
conn = &session->cnx[i];
@@ -671,32 +660,41 @@ ctldev_handle(int ctrl_fd)
}
item = item->q_forw;
}
+ if (conn == NULL) {
+ log_error("could not verify connection 0x%p ", conn);
+ return -ENXIO;
+ }
- if (ev->type == ISCSI_KEVENT_RECV_PDU) {
- if (conn == NULL) {
- log_error("could not verify connection 0x%p for "
- "event RECV_PDU", conn);
- return -ENXIO;
- }
+ ev_size = nlh->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
+ recv_handle = (ulong_t)recvpool_get(conn, ev_size);
+ if (!recv_handle) {
+ log_error("can not allocate memory for receive handle");
+ return -ENOMEM;
+ }
+
+ log_debug(6, "message real length is %d bytes, recv_handle %p",
+ nlh->nlmsg_len, (void*)recv_handle);
+
+ if ((rc = nlpayload_read(ctrl_fd, (void*)recv_handle,
+ ev_size, 0)) < 0) {
+ recvpool_put(conn, (void*)recv_handle);
+ log_error("can not read from NL socket, error %d", rc);
+ return rc;
+ }
+ if (ev->type == ISCSI_KEVENT_RECV_PDU) {
/* produce an event, so session manager will handle */
queue_produce(session->queue, EV_CNX_RECV_PDU, conn,
sizeof(ulong_t), &recv_handle);
actor_schedule(&session->mainloop);
-
} else if (ev->type == ISCSI_KEVENT_CNX_ERROR) {
- if (conn == NULL) {
- log_error("could not verify connection 0x%p for "
- "event CNX_ERR", conn);
- return -ENXIO;
- }
-
/* produce an event, so session manager will handle */
queue_produce(session->queue, EV_CNX_ERROR, conn,
sizeof(ulong_t), (void*)&ev->r.cnxerror.error);
actor_schedule(&session->mainloop);
-
+ recvpool_put(conn, (void*)recv_handle);
} else {
+ recvpool_put(conn, (void*)recv_handle);
log_error("unknown kernel event %d", ev->type);
return -EEXIST;
}
@@ -704,9 +702,10 @@ ctldev_handle(int ctrl_fd)
return 0;
}
-int ctldev_open(void)
+static int
+ctldev_open(void)
{
- int ctrl_fd;
+ log_debug(7, "in %s", __FUNCTION__);
nlm_sendbuf = calloc(1, NLM_BUF_DEFAULT_MAX);
if (!nlm_sendbuf) {
@@ -754,11 +753,38 @@ int ctldev_open(void)
return ctrl_fd;
}
-void
-ctldev_close(int ctrl_fd)
+static void
+ctldev_close(void)
{
+ log_debug(7, "in %s", __FUNCTION__);
+
free(pdu_sendbuf);
free(nlm_recvbuf);
free(nlm_sendbuf);
close(ctrl_fd);
}
+
+struct iscsi_ipc nl_ipc = {
+ .name = "Open-iSCSI Kernel IPC/NETLINK v.1",
+ .ctldev_bufmax = NLM_BUF_DEFAULT_MAX,
+ .ctldev_open = ctldev_open,
+ .ctldev_close = ctldev_close,
+ .ctldev_handle = ctldev_handle,
+ .trans_list = ktrans_list,
+ .create_session = kcreate_session,
+ .destroy_session = kdestroy_session,
+ .create_cnx = kcreate_cnx,
+ .destroy_cnx = kdestroy_cnx,
+ .bind_cnx = kbind_cnx,
+ .set_param = kset_param,
+ .get_param = NULL,
+ .start_cnx = kstart_cnx,
+ .stop_cnx = kstop_cnx,
+ .writev = kwritev,
+ .send_pdu_begin = ksend_pdu_begin,
+ .send_pdu_end = ksend_pdu_end,
+ .read = kread,
+ .recv_pdu_begin = krecv_pdu_begin,
+ .recv_pdu_end = krecv_pdu_end,
+};
+struct iscsi_ipc *ipc = &nl_ipc;