summaryrefslogtreecommitdiffstats
path: root/utils/gssd/gssd.c
diff options
context:
space:
mode:
authorOlga Kornievskaia <kolga@netapp.com>2016-04-28 16:21:41 -0400
committerSteve Dickson <steved@redhat.com>2016-04-29 10:37:53 -0400
commit8c34e538ef7492fda87b640343996dd33a2fde1d (patch)
tree32f61476c24357e9c1d717ee181013999924ae73 /utils/gssd/gssd.c
parentbf97c20a6c3b8d037663e23a39bcf2f003ec12ee (diff)
downloadnfs-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.c46
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 *