diff options
author | Olga Kornievskaia <kolga@netapp.com> | 2016-04-28 16:21:41 -0400 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2016-04-29 10:37:53 -0400 |
commit | 8c34e538ef7492fda87b640343996dd33a2fde1d (patch) | |
tree | 32f61476c24357e9c1d717ee181013999924ae73 /utils/gssd/gssd.c | |
parent | bf97c20a6c3b8d037663e23a39bcf2f003ec12ee (diff) | |
download | nfs-utils-8c34e538ef7492fda87b640343996dd33a2fde1d.tar.gz nfs-utils-8c34e538ef7492fda87b640343996dd33a2fde1d.tar.xz nfs-utils-8c34e538ef7492fda87b640343996dd33a2fde1d.zip |
gssd: use pthreads to handle upcalls
Currently, to persevere global data over multiple mounts,
the root process does not fork when handling an upcall.
Instead on not-forking create a pthread to handle the
upcall since global data can be shared among threads.
Reviewed-by: Jeff Layton <jlayton@poochiereds.net>
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/gssd/gssd.c')
-rw-r--r-- | utils/gssd/gssd.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c index 810f872..9bf7917 100644 --- a/utils/gssd/gssd.c +++ b/utils/gssd/gssd.c @@ -87,7 +87,9 @@ unsigned int rpc_timeout = 5; char *preferred_realm = NULL; /* Avoid DNS reverse lookups on server names */ static bool avoid_dns = true; - +int thread_started = false; +pthread_mutex_t pmutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t pcond = PTHREAD_COND_INITIALIZER; TAILQ_HEAD(topdir_list_head, topdir) topdir_list; @@ -361,20 +363,54 @@ gssd_destroy_client(struct clnt_info *clp) static void gssd_scan(void); +static inline void +wait_for_child_and_detach(pthread_t th) +{ + pthread_mutex_lock(&pmutex); + while (!thread_started) + pthread_cond_wait(&pcond, &pmutex); + thread_started = false; + pthread_mutex_unlock(&pmutex); + pthread_detach(th); +} + +/* For each upcall create a thread, detach from the main process so that + * resources are released back into the system without the need for a join. + * We need to wait for the child thread to start and consume the event from + * the file descriptor. + */ static void gssd_clnt_gssd_cb(int UNUSED(fd), short UNUSED(which), void *data) { struct clnt_info *clp = data; - - handle_gssd_upcall(clp); + pthread_t th; + int ret; + + ret = pthread_create(&th, NULL, (void *)handle_gssd_upcall, + (void *)clp); + if (ret != 0) { + printerr(0, "ERROR: pthread_create failed: ret %d: %s\n", + ret, strerror(errno)); + return; + } + wait_for_child_and_detach(th); } static void gssd_clnt_krb5_cb(int UNUSED(fd), short UNUSED(which), void *data) { struct clnt_info *clp = data; - - handle_krb5_upcall(clp); + pthread_t th; + int ret; + + ret = pthread_create(&th, NULL, (void *)handle_krb5_upcall, + (void *)clp); + if (ret != 0) { + printerr(0, "ERROR: pthread_create failed: ret %d: %s\n", + ret, strerror(errno)); + return; + } + wait_for_child_and_detach(th); } static struct clnt_info * |