A pthread resource leak was discovered in the ongoing pthread
creation code during the session recovery process.  These pthreads
were erroneously created as joinable instead of having the intended
detached attribute.

Signed-off-by: Eddie Wai <eddie....@broadcom.com>
---
 iscsiuio/RELEASE.TXT           |   12 ++++++++++++
 iscsiuio/src/unix/iscsid_ipc.c |   26 +++++++++++++-------------
 iscsiuio/src/unix/main.c       |    5 ++++-
 iscsiuio/src/unix/nic.c        |   23 ++---------------------
 iscsiuio/src/unix/nic_utils.c  |    5 ++++-
 5 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/iscsiuio/RELEASE.TXT b/iscsiuio/RELEASE.TXT
index 22628fd..48feedd 100644
--- a/iscsiuio/RELEASE.TXT
+++ b/iscsiuio/RELEASE.TXT
@@ -10,6 +10,18 @@
                Copyright (c) 2004 - 2013 Broadcom Corporation
                            All rights reserved
 
+uIP v0.7.10.2 (Feb 12, 2014)
+=======================================================
+   Fixes
+   -----
+   1. Problem: Cont00072504 - ifconfig shows allocation failure after
+               up/down few hours with iSCSI + L2 traffic
+      Cause:   A memory leak was discovered in the ongoing pthread creation
+               destruction code during the connection recovery process
+      Change:  Fixed the pthread creation code
+      Impact:  All
+
+
 uIP v0.7.8.2 (Dec 10, 2013)
 =======================================================
    Fixes
diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c
index 033308d..0b9b18c 100644
--- a/iscsiuio/src/unix/iscsid_ipc.c
+++ b/iscsiuio/src/unix/iscsid_ipc.c
@@ -334,9 +334,9 @@ static int parse_iface(void *arg)
        char ipv6_buf_str[INET6_ADDRSTRLEN];
        int request_type = 0;
        struct iface_rec *rec;
-       void *res;
        struct iface_rec_decode ird;
        struct in_addr src_match, dst_match;
+       pthread_attr_t attr;
 
        data = (iscsid_uip_broadcast_t *) arg;
        rec = &data->u.iface_rec.rec;
