|
|
6c64be |
From 2ff28eacd7c98d438a1864a09a124991ff2e1189 Mon Sep 17 00:00:00 2001
|
|
|
6c64be |
From: Mike Christie <michaelc@cs.wisc.edu>
|
|
|
6c64be |
Date: Tue, 28 May 2013 02:18:08 -0500
|
|
|
6c64be |
Subject: ISCSID: Added socket communication hooks for uip
|
|
|
6c64be |
|
|
|
6c64be |
From Eddie Wai:
|
|
|
6c64be |
|
|
|
6c64be |
This patch adds the communication path between iscsid->iscsiuio.
|
|
|
6c64be |
|
|
|
6c64be |
It utilizes the set_net_config func ptr in the iscsi_transport_template
|
|
|
6c64be |
to initiate the callbacks.
|
|
|
6c64be |
|
|
|
6c64be |
Two new files are introduced: uip_mgmt_ipc.h and uip_mgmt_ipc.c
|
|
|
6c64be |
|
|
|
6c64be |
Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
|
|
|
6c64be |
---
|
|
|
6c64be |
include/iscsi_err.h | 2 +
|
|
|
6c64be |
usr/Makefile | 3 +-
|
|
|
6c64be |
usr/initiator.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
6c64be |
usr/initiator.h | 4 ++
|
|
|
6c64be |
usr/initiator_common.c | 34 +++++++++++++++
|
|
|
6c64be |
usr/iscsid_req.c | 91 +++++++++++++++++++++++++++++++++++++++-
|
|
|
6c64be |
usr/iscsid_req.h | 2 +
|
|
|
6c64be |
usr/transport.c | 2 +
|
|
|
6c64be |
usr/transport.h | 3 ++
|
|
|
6c64be |
usr/uip_mgmt_ipc.c | 41 ++++++++++++++++++
|
|
|
6c64be |
usr/uip_mgmt_ipc.h | 73 ++++++++++++++++++++++++++++++++
|
|
|
6c64be |
11 files changed, 363 insertions(+), 4 deletions(-)
|
|
|
6c64be |
create mode 100644 usr/uip_mgmt_ipc.c
|
|
|
6c64be |
create mode 100644 usr/uip_mgmt_ipc.h
|
|
|
6c64be |
|
|
|
6c64be |
diff --git a/include/iscsi_err.h b/include/iscsi_err.h
|
|
|
6c64be |
index aabea4e..1139133 100644
|
|
|
6c64be |
--- a/include/iscsi_err.h
|
|
|
6c64be |
+++ b/include/iscsi_err.h
|
|
|
6c64be |
@@ -62,6 +62,8 @@ enum {
|
|
|
6c64be |
ISCSI_ERR_OP_NOT_SUPP = 27,
|
|
|
6c64be |
/* device or resource in use */
|
|
|
6c64be |
ISCSI_ERR_BUSY = 28,
|
|
|
6c64be |
+ /* Operation failed, but retrying layer may succeed */
|
|
|
6c64be |
+ ISCSI_ERR_AGAIN = 29,
|
|
|
6c64be |
|
|
|
6c64be |
/* Always last. Indicates end of error code space */
|
|
|
6c64be |
ISCSI_MAX_ERR_VAL,
|
|
|
6c64be |
diff --git a/usr/Makefile b/usr/Makefile
|
|
|
6c64be |
index 673b7f1..33b517c 100644
|
|
|
6c64be |
--- a/usr/Makefile
|
|
|
6c64be |
+++ b/usr/Makefile
|
|
|
6c64be |
@@ -40,7 +40,8 @@ SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o)
|
|
|
6c64be |
ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o iscsi_timer.o login.o log.o md5.o \
|
|
|
6c64be |
sha1.o iface.o idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o \
|
|
|
6c64be |
iscsi_net_util.o iscsid_req.o transport.o iser.o cxgbi.o be2iscsi.o \
|
|
|
6c64be |
- initiator_common.o iscsi_err.o $(IPC_OBJ) $(SYSDEPS_SRCS)
|
|
|
6c64be |
+ initiator_common.o iscsi_err.o uip_mgmt_ipc.o \
|
|
|
6c64be |
+ $(IPC_OBJ) $(SYSDEPS_SRCS)
|
|
|
6c64be |
# core initiator files
|
|
|
6c64be |
INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o kern_err_table.o
|
|
|
6c64be |
|
|
|
6c64be |
diff --git a/usr/initiator.c b/usr/initiator.c
|
|
|
6c64be |
index d475358..86df222 100644
|
|
|
6c64be |
--- a/usr/initiator.c
|
|
|
6c64be |
+++ b/usr/initiator.c
|
|
|
6c64be |
@@ -45,6 +45,7 @@
|
|
|
6c64be |
#include "iscsi_sysfs.h"
|
|
|
6c64be |
#include "iscsi_settings.h"
|
|
|
6c64be |
#include "iface.h"
|
|
|
6c64be |
+#include "host.h"
|
|
|
6c64be |
#include "sysdeps.h"
|
|
|
6c64be |
#include "iscsi_err.h"
|
|
|
6c64be |
#include "kern_err_table.h"
|
|
|
6c64be |
@@ -557,6 +558,48 @@ static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask)
|
|
|
6c64be |
return 0;
|
|
|
6c64be |
}
|
|
|
6c64be |
|
|
|
6c64be |
+static void iscsi_uio_poll_login_timedout(void *data)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ struct queue_task *qtask = data;
|
|
|
6c64be |
+ struct iscsi_conn *conn = qtask->conn;
|
|
|
6c64be |
+ iscsi_session_t *session = conn->session;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(3, "timeout waiting for UIO ...\n");
|
|
|
6c64be |
+ mgmt_ipc_write_rsp(qtask, ISCSI_ERR_TRANS_TIMEOUT);
|
|
|
6c64be |
+ conn_delete_timers(conn);
|
|
|
6c64be |
+ __session_destroy(session);
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
+static int iscsi_sched_uio_poll(queue_task_t *qtask)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ struct iscsi_conn *conn = qtask->conn;
|
|
|
6c64be |
+ struct iscsi_session *session = conn->session;
|
|
|
6c64be |
+ struct iscsi_transport *t = session->t;
|
|
|
6c64be |
+ struct iscsi_ev_context *ev_context;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ if (!t->template->set_net_config)
|
|
|
6c64be |
+ return 0;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ ev_context = iscsi_ev_context_get(conn, 0);
|
|
|
6c64be |
+ if (!ev_context) {
|
|
|
6c64be |
+ /* while reopening the recv pool should be full */
|
|
|
6c64be |
+ log_error("BUG: __session_conn_reopen could "
|
|
|
6c64be |
+ "not get conn context for recv.");
|
|
|
6c64be |
+ return -ENOMEM;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ ev_context->data = qtask;
|
|
|
6c64be |
+ conn->state = ISCSI_CONN_STATE_XPT_WAIT;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ iscsi_sched_ev_context(ev_context, conn, 0, EV_UIO_POLL);
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(3, "Setting login UIO poll timer %p timeout %d",
|
|
|
6c64be |
+ &conn->login_timer, conn->login_timeout);
|
|
|
6c64be |
+ actor_timer(&conn->login_timer, conn->login_timeout * 1000,
|
|
|
6c64be |
+ iscsi_uio_poll_login_timedout, qtask);
|
|
|
6c64be |
+ return -EAGAIN;
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
static void
|
|
|
6c64be |
__session_conn_reopen(iscsi_conn_t *conn, queue_task_t *qtask, int do_stop,
|
|
|
6c64be |
int redirected)
|
|
|
6c64be |
@@ -598,6 +641,11 @@ __session_conn_reopen(iscsi_conn_t *conn, queue_task_t *qtask, int do_stop,
|
|
|
6c64be |
if (!redirected)
|
|
|
6c64be |
session->reopen_cnt++;
|
|
|
6c64be |
|
|
|
6c64be |
+ /* uIP will needs to be re-triggered on the connection re-open */
|
|
|
6c64be |
+ if (iscsi_set_net_config(conn->session->t, conn->session,
|
|
|
6c64be |
+ &conn->session->nrec.iface) != 0)
|
|
|
6c64be |
+ goto queue_reopen;
|
|
|
6c64be |
+
|
|
|
6c64be |
if (iscsi_conn_connect(conn, qtask)) {
|
|
|
6c64be |
delay = ISCSI_CONN_ERR_REOPEN_DELAY;
|
|
|
6c64be |
goto queue_reopen;
|
|
|
6c64be |
@@ -1670,6 +1718,53 @@ failed_login:
|
|
|
6c64be |
|
|
|
6c64be |
}
|
|
|
6c64be |
|
|
|
6c64be |
+static void session_conn_uio_poll(void *data)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ struct iscsi_ev_context *ev_context = data;
|
|
|
6c64be |
+ iscsi_conn_t *conn = ev_context->conn;
|
|
|
6c64be |
+ struct iscsi_session *session = conn->session;
|
|
|
6c64be |
+ queue_task_t *qtask = ev_context->data;
|
|
|
6c64be |
+ int rc;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(4, "retrying uio poll");
|
|
|
6c64be |
+ rc = iscsi_set_net_config(session->t, session,
|
|
|
6c64be |
+ &conn->session->nrec.iface);
|
|
|
6c64be |
+ if (rc != 0) {
|
|
|
6c64be |
+ if (rc == ISCSI_ERR_AGAIN) {
|
|
|
6c64be |
+ ev_context->data = qtask;
|
|
|
6c64be |
+ iscsi_sched_ev_context(ev_context, conn, 2,
|
|
|
6c64be |
+ EV_UIO_POLL);
|
|
|
6c64be |
+ return;
|
|
|
6c64be |
+ } else {
|
|
|
6c64be |
+ log_error("session_conn_uio_poll() "
|
|
|
6c64be |
+ "connection failure [0x%x]", rc);
|
|
|
6c64be |
+ actor_delete(&conn->login_timer);
|
|
|
6c64be |
+ iscsi_login_eh(conn, qtask, ISCSI_ERR_INTERNAL);
|
|
|
6c64be |
+ iscsi_ev_context_put(ev_context);
|
|
|
6c64be |
+ return;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ iscsi_ev_context_put(ev_context);
|
|
|
6c64be |
+ actor_delete(&conn->login_timer);
|
|
|
6c64be |
+ log_debug(4, "UIO ready trying connect");
|
|
|
6c64be |
+
|
|
|
6c64be |
+ /* uIP is ready try to connect */
|
|
|
6c64be |
+ if (gettimeofday(&conn->initial_connect_time, NULL))
|
|
|
6c64be |
+ log_error("Could not get initial connect time. If "
|
|
|
6c64be |
+ "login errors iscsid may give up the initial "
|
|
|
6c64be |
+ "login early. You should manually login.");
|
|
|
6c64be |
+
|
|
|
6c64be |
+ conn->state = ISCSI_CONN_STATE_XPT_WAIT;
|
|
|
6c64be |
+ if (iscsi_conn_connect(conn, qtask)) {
|
|
|
6c64be |
+ int delay = ISCSI_CONN_ERR_REOPEN_DELAY;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(4, "Waiting %u seconds before trying to reconnect.\n",
|
|
|
6c64be |
+ delay);
|
|
|
6c64be |
+ queue_delayed_reopen(qtask, delay);
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
|
|
|
6c64be |
struct iscsi_conn *conn, unsigned long tmo,
|
|
|
6c64be |
int event)
|
|
|
6c64be |
@@ -1711,6 +1806,11 @@ static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
|
|
|
6c64be |
ev_context);
|
|
|
6c64be |
actor_schedule(&ev_context->actor);
|
|
|
6c64be |
break;
|
|
|
6c64be |
+ case EV_UIO_POLL:
|
|
|
6c64be |
+ actor_new(&ev_context->actor, session_conn_uio_poll,
|
|
|
6c64be |
+ ev_context);
|
|
|
6c64be |
+ actor_schedule(&ev_context->actor);
|
|
|
6c64be |
+ break;
|
|
|
6c64be |
case EV_CONN_LOGOUT_TIMER:
|
|
|
6c64be |
actor_timer(&ev_context->actor, tmo * 1000,
|
|
|
6c64be |
iscsi_logout_timedout, ev_context);
|
|
|
6c64be |
@@ -1844,7 +1944,17 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
|
|
|
6c64be |
conn = &session->conn[0];
|
|
|
6c64be |
qtask->conn = conn;
|
|
|
6c64be |
|
|
|
6c64be |
- if (iscsi_host_set_net_params(&rec->iface, session)) {
|
|
|
6c64be |
+ rc = iscsi_host_set_net_params(&rec->iface, session);
|
|
|
6c64be |
+ if (rc == ISCSI_ERR_AGAIN) {
|
|
|
6c64be |
+ iscsi_sched_uio_poll(qtask);
|
|
|
6c64be |
+ /*
|
|
|
6c64be |
+ * Cannot block iscsid, so caller is going to internally
|
|
|
6c64be |
+ * retry the operation.
|
|
|
6c64be |
+ */
|
|
|
6c64be |
+ qtask->rsp.command = MGMT_IPC_SESSION_LOGIN;
|
|
|
6c64be |
+ qtask->rsp.err = ISCSI_SUCCESS;
|
|
|
6c64be |
+ return ISCSI_SUCCESS;
|
|
|
6c64be |
+ } else if (rc) {
|
|
|
6c64be |
__session_destroy(session);
|
|
|
6c64be |
return ISCSI_ERR_LOGIN;
|
|
|
6c64be |
}
|
|
|
6c64be |
diff --git a/usr/initiator.h b/usr/initiator.h
|
|
|
6c64be |
index b45caab..d6dc02e 100644
|
|
|
6c64be |
--- a/usr/initiator.h
|
|
|
6c64be |
+++ b/usr/initiator.h
|
|
|
6c64be |
@@ -83,6 +83,7 @@ typedef enum iscsi_event_e {
|
|
|
6c64be |
EV_CONN_LOGOUT_TIMER,
|
|
|
6c64be |
EV_CONN_STOP,
|
|
|
6c64be |
EV_CONN_LOGIN,
|
|
|
6c64be |
+ EV_UIO_POLL,
|
|
|
6c64be |
} iscsi_event_e;
|
|
|
6c64be |
|
|
|
6c64be |
struct queue_task;
|
|
|
6c64be |
@@ -353,5 +354,8 @@ extern void iscsi_copy_operational_params(struct iscsi_conn *conn,
|
|
|
6c64be |
extern int iscsi_setup_authentication(struct iscsi_session *session,
|
|
|
6c64be |
struct iscsi_auth_config *auth_cfg);
|
|
|
6c64be |
extern int iscsi_setup_portal(struct iscsi_conn *conn, char *address, int port);
|
|
|
6c64be |
+extern int iscsi_set_net_config(struct iscsi_transport *t,
|
|
|
6c64be |
+ iscsi_session_t *session,
|
|
|
6c64be |
+ struct iface_rec *iface);
|
|
|
6c64be |
|
|
|
6c64be |
#endif /* INITIATOR_H */
|
|
|
6c64be |
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
|
|
|
6c64be |
index ef6820c..eb72795 100644
|
|
|
6c64be |
--- a/usr/initiator_common.c
|
|
|
6c64be |
+++ b/usr/initiator_common.c
|
|
|
6c64be |
@@ -562,6 +562,36 @@ TODO handle this
|
|
|
6c64be |
return 0;
|
|
|
6c64be |
}
|
|
|
6c64be |
|
|
|
6c64be |
+int iscsi_set_net_config(struct iscsi_transport *t, iscsi_session_t *session,
|
|
|
6c64be |
+ struct iface_rec *iface)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ if (t->template->set_net_config) {
|
|
|
6c64be |
+ /* uip needs the netdev name */
|
|
|
6c64be |
+ struct host_info hinfo;
|
|
|
6c64be |
+ int hostno, rc;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ /* this assumes that the netdev or hw address is going to be
|
|
|
6c64be |
+ set */
|
|
|
6c64be |
+ hostno = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
|
|
|
6c64be |
+ if (rc) {
|
|
|
6c64be |
+ log_debug(4, "Couldn't get host no.\n");
|
|
|
6c64be |
+ return rc;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ /* uip needs the netdev name */
|
|
|
6c64be |
+ if (!strlen(iface->netdev)) {
|
|
|
6c64be |
+ memset(&hinfo, 0, sizeof(hinfo));
|
|
|
6c64be |
+ hinfo.host_no = hostno;
|
|
|
6c64be |
+ iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
|
|
|
6c64be |
+ strcpy(iface->netdev, hinfo.iface.netdev);
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ return t->template->set_net_config(t, iface, session);
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ return 0;
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
int iscsi_host_set_net_params(struct iface_rec *iface,
|
|
|
6c64be |
struct iscsi_session *session)
|
|
|
6c64be |
{
|
|
|
6c64be |
@@ -600,6 +630,10 @@ int iscsi_host_set_net_params(struct iface_rec *iface,
|
|
|
6c64be |
log_warning("Could not brining up netdev %s. Try running "
|
|
|
6c64be |
"'ifup %s' first if login fails.", netdev, netdev);
|
|
|
6c64be |
|
|
|
6c64be |
+ rc = iscsi_set_net_config(t, session, iface);
|
|
|
6c64be |
+ if (rc != 0)
|
|
|
6c64be |
+ return rc;
|
|
|
6c64be |
+
|
|
|
6c64be |
rc = host_set_param(t, session->hostno,
|
|
|
6c64be |
ISCSI_HOST_PARAM_IPADDRESS,
|
|
|
6c64be |
iface->ipaddress, ISCSI_STRING);
|
|
|
6c64be |
diff --git a/usr/iscsid_req.c b/usr/iscsid_req.c
|
|
|
6c64be |
index 1c4678d..15f6353 100644
|
|
|
6c64be |
--- a/usr/iscsid_req.c
|
|
|
6c64be |
+++ b/usr/iscsid_req.c
|
|
|
6c64be |
@@ -22,6 +22,7 @@
|
|
|
6c64be |
#include <stdlib.h>
|
|
|
6c64be |
#include <string.h>
|
|
|
6c64be |
#include <errno.h>
|
|
|
6c64be |
+#include <fcntl.h>
|
|
|
6c64be |
#include <sys/un.h>
|
|
|
6c64be |
#include <sys/types.h>
|
|
|
6c64be |
#include <sys/socket.h>
|
|
|
6c64be |
@@ -32,6 +33,7 @@
|
|
|
6c64be |
#include "iscsi_util.h"
|
|
|
6c64be |
#include "config.h"
|
|
|
6c64be |
#include "iscsi_err.h"
|
|
|
6c64be |
+#include "uip_mgmt_ipc.h"
|
|
|
6c64be |
|
|
|
6c64be |
static void iscsid_startup(void)
|
|
|
6c64be |
{
|
|
|
6c64be |
@@ -54,7 +56,7 @@ static void iscsid_startup(void)
|
|
|
6c64be |
|
|
|
6c64be |
#define MAXSLEEP 128
|
|
|
6c64be |
|
|
|
6c64be |
-static int iscsid_connect(int *fd, int start_iscsid)
|
|
|
6c64be |
+static int ipc_connect(int *fd, char *unix_sock_name, int start_iscsid)
|
|
|
6c64be |
{
|
|
|
6c64be |
int nsec, addr_len;
|
|
|
6c64be |
struct sockaddr_un addr;
|
|
|
6c64be |
@@ -69,7 +71,8 @@ static int iscsid_connect(int *fd, int start_iscsid)
|
|
|
6c64be |
|
|
|
6c64be |
memset(&addr, 0, sizeof(addr));
|
|
|
6c64be |
addr.sun_family = AF_LOCAL;
|
|
|
6c64be |
- memcpy((char *) &addr.sun_path + 1, ISCSIADM_NAMESPACE, addr_len);
|
|
|
6c64be |
+ memcpy((char *) &addr.sun_path + 1, unix_sock_name,
|
|
|
6c64be |
+ strlen(unix_sock_name));
|
|
|
6c64be |
|
|
|
6c64be |
/*
|
|
|
6c64be |
* Trying to connect with exponential backoff
|
|
|
6c64be |
@@ -98,6 +101,11 @@ static int iscsid_connect(int *fd, int start_iscsid)
|
|
|
6c64be |
return ISCSI_ERR_ISCSID_NOTCONN;
|
|
|
6c64be |
}
|
|
|
6c64be |
|
|
|
6c64be |
+static int iscsid_connect(int *fd, int start_iscsid)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ return ipc_connect(fd, ISCSIADM_NAMESPACE, start_iscsid);
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
int iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid)
|
|
|
6c64be |
{
|
|
|
6c64be |
int err;
|
|
|
6c64be |
@@ -194,3 +202,82 @@ int iscsid_req_by_sid(iscsiadm_cmd_e cmd, int sid)
|
|
|
6c64be |
return err;
|
|
|
6c64be |
return iscsid_req_wait(cmd, fd);
|
|
|
6c64be |
}
|
|
|
6c64be |
+
|
|
|
6c64be |
+static int uip_connect(int *fd)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ return ipc_connect(fd, ISCSID_UIP_NAMESPACE, 0);
|
|
|
6c64be |
+}
|
|
|
6c64be |
+
|
|
|
6c64be |
+int uip_broadcast(void *buf, size_t buf_len)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ int err;
|
|
|
6c64be |
+ int fd;
|
|
|
6c64be |
+ iscsid_uip_rsp_t rsp;
|
|
|
6c64be |
+ int flags;
|
|
|
6c64be |
+ int count;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ err = uip_connect(&fd;;
|
|
|
6c64be |
+ if (err) {
|
|
|
6c64be |
+ log_warning("uIP daemon is not up");
|
|
|
6c64be |
+ return err;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(3, "connected to uIP daemon");
|
|
|
6c64be |
+
|
|
|
6c64be |
+ /* Send the data to uIP */
|
|
|
6c64be |
+ err = write(fd, buf, buf_len);
|
|
|
6c64be |
+ if (err != buf_len) {
|
|
|
6c64be |
+ log_error("got write error (%d/%d), daemon died?",
|
|
|
6c64be |
+ err, errno);
|
|
|
6c64be |
+ close(fd);
|
|
|
6c64be |
+ return ISCSI_ERR_ISCSID_COMM_ERR;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(3, "send iface config to uIP daemon");
|
|
|
6c64be |
+
|
|
|
6c64be |
+ /* Set the socket to a non-blocking read, this way if there are
|
|
|
6c64be |
+ * problems waiting for uIP, iscsid can bailout early */
|
|
|
6c64be |
+ flags = fcntl(fd, F_GETFL, 0);
|
|
|
6c64be |
+ if (flags == -1)
|
|
|
6c64be |
+ flags = 0;
|
|
|
6c64be |
+ err = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
|
|
6c64be |
+ if (err) {
|
|
|
6c64be |
+ log_error("could not set uip broadcast to non-blocking: %d",
|
|
|
6c64be |
+ errno);
|
|
|
6c64be |
+ close(fd);
|
|
|
6c64be |
+ return ISCSI_ERR;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+#define MAX_UIP_BROADCAST_READ_TRIES 3
|
|
|
6c64be |
+ for (count = 0; count < MAX_UIP_BROADCAST_READ_TRIES; count++) {
|
|
|
6c64be |
+ /* Wait for the response */
|
|
|
6c64be |
+ err = read(fd, &rsp, sizeof(rsp));
|
|
|
6c64be |
+ if (err == sizeof(rsp)) {
|
|
|
6c64be |
+ log_debug(3, "Broadcasted to uIP with length: %ld "
|
|
|
6c64be |
+ "cmd: 0x%x rsp: 0x%x\n", buf_len,
|
|
|
6c64be |
+ rsp.command, rsp.err);
|
|
|
6c64be |
+ err = 0;
|
|
|
6c64be |
+ break;
|
|
|
6c64be |
+ } else if ((err == -1) && (errno == EAGAIN)) {
|
|
|
6c64be |
+ usleep(250000);
|
|
|
6c64be |
+ continue;
|
|
|
6c64be |
+ } else {
|
|
|
6c64be |
+ log_error("Could not read response (%d/%d), daemon "
|
|
|
6c64be |
+ "died?", err, errno);
|
|
|
6c64be |
+ err = ISCSI_ERR;
|
|
|
6c64be |
+ break;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ if (count == MAX_UIP_BROADCAST_READ_TRIES) {
|
|
|
6c64be |
+ log_error("Could not broadcast to uIP after %d tries",
|
|
|
6c64be |
+ count);
|
|
|
6c64be |
+ err = ISCSI_ERR_AGAIN;
|
|
|
6c64be |
+ } else if (rsp.err != ISCSID_UIP_MGMT_IPC_DEVICE_UP) {
|
|
|
6c64be |
+ log_debug(3, "Device is not ready\n");
|
|
|
6c64be |
+ err = ISCSI_ERR_AGAIN;
|
|
|
6c64be |
+ }
|
|
|
6c64be |
+
|
|
|
6c64be |
+ close(fd);
|
|
|
6c64be |
+ return err;
|
|
|
6c64be |
+}
|
|
|
6c64be |
diff --git a/usr/iscsid_req.h b/usr/iscsid_req.h
|
|
|
6c64be |
index 68f5256..4fff43d 100644
|
|
|
6c64be |
--- a/usr/iscsid_req.h
|
|
|
6c64be |
+++ b/usr/iscsid_req.h
|
|
|
6c64be |
@@ -33,4 +33,6 @@ extern int iscsid_req_by_rec(int cmd, struct node_rec *rec);
|
|
|
6c64be |
extern int iscsid_req_by_sid_async(int cmd, int sid, int *fd);
|
|
|
6c64be |
extern int iscsid_req_by_sid(int cmd, int sid);
|
|
|
6c64be |
|
|
|
6c64be |
+extern int uip_broadcast(void *buf, size_t buf_len);
|
|
|
6c64be |
+
|
|
|
6c64be |
#endif
|
|
|
6c64be |
diff --git a/usr/transport.c b/usr/transport.c
|
|
|
6c64be |
index e6e3dfc..10212af 100644
|
|
|
6c64be |
--- a/usr/transport.c
|
|
|
6c64be |
+++ b/usr/transport.c
|
|
|
6c64be |
@@ -35,6 +35,7 @@
|
|
|
6c64be |
#include "log.h"
|
|
|
6c64be |
#include "iscsi_util.h"
|
|
|
6c64be |
#include "iscsi_sysfs.h"
|
|
|
6c64be |
+#include "uip_mgmt_ipc.h"
|
|
|
6c64be |
#include "cxgbi.h"
|
|
|
6c64be |
#include "be2iscsi.h"
|
|
|
6c64be |
#include "iser.h"
|
|
|
6c64be |
@@ -79,6 +80,7 @@ struct iscsi_transport_template bnx2i = {
|
|
|
6c64be |
.ep_connect = ktransport_ep_connect,
|
|
|
6c64be |
.ep_poll = ktransport_ep_poll,
|
|
|
6c64be |
.ep_disconnect = ktransport_ep_disconnect,
|
|
|
6c64be |
+ .set_net_config = uip_broadcast_params,
|
|
|
6c64be |
};
|
|
|
6c64be |
|
|
|
6c64be |
struct iscsi_transport_template be2iscsi = {
|
|
|
6c64be |
diff --git a/usr/transport.h b/usr/transport.h
|
|
|
6c64be |
index 672561b..5dcf872 100644
|
|
|
6c64be |
--- a/usr/transport.h
|
|
|
6c64be |
+++ b/usr/transport.h
|
|
|
6c64be |
@@ -35,6 +35,9 @@ struct iscsi_transport_template {
|
|
|
6c64be |
int (*ep_poll) (struct iscsi_conn *conn, int timeout_ms);
|
|
|
6c64be |
void (*ep_disconnect) (struct iscsi_conn *conn);
|
|
|
6c64be |
void (*create_conn) (struct iscsi_conn *conn);
|
|
|
6c64be |
+ int (*set_net_config) (struct iscsi_transport *t,
|
|
|
6c64be |
+ struct iface_rec *iface,
|
|
|
6c64be |
+ struct iscsi_session *session);
|
|
|
6c64be |
};
|
|
|
6c64be |
|
|
|
6c64be |
/* represents data path provider */
|
|
|
6c64be |
diff --git a/usr/uip_mgmt_ipc.c b/usr/uip_mgmt_ipc.c
|
|
|
6c64be |
new file mode 100644
|
|
|
6c64be |
index 0000000..f3074ee
|
|
|
6c64be |
--- /dev/null
|
|
|
6c64be |
+++ b/usr/uip_mgmt_ipc.c
|
|
|
6c64be |
@@ -0,0 +1,41 @@
|
|
|
6c64be |
+/*
|
|
|
6c64be |
+ * uIP iSCSI Daemon/Admin Management IPC
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
6c64be |
+ * it under the terms of the GNU General Public License as published
|
|
|
6c64be |
+ * by the Free Software Foundation; either version 2 of the License, or
|
|
|
6c64be |
+ * (at your option) any later version.
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
6c64be |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6c64be |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
6c64be |
+ * General Public License for more details.
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * See the file COPYING included with this distribution for more details.
|
|
|
6c64be |
+ */
|
|
|
6c64be |
+
|
|
|
6c64be |
+#include <string.h>
|
|
|
6c64be |
+
|
|
|
6c64be |
+#include "log.h"
|
|
|
6c64be |
+#include "uip_mgmt_ipc.h"
|
|
|
6c64be |
+#include "iscsid_req.h"
|
|
|
6c64be |
+
|
|
|
6c64be |
+int uip_broadcast_params(struct iscsi_transport *t,
|
|
|
6c64be |
+ struct iface_rec *iface,
|
|
|
6c64be |
+ struct iscsi_session *session)
|
|
|
6c64be |
+{
|
|
|
6c64be |
+ struct iscsid_uip_broadcast broadcast;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ log_debug(3, "broadcasting to uip\n");
|
|
|
6c64be |
+
|
|
|
6c64be |
+ memset(&broadcast, 0, sizeof(broadcast));
|
|
|
6c64be |
+
|
|
|
6c64be |
+ broadcast.header.command = ISCSID_UIP_IPC_GET_IFACE;
|
|
|
6c64be |
+ broadcast.header.payload_len = sizeof(*iface);
|
|
|
6c64be |
+
|
|
|
6c64be |
+ memcpy(&broadcast.u.iface_rec, iface, sizeof(*iface));
|
|
|
6c64be |
+
|
|
|
6c64be |
+ return uip_broadcast(&broadcast,
|
|
|
6c64be |
+ sizeof(iscsid_uip_broadcast_header_t) +
|
|
|
6c64be |
+ sizeof(*iface));
|
|
|
6c64be |
+}
|
|
|
6c64be |
diff --git a/usr/uip_mgmt_ipc.h b/usr/uip_mgmt_ipc.h
|
|
|
6c64be |
new file mode 100644
|
|
|
6c64be |
index 0000000..29a4769
|
|
|
6c64be |
--- /dev/null
|
|
|
6c64be |
+++ b/usr/uip_mgmt_ipc.h
|
|
|
6c64be |
@@ -0,0 +1,73 @@
|
|
|
6c64be |
+/*
|
|
|
6c64be |
+ * uIP iSCSI Daemon/Admin Management IPC
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
6c64be |
+ * it under the terms of the GNU General Public License as published
|
|
|
6c64be |
+ * by the Free Software Foundation; either version 2 of the License, or
|
|
|
6c64be |
+ * (at your option) any later version.
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
6c64be |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6c64be |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
6c64be |
+ * General Public License for more details.
|
|
|
6c64be |
+ *
|
|
|
6c64be |
+ * See the file COPYING included with this distribution for more details.
|
|
|
6c64be |
+ */
|
|
|
6c64be |
+#ifndef UIP_MGMT_IPC_H
|
|
|
6c64be |
+#define UIP_MGMT_IPC_H
|
|
|
6c64be |
+
|
|
|
6c64be |
+#include "types.h"
|
|
|
6c64be |
+#include "iscsi_if.h"
|
|
|
6c64be |
+#include "config.h"
|
|
|
6c64be |
+#include "mgmt_ipc.h"
|
|
|
6c64be |
+
|
|
|
6c64be |
+#include "initiator.h"
|
|
|
6c64be |
+#include "transport.h"
|
|
|
6c64be |
+
|
|
|
6c64be |
+#define ISCSID_UIP_NAMESPACE "ISCSID_UIP_ABSTRACT_NAMESPACE"
|
|
|
6c64be |
+
|
|
|
6c64be |
+typedef enum iscsid_uip_cmd {
|
|
|
6c64be |
+ ISCSID_UIP_IPC_UNKNOWN = 0,
|
|
|
6c64be |
+ ISCSID_UIP_IPC_GET_IFACE = 1,
|
|
|
6c64be |
+
|
|
|
6c64be |
+ __ISCSID_UIP_IPC_MAX_COMMAND
|
|
|
6c64be |
+} iscsid_uip_cmd_e;
|
|
|
6c64be |
+
|
|
|
6c64be |
+typedef struct iscsid_uip_broadcast_header {
|
|
|
6c64be |
+ iscsid_uip_cmd_e command;
|
|
|
6c64be |
+ uint32_t payload_len;
|
|
|
6c64be |
+} iscsid_uip_broadcast_header_t;
|
|
|
6c64be |
+
|
|
|
6c64be |
+/* IPC Request */
|
|
|
6c64be |
+typedef struct iscsid_uip_broadcast {
|
|
|
6c64be |
+ struct iscsid_uip_broadcast_header header;
|
|
|
6c64be |
+
|
|
|
6c64be |
+ union {
|
|
|
6c64be |
+ /* messages */
|
|
|
6c64be |
+ struct ipc_broadcast_iface_rec {
|
|
|
6c64be |
+ struct iface_rec rec;
|
|
|
6c64be |
+ } iface_rec;
|
|
|
6c64be |
+ } u;
|
|
|
6c64be |
+} iscsid_uip_broadcast_t;
|
|
|
6c64be |
+
|
|
|
6c64be |
+typedef enum iscsid_uip_mgmt_ipc_err {
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_OK = 0,
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_ERR = 1,
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_ERR_NOT_FOUND = 2,
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_ERR_NOMEM = 3,
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_DEVICE_UP = 4,
|
|
|
6c64be |
+ ISCSID_UIP_MGMT_IPC_DEVICE_INITIALIZING = 5,
|
|
|
6c64be |
+} iscsid_uip_mgmt_ipc_err_e;
|
|
|
6c64be |
+
|
|
|
6c64be |
+/* IPC Response */
|
|
|
6c64be |
+typedef struct iscsid_uip_mgmt_rsp {
|
|
|
6c64be |
+ iscsid_uip_cmd_e command;
|
|
|
6c64be |
+ iscsid_uip_mgmt_ipc_err_e err;
|
|
|
6c64be |
+} iscsid_uip_rsp_t;
|
|
|
6c64be |
+
|
|
|
6c64be |
+extern int uip_broadcast_params(struct iscsi_transport *t,
|
|
|
6c64be |
+ struct iface_rec *iface,
|
|
|
6c64be |
+ struct iscsi_session *session);
|
|
|
6c64be |
+
|
|
|
6c64be |
+
|
|
|
6c64be |
+#endif /* UIP_MGMT_IPC_H */
|
|
|
6c64be |
--
|
|
|
6c64be |
1.8.1.4
|
|
|
6c64be |
|