Skip to content

Commit

Permalink
iscsid: Check session's target_state before reopen a session
Browse files Browse the repository at this point in the history
When iscsid restart and sync a session, check if session's target_state
is BOUND before reopen it. If not, this session would be shutdown.

Refer to https://lore.kernel.org/all/20220802034729.2566787-1-haowenchao@huawei.com/
for details.

Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
  • Loading branch information
Wenchao Hao committed Aug 14, 2022
1 parent c6cf8e1 commit 4500276
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion usr/initiator.c
Expand Up @@ -2034,11 +2034,40 @@ sync_conn(iscsi_session_t *session, uint32_t cid)
return 0;
}

static int
iscsi_sysfs_get_target_state(uint32_t sid, char *state, int len)
{
char id[NAME_SIZE];
int fd;
int ret = 0;

sprintf(id, "/sys/class/iscsi_session/session%d/target_state", sid);

fd = open(id, O_RDONLY);
if (fd < 0) {
log_warning("failed to open session's target state %s", strerror(errno));
return errno;
}

ret = read(fd, state, len);
if (ret < 0) {
log_warning("failed to read session's target state %s", strerror(errno));
return errno;
}

if (ret && state[ret - 1] == '\n')
state[ret - 1] = '\0';

return 0;
}

int
iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid)
{
iscsi_session_t *session;
iscsi_conn_t *conn;
struct iscsi_transport *t;
char state[12];
int err;

session = session_find_by_sid(sid);
Expand Down Expand Up @@ -2067,8 +2096,39 @@ iscsi_sync_session(node_rec_t *rec, queue_task_t *qtask, uint32_t sid)
goto destroy_session;

qtask->rsp.command = MGMT_IPC_SESSION_SYNC;

log_debug(3, "Started sync iSCSI session %d", session->id);

err = iscsi_sysfs_get_target_state(sid, state, 12);
if (err || !strncmp(state, "BOUND", 5))
goto reopen_session;

/*
* If get target state succeed and the state is not BOUND, it means
* the session is in an invalid state which should not be reopened
*/
mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS);

/*
* Update connection's state so ipc->stop_conn() would
* be called for this connection in session_conn_shutdown()
*
* TODO: setting connection's state according to sysfs
*/
conn = &session->conn[0];
conn->state = ISCSI_CONN_STATE_IN_LOGIN;


if (!strncmp(state, "UNBINDING", 9))
log_warning("Donot sync UNBINDING session%d", sid);

if (!strncmp(state, "UNBOUND", 7)) {
log_warning("Shutdown UNBOUND session%d", sid);
session_conn_shutdown(conn, NULL, ISCSI_SUCCESS);
}

return 0;

reopen_session:
session->notify_qtask = qtask;
session_conn_reopen(&session->conn[0], qtask,
STOP_CONN_RECOVER);
Expand Down

0 comments on commit 4500276

Please sign in to comment.