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;
156 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
157 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
159 afs_int32 readonlyServer = 0;
162 int stackSize = 24000;
163 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
164 int CurrentConnections = 0;
165 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
166 #if defined(AFS_SGI_ENV)
171 int rxpackets = 150; /* 100 */
172 int nSmallVns = 400; /* 200 */
173 int large = 400; /* 200 */
174 int volcache = 400; /* 400 */
175 int numberofcbs = 60000; /* 60000 */
176 int lwps = 9; /* 6 */
177 int buffs = 90; /* 70 */
178 int novbc = 0; /* Enable Volume Break calls */
179 int busy_threshold = 600;
180 int udpBufSize = 0; /* UDP buffer size for receive*/
181 int sendBufSize = 16384; /* send buffer size */
186 * FileServer's name and IP address, both network byte order and
189 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
191 char FS_HostName[128] = "localhost";
192 afs_uint32 FS_HostAddr_NBO;
193 afs_uint32 FS_HostAddr_HBO;
194 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
195 /* All addresses in FS_HostAddrs are in NBO */
198 static void FlagMsg();
201 * Home for the performance statistics.
205 static void CheckDescriptors()
209 register int tsize = getdtablesize();
211 for (i = 0; i<tsize; i++) {
212 if (fstat(i, &status) != -1) {
213 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
214 i, status.st_dev, status.st_ino,
215 status.st_size, status.st_mode);
219 ResetCheckDescriptors();
221 } /*CheckDescriptors*/
224 #ifdef AFS_PTHREAD_ENV
225 void CheckSignal_Signal(x) {CheckSignal();}
226 void ShutDown_Signal(x) {ShutDown();}
227 void CheckDescriptors_Signal(x) {CheckDescriptors();}
228 #else /* AFS_PTHREAD_ENV */
229 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
230 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
231 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
232 #endif /* AFS_PTHREAD_ENV */
234 /* check whether caller is authorized to manage RX statistics */
235 int fs_rxstat_userok(struct rx_call *call)
237 return afsconf_SuperUser(confDir, call, NULL);
240 static void ResetCheckSignal(void)
244 #if defined(AFS_HPUX_ENV)
247 #if defined(AFS_NT40_ENV)
254 #if defined(AFS_PTHREAD_ENV)
255 softsig_signal(signo, CheckSignal_Signal);
257 signal(signo, CheckSignal_Signal);
261 static void ResetCheckDescriptors(void)
264 #if defined(AFS_PTHREAD_ENV)
265 softsig_signal(SIGTERM, CheckDescriptors_Signal);
267 signal(SIGTERM, CheckDescriptors_Signal);
273 /* proc called by rxkad module to get a key */
274 static int get_key(char *arock, register afs_int32 akvno, char *akey)
277 static struct afsconf_key tkey;
278 register afs_int32 code;
281 ViceLog(0, ("conf dir not open\n"));
284 code = afsconf_GetKey(confDir, akvno, tkey.key);
287 memcpy(akey, tkey.key, sizeof(tkey.key));
293 int viced_syscall(afs_uint32 a3, afs_uint32 a4, void * a5)
298 #ifndef AFS_LINUX20_ENV
299 old = (void (*)())signal(SIGSYS, SIG_IGN);
301 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
302 #ifndef AFS_LINUX20_ENV
310 #if !defined(AFS_NT40_ENV)
311 #include "AFS_component_version_number.c"
312 #endif /* !AFS_NT40_ENV */
314 #define MAXADMINNAME 64
315 char adminName[MAXADMINNAME];
323 if ((stat("/AdminName", &status)) || /* if file does not exist */
324 (status.st_size <= 0) || /* or it is too short */
325 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
326 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
327 strcpy(adminName, "System:Administrators"); /* use the default name */
330 read(fd, adminName, status.st_size); /* use name from the file */
333 close(fd); /* close fd if it was opened */
338 static void setThreadId(char *s)
340 #ifdef AFS_PTHREAD_ENV
341 /* set our 'thread-id' so that the host hold table works */
342 MUTEX_ENTER(&rx_stats_mutex); /* protects rxi_pthread_hinum */
344 pthread_setspecific(rx_thread_id_key, (void *)rxi_pthread_hinum);
345 MUTEX_EXIT(&rx_stats_mutex);
346 ViceLog(0,("Set thread id %d for '%s'\n", pthread_getspecific(rx_thread_id_key), s));
350 /* This LWP does things roughly every 5 minutes */
351 static void FiveMinuteCheckLWP()
356 ViceLog(1, ("Starting five minute check process\n"));
357 setThreadId("FiveMinuteCheckLWP");
359 #ifdef AFS_PTHREAD_ENV
361 #else /* AFS_PTHREAD_ENV */
362 IOMGR_Sleep(fiveminutes);
363 #endif /* AFS_PTHREAD_ENV */
365 /* close the log so it can be removed */
366 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
367 ViceLog(2, ("Cleaning up timed out callbacks\n"));
368 if(CleanupTimedOutCallBacks())
369 ViceLog(5,("Timed out callbacks deleted\n"));
370 ViceLog(2, ("Set disk usage statistics\n"));
372 if (FS_registered == 1) Do_VLRegisterRPC();
373 /* Force wakeup in case we missed something; pthreads does timedwait */
374 #ifndef AFS_PTHREAD_ENV
375 LWP_NoYieldSignal(&fsync_wait);
377 if(printBanner && (++msg&1)) { /* Every 10 minutes */
378 time_t now = FT_ApproxTime();
379 if (console != NULL) {
380 #ifndef AFS_QUIETFS_ENV
381 fprintf(console,"File server is running at %s\r",
382 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
383 #endif /* AFS_QUIETFS_ENV */
384 ViceLog(2, ("File server is running at %s\n",
385 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
389 } /*FiveMinuteCheckLWP*/
392 /* This LWP does host checks every 5 minutes: it should not be used for
393 * other 5 minute activities because it may be delayed by timeouts when
394 * it probes the workstations
396 static void HostCheckLWP()
398 ViceLog(1, ("Starting Host check process\n"));
399 setThreadId("HostCheckLWP");
401 #ifdef AFS_PTHREAD_ENV
403 #else /* AFS_PTHREAD_ENV */
404 IOMGR_Sleep(fiveminutes);
405 #endif /* AFS_PTHREAD_ENV */
406 ViceLog(2, ("Checking for dead venii & clients\n"));
411 /* This LWP does fsync checks every 5 minutes: it should not be used for
412 * other 5 minute activities because it may be delayed by timeouts when
413 * it probes the workstations
415 static FsyncCheckLWP()
418 #ifdef AFS_PTHREAD_ENV
419 struct timespec fsync_next;
421 ViceLog(1, ("Starting fsync check process\n"));
423 #ifdef AFS_PTHREAD_ENV
424 assert(pthread_cond_init(&fsync_cond, NULL) == 0);
425 assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
430 #ifdef AFS_PTHREAD_ENV
431 /* rounding is fine */
432 fsync_next.tv_nsec = 0;
433 fsync_next.tv_sec = time(0) + fiveminutes;
435 code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex,
437 if (code != 0 && code != ETIMEDOUT)
438 ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
439 #else /* AFS_PTHREAD_ENV */
440 if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
441 ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
442 #endif /* AFS_PTHREAD_ENV */
443 ViceLog(2, ("Checking for fsync events\n"));
445 code = BreakLaterCallBacks();
450 /*------------------------------------------------------------------------
451 * PRIVATE ClearXStatValues
454 * Initialize all of the values collected via the xstat
464 * Must be called during File Server initialization.
468 *------------------------------------------------------------------------*/
470 static void ClearXStatValues()
471 { /*ClearXStatValues*/
473 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
474 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
475 int i; /*Loop counter*/
478 * Zero all xstat-related structures.
480 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
481 #if FS_STATS_DETAILED
482 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
485 * That's not enough. We have to set reasonable minima for
486 * time and xfer values in the detailed stats.
488 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
489 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
490 opTimeP->minTime.tv_sec = 999999;
492 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
493 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
494 opXferP->minTime.tv_sec = 999999;
495 opXferP->minBytes = 999999999;
499 * There's more. We have to set our unique system identifier, as
500 * declared in param.h. If such a thing is not defined, we bitch
501 * and declare ourselves to be an unknown system type.
504 afs_perfstats.sysname_ID = SYS_NAME_ID;
507 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
508 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
510 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
511 #endif /* SYS_NAME_ID */
514 } /*ClearXStatValues*/
517 static void PrintCounters()
519 int dirbuff, dircall, dirio;
521 int workstations, activeworkstations, delworkstations;
525 TM_GetTimeOfDay(&tpl, 0);
527 ViceLog(0, ("Vice was last started at %s\n",
528 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
532 DStat(&dirbuff, &dircall, &dirio);
533 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
534 dirbuff, dircall, dirio));
535 rx_PrintStats(stderr);
537 PrintCallBackStats();
539 processSize = -1; /* TODO: */
541 processSize = (int)((long) sbrk(0) >> 10);
543 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
544 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
547 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
548 workstations, activeworkstations, delworkstations));
555 static void CheckSignal()
557 if (FS_registered > 0) {
559 * We have proper ip addresses; tell the vlserver what we got; the following
560 * routine will do the proper reporting for us
572 void ShutDownAndCore(int dopanic)
574 time_t now = time(0);
578 ViceLog(0, ("Shutting down file server at %s",
579 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
581 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
582 #ifndef AFS_QUIETFS_ENV
583 if (console != NULL) {
584 fprintf(console,"File server restart/shutdown received at %s\r",
585 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
591 /* do not allows new reqests to be served from now on, all new requests
592 are returned with an error code of RX_RESTARTING ( transient failure ) */
593 rx_SetRxTranquil(); /* dhruba */
597 rx_PrintStats(debugFile);
600 if (console != NULL) {
603 #ifndef AFS_QUIETFS_ENV
604 fprintf(console, "File server has terminated abnormally at %s\r",
605 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
607 ViceLog(0, ("File server has terminated abnormally at %s\n",
608 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
610 #ifndef AFS_QUIETFS_ENV
611 fprintf(console, "File server has terminated normally at %s\r",
612 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
614 ViceLog(0, ("File server has terminated normally at %s\n",
615 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
623 void ShutDown(void) /* backward compatibility */
625 ShutDownAndCore(DONTPANIC);
629 static void FlagMsg()
633 /* default supports help flag */
635 strcpy(buffer, "Usage: fileserver ");
636 strcat(buffer, "[-d <debug level>] ");
637 strcat(buffer, "[-p <number of processes>] ");
638 strcat(buffer, "[-spare <number of spare blocks>] ");
639 strcat(buffer, "[-pctspare <percentage spare>] ");
640 strcat(buffer, "[-b <buffers>] ");
641 strcat(buffer, "[-l <large vnodes>] ");
642 strcat(buffer, "[-s <small vnodes>] ");
643 strcat(buffer, "[-vc <volume cachesize>] ");
644 strcat(buffer, "[-w <call back wait interval>] ");
645 strcat(buffer, "[-cb <number of call backs>] ");
646 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
647 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
648 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
649 strcat(buffer, "[-readonly (read-only file server)] ");
650 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
651 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
652 strcat(buffer, "[-nobusy <no VBUSY before a volume is attached>] ");
653 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
654 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
655 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
657 strcat(buffer, "[-m <min percentage spare in partition>] ");
659 #if defined(AFS_SGI_ENV)
660 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
662 strcat(buffer, "[-L (large server conf)] ");
663 strcat(buffer, "[-S (small server conf)] ");
664 strcat(buffer, "[-k <stack size>] ");
665 strcat(buffer, "[-realm <Kerberos realm name>] ");
666 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
667 strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
668 /* strcat(buffer, "[-enable_peer_stats] "); */
669 /* strcat(buffer, "[-enable_process_stats] "); */
670 strcat(buffer, "[-help]\n");
672 ViceLog(0, ("%s", buffer));
681 static afs_int32 ParseRights(char *arights)
687 if (!arights || !strcmp(arights, "")) {
688 printf("Missing list of mode bits on -implicit option\n");
691 if (!strcmp(arights, "none"))
693 else if (!strcmp(arights, "read"))
694 mode = PRSFS_READ | PRSFS_LOOKUP;
695 else if (!strcmp(arights, "write"))
696 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
697 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
698 else if (!strcmp(arights, "all"))
699 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
700 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
702 len = strlen(arights);
705 if (tc == 'r') mode |= PRSFS_READ;
706 else if (tc == 'l') mode |= PRSFS_LOOKUP;
707 else if (tc == 'i') mode |= PRSFS_INSERT;
708 else if (tc == 'd') mode |= PRSFS_DELETE;
709 else if (tc == 'w') mode |= PRSFS_WRITE;
710 else if (tc == 'k') mode |= PRSFS_LOCK;
711 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
712 else if (tc == 'A') mode |= PRSFS_USR0;
713 else if (tc == 'B') mode |= PRSFS_USR1;
714 else if (tc == 'C') mode |= PRSFS_USR2;
715 else if (tc == 'D') mode |= PRSFS_USR3;
716 else if (tc == 'E') mode |= PRSFS_USR4;
717 else if (tc == 'F') mode |= PRSFS_USR5;
718 else if (tc == 'G') mode |= PRSFS_USR6;
719 else if (tc == 'H') mode |= PRSFS_USR7;
721 printf("Illegal -implicit rights character '%c'.\n", tc);
730 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
731 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
734 * AIX: sysconf() limit is real
735 * HP-UX: sysconf() limit is real
736 * IRIX: sysconf() limit is apparently NOT real -- too small
737 * DUX: sysconf() limit is apparently NOT real -- too big
738 * Linux: sysconf() limit is apparently NOT real -- too big
739 * Solaris: no sysconf() limit
742 max_fileserver_thread(void)
744 #if defined(AFS_PTHREAD_ENV)
745 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
748 ans = sysconf(_SC_THREAD_THREADS_MAX);
749 if (0 < ans && ans < MAX_FILESERVER_THREAD)
752 #endif /* defined(AFS_PTHREAD_ENV) */
753 return MAX_FILESERVER_THREAD;
756 static int ParseArgs(int argc, char *argv[])
758 int SawL=0, SawS=0, SawVC=0;
759 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
762 int bufSize = 0; /* temp variable to read in udp socket buf size*/
764 for (i = 1; i < argc; i++) {
765 if (!strcmp(argv[i], "-d")) {
766 debuglevel = atoi(argv[++i]);
767 LogLevel = debuglevel;
770 if (!strcmp(argv[i], "-banner")) {
773 if (!strcmp(argv[i], "-implicit")) {
774 implicitAdminRights = ParseRights(argv[++i]);
775 if (implicitAdminRights < 0) return implicitAdminRights;
777 if (!strcmp(argv[i], "-readonly")) {
780 if (!strcmp(argv[i], "-L")) {
783 if (!strcmp(argv[i], "-S")) {
787 if (!strcmp(argv[i], "-p")) {
788 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
790 lwps = atoi(argv[++i]);
797 if (!strcmp(argv[i], "-b")) {
799 buffs = atoi(argv[++i]);
802 if (!strcmp(argv[i], "-l")) {
804 large = atoi(argv[++i]);
807 if (!strcmp(argv[i], "-vc")) {
809 volcache = atoi(argv[++i]);
812 if (!strcmp(argv[i], "-novbc")) {
816 if (!strcmp(argv[i], "-rxpck")) {
818 rxpackets = atoi(argv[++i]);
821 if (!strcmp(argv[i], "-s")) {
823 nSmallVns = atoi(argv[++i]);
826 if (!strcmp(argv[i], "-k"))
827 stack = atoi(argv[++i]);
828 #if defined(AFS_SGI_ENV)
830 if (!strcmp(argv[i], "-lock")) {
835 if (!strcmp(argv[i], "-spare")) {
836 BlocksSpare = atoi(argv[++i]);
840 if (!strcmp(argv[i], "-pctspare")) {
841 PctSpare = atoi(argv[++i]);
842 BlocksSpare = 0; /* has non-zero default */
846 if (!strcmp(argv[i], "-w"))
847 fiveminutes = atoi(argv[++i]);
849 if (!strcmp(argv[i], "-hr")) {
850 int hr = atoi(argv[++i]);
851 if ((hr < 1) || (hr > 36)) {
852 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
856 hostaclRefresh = hr*60*60;
858 if (!strcmp(argv[i], "-rxdbg"))
861 if (!strcmp(argv[i], "-rxdbge"))
864 if (!strcmp(argv[i], "-cb")) {
866 numberofcbs = atoi(argv[++i]);
867 if ((numberofcbs < 10000) || (numberofcbs > 2147483647)) {
868 printf("number of cbs %d invalid; must be between 10000 and 2147483647\n",
874 if (!strcmp(argv[i], "-busyat")) {
876 busy_threshold = atoi(argv[++i]);
877 if (busy_threshold < 10) {
878 printf("Busy threshold %d is too low, will compute default.\n",
884 if (!strcmp(argv[i], "-nobusy"))
888 if (!strcmp(argv[i], "-m")) {
889 extern int aixlow_water;
890 aixlow_water = atoi(argv[++i]);
891 if ((aixlow_water < 0) || (aixlow_water > 30)) {
892 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
898 if (!strcmp(argv[i], "-nojumbo")) {
902 if (!strcmp(argv[i], "-realm")) {
903 extern char local_realm[AFS_REALM_SZ];
904 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
905 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
908 strncpy (local_realm, argv[i], AFS_REALM_SZ);
911 if ( !strcmp(argv[i], "-udpsize")) {
912 if ( (i+1) >= argc ) {
913 printf("You have to specify -udpsize <integer value>\n");
916 bufSize = atoi(argv[++i]);
917 if ( bufSize < rx_GetMinUdpBufSize() )
918 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
919 bufSize, rx_GetMinUdpBufSize() );
921 udpBufSize = bufSize;
924 if ( !strcmp(argv[i], "-sendsize")) {
925 if ( (i+1) >= argc ) {
926 printf("You have to specify -sendsize <integer value>\n");
929 bufSize = atoi(argv[++i]);
930 if ( bufSize < 16384 )
931 printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
934 sendBufSize = bufSize;
937 if (!strcmp(argv[i], "-enable_peer_stats")) {
938 rx_enablePeerRPCStats();
941 if (!strcmp(argv[i], "-enable_process_stats")) {
942 rx_enableProcessRPCStats();
946 if (strcmp(argv[i], "-syslog")==0) {
947 /* set syslog logging flag */
951 if (strncmp(argv[i], "-syslog=", 8)==0) {
953 serverLogSyslogFacility = atoi(argv[i]+8);
961 printf("Only one of -L, or -S must be specified\n");
965 if (!Sawrxpck) rxpackets = 100;
966 if (!Sawsmall) nSmallVns = 200;
967 if (!Sawlarge) large = 200;
968 if (!Sawcbs) numberofcbs = 20000;
969 if (!Sawlwps) lwps = 6;
970 if (!Sawbufs) buffs = 70;
971 if (!SawVC) volcache = 200;
974 if (!Sawrxpck) rxpackets = 200;
975 if (!Sawsmall) nSmallVns = 600;
976 if (!Sawlarge) large = 600;
977 if (!Sawcbs) numberofcbs = 64000;
978 if (!Sawlwps) lwps = 12;
979 if (!Sawbufs) buffs = 120;
980 if (!SawVC) volcache = 600;
983 busy_threshold = 3*rxpackets/2;
992 static void NewParms(int initializing)
994 static struct stat sbuf;
995 register afs_offs_t i;
998 char *argv[MAXPARMS];
1001 if (!(stat("/vice/file/parms",&sbuf))) {
1002 parms = (char *)malloc(sbuf.st_size);
1004 fd = open("parms", O_RDONLY, 0666);
1006 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1010 i = read(fd, parms, sbuf.st_size);
1012 if(i != sbuf.st_size) {
1014 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1017 ("Read on parms failed; expected %d bytes but read %d\n",
1024 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1026 for (argc = i = 0; i < sbuf.st_size; i++) {
1027 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1028 if(argv[argc] == 0) argv[argc] = (parms+i);
1031 *(parms + i) = '\0';
1032 if(argv[argc] != 0) {
1033 if(++argc == MAXPARMS) break;
1035 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1039 if(ParseArgs(argc, argv) == 0) {
1040 ViceLog(0, ("Change parameters to:"));
1042 ViceLog(0, ("Invalid parameter in:"));
1044 for(i = 0; i < argc; i++) {
1045 ViceLog(0, (" %s", argv[i]));
1052 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1057 /* Miscellaneous routines */
1058 void Die (char *msg)
1060 ViceLog (0,("%s\n", msg));
1071 * If this fails, it's because something major is wrong, and is not
1072 * likely to be time dependent.
1074 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1076 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1079 SystemId = SYSADMINID;
1080 SystemAnyUser = ANYUSERID;
1081 SystemAnyUserCPS.prlist_len = 0;
1082 SystemAnyUserCPS.prlist_val = NULL;
1083 AnonCPS.prlist_len = 0;
1084 AnonCPS.prlist_val = NULL;
1086 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1089 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1093 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1095 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1098 AnonymousID = ANONYMOUSID;
1101 #ifdef AFS_PTHREAD_ENV
1103 #else /* AFS_PTHREAD_ENV */
1105 #endif /* AFS_PTHREAD_ENV */
1109 struct rx_connection *serverconns[MAXSERVERS];
1110 struct ubik_client *cstruct;
1112 afs_int32 vl_Initialize(char *confDir)
1113 { afs_int32 code, scIndex = 0, i;
1114 struct afsconf_dir *tdir;
1115 struct rx_securityClass *sc;
1116 struct afsconf_cell info;
1118 tdir = afsconf_Open(confDir);
1120 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1123 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1125 ViceLog(0, ("Could not get security object for localAuth\n"));
1128 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1129 if (info.numServers > MAXSERVERS) {
1130 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1133 for (i = 0;i<info.numServers;i++)
1134 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1135 USER_SERVICE_ID, sc, scIndex);
1136 code = ubik_ClientInit(serverconns, &cstruct);
1138 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1144 #define SYSIDMAGIC 0x88aabbcc
1145 #define SYSIDVERSION 1
1149 afs_int32 fd, nentries, i;
1150 struct versionStamp vsn;
1154 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1155 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1158 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1159 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1162 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1163 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1166 if (vsn.magic != SYSIDMAGIC) {
1167 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1170 if (vsn.version != SYSIDVERSION) {
1171 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1174 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1175 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1178 afs_ntohuuid(&uuid);
1180 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1181 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1184 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1185 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1188 FS_HostAddr_cnt = nentries;
1189 for (i = 0; i < nentries; i++) {
1190 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1191 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1192 FS_HostAddr_cnt = 0; /* reset it */
1202 afs_int32 fd, nentries, i;
1203 struct versionStamp vsn;
1207 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1209 * File exists; keep the old one around
1211 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1213 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1215 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1218 vsn.magic = SYSIDMAGIC;
1220 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1221 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1225 afs_htonuuid(&uuid);
1226 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1227 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1230 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1231 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1234 for (i = 0; i < FS_HostAddr_cnt; i++) {
1235 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1236 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1246 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1247 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1248 * and so we need to convert each of them into HBO which is what the extra
1249 * array called FS_HostAddrs_HBO is used here.
1252 Do_VLRegisterRPC() {
1255 extern int VL_RegisterAddrs();
1256 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1259 for (i=0; i < FS_HostAddr_cnt ; i++)
1260 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1261 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1262 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1263 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1265 if (code == VL_MULTIPADDR) {
1266 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1267 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1269 } else if (code == RXGEN_OPCODE) {
1270 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1271 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1273 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1277 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1284 afs_int32 InitVL() {
1288 extern int rxi_numNetAddrs;
1289 extern afs_uint32 rxi_NetAddrs[];
1292 * If this fails, it's because something major is wrong, and is not
1293 * likely to be time dependent.
1295 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1297 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1301 /* Read or create the sysid file and register the fileserver's
1302 * IP addresses with the vlserver.
1304 code = ReadSysIdFile();
1306 /* Need to create the file */
1307 ViceLog(0, ("Creating new SysID file\n"));
1308 if ((code = afs_uuid_create(&FS_HostUUID))) {
1309 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1313 /* A good sysid file exists; inform the vlserver. If any conflicts,
1314 * we always use the latest interface available as the real truth.
1316 #ifndef AFS_NT40_ENV
1317 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1319 * Find addresses we are supposed to register as per the netrestrict
1320 * and netinfo files (/usr/afs/local/NetInfo and
1321 * /usr/afs/local/NetRestict)
1324 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1325 ADDRSPERSITE, reason,
1326 AFSDIR_SERVER_NETINFO_FILEPATH,
1327 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1329 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1332 FS_HostAddr_cnt = (afs_uint32) code;
1337 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1341 code = Do_VLRegisterRPC();
1346 main(int argc, char * argv[])
1352 struct rx_securityClass *sc[4];
1353 struct rx_service *tservice;
1354 #ifdef AFS_PTHREAD_ENV
1355 pthread_t parentPid, serverPid;
1356 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 #if defined(AFS_PTHREAD_ENV)
1430 /* initialize the pthread soft signal handler thread */
1434 /* install signal handlers for controlling the fileserver process */
1435 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
1436 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
1438 #if defined(AFS_SGI_ENV)
1439 /* give this guy a non-degrading priority so help busy servers */
1440 schedctl(NDPRI, 0, NDPNORMMAX);
1444 #ifndef AFS_NT40_ENV
1445 nice(-5); /* TODO: */
1448 assert(DInit(buffs) == 0);
1451 if (afs_winsockInit()<0) {
1452 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
1453 ViceLog(0, ("File server failed to intialize winsock.\n"));
1459 /* if we support more than 16 threads, then we better have the ability
1460 ** to keep open a large number of files simultaneously
1462 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
1463 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
1464 #elif defined(AFS_NT40_ENV)
1465 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
1468 curLimit = 0; /* the number of open file descriptors */
1469 code = getrlimit(RLIMIT_NOFILE, &rlim);
1471 curLimit = rlim.rlim_cur;
1472 rlim.rlim_cur = rlim.rlim_max;
1473 code = setrlimit(RLIMIT_NOFILE, &rlim);
1475 curLimit = rlim.rlim_max;
1478 ViceLog(0, ("Failed to increase open file limit, using default\n"));
1480 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
1482 curLimit -= 32; /* leave a slack of 32 file descriptors */
1483 if ( lwps > curLimit ) {
1486 else if ( lwps > 16 )
1487 lwps = 16; /* default to a maximum of 16 threads */
1488 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
1492 #ifndef AFS_PTHREAD_ENV
1493 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
1494 #endif /* !AFS_PTHREAD_ENV */
1496 /* Initialize volume support */
1498 V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
1501 /* initialize libacl routines */
1502 acl_Initialize(ACL_VERSION);
1504 /* initialize RX support */
1505 #ifndef AFS_NT40_ENV
1506 rxi_syscallp = viced_syscall;
1508 rx_extraPackets = rxpackets;
1509 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
1510 rx_SetBusyThreshold(busy_threshold, VBUSY);
1511 rx_SetCallAbortThreshold(10);
1512 rx_SetConnAbortThreshold(10);
1513 stackSize = lwps * 4000;
1514 if (stackSize < 32000)
1516 else if (stackSize > 44000)
1518 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
1519 rx_SetStackSize(1, stackSize);
1522 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
1523 if (rx_Init((int)htons(7000))<0) {
1524 ViceLog(0, ("Cannot initialize RX\n"));
1527 if (!rxJumbograms) {
1528 /* Don't send and don't allow 3.4 clients to send jumbograms. */
1532 rx_SetRxDeadTime(30);
1533 sc[0] = rxnull_NewServerSecurityObject();
1534 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
1535 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
1537 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
1539 tservice = rx_NewService
1540 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
1541 /* security classes */ sc, /* numb sec classes */ 4,
1542 RXAFS_ExecuteRequest);
1544 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
1547 rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
1548 rx_SetMinProcs(tservice, 3);
1549 rx_SetMaxProcs(tservice, lwps);
1550 rx_SetCheckReach(tservice, 1);
1552 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
1554 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
1557 rx_SetMinProcs(tservice, 2);
1558 rx_SetMaxProcs(tservice, 4);
1561 * Enable RX hot threads, which allows the listener thread to trade
1562 * places with an idle thread and moves the context switch from listener
1563 * to worker out of the critical path.
1565 rx_EnableHotThread();
1567 /* Some rx debugging */
1568 if (rxlog || eventlog) {
1569 debugFile = fopen("rx_dbg", "w");
1570 if (rxlog) rx_debugFile = debugFile;
1571 if (eventlog) rxevent_debugFile = debugFile;
1574 h_InitHostPackage(); /* set up local cellname and realmname */
1575 InitCallBack(numberofcbs);
1580 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
1586 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
1590 /* allow super users to manage RX statistics */
1591 rx_SetRxStatUserOk(fs_rxstat_userok);
1593 rx_StartServer(0); /* now start handling requests */
1595 /* we ensure that there is enough space in the vnode buffer to satisfy
1596 ** requests from all concurrent threads.
1597 ** the maximum number of vnodes used by a single thread at any one time
1598 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
1599 ** two vSmall for linking files and two vLarge and one vSmall for linking
1602 minVnodesRequired = 2 * lwps + 1;
1603 if ( minVnodesRequired > nSmallVns ) {
1604 nSmallVns = minVnodesRequired;
1605 ViceLog(0, ("Overriding -s command line parameter with %d\n",
1608 if ( minVnodesRequired > large ) {
1609 large = minVnodesRequired;
1610 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
1613 /* We now do this after getting the listener up and running, so that client
1614 connections don't timeout (maybe) if a file server is restarted, since it
1615 will be available "real soon now". Worry about whether we can satisfy the
1616 calls in the volume package itself.
1618 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
1619 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
1625 * We are done calling fopen/fdopen. It is safe to use a large
1626 * of the file descriptor cache.
1630 #ifdef AFS_PTHREAD_ENV
1631 assert(pthread_attr_init(&tattr) == 0);
1632 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
1634 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
1635 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
1636 assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
1637 #else /* AFS_PTHREAD_ENV */
1638 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1639 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
1641 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1642 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
1643 assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1644 (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
1645 #endif /* AFS_PTHREAD_ENV */
1647 TM_GetTimeOfDay(&tp, 0);
1649 #ifndef AFS_QUIETFS_ENV
1650 if (console != NULL) {
1651 fprintf(console, "File server has started at %s\r",
1652 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
1657 * Figure out the FileServer's name and primary address.
1659 ViceLog(0, ("Getting FileServer name...\n"));
1660 code = gethostname(FS_HostName, 64);
1662 ViceLog(0, ("gethostname() failed\n"));
1664 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
1666 ViceLog(0, ("Getting FileServer address...\n"));
1667 he = gethostbyname(FS_HostName);
1669 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
1673 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
1674 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
1675 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
1676 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
1677 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
1680 /* Install handler to catch the shutdown signal;
1681 * bosserver assumes SIGQUIT shutdown
1683 #if defined(AFS_PTHREAD_ENV)
1684 softsig_signal(SIGQUIT, ShutDown_Signal);
1686 signal(SIGQUIT, ShutDown_Signal);
1689 ViceLog(0,("File Server started %s",
1690 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
1691 #if FS_STATS_DETAILED
1692 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
1694 #ifdef AFS_PTHREAD_ENV
1696 sleep(1000); /* long time */
1698 #else /* AFS_PTHREAD_ENV */
1699 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
1700 #endif /* AFS_PTHREAD_ENV */