summaryrefslogtreecommitdiff
path: root/usr/initiator.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-01-29 22:50:43 -0600
committerMike Christie <michaelc@cs.wisc.edu>2011-01-31 21:52:18 -0600
commit9dca10af955255f9806942cb3370d4a86660a655 (patch)
tree5fb8e7f4ada8989fec2c815de7044ea2b75a281a /usr/initiator.c
parent44cc856b2115e6cd1221fe061b08b23d3cf188c8 (diff)
downloadopen-iscsi-9dca10af955255f9806942cb3370d4a86660a655.tar.gz
Use pass through interface for sendtargets (take4) Currenly offload cards like bnx2i, be2iscsi, cxgb3i must use a normal eth for discovery. This patch allows us to do discovery using the iscsi class passthrough interface.
Note1 that the dirver must set the CAP_TEXT_NEGO setting, which might requires scsi-misc. Limitations of patch: - MaxRecvDataSegmentLength is limited to 8K for discovery sessions when offload is used. V3: - bug fixes from Eddie Wai to call start conn after we have logged in. Fixed set param not setting all settings. Misc cleanups. V4: - fix iscsistart segfault due to missing initialization.
Diffstat (limited to 'usr/initiator.c')
-rw-r--r--usr/initiator.c759
1 files changed, 118 insertions, 641 deletions
diff --git a/usr/initiator.c b/usr/initiator.c
index 70c873b..81e407f 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -53,31 +53,17 @@
#define PROC_DIR "/proc"
static void iscsi_login_timedout(void *data);
+static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
+ struct iscsi_conn *conn, unsigned long tmo,
+ int event);
-/*
- * calculate parameter's padding
- */
-static unsigned int
-__padding(unsigned int param)
-{
- int pad;
-
- pad = param & 3;
- if (pad) {
- pad = 4 - pad;
- log_debug(1, "parameter's value %d padded to %d bytes\n",
- param, param + pad);
- }
- return param + pad;
-}
-
-static int iscsi_conn_context_alloc(iscsi_conn_t *conn)
+static int iscsi_ev_context_alloc(iscsi_conn_t *conn)
{
int i;
for (i = 0; i < CONTEXT_POOL_MAX; i++) {
conn->context_pool[i] = calloc(1,
- sizeof(struct iscsi_conn_context) +
+ sizeof(struct iscsi_ev_context) +
ipc->ctldev_bufmax);
if (!conn->context_pool[i]) {
int j;
@@ -91,7 +77,7 @@ static int iscsi_conn_context_alloc(iscsi_conn_t *conn)
return 0;
}
-static void iscsi_conn_context_free(iscsi_conn_t *conn)
+static void iscsi_ev_context_free(iscsi_conn_t *conn)
{
int i;
@@ -107,10 +93,10 @@ static void iscsi_conn_context_free(iscsi_conn_t *conn)
}
}
-struct iscsi_conn_context *iscsi_conn_context_get(iscsi_conn_t *conn,
- int ev_size)
+static struct iscsi_ev_context *
+iscsi_ev_context_get(iscsi_conn_t *conn, int ev_size)
{
- struct iscsi_conn_context *conn_context;
+ struct iscsi_ev_context *ev_context;
int i;
if (ev_size > ipc->ctldev_bufmax)
@@ -121,26 +107,26 @@ struct iscsi_conn_context *iscsi_conn_context_get(iscsi_conn_t *conn,
continue;
if (!conn->context_pool[i]->allocated) {
- conn_context = conn->context_pool[i];
+ ev_context = conn->context_pool[i];
- memset(&conn_context->actor, 0,
+ memset(&ev_context->actor, 0,
sizeof(struct actor));
- conn_context->allocated = 1;
+ ev_context->allocated = 1;
/* some callers abuse this pointer */
- conn_context->data = (void *)conn_context +
- sizeof(struct iscsi_conn_context);
- log_debug(7, "get conn context %p",
- &conn_context->actor);
- return conn_context;
+ ev_context->data = (void *)ev_context +
+ sizeof(struct iscsi_ev_context);
+ log_debug(7, "get ev context %p",
+ &ev_context->actor);
+ return ev_context;
}
}
return NULL;
}
-void iscsi_conn_context_put(struct iscsi_conn_context *conn_context)
+static void iscsi_ev_context_put(struct iscsi_ev_context *ev_context)
{
- log_debug(7, "put conn context %p", &conn_context->actor);
- conn_context->allocated = 0;
+ log_debug(7, "put ev context %p", &ev_context->actor);
+ ev_context->allocated = 0;
}
static void session_online_devs(int host_no, int sid)
@@ -250,183 +236,6 @@ __check_iscsi_status_class(iscsi_session_t *session, int cid,
return CONN_LOGIN_FAILED;
}
-static void
-__setup_authentication(iscsi_session_t *session,
- struct iscsi_auth_config *auth_cfg)
-{
- /* if we have any incoming credentials, we insist on authenticating
- * the target or not logging in at all
- */
- if (auth_cfg->username_in[0]
- || auth_cfg->password_in_length) {
- /* sanity check the config */
- if (auth_cfg->password_length == 0) {
- log_debug(1,
- "node record has incoming "
- "authentication credentials but has no outgoing "
- "credentials configured, exiting");
- return;
- }
- session->bidirectional_auth = 1;
- } else {
- /* no or 1-way authentication */
- session->bidirectional_auth = 0;
- }
-
- /* copy in whatever credentials we have */
- strlcpy(session->username, auth_cfg->username,
- sizeof (session->username));
- session->username[sizeof (session->username) - 1] = '\0';
- if ((session->password_length = auth_cfg->password_length))
- memcpy(session->password, auth_cfg->password,
- session->password_length);
-
- strlcpy(session->username_in, auth_cfg->username_in,
- sizeof (session->username_in));
- session->username_in[sizeof (session->username_in) - 1] = '\0';
- if ((session->password_in_length =
- auth_cfg->password_in_length))
- memcpy(session->password_in, auth_cfg->password_in,
- session->password_in_length);
-
- if (session->password_length || session->password_in_length) {
- /* setup the auth buffers */
- session->auth_buffers[0].address = &session->auth_client_block;
- session->auth_buffers[0].length =
- sizeof (session->auth_client_block);
- session->auth_buffers[1].address =
- &session->auth_recv_string_block;
- session->auth_buffers[1].length =
- sizeof (session->auth_recv_string_block);
-
- session->auth_buffers[2].address =
- &session->auth_send_string_block;
- session->auth_buffers[2].length =
- sizeof (session->auth_send_string_block);
-
- session->auth_buffers[3].address =
- &session->auth_recv_binary_block;
- session->auth_buffers[3].length =
- sizeof (session->auth_recv_binary_block);
-
- session->auth_buffers[4].address =
- &session->auth_send_binary_block;
- session->auth_buffers[4].length =
- sizeof (session->auth_send_binary_block);
-
- session->num_auth_buffers = 5;
- log_debug(6, "authentication setup complete...");
- } else {
- session->num_auth_buffers = 0;
- log_debug(6, "no authentication configured...");
- }
-}
-
-static int
-setup_portal(iscsi_conn_t *conn, conn_rec_t *conn_rec)
-{
- char port[NI_MAXSERV];
-
- sprintf(port, "%d", conn_rec->port);
- if (resolve_address(conn_rec->address, port, &conn->saddr)) {
- log_error("cannot resolve host name %s",
- conn_rec->address);
- return EINVAL;
- }
- conn->failback_saddr = conn->saddr;
-
- getnameinfo((struct sockaddr *)&conn->saddr, sizeof(conn->saddr),
- conn->host, sizeof(conn->host), NULL, 0, NI_NUMERICHOST);
- log_debug(4, "resolved %s to %s", conn_rec->address, conn->host);
- return 0;
-}
-
-static void
-iscsi_copy_operational_params(iscsi_conn_t *conn)
-{
- iscsi_session_t *session = conn->session;
- conn_rec_t *conn_rec = &session->nrec.conn[conn->id];
- node_rec_t *rec = &session->nrec;
-
- conn->hdrdgst_en = conn_rec->iscsi.HeaderDigest;
- conn->datadgst_en = conn_rec->iscsi.DataDigest;
-
- conn->max_recv_dlength =
- __padding(conn_rec->iscsi.MaxRecvDataSegmentLength);
- if (conn->max_recv_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN ||
- conn->max_recv_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) {
- log_error("Invalid iscsi.MaxRecvDataSegmentLength. Must be "
- "within %u and %u. Setting to %u\n",
- ISCSI_MIN_MAX_RECV_SEG_LEN,
- ISCSI_MAX_MAX_RECV_SEG_LEN,
- DEF_INI_MAX_RECV_SEG_LEN);
- conn_rec->iscsi.MaxRecvDataSegmentLength =
- DEF_INI_MAX_RECV_SEG_LEN;
- conn->max_recv_dlength = DEF_INI_MAX_RECV_SEG_LEN;
- }
-
- /* zero indicates to use the target's value */
- conn->max_xmit_dlength =
- __padding(conn_rec->iscsi.MaxXmitDataSegmentLength);
- if (conn->max_xmit_dlength == 0)
- conn->max_xmit_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
- if (conn->max_xmit_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN ||
- conn->max_xmit_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) {
- log_error("Invalid iscsi.MaxXmitDataSegmentLength. Must be "
- "within %u and %u. Setting to %u\n",
- ISCSI_MIN_MAX_RECV_SEG_LEN,
- ISCSI_MAX_MAX_RECV_SEG_LEN,
- DEF_INI_MAX_RECV_SEG_LEN);
- conn_rec->iscsi.MaxXmitDataSegmentLength =
- DEF_INI_MAX_RECV_SEG_LEN;
- conn->max_xmit_dlength = DEF_INI_MAX_RECV_SEG_LEN;
- }
-
- /* session's operational parameters */
- session->initial_r2t_en = rec->session.iscsi.InitialR2T;
- session->imm_data_en = rec->session.iscsi.ImmediateData;
- session->first_burst = __padding(rec->session.iscsi.FirstBurstLength);
- /*
- * some targets like netapp fail the login if sent bad first_burst
- * and max_burst lens, even when immediate data=no and
- * initial r2t = Yes, so we always check the user values.
- */
- if (session->first_burst < ISCSI_MIN_FIRST_BURST_LEN ||
- session->first_burst > ISCSI_MAX_FIRST_BURST_LEN) {
- log_error("Invalid iscsi.FirstBurstLength of %u. Must be "
- "within %u and %u. Setting to %u\n",
- session->first_burst,
- ISCSI_MIN_FIRST_BURST_LEN,
- ISCSI_MAX_FIRST_BURST_LEN,
- DEF_INI_FIRST_BURST_LEN);
- rec->session.iscsi.FirstBurstLength = DEF_INI_FIRST_BURST_LEN;
- session->first_burst = DEF_INI_FIRST_BURST_LEN;
- }
-
- session->max_burst = __padding(rec->session.iscsi.MaxBurstLength);
- if (session->max_burst < ISCSI_MIN_MAX_BURST_LEN ||
- session->max_burst > ISCSI_MAX_MAX_BURST_LEN) {
- log_error("Invalid iscsi.MaxBurstLength of %u. Must be "
- "within %u and %u. Setting to %u\n",
- session->max_burst, ISCSI_MIN_MAX_BURST_LEN,
- ISCSI_MAX_MAX_BURST_LEN, DEF_INI_MAX_BURST_LEN);
- rec->session.iscsi.MaxBurstLength = DEF_INI_MAX_BURST_LEN;
- session->max_burst = DEF_INI_MAX_BURST_LEN;
- }
-
- if (session->first_burst > session->max_burst) {
- log_error("Invalid iscsi.FirstBurstLength of %u. Must be "
- "less than iscsi.MaxBurstLength. Setting to %u\n",
- session->first_burst, session->max_burst);
- rec->session.iscsi.FirstBurstLength = session->max_burst;
- session->first_burst = session->max_burst;
- }
-
- session->def_time2wait = rec->session.iscsi.DefaultTime2Wait;
- session->def_time2retain = rec->session.iscsi.DefaultTime2Retain;
- session->erl = rec->session.iscsi.ERL;
-}
-
static int
__session_conn_create(iscsi_session_t *session, int cid)
{
@@ -434,7 +243,7 @@ __session_conn_create(iscsi_session_t *session, int cid)
conn_rec_t *conn_rec = &session->nrec.conn[cid];
int err;
- if (iscsi_conn_context_alloc(conn)) {
+ if (iscsi_ev_context_alloc(conn)) {
log_error("cannot allocate context_pool for conn cid %d", cid);
return ENOMEM;
}
@@ -486,14 +295,15 @@ __session_conn_create(iscsi_session_t *session, int cid)
conn->noop_out_interval = DEF_NOOP_OUT_INTERVAL;
}
- iscsi_copy_operational_params(conn);
+ iscsi_copy_operational_params(conn, &session->nrec.session.iscsi,
+ &conn_rec->iscsi);
/* TCP options */
conn->tcp_window_size = conn_rec->tcp.window_size;
/* FIXME: type_of_service */
/* resolve the string address to an IP address */
- err = setup_portal(conn, conn_rec);
+ err = iscsi_setup_portal(conn, conn_rec->address, conn_rec->port);
if (err)
return err;
return 0;
@@ -506,7 +316,7 @@ session_release(iscsi_session_t *session)
if (session->target_alias)
free(session->target_alias);
- iscsi_conn_context_free(&session->conn[0]);
+ iscsi_ev_context_free(&session->conn[0]);
free(session);
}
@@ -524,11 +334,10 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
log_debug(2, "Allocted session %p", session);
INIT_LIST_HEAD(&session->list);
- /* opened at daemon load time (iscsid.c) */
- session->ctrl_fd = control_fd;
session->t = t;
session->reopen_qtask.mgmt_ipc_fd = -1;
session->id = -1;
+ session->use_ipc = 1;
/* save node record. we might need it for redirection */
memcpy(&session->nrec, rec, sizeof(node_rec_t));
@@ -570,7 +379,7 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
session->isid[5] = 0;
/* setup authentication variables for the session*/
- __setup_authentication(session, &rec->session.auth);
+ iscsi_setup_authentication(session, &rec->session.auth);
session->param_mask = ~0ULL;
if (!(t->caps & CAP_MULTI_R2T))
@@ -601,18 +410,18 @@ __session_create(node_rec_t *rec, struct iscsi_transport *t)
static void iscsi_flush_context_pool(struct iscsi_session *session)
{
- struct iscsi_conn_context *conn_context;
+ struct iscsi_ev_context *ev_context;
struct iscsi_conn *conn = &session->conn[0];
int i;
for (i = 0; i < CONTEXT_POOL_MAX; i++) {
- conn_context = conn->context_pool[i];
- if (!conn_context)
+ ev_context = conn->context_pool[i];
+ if (!ev_context)
continue;
- if (conn_context->allocated) {
+ if (ev_context->allocated) {
actor_delete(&(conn->context_pool[i]->actor));
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
}
}
}
@@ -709,17 +518,17 @@ queue_delayed_reopen(queue_task_t *qtask, int delay)
static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask)
{
- struct iscsi_conn_context *conn_context;
+ struct iscsi_ev_context *ev_context;
int rc;
- conn_context = iscsi_conn_context_get(conn, 0);
- if (!conn_context) {
+ ev_context = iscsi_ev_context_get(conn, 0);
+ if (!ev_context) {
/* while reopening the recv pool should be full */
log_error("BUG: __session_conn_reopen could not get conn "
"context for recv.");
return ENOMEM;
}
- conn_context->data = qtask;
+ ev_context->data = qtask;
rc = conn->session->t->template->ep_connect(conn, 1);
if (rc < 0 && errno != EINPROGRESS) {
@@ -732,11 +541,11 @@ static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask)
log_error("cannot make a connection to %s:%s (%d,%d)",
conn->host, serv, rc, errno);
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
return ENOTCONN;
}
- iscsi_sched_conn_context(conn_context, conn, 0, EV_CONN_POLL);
+ iscsi_sched_ev_context(ev_context, conn, 0, EV_CONN_POLL);
log_debug(3, "Setting login timer %p timeout %d", &conn->login_timer,
conn->login_timeout);
actor_timer(&conn->login_timer, conn->login_timeout * 1000,
@@ -1020,15 +829,15 @@ __conn_error_handle(iscsi_session_t *session, iscsi_conn_t *conn)
static void session_conn_error(void *data)
{
- struct iscsi_conn_context *conn_context = data;
- enum iscsi_err error = *(enum iscsi_err *)conn_context->data;
- iscsi_conn_t *conn = conn_context->conn;
+ struct iscsi_ev_context *ev_context = data;
+ enum iscsi_err error = *(enum iscsi_err *)ev_context->data;
+ iscsi_conn_t *conn = ev_context->conn;
iscsi_session_t *session = conn->session;
log_warning("Kernel reported iSCSI connection %d:%d error (%d) "
"state (%d)", session->id, conn->id, error,
conn->state);
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
switch (error) {
case ISCSI_ERR_INVALID_HOST:
@@ -1136,17 +945,6 @@ static void conn_send_nop_out(void *data)
&conn->nop_out_timer, conn->noop_out_timeout);
}
-static void
-print_param_value(enum iscsi_param param, void *value, int type)
-{
- log_debug(3, "set operational parameter %d to:", param);
-
- if (type == ISCSI_STRING)
- log_debug(3, "%s", value ? (char *)value : "NULL");
- else
- log_debug(3, "%u", *(uint32_t *)value);
-}
-
void free_initiator(void)
{
struct iscsi_transport *t;
@@ -1188,292 +986,23 @@ static void session_scan_host(struct iscsi_session *session, int hostno,
mgmt_ipc_write_rsp(qtask, MGMT_IPC_ERR_INTERNAL);
}
-static int __iscsi_host_set_param(struct iscsi_transport *t,
- int host_no, int param, char *value,
- int type)
-{
- int rc;
-
- rc = ipc->set_host_param(t->handle, host_no, param, value, type);
- /* 2.6.20 and below returns EINVAL */
- if (rc && rc != -ENOSYS && rc != -EINVAL) {
- log_error("can't set operational parameter %d for "
- "host %d, retcode %d (%d)", param, host_no,
- rc, errno);
- return rc;
- }
- return 0;
-}
-
-mgmt_ipc_err_e iscsi_host_set_param(int host_no, int param, char *value)
-{
- struct iscsi_transport *t;
-
- t = iscsi_sysfs_get_transport_by_hba(host_no);
- if (!t)
- return MGMT_IPC_ERR_TRANS_FAILURE;
- if (__iscsi_host_set_param(t, host_no, param, value, ISCSI_STRING))
- return MGMT_IPC_ERR;
- return MGMT_IPC_OK;
-}
-
-#define MAX_SESSION_PARAMS 32
-#define MAX_HOST_PARAMS 3
-
static void
setup_full_feature_phase(iscsi_conn_t *conn)
{
iscsi_session_t *session = conn->session;
iscsi_login_context_t *c = &conn->login_context;
- int i, rc;
- uint32_t one = 1, zero = 0;
- struct hostparam {
- int param;
- int type;
- void *value;
- int set;
- } hosttbl[MAX_HOST_PARAMS] = {
- {
- .param = ISCSI_HOST_PARAM_NETDEV_NAME,
- .value = session->nrec.iface.netdev,
- .type = ISCSI_STRING,
- .set = 1,
- }, {
- .param = ISCSI_HOST_PARAM_HWADDRESS,
- .value = session->nrec.iface.hwaddress,
- .type = ISCSI_STRING,
- .set = 1,
- }, {
- .param = ISCSI_HOST_PARAM_INITIATOR_NAME,
- .value = session->initiator_name,
- .type = ISCSI_STRING,
- .set = 0,
- },
- };
- struct connparam {
- int param;
- int type;
- void *value;
- int conn_only;
- } conntbl[MAX_SESSION_PARAMS] = {
- {
- .param = ISCSI_PARAM_MAX_RECV_DLENGTH,
- .value = &conn->max_recv_dlength,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_MAX_XMIT_DLENGTH,
- .value = &conn->max_xmit_dlength,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_HDRDGST_EN,
- .value = &conn->hdrdgst_en,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_DATADGST_EN,
- .value = &conn->datadgst_en,
- .type = ISCSI_INT,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_INITIAL_R2T_EN,
- .value = &session->initial_r2t_en,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_MAX_R2T,
- .value = &one, /* FIXME: session->max_r2t */
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_IMM_DATA_EN,
- .value = &session->imm_data_en,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_FIRST_BURST,
- .value = &session->first_burst,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_MAX_BURST,
- .value = &session->max_burst,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_PDU_INORDER_EN,
- .value = &session->pdu_inorder_en,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param =ISCSI_PARAM_DATASEQ_INORDER_EN,
- .value = &session->dataseq_inorder_en,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_ERL,
- .value = &zero, /* FIXME: session->erl */
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_IFMARKER_EN,
- .value = &zero,/* FIXME: session->ifmarker_en */
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_OFMARKER_EN,
- .value = &zero,/* FIXME: session->ofmarker_en */
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_EXP_STATSN,
- .value = &conn->exp_statsn,
- .type = ISCSI_INT,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_TARGET_NAME,
- .conn_only = 0,
- .type = ISCSI_STRING,
- .value = session->target_name,
- }, {
- .param = ISCSI_PARAM_TPGT,
- .value = &session->portal_group_tag,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_PERSISTENT_ADDRESS,
- .value = session->nrec.conn[conn->id].address,
- .type = ISCSI_STRING,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_PERSISTENT_PORT,
- .value = &session->nrec.conn[conn->id].port,
- .type = ISCSI_INT,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_SESS_RECOVERY_TMO,
- .value = &session->replacement_timeout,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_USERNAME,
- .value = session->username,
- .type = ISCSI_STRING,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_USERNAME_IN,
- .value = session->username_in,
- .type = ISCSI_STRING,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_PASSWORD,
- .value = session->password,
- .type = ISCSI_STRING,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_PASSWORD_IN,
- .value = session->password_in,
- .type = ISCSI_STRING,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_FAST_ABORT,
- .value = &session->fast_abort,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_ABORT_TMO,
- .value = &session->abort_timeout,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_LU_RESET_TMO,
- .value = &session->lu_reset_timeout,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_TGT_RESET_TMO,
- .value = &session->tgt_reset_timeout,
- .type = ISCSI_INT,
- .conn_only = 0,
- }, {
- .param = ISCSI_PARAM_PING_TMO,
- .value = &conn->noop_out_timeout,
- .type = ISCSI_INT,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_RECV_TMO,
- .value = &conn->noop_out_interval,
- .type = ISCSI_INT,
- .conn_only = 1,
- }, {
- .param = ISCSI_PARAM_IFACE_NAME,
- .value = session->nrec.iface.name,
- .type = ISCSI_STRING,
- }, {
- .param = ISCSI_PARAM_INITIATOR_NAME,
- .value = session->initiator_name,
- .type = ISCSI_STRING,
- },
- };
+ int rc;
actor_delete(&conn->login_timer);
- /* Entered full-feature phase! */
- for (i = 0; i < MAX_SESSION_PARAMS; i++) {
- if (conn->id != 0 && !conntbl[i].conn_only)
- continue;
-
- if (!(session->param_mask & (1ULL << conntbl[i].param)))
- continue;
-
- rc = ipc->set_param(session->t->handle, session->id,
- conn->id, conntbl[i].param, conntbl[i].value,
- conntbl[i].type);
- if (rc && rc != -ENOSYS) {
- log_error("can't set operational parameter %d for "
- "connection %d:%d, retcode %d (%d)",
- conntbl[i].param, session->id, conn->id,
- rc, errno);
-
- iscsi_login_eh(conn, c->qtask,
- MGMT_IPC_ERR_LOGIN_FAILURE);
- return;
- }
- if (rc == -ENOSYS) {
- switch (conntbl[i].param) {
- case ISCSI_PARAM_PING_TMO:
- /*
- * older kernels may not support nops
- * in kernel
- */
- conn->userspace_nop = 1;
- break;
- case ISCSI_PARAM_INITIATOR_NAME:
- /* use host level one instead */
- hosttbl[ISCSI_HOST_PARAM_INITIATOR_NAME].set = 1;
- break;
- }
- }
-
- print_param_value(conntbl[i].param, conntbl[i].value,
- conntbl[i].type);
+ if (iscsi_session_set_params(conn)) {
+ iscsi_login_eh(conn, c->qtask, MGMT_IPC_ERR_LOGIN_FAILURE);
+ return;
}
- for (i = 0; i < MAX_HOST_PARAMS; i++) {
- if (!hosttbl[i].set)
- continue;
-
- if (__iscsi_host_set_param(session->t, session->hostno,
- hosttbl[i].param, hosttbl[i].value,
- hosttbl[i].type)) {
- iscsi_login_eh(conn, c->qtask,
- MGMT_IPC_ERR_LOGIN_FAILURE);
- return;
- }
-
- print_param_value(hosttbl[i].param, hosttbl[i].value,
- hosttbl[i].type);
+ if (iscsi_host_set_params(session)) {
+ iscsi_login_eh(conn, c->qtask, MGMT_IPC_ERR_LOGIN_FAILURE);
+ return;
}
if (ipc->start_conn(session->t->handle, session->id, conn->id,
@@ -1527,10 +1056,10 @@ setup_full_feature_phase(iscsi_conn_t *conn)
static void iscsi_logout_timedout(void *data)
{
- struct iscsi_conn_context *conn_context = data;
- struct iscsi_conn *conn = conn_context->conn;
+ struct iscsi_ev_context *ev_context = data;
+ struct iscsi_conn *conn = ev_context->conn;
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
/*
* assume we were in STATE_IN_LOGOUT or there
* was some nasty error
@@ -1542,7 +1071,7 @@ static void iscsi_logout_timedout(void *data)
static int iscsi_send_logout(iscsi_conn_t *conn)
{
struct iscsi_logout hdr;
- struct iscsi_conn_context *conn_context;
+ struct iscsi_ev_context *ev_context;
if (conn->state != STATE_LOGGED_IN)
return EINVAL;
@@ -1558,12 +1087,12 @@ static int iscsi_send_logout(iscsi_conn_t *conn)
return EIO;
conn->state = STATE_IN_LOGOUT;
- conn_context = iscsi_conn_context_get(conn, 0);
- if (!conn_context)
+ ev_context = iscsi_ev_context_get(conn, 0);
+ if (!ev_context)
/* unbounded logout */
log_warning("Could not allocate conn context for logout.");
else {
- iscsi_sched_conn_context(conn_context, conn,
+ iscsi_sched_ev_context(ev_context, conn,
conn->logout_timeout,
EV_CONN_LOGOUT_TIMER);
log_debug(3, "logout timeout timer %u\n",
@@ -1575,11 +1104,11 @@ static int iscsi_send_logout(iscsi_conn_t *conn)
static void iscsi_stop(void *data)
{
- struct iscsi_conn_context *conn_context = data;
- struct iscsi_conn *conn = conn_context->conn;
+ struct iscsi_ev_context *ev_context = data;
+ struct iscsi_conn *conn = ev_context->conn;
int rc = 0;
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
if (!iscsi_send_logout(conn))
return;
@@ -1741,11 +1270,11 @@ failed:
static void session_conn_recv_pdu(void *data)
{
- struct iscsi_conn_context *conn_context = data;
- iscsi_conn_t *conn = conn_context->conn;
+ struct iscsi_ev_context *ev_context = data;
+ iscsi_conn_t *conn = ev_context->conn;
struct iscsi_hdr hdr;
- conn->recv_context = conn_context;
+ conn->recv_context = ev_context;
switch (conn->state) {
case STATE_IN_LOGIN:
@@ -1755,11 +1284,10 @@ static void session_conn_recv_pdu(void *data)
case STATE_IN_LOGOUT:
case STATE_LOGOUT_REQUESTED:
/* read incoming PDU */
- if (!iscsi_io_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE,
- conn->data, ISCSI_DEF_MAX_RECV_SEG_LEN,
- ISCSI_DIGEST_NONE, 0)) {
+ if (iscsi_io_recv_pdu(conn, &hdr, ISCSI_DIGEST_NONE,
+ conn->data, ISCSI_DEF_MAX_RECV_SEG_LEN,
+ ISCSI_DIGEST_NONE, 0) < 0)
return;
- }
switch (hdr.opcode & ISCSI_OPCODE_MASK) {
case ISCSI_OP_NOOP_IN:
@@ -1777,17 +1305,17 @@ static void session_conn_recv_pdu(void *data)
}
break;
case STATE_XPT_WAIT:
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
log_debug(1, "ignoring incoming PDU in XPT_WAIT. "
"let connection re-establish or fail");
break;
case STATE_CLEANUP_WAIT:
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
log_debug(1, "ignoring incoming PDU in XPT_WAIT. "
"let connection cleanup");
break;
default:
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
log_error("Invalid state. Dropping PDU.\n");
}
}
@@ -1910,15 +1438,15 @@ retry_create:
static void session_conn_poll(void *data)
{
- struct iscsi_conn_context *conn_context = data;
- iscsi_conn_t *conn = conn_context->conn;
+ struct iscsi_ev_context *ev_context = data;
+ iscsi_conn_t *conn = ev_context->conn;
struct iscsi_session *session = conn->session;
mgmt_ipc_err_e err = MGMT_IPC_OK;
- queue_task_t *qtask = conn_context->data;
+ queue_task_t *qtask = ev_context->data;
iscsi_login_context_t *c = &conn->login_context;
int rc;
- iscsi_conn_context_put(conn_context);
+ iscsi_ev_context_put(ev_context);
if (conn->state != STATE_XPT_WAIT)
return;
@@ -1927,16 +1455,16 @@ static void session_conn_poll(void *data)
if (rc == 0) {
log_debug(4, "poll not connected %d", rc);
/* timedout: Poll again. */
- conn_context = iscsi_conn_context_get(conn, 0);
- if (!conn_context) {
+ ev_context = iscsi_ev_context_get(conn, 0);
+ if (!ev_context) {
/* while polling the recv pool should be full */
log_error("BUG: session_conn_poll could not get conn "
"context.");
iscsi_login_eh(conn, qtask, MGMT_IPC_ERR_INTERNAL);
return;
}
- conn_context->data = qtask;
- iscsi_sched_conn_context(conn_context, conn, 0, EV_CONN_POLL);
+ ev_context->data = qtask;
+ iscsi_sched_ev_context(ev_context, conn, 0, EV_CONN_POLL);
} else if (rc > 0) {
/* connected! */
memset(c, 0, sizeof(iscsi_login_context_t));
@@ -1961,10 +1489,9 @@ static void session_conn_poll(void *data)
"%d:%d", session->id, conn->id);
}
- iscsi_copy_operational_params(conn);
-
- if (session->t->template->create_conn)
- session->t->template->create_conn(conn);
+ iscsi_copy_operational_params(conn,
+ &session->nrec.session.iscsi,
+ &session->nrec.conn[conn->id].iscsi);
/*
* TODO: use the iface number or some other value
* so this will be persistent
@@ -2011,70 +1538,55 @@ cleanup:
session_conn_shutdown(conn, qtask, err);
}
-void iscsi_sched_conn_context(struct iscsi_conn_context *conn_context,
- struct iscsi_conn *conn, unsigned long tmo,
- int event)
+static int iscsi_sched_ev_context(struct iscsi_ev_context *ev_context,
+ struct iscsi_conn *conn, unsigned long tmo,
+ int event)
{
enum iscsi_err error;
log_debug(7, "sched conn context %p event %d, tmo %lu",
- &conn_context->actor, event, tmo);
+ &ev_context->actor, event, tmo);
- conn_context->conn = conn;
+ ev_context->conn = conn;
switch (event) {
case EV_CONN_RECV_PDU:
- actor_new(&conn_context->actor, session_conn_recv_pdu,
- conn_context);
- actor_schedule(&conn_context->actor);
+ actor_new(&ev_context->actor, session_conn_recv_pdu,
+ ev_context);
+ actor_schedule(&ev_context->actor);
break;
case EV_CONN_ERROR:
- error = *(enum iscsi_err *)conn_context->data;
+ error = *(enum iscsi_err *)ev_context->data;
- actor_new(&conn_context->actor, session_conn_error,
- conn_context);
+ actor_new(&ev_context->actor, session_conn_error,
+ ev_context);
/*
* We handle invalid host, by killing the session.
* It must go at the head of the queue, so we do not
* initiate error handling or logout or some other op.
*/
if (error == ISCSI_ERR_INVALID_HOST)
- actor_schedule_head(&conn_context->actor);
+ actor_schedule_head(&ev_context->actor);
else
- actor_schedule(&conn_context->actor);
+ actor_schedule(&ev_context->actor);
break;
case EV_CONN_POLL:
- actor_new(&conn_context->actor, session_conn_poll,
- conn_context);
- actor_schedule(&conn_context->actor);
+ actor_new(&ev_context->actor, session_conn_poll,
+ ev_context);
+ actor_schedule(&ev_context->actor);
break;
case EV_CONN_LOGOUT_TIMER:
- actor_timer(&conn_context->actor, tmo * 1000,
- iscsi_logout_timedout, conn_context);
+ actor_timer(&ev_context->actor, tmo * 1000,
+ iscsi_logout_timedout, ev_context);
break;
case EV_CONN_STOP:
- actor_new(&conn_context->actor, iscsi_stop,
- conn_context);
- actor_schedule(&conn_context->actor);
+ actor_new(&ev_context->actor, iscsi_stop,
+ ev_context);
+ actor_schedule(&ev_context->actor);
break;
default:
log_error("Invalid event type %d.", event);
- return;
- }
-}
-
-iscsi_session_t*
-session_find_by_sid(int sid)
-{
- struct iscsi_transport *t;
- iscsi_session_t *session;
-
- list_for_each_entry(t, &transports, list) {
- list_for_each_entry(session, &t->sessions, list) {
- if (session->id == sid)
- return session;
- }
}
- return NULL;
+ return 0;
}
static iscsi_session_t* session_find_by_rec(node_rec_t *rec)
@@ -2111,50 +1623,6 @@ static int session_is_running(node_rec_t *rec)
return 0;
}
-static int iface_set_param(struct iscsi_transport *t, struct iface_rec *iface,
- struct iscsi_session *session)
-{
- int rc = 0;
-
- log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, "
- "transport %s.\n",
- iface->name, iface->netdev, iface->ipaddress,
- iface->hwaddress, iface->transport_name);
-
- if (!t->template->set_host_ip)
- return 0;
-
- /* if we need to set the ip addr then set all the iface net settings */
- if (!iface_is_bound_by_ipaddr(iface)) {
- log_warning("Please set the iface.ipaddress for iface %s, "
- "then retry the login command.\n", iface->name);
- return EINVAL;
- }
-
- rc = __iscsi_host_set_param(t, session->hostno,
- ISCSI_HOST_PARAM_IPADDRESS,
- iface->ipaddress, ISCSI_STRING);
- if (rc)
- return rc;
-
- if (iface_is_bound_by_netdev(iface)) {
- rc = __iscsi_host_set_param(t, session->hostno,
- ISCSI_HOST_PARAM_NETDEV_NAME,
- iface->netdev, ISCSI_STRING);
- if (rc)
- return rc;
- }
-
- if (iface_is_bound_by_hwaddr(iface)) {
- rc = __iscsi_host_set_param(t, session->hostno,
- ISCSI_HOST_PARAM_HWADDRESS,
- iface->hwaddress, ISCSI_STRING);
- if (rc)
- return rc;
- }
- return 0;
-}
-
int
session_login_task(node_rec_t *rec, queue_task_t *qtask)
{
@@ -2168,8 +1636,6 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name);
if (!t)
return MGMT_IPC_ERR_TRANS_NOT_FOUND;
- if (set_transport_template(t))
- return MGMT_IPC_ERR_TRANS_NOT_FOUND;
if ((!(t->caps & CAP_RECOVERY_L0) &&
rec->session.iscsi.ERL != 0) ||
@@ -2234,7 +1700,7 @@ session_login_task(node_rec_t *rec, queue_task_t *qtask)
conn = &session->conn[0];
qtask->conn = conn;
- if (iface_set_param(t, &rec->iface, session)) {
+ if (iscsi_host_set_net_params(&rec->iface, session)) {
__session_destroy(session);
return MGMT_IPC_ERR_LOGIN_FAILURE;
}
@@ -2279,8 +1745,6 @@ iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid)
t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name);
if (!t)
return MGMT_IPC_ERR_TRANS_NOT_FOUND;
- if (set_transport_template(t))
- return MGMT_IPC_ERR_TRANS_NOT_FOUND;
session = __session_create(rec, t);
if (!session)
@@ -2392,7 +1856,7 @@ iscsi_host_send_targets(queue_task_t *qtask, int host_no, int do_login,
struct iscsi_transport *t;
t = iscsi_sysfs_get_transport_by_hba(host_no);
- if (!t || set_transport_template(t)) {
+ if (!t) {
log_error("Invalid host no %d for sendtargets\n", host_no);
return MGMT_IPC_ERR_TRANS_FAILURE;
}
@@ -2412,7 +1876,7 @@ iscsi_host_send_targets(queue_task_t *qtask, int host_no, int do_login,
* the card will have sessions preset in the FLASH and will log into them
* automaotically then send us notification that a session is setup.
*/
-void iscsi_async_session_creation(uint32_t host_no, uint32_t sid)
+static void iscsi_async_session_creation(uint32_t host_no, uint32_t sid)
{
struct iscsi_transport *transport;
@@ -2428,7 +1892,20 @@ void iscsi_async_session_creation(uint32_t host_no, uint32_t sid)
session_scan_host(NULL, host_no, NULL);
}
-void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid)
+static void iscsi_async_session_destruction(uint32_t host_no, uint32_t sid)
{
log_debug(3, "session destroyed sid %u host no %d", sid, host_no);
}
+
+static struct iscsi_ipc_ev_clbk ipc_clbk = {
+ .create_session = iscsi_async_session_creation,
+ .destroy_session = iscsi_async_session_destruction,
+ .get_ev_context = iscsi_ev_context_get,
+ .put_ev_context = iscsi_ev_context_put,
+ .sched_ev_context = iscsi_sched_ev_context,
+};
+
+void iscsi_initiator_init(void)
+{
+ ipc_register_ev_callback(&ipc_clbk);
+}