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;
978 char *argv[MAXPARMS];
981 if (!(stat("/vice/file/parms",&sbuf))) {
982 parms = (char *)malloc(sbuf.st_size);
984 fd = open("parms", O_RDONLY, 0666);
986 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
990 i = read(fd, parms, sbuf.st_size);
992 if(i != sbuf.st_size) {
994 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
997 ("Read on parms failed; expected %d bytes but read %d\n",
1004 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1006 for (argc = i = 0; i < sbuf.st_size; i++) {
1007 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1008 if(argv[argc] == 0) argv[argc] = (parms+i);
1011 *(parms + i) = '\0';
1012 if(argv[argc] != 0) {
1013 if(++argc == MAXPARMS) break;
1015 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1019 if(ParseArgs(argc, argv) == 0) {
1020 ViceLog(0, ("Change parameters to:"));
1022 ViceLog(0, ("Invalid parameter in:"));
1024 for(i = 0; i < argc; i++) {
1025 ViceLog(0, (" %s", argv[i]));
1032 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1037 /* Miscellaneous routines */
1038 void Die (char *msg)
1040 ViceLog (0,("%s\n", msg));
1051 * If this fails, it's because something major is wrong, and is not
1052 * likely to be time dependent.
1054 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1056 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1059 SystemId = SYSADMINID;
1060 SystemAnyUser = ANYUSERID;
1061 SystemAnyUserCPS.prlist_len = 0;
1062 SystemAnyUserCPS.prlist_val = NULL;
1063 AnonCPS.prlist_len = 0;
1064 AnonCPS.prlist_val = NULL;
1066 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1069 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1073 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1075 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1078 AnonymousID = ANONYMOUSID;
1081 #ifdef AFS_PTHREAD_ENV
1083 #else /* AFS_PTHREAD_ENV */
1085 #endif /* AFS_PTHREAD_ENV */
1089 struct rx_connection *serverconns[MAXSERVERS];
1090 struct ubik_client *cstruct;
1092 afs_int32 vl_Initialize(char *confDir)
1093 { afs_int32 code, scIndex = 0, i;
1094 struct afsconf_dir *tdir;
1095 struct rx_securityClass *sc;
1096 struct afsconf_cell info;
1098 tdir = afsconf_Open(confDir);
1100 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1103 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1105 ViceLog(0, ("Could not get security object for localAuth\n"));
1108 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1109 if (info.numServers > MAXSERVERS) {
1110 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1113 for (i = 0;i<info.numServers;i++)
1114 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1115 USER_SERVICE_ID, sc, scIndex);
1116 code = ubik_ClientInit(serverconns, &cstruct);
1118 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1124 #define SYSIDMAGIC 0x88aabbcc
1125 #define SYSIDVERSION 1
1129 afs_int32 fd, nentries, i;
1130 struct versionStamp vsn;
1134 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1135 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1138 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1139 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1142 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1143 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1146 if (vsn.magic != SYSIDMAGIC) {
1147 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1150 if (vsn.version != SYSIDVERSION) {
1151 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1154 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1155 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1158 afs_ntohuuid(&uuid);
1160 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1161 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1164 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1165 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1168 FS_HostAddr_cnt = nentries;
1169 for (i = 0; i < nentries; i++) {
1170 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1171 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1172 FS_HostAddr_cnt = 0; /* reset it */
1182 afs_int32 fd, nentries, i;
1183 struct versionStamp vsn;
1187 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1189 * File exists; keep the old one around
1191 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1193 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1195 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1198 vsn.magic = SYSIDMAGIC;
1200 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1201 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1205 afs_htonuuid(&uuid);
1206 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1207 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1210 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1211 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1214 for (i = 0; i < FS_HostAddr_cnt; i++) {
1215 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1216 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1226 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1227 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1228 * and so we need to convert each of them into HBO which is what the extra
1229 * array called FS_HostAddrs_HBO is used here.
1232 Do_VLRegisterRPC() {
1235 extern int VL_RegisterAddrs();
1236 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1239 for (i=0; i < FS_HostAddr_cnt ; i++)
1240 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1241 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1242 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1243 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1245 if (code == VL_MULTIPADDR) {
1246 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1247 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1249 } else if (code == RXGEN_OPCODE) {
1250 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1251 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1253 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1257 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1265 static int AddrsEqual(cnt, addr1, addr2)
1267 afs_int32 *addr1, *addr2;
1271 for (i = 0; i < cnt; i++) {
1272 for (j = 0; j < cnt; j++) {
1273 if (addr1[i] == addr2[j]) break;
1275 if (j == cnt) return 0;
1286 extern int rxi_numNetAddrs;
1287 extern afs_uint32 rxi_NetAddrs[];
1290 * If this fails, it's because something major is wrong, and is not
1291 * likely to be time dependent.
1293 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1295 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1299 /* Read or create the sysid file and register the fileserver's
1300 * IP addresses with the vlserver.
1302 code = ReadSysIdFile();
1304 /* Need to create the file */
1305 ViceLog(0, ("Creating new SysID file\n"));
1306 if ((code = afs_uuid_create(&FS_HostUUID))) {
1307 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1311 /* A good sysid file exists; inform the vlserver. If any conflicts,
1312 * we always use the latest interface available as the real truth.
1314 #ifndef AFS_NT40_ENV
1315 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1317 * Find addresses we are supposed to register as per the netrestrict
1318 * and netinfo files (/usr/afs/local/NetInfo and
1319 * /usr/afs/local/NetRestict)
1322 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1323 ADDRSPERSITE, reason,
1324 AFSDIR_SERVER_NETINFO_FILEPATH,
1325 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1327 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1330 FS_HostAddr_cnt = (afs_uint32) code;
1335 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1339 code = Do_VLRegisterRPC();
1344 main(int argc, char * argv[])
1350 struct rx_securityClass *sc[4];
1351 struct rx_service *tservice;
1352 #ifdef AFS_PTHREAD_ENV
1353 pthread_t parentPid, serverPid;
1354 pthread_attr_t tattr;
1356 #else /* AFS_PTHREAD_ENV */
1357 PROCESS parentPid, serverPid;
1358 #endif /* AFS_PTHREAD_ENV */
1360 int minVnodesRequired; /* min size of vnode cache */
1361 #ifndef AFS_NT40_ENV
1362 struct rlimit rlim; /* max number of open file descriptors */
1366 #ifdef AFS_AIX32_ENV
1367 struct sigaction nsa;
1369 sigemptyset(&nsa.sa_mask);
1370 nsa.sa_handler = SIG_DFL;
1371 nsa.sa_flags = SA_FULLDUMP;
1372 sigaction(SIGABRT, &nsa, NULL);
1373 sigaction(SIGSEGV, &nsa, NULL);
1376 /* Initialize dirpaths */
1377 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1379 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
1381 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
1385 #ifndef AFS_QUIETFS_ENV
1386 console = fopen("/dev/console","w");
1389 if(ParseArgs(argc,argv)) {
1394 #ifdef AFS_PTHREAD_ENV
1395 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
1396 #endif /* AFS_PTHREAD_ENV */
1398 #ifdef AFS_SGI_VNODE_GLUE
1399 if (afs_init_kernel_config(-1) <0) {
1400 printf("Can't determine NUMA configuration, not starting fileserver.\n");
1404 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
1406 fprintf(stderr, "Unable to open config directory %s\n",
1407 AFSDIR_SERVER_ETC_DIRPATH);
1413 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
1414 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
1417 if (SawSpare && SawPctSpare) {
1418 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
1422 #ifdef AFS_SGI_XFS_IOPS_ENV
1423 ViceLog(0, ("XFS/EFS File server starting\n"));
1425 ViceLog(0, ("File server starting\n"));
1428 /* install signal handlers for controlling the fileserver process */
1429 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
1430 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
1432 #if defined(AFS_SGI_ENV)
1433 /* give this guy a non-degrading priority so help busy servers */
1434 schedctl(NDPRI, 0, NDPNORMMAX);
1438 #ifndef AFS_NT40_ENV
1439 nice(-5); /* TODO: */
1442 assert(DInit(buffs) == 0);
1445 if (afs_winsockInit()<0) {
1446 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
1447 ViceLog(0, ("File server failed to intialize winsock.\n"));
1453 /* if we support more than 16 threads, then we better have the ability
1454 ** to keep open a large number of files simultaneously
1456 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
1457 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
1458 #elif defined(AFS_NT40_ENV)
1459 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
1462 curLimit = 0; /* the number of open file descriptors */
1463 code = getrlimit(RLIMIT_NOFILE, &rlim);
1465 curLimit = rlim.rlim_cur;
1466 rlim.rlim_cur = rlim.rlim_max;
1467 code = setrlimit(RLIMIT_NOFILE, &rlim);
1469 curLimit = rlim.rlim_max;
1472 ViceLog(0, ("Failed to increase open file limit, using default\n"));
1474 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
1476 curLimit -= 32; /* leave a slack of 32 file descriptors */
1477 if ( lwps > curLimit ) {
1480 else if ( lwps > 16 )
1481 lwps = 16; /* default to a maximum of 16 threads */
1482 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
1486 #ifndef AFS_PTHREAD_ENV
1487 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
1488 #endif /* !AFS_PTHREAD_ENV */
1490 /* Initialize volume support */
1492 V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
1495 /* initialize libacl routines */
1496 acl_Initialize(ACL_VERSION);
1498 /* initialize RX support */
1499 #ifndef AFS_NT40_ENV
1500 rxi_syscallp = viced_syscall;
1502 rx_extraPackets = rxpackets;
1503 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
1504 rx_SetBusyThreshold(busy_threshold, VBUSY);
1505 rx_SetCallAbortThreshold(10);
1506 rx_SetConnAbortThreshold(10);
1507 stackSize = lwps * 4000;
1508 if (stackSize < 32000)
1510 else if (stackSize > 44000)
1512 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
1513 rx_SetStackSize(1, stackSize);
1516 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
1517 if (rx_Init((int)htons(7000))<0) {
1518 ViceLog(0, ("Cannot initialize RX\n"));
1521 if (!rxJumbograms) {
1522 /* Don't send and don't allow 3.4 clients to send jumbograms. */
1526 rx_SetRxDeadTime(30);
1527 sc[0] = rxnull_NewServerSecurityObject();
1528 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
1529 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
1531 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
1533 tservice = rx_NewService
1534 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
1535 /* security classes */ sc, /* numb sec classes */ 4,
1536 RXAFS_ExecuteRequest);
1538 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
1541 rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
1542 rx_SetMinProcs(tservice, 3);
1543 rx_SetMaxProcs(tservice, lwps);
1544 rx_SetCheckReach(tservice, 1);
1546 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
1548 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
1551 rx_SetMinProcs(tservice, 2);
1552 rx_SetMaxProcs(tservice, 4);
1555 * Enable RX hot threads, which allows the listener thread to trade
1556 * places with an idle thread and moves the context switch from listener
1557 * to worker out of the critical path.
1559 rx_EnableHotThread();
1561 /* Some rx debugging */
1562 if (rxlog || eventlog) {
1563 debugFile = fopen("rx_dbg", "w");
1564 if (rxlog) rx_debugFile = debugFile;
1565 if (eventlog) rxevent_debugFile = debugFile;
1568 h_InitHostPackage(); /* set up local cellname and realmname */
1569 InitCallBack(numberofcbs);
1574 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
1580 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
1584 /* allow super users to manage RX statistics */
1585 rx_SetRxStatUserOk(fs_rxstat_userok);
1587 rx_StartServer(0); /* now start handling requests */
1589 /* we ensure that there is enough space in the vnode buffer to satisfy
1590 ** requests from all concurrent threads.
1591 ** the maximum number of vnodes used by a single thread at any one time
1592 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
1593 ** two vSmall for linking files and two vLarge and one vSmall for linking
1596 minVnodesRequired = 2 * lwps + 1;
1597 if ( minVnodesRequired > nSmallVns ) {
1598 nSmallVns = minVnodesRequired;
1599 ViceLog(0, ("Overriding -s command line parameter with %d\n",
1602 if ( minVnodesRequired > large ) {
1603 large = minVnodesRequired;
1604 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
1607 /* We now do this after getting the listener up and running, so that client
1608 connections don't timeout (maybe) if a file server is restarted, since it
1609 will be available "real soon now". Worry about whether we can satisfy the
1610 calls in the volume package itself.
1612 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
1613 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
1619 * We are done calling fopen/fdopen. It is safe to use a large
1620 * of the file descriptor cache.
1624 #ifdef AFS_PTHREAD_ENV
1625 assert(pthread_attr_init(&tattr) == 0);
1626 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
1627 /* Block signals in this thread (and children), create a signal thread */
1628 sigfillset(&nsigset);
1629 assert(AFS_SET_SIGMASK(SIG_BLOCK, &nsigset, NULL) == 0);
1630 assert(pthread_create(&serverPid, &tattr, (void *)SignalLWP, NULL) == 0);
1632 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
1633 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
1634 assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
1635 #else /* AFS_PTHREAD_ENV */
1636 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1637 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
1639 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1640 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
1641 assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1642 (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
1643 #endif /* AFS_PTHREAD_ENV */
1645 TM_GetTimeOfDay(&tp, 0);
1647 #ifndef AFS_QUIETFS_ENV
1648 if (console != NULL) {
1649 fprintf(console, "File server has started at %s\r",
1650 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
1655 * Figure out the FileServer's name and primary address.
1657 ViceLog(0, ("Getting FileServer name...\n"));
1658 code = gethostname(FS_HostName, 64);
1660 ViceLog(0, ("gethostname() failed\n"));
1662 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
1664 ViceLog(0, ("Getting FileServer address...\n"));
1665 he = gethostbyname(FS_HostName);
1667 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
1671 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
1672 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
1673 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
1674 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
1675 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
1678 /* Install handler to catch the shutdown signal */
1679 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
1681 ViceLog(0,("File Server started %s",
1682 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
1683 #if FS_STATS_DETAILED
1684 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
1686 #ifdef AFS_PTHREAD_ENV
1688 sleep(1000); /* long time */
1690 #else /* AFS_PTHREAD_ENV */
1691 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
1692 #endif /* AFS_PTHREAD_ENV */