summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-02-21 15:44:37 -0600
committerMike Christie <michaelc@cs.wisc.edu>2008-02-21 15:44:37 -0600
commitb11b31ac745ae72c3305a5658c619557000108a3 (patch)
tree08625b2173c72531e7f4ae086a98479d6e2c1377 /usr
parenta37c73fda80f962883bb4ff0e1ab068c4d8b9b49 (diff)
downloadopen-iscsi-b11b31ac745ae72c3305a5658c619557000108a3.tar.gz
Fix connection cleanup when iscsid is restarted.
If iscsid is restarted while a session is running, then the session is logged out we are leaving the iscsi connection in the kernel. The reason for this is because conn->ksetup is not set during the sync up. Instead of that hacky bool we can just check the kernel if there is a connection setup by looking in sysfs.
Diffstat (limited to 'usr')
-rw-r--r--usr/initiator.c7
-rw-r--r--usr/initiator.h1
-rw-r--r--usr/iscsi_sysfs.c24
-rw-r--r--usr/iscsi_sysfs.h1
4 files changed, 29 insertions, 4 deletions
diff --git a/usr/initiator.c b/usr/initiator.c
index b392bef..8123896 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -602,7 +602,10 @@ session_conn_shutdown(iscsi_conn_t *conn, queue_task_t *qtask,
{
iscsi_session_t *session = conn->session;
- if (!conn->ksetup)
+ if (session->id == -1)
+ goto disconnect_conn;
+
+ if (!sysfs_session_has_leadconn(session->id))
goto disconnect_conn;
if (conn->state == STATE_IN_LOGIN ||
@@ -623,7 +626,6 @@ session_conn_shutdown(iscsi_conn_t *conn, queue_task_t *qtask,
log_error("can not safely destroy connection %d", conn->id);
return MGMT_IPC_ERR_INTERNAL;
}
- conn->ksetup = 0;
disconnect_conn:
log_debug(2, "disconnect conn");
@@ -1720,7 +1722,6 @@ static void session_conn_poll(void *data)
err = MGMT_IPC_ERR_INTERNAL;
goto cleanup;
}
- conn->ksetup = 1;
log_debug(3, "created new iSCSI connection "
"%d:%d", session->id, conn->id);
}
diff --git a/usr/initiator.h b/usr/initiator.h
index e6b9bf3..8fe2d20 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -116,7 +116,6 @@ struct iscsi_conn_context;
/* daemon's connection structure */
typedef struct iscsi_conn {
uint32_t id;
- int ksetup;
struct iscsi_session *session;
iscsi_login_context_t login_context;
struct iscsi_conn_context *recv_context;
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index 0dfbcfd..a0864de 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -38,6 +38,12 @@
#define ISCSI_MAX_SYSFS_BUFFER NI_MAXHOST
+/*
+ * TODO: make this into a real API and check inputs better and add doc.
+ * We should also use a common lib and search sysfs according to the sysfs
+ * doc in the kernel documetnation.
+ */
+
/* tmp buffer used by sysfs functions */
static char sysfs_file[PATH_MAX];
int num_transports = 0;
@@ -463,6 +469,24 @@ free_info:
return rc;
}
+/**
+ * sysfs_session_has_leadconn - checks if session has lead conn in kernel
+ * @sid: session id
+ *
+ * return 1 if session has lead conn and 0 if not.
+ */
+int sysfs_session_has_leadconn(uint32_t sid)
+{
+ struct stat statb;
+
+ memset(sysfs_file, 0, PATH_MAX);
+ sprintf(sysfs_file, ISCSI_CONN_DIR"/connection%u:0", sid);
+ if (!stat(sysfs_file, &statb))
+ return 1;
+ else
+ return 0;
+}
+
int get_sessioninfo_by_sysfs_id(struct session_info *info, char *session)
{
int ret, pers_failed = 0;
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
index 9c1cc7b..a6163af 100644
--- a/usr/iscsi_sysfs.h
+++ b/usr/iscsi_sysfs.h
@@ -54,6 +54,7 @@ extern int get_iscsi_kernel_version(char *buf);
extern int check_class_version(void);
extern int get_sessioninfo_by_sysfs_id(struct session_info *info,
char *sys_session);
+extern int sysfs_session_has_leadconn(uint32_t sid);
typedef int (sysfs_session_op_fn)(void *, struct session_info *);
typedef int (sysfs_host_op_fn)(void *, struct host_info *);