2 * iSCSI Netlink/Linux Interface
4 * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
5 * Copyright (C) 2006 Mike Christie
6 * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
7 * maintained by open-iscsi@googlegroups.com
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * See the file COPYING included with this distribution for more details.
29 #include <asm/types.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <linux/netlink.h>
37 #include "iscsi_ipc.h"
38 #include "initiator.h"
39 #include "iscsi_sysfs.h"
40 #include "transport.h"
43 static struct sockaddr_nl src_addr
, dest_addr
;
44 static void *xmitbuf
= NULL
;
45 static int xmitlen
= 0;
46 static void *recvbuf
= NULL
;
47 static int recvlen
= 0;
48 static void *nlm_sendbuf
;
49 static void *nlm_recvbuf
;
50 static void *pdu_sendbuf
;
51 static void *setparam_buf
;
52 static struct iscsi_ipc_ev_clbk
*ipc_ev_clbk
;
54 static int ctldev_handle(void);
56 #define NLM_BUF_DEFAULT_MAX (NLMSG_SPACE(ISCSI_DEF_MAX_RECV_SEG_LEN + \
57 sizeof(struct iscsi_uevent) + \
58 sizeof(struct iscsi_hdr)))
60 #define PDU_SENDBUF_DEFAULT_MAX (ISCSI_DEF_MAX_RECV_SEG_LEN + \
61 sizeof(struct iscsi_uevent) + \
62 sizeof(struct iscsi_hdr))
64 #define NLM_SETPARAM_DEFAULT_MAX (NI_MAXHOST + 1 + sizeof(struct iscsi_uevent))
67 kread(char *data
, int count
)
69 log_debug(7, "in %s %u %u %p %p", __FUNCTION__
, recvlen
, count
,
72 memcpy(data
, recvbuf
+ recvlen
, count
);
78 nl_read(int ctrl_fd
, char *data
, int size
, int flags
)
84 log_debug(7, "in %s", __FUNCTION__
);
89 memset(&msg
, 0, sizeof(msg
));
90 msg
.msg_name
= (void*)&src_addr
;
91 msg
.msg_namelen
= sizeof(src_addr
);
95 rc
= recvmsg(ctrl_fd
, &msg
, flags
);
101 nlpayload_read(int ctrl_fd
, char *data
, int count
, int flags
)
107 log_debug(7, "in %s", __FUNCTION__
);
109 iov
.iov_base
= nlm_recvbuf
;
110 iov
.iov_len
= NLMSG_SPACE(count
);
112 if (iov
.iov_len
> NLM_BUF_DEFAULT_MAX
) {
113 log_error("Cannot read %lu bytes. nlm_recvbuf too small.",
117 memset(iov
.iov_base
, 0, iov
.iov_len
);
119 memset(&msg
, 0, sizeof(msg
));
120 msg
.msg_name
= (void*)&src_addr
;
121 msg
.msg_namelen
= sizeof(src_addr
);
126 * Netlink recvmsg call path:
128 * - transport api callback
129 * - iscsi_control_conn_error (should succeed)
130 * - iscsi_unicast_skb (must succeed)
131 * - netlink_unicast (must succeed)
132 * - netlink_data_ready (must succeed)
133 * - netlink_sendskb (must succeed)
134 * - netlink_recvmsg (must succeed)
135 * - sock_recvmsg (must succeed)
136 * - sys_recvmsg (must succeed)
137 * - sys_socketcall (must succeed)
138 * - syscall_call (must succeed)
140 * Note1: "must succeed" means succeed unless bug in daemon.
141 * It also means - no sleep and memory allocation on
144 * Note2: "should succeed" means will succeed in most of cases
145 * because of mempool preallocation.
147 * FIXME: if "Note2" than interface should generate iSCSI error
148 * level 0 on its own. Interface must always succeed on this.
150 rc
= recvmsg(ctrl_fd
, &msg
, flags
);
153 memcpy(data
, NLMSG_DATA(iov
.iov_base
), count
);
159 kwritev(enum iscsi_uevent_e type
, struct iovec
*iovp
, int count
)
162 struct nlmsghdr
*nlh
;
166 log_debug(7, "in %s", __FUNCTION__
);
168 for (i
= 0; i
< count
; i
++) {
169 datalen
+= iovp
[i
].iov_len
;
172 if (xmitbuf
&& type
!= ISCSI_UEVENT_SEND_PDU
) {
173 for (i
= 0; i
< count
; i
++) {
174 memcpy(xmitbuf
+ xmitlen
,
175 iovp
[i
].iov_base
, iovp
[i
].iov_len
);
176 xmitlen
+= iovp
[i
].iov_len
;
182 memset(nlh
, 0, NLMSG_SPACE(0));
185 for (i
= 1; i
< count
; i
++)
186 datalen
+= iovp
[i
].iov_len
;
188 nlh
->nlmsg_len
= NLMSG_ALIGN(datalen
);
189 nlh
->nlmsg_pid
= getpid();
190 nlh
->nlmsg_flags
= 0;
191 nlh
->nlmsg_type
= type
;
193 iovp
[0].iov_base
= (void *)nlh
;
194 iovp
[0].iov_len
= sizeof(*nlh
);
196 memset(&msg
, 0, sizeof(msg
));
197 msg
.msg_name
= (void*)&dest_addr
;
198 msg
.msg_namelen
= sizeof(dest_addr
);
200 msg
.msg_iovlen
= count
;
204 * Netlink down call path:
206 * - transport api call
207 * - iscsi_if_recv_msg (must succeed)
208 * - iscsi_if_rx (must succeed)
209 * - netlink_data_ready (must succeed)
210 * - netlink_sendskb (must succeed)
211 * - netlink_sendmsg (alloc_skb() might fail)
212 * - sock_sendmsg (must succeed)
213 * - sys_sendmsg (must succeed)
214 * - sys_socketcall (must succeed)
215 * - syscall_call (must succeed)
217 * Note1: "must succeed" means succeed unless bug in daemon.
218 * It also means - no sleep and memory allocation on
221 * Note2: netlink_sendmsg() might fail because of OOM. Since
222 * we are in user-space, we will sleep until we succeed.
225 rc
= sendmsg(ctrl_fd
, &msg
, 0);
227 log_debug(1, "sendmsg: alloc_skb() failed");
230 log_error("sendmsg: bug? ctrl_fd %d", ctrl_fd
);
239 * __kipc_call() should never block. Therefore
240 * Netlink's xmit logic is serialized. This means we do not allocate on
241 * xmit path. Instead we reuse nlm_sendbuf buffer.
243 * Transport must assure non-blocking operations for:
252 * Its OK to block for cleanup for short period of time in operatations for:
255 * - session_destroy()
257 * FIXME: interface needs to be extended to allow longer blocking on
261 __kipc_call(struct iovec
*iovp
, int count
)
264 struct iscsi_uevent
*ev
= iovp
[1].iov_base
;
265 enum iscsi_uevent_e type
= ev
->type
;
267 log_debug(7, "in %s", __FUNCTION__
);
269 rc
= kwritev(type
, iovp
, count
);
272 if ((rc
= nlpayload_read(ctrl_fd
, (void*)ev
,
273 sizeof(*ev
), MSG_PEEK
)) < 0) {
276 if (ev
->type
!= type
) {
277 log_debug(1, "expecting event %d, got %d, handling...",
279 if (ev
->type
== ISCSI_KEVENT_IF_ERROR
) {
280 if ((rc
= nlpayload_read(ctrl_fd
, (void*)ev
,
281 sizeof(*ev
), 0)) < 0) {
285 * iferror is u32, but the kernel returns
286 * negative errno values for errors.
290 if (iferr
== -ENOSYS
)
291 /* not fatal so let caller handle log */
292 log_debug(1, "Received iferror %d: %s.",
293 iferr
, strerror(-iferr
));
295 log_error("Received iferror %d: %s.",
296 iferr
, strerror(-iferr
));
298 log_error("Received iferror %d.",
303 * receive and queue async. event which as of
309 } else if (ev
->type
== ISCSI_UEVENT_GET_STATS
) {
310 /* kget_stats() will read */
313 if ((rc
= nlpayload_read(ctrl_fd
, (void*)ev
,
314 sizeof(*ev
), 0)) < 0) {
319 } while (ev
->type
!= type
);
325 ksendtargets(uint64_t transport_handle
, uint32_t host_no
, struct sockaddr
*addr
)
328 struct iscsi_uevent
*ev
;
331 log_debug(7, "in %s", __FUNCTION__
);
333 memset(setparam_buf
, 0, NLM_SETPARAM_DEFAULT_MAX
);
334 ev
= (struct iscsi_uevent
*)setparam_buf
;
335 ev
->type
= ISCSI_UEVENT_TGT_DSCVR
;
336 ev
->transport_handle
= transport_handle
;
337 ev
->u
.tgt_dscvr
.type
= ISCSI_TGT_DSCVR_SEND_TARGETS
;
338 ev
->u
.tgt_dscvr
.host_no
= host_no
;
340 if (addr
->sa_family
== PF_INET
)
341 addrlen
= sizeof(struct sockaddr_in
);
342 else if (addr
->sa_family
== PF_INET6
)
343 addrlen
= sizeof(struct sockaddr_in6
);
345 log_error("%s unknown addr family %d\n",
346 __FUNCTION__
, addr
->sa_family
);
349 memcpy(setparam_buf
+ sizeof(*ev
), addr
, addrlen
);
351 iov
[1].iov_base
= ev
;
352 iov
[1].iov_len
= sizeof(*ev
) + addrlen
;
353 rc
= __kipc_call(iov
, 2);
355 log_error("sendtargets failed rc%d\n", rc
);
362 kcreate_session(uint64_t transport_handle
, uint64_t ep_handle
,
363 uint32_t initial_cmdsn
, uint16_t cmds_max
, uint16_t qdepth
,
364 uint32_t *out_sid
, uint32_t *hostno
)
367 struct iscsi_uevent ev
;
370 log_debug(7, "in %s", __FUNCTION__
);
372 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
374 if (ep_handle
== 0) {
375 ev
.type
= ISCSI_UEVENT_CREATE_SESSION
;
376 ev
.transport_handle
= transport_handle
;
377 ev
.u
.c_session
.initial_cmdsn
= initial_cmdsn
;
378 ev
.u
.c_session
.cmds_max
= cmds_max
;
379 ev
.u
.c_session
.queue_depth
= qdepth
;
381 ev
.type
= ISCSI_UEVENT_CREATE_BOUND_SESSION
;
382 ev
.transport_handle
= transport_handle
;
383 ev
.u
.c_bound_session
.initial_cmdsn
= initial_cmdsn
;
384 ev
.u
.c_bound_session
.cmds_max
= cmds_max
;
385 ev
.u
.c_bound_session
.queue_depth
= qdepth
;
386 ev
.u
.c_bound_session
.ep_handle
= ep_handle
;
389 iov
[1].iov_base
= &ev
;
390 iov
[1].iov_len
= sizeof(ev
);
391 rc
= __kipc_call(iov
, 2);
395 *hostno
= ev
.r
.c_session_ret
.host_no
;
396 *out_sid
= ev
.r
.c_session_ret
.sid
;
402 kdestroy_session(uint64_t transport_handle
, uint32_t sid
)
405 struct iscsi_uevent ev
;
408 log_debug(7, "in %s", __FUNCTION__
);
410 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
412 ev
.type
= ISCSI_UEVENT_DESTROY_SESSION
;
413 ev
.transport_handle
= transport_handle
;
414 ev
.u
.d_session
.sid
= sid
;
416 iov
[1].iov_base
= &ev
;
417 iov
[1].iov_len
= sizeof(ev
);
418 rc
= __kipc_call(iov
, 2);
426 kunbind_session(uint64_t transport_handle
, uint32_t sid
)
429 struct iscsi_uevent ev
;
432 log_debug(7, "in %s", __FUNCTION__
);
434 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
436 ev
.type
= ISCSI_UEVENT_UNBIND_SESSION
;
437 ev
.transport_handle
= transport_handle
;
438 ev
.u
.d_session
.sid
= sid
;
440 iov
[1].iov_base
= &ev
;
441 iov
[1].iov_len
= sizeof(ev
);
442 rc
= __kipc_call(iov
, 2);
450 kcreate_conn(uint64_t transport_handle
, uint32_t sid
,
451 uint32_t cid
, uint32_t *out_cid
)
454 struct iscsi_uevent ev
;
457 log_debug(7, "in %s", __FUNCTION__
);
459 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
461 ev
.type
= ISCSI_UEVENT_CREATE_CONN
;
462 ev
.transport_handle
= transport_handle
;
463 ev
.u
.c_conn
.cid
= cid
;
464 ev
.u
.c_conn
.sid
= sid
;
466 iov
[1].iov_base
= &ev
;
467 iov
[1].iov_len
= sizeof(ev
);
468 rc
= __kipc_call(iov
, 2);
470 log_debug(7, "returned %d", rc
);
474 if ((int)ev
.r
.c_conn_ret
.cid
== -1)
477 *out_cid
= ev
.r
.c_conn_ret
.cid
;
482 kdestroy_conn(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
)
485 struct iscsi_uevent ev
;
488 log_debug(7, "in %s", __FUNCTION__
);
490 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
492 ev
.type
= ISCSI_UEVENT_DESTROY_CONN
;
493 ev
.transport_handle
= transport_handle
;
494 ev
.u
.d_conn
.sid
= sid
;
495 ev
.u
.d_conn
.cid
= cid
;
497 iov
[1].iov_base
= &ev
;
498 iov
[1].iov_len
= sizeof(ev
);
499 rc
= __kipc_call(iov
, 2);
507 kbind_conn(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
508 uint64_t transport_eph
, int is_leading
, int *retcode
)
511 struct iscsi_uevent ev
;
514 log_debug(7, "in %s", __FUNCTION__
);
516 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
518 ev
.type
= ISCSI_UEVENT_BIND_CONN
;
519 ev
.transport_handle
= transport_handle
;
520 ev
.u
.b_conn
.sid
= sid
;
521 ev
.u
.b_conn
.cid
= cid
;
522 ev
.u
.b_conn
.transport_eph
= transport_eph
;
523 ev
.u
.b_conn
.is_leading
= is_leading
;
525 iov
[1].iov_base
= &ev
;
526 iov
[1].iov_len
= sizeof(ev
);
527 rc
= __kipc_call(iov
, 2);
531 *retcode
= ev
.r
.retcode
;
537 ksend_pdu_begin(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
538 int hdr_size
, int data_size
)
540 struct iscsi_uevent
*ev
;
541 int total_xmitlen
= sizeof(*ev
) + hdr_size
+ data_size
;
543 log_debug(7, "in %s", __FUNCTION__
);
546 log_error("send's begin state machine bug?");
550 if (total_xmitlen
> PDU_SENDBUF_DEFAULT_MAX
) {
551 log_error("BUG: Cannot send %d bytes.", total_xmitlen
);
555 xmitbuf
= pdu_sendbuf
;
556 memset(xmitbuf
, 0, total_xmitlen
);
557 xmitlen
= sizeof(*ev
);
559 memset(ev
, 0, sizeof(*ev
));
560 ev
->type
= ISCSI_UEVENT_SEND_PDU
;
561 ev
->transport_handle
= transport_handle
;
562 ev
->u
.send_pdu
.sid
= sid
;
563 ev
->u
.send_pdu
.cid
= cid
;
564 ev
->u
.send_pdu
.hdr_size
= hdr_size
;
565 ev
->u
.send_pdu
.data_size
= data_size
;
567 log_debug(3, "send PDU began for hdr %d bytes and data %d bytes",
568 hdr_size
, data_size
);
572 ksend_pdu_end(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
576 struct iscsi_uevent
*ev
;
579 log_debug(7, "in %s", __FUNCTION__
);
582 log_error("send's end state machine bug?");
586 if (ev
->u
.send_pdu
.sid
!= sid
|| ev
->u
.send_pdu
.cid
!= cid
) {
587 log_error("send's end state machine corruption?");
591 iov
[1].iov_base
= xmitbuf
;
592 iov
[1].iov_len
= xmitlen
;
594 rc
= __kipc_call(iov
, 2);
598 *retcode
= ev
->r
.retcode
;
601 if (ev
->type
!= ISCSI_UEVENT_SEND_PDU
) {
602 log_error("bad event: bug on send_pdu_end?");
606 log_debug(3, "send PDU finished for conn %d:%d",
619 kset_host_param(uint64_t transport_handle
, uint32_t host_no
,
620 enum iscsi_host_param param
, void *value
, int type
)
622 struct iscsi_uevent
*ev
;
627 log_debug(7, "in %s", __FUNCTION__
);
629 memset(setparam_buf
, 0, NLM_SETPARAM_DEFAULT_MAX
);
630 ev
= (struct iscsi_uevent
*)setparam_buf
;
631 ev
->type
= ISCSI_UEVENT_SET_HOST_PARAM
;
632 ev
->transport_handle
= transport_handle
;
633 ev
->u
.set_host_param
.host_no
= host_no
;
634 ev
->u
.set_host_param
.param
= param
;
636 param_str
= setparam_buf
+ sizeof(*ev
);
639 sprintf(param_str
, "%d", *((int *)value
));
644 sprintf(param_str
, "%s", (char *)value
);
647 log_error("invalid type %d\n", type
);
650 ev
->u
.set_host_param
.len
= len
= strlen(param_str
) + 1;
652 iov
[1].iov_base
= ev
;
653 iov
[1].iov_len
= sizeof(*ev
) + len
;
654 rc
= __kipc_call(iov
, 2);
662 kset_param(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
663 enum iscsi_param param
, void *value
, int type
)
665 struct iscsi_uevent
*ev
;
670 log_debug(7, "in %s", __FUNCTION__
);
672 memset(setparam_buf
, 0, NLM_SETPARAM_DEFAULT_MAX
);
673 ev
= (struct iscsi_uevent
*)setparam_buf
;
674 ev
->type
= ISCSI_UEVENT_SET_PARAM
;
675 ev
->transport_handle
= transport_handle
;
676 ev
->u
.set_param
.sid
= sid
;
677 ev
->u
.set_param
.cid
= cid
;
678 ev
->u
.set_param
.param
= param
;
680 param_str
= setparam_buf
+ sizeof(*ev
);
683 sprintf(param_str
, "%d", *((int *)value
));
688 sprintf(param_str
, "%s", (char *)value
);
691 log_error("invalid type %d\n", type
);
694 ev
->u
.set_param
.len
= len
= strlen(param_str
) + 1;
696 iov
[1].iov_base
= ev
;
697 iov
[1].iov_len
= sizeof(*ev
) + len
;
698 rc
= __kipc_call(iov
, 2);
706 kstop_conn(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
, int flag
)
709 struct iscsi_uevent ev
;
712 log_debug(7, "in %s", __FUNCTION__
);
714 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
716 ev
.type
= ISCSI_UEVENT_STOP_CONN
;
717 ev
.transport_handle
= transport_handle
;
718 ev
.u
.stop_conn
.sid
= sid
;
719 ev
.u
.stop_conn
.cid
= cid
;
720 ev
.u
.stop_conn
.flag
= flag
;
722 iov
[1].iov_base
= &ev
;
723 iov
[1].iov_len
= sizeof(ev
);
724 rc
= __kipc_call(iov
, 2);
732 kstart_conn(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
736 struct iscsi_uevent ev
;
739 log_debug(7, "in %s", __FUNCTION__
);
741 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
743 ev
.type
= ISCSI_UEVENT_START_CONN
;
744 ev
.transport_handle
= transport_handle
;
745 ev
.u
.start_conn
.sid
= sid
;
746 ev
.u
.start_conn
.cid
= cid
;
748 iov
[1].iov_base
= &ev
;
749 iov
[1].iov_len
= sizeof(ev
);
750 rc
= __kipc_call(iov
, 2);
754 *retcode
= ev
.r
.retcode
;
759 krecv_pdu_begin(struct iscsi_conn
*conn
)
763 log_debug(7, "in %s", __FUNCTION__
);
766 log_error("recv's begin state machine bug?");
770 if (!conn
->recv_context
) {
771 rc
= ipc
->ctldev_handle();
773 /* event for some other conn */
776 /* fatal handling error or conn error */
779 * Session create/destroy event for another conn
781 if (!conn
->recv_context
)
785 recvbuf
= conn
->recv_context
->data
+ sizeof(struct iscsi_uevent
);
788 log_debug(3, "recv PDU began, pdu handle %p", recvbuf
);
793 krecv_pdu_end(struct iscsi_conn
*conn
)
795 log_debug(7, "in %s", __FUNCTION__
);
798 log_error("recv's end state machine bug?");
802 log_debug(3, "recv PDU finished for pdu handle 0x%p",
805 ipc_ev_clbk
->put_ev_context(conn
->recv_context
);
806 conn
->recv_context
= NULL
;
812 ktransport_ep_connect(iscsi_conn_t
*conn
, int non_blocking
)
815 struct iscsi_uevent
*ev
;
816 struct sockaddr
*dst_addr
= (struct sockaddr
*)&conn
->saddr
;
819 log_debug(7, "in %s", __FUNCTION__
);
821 memset(setparam_buf
, 0, NLM_SETPARAM_DEFAULT_MAX
);
822 ev
= (struct iscsi_uevent
*)setparam_buf
;
823 ev
->transport_handle
= conn
->session
->t
->handle
;
826 ev
->type
= ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST
;
827 ev
->u
.ep_connect_through_host
.non_blocking
= non_blocking
;
828 ev
->u
.ep_connect_through_host
.host_no
= conn
->session
->hostno
;
830 ev
->type
= ISCSI_UEVENT_TRANSPORT_EP_CONNECT
;
831 ev
->u
.ep_connect
.non_blocking
= non_blocking
;
834 if (dst_addr
->sa_family
== PF_INET
)
835 addrlen
= sizeof(struct sockaddr_in
);
836 else if (dst_addr
->sa_family
== PF_INET6
)
837 addrlen
= sizeof(struct sockaddr_in6
);
839 log_error("%s unknown addr family %d\n",
840 __FUNCTION__
, dst_addr
->sa_family
);
843 memcpy(setparam_buf
+ sizeof(*ev
), dst_addr
, addrlen
);
845 iov
[1].iov_base
= ev
;
846 iov
[1].iov_len
= sizeof(*ev
) + addrlen
;
847 rc
= __kipc_call(iov
, 2);
851 if (!ev
->r
.ep_connect_ret
.handle
)
854 conn
->transport_ep_handle
= ev
->r
.ep_connect_ret
.handle
;
856 log_debug(6, "%s got handle %llx",
857 __FUNCTION__
, (unsigned long long)conn
->transport_ep_handle
);
862 ktransport_ep_poll(iscsi_conn_t
*conn
, int timeout_ms
)
865 struct iscsi_uevent ev
;
868 log_debug(7, "in %s", __FUNCTION__
);
870 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
872 ev
.type
= ISCSI_UEVENT_TRANSPORT_EP_POLL
;
873 ev
.transport_handle
= conn
->session
->t
->handle
;
874 ev
.u
.ep_poll
.ep_handle
= conn
->transport_ep_handle
;
875 ev
.u
.ep_poll
.timeout_ms
= timeout_ms
;
877 iov
[1].iov_base
= &ev
;
878 iov
[1].iov_len
= sizeof(ev
);
879 rc
= __kipc_call(iov
, 2);
887 ktransport_ep_disconnect(iscsi_conn_t
*conn
)
890 struct iscsi_uevent ev
;
893 log_debug(7, "in %s", __FUNCTION__
);
895 if (conn
->transport_ep_handle
== -1)
898 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
900 ev
.type
= ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT
;
901 ev
.transport_handle
= conn
->session
->t
->handle
;
902 ev
.u
.ep_disconnect
.ep_handle
= conn
->transport_ep_handle
;
904 iov
[1].iov_base
= &ev
;
905 iov
[1].iov_len
= sizeof(ev
);
906 rc
= __kipc_call(iov
, 2);
908 log_error("connnection %d:%d transport disconnect failed for "
909 "ep %" PRIu64
" with error %d.", conn
->session
->id
,
910 conn
->id
, conn
->transport_ep_handle
, rc
);
912 conn
->transport_ep_handle
= -1;
916 kget_stats(uint64_t transport_handle
, uint32_t sid
, uint32_t cid
,
917 char *statsbuf
, int statsbuf_max
)
921 struct iscsi_uevent ev
;
922 char nlm_ev
[NLMSG_SPACE(sizeof(struct iscsi_uevent
))];
923 struct nlmsghdr
*nlh
;
926 log_debug(7, "in %s", __FUNCTION__
);
928 memset(&ev
, 0, sizeof(struct iscsi_uevent
));
930 ev
.type
= ISCSI_UEVENT_GET_STATS
;
931 ev
.transport_handle
= transport_handle
;
932 ev
.u
.get_stats
.sid
= sid
;
933 ev
.u
.get_stats
.cid
= cid
;
935 iov
[1].iov_base
= &ev
;
936 iov
[1].iov_len
= sizeof(ev
);
937 rc
= __kipc_call(iov
, 2);
941 if ((rc
= nl_read(ctrl_fd
, nlm_ev
,
942 NLMSG_SPACE(sizeof(struct iscsi_uevent
)), MSG_PEEK
)) < 0) {
943 log_error("can not read nlm_ev, error %d", rc
);
946 nlh
= (struct nlmsghdr
*)nlm_ev
;
947 ev_size
= nlh
->nlmsg_len
- NLMSG_ALIGN(sizeof(struct nlmsghdr
));
949 log_debug(6, "message real length is %d bytes", nlh
->nlmsg_len
);
951 if (ev_size
> statsbuf_max
) {
952 log_error("destanation buffer for statistics is "
953 "not big enough to fit %d bytes", statsbuf_max
);
954 ev_size
= statsbuf_max
;
957 if ((rc
= nlpayload_read(ctrl_fd
, (void*)statsbuf
, ev_size
, 0)) < 0) {
958 log_error("can not read from NL socket, error %d", rc
);
966 kset_net_config(uint64_t transport_handle
, uint32_t host_no
,
967 struct iovec
*iovs
, uint32_t param_count
)
969 struct iscsi_uevent ev
;
971 struct iovec
*iov
= iovs
+ 1;
973 log_debug(8, "in %s", __FUNCTION__
);
976 ev
.type
= ISCSI_UEVENT_SET_IFACE_PARAMS
;
977 ev
.transport_handle
= transport_handle
;
978 ev
.u
.set_iface_params
.host_no
= host_no
;
979 /* first two iovs for nlmsg hdr and ev */
980 ev
.u
.set_iface_params
.count
= param_count
- 2;
983 iov
->iov_len
= ev_len
;
984 rc
= __kipc_call(iovs
, param_count
);
991 static int krecv_conn_state(struct iscsi_conn
*conn
, int *state
)
995 rc
= ipc
->ctldev_handle();
997 /* event for some other conn */
1001 /* fatal handling error or conn error */
1004 *state
= *(enum iscsi_conn_state
*)conn
->recv_context
->data
;
1006 ipc_ev_clbk
->put_ev_context(conn
->recv_context
);
1007 conn
->recv_context
= NULL
;
1013 static void drop_data(struct nlmsghdr
*nlh
)
1017 ev_size
= nlh
->nlmsg_len
- NLMSG_ALIGN(sizeof(struct nlmsghdr
));
1018 nlpayload_read(ctrl_fd
, NULL
, ev_size
, 0);
1021 static int ctldev_handle(void)
1024 struct iscsi_uevent
*ev
;
1025 iscsi_session_t
*session
= NULL
;
1026 iscsi_conn_t
*conn
= NULL
;
1027 char nlm_ev
[NLMSG_SPACE(sizeof(struct iscsi_uevent
))];
1028 struct nlmsghdr
*nlh
;
1029 struct iscsi_ev_context
*ev_context
;
1030 uint32_t sid
= 0, cid
= 0, state
= 0;
1032 log_debug(7, "in %s", __FUNCTION__
);
1034 if ((rc
= nl_read(ctrl_fd
, nlm_ev
,
1035 NLMSG_SPACE(sizeof(struct iscsi_uevent
)), MSG_PEEK
)) < 0) {
1036 log_error("can not read nlm_ev, error %d", rc
);
1039 nlh
= (struct nlmsghdr
*)nlm_ev
;
1040 ev
= (struct iscsi_uevent
*)NLMSG_DATA(nlm_ev
);
1042 log_debug(7, "%s got event type %u\n", __FUNCTION__
, ev
->type
);
1043 /* drivers like qla4xxx can be inserted after iscsid is started */
1045 case ISCSI_KEVENT_CREATE_SESSION
:
1046 /* old kernels sent ISCSI_UEVENT_CREATE_SESSION on creation */
1047 case ISCSI_UEVENT_CREATE_SESSION
:
1049 if (ipc_ev_clbk
->create_session
)
1050 ipc_ev_clbk
->create_session(ev
->r
.c_session_ret
.host_no
,
1051 ev
->r
.c_session_ret
.sid
);
1053 case ISCSI_KEVENT_DESTROY_SESSION
:
1055 if (ipc_ev_clbk
->destroy_session
)
1056 ipc_ev_clbk
->destroy_session(ev
->r
.d_session
.host_no
,
1057 ev
->r
.d_session
.sid
);
1059 case ISCSI_KEVENT_RECV_PDU
:
1060 sid
= ev
->r
.recv_req
.sid
;
1061 cid
= ev
->r
.recv_req
.cid
;
1063 case ISCSI_KEVENT_CONN_ERROR
:
1064 sid
= ev
->r
.connerror
.sid
;
1065 cid
= ev
->r
.connerror
.cid
;
1067 case ISCSI_KEVENT_CONN_LOGIN_STATE
:
1068 sid
= ev
->r
.conn_login
.sid
;
1069 cid
= ev
->r
.conn_login
.cid
;
1070 state
= ev
->r
.conn_login
.state
;
1072 case ISCSI_KEVENT_UNBIND_SESSION
:
1073 sid
= ev
->r
.unbind_session
.sid
;
1074 /* session wide event so cid is 0 */
1078 if ((ev
->type
> ISCSI_UEVENT_MAX
&& ev
->type
< KEVENT_BASE
) ||
1079 (ev
->type
> ISCSI_KEVENT_MAX
))
1080 log_error("Unknown kernel event %d. You may want to "
1081 " upgrade your iscsi tools.", ev
->type
);
1084 * If another app is using the interface we might
1086 * stuff. Just drop it.
1088 log_debug(7, "Got unknwon event %d. Dropping.",
1094 /* verify connection */
1095 session
= session_find_by_sid(sid
);
1098 * this can happen normally when other apps are using the
1101 log_debug(1, "Could not verify connection %d:%d. Dropping "
1102 "event.\n", sid
, cid
);
1106 conn
= &session
->conn
[0];
1108 ev_size
= nlh
->nlmsg_len
- NLMSG_ALIGN(sizeof(struct nlmsghdr
));
1110 ev_context
= ipc_ev_clbk
->get_ev_context(conn
, ev_size
);
1113 log_error("Can not allocate memory for receive context.");
1117 log_debug(6, "message real length is %d bytes, recv_handle %p",
1118 nlh
->nlmsg_len
, ev_context
->data
);
1120 if ((rc
= nlpayload_read(ctrl_fd
, ev_context
->data
,
1122 ipc_ev_clbk
->put_ev_context(ev_context
);
1123 log_error("can not read from NL socket, error %d", rc
);
1129 * we sched these events because the handlers could call back
1130 * into ctldev_handle
1133 case ISCSI_KEVENT_RECV_PDU
:
1134 rc
= ipc_ev_clbk
->sched_ev_context(ev_context
, conn
, 0,
1137 case ISCSI_KEVENT_CONN_ERROR
:
1138 memcpy(ev_context
->data
, &ev
->r
.connerror
.error
,
1139 sizeof(ev
->r
.connerror
.error
));
1140 rc
= ipc_ev_clbk
->sched_ev_context(ev_context
, conn
, 0,
1143 case ISCSI_KEVENT_CONN_LOGIN_STATE
:
1144 memcpy(ev_context
->data
, &ev
->r
.conn_login
.state
,
1145 sizeof(ev
->r
.conn_login
.state
));
1146 rc
= ipc_ev_clbk
->sched_ev_context(ev_context
, conn
, 0,
1149 case ISCSI_KEVENT_UNBIND_SESSION
:
1150 rc
= ipc_ev_clbk
->sched_ev_context(ev_context
, conn
, 0,
1154 ipc_ev_clbk
->put_ev_context(ev_context
);
1155 log_error("unknown kernel event %d", ev
->type
);
1160 ipc_ev_clbk
->put_ev_context(ev_context
);
1167 log_debug(7, "in %s", __FUNCTION__
);
1169 nlm_sendbuf
= calloc(1, NLM_BUF_DEFAULT_MAX
);
1171 log_error("can not allocate nlm_sendbuf");
1175 nlm_recvbuf
= calloc(1, NLM_BUF_DEFAULT_MAX
);
1177 log_error("can not allocate nlm_recvbuf");
1178 goto free_nlm_sendbuf
;
1181 pdu_sendbuf
= calloc(1, PDU_SENDBUF_DEFAULT_MAX
);
1183 log_error("can not allocate nlm_sendbuf");
1184 goto free_nlm_recvbuf
;
1187 setparam_buf
= calloc(1, NLM_SETPARAM_DEFAULT_MAX
);
1188 if (!setparam_buf
) {
1189 log_error("can not allocate setparam_buf");
1190 goto free_pdu_sendbuf
;
1193 ctrl_fd
= socket(PF_NETLINK
, SOCK_RAW
, NETLINK_ISCSI
);
1195 log_error("can not create NETLINK_ISCSI socket");
1196 goto free_setparam_buf
;
1199 memset(&src_addr
, 0, sizeof(src_addr
));
1200 src_addr
.nl_family
= AF_NETLINK
;
1201 src_addr
.nl_pid
= getpid();
1202 src_addr
.nl_groups
= 1;
1203 if (bind(ctrl_fd
, (struct sockaddr
*)&src_addr
, sizeof(src_addr
))) {
1204 log_error("can not bind NETLINK_ISCSI socket");
1208 memset(&dest_addr
, 0, sizeof(dest_addr
));
1209 dest_addr
.nl_family
= AF_NETLINK
;
1210 dest_addr
.nl_pid
= 0; /* kernel */
1211 dest_addr
.nl_groups
= 0; /* unicast */
1213 log_debug(7, "created NETLINK_ISCSI socket...");
1233 log_debug(7, "in %s", __FUNCTION__
);
1243 struct iscsi_ipc nl_ipc
= {
1244 .name
= "Open-iSCSI Kernel IPC/NETLINK v.1",
1245 .ctldev_bufmax
= NLM_BUF_DEFAULT_MAX
,
1246 .ctldev_open
= ctldev_open
,
1247 .ctldev_close
= ctldev_close
,
1248 .ctldev_handle
= ctldev_handle
,
1249 .sendtargets
= ksendtargets
,
1250 .create_session
= kcreate_session
,
1251 .destroy_session
= kdestroy_session
,
1252 .unbind_session
= kunbind_session
,
1253 .create_conn
= kcreate_conn
,
1254 .destroy_conn
= kdestroy_conn
,
1255 .bind_conn
= kbind_conn
,
1256 .set_param
= kset_param
,
1257 .set_host_param
= kset_host_param
,
1259 .start_conn
= kstart_conn
,
1260 .stop_conn
= kstop_conn
,
1261 .get_stats
= kget_stats
,
1263 .send_pdu_begin
= ksend_pdu_begin
,
1264 .send_pdu_end
= ksend_pdu_end
,
1266 .recv_pdu_begin
= krecv_pdu_begin
,
1267 .recv_pdu_end
= krecv_pdu_end
,
1268 .set_net_config
= kset_net_config
,
1269 .recv_conn_state
= krecv_conn_state
,
1271 struct iscsi_ipc
*ipc
= &nl_ipc
;
1273 void ipc_register_ev_callback(struct iscsi_ipc_ev_clbk
*ev_clbk
)
1275 ipc_ev_clbk
= ev_clbk
;