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 <sys/resource.h>
40 #include <unistd.h> /* sysconf() */
43 #endif /* ITIMER_REAL */
44 #endif /* AFS_NT40_ENV */
49 #ifdef AFS_PTHREAD_ENV
51 #else /* AFS_PTHREAD_ENV */
52 #include <afs/assert.h>
53 #endif /* AFS_PTHREAD_ENV */
56 #include <afs/ptclient.h>
57 #include <afs/afsint.h>
58 #include <afs/vldbint.h>
59 #include <afs/errors.h>
60 #include <afs/ihandle.h>
61 #include <afs/vnode.h>
62 #include <afs/volume.h>
64 #include <afs/cellconfig.h>
66 #include <afs/prs_fs.h>
70 #include <afs/afs_args.h>
71 #include <afs/vlserver.h>
72 #include <afs/afsutil.h>
73 #include <afs/fileutil.h>
75 #include <afs/netutils.h>
79 #if defined(AFS_SGI_ENV)
80 #include "sys/schedctl.h"
83 #include <rx/rx_globals.h>
86 extern int BreakVolumeCallBacks(), InitCallBack();
87 extern int LogLevel, etext;
88 extern afs_int32 BlocksSpare, PctSpare;
91 static void ClearXStatValues(), NewParms(), PrintCounters();
92 static void ResetCheckDescriptors(void), ResetCheckSignal(void);
93 static int CheckSignal();
94 static int FiveMinuteCheckLWP(), HostCheckLWP();
95 extern int GetKeysFromToken();
96 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
97 extern int RXAFS_ExecuteRequest();
98 extern int RXSTATS_ExecuteRequest();
100 int eventlog = 0, rxlog = 0;
102 FILE * console = NULL;
105 #define AFS_QUIETFS_ENV 1
106 #define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
107 * now. We hope this will be replaced by a more
108 * intelligent estimate later. */
111 int SystemId; /* ViceID of "Administrators"*/
112 int SystemAnyUser; /* Viceid of "System:AnyUser" */
113 prlist SystemAnyUserCPS; /* CPS for "system:AnyUser */
114 int AnonymousID = 0; /* ViceId of "Anonymous"*/
115 prlist AnonCPS; /* CPS for "Anonymous"*/
117 struct afsconf_dir *confDir; /* Configuration dir object */
119 int restartMode = RESTART_ORDINARY;
121 int Testing = 0; /* for ListViceInodes */
124 * Home for the performance statistics.
126 struct afs_PerfStats afs_perfstats;
129 extern int Statistics;
136 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
137 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
141 int stackSize = 24000;
142 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
143 int CurrentConnections = 0;
144 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
145 #if defined(AFS_SGI_ENV)
150 int rxpackets = 150; /* 100 */
151 int nSmallVns = 400; /* 200 */
152 int large = 400; /* 200 */
153 int volcache = 400; /* 400 */
154 int numberofcbs = 60000; /* 60000 */
155 int lwps = 9; /* 6 */
156 int buffs = 90; /* 70 */
157 int novbc = 0; /* Enable Volume Break calls */
158 int busy_threshold = 600;
159 int udpBufSize = 0; /* UDP buffer size for receive*/
164 * FileServer's name and IP address, both network byte order and
167 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
169 char FS_HostName[128] = "localhost";
170 afs_uint32 FS_HostAddr_NBO;
171 afs_uint32 FS_HostAddr_HBO;
172 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
173 /* All addresses in FS_HostAddrs are in NBO */
180 * Home for the performance statistics.
184 static CheckDescriptors()
188 register int tsize = getdtablesize();
190 for (i = 0; i<tsize; i++) {
191 if (fstat(i, &status) != -1) {
192 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
193 i, status.st_dev, status.st_ino,
194 status.st_size, status.st_mode);
198 ResetCheckDescriptors();
200 } /*CheckDescriptors*/
203 #ifdef AFS_PTHREAD_ENV
204 void CheckSignal_Signal(x) {CheckSignal(0);}
205 void ShutDown_Signal(x) {ShutDown(0);}
206 void CheckDescriptors_Signal(x) {CheckDescriptors(0);}
207 #else /* AFS_PTHREAD_ENV */
208 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
209 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
210 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
211 #endif /* AFS_PTHREAD_ENV */
213 /* check whether caller is authorized to manage RX statistics */
214 int fs_rxstat_userok(call)
215 struct rx_call *call;
217 return afsconf_SuperUser(confDir, call, (char *)0);
220 static void ResetCheckSignal(void)
223 signal(SIGPOLL, CheckSignal_Signal);
226 signal(SIGUSR2, CheckSignal_Signal);
228 signal(SIGXCPU, CheckSignal_Signal);
233 static void ResetCheckDescriptors(void)
236 signal(SIGTERM, CheckDescriptors_Signal);
241 /* proc called by rxkad module to get a key */
242 static int get_key(arock, akvno, akey)
245 register afs_int32 akvno;
249 static struct afsconf_key tkey;
250 register afs_int32 code;
253 ViceLog(0, ("conf dir not open\n"));
256 code = afsconf_GetKey(confDir, akvno, tkey.key);
259 memcpy(akey, tkey.key, sizeof(tkey.key));
265 int viced_syscall(a3, a4, a5)
272 #ifndef AFS_LINUX20_ENV
273 old = (void (*)())signal(SIGSYS, SIG_IGN);
275 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
276 #ifndef AFS_LINUX20_ENV
284 #if !defined(AFS_NT40_ENV)
285 #include "AFS_component_version_number.c"
286 #endif /* !AFS_NT40_ENV */
297 struct rx_securityClass *sc[4];
298 struct rx_service *tservice;
299 #ifdef AFS_PTHREAD_ENV
300 pthread_t parentPid, serverPid;
301 pthread_attr_t tattr;
303 #else /* AFS_PTHREAD_ENV */
304 PROCESS parentPid, serverPid;
305 #endif /* AFS_PTHREAD_ENV */
307 int minVnodesRequired; /* min size of vnode cache */
309 struct rlimit rlim; /* max number of open file descriptors */
314 struct sigaction nsa;
316 sigemptyset(&nsa.sa_mask);
317 nsa.sa_handler = SIG_DFL;
318 nsa.sa_flags = SA_FULLDUMP;
319 sigaction(SIGABRT, &nsa, NULL);
320 sigaction(SIGSEGV, &nsa, NULL);
323 /* Initialize dirpaths */
324 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
326 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
328 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
332 #ifndef AFS_QUIETFS_ENV
333 console = fopen("/dev/console","w");
336 if(ParseArgs(argc,argv)) {
341 #ifdef AFS_PTHREAD_ENV
342 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
343 #endif /* AFS_PTHREAD_ENV */
345 #ifdef AFS_SGI_VNODE_GLUE
346 if (afs_init_kernel_config(-1) <0) {
347 printf("Can't determine NUMA configuration, not starting fileserver.\n");
351 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
355 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
356 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
359 if (SawSpare && SawPctSpare) {
360 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
364 #ifdef AFS_SGI_XFS_IOPS_ENV
365 ViceLog(0, ("XFS/EFS File server starting\n"));
367 ViceLog(0, ("File server starting\n"));
370 /* install signal handlers for controlling the fileserver process */
371 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
372 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
374 #if defined(AFS_SGI_ENV)
375 /* give this guy a non-degrading priority so help busy servers */
376 schedctl(NDPRI, 0, NDPNORMMAX);
381 nice(-5); /* TODO: */
384 assert(DInit(buffs) == 0);
387 if (afs_winsockInit()<0) {
388 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
389 ViceLog(0, ("File server failed to intialize winsock.\n"));
395 /* if we support more than 16 threads, then we better have the ability
396 ** to keep open a large number of files simultaneously
398 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
399 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
400 #elif defined(AFS_NT40_ENV)
401 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
404 curLimit = 0; /* the number of open file descriptors */
405 code = getrlimit(RLIMIT_NOFILE, &rlim);
407 curLimit = rlim.rlim_cur;
408 rlim.rlim_cur = rlim.rlim_max;
409 code = setrlimit(RLIMIT_NOFILE, &rlim);
411 curLimit = rlim.rlim_max;
414 ViceLog(0, ("Failed to increase open file limit, using default\n"));
416 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
418 curLimit -= 32; /* leave a slack of 32 file descriptors */
419 if ( lwps > curLimit ) {
422 else if ( lwps > 16 )
423 lwps = 16; /* default to a maximum of 16 threads */
424 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
428 #ifndef AFS_PTHREAD_ENV
429 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
430 #endif /* !AFS_PTHREAD_ENV */
432 /* Initialize volume support */
434 V_BreakVolumeCallbacks = BreakVolumeCallBacks;
437 /* initialize libacl routines */
438 acl_Initialize(ACL_VERSION);
440 /* initialize RX support */
442 rxi_syscallp = viced_syscall;
444 rx_extraPackets = rxpackets;
445 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
446 rx_SetBusyThreshold(busy_threshold, VBUSY);
447 rx_SetCallAbortThreshold(10);
448 rx_SetConnAbortThreshold(10);
449 stackSize = lwps * 4000;
450 if (stackSize < 32000)
452 else if (stackSize > 44000)
454 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
455 rx_SetStackSize(1, stackSize);
458 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
459 if (rx_Init((int)htons(7000))<0) {
460 ViceLog(0, ("Cannot initialize RX\n"));
464 /* Don't send and don't allow 3.4 clients to send jumbograms. */
468 rx_SetRxDeadTime(30);
469 sc[0] = rxnull_NewServerSecurityObject();
470 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
471 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, (char *) 0,
472 get_key, (char *) 0);
473 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, (char *) 0,
474 get_key, (char *) 0);
475 tservice = rx_NewService
476 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
477 /* security classes */ sc, /* numb sec classes */ 4,
478 RXAFS_ExecuteRequest);
480 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
483 rx_SetDestroyConnProc(tservice, (char (*)()) h_FreeConnection);
484 rx_SetMinProcs(tservice, 3);
485 rx_SetMaxProcs(tservice, lwps);
487 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
489 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
492 rx_SetMinProcs(tservice, 2);
493 rx_SetMaxProcs(tservice, 4);
496 * Enable RX hot threads, which allows the listener thread to trade
497 * places with an idle thread and moves the context switch from listener
498 * to worker out of the critical path.
500 rx_EnableHotThread();
502 /* Some rx debugging */
503 if (rxlog || eventlog) {
504 debugFile = fopen("rx_dbg", "w");
505 if (rxlog) rx_debugFile = debugFile;
506 if (eventlog) rxevent_debugFile = debugFile;
509 h_InitHostPackage(); /* set up local cellname and realmname */
510 InitCallBack(numberofcbs);
515 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
521 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
525 /* allow super users to manage RX statistics */
526 rx_SetRxStatUserOk(fs_rxstat_userok);
528 rx_StartServer(0); /* now start handling requests */
530 /* we ensure that there is enough space in the vnode buffer to satisfy
531 ** requests from all concurrent threads.
532 ** the maximum number of vnodes used by a single thread at any one time
533 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
534 ** two vSmall for linking files and two vLarge and one vSmall for linking
537 minVnodesRequired = 2 * lwps + 1;
538 if ( minVnodesRequired > nSmallVns ) {
539 nSmallVns = minVnodesRequired;
540 ViceLog(0, ("Overriding -s command line parameter with %d\n",
543 if ( minVnodesRequired > large ) {
544 large = minVnodesRequired;
545 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
548 /* We now do this after getting the listener up and running, so that client
549 connections don't timeout (maybe) if a file server is restarted, since it
550 will be available "real soon now". Worry about whether we can satisfy the
551 calls in the volume package itself.
553 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
554 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
560 * We are done calling fopen/fdopen. It is safe to use a large
561 * of the file descriptor cache.
565 #ifdef AFS_PTHREAD_ENV
566 assert(pthread_attr_init(&tattr) == 0);
567 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
568 /* Block signals in the threads */
570 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
571 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
572 AFS_SIGSET_RESTORE();
573 #else /* AFS_PTHREAD_ENV */
574 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
575 &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
577 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
578 &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
579 #endif /* AFS_PTHREAD_ENV */
581 TM_GetTimeOfDay(&tp, 0);
583 #ifndef AFS_QUIETFS_ENV
584 if (console != NULL) {
585 fprintf(console, "File server has started at %s\r",
586 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
591 * Figure out the FileServer's name and primary address.
593 ViceLog(0, ("Getting FileServer name...\n"));
594 code = gethostname(FS_HostName, 64);
596 ViceLog(0, ("gethostname() failed\n"));
598 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
600 ViceLog(0, ("Getting FileServer address...\n"));
601 he = gethostbyname(FS_HostName);
603 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
607 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
608 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
609 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
610 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
611 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
614 /* Install handler to catch the shutdown signal */
615 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
617 ViceLog(0,("File Server started %s",
618 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
619 #if FS_STATS_DETAILED
620 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
622 #ifdef AFS_PTHREAD_ENV
624 sleep(1000); /* long time */
626 #else /* AFS_PTHREAD_ENV */
627 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
628 #endif /* AFS_PTHREAD_ENV */
632 /* This LWP does things roughly every 5 minutes */
633 static FiveMinuteCheckLWP()
639 ViceLog(1, ("Starting five minute check process\n"));
641 #ifdef AFS_PTHREAD_ENV
643 #else /* AFS_PTHREAD_ENV */
644 IOMGR_Sleep(fiveminutes);
645 #endif /* AFS_PTHREAD_ENV */
647 /* close the log so it can be removed */
648 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
649 ViceLog(2, ("Cleaning up timed out callbacks\n"));
650 if(CleanupTimedOutCallBacks())
651 ViceLog(5,("Timed out callbacks deleted\n"));
652 ViceLog(2, ("Set disk usage statistics\n"));
654 if (FS_registered == 1) Do_VLRegisterRPC();
655 if(printBanner && (++msg&1)) { /* Every 10 minutes */
656 time_t now = FT_ApproxTime();
657 if (console != NULL) {
658 #ifndef AFS_QUIETFS_ENV
659 fprintf(console,"File server is running at %s\r",
660 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
661 #endif /* AFS_QUIETFS_ENV */
662 ViceLog(2, ("File server is running at %s\n",
663 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
667 } /*FiveMinuteCheckLWP*/
670 /* This LWP does host checks every 5 minutes: it should not be used for
671 * other 5 minute activities because it may be delayed by timeouts when
672 * it probes the workstations
674 static HostCheckLWP()
677 ViceLog(1, ("Starting Host check process\n"));
679 #ifdef AFS_PTHREAD_ENV
681 #else /* AFS_PTHREAD_ENV */
682 IOMGR_Sleep(fiveminutes);
683 #endif /* AFS_PTHREAD_ENV */
684 ViceLog(2, ("Checking for dead venii & clients\n"));
690 #define MAXADMINNAME 64
691 char adminName[MAXADMINNAME];
699 if ((stat("/AdminName", &status)) || /* if file does not exist */
700 (status.st_size <= 0) || /* or it is too short */
701 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
702 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
703 strcpy(adminName, "System:Administrators"); /* use the default name */
706 read(fd, adminName, status.st_size); /* use name from the file */
709 close(fd); /* close fd if it was opened */
714 /*------------------------------------------------------------------------
715 * PRIVATE ClearXStatValues
718 * Initialize all of the values collected via the xstat
728 * Must be called during File Server initialization.
732 *------------------------------------------------------------------------*/
734 static void ClearXStatValues()
736 { /*ClearXStatValues*/
738 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
739 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
740 int i; /*Loop counter*/
743 * Zero all xstat-related structures.
745 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
746 #if FS_STATS_DETAILED
747 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
750 * That's not enough. We have to set reasonable minima for
751 * time and xfer values in the detailed stats.
753 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
754 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
755 opTimeP->minTime.tv_sec = 999999;
757 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
758 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
759 opXferP->minTime.tv_sec = 999999;
760 opXferP->minBytes = 999999999;
764 * There's more. We have to set our unique system identifier, as
765 * declared in param.h. If such a thing is not defined, we bitch
766 * and declare ourselves to be an unknown system type.
769 afs_perfstats.sysname_ID = SYS_NAME_ID;
772 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
773 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
775 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
776 #endif /* SYS_NAME_ID */
779 } /*ClearXStatValues*/
782 static void PrintCounters()
785 int dirbuff, dircall, dirio;
787 int workstations, activeworkstations, delworkstations;
791 TM_GetTimeOfDay(&tpl, 0);
793 ViceLog(0, ("Vice was last started at %s\n",
794 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
798 DStat(&dirbuff, &dircall, &dirio);
799 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
800 dirbuff, dircall, dirio));
801 rx_PrintStats(stderr);
803 PrintCallBackStats();
805 processSize = -1; /* TODO: */
807 processSize = (int)((long) sbrk(0) >> 10);
809 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
810 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
813 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
814 workstations, activeworkstations, delworkstations));
824 if (FS_registered > 0) {
826 * We have proper ip addresses; tell the vlserver what we got; the following
827 * routine will do the proper reporting for us
839 void ShutDownAndCore(dopanic)
842 time_t now = time(0);
846 ViceLog(0, ("Shutting down file server at %s",
847 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
849 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
850 #ifndef AFS_QUIETFS_ENV
851 if (console != NULL) {
852 fprintf(console,"File server restart/shutdown received at %s\r",
853 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
859 /* do not allows new reqests to be served from now on, all new requests
860 are returned with an error code of RX_RESTARTING ( transient failure ) */
861 rx_SetRxTranquil(); /* dhruba */
865 rx_PrintStats(debugFile);
868 if (console != NULL) {
871 #ifndef AFS_QUIETFS_ENV
872 fprintf(console, "File server has terminated abnormally at %s\r",
873 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
875 ViceLog(0, ("File server has terminated abnormally at %s\n",
876 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
878 #ifndef AFS_QUIETFS_ENV
879 fprintf(console, "File server has terminated normally at %s\r",
880 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
882 ViceLog(0, ("File server has terminated normally at %s\n",
883 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
891 void ShutDown() /* backward compatibility */
893 ShutDownAndCore(DONTPANIC);
902 /* default supports help flag */
904 strcpy(buffer, "Usage: fileserver ");
905 strcat(buffer, "[-d <debug level>] ");
906 strcat(buffer, "[-p <number of processes>] ");
907 strcat(buffer, "[-spare <number of spare blocks>] ");
908 strcat(buffer, "[-pctspare <percentage spare>] ");
909 strcat(buffer, "[-b <buffers>] ");
910 strcat(buffer, "[-l <large vnodes>] ");
911 strcat(buffer, "[-s <small vnodes>] ");
912 strcat(buffer, "[-vc <volume cachesize>] ");
913 strcat(buffer, "[-w <call back wait interval>] ");
914 strcat(buffer, "[-cb <number of call backs>] ");
915 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
916 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
917 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
918 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
919 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
920 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
921 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
922 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
924 strcat(buffer, "[-m <min percentage spare in partition>] ");
926 #if defined(AFS_SGI_ENV)
927 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
929 strcat(buffer, "[-L (large server conf)] ");
930 strcat(buffer, "[-S (small server conf)] ");
931 strcat(buffer, "[-k <stack size>] ");
932 strcat(buffer, "[-realm <Kerberos realm name>] ");
933 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
934 /* strcat(buffer, "[-enable_peer_stats] "); */
935 /* strcat(buffer, "[-enable_process_stats] "); */
936 strcat(buffer, "[-help]\n");
938 ViceLog(0, ("%s", buffer));
947 static afs_int32 ParseRights(arights)
954 if (!arights || !strcmp(arights, "")) {
955 printf("Missing list of mode bits on -implicit option\n");
958 if (!strcmp(arights, "none"))
960 else if (!strcmp(arights, "read"))
961 mode = PRSFS_READ | PRSFS_LOOKUP;
962 else if (!strcmp(arights, "write"))
963 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
964 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
965 else if (!strcmp(arights, "all"))
966 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
967 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
969 len = strlen(arights);
972 if (tc == 'r') mode |= PRSFS_READ;
973 else if (tc == 'l') mode |= PRSFS_LOOKUP;
974 else if (tc == 'i') mode |= PRSFS_INSERT;
975 else if (tc == 'd') mode |= PRSFS_DELETE;
976 else if (tc == 'w') mode |= PRSFS_WRITE;
977 else if (tc == 'k') mode |= PRSFS_LOCK;
978 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
979 else if (tc == 'A') mode |= PRSFS_USR0;
980 else if (tc == 'B') mode |= PRSFS_USR1;
981 else if (tc == 'C') mode |= PRSFS_USR2;
982 else if (tc == 'D') mode |= PRSFS_USR3;
983 else if (tc == 'E') mode |= PRSFS_USR4;
984 else if (tc == 'F') mode |= PRSFS_USR5;
985 else if (tc == 'G') mode |= PRSFS_USR6;
986 else if (tc == 'H') mode |= PRSFS_USR7;
988 printf("Illegal -implicit rights character '%c'.\n", tc);
997 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
998 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
1001 * AIX: sysconf() limit is real
1002 * HP-UX: sysconf() limit is real
1003 * IRIX: sysconf() limit is apparently NOT real -- too small
1004 * DUX: sysconf() limit is apparently NOT real -- too big
1005 * Linux: sysconf() limit is apparently NOT real -- too big
1006 * Solaris: no sysconf() limit
1009 max_fileserver_thread(void)
1011 #if defined(AFS_PTHREAD_ENV)
1012 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
1015 ans = sysconf(_SC_THREAD_THREADS_MAX);
1016 if (0 < ans && ans < MAX_FILESERVER_THREAD)
1019 #endif /* defined(AFS_PTHREAD_ENV) */
1020 return MAX_FILESERVER_THREAD;
1023 static ParseArgs(argc, argv)
1028 int SawL=0, SawS=0, SawVC=0;
1029 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
1032 int bufSize = 0; /* temp variable to read in udp socket buf size*/
1034 for (i = 1; i < argc; i++) {
1035 if (!strcmp(argv[i], "-d")) {
1036 debuglevel = atoi(argv[++i]);
1037 LogLevel = debuglevel;
1040 if (!strcmp(argv[i], "-banner")) {
1043 if (!strcmp(argv[i], "-implicit")) {
1044 implicitAdminRights = ParseRights(argv[++i]);
1045 if (implicitAdminRights < 0) return implicitAdminRights;
1047 if (!strcmp(argv[i], "-L")) {
1050 if (!strcmp(argv[i], "-S")) {
1054 if (!strcmp(argv[i], "-p")) {
1055 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
1057 lwps = atoi(argv[++i]);
1058 if (lwps > lwps_max)
1064 if (!strcmp(argv[i], "-b")) {
1066 buffs = atoi(argv[++i]);
1069 if (!strcmp(argv[i], "-l")) {
1071 large = atoi(argv[++i]);
1074 if (!strcmp(argv[i], "-vc")) {
1076 volcache = atoi(argv[++i]);
1079 if (!strcmp(argv[i], "-novbc")) {
1083 if (!strcmp(argv[i], "-rxpck")) {
1085 rxpackets = atoi(argv[++i]);
1088 if (!strcmp(argv[i], "-s")) {
1090 nSmallVns = atoi(argv[++i]);
1093 if (!strcmp(argv[i], "-k"))
1094 stack = atoi(argv[++i]);
1095 #if defined(AFS_SGI_ENV)
1097 if (!strcmp(argv[i], "-lock")) {
1102 if (!strcmp(argv[i], "-spare")) {
1103 BlocksSpare = atoi(argv[++i]);
1107 if (!strcmp(argv[i], "-pctspare")) {
1108 PctSpare = atoi(argv[++i]);
1109 BlocksSpare = 0; /* has non-zero default */
1113 if (!strcmp(argv[i], "-w"))
1114 fiveminutes = atoi(argv[++i]);
1116 if (!strcmp(argv[i], "-hr")) {
1117 int hr = atoi(argv[++i]);
1118 if ((hr < 1) || (hr > 36)) {
1119 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
1123 hostaclRefresh = hr*60*60;
1125 if (!strcmp(argv[i], "-rxdbg"))
1128 if (!strcmp(argv[i], "-rxdbge"))
1131 if (!strcmp(argv[i], "-cb")) {
1133 numberofcbs = atoi(argv[++i]);
1134 if ((numberofcbs < 10000) || (numberofcbs > 65535)) {
1135 printf("number of cbs %d invalid; must be between 10000 and 65535\n",
1141 if (!strcmp(argv[i], "-busyat")) {
1143 busy_threshold = atoi(argv[++i]);
1144 if (busy_threshold < 10) {
1145 printf("Busy threshold %d is too low, will compute default.\n",
1150 #ifdef AFS_AIX32_ENV
1152 if (!strcmp(argv[i], "-m")) {
1153 extern int aixlow_water;
1154 aixlow_water = atoi(argv[++i]);
1155 if ((aixlow_water < 0) || (aixlow_water > 30)) {
1156 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
1162 if (!strcmp(argv[i], "-nojumbo")) {
1166 if (!strcmp(argv[i], "-realm")) {
1167 extern char local_realm[AFS_REALM_SZ];
1168 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
1169 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
1172 strncpy (local_realm, argv[i], AFS_REALM_SZ);
1175 if ( !strcmp(argv[i], "-udpsize")) {
1176 if ( (i+1) >= argc ) {
1177 printf("You have to specify -udpsize <integer value>\n");
1180 bufSize = atoi(argv[++i]);
1181 if ( bufSize < rx_GetMinUdpBufSize() )
1182 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
1183 bufSize, rx_GetMinUdpBufSize() );
1185 udpBufSize = bufSize;
1188 if (!strcmp(argv[i], "-enable_peer_stats")) {
1189 rx_enablePeerRPCStats();
1192 if (!strcmp(argv[i], "-enable_process_stats")) {
1193 rx_enableProcessRPCStats();
1195 #ifndef AFS_NT40_ENV
1197 if (strcmp(argv[i], "-syslog")==0) {
1198 /* set syslog logging flag */
1199 serverLogSyslog = 1;
1202 if (strncmp(argv[i], "-syslog=", 8)==0) {
1203 serverLogSyslog = 1;
1204 serverLogSyslogFacility = atoi(argv[i]+8);
1212 printf("Only one of -L, or -S must be specified\n");
1216 if (!Sawrxpck) rxpackets = 100;
1217 if (!Sawsmall) nSmallVns = 200;
1218 if (!Sawlarge) large = 200;
1219 if (!Sawcbs) numberofcbs = 20000;
1220 if (!Sawlwps) lwps = 6;
1221 if (!Sawbufs) buffs = 70;
1222 if (!SawVC) volcache = 200;
1225 if (!Sawrxpck) rxpackets = 200;
1226 if (!Sawsmall) nSmallVns = 600;
1227 if (!Sawlarge) large = 600;
1228 if (!Sawcbs) numberofcbs = 64000;
1229 if (!Sawlwps) lwps = 12;
1230 if (!Sawbufs) buffs = 120;
1231 if (!SawVC) volcache = 600;
1234 busy_threshold = 3*rxpackets/2;
1243 static void NewParms(initializing)
1247 static struct stat sbuf;
1250 char *argv[MAXPARMS];
1253 if (!(stat("/vice/file/parms",&sbuf))) {
1254 parms = (char *)malloc(sbuf.st_size);
1255 if(parms <= (char *)0) return;
1256 fd = open("parms", O_RDONLY, 0666);
1258 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1262 i = read(fd, parms, sbuf.st_size);
1264 if(i != sbuf.st_size) {
1266 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1269 ("Read on parms failed; expected %d bytes but read %d\n",
1275 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1277 for (argc = i = 0; i < sbuf.st_size; i++) {
1278 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1279 if(argv[argc] == 0) argv[argc] = (parms+i);
1282 *(parms + i) = '\0';
1283 if(argv[argc] != 0) {
1284 if(++argc == MAXPARMS) break;
1286 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1290 if(ParseArgs(argc, argv) == 0)
1291 ViceLog(0, ("Change parameters to:"));
1293 ViceLog(0, ("Invalid parameter in:"));
1294 for(i = 0; i < argc; i++) {
1295 ViceLog(0, (" %s", argv[i]));
1302 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1307 /* Miscellaneous routines */
1312 ViceLog (0,("%s\n", msg));
1324 * If this fails, it's because something major is wrong, and is not
1325 * likely to be time dependent.
1327 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1329 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1332 SystemId = SYSADMINID;
1333 SystemAnyUser = ANYUSERID;
1334 SystemAnyUserCPS.prlist_len = 0;
1335 SystemAnyUserCPS.prlist_val = (afs_int32 *)0;
1336 AnonCPS.prlist_len = 0;
1337 AnonCPS.prlist_val = (afs_int32 *)0;
1339 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1342 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1346 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1348 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1351 AnonymousID = ANONYMOUSID;
1354 #ifdef AFS_PTHREAD_ENV
1356 #else /* AFS_PTHREAD_ENV */
1358 #endif /* AFS_PTHREAD_ENV */
1362 struct rx_connection *serverconns[MAXSERVERS];
1363 struct ubik_client *cstruct;
1364 afs_int32 vl_Initialize(confDir)
1366 { afs_int32 code, scIndex = 0, i;
1367 struct afsconf_dir *tdir;
1368 struct rx_securityClass *sc;
1369 struct afsconf_cell info;
1371 tdir = afsconf_Open(confDir);
1373 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1376 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1378 ViceLog(0, ("Could not get security object for localAuth\n"));
1381 code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE, &info);
1382 if (info.numServers > MAXSERVERS) {
1383 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1386 for (i = 0;i<info.numServers;i++)
1387 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1388 USER_SERVICE_ID, sc, scIndex);
1389 code = ubik_ClientInit(serverconns, &cstruct);
1391 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1397 #define SYSIDMAGIC 0x88aabbcc
1398 #define SYSIDVERSION 1
1401 afs_int32 fd, nentries, i;
1402 struct versionStamp vsn;
1406 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1407 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1410 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1411 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1414 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1415 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1418 if (vsn.magic != SYSIDMAGIC) {
1419 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1422 if (vsn.version != SYSIDVERSION) {
1423 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1426 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1427 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1430 afs_ntohuuid(&uuid);
1432 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1433 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1436 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1437 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1440 FS_HostAddr_cnt = nentries;
1441 for (i = 0; i < nentries; i++) {
1442 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1443 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1444 FS_HostAddr_cnt = 0; /* reset it */
1453 afs_int32 fd, nentries, i;
1454 struct versionStamp vsn;
1458 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1460 * File exists; keep the old one around
1462 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1464 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1466 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1469 vsn.magic = SYSIDMAGIC;
1471 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1472 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1476 afs_htonuuid(&uuid);
1477 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1478 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1481 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1482 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1485 for (i = 0; i < FS_HostAddr_cnt; i++) {
1486 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1487 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1497 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1498 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1499 * and so we need to convert each of them into HBO which is what the extra
1500 * array called FS_HostAddrs_HBO is used here.
1502 Do_VLRegisterRPC() {
1505 extern int VL_RegisterAddrs();
1506 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1509 for (i=0; i < FS_HostAddr_cnt ; i++)
1510 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1511 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1512 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1513 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1515 if (code == VL_MULTIPADDR) {
1516 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1517 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1519 } else if (code == RXGEN_OPCODE) {
1520 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1521 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1523 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1527 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1534 AddrsEqual(cnt, addr1, addr2)
1536 afs_int32 *addr1, *addr2;
1540 for (i = 0; i < cnt; i++) {
1541 for (j = 0; j < cnt; j++) {
1542 if (addr1[i] == addr2[j]) break;
1544 if (j == cnt) return 0;
1553 extern int rxi_numNetAddrs;
1554 extern afs_uint32 rxi_NetAddrs[];
1557 * If this fails, it's because something major is wrong, and is not
1558 * likely to be time dependent.
1560 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1562 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1566 /* Read or create the sysid file and register the fileserver's
1567 * IP addresses with the vlserver.
1569 code = ReadSysIdFile();
1571 /* Need to create the file */
1572 ViceLog(0, ("Creating new SysID file\n"));
1573 if (code = afs_uuid_create(&FS_HostUUID)) {
1574 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1578 /* A good sysid file exists; inform the vlserver. If any conflicts,
1579 * we always use the latest interface available as the real truth.
1581 #ifndef AFS_NT40_ENV
1582 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1584 * Find addresses we are supposed to register as per the netrestrict
1585 * and netinfo files (/usr/afs/local/NetInfo and
1586 * /usr/afs/local/NetRestict)
1589 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1590 ADDRSPERSITE, reason,
1591 AFSDIR_SERVER_NETINFO_FILEPATH,
1592 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1594 ViceLog(0,("Can' register any valid addresses:%s\n",reason));
1597 FS_HostAddr_cnt = (afs_uint32) code;
1602 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1606 code = Do_VLRegisterRPC();