On 06/12/2009 11:32 PM, Mike Christie wrote:
> On 06/11/2009 03:49 AM, tweyergraf wrote:
>>
>> On Jun 11, 1:29 am, Mike Christie<micha...@cs.wisc.edu>   wrote:
>>> On 06/09/2009 09:24 AM, tweyergraf wrote:
>>>
>>> [...]
>>> So after the releasing session entry you get the glibc free error
>>> message, right?
>> Yes, exactly. iscsid crashes precisely in the function session_release
>> in initiator.c. I have wrapped the calls to
>> iscsi_conn_context_free() and free() calles in this function with my
>> own log_debug calls. The call of free(session) *sometimes* causes the
>> crash.
>> Currently, i am about to setup a dedicated test-system to facilitate
>> the possibility of further tests. I think by
>> monday next week, i could do further investigations. If you want me to
>> do something to find out more about this issue, feel free ;)
>> I have used open-iscsi quit intensively and never had such a problem.
>> But this problem occurs on quit a few different systems ( about 10 ).
>> Some are XEN Dom0's some dedicated hosts. They connect to Linux-IET
>> targets as well as to ou EMC storage-backend. The error occurs with
>> both target-types. I am also fairly certain, that we can rule-out
>> networking issus, since the systems are on different networks with
>> different network-setups. Also, the problem arises with the Centos
>> open-iscsi packages, as well as self-build open-iscsi versions 870.3
>> and 871-test4.
>>
>> As stated previously, iscsid runs stable, if I comment-out the two
>> functioncalls above in session_release(). Of course, I am leaking
>> memory in iscsid if I login to new targets ( which fortunatly does not
>> happen often enough).
>>
>> Feel free to request more tests, give suggestions or ask for more
>> information.
>>
>
> Are you doing iscsi boot? In the logs it looks like there are sessions
> running when iscsid starts up. This is fine, iscsid can handle this. But
> maybe if we can take that out of the picture we can narrow the problem down,
>

Could you try the attached patch. It was made against the open-iscsi.git 
tree but should apply to 871-test4.

There is a possible double free in the code. I do not think you are 
hitting the one I fixed in the patch. It would be really rare to hit it. 
I also added some more debug info in there and some more checks though.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

diff --git a/usr/initiator.c b/usr/initiator.c
index 330e199..9ca6b0f 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -81,8 +81,15 @@ static int iscsi_conn_context_alloc(iscsi_conn_t *conn)
                                           ipc->ctldev_bufmax);
                if (!conn->context_pool[i]) {
                        int j;
-                       for (j = 0; j < i; j++)
+                       for (j = 0; j < i; j++) {
                                free(conn->context_pool[j]);
+                               /* tmp hack. in the failure path 
+                                * iscsi_conn_context_free can be called and
+                                * we will double free this if we do not null
+                                * it again
+                                */
+                               conn->context_pool[j] = NULL;
+                       }
                        return ENOMEM;
                }
                conn->context_pool[i]->conn = conn;
@@ -96,14 +103,17 @@ static void iscsi_conn_context_free(iscsi_conn_t *conn)
        int i;
 
        for (i = 0; i < CONTEXT_POOL_MAX; i++) {
-               if (!conn->context_pool[i])
+               if (!conn->context_pool[i]) {
+                       log_error("BUG trying to call context free again\n");
                        continue;
+               }
 
                if (conn->context_pool[i]->allocated)
                        /* missing flush on shutdown */
                        log_error("BUG: context_pool leak %p",
                                  conn->context_pool[i]);
                free(conn->context_pool[i]);
+               conn->context_pool[i] = NULL;
        }
 }
 
@@ -488,17 +498,6 @@ __session_conn_create(iscsi_session_t *session, int cid)
        return 0;
 }
 
-static void
-session_release(iscsi_session_t *session)
-{
-       log_debug(2, "Releasing session %p", session);
-
-       if (session->target_alias)
-               free(session->target_alias);
-       iscsi_conn_context_free(&session->conn[0]);
-       free(session);
-}
-
 static iscsi_session_t*
 __session_create(node_rec_t *rec, struct iscsi_transport *t)
 {
@@ -602,9 +601,12 @@ static void
 __session_destroy(iscsi_session_t *session)
 {
        log_debug(1, "destroying session\n");
-       list_del(&session->list);
        iscsi_flush_context_pool(session);
-       session_release(session);
+
+       if (session->target_alias)
+               free(session->target_alias);
+       iscsi_conn_context_free(&session->conn[0]);
+       free(session);
 }
 
 static void
@@ -1126,12 +1128,11 @@ void free_initiator(void)
        struct iscsi_transport *t;
        iscsi_session_t *session, *tmp;
 
+       log_debug(1, "freeing initiator\n");
+
        list_for_each_entry(t, &transports, list) {
-               list_for_each_entry_safe(session, tmp, &t->sessions, list) {
-                       list_del(&session->list);
-                       iscsi_flush_context_pool(session);
-                       session_release(session);
-               }
+               list_for_each_entry_safe(session, tmp, &t->sessions, list)
+                       __session_destroy(session);
        }
 
        free_transports();
diff --git a/usr/iscsid.c b/usr/iscsid.c
index ea29bb2..f7c2eb2 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -278,6 +278,8 @@ static void iscsid_exit(void)
        if (daemon_config.initiator_alias)
                free(daemon_config.initiator_alias);
        free_initiator();
+       idbm_terminate();
+       sysfs_cleanup();
 }
 
 static void iscsid_shutdown(void)
@@ -509,7 +511,5 @@ int main(int argc, char *argv[])
        isns_fd = isns_init();
        event_loop(ipc, control_fd, mgmt_ipc_fd, isns_fd);
        iscsid_shutdown();
-       idbm_terminate();
-       sysfs_cleanup();
        return 0;
 }

Reply via email to