viced-set-fssync-threadid-20030304
[openafs.git] / src / viced / viced.c
index e66c114..c209c6e 100644 (file)
@@ -85,6 +85,9 @@ RCSID("$Header$");
 #endif
 #include "viced.h"
 #include "host.h"
+#ifdef AFS_PTHREAD_ENV
+#include "softsig.h"
+#endif
 #if defined(AFS_SGI_ENV)
 #include "sys/schedctl.h"
 #include "sys/lock.h"
@@ -93,6 +96,8 @@ RCSID("$Header$");
 
 
 extern int      BreakVolumeCallBacks(), InitCallBack();
+extern int      BreakVolumeCallBacks(), InitCallBack(), BreakLaterCallBacks();
+extern int BreakVolumeCallBacksLater();
 extern int     LogLevel, etext;
 extern afs_int32       BlocksSpare, PctSpare;
 
@@ -108,6 +113,13 @@ int eventlog = 0, rxlog = 0;
 FILE *debugFile;
 FILE * console = NULL;
 
+#ifdef AFS_PTHREAD_ENV
+pthread_mutex_t fsync_glock_mutex;
+pthread_cond_t fsync_cond;
+#else 
+char fsync_wait[1];
+#endif /* AFS_PTHREAD_ENV */
+
 #ifdef AFS_NT40_ENV
 #define AFS_QUIETFS_ENV 1
 #define NT_OPEN_MAX    1024 /* This is an arbitrary no. we came up with for 
@@ -135,6 +147,7 @@ struct afs_PerfStats afs_perfstats;
 extern int     LogLevel;
 extern int     Statistics;
 
+int     busyonrst = 1;
 int     timeout = 30;
 int    SawSpare;
 int    SawPctSpare;
@@ -164,7 +177,9 @@ int     lwps = 9;           /* 6 */
 int     buffs = 90;            /* 70 */
 int    novbc = 0;              /* Enable Volume Break calls */
 int     busy_threshold = 600;
+int    abort_threshold = 10;
 int    udpBufSize = 0;         /* UDP buffer size for receive*/
+int    sendBufSize = 16384;    /* send buffer size */
 
 struct timeval  tp;
 
@@ -225,22 +240,34 @@ int fs_rxstat_userok(struct rx_call *call)
 
 static void ResetCheckSignal(void)
 {
-#ifdef AFS_HPUX_ENV
-    signal(SIGPOLL, CheckSignal_Signal);
+    int signo;
+
+#if defined(AFS_HPUX_ENV)
+    signo = SIGPOLL;
 #else
-#ifdef AFS_NT40_ENV
-    signal(SIGUSR2, CheckSignal_Signal);
+#if defined(AFS_NT40_ENV)
+    signo = SIGUSR2;
 #else
-    signal(SIGXCPU, CheckSignal_Signal);
+    signo = SIGXCPU;
 #endif
 #endif
+
+#if defined(AFS_PTHREAD_ENV)
+    softsig_signal(signo, CheckSignal_Signal);
+#else
+    signal(signo, CheckSignal_Signal);
+#endif
 }
 
 static void ResetCheckDescriptors(void)
 {
 #ifndef AFS_NT40_ENV
+#if defined(AFS_PTHREAD_ENV)
+    softsig_signal(SIGTERM, CheckDescriptors_Signal);
+#else
     signal(SIGTERM, CheckDescriptors_Signal);
 #endif
+#endif
 }
 
 
@@ -309,6 +336,18 @@ CheckAdminName()
 } /*CheckAdminName*/
 
 
