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 <afs/param.h>
23 #include <sys/types.h>
24 #include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
30 #include <WINNT/afsevent.h>
33 #include <netinet/in.h>
35 #include <sys/resource.h>
36 #include <unistd.h> /* sysconf() */
39 #endif /* ITIMER_REAL */
40 #endif /* AFS_NT40_ENV */
45 #ifdef AFS_PTHREAD_ENV
47 #else /* AFS_PTHREAD_ENV */
48 #include <afs/assert.h>
49 #endif /* AFS_PTHREAD_ENV */
52 #include <afs/ptclient.h>
53 #include <afs/afsint.h>
54 #include <afs/vldbint.h>
55 #include <afs/errors.h>
56 #include <afs/ihandle.h>
57 #include <afs/vnode.h>
58 #include <afs/volume.h>
60 #include <afs/cellconfig.h>
62 #include <afs/prs_fs.h>
66 #include <afs/afs_args.h>
67 #include <afs/vlserver.h>
68 #include <afs/afsutil.h>
69 #include <afs/fileutil.h>
71 #include <afs/netutils.h>
75 #if defined(AFS_SGI_ENV)
76 #include "sys/schedctl.h"
79 #include <rx/rx_globals.h>
82 extern int BreakVolumeCallBacks(), InitCallBack();
83 extern int LogLevel, etext;
84 extern afs_int32 BlocksSpare, PctSpare;
87 static void ClearXStatValues(), NewParms(), PrintCounters();
88 static void ResetCheckDescriptors(void), ResetCheckSignal(void);
89 static int CheckSignal();
90 static int FiveMinuteCheckLWP(), HostCheckLWP();
91 extern int GetKeysFromToken();
92 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
93 extern int RXAFS_ExecuteRequest();
94 extern int RXSTATS_ExecuteRequest();
96 int eventlog = 0, rxlog = 0;
98 FILE * console = NULL;
101 #define AFS_QUIETFS_ENV 1
102 #define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
103 * now. We hope this will be replaced by a more
104 * intelligent estimate later. */
107 int SystemId; /* ViceID of "Administrators"*/
108 int SystemAnyUser; /* Viceid of "System:AnyUser" */
109 prlist SystemAnyUserCPS; /* CPS for "system:AnyUser */
110 int AnonymousID = 0; /* ViceId of "Anonymous"*/
111 prlist AnonCPS; /* CPS for "Anonymous"*/
113 struct afsconf_dir *confDir; /* Configuration dir object */
115 int restartMode = RESTART_ORDINARY;
117 int Testing = 0; /* for ListViceInodes */
120 * Home for the performance statistics.
122 struct afs_PerfStats afs_perfstats;
125 extern int Statistics;
132 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
133 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
137 int stackSize = 24000;
138 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
139 int CurrentConnections = 0;
140 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
141 #if defined(AFS_SGI_ENV)
146 int rxpackets = 150; /* 100 */
147 int nSmallVns = 400; /* 200 */
148 int large = 400; /* 200 */
149 int volcache = 400; /* 400 */
150 int numberofcbs = 60000; /* 60000 */
151 int lwps = 9; /* 6 */
152 int buffs = 90; /* 70 */
153 int novbc = 0; /* Enable Volume Break calls */
154 int busy_threshold = 600;
155 int udpBufSize = 0; /* UDP buffer size for receive*/
160 * FileServer's name and IP address, both network byte order and
163 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
165 char FS_HostName[128] = "localhost";
166 afs_uint32 FS_HostAddr_NBO;
167 afs_uint32 FS_HostAddr_HBO;
168 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
169 /* All addresses in FS_HostAddrs are in NBO */
176 * Home for the performance statistics.
180 static CheckDescriptors()
184 register int tsize = getdtablesize();
186 for (i = 0; i<tsize; i++) {
187 if (fstat(i, &status) != -1) {
188 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
189 i, status.st_dev, status.st_ino,
190 status.st_size, status.st_mode);
194 ResetCheckDescriptors();
196 } /*CheckDescriptors*/
199 #ifdef AFS_PTHREAD_ENV
200 void CheckSignal_Signal(x) {CheckSignal(0);}
201 void ShutDown_Signal(x) {ShutDown(0);}
202 void CheckDescriptors_Signal(x) {CheckDescriptors(0);}
203 #else /* AFS_PTHREAD_ENV */
204 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
205 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
206 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
207 #endif /* AFS_PTHREAD_ENV */
209 /* check whether caller is authorized to manage RX statistics */
210 int fs_rxstat_userok(call)
211 struct rx_call *call;
213 return afsconf_SuperUser(confDir, call, (char *)0);
216 static void ResetCheckSignal(void)
219 signal(SIGPOLL, CheckSignal_Signal);
222 signal(SIGUSR2, CheckSignal_Signal);
224 signal(SIGXCPU, CheckSignal_Signal);
229 static void ResetCheckDescriptors(void)
232 signal(SIGTERM, CheckDescriptors_Signal);
237 /* proc called by rxkad module to get a key */
238 static int get_key(arock, akvno, akey)
241 register afs_int32 akvno;
245 static struct afsconf_key tkey;
246 register afs_int32 code;
249 ViceLog(0, ("conf dir not open\n"));
252 code = afsconf_GetKey(confDir, akvno, tkey.key);
255 bcopy(tkey.key, akey, sizeof(tkey.key));
261 int viced_syscall(a3, a4, a5)
268 #ifndef AFS_LINUX20_ENV
269 old = (void (*)())signal(SIGSYS, SIG_IGN);
271 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
272 #ifndef AFS_LINUX20_ENV
280 #if !defined(AFS_NT40_ENV)
281 #include "AFS_component_version_number.c"
282 #endif /* !AFS_NT40_ENV */
293 struct rx_securityClass *sc[4];
294 struct rx_service *tservice;
295 #ifdef AFS_PTHREAD_ENV
296 pthread_t parentPid, serverPid;
297 pthread_attr_t tattr;
299 #else /* AFS_PTHREAD_ENV */
300 PROCESS parentPid, serverPid;
301 #endif /* AFS_PTHREAD_ENV */
303 int minVnodesRequired; /* min size of vnode cache */
305 struct rlimit rlim; /* max number of open file descriptors */
310 struct sigaction nsa;
312 sigemptyset(&nsa.sa_mask);
313 nsa.sa_handler = SIG_DFL;
314 nsa.sa_flags = SA_FULLDUMP;
315 sigaction(SIGABRT, &nsa, NULL);
316 sigaction(SIGSEGV, &nsa, NULL);
319 /* Initialize dirpaths */
320 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
322 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
324 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
328 #ifndef AFS_QUIETFS_ENV
329 console = fopen("/dev/console","w");
332 if(ParseArgs(argc,argv)) {
337 #ifdef AFS_PTHREAD_ENV
338 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
339 #endif /* AFS_PTHREAD_ENV */
341 #ifdef AFS_SGI_VNODE_GLUE
342 if (afs_init_kernel_config(-1) <0) {
343 printf("Can't determine NUMA configuration, not starting fileserver.\n");
347 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
351 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
352 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
355 if (SawSpare && SawPctSpare) {
356 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
360 #ifdef AFS_SGI_XFS_IOPS_ENV
361 ViceLog(0, ("XFS/EFS File server starting\n"));
363 ViceLog(0, ("File server starting\n"));
366 /* install signal handlers for controlling the fileserver process */
367 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
368 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
370 #if defined(AFS_SGI_ENV)
371 /* give this guy a non-degrading priority so help busy servers */
372 schedctl(NDPRI, 0, NDPNORMMAX);
377 nice(-5); /* TODO: */
380 assert(DInit(buffs) == 0);
383 if (afs_winsockInit()<0) {
384 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
385 ViceLog(0, ("File server failed to intialize winsock.\n"));
391 /* if we support more than 16 threads, then we better have the ability
392 ** to keep open a large number of files simultaneously
394 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
395 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
396 #elif defined(AFS_NT40_ENV)
397 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
400 curLimit = 0; /* the number of open file descriptors */
401 code = getrlimit(RLIMIT_NOFILE, &rlim);
403 curLimit = rlim.rlim_cur;
404 rlim.rlim_cur = rlim.rlim_max;
405 code = setrlimit(RLIMIT_NOFILE, &rlim);
407 curLimit = rlim.rlim_max;
410 ViceLog(0, ("Failed to increase open file limit, using default\n"));
412 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
414 curLimit -= 32; /* leave a slack of 32 file descriptors */
415 if ( lwps > curLimit ) {
418 else if ( lwps > 16 )
419 lwps = 16; /* default to a maximum of 16 threads */
420 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
424 #ifndef AFS_PTHREAD_ENV
425 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
426 #endif /* !AFS_PTHREAD_ENV */
428 /* Initialize volume support */
430 V_BreakVolumeCallbacks = BreakVolumeCallBacks;
433 /* initialize libacl routines */
434 acl_Initialize(ACL_VERSION);
436 /* initialize RX support */
438 rxi_syscallp = viced_syscall;
440 rx_extraPackets = rxpackets;
441 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
442 rx_SetBusyThreshold(busy_threshold, VBUSY);
443 rx_SetCallAbortThreshold(10);
444 rx_SetConnAbortThreshold(10);
445 stackSize = lwps * 4000;
446 if (stackSize < 32000)
448 else if (stackSize > 44000)
450 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
451 rx_SetStackSize(1, stackSize);
454 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
455 if (rx_Init((int)htons(7000))<0) {
456 ViceLog(0, ("Cannot initialize RX\n"));
460 /* Don't send and don't allow 3.4 clients to send jumbograms. */
464 rx_SetRxDeadTime(30);
465 sc[0] = rxnull_NewServerSecurityObject();
466 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
467 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, (char *) 0,
468 get_key, (char *) 0);
469 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, (char *) 0,
470 get_key, (char *) 0);
471 tservice = rx_NewService
472 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
473 /* security classes */ sc, /* numb sec classes */ 4,
474 RXAFS_ExecuteRequest);
476 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
479 rx_SetDestroyConnProc(tservice, (char (*)()) h_FreeConnection);
480 rx_SetMinProcs(tservice, 3);
481 rx_SetMaxProcs(tservice, lwps);
483 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
485 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
488 rx_SetMinProcs(tservice, 2);
489 rx_SetMaxProcs(tservice, 4);
492 * Enable RX hot threads, which allows the listener thread to trade
493 * places with an idle thread and moves the context switch from listener
494 * to worker out of the critical path.
496 rx_EnableHotThread();
498 /* Some rx debugging */
499 if (rxlog || eventlog) {
500 debugFile = fopen("rx_dbg", "w");
501 if (rxlog) rx_debugFile = debugFile;
502 if (eventlog) rxevent_debugFile = debugFile;
505 h_InitHostPackage(); /* set up local cellname and realmname */
506 InitCallBack(numberofcbs);
511 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
517 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
521 /* allow super users to manage RX statistics */
522 rx_SetRxStatUserOk(fs_rxstat_userok);
524 rx_StartServer(0); /* now start handling requests */
526 /* we ensure that there is enough space in the vnode buffer to satisfy
527 ** requests from all concurrent threads.
528 ** the maximum number of vnodes used by a single thread at any one time
529 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
530 ** two vSmall for linking files and two vLarge and one vSmall for linking
533 minVnodesRequired = 2 * lwps + 1;
534 if ( minVnodesRequired > nSmallVns ) {
535 nSmallVns = minVnodesRequired;
536 ViceLog(0, ("Overriding -s command line parameter with %d\n",
539 if ( minVnodesRequired > large ) {
540 large = minVnodesRequired;
541 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
544 /* We now do this after getting the listener up and running, so that client
545 connections don't timeout (maybe) if a file server is restarted, since it
546 will be available "real soon now". Worry about whether we can satisfy the
547 calls in the volume package itself.
549 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
550 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
556 * We are done calling fopen/fdopen. It is safe to use a large
557 * of the file descriptor cache.
561 #ifdef AFS_PTHREAD_ENV
562 assert(pthread_attr_init(&tattr) == 0);
563 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
564 /* Block signals in the threads */
566 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
567 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
568 AFS_SIGSET_RESTORE();
569 #else /* AFS_PTHREAD_ENV */
570 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
571 &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
573 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
574 &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
575 #endif /* AFS_PTHREAD_ENV */
577 TM_GetTimeOfDay(&tp, 0);
579 #ifndef AFS_QUIETFS_ENV
580 if (console != NULL) {
581 fprintf(console, "File server has started at %s\r",
582 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
587 * Figure out the FileServer's name and primary address.
589 ViceLog(0, ("Getting FileServer name...\n"));
590 code = gethostname(FS_HostName, 64);
592 ViceLog(0, ("gethostname() failed\n"));
594 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
596 ViceLog(0, ("Getting FileServer address...\n"));
597 he = gethostbyname(FS_HostName);
599 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
602 bcopy(he->h_addr, &FS_HostAddr_NBO, 4);
603 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
604 ViceLog(0,("FileServer %s has address 0x%x (0x%x in host byte order)\n",
605 FS_HostName, FS_HostAddr_NBO, FS_HostAddr_HBO));
608 /* Install handler to catch the shutdown signal */
609 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
611 ViceLog(0,("File Server started %s",
612 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
613 #if FS_STATS_DETAILED
614 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
616 #ifdef AFS_PTHREAD_ENV
618 sleep(1000); /* long time */
620 #else /* AFS_PTHREAD_ENV */
621 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
622 #endif /* AFS_PTHREAD_ENV */
626 /* This LWP does things roughly every 5 minutes */
627 static FiveMinuteCheckLWP()
633 ViceLog(1, ("Starting five minute check process\n"));
635 #ifdef AFS_PTHREAD_ENV
637 #else /* AFS_PTHREAD_ENV */
638 IOMGR_Sleep(fiveminutes);
639 #endif /* AFS_PTHREAD_ENV */
641 /* close the log so it can be removed */
642 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
643 ViceLog(2, ("Cleaning up timed out callbacks\n"));
644 if(CleanupTimedOutCallBacks())
645 ViceLog(5,("Timed out callbacks deleted\n"));
646 ViceLog(2, ("Set disk usage statistics\n"));
648 if (FS_registered == 1) Do_VLRegisterRPC();
649 #ifndef AFS_QUIETFS_ENV
650 if(printBanner && (++msg&1)) { /* Every 10 minutes */
651 time_t now = FT_ApproxTime();
652 if (console != NULL) {
653 fprintf(console,"File server is running at %s\r",
654 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
657 #endif /* AFS_QUIETFS_ENV */
659 } /*FiveMinuteCheckLWP*/
662 /* This LWP does host checks every 5 minutes: it should not be used for
663 * other 5 minute activities because it may be delayed by timeouts when
664 * it probes the workstations
666 static HostCheckLWP()
669 ViceLog(1, ("Starting Host check process\n"));
671 #ifdef AFS_PTHREAD_ENV
673 #else /* AFS_PTHREAD_ENV */
674 IOMGR_Sleep(fiveminutes);
675 #endif /* AFS_PTHREAD_ENV */
676 ViceLog(2, ("Checking for dead venii & clients\n"));
682 #define MAXADMINNAME 64
683 char adminName[MAXADMINNAME];
691 if ((stat("/AdminName", &status)) || /* if file does not exist */
692 (status.st_size <= 0) || /* or it is too short */
693 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
694 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
695 strcpy(adminName, "System:Administrators"); /* use the default name */
698 read(fd, adminName, status.st_size); /* use name from the file */
701 close(fd); /* close fd if it was opened */
706 /*------------------------------------------------------------------------
707 * PRIVATE ClearXStatValues
710 * Initialize all of the values collected via the xstat
720 * Must be called during File Server initialization.
724 *------------------------------------------------------------------------*/
726 static void ClearXStatValues()
728 { /*ClearXStatValues*/
730 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
731 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
732 int i; /*Loop counter*/
735 * Zero all xstat-related structures.
737 bzero((char *)(&afs_perfstats), sizeof(struct afs_PerfStats));
738 #if FS_STATS_DETAILED
739 bzero((char *)(&afs_FullPerfStats), sizeof(struct fs_stats_FullPerfStats));
742 * That's not enough. We have to set reasonable minima for
743 * time and xfer values in the detailed stats.
745 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
746 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
747 opTimeP->minTime.tv_sec = 999999;
749 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
750 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
751 opXferP->minTime.tv_sec = 999999;
752 opXferP->minBytes = 999999999;
756 * There's more. We have to set our unique system identifier, as
757 * declared in param.h. If such a thing is not defined, we bitch
758 * and declare ourselves to be an unknown system type.
761 afs_perfstats.sysname_ID = SYS_NAME_ID;
764 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
765 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
767 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
768 #endif /* SYS_NAME_ID */
771 } /*ClearXStatValues*/
774 static void PrintCounters()
777 int dirbuff, dircall, dirio;
779 int workstations, activeworkstations, delworkstations;
783 TM_GetTimeOfDay(&tpl, 0);
785 ViceLog(0, ("Vice was last started at %s\n",
786 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
790 DStat(&dirbuff, &dircall, &dirio);
791 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
792 dirbuff, dircall, dirio));
793 rx_PrintStats(stderr);
795 PrintCallBackStats();
797 processSize = -1; /* TODO: */
799 processSize = (int)((long) sbrk(0) >> 10);
801 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
802 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
805 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
806 workstations, activeworkstations, delworkstations));
816 if (FS_registered > 0) {
818 * We have proper ip addresses; tell the vlserver what we got; the following
819 * routine will do the proper reporting for us
831 void ShutDownAndCore(dopanic)
834 time_t now = time(0);
838 ViceLog(0, ("Shutting down file server at %s",
839 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
841 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
842 #ifndef AFS_QUIETFS_ENV
843 if (console != NULL) {
844 fprintf(console,"File server restart/shutdown received at %s\r",
845 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
851 /* do not allows new reqests to be served from now on, all new requests
852 are returned with an error code of RX_RESTARTING ( transient failure ) */
853 rx_SetRxTranquil(); /* dhruba */
857 rx_PrintStats(debugFile);
860 #ifndef AFS_QUIETFS_ENV
861 if (console != NULL) {
864 fprintf(console, "File server has terminated abnormally at %s\r",
865 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
867 fprintf(console, "File server has terminated normally at %s\r",
868 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
876 void ShutDown() /* backward compatibility */
878 ShutDownAndCore(DONTPANIC);
887 /* default supports help flag */
889 strcpy(buffer, "Usage: fileserver ");
890 strcat(buffer, "[-d <debug level>] ");
891 strcat(buffer, "[-p <number of processes>] ");
892 strcat(buffer, "[-spare <number of spare blocks>] ");
893 strcat(buffer, "[-pctspare <percentage spare>] ");
894 strcat(buffer, "[-b <buffers>] ");
895 strcat(buffer, "[-l <large vnodes>] ");
896 strcat(buffer, "[-s <small vnodes>] ");
897 strcat(buffer, "[-vc <volume cachesize>] ");
898 strcat(buffer, "[-w <call back wait interval>] ");
899 strcat(buffer, "[-cb <number of call backs>] ");
900 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
901 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
902 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
903 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
904 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
905 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
906 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
907 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
909 strcat(buffer, "[-m <min percentage spare in partition>] ");
911 #if defined(AFS_SGI_ENV)
912 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
914 strcat(buffer, "[-L (large server conf)] ");
915 strcat(buffer, "[-S (small server conf)] ");
916 strcat(buffer, "[-k <stack size>] ");
917 strcat(buffer, "[-realm <Kerberos realm name>] ");
918 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
919 /* strcat(buffer, "[-enable_peer_stats] "); */
920 /* strcat(buffer, "[-enable_process_stats] "); */
921 strcat(buffer, "[-help]\n");
923 ViceLog(0, ("%s", buffer));
932 static afs_int32 ParseRights(arights)
939 if (!arights || !strcmp(arights, "")) {
940 printf("Missing list of mode bits on -implicit option\n");
943 if (!strcmp(arights, "none"))
945 else if (!strcmp(arights, "read"))
946 mode = PRSFS_READ | PRSFS_LOOKUP;
947 else if (!strcmp(arights, "write"))
948 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
949 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
950 else if (!strcmp(arights, "all"))
951 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
952 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
954 len = strlen(arights);
957 if (tc == 'r') mode |= PRSFS_READ;
958 else if (tc == 'l') mode |= PRSFS_LOOKUP;
959 else if (tc == 'i') mode |= PRSFS_INSERT;
960 else if (tc == 'd') mode |= PRSFS_DELETE;
961 else if (tc == 'w') mode |= PRSFS_WRITE;
962 else if (tc == 'k') mode |= PRSFS_LOCK;
963 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
964 else if (tc == 'A') mode |= PRSFS_USR0;
965 else if (tc == 'B') mode |= PRSFS_USR1;
966 else if (tc == 'C') mode |= PRSFS_USR2;
967 else if (tc == 'D') mode |= PRSFS_USR3;
968 else if (tc == 'E') mode |= PRSFS_USR4;
969 else if (tc == 'F') mode |= PRSFS_USR5;
970 else if (tc == 'G') mode |= PRSFS_USR6;
971 else if (tc == 'H') mode |= PRSFS_USR7;
973 printf("Illegal -implicit rights character '%c'.\n", tc);
982 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
983 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
986 * AIX: sysconf() limit is real
987 * HP-UX: sysconf() limit is real
988 * IRIX: sysconf() limit is apparently NOT real -- too small
989 * DUX: sysconf() limit is apparently NOT real -- too big
990 * Linux: sysconf() limit is apparently NOT real -- too big
991 * Solaris: no sysconf() limit
994 max_fileserver_thread(void)
996 #if defined(AFS_PTHREAD_ENV)
997 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
1000 ans = sysconf(_SC_THREAD_THREADS_MAX);
1001 if (0 < ans && ans < MAX_FILESERVER_THREAD)
1004 #endif /* defined(AFS_PTHREAD_ENV) */
1005 return MAX_FILESERVER_THREAD;
1008 static ParseArgs(argc, argv)
1013 int SawL=0, SawS=0, SawVC=0;
1014 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
1017 int bufSize = 0; /* temp variable to read in udp socket buf size*/
1019 for (i = 1; i < argc; i++) {
1020 if (!strcmp(argv[i], "-d")) {
1021 debuglevel = atoi(argv[++i]);
1022 LogLevel = debuglevel;
1025 if (!strcmp(argv[i], "-banner")) {
1028 if (!strcmp(argv[i], "-implicit")) {
1029 implicitAdminRights = ParseRights(argv[++i]);
1030 if (implicitAdminRights < 0) return implicitAdminRights;
1032 if (!strcmp(argv[i], "-L")) {
1035 if (!strcmp(argv[i], "-S")) {
1039 if (!strcmp(argv[i], "-p")) {
1040 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
1042 lwps = atoi(argv[++i]);
1043 if (lwps > lwps_max)
1049 if (!strcmp(argv[i], "-b")) {
1051 buffs = atoi(argv[++i]);
1054 if (!strcmp(argv[i], "-l")) {
1056 large = atoi(argv[++i]);
1059 if (!strcmp(argv[i], "-vc")) {
1061 volcache = atoi(argv[++i]);
1064 if (!strcmp(argv[i], "-novbc")) {
1068 if (!strcmp(argv[i], "-rxpck")) {
1070 rxpackets = atoi(argv[++i]);
1073 if (!strcmp(argv[i], "-s")) {
1075 nSmallVns = atoi(argv[++i]);
1078 if (!strcmp(argv[i], "-k"))
1079 stack = atoi(argv[++i]);
1080 #if defined(AFS_SGI_ENV)
1082 if (!strcmp(argv[i], "-lock")) {
1087 if (!strcmp(argv[i], "-spare")) {
1088 BlocksSpare = atoi(argv[++i]);
1092 if (!strcmp(argv[i], "-pctspare")) {
1093 PctSpare = atoi(argv[++i]);
1094 BlocksSpare = 0; /* has non-zero default */
1098 if (!strcmp(argv[i], "-w"))
1099 fiveminutes = atoi(argv[++i]);
1101 if (!strcmp(argv[i], "-hr")) {
1102 int hr = atoi(argv[++i]);
1103 if ((hr < 1) || (hr > 36)) {
1104 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
1108 hostaclRefresh = hr*60*60;
1110 if (!strcmp(argv[i], "-rxdbg"))
1113 if (!strcmp(argv[i], "-rxdbge"))
1116 if (!strcmp(argv[i], "-cb")) {
1118 numberofcbs = atoi(argv[++i]);
1119 if ((numberofcbs < 10000) || (numberofcbs > 65535)) {
1120 printf("number of cbs %d invalid; must be between 10000 and 65535\n",
1126 if (!strcmp(argv[i], "-busyat")) {
1128 busy_threshold = atoi(argv[++i]);
1129 if (busy_threshold < 10) {
1130 printf("Busy threshold %d is too low, will compute default.\n",
1135 #ifdef AFS_AIX32_ENV
1137 if (!strcmp(argv[i], "-m")) {
1138 extern int aixlow_water;
1139 aixlow_water = atoi(argv[++i]);
1140 if ((aixlow_water < 0) || (aixlow_water > 30)) {
1141 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
1147 if (!strcmp(argv[i], "-nojumbo")) {
1151 if (!strcmp(argv[i], "-realm")) {
1152 extern char local_realm[AFS_REALM_SZ];
1153 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
1154 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
1157 strncpy (local_realm, argv[i], AFS_REALM_SZ);
1160 if ( !strcmp(argv[i], "-udpsize")) {
1161 if ( (i+1) >= argc ) {
1162 printf("You have to specify -udpsize <integer value>\n");
1165 bufSize = atoi(argv[++i]);
1166 if ( bufSize < rx_GetMinUdpBufSize() )
1167 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
1168 bufSize, rx_GetMinUdpBufSize() );
1170 udpBufSize = bufSize;
1173 if (!strcmp(argv[i], "-enable_peer_stats")) {
1174 rx_enablePeerRPCStats();
1177 if (!strcmp(argv[i], "-enable_process_stats")) {
1178 rx_enableProcessRPCStats();
1180 #ifndef AFS_NT40_ENV
1182 if (strcmp(argv[i], "-syslog")==0) {
1183 /* set syslog logging flag */
1184 serverLogSyslog = 1;
1187 if (strncmp(argv[i], "-syslog=", 8)==0) {
1188 serverLogSyslog = 1;
1189 serverLogSyslogFacility = atoi(argv[i]+8);
1197 printf("Only one of -L, or -S must be specified\n");
1201 if (!Sawrxpck) rxpackets = 100;
1202 if (!Sawsmall) nSmallVns = 200;
1203 if (!Sawlarge) large = 200;
1204 if (!Sawcbs) numberofcbs = 20000;
1205 if (!Sawlwps) lwps = 6;
1206 if (!Sawbufs) buffs = 70;
1207 if (!SawVC) volcache = 200;
1210 if (!Sawrxpck) rxpackets = 200;
1211 if (!Sawsmall) nSmallVns = 600;
1212 if (!Sawlarge) large = 600;
1213 if (!Sawcbs) numberofcbs = 64000;
1214 if (!Sawlwps) lwps = 12;
1215 if (!Sawbufs) buffs = 120;
1216 if (!SawVC) volcache = 600;
1219 busy_threshold = 3*rxpackets/2;
1228 static void NewParms(initializing)
1232 static struct stat sbuf;
1235 char *argv[MAXPARMS];
1238 if (!(stat("/vice/file/parms",&sbuf))) {
1239 parms = (char *)malloc(sbuf.st_size);
1240 if(parms <= (char *)0) return;
1241 fd = open("parms", O_RDONLY, 0666);
1243 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1247 i = read(fd, parms, sbuf.st_size);
1249 if(i != sbuf.st_size) {
1251 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1254 ("Read on parms failed; expected %d bytes but read %d\n",
1260 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1262 for (argc = i = 0; i < sbuf.st_size; i++) {
1263 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1264 if(argv[argc] == 0) argv[argc] = (parms+i);
1267 *(parms + i) = '\0';
1268 if(argv[argc] != 0) {
1269 if(++argc == MAXPARMS) break;
1271 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1275 if(ParseArgs(argc, argv) == 0)
1276 ViceLog(0, ("Change parameters to:"));
1278 ViceLog(0, ("Invalid parameter in:"));
1279 for(i = 0; i < argc; i++) {
1280 ViceLog(0, (" %s", argv[i]));
1287 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1292 /* Miscellaneous routines */
1297 ViceLog (0,("%s\n", msg));
1309 * If this fails, it's because something major is wrong, and is not
1310 * likely to be time dependent.
1312 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1314 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1317 SystemId = SYSADMINID;
1318 SystemAnyUser = ANYUSERID;
1319 SystemAnyUserCPS.prlist_len = 0;
1320 SystemAnyUserCPS.prlist_val = (afs_int32 *)0;
1321 AnonCPS.prlist_len = 0;
1322 AnonCPS.prlist_val = (afs_int32 *)0;
1324 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1327 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1331 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1333 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1336 AnonymousID = ANONYMOUSID;
1339 #ifdef AFS_PTHREAD_ENV
1341 #else /* AFS_PTHREAD_ENV */
1343 #endif /* AFS_PTHREAD_ENV */
1347 struct rx_connection *serverconns[MAXSERVERS];
1348 struct ubik_client *cstruct;
1349 afs_int32 vl_Initialize(confDir)
1351 { afs_int32 code, scIndex = 0, i;
1352 struct afsconf_dir *tdir;
1353 struct rx_securityClass *sc;
1354 struct afsconf_cell info;
1356 tdir = afsconf_Open(confDir);
1358 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1361 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1363 ViceLog(0, ("Could not get security object for localAuth\n"));
1366 code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE, &info);
1367 if (info.numServers > MAXSERVERS) {
1368 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1371 for (i = 0;i<info.numServers;i++)
1372 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1373 USER_SERVICE_ID, sc, scIndex);
1374 code = ubik_ClientInit(serverconns, &cstruct);
1376 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1382 #define SYSIDMAGIC 0x88aabbcc
1383 #define SYSIDVERSION 1
1386 afs_int32 fd, nentries, i;
1387 struct versionStamp vsn;
1391 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1392 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1395 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1396 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1399 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1400 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1403 if (vsn.magic != SYSIDMAGIC) {
1404 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1407 if (vsn.version != SYSIDVERSION) {
1408 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1411 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1412 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1415 afs_ntohuuid(&uuid);
1417 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1418 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1421 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1422 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1425 FS_HostAddr_cnt = nentries;
1426 for (i = 0; i < nentries; i++) {
1427 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1428 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1429 FS_HostAddr_cnt = 0; /* reset it */
1438 afs_int32 fd, nentries, i;
1439 struct versionStamp vsn;
1443 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1445 * File exists; keep the old one around
1447 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1449 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1451 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1454 vsn.magic = SYSIDMAGIC;
1456 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1457 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1461 afs_htonuuid(&uuid);
1462 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1463 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1466 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1467 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1470 for (i = 0; i < FS_HostAddr_cnt; i++) {
1471 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1472 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1482 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1483 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1484 * and so we need to convert each of them into HBO which is what the extra
1485 * array called FS_HostAddrs_HBO is used here.
1487 Do_VLRegisterRPC() {
1490 extern int VL_RegisterAddrs();
1491 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1494 for (i=0; i < FS_HostAddr_cnt ; i++)
1495 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1496 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1497 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1498 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1500 if (code == VL_MULTIPADDR) {
1501 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1502 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1504 } else if (code == RXGEN_OPCODE) {
1505 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1506 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1508 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1512 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1519 AddrsEqual(cnt, addr1, addr2)
1521 afs_int32 *addr1, *addr2;
1525 for (i = 0; i < cnt; i++) {
1526 for (j = 0; j < cnt; j++) {
1527 if (addr1[i] == addr2[j]) break;
1529 if (j == cnt) return 0;
1538 extern int rxi_numNetAddrs;
1539 extern afs_uint32 rxi_NetAddrs[];
1542 * If this fails, it's because something major is wrong, and is not
1543 * likely to be time dependent.
1545 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1547 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1551 /* Read or create the sysid file and register the fileserver's
1552 * IP addresses with the vlserver.
1554 code = ReadSysIdFile();
1556 /* Need to create the file */
1557 ViceLog(0, ("Creating new SysID file\n"));
1558 if (code = afs_uuid_create(&FS_HostUUID)) {
1559 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1563 /* A good sysid file exists; inform the vlserver. If any conflicts,
1564 * we always use the latest interface available as the real truth.
1566 #ifndef AFS_NT40_ENV
1567 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1569 * Find addresses we are supposed to register as per the netrestrict
1570 * and netinfo files (/usr/afs/local/NetInfo and
1571 * /usr/afs/local/NetRestict)
1574 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1575 ADDRSPERSITE, reason,
1576 AFSDIR_SERVER_NETINFO_FILEPATH,
1577 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1579 ViceLog(0,("Can' register any valid addresses:%s\n",reason));
1582 FS_HostAddr_cnt = (afs_uint32) code;
1587 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1591 code = Do_VLRegisterRPC();