summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-04-17 10:54:00 -0500
committerMike Christie <michaelc@cs.wisc.edu>2009-05-10 21:52:04 -0500
commit695d44394051892f807ceab61af3d24fad05304b (patch)
tree24e1d1c1d963491c066d43e1dd33169b0779dbdb
parent2a9c6b5966d9453305fd1114550719981deb5548 (diff)
downloadopen-iscsi-695d44394051892f807ceab61af3d24fad05304b.tar.gz
bind offloaded connection to port
If we are using a offload card, then iface_set_param will match the iface info to a scsi_host and pass that info down to setup the net settings of the port (currently we just set the ip address). When we create the tcp/ip connection by calling ep_connect, we currently just go by the routing table info. I think there are two problems with this. 1. Some drivers do not have access to a routing table. Some drivers like qla4xxx do not even know about other ports. 2. If you have two initiator ports on the same subnet, the user may have set things up so that session1 was supposed to be run through port1. and session2 was supposed to be run through port2. It looks like we could end with both sessions going through one of the ports. Also how do you edit the routing table for the offload cards? You cannot use normal net tools like route can you? 3. If we set up hostA in the iface_set_param step, but then the routing info leads us to hostB, we are stuck. I did the attached patches to fix this. Basically we just pass down the scsi host we want to go through.
-rw-r--r--include/iscsi_if.h6
-rw-r--r--usr/initiator.c2
-rw-r--r--usr/initiator.h1
-rw-r--r--usr/netlink.c11
4 files changed, 17 insertions, 3 deletions
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index 81f92e8..0fb733d 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -52,6 +52,8 @@ enum iscsi_uevent_e {
ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17,
ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18,
+ ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 22,
+
/* up events */
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2,
@@ -131,6 +133,10 @@ struct iscsi_uevent {
struct msg_transport_connect {
uint32_t non_blocking;
} ep_connect;
+ struct msg_transport_connect_through_host {
+ uint32_t host_no;
+ uint32_t non_blocking;
+ } ep_connect_through_host;
struct msg_transport_poll {
uint64_t ep_handle;
uint32_t timeout_ms;
diff --git a/usr/initiator.c b/usr/initiator.c
index 8e4ea6b..4a56347 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -2074,7 +2074,7 @@ static int iface_set_param(struct iscsi_transport *t, struct iface_rec *iface,
hostno = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
if (rc)
return rc;
-
+ session->conn[0].bind_ep = 1;
session->hostno = hostno;
rc = __iscsi_host_set_param(t, session->hostno,
diff --git a/usr/initiator.h b/usr/initiator.h
index 682ebfc..5bcf4d1 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -152,6 +152,7 @@ typedef struct iscsi_conn {
* transports (eg iser) which does these ops from the kernel.
* In the case of TCP, it is just the transport_fd casted to u64. */
uint64_t transport_ep_handle;
+ int bind_ep;
/* timeouts */
int login_timeout;
diff --git a/usr/netlink.c b/usr/netlink.c
index 9172259..3d697ef 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -757,9 +757,17 @@ ktransport_ep_connect(iscsi_conn_t *conn, int non_blocking)
memset(setparam_buf, 0, NLM_SETPARAM_DEFAULT_MAX);
ev = (struct iscsi_uevent *)setparam_buf;
- ev->type = ISCSI_UEVENT_TRANSPORT_EP_CONNECT;
ev->transport_handle = conn->session->t->handle;
+ if (conn->bind_ep) {
+ ev->type = ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST;
+ ev->u.ep_connect_through_host.non_blocking = non_blocking;
+ ev->u.ep_connect_through_host.host_no = conn->session->hostno;
+ } else {
+ ev->type = ISCSI_UEVENT_TRANSPORT_EP_CONNECT;
+ ev->u.ep_connect.non_blocking = non_blocking;
+ }
+
if (dst_addr->sa_family == PF_INET)
addrlen = sizeof(struct sockaddr_in);
else if (dst_addr->sa_family == PF_INET6)
@@ -770,7 +778,6 @@ ktransport_ep_connect(iscsi_conn_t *conn, int non_blocking)
return -EINVAL;
}
memcpy(setparam_buf + sizeof(*ev), dst_addr, addrlen);
- ev->u.ep_connect.non_blocking = non_blocking;
if ((rc = __kipc_call(ev, sizeof(*ev) + addrlen)) < 0)
return rc;