- Connection reinstatement fixes
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Wed, 4 Mar 2009 18:31:35 +0000 (18:31 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Wed, 4 Mar 2009 18:31:35 +0000 (18:31 +0000)
 - Minor cleanups

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@687 d57e44dd-8a1f-0410-8b47-8ef2f437770f

iscsi-scst/kernel/conn.c
iscsi-scst/kernel/nthread.c
iscsi-scst/usr/conn.c
iscsi-scst/usr/event.c
iscsi-scst/usr/iscsi_scstd.c
iscsi-scst/usr/iscsid.h

index 42bd843..40e05db 100644 (file)
@@ -32,32 +32,36 @@ static void print_conn_state(char *p, size_t size, struct iscsi_conn *conn)
 
        switch (conn->rd_state) {
        case ISCSI_CONN_RD_STATE_PROCESSING:
-               snprintf(p, size, "%s", "read_processing ");
+               size -= scnprintf(p, size, "%s", "read_processing ");
                printed = 1;
                break;
        case ISCSI_CONN_RD_STATE_IN_LIST:
-               snprintf(p, size, "%s", "in_read_list ");
+               size -= scnprintf(p, size, "%s", "in_read_list ");
                printed = 1;
                break;
        }
 
        switch (conn->wr_state) {
        case ISCSI_CONN_WR_STATE_PROCESSING:
-               snprintf(p, size, "%s", "write_processing ");
+               size -= scnprintf(p, size, "%s", "write_processing ");
                printed = 1;
                break;
        case ISCSI_CONN_WR_STATE_IN_LIST:
-               snprintf(p, size, "%s", "in_write_list ");
+               size -= scnprintf(p, size, "%s", "in_write_list ");
                printed = 1;
                break;
        case ISCSI_CONN_WR_STATE_SPACE_WAIT:
-               snprintf(p, size, "%s", "space_waiting ");
+               size -= scnprintf(p, size, "%s", "space_waiting ");
                printed = 1;
                break;
        }
 
-       if (!printed)
+       if (conn->conn_reinstating)
+               snprintf(p, size, "%s", "reinstating ");
+       else if (!printed)
                snprintf(p, size, "%s", "established idle ");
+
+       return;
 }
 
 static void print_digest_state(char *p, size_t size, unsigned long flags)
@@ -184,7 +188,7 @@ void mark_conn_closed(struct iscsi_conn *conn)
        __mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE);
 }
 
-static void iscsi_state_change(struct sock *sk)
+static void __iscsi_state_change(struct sock *sk)
 {
        struct iscsi_conn *conn = sk->sk_user_data;
 
@@ -202,9 +206,17 @@ static void iscsi_state_change(struct sock *sk)
        } else
                iscsi_make_conn_rd_active(conn);
 
+       TRACE_EXIT();
+       return;
+}
+
+static void iscsi_state_change(struct sock *sk)
+{
+       struct iscsi_conn *conn = sk->sk_user_data;
+
+       __iscsi_state_change(sk);
        conn->old_state_change(sk);
 
-       TRACE_EXIT();
        return;
 }
 
@@ -308,7 +320,11 @@ void __iscsi_socket_bind(struct iscsi_conn *conn)
 
        write_unlock_bh(&conn->sock->sk->sk_callback_lock);
 
-       iscsi_make_conn_rd_active(conn);
+       /*
+        * Check, if conn was closed while we were initializing it.
+        * This function will make conn rd_active, if necessary.
+        */
+       __iscsi_state_change(conn->sock->sk);
 
        return;
 }
@@ -501,7 +517,8 @@ int conn_add(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
                goto out;
 
        if (reinstatement) {
-               TRACE_MGMT_DBG("Reinstating conn %p", conn);
+               TRACE_MGMT_DBG("Reinstating conn (old %p, new %p)", conn,
+                       new_conn);
                conn->conn_reinst_successor = new_conn;
                new_conn->conn_reinstating = 1;
                __mark_conn_closed(conn, 0);
index bc717fa..5a629d5 100644 (file)
@@ -526,6 +526,7 @@ static void close_conn(struct iscsi_conn *conn)
        mutex_lock(&target->target_mutex);
 
        free_sess = (conn->conn_reinst_successor == NULL);
+       conn->conn_reinst_successor = NULL;
 
        conn_free(conn);
 
index f5c2296..38d396a 100644 (file)
@@ -57,7 +57,7 @@ void conn_pass_to_kern(struct connection *conn, int fd)
 {
        int err;
 
-       log_debug(1, "fd %d, cid %u, stat_sn %u, exp_stat_sn %u sid%" PRIx64,
+       log_debug(1, "fd %d, cid %u, stat_sn %u, exp_stat_sn %u sid %" PRIx64,
                fd, conn->cid, conn->stat_sn, conn->exp_stat_sn, conn->sid.id64);
 
        err = kernel_conn_create(conn->tid, conn->sess->sid.id64, conn->cid,
@@ -65,9 +65,7 @@ void conn_pass_to_kern(struct connection *conn, int fd)
                              conn->session_param[key_header_digest].val,
                              conn->session_param[key_data_digest].val);
 
-       if (err == 0)
-               conn->sess->kern_conn_cnt++;
-       else
+       if (err != 0)
                log_error("kernel_conn_create() failed: %s", strerror(errno));
 
        /* We don't need to return err, because we are going to close conn anyway */
index ec6bf40..07ab170 100644 (file)
@@ -80,6 +80,7 @@ static int nl_read(int fd, void *data, int len)
 void handle_iscsi_events(int fd)
 {
        struct session *session;
+       struct connection *conn;
        struct iscsi_kern_event event;
        int res;
 
@@ -98,13 +99,22 @@ retry:
 
        switch (event.state) {
        case E_CONN_CLOSE:
-               if (!(session = session_find_id(event.tid, event.sid))) {
-                       log_warning("session %#" PRIx64 " not found?", event.sid);
+               session = session_find_id(event.tid, event.sid);
+               if (session == NULL) {
+                       log_error("Session %#" PRIx64 " not found", event.sid);
                        goto retry;
                }
 
-               session->kern_conn_cnt--;
-               if ((session->kern_conn_cnt == 0) && list_empty(&session->conn_list))
+               conn = conn_find(session, event.cid);
+               if (conn == NULL) {
+                       log_error("Connection %x for session %#" PRIx64 " not "
+                               "found", event.cid, event.sid);
+                       goto retry;
+               }
+
+               conn_free(conn);
+
+               if (list_empty(&session->conn_list))
                        session_free(session);
                break;
        default:
index 9720dac..6b663af 100644 (file)
@@ -568,7 +568,6 @@ static void event_loop(int timeout)
                        if (conn->state == STATE_CLOSE) {
                                log_debug(0, "closing conn %p", conn);
                                conn_free_pdu(conn);
-                               conn_free(conn);
                                close(pollfd->fd);
                                pollfd->fd = -1;
                                incoming[i] = NULL;
index b96b955..4396dc6 100644 (file)
@@ -58,7 +58,6 @@ struct session {
        struct target *target;
        union iscsi_sid sid;
 
-       int kern_conn_cnt;
        struct __qelem conn_list;
 };