diff options
author | scottl <scottl@FreeBSD.org> | 2008-11-25 07:17:11 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2008-11-25 07:17:11 +0000 |
commit | b0a070ce29c7f901038f9cfb6bfef9247d44075f (patch) | |
tree | 413f5b0f4f80fd3ec9f759e583d550deabbd83a4 /sbin | |
parent | 910037c59a4e6f6be1f74e35e4c5ed1e72c13895 (diff) | |
download | FreeBSD-src-b0a070ce29c7f901038f9cfb6bfef9247d44075f.zip FreeBSD-src-b0a070ce29c7f901038f9cfb6bfef9247d44075f.tar.gz |
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
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/iscontrol/auth_subr.c | 3 | ||||
-rw-r--r-- | sbin/iscontrol/config.c | 2 | ||||
-rw-r--r-- | sbin/iscontrol/fsm.c | 97 | ||||
-rw-r--r-- | sbin/iscontrol/iscontrol.8 | 2 | ||||
-rw-r--r-- | sbin/iscontrol/iscontrol.c | 15 | ||||
-rw-r--r-- | sbin/iscontrol/iscontrol.h | 9 | ||||
-rw-r--r-- | sbin/iscontrol/iscsi.conf.5 | 2 | ||||
-rw-r--r-- | sbin/iscontrol/login.c | 15 | ||||
-rw-r--r-- | sbin/iscontrol/misc.c | 2 | ||||
-rw-r--r-- | sbin/iscontrol/pdu.c | 3 |
10 files changed, 91 insertions, 59 deletions
diff --git a/sbin/iscontrol/auth_subr.c b/sbin/iscontrol/auth_subr.c index 8381687..06c0ee5 100644 --- a/sbin/iscontrol/auth_subr.c +++ b/sbin/iscontrol/auth_subr.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2007 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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) diff --git a/sbin/iscontrol/config.c b/sbin/iscontrol/config.c index 409ed2c..d6d250d 100644 --- a/sbin/iscontrol/config.c +++ b/sbin/iscontrol/config.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2007 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il> * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sbin/iscontrol/fsm.c b/sbin/iscontrol/fsm.c index 6a1c529..443ebca 100644 --- a/sbin/iscontrol/fsm.c +++ b/sbin/iscontrol/fsm.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2007 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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@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@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; diff --git a/sbin/iscontrol/iscontrol.8 b/sbin/iscontrol/iscontrol.8 index 4ae0d3f..aaa126d 100644 --- a/sbin/iscontrol/iscontrol.8 +++ b/sbin/iscontrol/iscontrol.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007 Daniel Braniss <danny@cs.huji.ac.il> +.\" Copyright (c) 2007-2008 Daniel Braniss <danny@cs.huji.ac.il> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without diff --git a/sbin/iscontrol/iscontrol.c b/sbin/iscontrol/iscontrol.c index d5d5929..8cfa5fa 100644 --- a/sbin/iscontrol/iscontrol.c +++ b/sbin/iscontrol/iscontrol.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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); } diff --git a/sbin/iscontrol/iscontrol.h b/sbin/iscontrol/iscontrol.h index c93c35a..a89d7af 100644 --- a/sbin/iscontrol/iscontrol.h +++ b/sbin/iscontrol/iscontrol.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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; diff --git a/sbin/iscontrol/iscsi.conf.5 b/sbin/iscontrol/iscsi.conf.5 index 3388746..2edcd35 100644 --- a/sbin/iscontrol/iscsi.conf.5 +++ b/sbin/iscontrol/iscsi.conf.5 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007 Daniel Braniss <danny@cs.huji.ac.il> +.\" Copyright (c) 2007-2008 Daniel Braniss <danny@cs.huji.ac.il> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without diff --git a/sbin/iscontrol/login.c b/sbin/iscontrol/login.c index 44ea889..ec17f21 100644 --- a/sbin/iscontrol/login.c +++ b/sbin/iscontrol/login.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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); diff --git a/sbin/iscontrol/misc.c b/sbin/iscontrol/misc.c index 4ac3f0a..9634a1b 100644 --- a/sbin/iscontrol/misc.c +++ b/sbin/iscontrol/misc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il> * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sbin/iscontrol/pdu.c b/sbin/iscontrol/pdu.c index 18dfdfc..980d20a 100644 --- a/sbin/iscontrol/pdu.c +++ b/sbin/iscontrol/pdu.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> + * Copyright (c) 2005-2008 Daniel Braniss <danny@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) |