+static void setThreadId(char *s)
+{
+#ifdef AFS_PTHREAD_ENV
+    /* set our 'thread-id' so that the host hold table works */
+    MUTEX_ENTER(&rx_stats_mutex);   /* protects rxi_pthread_hinum */ 
+    ++rxi_pthread_hinum;
+    pthread_setspecific(rx_thread_id_key, (void *)rxi_pthread_hinum);
+    MUTEX_EXIT(&rx_stats_mutex);
+    ViceLog(0,("Set thread id %d for '%s'\n", pthread_getspecific(rx_thread_id_key), s));
+#endif
+}
+
 /* This LWP does things roughly every 5 minutes */
 static void FiveMinuteCheckLWP()
 {
@@ -316,6 +355,7 @@ static void FiveMinuteCheckLWP()
     char tbuffer[32];
 
     ViceLog(1, ("Starting five minute check process\n"));
+    setThreadId("FiveMinuteCheckLWP");
     while (1) {
 #ifdef AFS_PTHREAD_ENV
        sleep(fiveminutes);
@@ -331,6 +371,10 @@ static void FiveMinuteCheckLWP()
        ViceLog(2, ("Set disk usage statistics\n"));
        VSetDiskUsage();
        if (FS_registered == 1) Do_VLRegisterRPC();
+       /* Force wakeup in case we missed something; pthreads does timedwait */
+#ifndef AFS_PTHREAD_ENV
+       LWP_NoYieldSignal(&fsync_wait);
+#endif
        if(printBanner && (++msg&1)) { /* Every 10 minutes */
            time_t now = FT_ApproxTime();
            if (console != NULL) {
@@ -353,6 +397,7 @@ static void FiveMinuteCheckLWP()
 static void HostCheckLWP()
 {
     ViceLog(1, ("Starting Host check process\n"));
+    setThreadId("HostCheckLWP");
     while(1) {
 #ifdef AFS_PTHREAD_ENV
        sleep(fiveminutes);
@@ -364,6 +409,46 @@ static void HostCheckLWP()
     }
 } /*HostCheckLWP*/
 
+/* This LWP does fsync checks every 5 minutes:  it should not be used for
+ * other 5 minute activities because it may be delayed by timeouts when
+ * it probes the workstations
+ */
+static FsyncCheckLWP()
+{
+    afs_int32 code;
+#ifdef AFS_PTHREAD_ENV
+    struct timespec fsync_next;
+#endif
+    ViceLog(1, ("Starting fsync check process\n"));
+
+    setThreadId("FsyncCheckLWP");
+
+#ifdef AFS_PTHREAD_ENV
+    assert(pthread_cond_init(&fsync_cond, NULL) == 0);
+    assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
+#endif
+
+    FSYNC_LOCK
+    while(1) {
+#ifdef AFS_PTHREAD_ENV
+       /* rounding is fine */
+       fsync_next.tv_nsec = 0;
+       fsync_next.tv_sec = time(0) + fiveminutes;
+       
+       code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex, 
+                                     &fsync_next);
+       if (code != 0 && code != ETIMEDOUT) 
+           ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
+#else /* AFS_PTHREAD_ENV */
+       if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
+           ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
+#endif /* AFS_PTHREAD_ENV */
+       ViceLog(2, ("Checking for fsync events\n"));
+       do {
+           code = BreakLaterCallBacks();
+       } while (code != 0);
+    }
+} 
 
 /*------------------------------------------------------------------------
  * PRIVATE ClearXStatValues
@@ -567,6 +652,7 @@ static void FlagMsg()
     strcat(buffer, "[-readonly (read-only file server)] ");
     strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
     strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
+    strcat(buffer, "[-nobusy <no VBUSY before a volume is attached>] ");
     strcat(buffer, "[-rxpck <number of rx extra packets>] ");
     strcat(buffer, "[-rxdbg (enable rx debugging)] ");
     strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
@@ -581,6 +667,7 @@ static void FlagMsg()
     strcat(buffer, "[-k <stack size>] ");
     strcat(buffer, "[-realm <Kerberos realm name>] ");
     strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
+    strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
 /*   strcat(buffer, "[-enable_peer_stats] "); */
 /*   strcat(buffer, "[-enable_process_stats] "); */
     strcat(buffer, "[-help]\n");
@@ -739,6 +826,10 @@ static int ParseArgs(int argc, char *argv[])
                nSmallVns = atoi(argv[++i]);
            }
        else    
+           if (!strcmp(argv[i], "-abortthreshold")) {
+               abort_threshold = atoi(argv[++i]);
+           }
+       else    
            if (!strcmp(argv[i], "-k"))
                stack = atoi(argv[++i]);
 #if defined(AFS_SGI_ENV)
@@ -795,7 +886,10 @@ static int ParseArgs(int argc, char *argv[])
                           busy_threshold);
                    Sawbusy = 0;
                }
-           }
+             }
+           else
+             if (!strcmp(argv[i], "-nobusy")) 
+               busyonrst=0;
 #ifdef AFS_AIX32_ENV
        else
            if (!strcmp(argv[i], "-m")) {
@@ -834,6 +928,19 @@ static int ParseArgs(int argc, char *argv[])
                    udpBufSize = bufSize;
            }
        else
