summaryrefslogtreecommitdiff
path: root/sbin/iscontrol
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2008-11-25 07:17:11 +0000
committerScott Long <scottl@FreeBSD.org>2008-11-25 07:17:11 +0000
commit3f3137fee5946f0c64456dfa13a6bcd17f8771bb (patch)
tree413f5b0f4f80fd3ec9f759e583d550deabbd83a4 /sbin/iscontrol
parentdfabb37be2c5516283add90b07ad43b44a3b840f (diff)
downloadsrc-test2-3f3137fee5946f0c64456dfa13a6bcd17f8771bb.tar.gz
src-test2-3f3137fee5946f0c64456dfa13a6bcd17f8771bb.zip
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
Notes
Notes: svn path=/head/; revision=185289
Diffstat (limited to 'sbin/iscontrol')
-rw-r--r--sbin/iscontrol/auth_subr.c3
-rw-r--r--sbin/iscontrol/config.c2
-rw-r--r--sbin/iscontrol/fsm.c97
-rw-r--r--sbin/iscontrol/iscontrol.82
-rw-r--r--sbin/iscontrol/iscontrol.c15
-rw-r--r--sbin/iscontrol/iscontrol.h9
-rw-r--r--sbin/iscontrol/iscsi.conf.52
-rw-r--r--sbin/iscontrol/login.c15
-rw-r--r--sbin/iscontrol/misc.c2
-rw-r--r--sbin/iscontrol/pdu.c3
10 files changed, 91 insertions, 59 deletions
diff --git a/sbin/iscontrol/auth_subr.c b/sbin/iscontrol/auth_subr.c
index 8381687fca51..06c0ee57fd73 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 409ed2c5680d..d6d250d59332 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 6a1c529a2432..443ebcac6b2e 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 4ae0d3f1d8f2..aaa126dc06ec 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 d5d5929188bd..8cfa5fa469c0 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 c93c35af8049..a89d7afd5f30 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 3388746822c5..2edcd35742a2 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 44ea889a329e..ec17f211573a 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 4ac3f0a349f7..9634a1bb023c 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 18dfdfc03b56..980d20a41049 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)