@@ -594,7 +594,9 @@ static int parse_iface(void *arg)
 
        nic_iface->flags |= NIC_IFACE_PATHREQ_WAIT1;
        if (nic->nl_process_thread == INVALID_THREAD) {
-               rc = pthread_create(&nic->nl_process_thread, NULL,
+               pthread_attr_init(&attr);
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+               rc = pthread_create(&nic->nl_process_thread, &attr,
                                    nl_process_handle_thread, nic);
                if (rc != 0) {
                        LOG_ERR(PFX "%s: Could not create NIC NL "
@@ -745,14 +747,16 @@ enable_nic:
        case NIC_STOPPED:
                /* This thread will be thrown away when completed */
                if (nic->enable_thread != INVALID_THREAD) {
-                       rc = pthread_join(nic->enable_thread, &res);
+                       rc = pthread_cancel(nic->enable_thread);
                        if (rc != 0) {
-                               LOG_INFO(PFX "%s: failed joining enable NIC "
+                               LOG_INFO(PFX "%s: failed to cancel enable NIC "
                                         "thread\n", nic->log_name);
                                goto eagain;
                        }
                }
-               rc = pthread_create(&nic->enable_thread, NULL,
+               pthread_attr_init(&attr);
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+               rc = pthread_create(&nic->enable_thread, &attr,
                                    enable_nic_thread, (void *)nic);
                if (rc != 0)
                        LOG_WARN(PFX "%s: failed starting enable NIC thread\n",
@@ -1001,9 +1005,12 @@ error:
  */
 int iscsid_start()
 {
+       pthread_attr_t attr;
        int rc;
 
-       rc = pthread_create(&iscsid_opts.thread, NULL, iscsid_loop, NULL);
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+       rc = pthread_create(&iscsid_opts.thread, &attr, iscsid_loop, NULL);
        if (rc != 0) {
                LOG_ERR(PFX "Could not start iscsid listening thread rc=%d",
                        rc);
@@ -1026,7 +1033,6 @@ error:
 void iscsid_cleanup()
 {
        int rc;
-       void *res;
 
        if (iscsid_opts.fd != INVALID_FD) {
                rc = pthread_cancel(iscsid_opts.thread);
@@ -1034,12 +1040,6 @@ void iscsid_cleanup()
                        LOG_ERR("Could not cancel iscsid listening thread: %s",
                                strerror(rc));
                }
-
-               rc = pthread_join(iscsid_opts.thread, &res);
-               if (rc != 0) {
-                       LOG_ERR("Could not wait for the iscsid listening "
-                               "thread: %s", strerror(rc));
-               }
        }
 
        LOG_INFO(PFX "iscsid listening thread has shutdown");
diff --git a/iscsiuio/src/unix/main.c b/iscsiuio/src/unix/main.c
index 340e275..e33db04 100644
--- a/iscsiuio/src/unix/main.c
+++ b/iscsiuio/src/unix/main.c
@@ -237,6 +237,7 @@ int main(int argc, char *argv[])
        int fd;
        int foreground = 0;
        pid_t pid;
+       pthread_attr_t attr;
 
        /*  Record the start time for the user space daemon */
        opt.start_time = time(NULL);
@@ -366,7 +367,9 @@ int main(int argc, char *argv[])
        rc = pthread_sigmask(SIG_SETMASK, &set, NULL);
 
        /*  Spin off the signal handling thread */
-       rc = pthread_create(&signal_thread, NULL, signal_handle_thread, NULL);
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+       rc = pthread_create(&signal_thread, &attr, signal_handle_thread, NULL);
        if (rc != 0)
                LOG_ERR("Could not create signal handling thread");
 
diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c
index 7c3f4d5..18e3007 100644
--- a/iscsiuio/src/unix/nic.c
+++ b/iscsiuio/src/unix/nic.c
@@ -450,7 +450,6 @@ int nic_remove(nic_t *nic)
        int rc;
        nic_t *prev, *current;
        struct stat file_stat;
-       void *res;
        nic_interface_t *nic_iface, *next_nic_iface, *vlan_iface;
 
        pthread_mutex_lock(&nic->nic_mutex);
@@ -471,12 +470,6 @@ int nic_remove(nic_t *nic)
                        LOG_DEBUG(PFX "%s: Couldn't send cancel to nic enable "
                                  "thread", nic->log_name);
 
-               LOG_DEBUG(PFX "%s: Waiting to join nic enable thread",
-                         nic->log_name);
-               rc = pthread_join(nic->enable_thread, &res);
-               if (rc != 0)
-                       LOG_DEBUG(PFX "%s: Couldn't join to canceled enable "
-                                 "nic thread", nic->log_name);
                nic->enable_thread = INVALID_THREAD;
                LOG_DEBUG(PFX "%s: nic enable thread cleaned", nic->log_name);
        } else {
@@ -492,11 +485,6 @@ int nic_remove(nic_t *nic)
                        LOG_DEBUG(PFX "%s: Couldn't send cancel to nic",
                                  nic->log_name);
 
-               LOG_DEBUG(PFX "%s: Waiting to join nic thread", nic->log_name);
-               rc = pthread_join(nic->thread, &res);
-               if (rc != 0)
-                       LOG_DEBUG(PFX "%s: Couldn't join to canceled nic "
-                                 "thread", nic->log_name);
                nic->thread = INVALID_THREAD;
                LOG_DEBUG(PFX "%s: nic thread cleaned", nic->log_name);
        } else {
@@ -511,12 +499,6 @@ int nic_remove(nic_t *nic)
                        LOG_DEBUG(PFX "%s: Couldn't send cancel to nic nl "
                                  "thread", nic->log_name);
 
-               LOG_DEBUG(PFX "%s: Waiting to join nic nl thread",
-                         nic->log_name);
-               rc = pthread_join(nic->nl_process_thread, &res);
-               if (rc != 0)
-                       LOG_DEBUG(PFX "%s: Couldn't join to canceled nic nl "
-                                 "thread", nic->log_name);
                nic->nl_process_thread = INVALID_THREAD;
                LOG_DEBUG(PFX "%s: nic nl thread cleaned", nic->log_name);
        } else {
@@ -1238,7 +1220,6 @@ static int do_acquisition(nic_t *nic, nic_interface_t 
*nic_iface,
 {
        struct in_addr addr;
        struct in6_addr addr6;
-       void *res;
        char buf[INET6_ADDRSTRLEN];
        int rc = -1;
 
@@ -1316,9 +1297,9 @@ static int do_acquisition(nic_t *nic, nic_interface_t 
*nic_iface,
                        if (nic->enable_thread == INVALID_THREAD)
                                goto dhcp_err;
 
-                       rc = pthread_join(nic->enable_thread, &res);
+                       rc = pthread_cancel(nic->enable_thread);
                        if (rc != 0)
-                               LOG_ERR(PFX "%s: Couldn't join to canceled "
+                               LOG_ERR(PFX "%s: Couldn't cancel "
                                        "enable nic thread", nic->log_name);
 dhcp_err:
                        pthread_mutex_lock(&nic->nic_mutex);
diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c
index 2acd3c2..fee9a4b 100644
--- a/iscsiuio/src/unix/nic_utils.c
+++ b/iscsiuio/src/unix/nic_utils.c
@@ -871,6 +871,7 @@ error:
 
 void prepare_nic_thread(nic_t *nic)
 {
+       pthread_attr_t attr;
        int rc;
 
        pthread_mutex_lock(&nic->nic_mutex);
@@ -881,7 +882,9 @@ void prepare_nic_thread(nic_t *nic)
                LOG_INFO(PFX "%s: spinning up thread for nic", nic->log_name);
 
                /*  Try to spin up the nic thread */
-               rc = pthread_create(&nic->thread, NULL, nic_loop, nic);
+               pthread_attr_init(&attr);
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+               rc = pthread_create(&nic->thread, &attr, nic_loop, nic);
                if (rc != 0) {
                        LOG_ERR(PFX "%s: Couldn't create thread for nic",
                                nic->log_name);
-- 
1.7.1

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

Reply via email to