+           if ( !strcmp(argv[i], "-sendsize")) {
+               if ( (i+1) >= argc ) {
+                   printf("You have to specify -sendsize <integer value>\n");
+                   return -1;
+               }
+               bufSize = atoi(argv[++i]);
+               if ( bufSize < 16384 )
+                   printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
+                               bufSize, 16384);
+               else
+                   sendBufSize = bufSize;
+           }
+       else
            if (!strcmp(argv[i], "-enable_peer_stats")) {
                rx_enablePeerRPCStats();
            }
@@ -892,7 +999,8 @@ static int ParseArgs(int argc, char *argv[])
 static void NewParms(int initializing)
 {
     static struct stat sbuf;
-    register int i, fd;
+    register afs_offs_t i;
+    register int fd;
     char *parms;
     char *argv[MAXPARMS];
     register int argc;
@@ -1180,25 +1288,7 @@ Do_VLRegisterRPC() {
     return 0;
 }
 
-#if 0
-static int AddrsEqual(cnt, addr1, addr2) 
-    int cnt;
-    afs_int32 *addr1, *addr2; 
-{
-    register int i, j;
-
-    for (i = 0; i < cnt; i++) {
-       for (j = 0; j < cnt; j++) {
-           if (addr1[i] == addr2[j]) break;
-       }
-       if (j == cnt) return 0;
-    }
-    return 1;
-}
-#endif
-
-afs_int32 
-InitVL() {
+afs_int32 InitVL() {
     int (*old)();
     afs_int32 code;
     afs_int32 cnt, i;
@@ -1271,7 +1361,6 @@ main(int argc, char * argv[])
 #ifdef AFS_PTHREAD_ENV
     pthread_t parentPid, serverPid;
     pthread_attr_t tattr;
-    AFS_SIGSET_DECL;
 #else /* AFS_PTHREAD_ENV */
     PROCESS parentPid, serverPid;
 #endif /* AFS_PTHREAD_ENV */
@@ -1344,6 +1433,11 @@ main(int argc, char * argv[])
     ViceLog(0, ("File server starting\n"));
 #endif
 
+#if defined(AFS_PTHREAD_ENV)
+    /* initialize the pthread soft signal handler thread */
+    softsig_init();
+#endif
+
     /* install signal handlers for controlling the fileserver process */
     ResetCheckSignal();  /* set CheckSignal_Signal() sig handler */
     ResetCheckDescriptors();  /* set CheckDescriptors_Signal() sig handler */
@@ -1408,7 +1502,7 @@ main(int argc, char * argv[])
 
     /* Initialize volume support */
     if (!novbc) {
-       V_BreakVolumeCallbacks = BreakVolumeCallBacks;
+       V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
     }
 
     /* initialize libacl routines */
@@ -1421,8 +1515,8 @@ main(int argc, char * argv[])
     rx_extraPackets = rxpackets;
     rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
     rx_SetBusyThreshold(busy_threshold, VBUSY);
-    rx_SetCallAbortThreshold(10);
-    rx_SetConnAbortThreshold(10);
+    rx_SetCallAbortThreshold(abort_threshold);
+    rx_SetConnAbortThreshold(abort_threshold);
     stackSize = lwps * 4000;
     if (stackSize < 32000)
        stackSize = 32000;
@@ -1543,17 +1637,18 @@ main(int argc, char * argv[])
 #ifdef AFS_PTHREAD_ENV
     assert(pthread_attr_init(&tattr) == 0);
     assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
-    /* Block signals in the threads */
-    AFS_SIGSET_CLEAR();
+
     assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
     assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
-    AFS_SIGSET_RESTORE();
+    assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
 #else /* AFS_PTHREAD_ENV */
     assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
                             (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
            
     assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
            (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
+    assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
+           (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
 #endif /* AFS_PTHREAD_ENV */
 
     TM_GetTimeOfDay(&tp, 0);
@@ -1589,8 +1684,14 @@ main(int argc, char * argv[])
                   FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
     }
 
-    /* Install handler to catch the shutdown signal */
-    signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
+    /* Install handler to catch the shutdown signal;
+     * bosserver assumes SIGQUIT shutdown
+     */
+#if defined(AFS_PTHREAD_ENV)
+    softsig_signal(SIGQUIT, ShutDown_Signal);
+#else
+    signal(SIGQUIT, ShutDown_Signal);
+#endif
 
     ViceLog(0,("File Server started %s",
               afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));