]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
vol: Add timeouts to SYNC server select() calls
authorAndrew Deason <adeason@sinenomine.net>
Tue, 29 Mar 2011 17:28:46 +0000 (12:28 -0500)
committerDerrick Brashear <shadow@dementix.org>
Thu, 15 Dec 2011 14:58:14 +0000 (06:58 -0800)
Normally *SYNC server processes wait indefinitely for activity to
occur on one of the SYNC sockets. On some Linux kernels, there exists
a race condition where data can come in on a socket, but the select()
call continues to wait. To ensure that we do not hang forever in such
a scenario, add a timeout to the select() call, which will ensure we
notice the new data within 10 seconds. Raise the timeout on non-Linux
to reduce impact elsewhere.

The Linux kernel bug is tracked in
<https://bugzilla.redhat.com/show_bug.cgi?id=494404>, though that bug
report may not represent all affected kernels.

Reviewed-on: http://gerrit.openafs.org/4377
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit 920a00e075b679f59e31b9fcbe7f5db15e345a95)

Change-Id: Iae4035bc952b66f88843d51ff341b0576f15163d
Reviewed-on: http://gerrit.openafs.org/6276
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
src/vol/daemon_com.h
src/vol/fssync-server.c
src/vol/salvsync-server.c

index 81fd38c218fb3c4865b16bbd770a71d0fc83d88c..249c270da8af7982446101c0e4ddd94a312c80a7 100644 (file)
@@ -87,6 +87,15 @@ enum SYNCReasonCode {
     afs_int64 _##buf##_l[SYNC_PROTO_MAX_LEN/sizeof(afs_int64)]; \
     char * buf = (char *)(_##buf##_l)
 
+#ifdef AFS_LINUX26_ENV
+/* Some Linux kernels have a bug where we are not woken up immediately from a
+ * select() when data is available. Work around this by having a low select()
+ * timeout, so we don't hang in those situations. */
+# define SYNC_SELECT_TIMEOUT 10
+#else
+# define SYNC_SELECT_TIMEOUT 86400
+#endif
+
 #ifdef USE_UNIX_SOCKETS
 #include <afs/afsutil.h>
 #include <sys/un.h>
index 616db044541e6c58f8baad0e15c1c71f188120d2..f5b915e991ab524be18f467b472b8e04cb0f206e 100644 (file)
@@ -332,12 +332,15 @@ FSYNC_sync(void * args)
            CallHandler(FSYNC_readfds, nfds, POLLIN|POLLPRI);
 #else
        int maxfd;
+       struct timeval s_timeout;
        GetHandler(&FSYNC_readfds, &maxfd);
+       s_timeout.tv_sec = SYNC_SELECT_TIMEOUT;
+       s_timeout.tv_usec = 0;
        /* Note: check for >= 1 below is essential since IOMGR_select
         * doesn't have exactly same semantics as select.
         */
 #ifdef AFS_PTHREAD_ENV
-       if (select(maxfd + 1, &FSYNC_readfds, NULL, NULL, NULL) >= 1)
+       if (select(maxfd + 1, &FSYNC_readfds, NULL, NULL, &s_timeout) >= 1)
 #else /* AFS_PTHREAD_ENV */
        if (IOMGR_Select(maxfd + 1, &FSYNC_readfds, NULL, NULL, NULL) >= 1)
 #endif /* AFS_PTHREAD_ENV */
index f6b530a225136b7f53be540782bda3bdbd643f85..f054dd6c6512ecff81fb1f3cafa1beadc7634c55 100644 (file)
@@ -342,11 +342,14 @@ SALVSYNC_syncThread(void * args)
 
     for (;;) {
        int maxfd;
+       struct timeval s_timeout;
        GetHandler(&SALVSYNC_readfds, &maxfd);
+       s_timeout.tv_sec = SYNC_SELECT_TIMEOUT;
+       s_timeout.tv_usec = 0;
        /* Note: check for >= 1 below is essential since IOMGR_select
         * doesn't have exactly same semantics as select.
         */
-       if (select(maxfd + 1, &SALVSYNC_readfds, NULL, NULL, NULL) >= 1)
+       if (select(maxfd + 1, &SALVSYNC_readfds, NULL, NULL, &s_timeout) >= 1)
            CallHandler(&SALVSYNC_readfds);
     }