iser-target: Work-around live target stack shutdown resource cleanup
authorSagi Grimberg <sagig@mellanox.com>
Tue, 2 Dec 2014 14:57:36 +0000 (16:57 +0200)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sat, 13 Dec 2014 07:32:27 +0000 (23:32 -0800)
Currently we have no way to tell that the target stack is in shutdown
sequence. In case we have open connections, the initiator immediately
attempts to reconnect in a DDOS attack style, so we may end up
terminating the iser enabled network portal while it's np_accept_list
still have pending connections.

The workaround is simply release all the connections in the list.
A proper fix will be to start shutdown sequence by shutting the
network portal to avoid initiator immediate reconnect attempts.

But the temporary work around seems to work at this point, so I think
we can do this for now...

Reported-by: Slava Shwartsman <valyushash@gmail.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/infiniband/ulp/isert/ib_isert.c

index a6daabc70425dac11b0d422c815771fa6b2494c9..b88686e96a5463b208252bba2ec02eee70e68a92 100644 (file)
@@ -3369,10 +3369,31 @@ static void
 isert_free_np(struct iscsi_np *np)
 {
        struct isert_np *isert_np = (struct isert_np *)np->np_context;
+       struct isert_conn *isert_conn, *n;
 
        if (isert_np->np_cm_id)
                rdma_destroy_id(isert_np->np_cm_id);
 
+       /*
+        * FIXME: At this point we don't have a good way to insure
+        * that at this point we don't have hanging connections that
+        * completed RDMA establishment but didn't start iscsi login
+        * process. So work-around this by cleaning up what ever piled
+        * up in np_accept_list.
+        */
+       mutex_lock(&isert_np->np_accept_mutex);
+       if (!list_empty(&isert_np->np_accept_list)) {
+               pr_info("Still have isert connections, cleaning up...\n");
+               list_for_each_entry_safe(isert_conn, n,
+                                        &isert_np->np_accept_list,
+                                        conn_accept_node) {
+                       pr_info("cleaning isert_conn %p state (%d)\n",
+                                  isert_conn, isert_conn->state);
+                       isert_connect_release(isert_conn);
+               }
+       }
+       mutex_unlock(&isert_np->np_accept_mutex);
+
        np->np_context = NULL;
        kfree(isert_np);
 }