2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/iscsi/initiator/iscsi.c,v 1.4 2008/11/25 07:17:11 scottl Exp $
30 | $Id: iscsi.c,v 1.35 2007/04/22 08:58:29 danny Exp danny $
33 #include "opt_iscsi_initiator.h"
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <sys/ctype.h>
43 #include <sys/errno.h>
44 #include <sys/sysctl.h>
47 #include <sys/socketvar.h>
48 #include <sys/socket.h>
49 #include <sys/protosw.h>
51 #include <sys/ioccom.h>
52 #include <sys/queue.h>
53 #include <sys/kthread.h>
55 #include <sys/syslog.h>
56 #include <sys/eventhandler.h>
57 #include <sys/mutex.h>
58 #include <sys/mutex2.h>
59 #include <sys/devfs.h>
62 #include <bus/cam/cam.h>
63 #include <dev/disk/iscsi/initiator/iscsi.h>
64 #include <dev/disk/iscsi/initiator/iscsivar.h>
66 static char *iscsi_driver_version = "2.1.0";
68 static struct isc_softc isc;
70 MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI driver");
72 struct objcache_malloc_args iscsi_malloc_args = {
73 sizeof(pduq_t), M_ISCSI
76 #ifdef ISCSI_INITIATOR_DEBUG
77 int iscsi_debug = ISCSI_INITIATOR_DEBUG;
78 SYSCTL_INT(_debug, OID_AUTO, iscsi_initiator, CTLFLAG_RW, &iscsi_debug, 0, "iSCSI driver debug flag");
80 struct lock iscsi_dbg_lock;
84 static char isid[6+1] = {
94 static int i_create_session(struct cdev *dev, int *ndev);
96 static int i_ping(struct cdev *dev);
97 static int i_send(struct cdev *dev, caddr_t arg, struct thread *td);
98 static int i_recv(struct cdev *dev, caddr_t arg, struct thread *td);
99 static int i_setsoc(isc_session_t *sp, int fd, struct thread *td);
101 static void free_pdus(struct isc_softc *sc);
103 static d_open_t iscsi_open;
104 static d_close_t iscsi_close;
105 static d_ioctl_t iscsi_ioctl;
106 #ifdef ISCSI_INITIATOR_DEBUG
107 static d_read_t iscsi_read;
110 static struct dev_ops iscsi_ops = {
111 .head = { "iscsi", ISCSI_CDEV_MAJOR, D_DISK},
112 .d_open = iscsi_open,
113 .d_close = iscsi_close,
114 .d_ioctl = iscsi_ioctl,
115 #ifdef ISCSI_INITIATOR_DEBUG
116 .d_read = iscsi_read,
121 iscsi_open(struct dev_open_args *ap)
123 cdev_t dev = ap->a_head.a_dev;
127 debug(7, "dev=%d", dev->si_uminor);
129 if(minor(dev) > MAX_SESSIONS) {
134 /* Make sure the device is passed */
135 if (dev->si_drv1 == NULL)
136 dev->si_drv1 = (struct isc *)isc.dev->si_drv1;
138 if(minor(dev) == MAX_SESSIONS) {
140 struct isc_softc *sc = (struct isc_softc *)dev->si_drv1;
142 // this should be in iscsi_start
143 if(sc->cam_sim == NULL)
151 iscsi_close(struct dev_close_args *ap)
153 cdev_t dev = ap->a_head.a_dev;
154 int flag = ap->a_fflag;
159 debug(3, "flag=%x", flag);
161 if(minor(dev) == MAX_SESSIONS) {
164 sp = (isc_session_t *)dev->si_drv2;
166 sdebug(2, "session=%d flags=%x", minor(dev), sp->flags );
168 | if still in full phase, this probably means
169 | that something went realy bad.
170 | it could be a result from 'shutdown', in which case
171 | we will ignore it (so buffers can be flushed).
172 | the problem is that there is no way of differentiating
173 | between a shutdown procedure and 'iscontrol' dying.
175 if(sp->flags & ISC_FFPHASE)
176 // delay in case this is a shutdown.
177 tsleep(sp, 0, "isc-cls", 60*hz);
185 iscsi_ioctl(struct dev_ioctl_args *ap)
188 cdev_t dev = ap->a_head.a_dev;
189 caddr_t arg = ap->a_data;
194 sc = (struct isc *)dev->si_drv1;
198 if(minor(dev) == MAX_SESSIONS) {
200 | non Session commands
207 error = i_create_session(dev, (int *)arg);
213 error = ENXIO; // XXX:
217 sp = (isc_session_t *)dev->si_drv2;
224 sdebug(6, "dev=%d cmd=%d", minor(dev), (int)(ap->a_cmd & 0xff));
228 error = i_setsoc(sp, *(u_int *)arg, curthread);
232 opt = (isc_opt_t *)arg;
233 error = i_setopt(sp, opt);
237 error = i_send(dev, arg, curthread);
241 error = i_recv(dev, arg, curthread);
249 error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 1);
251 sp->proc = curthread->td_proc;
252 SYSCTL_ADD_UINT(&sp->clist,
253 SYSCTL_CHILDREN(sp->oid),
257 &sp->proc->p_pid, sizeof(pid_t), "control process id");
262 error = sp->soc == NULL? ENOTCONN: ism_fullfeature(dev, 2);
266 error = ism_fullfeature(dev, 0);
270 int sig = *(int *)arg;
272 if(sig < 0 || sig > _SIG_MAXSIG)
280 iscsi_cam_t *cp = (iscsi_cam_t *)arg;
282 error = ic_getCamVals(sp, cp);
294 iscsi_read(struct dev_read_args *ra)
296 #ifdef ISCSI_INITIATOR_DEBUG
297 struct isc_softc *sc;
298 cdev_t dev = ra->a_head.a_dev;
299 struct uio *uio = ra->a_uio;
304 sc = (struct isc_softc *)dev->si_drv1;
305 sp = (isc_session_t *)dev->si_drv2;
307 if(minor(dev) == MAX_SESSIONS) {
308 ksprintf(buf, "/----- Session ------/\n");
309 uiomove(buf, strlen(buf), uio);
312 TAILQ_FOREACH(sp, &sc->isc_sess, sp_link) {
313 if(uio->uio_resid == 0)
315 ksprintf(buf, "%03d] '%s' '%s'\n", i++, sp->opt.targetAddress, sp->opt.targetName);
316 uiomove(buf, strlen(buf), uio);
318 ksprintf(buf, "%d/%d /---- free -----/\n", sc->npdu_alloc, sc->npdu_max);
320 uiomove(buf, strlen(buf), uio);
321 TAILQ_FOREACH(pq, &sc->freepdu, pq_link) {
322 if(uio->uio_resid == 0)
324 ksprintf(buf, "%03d] %06x\n", i++, ntohl(pq->pdu.ipdu.bhs.itt));
325 uiomove(buf, strlen(buf), uio);
330 struct socket *so = sp->soc;
331 #define pukeit(i, pq) do {\
332 ksprintf(buf, "%03d] %06x %02x %x %ld\n",\
333 i, ntohl( pq->pdu.ipdu.bhs.CmdSN), \
334 pq->pdu.ipdu.bhs.opcode, ntohl(pq->pdu.ipdu.bhs.itt),\
335 (long)pq->ts.tv_sec);\
338 ksprintf(buf, "%d/%d /---- hld -----/\n", sp->stats.nhld, sp->stats.max_hld);
339 uiomove(buf, strlen(buf), uio);
340 TAILQ_FOREACH(pq, &sp->hld, pq_link) {
341 if(uio->uio_resid == 0)
344 uiomove(buf, strlen(buf), uio);
346 ksprintf(buf, "%d/%d /---- rsp -----/\n", sp->stats.nrsp, sp->stats.max_rsp);
347 uiomove(buf, strlen(buf), uio);
349 TAILQ_FOREACH(pq, &sp->rsp, pq_link) {
350 if(uio->uio_resid == 0)
353 uiomove(buf, strlen(buf), uio);
355 ksprintf(buf, "%d/%d /---- csnd -----/\n", sp->stats.ncsnd, sp->stats.max_csnd);
357 uiomove(buf, strlen(buf), uio);
358 TAILQ_FOREACH(pq, &sp->csnd, pq_link) {
359 if(uio->uio_resid == 0)
362 uiomove(buf, strlen(buf), uio);
364 ksprintf(buf, "%d/%d /---- wsnd -----/\n", sp->stats.nwsnd, sp->stats.max_wsnd);
366 uiomove(buf, strlen(buf), uio);
367 TAILQ_FOREACH(pq, &sp->wsnd, pq_link) {
368 if(uio->uio_resid == 0)
371 uiomove(buf, strlen(buf), uio);
373 ksprintf(buf, "%d/%d /---- isnd -----/\n", sp->stats.nisnd, sp->stats.max_isnd);
375 uiomove(buf, strlen(buf), uio);
376 TAILQ_FOREACH(pq, &sp->isnd, pq_link) {
377 if(uio->uio_resid == 0)
380 uiomove(buf, strlen(buf), uio);
383 ksprintf(buf, "/---- Stats ---/\n");
384 uiomove(buf, strlen(buf), uio);
386 ksprintf(buf, "recv=%d sent=%d\n", sp->stats.nrecv, sp->stats.nsent);
387 uiomove(buf, strlen(buf), uio);
389 ksprintf(buf, "flags=%x pdus: alloc=%d max=%d\n",
390 sp->flags, sc->npdu_alloc, sc->npdu_max);
391 uiomove(buf, strlen(buf), uio);
393 ksprintf(buf, "cws=%d last cmd=%x exp=%x max=%x stat=%x itt=%x\n",
394 sp->cws, sp->sn.cmd, sp->sn.expCmd, sp->sn.maxCmd, sp->sn.stat, sp->sn.itt);
395 uiomove(buf, strlen(buf), uio);
398 ksprintf(buf, "/---- socket -----/\nso_state=%x\n", so->so_state);
399 uiomove(buf, strlen(buf), uio);
407 i_ping(struct cdev *dev)
415 i_setsoc(isc_session_t *sp, int fd, struct thread *td)
421 isc_stop_receiver(sp);
429 if ((error = holdsock(td->td_proc->p_fd, fd, &fp)) == 0) {
430 sp->soc = fp->f_data;
432 isc_start_receiver(sp);
439 i_send(struct cdev *dev, caddr_t arg, struct thread *td)
441 isc_session_t *sp = (isc_session_t *)dev->si_drv2;
442 struct isc_softc *sc = (struct isc_softc *)dev->si_drv1;
453 if((pq = pdu_alloc(sc, M_NOWAIT)) == NULL)
456 pq->pdu = *(pdu_t *)arg;
458 if((error = i_prepPDU(sp, pq)) != 0)
461 sdebug(3, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len);
463 pq->buf = bp = kmalloc(pq->len - sizeof(union ipdu_u), M_ISCSI, M_NOWAIT);
464 if(pq->buf == NULL) {
471 error = copyin(pp->ahs, bp, n);
473 sdebug(3, "copyin ahs: error=%d", error);
476 pp->ahs = (ahs_t *)bp;
481 error = copyin(pp->ds, bp, n);
483 sdebug(3, "copyin ds: error=%d", error);
494 error = isc_qout(sp, pq);
497 wakeup(&sp->flags); // XXX: to 'push' proc_out ...
507 | NOTE: must calculate digest if requiered.
510 i_recv(struct cdev *dev, caddr_t arg, struct thread *td)
512 isc_session_t *sp = (isc_session_t *)dev->si_drv2;
516 int error, mustfree, cnt;
517 size_t need, have, n;
527 cnt = 6; // XXX: maybe the user can request a time out?
528 iscsi_lock_ex(&sp->rsp_mtx);
529 while((pq = TAILQ_FIRST(&sp->rsp)) == NULL) {
530 issleep(&sp->rsp, &sp->rsp_mtx, 0, "isc_rsp", hz*10);
531 if(cnt-- == 0) break; // XXX: for now, needs work
536 TAILQ_REMOVE(&sp->rsp, pq, pq_link);
538 iscsi_unlock_ex(&sp->rsp_mtx);
540 sdebug(4, "cnt=%d", cnt);
544 sdebug(3, "error=%d sp->flags=%x ", error, sp->flags);
572 if(len > pq->mp->m_len) {
574 bp = kmalloc(len, M_ISCSI, M_INTWAIT);
575 sdebug(4, "need mbufcopy: %d", len);
576 i_mbufcopy(pq->mp, bp, len);
579 bp = mtod(pq->mp, caddr_t);
585 n = MIN(up->ahs_size, need);
586 error = copyout(bp, (caddr_t)up->ahs, n);
590 if(!error && pp->ds_len) {
594 if((have = up->ds_size) == 0) {
595 have = up->ahs_size - n;
596 up->ds = (caddr_t)up->ahs + n;
599 error = copyout(bp, (caddr_t)up->ds, n);
607 sdebug(6, "len=%d ahs_len=%d ds_len=%d", pq->len, pp->ahs_len, pp->ds_len);
609 pdu_free(sp->isc, pq);
615 i_create_session(struct cdev *dev, int *ndev)
617 struct isc_softc *sc = (struct isc_softc *)dev->si_drv1;
622 sp = (isc_session_t *)kmalloc(sizeof *sp, M_ISCSI, M_WAITOK | M_ZERO);
625 lockmgr(&sc->lock, LK_EXCLUSIVE);
627 | search for the lowest unused sid
629 for(n = 0; n < MAX_SESSIONS; n++)
630 if(sc->sessions[n] == NULL)
632 if(n == MAX_SESSIONS) {
633 lockmgr(&sc->lock, LK_RELEASE);
637 TAILQ_INSERT_TAIL(&sc->isc_sess, sp, sp_link);
639 lockmgr(&sc->lock, LK_RELEASE);
641 sc->sessions[n] = sp;
642 debug(8, "n is %d", n);
643 sp->dev = make_dev(&iscsi_ops, n, UID_ROOT, GID_WHEEL, 0600, "iscsi%d", n);
645 reference_dev(sp->dev);
646 udev_dict_set_cstr(sp->dev, "subsystem", "disk");
647 udev_dict_set_cstr(sp->dev, "disk-type", "network");
651 sp->dev->si_drv1 = sc;
652 sp->dev->si_drv2 = sp;
654 sp->opt.maxRecvDataSegmentLength = 8192;
655 sp->opt.maxXmitDataSegmentLength = 8192;
657 sp->opt.maxBurstLength = 65536; // 64k
659 sdebug(2, "sessionID=%d sp=%p", n, sp);
660 error = ism_start(sp);
667 iscsi_counters(isc_session_t *sp)
672 #define _puke(i, pq) do {\
673 debug(2, "%03d] %06x %02x %x %ld %jd %x\n",\
674 i, ntohl( pq->pdu.ipdu.bhs.CmdSN), \
675 pq->pdu.ipdu.bhs.opcode, ntohl(pq->pdu.ipdu.bhs.itt),\
676 (long)pq->ts.sec, pq->ts.frac, pq->flags);\
680 TAILQ_FOREACH(pq, &sp->hld, pq_link) {
684 TAILQ_FOREACH(pq, &sp->rsp, pq_link) r++;
685 TAILQ_FOREACH(pq, &sp->csnd, pq_link) s++;
686 TAILQ_FOREACH(pq, &sp->wsnd, pq_link) s++;
687 TAILQ_FOREACH(pq, &sp->isnd, pq_link) s++;
688 debug(2, "hld=%d rsp=%d snd=%d", h, r, s);
693 iscsi_shutdown(void *v)
695 struct isc_softc *sc = (struct isc_softc *)v;
701 xdebug("sc is NULL!");
705 debug(2, "sc->eh is NULL");
707 EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->eh);
708 debug(2, "done n=%d", sc->nsess);
711 TAILQ_FOREACH(sp, &sc->isc_sess, sp_link) {
712 debug(2, "%2d] sp->flags=0x%08x", n, sp->flags);
719 init_pdus(struct isc_softc *sc)
723 sc->pdu_zone = objcache_create("pdu", 0, 0,
725 objcache_malloc_alloc,
726 objcache_malloc_free,
729 if(sc->pdu_zone == NULL) {
730 kprintf("iscsi_initiator: objcache_create failed");
733 TAILQ_INIT(&sc->freepdu);
739 free_pdus(struct isc_softc *sc)
745 if(sc->pdu_zone != NULL) {
746 TAILQ_FOREACH(pq, &sc->freepdu, pq_link) {
747 TAILQ_REMOVE(&sc->freepdu, pq, pq_link);
748 objcache_put(sc->pdu_zone, pq);
750 objcache_destroy(sc->pdu_zone);
758 struct isc_softc *sc = &isc;
762 memset(sc, 0, sizeof(struct isc_softc));
764 sc->dev = make_dev(&iscsi_ops, MAX_SESSIONS, UID_ROOT, GID_WHEEL, 0600, "iscsi");
767 sc->dev->si_drv1 = sc;
769 reference_dev(sc->dev);
771 TAILQ_INIT(&sc->isc_sess);
772 if(init_pdus(sc) != 0)
773 xdebug("pdu zone init failed!"); // XXX: should cause terminal failure ...
775 lockinit(&sc->lock, "iscsi", 0, LK_CANRECURSE);
776 lockinit(&sc->pdu_lock, "iscsi pdu pool", 0, LK_CANRECURSE);
779 // XXX: this will cause a panic if the
780 // module is loaded too early
787 #ifdef DO_EVENTHANDLER
788 if((sc->eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown,
789 sc, SHUTDOWN_PRI_DEFAULT-1)) == NULL)
790 xdebug("shutdown event registration failed\n");
795 sysctl_ctx_init(&sc->clist);
796 sc->oid = SYSCTL_ADD_NODE(&sc->clist,
797 SYSCTL_STATIC_CHILDREN(_net),
804 SYSCTL_ADD_STRING(&sc->clist,
805 SYSCTL_CHILDREN(sc->oid),
809 iscsi_driver_version,
811 "iscsi driver version");
813 SYSCTL_ADD_STRING(&sc->clist,
814 SYSCTL_CHILDREN(sc->oid),
820 "initiator part of the Session Identifier");
822 SYSCTL_ADD_INT(&sc->clist,
823 SYSCTL_CHILDREN(sc->oid),
829 "number of active session");
831 kprintf("iscsi: version %s\n", iscsi_driver_version);
836 | unload SHOULD fail if there is activity
837 | activity: there is/are active session/s
842 struct isc_softc *sc = &isc;
843 isc_session_t *sp, *sp_tmp;
848 | go through all the sessions
849 | Note: close should have done this ...
851 TAILQ_FOREACH_MUTABLE(sp, &sc->isc_sess, sp_link, sp_tmp) {
852 //XXX: check for activity ...
855 if(sc->cam_sim != NULL)
858 lockuninit(&sc->lock);
859 lockuninit(&sc->pdu_lock);
863 release_dev(sc->dev);
864 destroy_dev(sc->dev);
865 //dev_ops_remove(&sc->dev, -1, 0);
868 if(sysctl_ctx_free(&sc->clist))
869 xdebug("sysctl_ctx_free failed");
871 iscsi_shutdown(sc); // XXX: check EVENTHANDLER_ ...
875 iscsi_modevent(module_t mod, int what, void *arg)
897 moduledata_t iscsi_mod = {
899 (modeventhand_t) iscsi_modevent,
908 nfs_setup_diskless();
909 if (nfs_diskless_valid)
910 rootdevnames[0] = "nfs:";
912 kprintf("** iscsi_rootconf **\n");
915 SYSINIT(cpu_rootconf1, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, iscsi_rootconf, NULL)
918 DECLARE_MODULE(iscsi_initiator, iscsi_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
919 MODULE_DEPEND(iscsi_initiator, cam, 1, 1, 1);