svn commit: r185289 - in head: sbin/iscontrol
sys/dev/iscsi/initiator
Scott Long
scottl at FreeBSD.org
Mon Nov 24 23:17:12 PST 2008
Author: scottl
Date: Tue Nov 25 07:17:11 2008
New Revision: 185289
URL: http://svn.freebsd.org/changeset/base/185289
Log:
Big update to the iSCSI initiator code. Highlights include IPv6 support,
many bugs fixes, many more performance improvements.
Submitted by: Danny Braniss
M sbin/iscontrol/iscsi.conf.5
M sbin/iscontrol/iscontrol.8
M sbin/iscontrol/iscontrol.h
M sbin/iscontrol/config.c
M sbin/iscontrol/fsm.c
M sbin/iscontrol/login.c
M sbin/iscontrol/pdu.c
M sbin/iscontrol/misc.c
M sbin/iscontrol/auth_subr.c
M sbin/iscontrol/iscontrol.c
M sys/dev/iscsi/initiator/isc_cam.c
M sys/dev/iscsi/initiator/iscsi.h
M sys/dev/iscsi/initiator/isc_soc.c
M sys/dev/iscsi/initiator/iscsi_subr.c
M sys/dev/iscsi/initiator/iscsivar.h
M sys/dev/iscsi/initiator/isc_subr.c
M sys/dev/iscsi/initiator/iscsi.c
M sys/dev/iscsi/initiator/isc_sm.c
Modified:
head/sbin/iscontrol/auth_subr.c
head/sbin/iscontrol/config.c
head/sbin/iscontrol/fsm.c
head/sbin/iscontrol/iscontrol.8
head/sbin/iscontrol/iscontrol.c
head/sbin/iscontrol/iscontrol.h
head/sbin/iscontrol/iscsi.conf.5
head/sbin/iscontrol/login.c
head/sbin/iscontrol/misc.c
head/sbin/iscontrol/pdu.c
head/sys/dev/iscsi/initiator/isc_cam.c
head/sys/dev/iscsi/initiator/isc_sm.c
head/sys/dev/iscsi/initiator/isc_soc.c
head/sys/dev/iscsi/initiator/isc_subr.c
head/sys/dev/iscsi/initiator/iscsi.c
head/sys/dev/iscsi/initiator/iscsi.h
head/sys/dev/iscsi/initiator/iscsi_subr.c
head/sys/dev/iscsi/initiator/iscsivar.h
Modified: head/sbin/iscontrol/auth_subr.c
==============================================================================
--- head/sbin/iscontrol/auth_subr.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/auth_subr.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include "iscsi.h"
#include "iscontrol.h"
-#include "pdu.h"
static int
chapMD5(char id, char *cp, char *chapSecret, unsigned char *digest)
Modified: head/sbin/iscontrol/config.c
==============================================================================
--- head/sbin/iscontrol/config.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/config.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Modified: head/sbin/iscontrol/fsm.c
==============================================================================
--- head/sbin/iscontrol/fsm.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/fsm.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include "iscsi.h"
#include "iscontrol.h"
-#include "pdu.h"
typedef enum {
T1 = 1,
@@ -66,38 +65,40 @@ typedef enum {
T10, T11, T12, T13, T14, T15, T16, T18
} trans_t;
+/*
+ | now supports IPV6
+ | thanks to:
+ | Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
+ | ume at mahoroba.org ume@{,jp.}FreeBSD.org
+ | http://www.imasy.org/~ume/
+ */
static trans_t
tcpConnect(isess_t *sess)
{
isc_opt_t *op = sess->op;
- int val, sv_errno;
- struct addrinfo *res, hints;
- struct sockaddr_in sn;
- struct in_addr ipn;
- time_t sec;
+ int val, sv_errno, soc;
+ struct addrinfo *res, *res0, hints;
+ char pbuf[10];
debug_called(3);
if(sess->flags & (SESS_RECONNECT|SESS_REDIRECT)) {
syslog(LOG_INFO, "%s", (sess->flags & SESS_RECONNECT)
? "Reconnect": "Redirected");
- debug(3, "%s", (sess->flags & SESS_RECONNECT) ? "Reconnect": "Redirected");
+ debug(1, "%s", (sess->flags & SESS_RECONNECT) ? "Reconnect": "Redirected");
shutdown(sess->soc, SHUT_RDWR);
//close(sess->soc);
- sleep(5); // XXX: actually should be ?
sess->soc = -1;
sess->flags &= ~SESS_CONNECTED;
if(sess->flags & SESS_REDIRECT) {
- if(sess->redirect_cnt++ > MAXREDIRECTS) {
- syslog(LOG_WARNING, "too many redirects > %d", MAXREDIRECTS);
- return 0;
- }
+ sess->redirect_cnt++;
sess->flags |= SESS_RECONNECT;
- }
- if((sess->flags & SESS_RECONNECT) == 0)
- return 0;
-
+ } else
+ sleep(2); // XXX: actually should be ?
+#ifdef notyet
+ {
+ time_t sec;
// make sure we are not in a loop
// XXX: this code has to be tested
sec = time(0) - sess->reconnect_time;
@@ -117,41 +118,46 @@ tcpConnect(isess_t *sess)
return 0;
}
}
- sess->reconnect_cnt++;
- // sess->flags &= ~(SESS_RECONNECT|SESS_REDIRECT);
}
-
- if((sess->soc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- fprintf(stderr, "tcpConnect: socket: %m");
- return 0;
+#endif
+ sess->reconnect_cnt++;
}
+ snprintf(pbuf, sizeof(pbuf), "%d", op->port);
memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_INET;
+ hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
-
- debug(3, "targetAddress=%s port=%d", op->targetAddress, op->port);
- if(inet_aton(op->targetAddress, &ipn))
- hints.ai_flags |= AI_NUMERICHOST;
- if((val = getaddrinfo(op->targetAddress, NULL, &hints, &res)) != 0) {
+ debug(1, "targetAddress=%s port=%d", op->targetAddress, op->port);
+ if((val = getaddrinfo(op->targetAddress, pbuf, &hints, &res0)) != 0) {
fprintf(stderr, "getaddrinfo(%s): %s\n", op->targetAddress, gai_strerror(val));
return 0;
}
- memcpy(&sn, res->ai_addr, sizeof(struct sockaddr_in));
- sn.sin_port = htons(op->port);
- freeaddrinfo(res);
+ sess->flags &= ~SESS_CONNECTED;
+ sv_errno = 0;
+ soc = -1;
+ for(res = res0; res; res = res->ai_next) {
+ soc = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (soc == -1)
+ continue;
// from Patrick.Guelat at imp.ch:
// iscontrol can be called without waiting for the socket entry to time out
val = 1;
- if(setsockopt(sess->soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) {
+ if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) {
fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n",
errno, strerror(errno));
}
- sess->flags &= ~SESS_CONNECTED;
+ if(connect(soc, res->ai_addr, res->ai_addrlen) == 0)
+ break;
+ sv_errno = errno;
+ close(soc);
+ soc = -1;
+ }
+ freeaddrinfo(res0);
+ if(soc != -1) {
+ sess->soc = soc;
- if(connect(sess->soc, (struct sockaddr *)&sn, sizeof(struct sockaddr_in)) != -1) {
#if 0
struct timeval timeout;
@@ -190,21 +196,29 @@ tcpConnect(isess_t *sess)
}
sess->flags |= SESS_CONNECTED;
return T1;
-
}
- sv_errno = errno;
+
fprintf(stderr, "errno=%d\n", sv_errno);
perror("connect");
switch(sv_errno) {
case ECONNREFUSED:
case ENETUNREACH:
case ETIMEDOUT:
+ if((sess->flags & SESS_REDIRECT) == 0) {
+ if(strcmp(op->targetAddress, sess->target.address) != 0) {
+ syslog(LOG_INFO, "reconnecting to original target address");
+ free(op->targetAddress);
+ op->targetAddress = sess->target.address;
+ op->port = sess->target.port;
+ op->targetPortalGroupTag = sess->target.pgt;
+ return T1;
+ }
+ }
sleep(5); // for now ...
return T1;
default:
return 0; // terminal error
}
-
}
int
@@ -416,7 +430,6 @@ supervise(isess_t *sess)
}
else {
-
if(ioctl(sess->fd, ISCSIRESTART)) {
perror("ISCSIRESTART");
return -1;
@@ -554,7 +567,10 @@ doLogin(isess_t *sess)
return T7;
case 2: // initiator terminal error
+ return 0;
case 3: // target terminal error -- could retry ...
+ sleep(5);
+ return T7; // lets try
default:
return 0;
}
@@ -654,6 +670,9 @@ fsm(isc_opt_t *op)
sess->op = op;
sess->fd = -1;
sess->soc = -1;
+ sess->target.address = strdup(op->targetAddress);
+ sess->target.port = op->port;
+ sess->target.pgt = op->targetPortalGroupTag;
sess->flags = SESS_INITIALLOGIN | SESS_INITIALLOGIN1;
Modified: head/sbin/iscontrol/iscontrol.8
==============================================================================
--- head/sbin/iscontrol/iscontrol.8 Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/iscontrol.8 Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2007 Daniel Braniss <danny at cs.huji.ac.il>
+.\" Copyright (c) 2007-2008 Daniel Braniss <danny at cs.huji.ac.il>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
Modified: head/sbin/iscontrol/iscontrol.c
==============================================================================
--- head/sbin/iscontrol/iscontrol.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/iscontrol.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include "iscsi.h"
#include "iscontrol.h"
-//#include "pdu.h"
#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] "
#define OPTIONS "vdc:t:n:"
@@ -129,7 +128,7 @@ int
main(int cc, char **vv)
{
int ch, disco;
- char *pname, *p, *ta, *kw;
+ char *pname, *p, *q, *ta, *kw;
isc_opt_t *op;
FILE *fd;
@@ -191,12 +190,18 @@ main(int cc, char **vv)
fprintf(stderr, "No target!\n");
goto badu;
}
- if((p = strchr(op->targetAddress, ':')) != NULL) {
+ q = op->targetAddress;
+ if(*q == '[' && (q = strchr(q, ']')) != NULL) {
+ *q++ = '\0';
+ op->targetAddress++;
+ } else
+ q = op->targetAddress;
+ if((p = strchr(q, ':')) != NULL) {
*p++ = 0;
op->port = atoi(p);
p = strchr(p, ',');
}
- if(p || ((p = strchr(op->targetAddress, ',')) != NULL)) {
+ if(p || ((p = strchr(q, ',')) != NULL)) {
*p++ = 0;
op->targetPortalGroupTag = atoi(p);
}
Modified: head/sbin/iscontrol/iscontrol.h
==============================================================================
--- head/sbin/iscontrol/iscontrol.h Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/iscontrol.h Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,12 @@ int vflag;
typedef int auth_t(void *sess);
+typedef struct {
+ char *address;
+ int port;
+ int pgt;
+} target_t;
+
typedef struct isess {
int flags;
#define SESS_CONNECTED BIT(0)
@@ -61,6 +67,7 @@ typedef struct isess {
isc_opt_t *op; // operational values
+ target_t target; // the Original target address
int fd; // the session fd
int soc; // the socket
iscsi_cam_t cam;
Modified: head/sbin/iscontrol/iscsi.conf.5
==============================================================================
--- head/sbin/iscontrol/iscsi.conf.5 Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/iscsi.conf.5 Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2007 Daniel Braniss <danny at cs.huji.ac.il>
+.\" Copyright (c) 2007-2008 Daniel Braniss <danny at cs.huji.ac.il>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
Modified: head/sbin/iscontrol/login.c
==============================================================================
--- head/sbin/iscontrol/login.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/login.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include "iscsi.h"
#include "iscontrol.h"
-#include "pdu.h"
static char *status_class1[] = {
"Initiator error",
@@ -173,16 +172,18 @@ processParams(isess_t *sess, pdu_t *pp)
klen = eq - ptr;
if(klen > 0) {
if(strncmp(ptr, "TargetAddress", klen) == 0) {
- char *p, *q;
+ char *p, *q, *ta = NULL;
// TargetAddress=domainname[:port][,portal-group-tag]
// XXX: if(op->targetAddress) free(op->targetAddress);
q = op->targetAddress = strdup(eq+1);
if(*q == '[') {
// bracketed IPv6
- if((q = strchr(q, ']')) != NULL)
- q++;
- else
+ if((q = strchr(q, ']')) != NULL) {
+ *q++ = '\0';
+ ta = op->targetAddress;
+ op->targetAddress = strdup(ta+1);
+ } else
q = op->targetAddress;
}
if((p = strchr(q, ',')) != NULL) {
@@ -193,6 +194,8 @@ processParams(isess_t *sess, pdu_t *pp)
*p++ = 0;
op->port = atoi(p);
}
+ if(ta)
+ free(ta);
} else if(strncmp(ptr, "MaxRecvDataSegmentLength", klen) == 0) {
// danny's RFC
op->maxXmitDataSegmentLength = strtol(eq+1, (char **)NULL, 0);
Modified: head/sbin/iscontrol/misc.c
==============================================================================
--- head/sbin/iscontrol/misc.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/misc.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Modified: head/sbin/iscontrol/pdu.c
==============================================================================
--- head/sbin/iscontrol/pdu.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sbin/iscontrol/pdu.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include "iscsi.h"
#include "iscontrol.h"
-#include "pdu.h"
int
xmitpdu(isess_t *sess, pdu_t *pp)
Modified: head/sys/dev/iscsi/initiator/isc_cam.c
==============================================================================
--- head/sys/dev/iscsi/initiator/isc_cam.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sys/dev/iscsi/initiator/isc_cam.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -193,6 +193,23 @@ _inq(struct cam_sim *sim, union ccb *ccb
cpi->ccb_h.status = CAM_REQ_CMP;
}
+static __inline int
+_scsi_encap(struct cam_sim *sim, union ccb *ccb)
+{
+ int ret;
+
+#if __FreeBSD_version < 700000
+ ret = scsi_encap(sim, ccb);
+#else
+ struct isc_softc *isp = (struct isc_softc *)cam_sim_softc(sim);
+
+ mtx_unlock(&isp->cam_mtx);
+ ret = scsi_encap(sim, ccb);
+ mtx_lock(&isp->cam_mtx);
+#endif
+ return ret;
+}
+
static void
ic_action(struct cam_sim *sim, union ccb *ccb)
{
@@ -281,17 +298,8 @@ ic_action(struct cam_sim *sim, union ccb
ccb_h->status = CAM_LUN_INVALID;
break;
}
-#if __FreeBSD_version < 700000
- if(scsi_encap(sim, ccb) != 0)
+ if(_scsi_encap(sim, ccb) != 0)
return;
-#else
- mtx_unlock(&isp->cam_mtx);
- if(scsi_encap(sim, ccb) != 0) {
- mtx_lock(&isp->cam_mtx);
- return;
- }
- mtx_lock(&isp->cam_mtx);
-#endif
break;
}
@@ -396,7 +404,11 @@ ic_init(struct isc_softc *isp)
return ENXIO;
}
CAM_LOCK(isp);
- if(xpt_bus_register(sim, NULL, 0/*bus_number*/) != CAM_SUCCESS)
+ if(xpt_bus_register(sim,
+#if __FreeBSD_version >= 700000
+ NULL,
+#endif
+ 0/*bus_number*/) != CAM_SUCCESS)
goto bad;
if(xpt_create_path(&path, xpt_periph, cam_sim_path(sim),
Modified: head/sys/dev/iscsi/initiator/isc_sm.c
==============================================================================
--- head/sys/dev/iscsi/initiator/isc_sm.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sys/dev/iscsi/initiator/isc_sm.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -174,7 +174,7 @@ _nop_out(isc_session_t *sp)
/*
| only send a nop if window is closed.
*/
- if((pq = pdu_alloc(sp->isc, 0)) == NULL)
+ if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL)
// I guess we ran out of resources
return;
nop_out = &pq->pdu.ipdu.nop_out;
@@ -224,7 +224,6 @@ _nop_in(isc_session_t *sp, pduq_t *pq)
nop_out = &pp->ipdu.nop_out;
nop_out->sn.maxcmd = 0;
memset(nop_out->mbz, 0, sizeof(nop_out->mbz));
-
(void)isc_qout(sp, pq); //XXX: should check return?
return;
}
@@ -318,27 +317,24 @@ isc_qout(isc_session_t *sp, pduq_t *pq)
i_nqueue_csnd(sp, pq);
sdebug(5, "enqued: pq=%p", pq);
-#ifdef ISC_OWAITING
- if(sp->flags & ISC_OWAITING) {
- mtx_lock(&sp->io_mtx); // XXX
- wakeup(&sp->flags);
- mtx_unlock(&sp->io_mtx); // XXX
- }
-#else
+
+ mtx_lock(&sp->io_mtx);
+ sp->flags |= ISC_OQNOTEMPTY;
+ if(sp->flags & ISC_OWAITING)
wakeup(&sp->flags);
-#endif
+ mtx_unlock(&sp->io_mtx);
+
return error;
}
/*
| called when a fullPhase is restarted
*/
-static int
+static void
ism_restart(isc_session_t *sp)
{
int lastcmd;
sdebug(2, "restart ...");
- sp->flags |= ISC_SM_HOLD;
lastcmd = iscsi_requeue(sp);
#if 0
if(lastcmd != sp->sn.cmd) {
@@ -346,8 +342,13 @@ ism_restart(isc_session_t *sp)
sp->sn.cmd = lastcmd;
}
#endif
- sp->flags &= ~ISC_SM_HOLD;
- return 0;
+ mtx_lock(&sp->io_mtx);
+ if(sp->flags & ISC_OWAITING) {
+ wakeup(&sp->flags);
+ }
+ mtx_unlock(&sp->io_mtx);
+
+ sdebug(2, "restarted lastcmd=0x%x", lastcmd);
}
int
@@ -367,7 +368,7 @@ ism_fullfeature(struct cdev *dev, int fl
error = ic_fullfeature(dev);
break;
case 2: // restart
- error = ism_restart(sp);
+ ism_restart(sp);
break;
}
return error;
@@ -454,32 +455,40 @@ ism_recv(isc_session_t *sp, pduq_t *pq)
}
}
+/*
+ | go through the out queues looking for work
+ | if either nothing to do, or window is closed
+ | return.
+ */
static int
proc_out(isc_session_t *sp)
{
sn_t *sn = &sp->sn;
pduq_t *pq;
- int error, ndone = 0;
+ int error, ndone;
int which;
debug_called(8);
+ error = ndone = 0;
- while(1) {
+ while(sp->flags & ISC_LINK_UP) {
pdu_t *pp;
bhs_t *bhs;
-
/*
| check if there is outstanding work in:
- | 1- the Inmediate queue
+ | 1- the Immediate queue
| 2- the R2T queue
| 3- the cmd queue, only if the command window allows it.
*/
which = BIT(0) | BIT(1);
- if(SNA_GT(sn->cmd, sn->maxCmd) == 0)
+ if(SNA_GT(sn->cmd, sn->maxCmd) == 0) // if(sn->maxCmd - sn->smc + 1) > 0
which |= BIT(2);
+ sdebug(4, "which=%d sn->maxCmd=%d sn->cmd=%d", which, sn->maxCmd, sn->cmd);
+
if((pq = i_dqueue_snd(sp, which)) == NULL)
break;
+ sdebug(4, "pq=%p", pq);
pp = &pq->pdu;
bhs = &pp->ipdu.bhs;
@@ -510,38 +519,45 @@ proc_out(isc_session_t *sp)
// XXX: and now?
}
- sdebug(5, "opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)",
+ sdebug(4, "opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)",
bhs->opcode,
sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt);
if(pq->ccb)
i_nqueue_hld(sp, pq);
- if((error = isc_sendPDU(sp, pq)) == 0)
+ if((error = isc_sendPDU(sp, pq)) == 0) {
ndone++;
+ if(pq->ccb == NULL)
+ pdu_free(sp->isc, pq);
+ }
else {
xdebug("error=%d ndone=%d opcode=0x%x ccb=%p itt=%x",
error, ndone, bhs->opcode, pq->ccb, ntohl(bhs->itt));
- if(error == EPIPE) {
- // XXX: better do some error recovery ...
+ if(pq->ccb)
+ i_remove_hld(sp, pq);
+ switch(error) {
+ case EPIPE:
+ sp->flags &= ~ISC_LINK_UP;
+
+ case EAGAIN:
+ xdebug("requed");
+ i_rqueue_pdu(sp, pq);
break;
- }
-#if 0
+
+ default:
if(pq->ccb) {
- i_remove_hld(sp, pq);
- pq->ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR; // some better error?
- XPT_DONE(pq->ccb);
+ xdebug("back to cam");
+ pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error?
+ XPT_DONE(sp->isc, pq->ccb);
+ pdu_free(sp->isc, pq);
}
- else {
- // XXX: now what?
- // how do we pass back an error?
+ else
+ xdebug("we lost it!");
}
-#endif
}
- if(pq->ccb == NULL || error)
- pdu_free(sp->isc, pq);
}
- return ndone;
+ return error;
}
/*
@@ -551,42 +567,46 @@ static void
ism_proc(void *vp)
{
isc_session_t *sp = (isc_session_t *)vp;
- int odone;
+ int error;
debug_called(8);
- sdebug(3, "started");
sp->flags |= ISC_SM_RUNNING;
+ sdebug(3, "started sp->flags=%x", sp->flags);
do {
- if(sp->flags & ISC_SM_HOLD)
- odone = 0;
- else
- odone = proc_out(sp);
- sdebug(7, "odone=%d", odone);
- if(odone == 0) {
+ if((sp->flags & ISC_HOLD) == 0) {
+ error = proc_out(sp);
+ if(error) {
+ sdebug(3, "error=%d", error);
+ }
+ }
mtx_lock(&sp->io_mtx);
-#ifdef ISC_OWAITING
+ if((sp->flags & ISC_LINK_UP) == 0) {
+ wakeup(&sp->soc);
+ }
+
+ if(!(sp->flags & ISC_OQNOTEMPTY)) {
sp->flags |= ISC_OWAITING;
-#endif
- if((msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK)
- && (sp->flags & ISC_CON_RUNNING))
+ if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) {
+ if(sp->flags & ISC_CON_RUNNING)
_nop_out(sp);
-#ifdef ISC_OWAITING
+ }
sp->flags &= ~ISC_OWAITING;
-#endif
- mtx_unlock(&sp->io_mtx);
}
+ sp->flags &= ~ISC_OQNOTEMPTY;
+ mtx_unlock(&sp->io_mtx);
} while(sp->flags & ISC_SM_RUN);
sp->flags &= ~ISC_SM_RUNNING;
+ sdebug(3, "dropped ISC_SM_RUNNING");
#if __FreeBSD_version >= 700000
destroy_dev(sp->dev);
#endif
+ wakeup(sp);
- sdebug(3, "terminated");
+ debug(3, "terminated sp=%p sp->sid=%d", sp, sp->sid);
- wakeup(sp);
kproc_exit(0);
}
@@ -695,6 +715,13 @@ isc_add_sysctls(isc_session_t *sp)
CTLFLAG_RD,
(void *)sp, 0,
isc_dump_stats, "A", "statistics");
+
+ SYSCTL_ADD_INT(&sp->clist,
+ SYSCTL_CHILDREN(sp->oid),
+ OID_AUTO,
+ "douio",
+ CTLFLAG_RW,
+ &sp->douio, 0, "enable uio on read");
}
void
@@ -782,5 +809,6 @@ ism_start(isc_session_t *sp)
sp->flags |= ISC_SM_RUN;
+ debug(4, "starting ism_proc: sp->sid=%d", sp->sid);
return kproc_create(ism_proc, sp, &sp->stp, 0, 0, "ism_%d", sp->sid);
}
Modified: head/sys/dev/iscsi/initiator/isc_soc.c
==============================================================================
--- head/sys/dev/iscsi/initiator/isc_soc.c Tue Nov 25 05:17:39 2008 (r185288)
+++ head/sys/dev/iscsi/initiator/isc_soc.c Tue Nov 25 07:17:11 2008 (r185289)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2005-2007 Daniel Braniss <danny at cs.huji.ac.il>
+ * Copyright (c) 2005-2008 Daniel Braniss <danny at cs.huji.ac.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,157 +55,179 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/user.h>
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+
#include <dev/iscsi/initiator/iscsi.h>
#include <dev/iscsi/initiator/iscsivar.h>
-#ifndef USE_MBUF
+#ifndef NO_USE_MBUF
#define USE_MBUF
#endif
#ifdef USE_MBUF
+
+static int ou_refcnt = 0;
+
/*
- | a dummy function for freeing external storage for mbuf
+ | function for freeing external storage for mbuf
*/
static void
-nil_fn(void *a, void *b)
+ext_free(void *a, void *b)
{
+ pduq_t *pq = b;
+
+ if(pq->buf != NULL) {
+ debug(3, "ou_refcnt=%d a=%p b=%p", ou_refcnt, a, pq->buf);
+ free(pq->buf, M_ISCSI);
+ pq->buf = NULL;
+ }
}
-static int nil_refcnt = 0;
-#endif /* USE_MBUF */
int
isc_sendPDU(isc_session_t *sp, pduq_t *pq)
{
+ struct mbuf *mh, **mp;
pdu_t *pp = &pq->pdu;
int len, error;
-#ifdef USE_MBUF
- struct mbuf *mh, **mp;
-#else
- struct uio *uio = &pq->uio;
- struct iovec *iv;
-#endif /* USE_MBUF */
debug_called(8);
-
-#ifndef USE_MBUF
- bzero(uio, sizeof(struct uio));
- uio->uio_rw = UIO_WRITE;
- uio->uio_segflg = UIO_SYSSPACE;
- uio->uio_td = sp->td;
- uio->uio_iov = iv = pq->iov;
-
- iv->iov_base = &pp->ipdu;
- iv->iov_len = sizeof(union ipdu_u);
- uio->uio_resid = pq->len;
- iv++;
-#else /* USE_MBUF */
- /* mbuf for the iSCSI header */
- MGETHDR(mh, M_WAIT, MT_DATA);
+ /*
+ | mbuf for the iSCSI header
+ */
+ MGETHDR(mh, M_TRYWAIT, MT_DATA);
mh->m_len = mh->m_pkthdr.len = sizeof(union ipdu_u);
mh->m_pkthdr.rcvif = NULL;
MH_ALIGN(mh, sizeof(union ipdu_u));
bcopy(&pp->ipdu, mh->m_data, sizeof(union ipdu_u));
mh->m_next = NULL;
-#endif /* USE_MBUF */
if(sp->hdrDigest)
pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0);
if(pp->ahs_len) {
-#ifndef USE_MBUF
- iv->iov_base = pp->ahs;
- iv->iov_len = pp->ahs_len;
- iv++;
-#else /* USE_MBUF */
- /* Add any AHS to the iSCSI hdr mbuf */
- /* XXX Assert: (mh->m_pkthdr.len + pp->ahs_len) < MHLEN */
+ /*
+ | Add any AHS to the iSCSI hdr mbuf
+ | XXX Assert: (mh->m_pkthdr.len + pp->ahs_len) < MHLEN
+ */
bcopy(pp->ahs, (mh->m_data + mh->m_len), pp->ahs_len);
mh->m_len += pp->ahs_len;
mh->m_pkthdr.len += pp->ahs_len;
-#endif /* USE_MBUF */
+
if(sp->hdrDigest)
pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig);
}
if(sp->hdrDigest) {
debug(2, "hdr_dig=%x", pq->pdu.hdr_dig);
-#ifndef USE_MBUF
- iv->iov_base = &pp->hdr_dig;
- iv->iov_len = sizeof(int);
- iv++;
-#else /* USE_MBUF */
- /* Add header digest to the iSCSI hdr mbuf */
- /* XXX Assert: (mh->m_pkthdr.len + 4) < MHLEN */
+ /*
+ | Add header digest to the iSCSI hdr mbuf
+ | XXX Assert: (mh->m_pkthdr.len + 4) < MHLEN
+ */
bcopy(&pp->hdr_dig, (mh->m_data + mh->m_len), sizeof(int));
mh->m_len += sizeof(int);
mh->m_pkthdr.len += sizeof(int);
-#endif /* USE_MBUF */
}
-#ifdef USE_MBUF
mp = &mh->m_next;
-#endif /* USE_MBUF */
if(pq->pdu.ds) {
-#ifndef USE_MBUF
- iv->iov_base = pp->ds;
- iv->iov_len = pp->ds_len;
- while(iv->iov_len & 03) // the specs say it must be int alligned
- iv->iov_len++;
- iv++;
-#else /* USE_MBUF */
struct mbuf *md;
int off = 0;
len = pp->ds_len;
while(len & 03) // the specs say it must be int alligned
len++;
-
- while (len > 0) {
+ while(len > 0) {
int l;
- MGET(md, M_WAIT, MT_DATA);
- md->m_ext.ref_cnt = &nil_refcnt;
+ MGET(md, M_TRYWAIT, MT_DATA);
+ md->m_ext.ref_cnt = &ou_refcnt;
l = min(MCLBYTES, len);
- MEXTADD(md, pp->ds + off, l, nil_fn,
- pp->ds + off, NULL, 0, EXT_EXTREF);
+ debug(5, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l);
+ MEXTADD(md, pp->ds + off, l, ext_free, pp->ds + off, pq, 0, EXT_EXTREF);
md->m_len = l;
md->m_next = NULL;
mh->m_pkthdr.len += l;
*mp = md;
mp = &md->m_next;
-
len -= l;
off += l;
}
-#endif /* USE_MBUF */
}
if(sp->dataDigest) {
-#ifdef USE_MBUF
struct mbuf *me;
-#endif /* USE_MBUF */
pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0);
-#ifndef USE_MBUF
- iv->iov_base = &pp->ds_dig;
- iv->iov_len = sizeof(int);
- iv++;
-#else /* USE_MBUF */
- MGET(me, M_WAIT, MT_DATA);
+
+ MGET(me, M_TRYWAIT, MT_DATA);
me->m_len = sizeof(int);
MH_ALIGN(mh, sizeof(int));
bcopy(&pp->ds_dig, me->m_data, sizeof(int));
me->m_next = NULL;
-
mh->m_pkthdr.len += sizeof(int);
*mp = me;
-#endif /* USE_MBUF */
}
+ if((error = sosend(sp->soc, NULL, NULL, mh, 0, 0, sp->td)) != 0) {
+ sdebug(3, "error=%d", error);
+ return error;
+ }
+ sp->stats.nsent++;
+ getbintime(&sp->stats.t_sent);
+ return 0;
+}
+#else /* NO_USE_MBUF */
+int
+isc_sendPDU(isc_session_t *sp, pduq_t *pq)
+{
+ struct uio *uio = &pq->uio;
+ struct iovec *iv;
+ pdu_t *pp = &pq->pdu;
+ int len, error;
+
+ debug_called(8);
+
+ bzero(uio, sizeof(struct uio));
+ uio->uio_rw = UIO_WRITE;
+ uio->uio_segflg = UIO_SYSSPACE;
+ uio->uio_td = sp->td;
+ uio->uio_iov = iv = pq->iov;
+
+ iv->iov_base = &pp->ipdu;
+ iv->iov_len = sizeof(union ipdu_u);
+ uio->uio_resid = pq->len;
+ iv++;
+ if(sp->hdrDigest)
+ pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, sizeof(union ipdu_u), 0);
+ if(pp->ahs_len) {
+ iv->iov_base = pp->ahs;
+ iv->iov_len = pp->ahs_len;
+ iv++;
-#ifndef USE_MBUF
+ if(sp->hdrDigest)
+ pq->pdu.hdr_dig = sp->hdrDigest(&pp->ahs, pp->ahs_len, pq->pdu.hdr_dig);
+ }
+ if(sp->hdrDigest) {
+ debug(2, "hdr_dig=%x", pq->pdu.hdr_dig);
+ iv->iov_base = &pp->hdr_dig;
+ iv->iov_len = sizeof(int);
+ iv++;
+ }
+ if(pq->pdu.ds) {
+ iv->iov_base = pp->ds;
+ iv->iov_len = pp->ds_len;
+ while(iv->iov_len & 03) // the specs say it must be int alligned
+ iv->iov_len++;
+ iv++;
+ }
+ if(sp->dataDigest) {
+ pp->ds_dig = sp->dataDigest(pp->ds, pp->ds_len, 0);
+ iv->iov_base = &pp->ds_dig;
+ iv->iov_len = sizeof(int);
+ iv++;
+ }
uio->uio_iovcnt = iv - pq->iov;
sdebug(5, "opcode=%x iovcnt=%d uio_resid=%d itt=%x",
pp->ipdu.bhs.opcode, uio->uio_iovcnt, uio->uio_resid,
ntohl(pp->ipdu.bhs.itt));
sdebug(5, "sp=%p sp->soc=%p uio=%p sp->td=%p",
sp, sp->soc, uio, sp->td);
-
do {
len = uio->uio_resid;
error = sosend(sp->soc, NULL, uio, 0, 0, 0, sp->td);
@@ -243,20 +265,12 @@ isc_sendPDU(isc_session_t *sp, pduq_t *p
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list