2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* viced.c - File Server main loop */
14 /* Function - This routine has the initialization code for */
17 /* ********************************************************************** */
19 #include <afsconfig.h>
20 #include <afs/param.h>
27 #include <sys/types.h>
28 #include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
34 #include <WINNT/afsevent.h>
37 #include <netinet/in.h>
39 #include <unistd.h> /* sysconf() */
51 #endif /* ITIMER_REAL */
52 #include <sys/resource.h>
53 #endif /* AFS_NT40_ENV */
58 #ifdef AFS_PTHREAD_ENV
60 #else /* AFS_PTHREAD_ENV */
61 #include <afs/assert.h>
62 #endif /* AFS_PTHREAD_ENV */
65 #include <afs/ptclient.h>
66 #include <afs/afsint.h>
67 #include <afs/vldbint.h>
68 #include <afs/errors.h>
69 #include <afs/ihandle.h>
70 #include <afs/vnode.h>
71 #include <afs/volume.h>
73 #include <afs/cellconfig.h>
75 #include <afs/prs_fs.h>
79 #include <afs/afs_args.h>
80 #include <afs/vlserver.h>
81 #include <afs/afsutil.h>
82 #include <afs/fileutil.h>
84 #include <afs/netutils.h>
88 #ifdef AFS_PTHREAD_ENV
91 #if defined(AFS_SGI_ENV)
92 #include "sys/schedctl.h"
95 #include <rx/rx_globals.h>
98 extern int BreakVolumeCallBacks(), InitCallBack();
99 extern int BreakVolumeCallBacks(), InitCallBack(), BreakLaterCallBacks();
100 extern int BreakVolumeCallBacksLater();
101 extern int LogLevel, etext;
102 extern afs_int32 BlocksSpare, PctSpare;
105 static void ClearXStatValues(), NewParms(), PrintCounters();
106 static void ResetCheckDescriptors(void), ResetCheckSignal(void);
107 static void CheckSignal(void);
108 extern int GetKeysFromToken();
109 extern int RXAFS_ExecuteRequest();
110 extern int RXSTATS_ExecuteRequest();
112 int eventlog = 0, rxlog = 0;
114 FILE * console = NULL;
116 #ifdef AFS_PTHREAD_ENV
117 pthread_mutex_t fsync_glock_mutex;
118 pthread_cond_t fsync_cond;
121 #endif /* AFS_PTHREAD_ENV */
124 #define AFS_QUIETFS_ENV 1
125 #define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
126 * now. We hope this will be replaced by a more
127 * intelligent estimate later. */
130 int SystemId; /* ViceID of "Administrators"*/
131 int SystemAnyUser; /* Viceid of "System:AnyUser" */
132 prlist SystemAnyUserCPS; /* CPS for "system:AnyUser */
133 int AnonymousID = 0; /* ViceId of "Anonymous"*/
134 prlist AnonCPS; /* CPS for "Anonymous"*/
136 struct afsconf_dir *confDir; /* Configuration dir object */
138 int restartMode = RESTART_ORDINARY;
140 int Testing = 0; /* for ListViceInodes */
143 * Home for the performance statistics.
145 struct afs_PerfStats afs_perfstats;
148 extern int Statistics;
155 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
156 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
158 afs_int32 readonlyServer = 0;
161 int stackSize = 24000;
162 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
163 int CurrentConnections = 0;
164 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
165 #if defined(AFS_SGI_ENV)
170 int rxpackets = 150; /* 100 */
171 int nSmallVns = 400; /* 200 */
172 int large = 400; /* 200 */
173 int volcache = 400; /* 400 */
174 int numberofcbs = 60000; /* 60000 */
175 int lwps = 9; /* 6 */
176 int buffs = 90; /* 70 */
177 int novbc = 0; /* Enable Volume Break calls */
178 int busy_threshold = 600;
179 int udpBufSize = 0; /* UDP buffer size for receive*/
180 int sendBufSize = 16384; /* send buffer size */
185 * FileServer's name and IP address, both network byte order and
188 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
190 char FS_HostName[128] = "localhost";
191 afs_uint32 FS_HostAddr_NBO;
192 afs_uint32 FS_HostAddr_HBO;
193 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
194 /* All addresses in FS_HostAddrs are in NBO */
197 static void FlagMsg();
200 * Home for the performance statistics.
204 static void CheckDescriptors()
208 register int tsize = getdtablesize();
210 for (i = 0; i<tsize; i++) {
211 if (fstat(i, &status) != -1) {
212 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
213 i, status.st_dev, status.st_ino,
214 status.st_size, status.st_mode);
218 ResetCheckDescriptors();
220 } /*CheckDescriptors*/
223 #ifdef AFS_PTHREAD_ENV
224 void CheckSignal_Signal(x) {CheckSignal();}
225 void ShutDown_Signal(x) {ShutDown();}
226 void CheckDescriptors_Signal(x) {CheckDescriptors();}
227 #else /* AFS_PTHREAD_ENV */
228 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
229 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
230 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
231 #endif /* AFS_PTHREAD_ENV */
233 /* check whether caller is authorized to manage RX statistics */
234 int fs_rxstat_userok(struct rx_call *call)
236 return afsconf_SuperUser(confDir, call, NULL);
239 static void ResetCheckSignal(void)
243 #if defined(AFS_HPUX_ENV)
245 #elsif defined(AFS_NT40_ENV)
251 #if defined(AFS_PTHREAD_ENV)
252 softsig_signal(signo, CheckSignal_Signal);
254 signal(signo, CheckSignal_Signal);
258 static void ResetCheckDescriptors(void)
261 #if defined(AFS_PTHREAD_ENV)
262 softsig_signal(SIGTERM, CheckDescriptors_Signal);
264 signal(SIGTERM, CheckDescriptors_Signal);
270 /* proc called by rxkad module to get a key */
271 static int get_key(char *arock, register afs_int32 akvno, char *akey)
274 static struct afsconf_key tkey;
275 register afs_int32 code;
278 ViceLog(0, ("conf dir not open\n"));
281 code = afsconf_GetKey(confDir, akvno, tkey.key);
284 memcpy(akey, tkey.key, sizeof(tkey.key));
290 int viced_syscall(afs_uint32 a3, afs_uint32 a4, void * a5)
295 #ifndef AFS_LINUX20_ENV
296 old = (void (*)())signal(SIGSYS, SIG_IGN);
298 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
299 #ifndef AFS_LINUX20_ENV
307 #if !defined(AFS_NT40_ENV)
308 #include "AFS_component_version_number.c"
309 #endif /* !AFS_NT40_ENV */
311 #define MAXADMINNAME 64
312 char adminName[MAXADMINNAME];
320 if ((stat("/AdminName", &status)) || /* if file does not exist */
321 (status.st_size <= 0) || /* or it is too short */
322 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
323 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
324 strcpy(adminName, "System:Administrators"); /* use the default name */
327 read(fd, adminName, status.st_size); /* use name from the file */
330 close(fd); /* close fd if it was opened */
335 /* This LWP does things roughly every 5 minutes */
336 static void FiveMinuteCheckLWP()
341 ViceLog(1, ("Starting five minute check process\n"));
343 #ifdef AFS_PTHREAD_ENV
345 #else /* AFS_PTHREAD_ENV */
346 IOMGR_Sleep(fiveminutes);
347 #endif /* AFS_PTHREAD_ENV */
349 /* close the log so it can be removed */
350 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
351 ViceLog(2, ("Cleaning up timed out callbacks\n"));
352 if(CleanupTimedOutCallBacks())
353 ViceLog(5,("Timed out callbacks deleted\n"));
354 ViceLog(2, ("Set disk usage statistics\n"));
356 if (FS_registered == 1) Do_VLRegisterRPC();
357 /* Force wakeup in case we missed something; pthreads does timedwait */
358 #ifndef AFS_PTHREAD_ENV
359 LWP_NoYieldSignal(&fsync_wait);
361 if(printBanner && (++msg&1)) { /* Every 10 minutes */
362 time_t now = FT_ApproxTime();
363 if (console != NULL) {
364 #ifndef AFS_QUIETFS_ENV
365 fprintf(console,"File server is running at %s\r",
366 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
367 #endif /* AFS_QUIETFS_ENV */
368 ViceLog(2, ("File server is running at %s\n",
369 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
373 } /*FiveMinuteCheckLWP*/
376 /* This LWP does host checks every 5 minutes: it should not be used for
377 * other 5 minute activities because it may be delayed by timeouts when
378 * it probes the workstations
380 static void HostCheckLWP()
382 ViceLog(1, ("Starting Host check process\n"));
384 #ifdef AFS_PTHREAD_ENV
386 #else /* AFS_PTHREAD_ENV */
387 IOMGR_Sleep(fiveminutes);
388 #endif /* AFS_PTHREAD_ENV */
389 ViceLog(2, ("Checking for dead venii & clients\n"));
394 /* This LWP does fsync checks every 5 minutes: it should not be used for
395 * other 5 minute activities because it may be delayed by timeouts when
396 * it probes the workstations
398 static FsyncCheckLWP()
401 #ifdef AFS_PTHREAD_ENV
402 struct timespec fsync_next;
404 ViceLog(1, ("Starting fsync check process\n"));
406 #ifdef AFS_PTHREAD_ENV
407 assert(pthread_cond_init(&fsync_cond, NULL) == 0);
408 assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
413 #ifdef AFS_PTHREAD_ENV
414 /* rounding is fine */
415 fsync_next.tv_nsec = 0;
416 fsync_next.tv_sec = time(0) + fiveminutes;
418 code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex,
420 if (code != 0 && code != ETIMEDOUT)
421 ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
422 #else /* AFS_PTHREAD_ENV */
423 if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
424 ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
425 #endif /* AFS_PTHREAD_ENV */
426 ViceLog(2, ("Checking for fsync events\n"));
428 code = BreakLaterCallBacks();
433 /*------------------------------------------------------------------------
434 * PRIVATE ClearXStatValues
437 * Initialize all of the values collected via the xstat
447 * Must be called during File Server initialization.
451 *------------------------------------------------------------------------*/
453 static void ClearXStatValues()
454 { /*ClearXStatValues*/
456 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
457 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
458 int i; /*Loop counter*/
461 * Zero all xstat-related structures.
463 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
464 #if FS_STATS_DETAILED
465 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
468 * That's not enough. We have to set reasonable minima for
469 * time and xfer values in the detailed stats.
471 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
472 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
473 opTimeP->minTime.tv_sec = 999999;
475 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
476 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
477 opXferP->minTime.tv_sec = 999999;
478 opXferP->minBytes = 999999999;
482 * There's more. We have to set our unique system identifier, as
483 * declared in param.h. If such a thing is not defined, we bitch
484 * and declare ourselves to be an unknown system type.
487 afs_perfstats.sysname_ID = SYS_NAME_ID;
490 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
491 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
493 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
494 #endif /* SYS_NAME_ID */
497 } /*ClearXStatValues*/
500 static void PrintCounters()
502 int dirbuff, dircall, dirio;
504 int workstations, activeworkstations, delworkstations;
508 TM_GetTimeOfDay(&tpl, 0);
510 ViceLog(0, ("Vice was last started at %s\n",
511 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
515 DStat(&dirbuff, &dircall, &dirio);
516 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
517 dirbuff, dircall, dirio));
518 rx_PrintStats(stderr);
520 PrintCallBackStats();
522 processSize = -1; /* TODO: */
524 processSize = (int)((long) sbrk(0) >> 10);
526 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
527 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
530 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
531 workstations, activeworkstations, delworkstations));
538 static void CheckSignal()
540 if (FS_registered > 0) {
542 * We have proper ip addresses; tell the vlserver what we got; the following
543 * routine will do the proper reporting for us
555 void ShutDownAndCore(int dopanic)
557 time_t now = time(0);
561 ViceLog(0, ("Shutting down file server at %s",
562 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
564 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
565 #ifndef AFS_QUIETFS_ENV
566 if (console != NULL) {
567 fprintf(console,"File server restart/shutdown received at %s\r",
568 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
574 /* do not allows new reqests to be served from now on, all new requests
575 are returned with an error code of RX_RESTARTING ( transient failure ) */
576 rx_SetRxTranquil(); /* dhruba */
580 rx_PrintStats(debugFile);
583 if (console != NULL) {
586 #ifndef AFS_QUIETFS_ENV
587 fprintf(console, "File server has terminated abnormally at %s\r",
588 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
590 ViceLog(0, ("File server has terminated abnormally at %s\n",
591 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
593 #ifndef AFS_QUIETFS_ENV
594 fprintf(console, "File server has terminated normally at %s\r",
595 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
597 ViceLog(0, ("File server has terminated normally at %s\n",
598 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
606 void ShutDown(void) /* backward compatibility */
608 ShutDownAndCore(DONTPANIC);
612 static void FlagMsg()
616 /* default supports help flag */
618 strcpy(buffer, "Usage: fileserver ");
619 strcat(buffer, "[-d <debug level>] ");
620 strcat(buffer, "[-p <number of processes>] ");
621 strcat(buffer, "[-spare <number of spare blocks>] ");
622 strcat(buffer, "[-pctspare <percentage spare>] ");
623 strcat(buffer, "[-b <buffers>] ");
624 strcat(buffer, "[-l <large vnodes>] ");
625 strcat(buffer, "[-s <small vnodes>] ");
626 strcat(buffer, "[-vc <volume cachesize>] ");
627 strcat(buffer, "[-w <call back wait interval>] ");
628 strcat(buffer, "[-cb <number of call backs>] ");
629 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
630 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
631 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
632 strcat(buffer, "[-readonly (read-only file server)] ");
633 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
634 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
635 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
636 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
637 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
639 strcat(buffer, "[-m <min percentage spare in partition>] ");
641 #if defined(AFS_SGI_ENV)
642 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
644 strcat(buffer, "[-L (large server conf)] ");
645 strcat(buffer, "[-S (small server conf)] ");
646 strcat(buffer, "[-k <stack size>] ");
647 strcat(buffer, "[-realm <Kerberos realm name>] ");
648 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
649 strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
650 /* strcat(buffer, "[-enable_peer_stats] "); */
651 /* strcat(buffer, "[-enable_process_stats] "); */
652 strcat(buffer, "[-help]\n");
654 ViceLog(0, ("%s", buffer));
663 static afs_int32 ParseRights(char *arights)
669 if (!arights || !strcmp(arights, "")) {
670 printf("Missing list of mode bits on -implicit option\n");
673 if (!strcmp(arights, "none"))
675 else if (!strcmp(arights, "read"))
676 mode = PRSFS_READ | PRSFS_LOOKUP;
677 else if (!strcmp(arights, "write"))
678 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
679 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
680 else if (!strcmp(arights, "all"))
681 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
682 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
684 len = strlen(arights);
687 if (tc == 'r') mode |= PRSFS_READ;
688 else if (tc == 'l') mode |= PRSFS_LOOKUP;
689 else if (tc == 'i') mode |= PRSFS_INSERT;
690 else if (tc == 'd') mode |= PRSFS_DELETE;
691 else if (tc == 'w') mode |= PRSFS_WRITE;
692 else if (tc == 'k') mode |= PRSFS_LOCK;
693 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
694 else if (tc == 'A') mode |= PRSFS_USR0;
695 else if (tc == 'B') mode |= PRSFS_USR1;
696 else if (tc == 'C') mode |= PRSFS_USR2;
697 else if (tc == 'D') mode |= PRSFS_USR3;
698 else if (tc == 'E') mode |= PRSFS_USR4;
699 else if (tc == 'F') mode |= PRSFS_USR5;
700 else if (tc == 'G') mode |= PRSFS_USR6;
701 else if (tc == 'H') mode |= PRSFS_USR7;
703 printf("Illegal -implicit rights character '%c'.\n", tc);
712 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
713 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
716 * AIX: sysconf() limit is real
717 * HP-UX: sysconf() limit is real
718 * IRIX: sysconf() limit is apparently NOT real -- too small
719 * DUX: sysconf() limit is apparently NOT real -- too big
720 * Linux: sysconf() limit is apparently NOT real -- too big
721 * Solaris: no sysconf() limit
724 max_fileserver_thread(void)
726 #if defined(AFS_PTHREAD_ENV)
727 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
730 ans = sysconf(_SC_THREAD_THREADS_MAX);
731 if (0 < ans && ans < MAX_FILESERVER_THREAD)
734 #endif /* defined(AFS_PTHREAD_ENV) */
735 return MAX_FILESERVER_THREAD;
738 static int ParseArgs(int argc, char *argv[])
740 int SawL=0, SawS=0, SawVC=0;
741 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
744 int bufSize = 0; /* temp variable to read in udp socket buf size*/
746 for (i = 1; i < argc; i++) {
747 if (!strcmp(argv[i], "-d")) {
748 debuglevel = atoi(argv[++i]);
749 LogLevel = debuglevel;
752 if (!strcmp(argv[i], "-banner")) {
755 if (!strcmp(argv[i], "-implicit")) {
756 implicitAdminRights = ParseRights(argv[++i]);
757 if (implicitAdminRights < 0) return implicitAdminRights;
759 if (!strcmp(argv[i], "-readonly")) {
762 if (!strcmp(argv[i], "-L")) {
765 if (!strcmp(argv[i], "-S")) {
769 if (!strcmp(argv[i], "-p")) {
770 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
772 lwps = atoi(argv[++i]);
779 if (!strcmp(argv[i], "-b")) {
781 buffs = atoi(argv[++i]);
784 if (!strcmp(argv[i], "-l")) {
786 large = atoi(argv[++i]);
789 if (!strcmp(argv[i], "-vc")) {
791 volcache = atoi(argv[++i]);
794 if (!strcmp(argv[i], "-novbc")) {
798 if (!strcmp(argv[i], "-rxpck")) {
800 rxpackets = atoi(argv[++i]);
803 if (!strcmp(argv[i], "-s")) {
805 nSmallVns = atoi(argv[++i]);
808 if (!strcmp(argv[i], "-k"))
809 stack = atoi(argv[++i]);
810 #if defined(AFS_SGI_ENV)
812 if (!strcmp(argv[i], "-lock")) {
817 if (!strcmp(argv[i], "-spare")) {
818 BlocksSpare = atoi(argv[++i]);
822 if (!strcmp(argv[i], "-pctspare")) {
823 PctSpare = atoi(argv[++i]);
824 BlocksSpare = 0; /* has non-zero default */
828 if (!strcmp(argv[i], "-w"))
829 fiveminutes = atoi(argv[++i]);
831 if (!strcmp(argv[i], "-hr")) {
832 int hr = atoi(argv[++i]);
833 if ((hr < 1) || (hr > 36)) {
834 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
838 hostaclRefresh = hr*60*60;
840 if (!strcmp(argv[i], "-rxdbg"))
843 if (!strcmp(argv[i], "-rxdbge"))
846 if (!strcmp(argv[i], "-cb")) {
848 numberofcbs = atoi(argv[++i]);
849 if ((numberofcbs < 10000) || (numberofcbs > 2147483647)) {
850 printf("number of cbs %d invalid; must be between 10000 and 2147483647\n",
856 if (!strcmp(argv[i], "-busyat")) {
858 busy_threshold = atoi(argv[++i]);
859 if (busy_threshold < 10) {
860 printf("Busy threshold %d is too low, will compute default.\n",
867 if (!strcmp(argv[i], "-m")) {
868 extern int aixlow_water;
869 aixlow_water = atoi(argv[++i]);
870 if ((aixlow_water < 0) || (aixlow_water > 30)) {
871 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
877 if (!strcmp(argv[i], "-nojumbo")) {
881 if (!strcmp(argv[i], "-realm")) {
882 extern char local_realm[AFS_REALM_SZ];
883 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
884 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
887 strncpy (local_realm, argv[i], AFS_REALM_SZ);
890 if ( !strcmp(argv[i], "-udpsize")) {
891 if ( (i+1) >= argc ) {
892 printf("You have to specify -udpsize <integer value>\n");
895 bufSize = atoi(argv[++i]);
896 if ( bufSize < rx_GetMinUdpBufSize() )
897 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
898 bufSize, rx_GetMinUdpBufSize() );
900 udpBufSize = bufSize;
903 if ( !strcmp(argv[i], "-sendsize")) {
904 if ( (i+1) >= argc ) {
905 printf("You have to specify -sendsize <integer value>\n");
908 bufSize = atoi(argv[++i]);
909 if ( bufSize < 16384 )
910 printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
913 sendBufSize = bufSize;
916 if (!strcmp(argv[i], "-enable_peer_stats")) {
917 rx_enablePeerRPCStats();
920 if (!strcmp(argv[i], "-enable_process_stats")) {
921 rx_enableProcessRPCStats();
925 if (strcmp(argv[i], "-syslog")==0) {
926 /* set syslog logging flag */
930 if (strncmp(argv[i], "-syslog=", 8)==0) {
932 serverLogSyslogFacility = atoi(argv[i]+8);
940 printf("Only one of -L, or -S must be specified\n");
944 if (!Sawrxpck) rxpackets = 100;
945 if (!Sawsmall) nSmallVns = 200;
946 if (!Sawlarge) large = 200;
947 if (!Sawcbs) numberofcbs = 20000;
948 if (!Sawlwps) lwps = 6;
949 if (!Sawbufs) buffs = 70;
950 if (!SawVC) volcache = 200;
953 if (!Sawrxpck) rxpackets = 200;
954 if (!Sawsmall) nSmallVns = 600;
955 if (!Sawlarge) large = 600;
956 if (!Sawcbs) numberofcbs = 64000;
957 if (!Sawlwps) lwps = 12;
958 if (!Sawbufs) buffs = 120;
959 if (!SawVC) volcache = 600;
962 busy_threshold = 3*rxpackets/2;
971 static void NewParms(int initializing)
973 static struct stat sbuf;
974 register afs_offs_t i;
977 char *argv[MAXPARMS];
980 if (!(stat("/vice/file/parms",&sbuf))) {
981 parms = (char *)malloc(sbuf.st_size);
983 fd = open("parms", O_RDONLY, 0666);
985 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
989 i = read(fd, parms, sbuf.st_size);
991 if(i != sbuf.st_size) {
993 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
996 ("Read on parms failed; expected %d bytes but read %d\n",
1003 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1005 for (argc = i = 0; i < sbuf.st_size; i++) {
1006 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1007 if(argv[argc] == 0) argv[argc] = (parms+i);
1010 *(parms + i) = '\0';
1011 if(argv[argc] != 0) {
1012 if(++argc == MAXPARMS) break;
1014 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1018 if(ParseArgs(argc, argv) == 0) {
1019 ViceLog(0, ("Change parameters to:"));
1021 ViceLog(0, ("Invalid parameter in:"));
1023 for(i = 0; i < argc; i++) {
1024 ViceLog(0, (" %s", argv[i]));
1031 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1036 /* Miscellaneous routines */
1037 void Die (char *msg)
1039 ViceLog (0,("%s\n", msg));
1050 * If this fails, it's because something major is wrong, and is not
1051 * likely to be time dependent.
1053 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1055 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1058 SystemId = SYSADMINID;
1059 SystemAnyUser = ANYUSERID;
1060 SystemAnyUserCPS.prlist_len = 0;
1061 SystemAnyUserCPS.prlist_val = NULL;
1062 AnonCPS.prlist_len = 0;
1063 AnonCPS.prlist_val = NULL;
1065 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1068 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1072 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1074 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1077 AnonymousID = ANONYMOUSID;
1080 #ifdef AFS_PTHREAD_ENV
1082 #else /* AFS_PTHREAD_ENV */
1084 #endif /* AFS_PTHREAD_ENV */
1088 struct rx_connection *serverconns[MAXSERVERS];
1089 struct ubik_client *cstruct;
1091 afs_int32 vl_Initialize(char *confDir)
1092 { afs_int32 code, scIndex = 0, i;
1093 struct afsconf_dir *tdir;
1094 struct rx_securityClass *sc;
1095 struct afsconf_cell info;
1097 tdir = afsconf_Open(confDir);
1099 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1102 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1104 ViceLog(0, ("Could not get security object for localAuth\n"));
1107 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1108 if (info.numServers > MAXSERVERS) {
1109 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1112 for (i = 0;i<info.numServers;i++)
1113 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1114 USER_SERVICE_ID, sc, scIndex);
1115 code = ubik_ClientInit(serverconns, &cstruct);
1117 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1123 #define SYSIDMAGIC 0x88aabbcc
1124 #define SYSIDVERSION 1
1128 afs_int32 fd, nentries, i;
1129 struct versionStamp vsn;
1133 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1134 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1137 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1138 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1141 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1142 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1145 if (vsn.magic != SYSIDMAGIC) {
1146 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1149 if (vsn.version != SYSIDVERSION) {
1150 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1153 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1154 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1157 afs_ntohuuid(&uuid);
1159 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1160 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1163 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1164 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1167 FS_HostAddr_cnt = nentries;
1168 for (i = 0; i < nentries; i++) {
1169 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1170 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1171 FS_HostAddr_cnt = 0; /* reset it */
1181 afs_int32 fd, nentries, i;
1182 struct versionStamp vsn;
1186 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1188 * File exists; keep the old one around
1190 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1192 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1194 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1197 vsn.magic = SYSIDMAGIC;
1199 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1200 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1204 afs_htonuuid(&uuid);
1205 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1206 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1209 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1210 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1213 for (i = 0; i < FS_HostAddr_cnt; i++) {
1214 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1215 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1225 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1226 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1227 * and so we need to convert each of them into HBO which is what the extra
1228 * array called FS_HostAddrs_HBO is used here.
1231 Do_VLRegisterRPC() {
1234 extern int VL_RegisterAddrs();
1235 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1238 for (i=0; i < FS_HostAddr_cnt ; i++)
1239 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1240 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1241 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1242 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1244 if (code == VL_MULTIPADDR) {
1245 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1246 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1248 } else if (code == RXGEN_OPCODE) {
1249 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1250 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1252 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1256 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1264 static int AddrsEqual(cnt, addr1, addr2)
1266 afs_int32 *addr1, *addr2;
1270 for (i = 0; i < cnt; i++) {
1271 for (j = 0; j < cnt; j++) {
1272 if (addr1[i] == addr2[j]) break;
1274 if (j == cnt) return 0;
1285 extern int rxi_numNetAddrs;
1286 extern afs_uint32 rxi_NetAddrs[];
1289 * If this fails, it's because something major is wrong, and is not
1290 * likely to be time dependent.
1292 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1294 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1298 /* Read or create the sysid file and register the fileserver's
1299 * IP addresses with the vlserver.
1301 code = ReadSysIdFile();
1303 /* Need to create the file */
1304 ViceLog(0, ("Creating new SysID file\n"));
1305 if ((code = afs_uuid_create(&FS_HostUUID))) {
1306 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1310 /* A good sysid file exists; inform the vlserver. If any conflicts,
1311 * we always use the latest interface available as the real truth.
1313 #ifndef AFS_NT40_ENV
1314 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1316 * Find addresses we are supposed to register as per the netrestrict
1317 * and netinfo files (/usr/afs/local/NetInfo and
1318 * /usr/afs/local/NetRestict)
1321 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1322 ADDRSPERSITE, reason,
1323 AFSDIR_SERVER_NETINFO_FILEPATH,
1324 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1326 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1329 FS_HostAddr_cnt = (afs_uint32) code;
1334 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1338 code = Do_VLRegisterRPC();
1343 main(int argc, char * argv[])
1349 struct rx_securityClass *sc[4];
1350 struct rx_service *tservice;
1351 #ifdef AFS_PTHREAD_ENV
1352 pthread_t parentPid, serverPid;
1353 pthread_attr_t tattr;
1354 #else /* AFS_PTHREAD_ENV */
1355 PROCESS parentPid, serverPid;
1356 #endif /* AFS_PTHREAD_ENV */
1358 int minVnodesRequired; /* min size of vnode cache */
1359 #ifndef AFS_NT40_ENV
1360 struct rlimit rlim; /* max number of open file descriptors */
1364 #ifdef AFS_AIX32_ENV
1365 struct sigaction nsa;
1367 sigemptyset(&nsa.sa_mask);
1368 nsa.sa_handler = SIG_DFL;
1369 nsa.sa_flags = SA_FULLDUMP;
1370 sigaction(SIGABRT, &nsa, NULL);
1371 sigaction(SIGSEGV, &nsa, NULL);
1374 /* Initialize dirpaths */
1375 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1377 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
1379 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
1383 #ifndef AFS_QUIETFS_ENV
1384 console = fopen("/dev/console","w");
1387 if(ParseArgs(argc,argv)) {
1392 #ifdef AFS_PTHREAD_ENV
1393 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
1394 #endif /* AFS_PTHREAD_ENV */
1396 #ifdef AFS_SGI_VNODE_GLUE
1397 if (afs_init_kernel_config(-1) <0) {
1398 printf("Can't determine NUMA configuration, not starting fileserver.\n");
1402 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
1404 fprintf(stderr, "Unable to open config directory %s\n",
1405 AFSDIR_SERVER_ETC_DIRPATH);
1411 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
1412 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
1415 if (SawSpare && SawPctSpare) {
1416 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
1420 #ifdef AFS_SGI_XFS_IOPS_ENV
1421 ViceLog(0, ("XFS/EFS File server starting\n"));
1423 ViceLog(0, ("File server starting\n"));
1426 #if defined(AFS_PTHREAD_ENV)
1427 /* initialize the pthread soft signal handler thread */
1431 /* install signal handlers for controlling the fileserver process */
1432 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
1433 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
1435 #if defined(AFS_SGI_ENV)
1436 /* give this guy a non-degrading priority so help busy servers */
1437 schedctl(NDPRI, 0, NDPNORMMAX);
1441 #ifndef AFS_NT40_ENV
1442 nice(-5); /* TODO: */
1445 assert(DInit(buffs) == 0);
1448 if (afs_winsockInit()<0) {
1449 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
1450 ViceLog(0, ("File server failed to intialize winsock.\n"));
1456 /* if we support more than 16 threads, then we better have the ability
1457 ** to keep open a large number of files simultaneously
1459 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
1460 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
1461 #elif defined(AFS_NT40_ENV)
1462 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
1465 curLimit = 0; /* the number of open file descriptors */
1466 code = getrlimit(RLIMIT_NOFILE, &rlim);
1468 curLimit = rlim.rlim_cur;
1469 rlim.rlim_cur = rlim.rlim_max;
1470 code = setrlimit(RLIMIT_NOFILE, &rlim);
1472 curLimit = rlim.rlim_max;
1475 ViceLog(0, ("Failed to increase open file limit, using default\n"));
1477 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
1479 curLimit -= 32; /* leave a slack of 32 file descriptors */
1480 if ( lwps > curLimit ) {
1483 else if ( lwps > 16 )
1484 lwps = 16; /* default to a maximum of 16 threads */
1485 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
1489 #ifndef AFS_PTHREAD_ENV
1490 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
1491 #endif /* !AFS_PTHREAD_ENV */
1493 /* Initialize volume support */
1495 V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
1498 /* initialize libacl routines */
1499 acl_Initialize(ACL_VERSION);
1501 /* initialize RX support */
1502 #ifndef AFS_NT40_ENV
1503 rxi_syscallp = viced_syscall;
1505 rx_extraPackets = rxpackets;
1506 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
1507 rx_SetBusyThreshold(busy_threshold, VBUSY);
1508 rx_SetCallAbortThreshold(10);
1509 rx_SetConnAbortThreshold(10);
1510 stackSize = lwps * 4000;
1511 if (stackSize < 32000)
1513 else if (stackSize > 44000)
1515 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
1516 rx_SetStackSize(1, stackSize);
1519 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
1520 if (rx_Init((int)htons(7000))<0) {
1521 ViceLog(0, ("Cannot initialize RX\n"));
1524 if (!rxJumbograms) {
1525 /* Don't send and don't allow 3.4 clients to send jumbograms. */
1529 rx_SetRxDeadTime(30);
1530 sc[0] = rxnull_NewServerSecurityObject();
1531 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
1532 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
1534 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
1536 tservice = rx_NewService
1537 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
1538 /* security classes */ sc, /* numb sec classes */ 4,
1539 RXAFS_ExecuteRequest);
1541 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
1544 rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
1545 rx_SetMinProcs(tservice, 3);
1546 rx_SetMaxProcs(tservice, lwps);
1547 rx_SetCheckReach(tservice, 1);
1549 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
1551 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
1554 rx_SetMinProcs(tservice, 2);
1555 rx_SetMaxProcs(tservice, 4);
1558 * Enable RX hot threads, which allows the listener thread to trade
1559 * places with an idle thread and moves the context switch from listener
1560 * to worker out of the critical path.
1562 rx_EnableHotThread();
1564 /* Some rx debugging */
1565 if (rxlog || eventlog) {
1566 debugFile = fopen("rx_dbg", "w");
1567 if (rxlog) rx_debugFile = debugFile;
1568 if (eventlog) rxevent_debugFile = debugFile;
1571 h_InitHostPackage(); /* set up local cellname and realmname */
1572 InitCallBack(numberofcbs);
1577 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
1583 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
1587 /* allow super users to manage RX statistics */
1588 rx_SetRxStatUserOk(fs_rxstat_userok);
1590 rx_StartServer(0); /* now start handling requests */
1592 /* we ensure that there is enough space in the vnode buffer to satisfy
1593 ** requests from all concurrent threads.
1594 ** the maximum number of vnodes used by a single thread at any one time
1595 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
1596 ** two vSmall for linking files and two vLarge and one vSmall for linking
1599 minVnodesRequired = 2 * lwps + 1;
1600 if ( minVnodesRequired > nSmallVns ) {
1601 nSmallVns = minVnodesRequired;
1602 ViceLog(0, ("Overriding -s command line parameter with %d\n",
1605 if ( minVnodesRequired > large ) {
1606 large = minVnodesRequired;
1607 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
1610 /* We now do this after getting the listener up and running, so that client
1611 connections don't timeout (maybe) if a file server is restarted, since it
1612 will be available "real soon now". Worry about whether we can satisfy the
1613 calls in the volume package itself.
1615 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
1616 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
1622 * We are done calling fopen/fdopen. It is safe to use a large
1623 * of the file descriptor cache.
1627 #ifdef AFS_PTHREAD_ENV
1628 assert(pthread_attr_init(&tattr) == 0);
1629 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
1631 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
1632 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
1633 assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
1634 #else /* AFS_PTHREAD_ENV */
1635 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1636 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
1638 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1639 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
1640 assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1641 (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
1642 #endif /* AFS_PTHREAD_ENV */
1644 TM_GetTimeOfDay(&tp, 0);
1646 #ifndef AFS_QUIETFS_ENV
1647 if (console != NULL) {
1648 fprintf(console, "File server has started at %s\r",
1649 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
1654 * Figure out the FileServer's name and primary address.
1656 ViceLog(0, ("Getting FileServer name...\n"));
1657 code = gethostname(FS_HostName, 64);
1659 ViceLog(0, ("gethostname() failed\n"));
1661 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
1663 ViceLog(0, ("Getting FileServer address...\n"));
1664 he = gethostbyname(FS_HostName);
1666 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
1670 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
1671 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
1672 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
1673 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
1674 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
1677 /* Install handler to catch the shutdown signal;
1678 * bosserver assumes SIGQUIT shutdown
1680 #if defined(AFS_PTHREAD_ENV)
1681 softsig_signal(SIGQUIT, ShutDown_Signal);
1683 signal(SIGQUIT, ShutDown_Signal);
1686 ViceLog(0,("File Server started %s",
1687 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
1688 #if FS_STATS_DETAILED
1689 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
1691 #ifdef AFS_PTHREAD_ENV
1693 sleep(1000); /* long time */
1695 #else /* AFS_PTHREAD_ENV */
1696 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
1697 #endif /* AFS_PTHREAD_ENV */