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 abort_threshold = 10;
181 int udpBufSize = 0; /* UDP buffer size for receive*/
182 int sendBufSize = 16384; /* send buffer size */
187 * FileServer's name and IP address, both network byte order and
190 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
192 char FS_HostName[128] = "localhost";
193 afs_uint32 FS_HostAddr_NBO;
194 afs_uint32 FS_HostAddr_HBO;
195 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
196 /* All addresses in FS_HostAddrs are in NBO */
199 static void FlagMsg();
202 * Home for the performance statistics.
206 static void CheckDescriptors()
210 register int tsize = getdtablesize();
212 for (i = 0; i<tsize; i++) {
213 if (fstat(i, &status) != -1) {
214 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
215 i, status.st_dev, status.st_ino,
216 status.st_size, status.st_mode);
220 ResetCheckDescriptors();
222 } /*CheckDescriptors*/
225 #ifdef AFS_PTHREAD_ENV
226 void CheckSignal_Signal(x) {CheckSignal();}
227 void ShutDown_Signal(x) {ShutDown();}
228 void CheckDescriptors_Signal(x) {CheckDescriptors();}
229 #else /* AFS_PTHREAD_ENV */
230 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
231 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
232 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
233 #endif /* AFS_PTHREAD_ENV */
235 /* check whether caller is authorized to manage RX statistics */
236 int fs_rxstat_userok(struct rx_call *call)
238 return afsconf_SuperUser(confDir, call, NULL);
241 static void ResetCheckSignal(void)
245 #if defined(AFS_HPUX_ENV)
248 #if defined(AFS_NT40_ENV)
255 #if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
256 softsig_signal(signo, CheckSignal_Signal);
258 signal(signo, CheckSignal_Signal);
262 static void ResetCheckDescriptors(void)
265 #if defined(AFS_PTHREAD_ENV)
266 softsig_signal(SIGTERM, CheckDescriptors_Signal);
268 signal(SIGTERM, CheckDescriptors_Signal);
274 /* proc called by rxkad module to get a key */
275 static int get_key(char *arock, register afs_int32 akvno, char *akey)
278 static struct afsconf_key tkey;
279 register afs_int32 code;
282 ViceLog(0, ("conf dir not open\n"));
285 code = afsconf_GetKey(confDir, akvno, tkey.key);
288 memcpy(akey, tkey.key, sizeof(tkey.key));
294 int viced_syscall(afs_uint32 a3, afs_uint32 a4, void * a5)
299 #ifndef AFS_LINUX20_ENV
300 old = (void (*)())signal(SIGSYS, SIG_IGN);
302 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
303 #ifndef AFS_LINUX20_ENV
311 #if !defined(AFS_NT40_ENV)
312 #include "AFS_component_version_number.c"
313 #endif /* !AFS_NT40_ENV */
315 #define MAXADMINNAME 64
316 char adminName[MAXADMINNAME];
324 if ((stat("/AdminName", &status)) || /* if file does not exist */
325 (status.st_size <= 0) || /* or it is too short */
326 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
327 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
328 strcpy(adminName, "System:Administrators"); /* use the default name */
331 read(fd, adminName, status.st_size); /* use name from the file */
334 close(fd); /* close fd if it was opened */
339 static void setThreadId(char *s)
341 #if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
342 /* set our 'thread-id' so that the host hold table works */
343 MUTEX_ENTER(&rx_stats_mutex); /* protects rxi_pthread_hinum */
345 pthread_setspecific(rx_thread_id_key, (void *)rxi_pthread_hinum);
346 MUTEX_EXIT(&rx_stats_mutex);
347 ViceLog(0,("Set thread id %d for '%s'\n", pthread_getspecific(rx_thread_id_key), s));
351 /* This LWP does things roughly every 5 minutes */
352 static void FiveMinuteCheckLWP()
357 ViceLog(1, ("Starting five minute check process\n"));
358 setThreadId("FiveMinuteCheckLWP");
360 #ifdef AFS_PTHREAD_ENV
362 #else /* AFS_PTHREAD_ENV */
363 IOMGR_Sleep(fiveminutes);
364 #endif /* AFS_PTHREAD_ENV */
366 /* close the log so it can be removed */
367 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
368 ViceLog(2, ("Cleaning up timed out callbacks\n"));
369 if(CleanupTimedOutCallBacks())
370 ViceLog(5,("Timed out callbacks deleted\n"));
371 ViceLog(2, ("Set disk usage statistics\n"));
373 if (FS_registered == 1) Do_VLRegisterRPC();
374 /* Force wakeup in case we missed something; pthreads does timedwait */
375 #ifndef AFS_PTHREAD_ENV
376 LWP_NoYieldSignal(&fsync_wait);
378 if(printBanner && (++msg&1)) { /* Every 10 minutes */
379 time_t now = FT_ApproxTime();
380 if (console != NULL) {
381 #ifndef AFS_QUIETFS_ENV
382 fprintf(console,"File server is running at %s\r",
383 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
384 #endif /* AFS_QUIETFS_ENV */
385 ViceLog(2, ("File server is running at %s\n",
386 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
390 } /*FiveMinuteCheckLWP*/
393 /* This LWP does host checks every 5 minutes: it should not be used for
394 * other 5 minute activities because it may be delayed by timeouts when
395 * it probes the workstations
397 static void HostCheckLWP()
399 ViceLog(1, ("Starting Host check process\n"));
400 setThreadId("HostCheckLWP");
402 #ifdef AFS_PTHREAD_ENV
404 #else /* AFS_PTHREAD_ENV */
405 IOMGR_Sleep(fiveminutes);
406 #endif /* AFS_PTHREAD_ENV */
407 ViceLog(2, ("Checking for dead venii & clients\n"));
412 /* This LWP does fsync checks every 5 minutes: it should not be used for
413 * other 5 minute activities because it may be delayed by timeouts when
414 * it probes the workstations
416 static FsyncCheckLWP()
419 #ifdef AFS_PTHREAD_ENV
420 struct timespec fsync_next;
422 ViceLog(1, ("Starting fsync check process\n"));
424 setThreadId("FsyncCheckLWP");
426 #ifdef AFS_PTHREAD_ENV
427 assert(pthread_cond_init(&fsync_cond, NULL) == 0);
428 assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
433 #ifdef AFS_PTHREAD_ENV
434 /* rounding is fine */
435 fsync_next.tv_nsec = 0;
436 fsync_next.tv_sec = time(0) + fiveminutes;
438 code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex,
440 if (code != 0 && code != ETIMEDOUT)
441 ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
442 #else /* AFS_PTHREAD_ENV */
443 if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
444 ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
445 #endif /* AFS_PTHREAD_ENV */
446 ViceLog(2, ("Checking for fsync events\n"));
448 code = BreakLaterCallBacks();
453 /*------------------------------------------------------------------------
454 * PRIVATE ClearXStatValues
457 * Initialize all of the values collected via the xstat
467 * Must be called during File Server initialization.
471 *------------------------------------------------------------------------*/
473 static void ClearXStatValues()
474 { /*ClearXStatValues*/
476 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
477 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
478 int i; /*Loop counter*/
481 * Zero all xstat-related structures.
483 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
484 #if FS_STATS_DETAILED
485 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
488 * That's not enough. We have to set reasonable minima for
489 * time and xfer values in the detailed stats.
491 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
492 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
493 opTimeP->minTime.tv_sec = 999999;
495 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
496 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
497 opXferP->minTime.tv_sec = 999999;
498 opXferP->minBytes = 999999999;
502 * There's more. We have to set our unique system identifier, as
503 * declared in param.h. If such a thing is not defined, we bitch
504 * and declare ourselves to be an unknown system type.
507 afs_perfstats.sysname_ID = SYS_NAME_ID;
510 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
511 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
513 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
514 #endif /* SYS_NAME_ID */
517 } /*ClearXStatValues*/
520 static void PrintCounters()
522 int dirbuff, dircall, dirio;
524 int workstations, activeworkstations, delworkstations;
528 TM_GetTimeOfDay(&tpl, 0);
530 ViceLog(0, ("Vice was last started at %s\n",
531 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
535 DStat(&dirbuff, &dircall, &dirio);
536 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
537 dirbuff, dircall, dirio));
538 rx_PrintStats(stderr);
540 PrintCallBackStats();
542 processSize = -1; /* TODO: */
544 processSize = (int)((long) sbrk(0) >> 10);
546 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
547 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
550 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
551 workstations, activeworkstations, delworkstations));
558 static void CheckSignal()
560 if (FS_registered > 0) {
562 * We have proper ip addresses; tell the vlserver what we got; the following
563 * routine will do the proper reporting for us
575 void ShutDownAndCore(int dopanic)
577 time_t now = time(0);
581 ViceLog(0, ("Shutting down file server at %s",
582 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
584 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
585 #ifndef AFS_QUIETFS_ENV
586 if (console != NULL) {
587 fprintf(console,"File server restart/shutdown received at %s\r",
588 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
594 /* do not allows new reqests to be served from now on, all new requests
595 are returned with an error code of RX_RESTARTING ( transient failure ) */
596 rx_SetRxTranquil(); /* dhruba */
600 rx_PrintStats(debugFile);
603 if (console != NULL) {
606 #ifndef AFS_QUIETFS_ENV
607 fprintf(console, "File server has terminated abnormally at %s\r",
608 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
610 ViceLog(0, ("File server has terminated abnormally at %s\n",
611 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
613 #ifndef AFS_QUIETFS_ENV
614 fprintf(console, "File server has terminated normally at %s\r",
615 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
617 ViceLog(0, ("File server has terminated normally at %s\n",
618 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
626 void ShutDown(void) /* backward compatibility */
628 ShutDownAndCore(DONTPANIC);
632 static void FlagMsg()
636 /* default supports help flag */
638 strcpy(buffer, "Usage: fileserver ");
639 strcat(buffer, "[-d <debug level>] ");
640 strcat(buffer, "[-p <number of processes>] ");
641 strcat(buffer, "[-spare <number of spare blocks>] ");
642 strcat(buffer, "[-pctspare <percentage spare>] ");
643 strcat(buffer, "[-b <buffers>] ");
644 strcat(buffer, "[-l <large vnodes>] ");
645 strcat(buffer, "[-s <small vnodes>] ");
646 strcat(buffer, "[-vc <volume cachesize>] ");
647 strcat(buffer, "[-w <call back wait interval>] ");
648 strcat(buffer, "[-cb <number of call backs>] ");
649 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
650 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
651 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
652 strcat(buffer, "[-readonly (read-only file server)] ");
653 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
654 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
655 strcat(buffer, "[-nobusy <no VBUSY before a volume is attached>] ");
656 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
657 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
658 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
660 strcat(buffer, "[-m <min percentage spare in partition>] ");
662 #if defined(AFS_SGI_ENV)
663 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
665 strcat(buffer, "[-L (large server conf)] ");
666 strcat(buffer, "[-S (small server conf)] ");
667 strcat(buffer, "[-k <stack size>] ");
668 strcat(buffer, "[-realm <Kerberos realm name>] ");
669 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
670 strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
671 /* strcat(buffer, "[-enable_peer_stats] "); */
672 /* strcat(buffer, "[-enable_process_stats] "); */
673 strcat(buffer, "[-help]\n");
675 ViceLog(0, ("%s", buffer));
684 static afs_int32 ParseRights(char *arights)
690 if (!arights || !strcmp(arights, "")) {
691 printf("Missing list of mode bits on -implicit option\n");
694 if (!strcmp(arights, "none"))
696 else if (!strcmp(arights, "read"))
697 mode = PRSFS_READ | PRSFS_LOOKUP;
698 else if (!strcmp(arights, "write"))
699 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
700 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
701 else if (!strcmp(arights, "all"))
702 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
703 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
705 len = strlen(arights);
708 if (tc == 'r') mode |= PRSFS_READ;
709 else if (tc == 'l') mode |= PRSFS_LOOKUP;
710 else if (tc == 'i') mode |= PRSFS_INSERT;
711 else if (tc == 'd') mode |= PRSFS_DELETE;
712 else if (tc == 'w') mode |= PRSFS_WRITE;
713 else if (tc == 'k') mode |= PRSFS_LOCK;
714 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
715 else if (tc == 'A') mode |= PRSFS_USR0;
716 else if (tc == 'B') mode |= PRSFS_USR1;
717 else if (tc == 'C') mode |= PRSFS_USR2;
718 else if (tc == 'D') mode |= PRSFS_USR3;
719 else if (tc == 'E') mode |= PRSFS_USR4;
720 else if (tc == 'F') mode |= PRSFS_USR5;
721 else if (tc == 'G') mode |= PRSFS_USR6;
722 else if (tc == 'H') mode |= PRSFS_USR7;
724 printf("Illegal -implicit rights character '%c'.\n", tc);
733 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
734 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
737 * AIX: sysconf() limit is real
738 * HP-UX: sysconf() limit is real
739 * IRIX: sysconf() limit is apparently NOT real -- too small
740 * DUX: sysconf() limit is apparently NOT real -- too big
741 * Linux: sysconf() limit is apparently NOT real -- too big
742 * Solaris: no sysconf() limit
745 max_fileserver_thread(void)
747 #if defined(AFS_PTHREAD_ENV)
748 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
751 ans = sysconf(_SC_THREAD_THREADS_MAX);
752 if (0 < ans && ans < MAX_FILESERVER_THREAD)
755 #endif /* defined(AFS_PTHREAD_ENV) */
756 return MAX_FILESERVER_THREAD;
759 static int ParseArgs(int argc, char *argv[])
761 int SawL=0, SawS=0, SawVC=0;
762 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
765 int bufSize = 0; /* temp variable to read in udp socket buf size*/
767 for (i = 1; i < argc; i++) {
768 if (!strcmp(argv[i], "-d")) {
769 debuglevel = atoi(argv[++i]);
770 LogLevel = debuglevel;
773 if (!strcmp(argv[i], "-banner")) {
776 if (!strcmp(argv[i], "-implicit")) {
777 implicitAdminRights = ParseRights(argv[++i]);
778 if (implicitAdminRights < 0) return implicitAdminRights;
780 if (!strcmp(argv[i], "-readonly")) {
783 if (!strcmp(argv[i], "-L")) {
786 if (!strcmp(argv[i], "-S")) {
790 if (!strcmp(argv[i], "-p")) {
791 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
793 lwps = atoi(argv[++i]);
800 if (!strcmp(argv[i], "-b")) {
802 buffs = atoi(argv[++i]);
805 if (!strcmp(argv[i], "-l")) {
807 large = atoi(argv[++i]);
810 if (!strcmp(argv[i], "-vc")) {
812 volcache = atoi(argv[++i]);
815 if (!strcmp(argv[i], "-novbc")) {
819 if (!strcmp(argv[i], "-rxpck")) {
821 rxpackets = atoi(argv[++i]);
824 if (!strcmp(argv[i], "-s")) {
826 nSmallVns = atoi(argv[++i]);
829 if (!strcmp(argv[i], "-abortthreshold")) {
830 abort_threshold = atoi(argv[++i]);
833 if (!strcmp(argv[i], "-k"))
834 stack = atoi(argv[++i]);
835 #if defined(AFS_SGI_ENV)
837 if (!strcmp(argv[i], "-lock")) {
842 if (!strcmp(argv[i], "-spare")) {
843 BlocksSpare = atoi(argv[++i]);
847 if (!strcmp(argv[i], "-pctspare")) {
848 PctSpare = atoi(argv[++i]);
849 BlocksSpare = 0; /* has non-zero default */
853 if (!strcmp(argv[i], "-w"))
854 fiveminutes = atoi(argv[++i]);
856 if (!strcmp(argv[i], "-hr")) {
857 int hr = atoi(argv[++i]);
858 if ((hr < 1) || (hr > 36)) {
859 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
863 hostaclRefresh = hr*60*60;
865 if (!strcmp(argv[i], "-rxdbg"))
868 if (!strcmp(argv[i], "-rxdbge"))
871 if (!strcmp(argv[i], "-cb")) {
873 numberofcbs = atoi(argv[++i]);
874 if ((numberofcbs < 10000) || (numberofcbs > 2147483647)) {
875 printf("number of cbs %d invalid; must be between 10000 and 2147483647\n",
881 if (!strcmp(argv[i], "-busyat")) {
883 busy_threshold = atoi(argv[++i]);
884 if (busy_threshold < 10) {
885 printf("Busy threshold %d is too low, will compute default.\n",
891 if (!strcmp(argv[i], "-nobusy"))
895 if (!strcmp(argv[i], "-m")) {
896 extern int aixlow_water;
897 aixlow_water = atoi(argv[++i]);
898 if ((aixlow_water < 0) || (aixlow_water > 30)) {
899 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
905 if (!strcmp(argv[i], "-nojumbo")) {
909 if (!strcmp(argv[i], "-realm")) {
910 extern char local_realm[AFS_REALM_SZ];
911 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
912 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
915 strncpy (local_realm, argv[i], AFS_REALM_SZ);
918 if ( !strcmp(argv[i], "-udpsize")) {
919 if ( (i+1) >= argc ) {
920 printf("You have to specify -udpsize <integer value>\n");
923 bufSize = atoi(argv[++i]);
924 if ( bufSize < rx_GetMinUdpBufSize() )
925 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
926 bufSize, rx_GetMinUdpBufSize() );
928 udpBufSize = bufSize;
931 if ( !strcmp(argv[i], "-sendsize")) {
932 if ( (i+1) >= argc ) {
933 printf("You have to specify -sendsize <integer value>\n");
936 bufSize = atoi(argv[++i]);
937 if ( bufSize < 16384 )
938 printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
941 sendBufSize = bufSize;
944 if (!strcmp(argv[i], "-enable_peer_stats")) {
945 rx_enablePeerRPCStats();
948 if (!strcmp(argv[i], "-enable_process_stats")) {
949 rx_enableProcessRPCStats();
953 if (strcmp(argv[i], "-syslog")==0) {
954 /* set syslog logging flag */
958 if (strncmp(argv[i], "-syslog=", 8)==0) {
960 serverLogSyslogFacility = atoi(argv[i]+8);
968 printf("Only one of -L, or -S must be specified\n");
972 if (!Sawrxpck) rxpackets = 100;
973 if (!Sawsmall) nSmallVns = 200;
974 if (!Sawlarge) large = 200;
975 if (!Sawcbs) numberofcbs = 20000;
976 if (!Sawlwps) lwps = 6;
977 if (!Sawbufs) buffs = 70;
978 if (!SawVC) volcache = 200;
981 if (!Sawrxpck) rxpackets = 200;
982 if (!Sawsmall) nSmallVns = 600;
983 if (!Sawlarge) large = 600;
984 if (!Sawcbs) numberofcbs = 64000;
985 if (!Sawlwps) lwps = 12;
986 if (!Sawbufs) buffs = 120;
987 if (!SawVC) volcache = 600;
990 busy_threshold = 3*rxpackets/2;
999 static void NewParms(int initializing)
1001 static struct stat sbuf;
1004 char *argv[MAXPARMS];
1007 if (!(stat("/vice/file/parms",&sbuf))) {
1008 parms = (char *)malloc(sbuf.st_size);
1010 fd = open("parms", O_RDONLY, 0666);
1012 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1016 i = read(fd, parms, sbuf.st_size);
1018 if(i != sbuf.st_size) {
1020 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1023 ("Read on parms failed; expected %d bytes but read %d\n",
1030 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1032 for (argc = i = 0; i < sbuf.st_size; i++) {
1033 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1034 if(argv[argc] == 0) argv[argc] = (parms+i);
1037 *(parms + i) = '\0';
1038 if(argv[argc] != 0) {
1039 if(++argc == MAXPARMS) break;
1041 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1045 if(ParseArgs(argc, argv) == 0) {
1046 ViceLog(0, ("Change parameters to:"));
1048 ViceLog(0, ("Invalid parameter in:"));
1050 for(i = 0; i < argc; i++) {
1051 ViceLog(0, (" %s", argv[i]));
1058 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1063 /* Miscellaneous routines */
1064 void Die (char *msg)
1066 ViceLog (0,("%s\n", msg));
1077 * If this fails, it's because something major is wrong, and is not
1078 * likely to be time dependent.
1080 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1082 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1085 SystemId = SYSADMINID;
1086 SystemAnyUser = ANYUSERID;
1087 SystemAnyUserCPS.prlist_len = 0;
1088 SystemAnyUserCPS.prlist_val = NULL;
1089 AnonCPS.prlist_len = 0;
1090 AnonCPS.prlist_val = NULL;
1092 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1095 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1099 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1101 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1104 AnonymousID = ANONYMOUSID;
1107 #ifdef AFS_PTHREAD_ENV
1109 #else /* AFS_PTHREAD_ENV */
1111 #endif /* AFS_PTHREAD_ENV */
1115 struct rx_connection *serverconns[MAXSERVERS];
1116 struct ubik_client *cstruct;
1118 afs_int32 vl_Initialize(char *confDir)
1119 { afs_int32 code, scIndex = 0, i;
1120 struct afsconf_dir *tdir;
1121 struct rx_securityClass *sc;
1122 struct afsconf_cell info;
1124 tdir = afsconf_Open(confDir);
1126 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1129 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1131 ViceLog(0, ("Could not get security object for localAuth\n"));
1134 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1135 if (info.numServers > MAXSERVERS) {
1136 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1139 for (i = 0;i<info.numServers;i++)
1140 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1141 USER_SERVICE_ID, sc, scIndex);
1142 code = ubik_ClientInit(serverconns, &cstruct);
1144 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1150 #define SYSIDMAGIC 0x88aabbcc
1151 #define SYSIDVERSION 1
1155 afs_int32 fd, nentries, i;
1156 struct versionStamp vsn;
1160 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1161 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1164 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1165 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1168 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1169 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1172 if (vsn.magic != SYSIDMAGIC) {
1173 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1176 if (vsn.version != SYSIDVERSION) {
1177 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1180 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1181 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1184 afs_ntohuuid(&uuid);
1186 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1187 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1190 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1191 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1194 FS_HostAddr_cnt = nentries;
1195 for (i = 0; i < nentries; i++) {
1196 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1197 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1198 FS_HostAddr_cnt = 0; /* reset it */
1208 afs_int32 fd, nentries, i;
1209 struct versionStamp vsn;
1213 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1215 * File exists; keep the old one around
1217 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1219 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1221 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1224 vsn.magic = SYSIDMAGIC;
1226 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1227 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1231 afs_htonuuid(&uuid);
1232 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1233 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1236 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1237 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1240 for (i = 0; i < FS_HostAddr_cnt; i++) {
1241 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1242 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1252 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1253 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1254 * and so we need to convert each of them into HBO which is what the extra
1255 * array called FS_HostAddrs_HBO is used here.
1258 Do_VLRegisterRPC() {
1261 extern int VL_RegisterAddrs();
1262 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1265 for (i=0; i < FS_HostAddr_cnt ; i++)
1266 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1267 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1268 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1269 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1271 if (code == VL_MULTIPADDR) {
1272 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1273 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1275 } else if (code == RXGEN_OPCODE) {
1276 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1277 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1279 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1283 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1290 afs_int32 InitVL() {
1294 extern int rxi_numNetAddrs;
1295 extern afs_uint32 rxi_NetAddrs[];
1298 * If this fails, it's because something major is wrong, and is not
1299 * likely to be time dependent.
1301 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1303 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1307 /* Read or create the sysid file and register the fileserver's
1308 * IP addresses with the vlserver.
1310 code = ReadSysIdFile();
1312 /* Need to create the file */
1313 ViceLog(0, ("Creating new SysID file\n"));
1314 if ((code = afs_uuid_create(&FS_HostUUID))) {
1315 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1319 /* A good sysid file exists; inform the vlserver. If any conflicts,
1320 * we always use the latest interface available as the real truth.
1322 #ifndef AFS_NT40_ENV
1323 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1325 * Find addresses we are supposed to register as per the netrestrict
1326 * and netinfo files (/usr/afs/local/NetInfo and
1327 * /usr/afs/local/NetRestict)
1330 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1331 ADDRSPERSITE, reason,
1332 AFSDIR_SERVER_NETINFO_FILEPATH,
1333 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1335 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1338 FS_HostAddr_cnt = (afs_uint32) code;
1343 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1347 code = Do_VLRegisterRPC();
1352 main(int argc, char * argv[])
1358 struct rx_securityClass *sc[4];
1359 struct rx_service *tservice;
1360 #ifdef AFS_PTHREAD_ENV
1361 pthread_t parentPid, serverPid;
1362 pthread_attr_t tattr;
1363 #else /* AFS_PTHREAD_ENV */
1364 PROCESS parentPid, serverPid;
1365 #endif /* AFS_PTHREAD_ENV */
1367 int minVnodesRequired; /* min size of vnode cache */
1368 #ifndef AFS_NT40_ENV
1369 struct rlimit rlim; /* max number of open file descriptors */
1373 #ifdef AFS_AIX32_ENV
1374 struct sigaction nsa;
1376 sigemptyset(&nsa.sa_mask);
1377 nsa.sa_handler = SIG_DFL;
1378 nsa.sa_flags = SA_FULLDUMP;
1379 sigaction(SIGABRT, &nsa, NULL);
1380 sigaction(SIGSEGV, &nsa, NULL);
1383 /* Initialize dirpaths */
1384 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1386 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
1388 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
1392 #ifndef AFS_QUIETFS_ENV
1393 console = fopen("/dev/console","w");
1396 if(ParseArgs(argc,argv)) {
1401 #ifdef AFS_PTHREAD_ENV
1402 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
1403 #endif /* AFS_PTHREAD_ENV */
1405 #ifdef AFS_SGI_VNODE_GLUE
1406 if (afs_init_kernel_config(-1) <0) {
1407 printf("Can't determine NUMA configuration, not starting fileserver.\n");
1411 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
1413 fprintf(stderr, "Unable to open config directory %s\n",
1414 AFSDIR_SERVER_ETC_DIRPATH);
1420 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
1421 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
1424 if (SawSpare && SawPctSpare) {
1425 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
1429 #ifdef AFS_SGI_XFS_IOPS_ENV
1430 ViceLog(0, ("XFS/EFS File server starting\n"));
1432 ViceLog(0, ("File server starting\n"));
1435 #if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
1436 /* initialize the pthread soft signal handler thread */
1440 /* install signal handlers for controlling the fileserver process */
1441 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
1442 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
1444 #if defined(AFS_SGI_ENV)
1445 /* give this guy a non-degrading priority so help busy servers */
1446 schedctl(NDPRI, 0, NDPNORMMAX);
1450 #ifndef AFS_NT40_ENV
1451 nice(-5); /* TODO: */
1454 assert(DInit(buffs) == 0);
1457 if (afs_winsockInit()<0) {
1458 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
1459 ViceLog(0, ("File server failed to intialize winsock.\n"));
1465 /* if we support more than 16 threads, then we better have the ability
1466 ** to keep open a large number of files simultaneously
1468 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
1469 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
1470 #elif defined(AFS_NT40_ENV)
1471 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
1474 curLimit = 0; /* the number of open file descriptors */
1475 code = getrlimit(RLIMIT_NOFILE, &rlim);
1477 curLimit = rlim.rlim_cur;
1478 rlim.rlim_cur = rlim.rlim_max;
1479 code = setrlimit(RLIMIT_NOFILE, &rlim);
1481 curLimit = rlim.rlim_max;
1484 ViceLog(0, ("Failed to increase open file limit, using default\n"));
1486 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
1488 curLimit -= 32; /* leave a slack of 32 file descriptors */
1489 if ( lwps > curLimit ) {
1492 else if ( lwps > 16 )
1493 lwps = 16; /* default to a maximum of 16 threads */
1494 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
1498 #ifndef AFS_PTHREAD_ENV
1499 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
1500 #endif /* !AFS_PTHREAD_ENV */
1502 /* Initialize volume support */
1504 V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
1507 /* initialize libacl routines */
1508 acl_Initialize(ACL_VERSION);
1510 /* initialize RX support */
1511 #ifndef AFS_NT40_ENV
1512 rxi_syscallp = viced_syscall;
1514 rx_extraPackets = rxpackets;
1515 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
1516 rx_SetBusyThreshold(busy_threshold, VBUSY);
1517 rx_SetCallAbortThreshold(abort_threshold);
1518 rx_SetConnAbortThreshold(abort_threshold);
1519 stackSize = lwps * 4000;
1520 if (stackSize < 32000)
1522 else if (stackSize > 44000)
1524 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
1525 rx_SetStackSize(1, stackSize);
1528 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
1529 if (rx_Init((int)htons(7000))<0) {
1530 ViceLog(0, ("Cannot initialize RX\n"));
1533 if (!rxJumbograms) {
1534 /* Don't send and don't allow 3.4 clients to send jumbograms. */
1538 rx_SetRxDeadTime(30);
1539 sc[0] = rxnull_NewServerSecurityObject();
1540 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
1541 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
1543 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
1545 tservice = rx_NewService
1546 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
1547 /* security classes */ sc, /* numb sec classes */ 4,
1548 RXAFS_ExecuteRequest);
1550 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
1553 rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
1554 rx_SetMinProcs(tservice, 3);
1555 rx_SetMaxProcs(tservice, lwps);
1556 rx_SetCheckReach(tservice, 1);
1558 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
1560 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
1563 rx_SetMinProcs(tservice, 2);
1564 rx_SetMaxProcs(tservice, 4);
1567 * Enable RX hot threads, which allows the listener thread to trade
1568 * places with an idle thread and moves the context switch from listener
1569 * to worker out of the critical path.
1571 rx_EnableHotThread();
1573 /* Some rx debugging */
1574 if (rxlog || eventlog) {
1575 debugFile = fopen("rx_dbg", "w");
1576 if (rxlog) rx_debugFile = debugFile;
1577 if (eventlog) rxevent_debugFile = debugFile;
1580 init_sys_error_to_et(); /* Set up error table translation */
1581 h_InitHostPackage(); /* set up local cellname and realmname */
1582 InitCallBack(numberofcbs);
1587 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
1593 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
1597 /* allow super users to manage RX statistics */
1598 rx_SetRxStatUserOk(fs_rxstat_userok);
1600 rx_StartServer(0); /* now start handling requests */
1602 /* we ensure that there is enough space in the vnode buffer to satisfy
1603 ** requests from all concurrent threads.
1604 ** the maximum number of vnodes used by a single thread at any one time
1605 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
1606 ** two vSmall for linking files and two vLarge and one vSmall for linking
1609 minVnodesRequired = 2 * lwps + 1;
1610 if ( minVnodesRequired > nSmallVns ) {
1611 nSmallVns = minVnodesRequired;
1612 ViceLog(0, ("Overriding -s command line parameter with %d\n",
1615 if ( minVnodesRequired > large ) {
1616 large = minVnodesRequired;
1617 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
1620 /* We now do this after getting the listener up and running, so that client
1621 connections don't timeout (maybe) if a file server is restarted, since it
1622 will be available "real soon now". Worry about whether we can satisfy the
1623 calls in the volume package itself.
1625 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
1626 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
1632 * We are done calling fopen/fdopen. It is safe to use a large
1633 * of the file descriptor cache.
1637 #ifdef AFS_PTHREAD_ENV
1638 ViceLog(5, ("Starting pthreads\n"));
1639 assert(pthread_attr_init(&tattr) == 0);
1640 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
1642 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
1643 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
1644 assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
1645 #else /* AFS_PTHREAD_ENV */
1646 ViceLog(5, ("Starting LWP\n"));
1647 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1648 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
1650 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1651 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
1652 assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
1653 (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
1654 #endif /* AFS_PTHREAD_ENV */
1656 TM_GetTimeOfDay(&tp, 0);
1658 #ifndef AFS_QUIETFS_ENV
1659 if (console != NULL) {
1660 fprintf(console, "File server has started at %s\r",
1661 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
1666 * Figure out the FileServer's name and primary address.
1668 ViceLog(0, ("Getting FileServer name...\n"));
1669 code = gethostname(FS_HostName, 64);
1671 ViceLog(0, ("gethostname() failed\n"));
1673 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
1675 ViceLog(0, ("Getting FileServer address...\n"));
1676 he = gethostbyname(FS_HostName);
1678 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
1682 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
1683 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
1684 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
1685 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
1686 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
1689 /* Install handler to catch the shutdown signal;
1690 * bosserver assumes SIGQUIT shutdown
1692 #if defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
1693 softsig_signal(SIGQUIT, ShutDown_Signal);
1695 signal(SIGQUIT, ShutDown_Signal);
1698 ViceLog(0,("File Server started %s",
1699 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
1700 #if FS_STATS_DETAILED
1701 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
1703 #ifdef AFS_PTHREAD_ENV
1705 sleep(1000); /* long time */
1707 #else /* AFS_PTHREAD_ENV */
1708 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
1709 #endif /* AFS_PTHREAD_ENV */