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 #if defined(AFS_SGI_ENV)
89 #include "sys/schedctl.h"
92 #include <rx/rx_globals.h>
95 extern int BreakVolumeCallBacks(), InitCallBack();
96 extern int BreakVolumeCallBacks(), InitCallBack(), BreakLaterCallBacks();
97 extern int BreakVolumeCallBacksLater();
98 extern int LogLevel, etext;
99 extern afs_int32 BlocksSpare, PctSpare;
102 static void ClearXStatValues(), NewParms(), PrintCounters();
103 static void ResetCheckDescriptors(void), ResetCheckSignal(void);
104 static void CheckSignal(void);
105 extern int GetKeysFromToken();
106 extern int RXAFS_ExecuteRequest();
107 extern int RXSTATS_ExecuteRequest();
109 int eventlog = 0, rxlog = 0;
111 FILE * console = NULL;
113 #ifdef AFS_PTHREAD_ENV
114 pthread_mutex_t fsync_glock_mutex;
115 pthread_cond_t fsync_cond;
118 #endif /* AFS_PTHREAD_ENV */
121 #define AFS_QUIETFS_ENV 1
122 #define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
123 * now. We hope this will be replaced by a more
124 * intelligent estimate later. */
127 int SystemId; /* ViceID of "Administrators"*/
128 int SystemAnyUser; /* Viceid of "System:AnyUser" */
129 prlist SystemAnyUserCPS; /* CPS for "system:AnyUser */
130 int AnonymousID = 0; /* ViceId of "Anonymous"*/
131 prlist AnonCPS; /* CPS for "Anonymous"*/
133 struct afsconf_dir *confDir; /* Configuration dir object */
135 int restartMode = RESTART_ORDINARY;
137 int Testing = 0; /* for ListViceInodes */
140 * Home for the performance statistics.
142 struct afs_PerfStats afs_perfstats;
145 extern int Statistics;
152 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
153 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
155 afs_int32 readonlyServer = 0;
158 int stackSize = 24000;
159 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
160 int CurrentConnections = 0;
161 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
162 #if defined(AFS_SGI_ENV)
167 int rxpackets = 150; /* 100 */
168 int nSmallVns = 400; /* 200 */
169 int large = 400; /* 200 */
170 int volcache = 400; /* 400 */
171 int numberofcbs = 60000; /* 60000 */
172 int lwps = 9; /* 6 */
173 int buffs = 90; /* 70 */
174 int novbc = 0; /* Enable Volume Break calls */
175 int busy_threshold = 600;
176 int udpBufSize = 0; /* UDP buffer size for receive*/
177 int sendBufSize = 16384; /* send buffer size */
182 * FileServer's name and IP address, both network byte order and
185 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
187 char FS_HostName[128] = "localhost";
188 afs_uint32 FS_HostAddr_NBO;
189 afs_uint32 FS_HostAddr_HBO;
190 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
191 /* All addresses in FS_HostAddrs are in NBO */
194 static void FlagMsg();
197 * Home for the performance statistics.
201 static void CheckDescriptors()
205 register int tsize = getdtablesize();
207 for (i = 0; i<tsize; i++) {
208 if (fstat(i, &status) != -1) {
209 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
210 i, status.st_dev, status.st_ino,
211 status.st_size, status.st_mode);
215 ResetCheckDescriptors();
217 } /*CheckDescriptors*/
220 #ifdef AFS_PTHREAD_ENV
221 void CheckSignal_Signal(x) {CheckSignal();}
222 void ShutDown_Signal(x) {ShutDown();}
223 void CheckDescriptors_Signal(x) {CheckDescriptors();}
224 #else /* AFS_PTHREAD_ENV */
225 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
226 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
227 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
228 #endif /* AFS_PTHREAD_ENV */
230 /* check whether caller is authorized to manage RX statistics */
231 int fs_rxstat_userok(struct rx_call *call)
233 return afsconf_SuperUser(confDir, call, NULL);
236 static void ResetCheckSignal(void)
239 signal(SIGPOLL, CheckSignal_Signal);
242 signal(SIGUSR2, CheckSignal_Signal);
244 signal(SIGXCPU, CheckSignal_Signal);
249 static void ResetCheckDescriptors(void)
252 signal(SIGTERM, CheckDescriptors_Signal);
257 /* proc called by rxkad module to get a key */
258 static int get_key(char *arock, register afs_int32 akvno, char *akey)
261 static struct afsconf_key tkey;
262 register afs_int32 code;
265 ViceLog(0, ("conf dir not open\n"));
268 code = afsconf_GetKey(confDir, akvno, tkey.key);
271 memcpy(akey, tkey.key, sizeof(tkey.key));
277 int viced_syscall(afs_uint32 a3, afs_uint32 a4, void * a5)
282 #ifndef AFS_LINUX20_ENV
283 old = (void (*)())signal(SIGSYS, SIG_IGN);
285 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
286 #ifndef AFS_LINUX20_ENV
294 #if !defined(AFS_NT40_ENV)
295 #include "AFS_component_version_number.c"
296 #endif /* !AFS_NT40_ENV */
298 #define MAXADMINNAME 64
299 char adminName[MAXADMINNAME];
307 if ((stat("/AdminName", &status)) || /* if file does not exist */
308 (status.st_size <= 0) || /* or it is too short */
309 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
310 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
311 strcpy(adminName, "System:Administrators"); /* use the default name */
314 read(fd, adminName, status.st_size); /* use name from the file */
317 close(fd); /* close fd if it was opened */
322 #ifdef AFS_PTHREAD_ENV
323 /* A special LWP that will receive signals, to avoid deadlock */
324 static void SignalLWP()
328 sigfillset(&nsigset);
329 assert(AFS_SET_SIGMASK(SIG_UNBLOCK, &nsigset, NULL) == 0);
337 /* This LWP does things roughly every 5 minutes */
338 static void FiveMinuteCheckLWP()
343 ViceLog(1, ("Starting five minute check process\n"));
345 #ifdef AFS_PTHREAD_ENV
347 #else /* AFS_PTHREAD_ENV */
348 IOMGR_Sleep(fiveminutes);
349 #endif /* AFS_PTHREAD_ENV */
351 /* close the log so it can be removed */
352 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
353 ViceLog(2, ("Cleaning up timed out callbacks\n"));
354 if(CleanupTimedOutCallBacks())
355 ViceLog(5,("Timed out callbacks deleted\n"));
356 ViceLog(2, ("Set disk usage statistics\n"));
358 if (FS_registered == 1) Do_VLRegisterRPC();
359 /* Force wakeup in case we missed something; pthreads does timedwait */
360 #ifndef AFS_PTHREAD_ENV
361 LWP_NoYieldSignal(&fsync_wait);
363 if(printBanner && (++msg&1)) { /* Every 10 minutes */
364 time_t now = FT_ApproxTime();
365 if (console != NULL) {
366 #ifndef AFS_QUIETFS_ENV
367 fprintf(console,"File server is running at %s\r",
368 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
369 #endif /* AFS_QUIETFS_ENV */
370 ViceLog(2, ("File server is running at %s\n",
371 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
375 } /*FiveMinuteCheckLWP*/
378 /* This LWP does host checks every 5 minutes: it should not be used for
379 * other 5 minute activities because it may be delayed by timeouts when
380 * it probes the workstations
382 static void HostCheckLWP()
384 ViceLog(1, ("Starting Host check process\n"));
386 #ifdef AFS_PTHREAD_ENV
388 #else /* AFS_PTHREAD_ENV */
389 IOMGR_Sleep(fiveminutes);
390 #endif /* AFS_PTHREAD_ENV */
391 ViceLog(2, ("Checking for dead venii & clients\n"));
396 /* This LWP does fsync checks every 5 minutes: it should not be used for
397 * other 5 minute activities because it may be delayed by timeouts when
398 * it probes the workstations
400 static FsyncCheckLWP()
403 #ifdef AFS_PTHREAD_ENV
404 struct timespec fsync_next;
406 ViceLog(1, ("Starting fsync check process\n"));
408 #ifdef AFS_PTHREAD_ENV
409 assert(pthread_cond_init(&fsync_cond, NULL) == 0);
410 assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
415 #ifdef AFS_PTHREAD_ENV
416 /* rounding is fine */
417 fsync_next.tv_nsec = 0;
418 fsync_next.tv_sec = time(0) + fiveminutes;
420 code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex,
422 if (code != 0 && code != ETIMEDOUT)
423 ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
424 #else /* AFS_PTHREAD_ENV */
425 if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
426 ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
427 #endif /* AFS_PTHREAD_ENV */
428 ViceLog(2, ("Checking for fsync events\n"));
430 code = BreakLaterCallBacks();
435 /*------------------------------------------------------------------------
436 * PRIVATE ClearXStatValues
439 * Initialize all of the values collected via the xstat
449 * Must be called during File Server initialization.
453 *------------------------------------------------------------------------*/
455 static void ClearXStatValues()
456 { /*ClearXStatValues*/
458 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
459 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
460 int i; /*Loop counter*/
463 * Zero all xstat-related structures.
465 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
466 #if FS_STATS_DETAILED
467 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
470 * That's not enough. We have to set reasonable minima for
471 * time and xfer values in the detailed stats.
473 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
474 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
475 opTimeP->minTime.tv_sec = 999999;
477 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
478 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
479 opXferP->minTime.tv_sec = 999999;
480 opXferP->minBytes = 999999999;
484 * There's more. We have to set our unique system identifier, as
485 * declared in param.h. If such a thing is not defined, we bitch
486 * and declare ourselves to be an unknown system type.
489 afs_perfstats.sysname_ID = SYS_NAME_ID;
492 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
493 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
495 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
496 #endif /* SYS_NAME_ID */
499 } /*ClearXStatValues*/
502 static void PrintCounters()
504 int dirbuff, dircall, dirio;
506 int workstations, activeworkstations, delworkstations;
510 TM_GetTimeOfDay(&tpl, 0);
512 ViceLog(0, ("Vice was last started at %s\n",
513 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
517 DStat(&dirbuff, &dircall, &dirio);
518 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
519 dirbuff, dircall, dirio));
520 rx_PrintStats(stderr);
522 PrintCallBackStats();
524 processSize = -1; /* TODO: */
526 processSize = (int)((long) sbrk(0) >> 10);
528 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
529 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
532 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
533 workstations, activeworkstations, delworkstations));
540 static void CheckSignal()
542 if (FS_registered > 0) {
544 * We have proper ip addresses; tell the vlserver what we got; the following
545 * routine will do the proper reporting for us
557 void ShutDownAndCore(int dopanic)
559 time_t now = time(0);
563 ViceLog(0, ("Shutting down file server at %s",
564 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
566 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
567 #ifndef AFS_QUIETFS_ENV
568 if (console != NULL) {
569 fprintf(console,"File server restart/shutdown received at %s\r",
570 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
576 /* do not allows new reqests to be served from now on, all new requests
577 are returned with an error code of RX_RESTARTING ( transient failure ) */
578 rx_SetRxTranquil(); /* dhruba */
582 rx_PrintStats(debugFile);
585 if (console != NULL) {
588 #ifndef AFS_QUIETFS_ENV
589 fprintf(console, "File server has terminated abnormally at %s\r",
590 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
592 ViceLog(0, ("File server has terminated abnormally at %s\n",
593 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
595 #ifndef AFS_QUIETFS_ENV
596 fprintf(console, "File server has terminated normally at %s\r",
597 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
599 ViceLog(0, ("File server has terminated normally at %s\n",
600 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
608 void ShutDown(void) /* backward compatibility */
610 ShutDownAndCore(DONTPANIC);
614 static void FlagMsg()
618 /* default supports help flag */
620 strcpy(buffer, "Usage: fileserver ");
621 strcat(buffer, "[-d <debug level>] ");
622 strcat(buffer, "[-p <number of processes>] ");
623 strcat(buffer, "[-spare <number of spare blocks>] ");
624 strcat(buffer, "[-pctspare <percentage spare>] ");
625 strcat(buffer, "[-b <buffers>] ");
626 strcat(buffer, "[-l <large vnodes>] ");
627 strcat(buffer, "[-s <small vnodes>] ");
628 strcat(buffer, "[-vc <volume cachesize>] ");
629 strcat(buffer, "[-w <call back wait interval>] ");
630 strcat(buffer, "[-cb <number of call backs>] ");
631 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
632 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
633 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
634 strcat(buffer, "[-readonly (read-only file server)] ");
635 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
636 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
637 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
638 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
639 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
641 strcat(buffer, "[-m <min percentage spare in partition>] ");
643 #if defined(AFS_SGI_ENV)
644 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
646 strcat(buffer, "[-L (large server conf)] ");
647 strcat(buffer, "[-S (small server conf)] ");
648 strcat(buffer, "[-k <stack size>] ");
649 strcat(buffer, "[-realm <Kerberos realm name>] ");
650 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
651 strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
652 /* strcat(buffer, "[-enable_peer_stats] "); */
653 /* strcat(buffer, "[-enable_process_stats] "); */
654 strcat(buffer, "[-help]\n");
656 ViceLog(0, ("%s", buffer));
665 static afs_int32 ParseRights(char *arights)
671 if (!arights || !strcmp(arights, "")) {
672 printf("Missing list of mode bits on -implicit option\n");
675 if (!strcmp(arights, "none"))
677 else if (!strcmp(arights, "read"))
678 mode = PRSFS_READ | PRSFS_LOOKUP;
679 else if (!strcmp(arights, "write"))
680 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
681 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
682 else if (!strcmp(arights, "all"))
683 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
684 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
686 len = strlen(arights);
689 if (tc == 'r') mode |= PRSFS_READ;
690 else if (tc == 'l') mode |= PRSFS_LOOKUP;
691 else if (tc == 'i') mode |= PRSFS_INSERT;
692 else if (tc == 'd') mode |= PRSFS_DELETE;
693 else if (tc == 'w') mode |= PRSFS_WRITE;
694 else if (tc == 'k') mode |= PRSFS_LOCK;
695 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
696 else if (tc == 'A') mode |= PRSFS_USR0;
697 else if (tc == 'B') mode |= PRSFS_USR1;
698 else if (tc == 'C') mode |= PRSFS_USR2;
699 else if (tc == 'D') mode |= PRSFS_USR3;
700 else if (tc == 'E') mode |= PRSFS_USR4;
701 else if (tc == 'F') mode |= PRSFS_USR5;
702 else if (tc == 'G') mode |= PRSFS_USR6;
703 else if (tc == 'H') mode |= PRSFS_USR7;
705 printf("Illegal -implicit rights character '%c'.\n", tc);
714 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
715 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
718 * AIX: sysconf() limit is real
719 * HP-UX: sysconf() limit is real
720 * IRIX: sysconf() limit is apparently NOT real -- too small
721 * DUX: sysconf() limit is apparently NOT real -- too big
722 * Linux: sysconf() limit is apparently NOT real -- too big
723 * Solaris: no sysconf() limit
726 max_fileserver_thread(void)
728 #if defined(AFS_PTHREAD_ENV)
729 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
732 ans = sysconf(_SC_THREAD_THREADS_MAX);
733 if (0 < ans && ans < MAX_FILESERVER_THREAD)
736 #endif /* defined(AFS_PTHREAD_ENV) */
737 return MAX_FILESERVER_THREAD;
740 static int ParseArgs(int argc, char *argv[])
742 int SawL=0, SawS=0, SawVC=0;
743 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
746 int bufSize = 0; /* temp variable to read in udp socket buf size*/
748 for (i = 1; i < argc; i++) {
749 if (!strcmp(argv[i], "-d")) {
750 debuglevel = atoi(argv[++i]);
751 LogLevel = debuglevel;
754 if (!strcmp(argv[i], "-banner")) {
757 if (!strcmp(argv[i], "-implicit")) {
758 implicitAdminRights = ParseRights(argv[++i]);
759 if (implicitAdminRights < 0) return implicitAdminRights;
761 if (!strcmp(argv[i], "-readonly")) {
764 if (!strcmp(argv[i], "-L")) {
767 if (!strcmp(argv[i], "-S")) {
771 if (!strcmp(argv[i], "-p")) {
772 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
774 lwps = atoi(argv[++i]);
781 if (!strcmp(argv[i], "-b")) {
783 buffs = atoi(argv[++i]);
786 if (!strcmp(argv[i], "-l")) {
788 large = atoi(argv[++i]);
791 if (!strcmp(argv[i], "-vc")) {
793 volcache = atoi(argv[++i]);
796 if (!strcmp(argv[i], "-novbc")) {
800 if (!strcmp(argv[i], "-rxpck")) {
802 rxpackets = atoi(argv[++i]);
805 if (!strcmp(argv[i], "-s")) {
807 nSmallVns = atoi(argv[++i]);
810 if (!strcmp(argv[i], "-k"))
811 stack = atoi(argv[++i]);
812 #if defined(AFS_SGI_ENV)
814 if (!strcmp(argv[i], "-lock")) {
819 if (!strcmp(argv[i], "-spare")) {
820 BlocksSpare = atoi(argv[++i]);
824 if (!strcmp(argv[i], "-pctspare")) {
825 PctSpare = atoi(argv[++i]);
826 BlocksSpare = 0; /* has non-zero default */
830 if (!strcmp(argv[i], "-w"))
831 fiveminutes = atoi(argv[++i]);
833 if (!strcmp(argv[i], "-hr")) {
834 int hr = atoi(argv[++i]);
835 if ((hr < 1) || (hr > 36)) {
836 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
840 hostaclRefresh = hr*60*60;
842 if (!strcmp(argv[i], "-rxdbg"))
845 if (!strcmp(argv[i], "-rxdbge"))
848 if (!strcmp(argv[i], "-cb")) {
850 numberofcbs = atoi(argv[++i]);
851 if ((numberofcbs < 10000) || (numberofcbs > 2147483647)) {
852 printf("number of cbs %d invalid; must be between 10000 and 2147483647\n",
858 if (!strcmp(argv[i], "-busyat")) {
860 busy_threshold = atoi(argv[++i]);
861 if (busy_threshold < 10) {
862 printf("Busy threshold %d is too low, will compute default.\n",
869 if (!strcmp(argv[i], "-m")) {
870 extern int aixlow_water;
871 aixlow_water = atoi(argv[++i]);
872 if ((aixlow_water < 0) || (aixlow_water > 30)) {
873 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
879 if (!strcmp(argv[i], "-nojumbo")) {
883 if (!strcmp(argv[i], "-realm")) {
884 extern char local_realm[AFS_REALM_SZ];
885 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
886 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
889 strncpy (local_realm, argv[i], AFS_REALM_SZ);
892 if ( !strcmp(argv[i], "-udpsize")) {
893 if ( (i+1) >= argc ) {
894 printf("You have to specify -udpsize <integer value>\n");
897 bufSize = atoi(argv[++i]);
898 if ( bufSize < rx_GetMinUdpBufSize() )
899 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
900 bufSize, rx_GetMinUdpBufSize() );
902 udpBufSize = bufSize;
905 if ( !strcmp(argv[i], "-sendsize")) {
906 if ( (i+1) >= argc ) {
907 printf("You have to specify -sendsize <integer value>\n");
910 bufSize = atoi(argv[++i]);
911 if ( bufSize < 16384 )
912 printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
915 sendBufSize = bufSize;
918 if (!strcmp(argv[i], "-enable_peer_stats")) {
919 rx_enablePeerRPCStats();
922 if (!strcmp(argv[i], "-enable_process_stats")) {
923 rx_enableProcessRPCStats();
927 if (strcmp(argv[i], "-syslog")==0) {
928 /* set syslog logging flag */
932 if (strncmp(argv[i], "-syslog=", 8)==0) {
934 serverLogSyslogFacility = atoi(argv[i]+8);
942 printf("Only one of -L, or -S must be specified\n");
946 if (!Sawrxpck) rxpackets = 100;
947 if (!Sawsmall) nSmallVns = 200;
948 if (!Sawlarge) large = 200;
949 if (!Sawcbs) numberofcbs = 20000;
950 if (!Sawlwps) lwps = 6;
951 if (!Sawbufs) buffs = 70;
952 if (!SawVC) volcache = 200;
955 if (!Sawrxpck) rxpackets = 200;
956 if (!Sawsmall) nSmallVns = 600;
957 if (!Sawlarge) large = 600;
958 if (!Sawcbs) numberofcbs = 64000;
959 if (!Sawlwps) lwps = 12;
960 if (!Sawbufs) buffs = 120;
961 if (!SawVC) volcache = 600;
964 busy_threshold = 3*rxpackets/2;
973 static void NewParms(int initializing)
975 static struct stat sbuf;
976 register afs_offs_t i;
979 char *argv[MAXPARMS];
982 if (!(stat("/vice/file/parms",&sbuf))) {
983 parms = (char *)malloc(sbuf.st_size);
985 fd = open("parms", O_RDONLY, 0666);
987 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
991 i = read(fd, parms, sbuf.st_size);
993 if(i != sbuf.st_size) {
995 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
998 ("Read on parms failed; expected %d bytes but read %d\n",
1005 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1007 for (argc = i = 0; i < sbuf.st_size; i++) {
1008 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1009 if(argv[argc] == 0) argv[argc] = (parms+i);
1012 *(parms + i) = '\0';
1013 if(argv[argc] != 0) {
1014 if(++argc == MAXPARMS) break;
1016 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1020 if(ParseArgs(argc, argv) == 0) {
1021 ViceLog(0, ("Change parameters to:"));
1023 ViceLog(0, ("Invalid parameter in:"));
1025 for(i = 0; i < argc; i++) {
1026 ViceLog(0, (" %s", argv[i]));
1033 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1038 /* Miscellaneous routines */
1039 void Die (char *msg)
1041 ViceLog (0,("%s\n", msg));
1052 * If this fails, it's because something major is wrong, and is not
1053 * likely to be time dependent.
1055 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1057 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1060 SystemId = SYSADMINID;
1061 SystemAnyUser = ANYUSERID;
1062 SystemAnyUserCPS.prlist_len = 0;
1063 SystemAnyUserCPS.prlist_val = NULL;
1064 AnonCPS.prlist_len = 0;
1065 AnonCPS.prlist_val = NULL;
1067 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1070 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1074 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1076 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1079 AnonymousID = ANONYMOUSID;
1082 #ifdef AFS_PTHREAD_ENV
1084 #else /* AFS_PTHREAD_ENV */
1086 #endif /* AFS_PTHREAD_ENV */
1090 struct rx_connection *serverconns[MAXSERVERS];
1091 struct ubik_client *cstruct;
1093 afs_int32 vl_Initialize(char *confDir)
1094 { afs_int32 code, scIndex = 0, i;
1095 struct afsconf_dir *tdir;
1096 struct rx_securityClass *sc;
1097 struct afsconf_cell info;
1099 tdir = afsconf_Open(confDir);
1101 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1104 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1106 ViceLog(0, ("Could not get security object for localAuth\n"));
1109 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1110 if (info.numServers > MAXSERVERS) {
1111 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1114 for (i = 0;i<info.numServers;i++)
1115 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1116 USER_SERVICE_ID, sc, scIndex);
1117 code = ubik_ClientInit(serverconns, &cstruct);
1119 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1125 #define SYSIDMAGIC 0x88aabbcc
1126 #define SYSIDVERSION 1
1130 afs_int32 fd, nentries, i;
1131 struct versionStamp vsn;
1135 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1136 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1139 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1140 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1143 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1144 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1147 if (vsn.magic != SYSIDMAGIC) {
1148 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1151 if (vsn.version != SYSIDVERSION) {
1152 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1155 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1156 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1159 afs_ntohuuid(&uuid);
1161 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1162 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1165 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1166 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1169 FS_HostAddr_cnt = nentries;
1170 for (i = 0; i < nentries; i++) {
1171 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1172 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1173 FS_HostAddr_cnt = 0; /* reset it */
1183 afs_int32 fd, nentries, i;
1184 struct versionStamp vsn;
1188 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1190 * File exists; keep the old one around
1192 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1194 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1196 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1199 vsn.magic = SYSIDMAGIC;
1201 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1202 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1206 afs_htonuuid(&uuid);
1207 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1208 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1211 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1212 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1215 for (i = 0; i < FS_HostAddr_cnt; i++) {
1216 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1217 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1227 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1228 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1229 * and so we need to convert each of them into HBO which is what the extra
1230 * array called FS_HostAddrs_HBO is used here.
1233 Do_VLRegisterRPC() {
1236 extern int VL_RegisterAddrs();
1237 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1240 for (i=0; i < FS_HostAddr_cnt ; i++)
1241 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1242 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1243 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1244 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1246 if (code == VL_MULTIPADDR) {
1247 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1248 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1250 } else if (code == RXGEN_OPCODE) {
1251 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1252 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1254 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1258 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1266 static int AddrsEqual(cnt, addr1, addr2)
1268 afs_int32 *addr1, *addr2;
1272 for (i = 0; i < cnt; i++) {
1273 for (j = 0; j < cnt; j++) {
1274 if (addr1[i] == addr2[j]) break;
1276 if (j == cnt) return 0;
1287 extern int rxi_numNetAddrs;
1288 extern afs_uint32 rxi_NetAddrs[];
1291 * If this fails, it's because something major is wrong, and is not
1292 * likely to be time dependent.
1294 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1296 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1300 /* Read or create the sysid file and register the fileserver's
1301 * IP addresses with the vlserver.
1303 code = ReadSysIdFile();
1305 /* Need to create the file */
1306 ViceLog(0, ("Creating new SysID file\n"));
1307 if ((code = afs_uuid_create(&FS_HostUUID))) {
1308 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1312 /* A good sysid file exists; inform the vlserver. If any conflicts,
1313 * we always use the latest interface available as the real truth.
1315 #ifndef AFS_NT40_ENV
1316 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1318 * Find addresses we are supposed to register as per the netrestrict
1319 * and netinfo files (/usr/afs/local/NetInfo and
1320 * /usr/afs/local/NetRestict)
1323 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1324 ADDRSPERSITE, reason,
1325 AFSDIR_SERVER_NETINFO_FILEPATH,
1326 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1328 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1331 FS_HostAddr_cnt = (afs_uint32) code;
1336 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1340 code = Do_VLRegisterRPC();
1345 main(int argc, char * argv[])
1351 struct rx_securityClass *sc[4];
1352 struct rx_service *tservice;
1353 #ifdef AFS_PTHREAD_ENV
1354 pthread_t parentPid, serverPid;
1355 pthread_attr_t tattr;
1357 #else /* AFS_PTHREAD_ENV */
1358 PROCESS parentPid, serverPid;
1359 #endif /* AFS_PTHREAD_ENV */
1361 int minVnodesRequired; /* min size of vnode cache */
1362 #ifndef AFS_NT40_ENV
1363 struct rlimit rlim; /* max number of open file descriptors */
1367 #ifdef AFS_AIX32_ENV
1368 struct sigaction nsa;
1370 sigemptyset(&nsa.sa_mask);
1371 nsa.sa_handler = SIG_DFL;
1372 nsa.sa_flags = SA_FULLDUMP;
1373 sigaction(SIGABRT, &nsa, NULL);
1374 sigaction(SIGSEGV, &nsa, NULL);
1377 /* Initialize dirpaths */
1378 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1380 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
1382 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
1386 #ifndef AFS_QUIETFS_ENV
1387 console = fopen("/dev/console","w");
1390 if(ParseArgs(argc,argv)) {
1395 #ifdef AFS_PTHREAD_ENV
1396 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
1397 #endif /* AFS_PTHREAD_ENV */
1399 #ifdef AFS_SGI_VNODE_GLUE
1400 if (afs_init_kernel_config(-1) <0) {
1401 printf("Can't determine NUMA configuration, not starting fileserver.\n");
1405 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
1407 fprintf(stderr, "Unable to open config directory %s\n",
1408 AFSDIR_SERVER_ETC_DIRPATH);
1414 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
1415 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
1418 if (SawSpare && SawPctSpare) {
1419 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
1423 #ifdef AFS_SGI_XFS_IOPS_ENV
1424 ViceLog(0, ("XFS/EFS File server starting\n"));
1426 ViceLog(0, ("File server starting\n"));
1429 /* install signal handlers for controlling the fileserver process */
1430 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
1431 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
1433 #if defined(AFS_SGI_ENV)
1434 /* give this guy a non-degrading priority so help busy servers */
1435 schedctl(NDPRI, 0, NDPNORMMAX);
1439 #ifndef AFS_NT40_ENV
1440 nice(-5); /* TODO: */
1443 assert(DInit(buffs) == 0);
1446 if (afs_winsockInit()<0) {
1447 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
1448 ViceLog(0, ("File server failed to intialize winsock.\n"));
1454 /* if we support more than 16 threads, then we better have the ability
1455 ** to keep open a large number of files simultaneously
1457 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
1458 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
1459 #elif defined(AFS_NT40_ENV)
1460 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
1463 curLimit = 0; /* the number of open file descriptors */
1464 code = getrlimit(RLIMIT_NOFILE, &rlim);
1466 curLimit = rlim.rlim_cur;
1467 rlim.rlim_cur = rlim.rlim_max;
1468 code = setrlimit(RLIMIT_NOFILE, &rlim);
1470 curLimit = rlim.rlim_max;
1473 ViceLog(0, ("Failed to increase open file limit, using default\n"));
1475 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
1477 curLimit -= 32; /* leave a slack of 32 file descriptors */
1478 if ( lwps > curLimit ) {
1481 else if ( lwps > 16 )
1482 lwps = 16; /* default to a maximum of 16 threads */
1483 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
1487 #ifndef AFS_PTHREAD_ENV
1488 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
1489 #endif /* !AFS_PTHREAD_ENV */
1491 /* Initialize volume support */
1493 V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
1496 /* initialize libacl routines */
1497 acl_Initialize(ACL_VERSION);
1499 /* initialize RX support */
1500 #ifndef AFS_NT40_ENV
1501 rxi_syscallp = viced_syscall;
1503 rx_extraPackets = rxpackets;
1504 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
1505 rx_SetBusyThreshold(busy_threshold, VBUSY);
1506 rx_SetCallAbortThreshold(10);
1507 rx_SetConnAbortThreshold(10);
1508 stackSize = lwps * 4000;
1509 if (stackSize < 32000)
1511 else if (stackSize > 44000)
1513 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
1514 rx_SetStackSize(1, stackSize);
1517 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
1518 if (rx_Init((int)htons(7000))<0) {
1519 ViceLog(0, ("Cannot initialize RX\n"));
1522 if (!rxJumbograms) {
1523 /* Don't send and don't allow 3.4 clients to send jumbograms. */
1527 rx_SetRxDeadTime(30);
1528 sc[0] = rxnull_NewServerSecurityObject();
1529 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
1530 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
1532 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
1534 tservice = rx_NewService
1535 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
1536 /* security classes */ sc, /* numb sec classes */ 4,
1537 RXAFS_ExecuteRequest);
1539 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
1542 rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
1543 rx_SetMinProcs(tservice, 3);
1544 rx_SetMaxProcs(tservice, lwps);
1545 rx_SetCheckReach(tservice, 1);
1547 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
1549 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
1552 rx_SetMinProcs(tservice, 2);
1553 rx_SetMaxProcs(tservice, 4);
1556 * Enable RX hot threads, which allows the listener thread to trade
1557 * places with an idle thread and moves the context switch from listener
1558 * to worker out of the critical path.
1560 rx_EnableHotThread();
1562 /* Some rx debugging */
1563 if (rxlog || eventlog) {
1564 debugFile = fopen("rx_dbg", "w");
1565 if (rxlog) rx_debugFile = debugFile;
1566 if (eventlog) rxevent_debugFile = debugFile;
1569 h_InitHostPackage(); /* set up local cellname and realmname */
1570 InitCallBack(numberofcbs);
1575 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
1581 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
1585 /* allow super users to manage RX statistics */
1586 rx_SetRxStatUserOk(fs_rxstat_userok);
1588 rx_StartServer(0); /* now start handling requests */
1590 /* we ensure that there is enough space in the vnode buffer to satisfy
1591 ** requests from all concurrent threads.
1592 ** the maximum number of vnodes used by a single thread at any one time
1593 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
1594 ** two vSmall for linking files and two vLarge and one vSmall for linking
1597 minVnodesRequired = 2 * lwps + 1;
1598 if ( minVnodesRequired > nSmallVns ) {
1599 nSmallVns = minVnodesRequired;
1600 ViceLog(0, ("Overriding -s command line parameter with %d\n",
1603 if ( minVnodesRequired > large ) {
1604 large = minVnodesRequired;
1605 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
1608 /* We now do this after getting the listener up and running, so that client
1609 connections don't timeout (maybe) if a file server is restarted, since it
1610 will be available "real soon now". Worry about whether we can satisfy the
1611 calls in the volume package itself.
1613 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
1614 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
1620 * We are done calling fopen/fdopen. It is safe to use a large
1621 * of the file descriptor cache.
1625 #ifdef AFS_PTHREAD_ENV
1626 assert(pthread_attr_init(&tattr) == 0);
1627 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
1628 /* Block signals in this thread (and children), create a signal thread */
1629 sigfillset(&nsigset);
1630 assert(AFS_SET_SIGMASK(SIG_BLOCK, &nsigset, NULL) == 0);
1631 assert(pthread_create(&serverPid, &tattr, (void *)SignalLWP, NULL) == 0);
1633 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
1634 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
1635 assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
1636 #else /* AFS_PTHREAD_ENV */
1637 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1638 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
1640 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1641 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
1642 assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1643 (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
1644 #endif /* AFS_PTHREAD_ENV */
1646 TM_GetTimeOfDay(&tp, 0);
1648 #ifndef AFS_QUIETFS_ENV
1649 if (console != NULL) {
1650 fprintf(console, "File server has started at %s\r",
1651 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
1656 * Figure out the FileServer's name and primary address.
1658 ViceLog(0, ("Getting FileServer name...\n"));
1659 code = gethostname(FS_HostName, 64);
1661 ViceLog(0, ("gethostname() failed\n"));
1663 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
1665 ViceLog(0, ("Getting FileServer address...\n"));
1666 he = gethostbyname(FS_HostName);
1668 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
1672 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
1673 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
1674 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
1675 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
1676 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
1679 /* Install handler to catch the shutdown signal */
1680 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
1682 ViceLog(0,("File Server started %s",
1683 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
1684 #if FS_STATS_DETAILED
1685 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
1687 #ifdef AFS_PTHREAD_ENV
1689 sleep(1000); /* long time */
1691 #else /* AFS_PTHREAD_ENV */
1692 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
1693 #endif /* AFS_PTHREAD_ENV */