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));
603 bcopy(he->h_addr, &FS_HostAddr_NBO, 4);
604 hoststr = afs_inet_ntoa_r(FS_HostAddr_NBO);
605 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
606 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
607 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
611 /* Install handler to catch the shutdown signal */
612 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
614 ViceLog(0,("File Server started %s",
615 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
616 #if FS_STATS_DETAILED
617 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
619 #ifdef AFS_PTHREAD_ENV
621 sleep(1000); /* long time */
623 #else /* AFS_PTHREAD_ENV */
624 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
625 #endif /* AFS_PTHREAD_ENV */
629 /* This LWP does things roughly every 5 minutes */
630 static FiveMinuteCheckLWP()
636 ViceLog(1, ("Starting five minute check process\n"));
638 #ifdef AFS_PTHREAD_ENV
640 #else /* AFS_PTHREAD_ENV */
641 IOMGR_Sleep(fiveminutes);
642 #endif /* AFS_PTHREAD_ENV */
644 /* close the log so it can be removed */
645 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
646 ViceLog(2, ("Cleaning up timed out callbacks\n"));
647 if(CleanupTimedOutCallBacks())
648 ViceLog(5,("Timed out callbacks deleted\n"));
649 ViceLog(2, ("Set disk usage statistics\n"));
651 if (FS_registered == 1) Do_VLRegisterRPC();
652 if(printBanner && (++msg&1)) { /* Every 10 minutes */
653 time_t now = FT_ApproxTime();
654 if (console != NULL) {
655 #ifndef AFS_QUIETFS_ENV
656 fprintf(console,"File server is running at %s\r",
657 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
658 #endif /* AFS_QUIETFS_ENV */
659 ViceLog(2, ("File server is running at %s\n",
660 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
664 } /*FiveMinuteCheckLWP*/
667 /* This LWP does host checks every 5 minutes: it should not be used for
668 * other 5 minute activities because it may be delayed by timeouts when
669 * it probes the workstations
671 static HostCheckLWP()
674 ViceLog(1, ("Starting Host check process\n"));
676 #ifdef AFS_PTHREAD_ENV
678 #else /* AFS_PTHREAD_ENV */
679 IOMGR_Sleep(fiveminutes);
680 #endif /* AFS_PTHREAD_ENV */
681 ViceLog(2, ("Checking for dead venii & clients\n"));
687 #define MAXADMINNAME 64
688 char adminName[MAXADMINNAME];
696 if ((stat("/AdminName", &status)) || /* if file does not exist */
697 (status.st_size <= 0) || /* or it is too short */
698 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
699 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
700 strcpy(adminName, "System:Administrators"); /* use the default name */
703 read(fd, adminName, status.st_size); /* use name from the file */
706 close(fd); /* close fd if it was opened */
711 /*------------------------------------------------------------------------
712 * PRIVATE ClearXStatValues
715 * Initialize all of the values collected via the xstat
725 * Must be called during File Server initialization.
729 *------------------------------------------------------------------------*/
731 static void ClearXStatValues()
733 { /*ClearXStatValues*/
735 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
736 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
737 int i; /*Loop counter*/
740 * Zero all xstat-related structures.
742 bzero((char *)(&afs_perfstats), sizeof(struct afs_PerfStats));
743 #if FS_STATS_DETAILED
744 bzero((char *)(&afs_FullPerfStats), sizeof(struct fs_stats_FullPerfStats));
747 * That's not enough. We have to set reasonable minima for
748 * time and xfer values in the detailed stats.
750 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
751 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
752 opTimeP->minTime.tv_sec = 999999;
754 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
755 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
756 opXferP->minTime.tv_sec = 999999;
757 opXferP->minBytes = 999999999;
761 * There's more. We have to set our unique system identifier, as
762 * declared in param.h. If such a thing is not defined, we bitch
763 * and declare ourselves to be an unknown system type.
766 afs_perfstats.sysname_ID = SYS_NAME_ID;
769 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
770 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
772 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
773 #endif /* SYS_NAME_ID */
776 } /*ClearXStatValues*/
779 static void PrintCounters()
782 int dirbuff, dircall, dirio;
784 int workstations, activeworkstations, delworkstations;
788 TM_GetTimeOfDay(&tpl, 0);
790 ViceLog(0, ("Vice was last started at %s\n",
791 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
795 DStat(&dirbuff, &dircall, &dirio);
796 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
797 dirbuff, dircall, dirio));
798 rx_PrintStats(stderr);
800 PrintCallBackStats();
802 processSize = -1; /* TODO: */
804 processSize = (int)((long) sbrk(0) >> 10);
806 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
807 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
810 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
811 workstations, activeworkstations, delworkstations));
821 if (FS_registered > 0) {
823 * We have proper ip addresses; tell the vlserver what we got; the following
824 * routine will do the proper reporting for us
836 void ShutDownAndCore(dopanic)
839 time_t now = time(0);
843 ViceLog(0, ("Shutting down file server at %s",
844 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
846 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
847 #ifndef AFS_QUIETFS_ENV
848 if (console != NULL) {
849 fprintf(console,"File server restart/shutdown received at %s\r",
850 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
856 /* do not allows new reqests to be served from now on, all new requests
857 are returned with an error code of RX_RESTARTING ( transient failure ) */
858 rx_SetRxTranquil(); /* dhruba */
862 rx_PrintStats(debugFile);
865 if (console != NULL) {
868 #ifndef AFS_QUIETFS_ENV
869 fprintf(console, "File server has terminated abnormally at %s\r",
870 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
872 ViceLog(0, ("File server has terminated abnormally at %s\n",
873 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
875 #ifndef AFS_QUIETFS_ENV
876 fprintf(console, "File server has terminated normally at %s\r",
877 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
879 ViceLog(0, ("File server has terminated normally at %s\n",
880 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
888 void ShutDown() /* backward compatibility */
890 ShutDownAndCore(DONTPANIC);
899 /* default supports help flag */
901 strcpy(buffer, "Usage: fileserver ");
902 strcat(buffer, "[-d <debug level>] ");
903 strcat(buffer, "[-p <number of processes>] ");
904 strcat(buffer, "[-spare <number of spare blocks>] ");
905 strcat(buffer, "[-pctspare <percentage spare>] ");
906 strcat(buffer, "[-b <buffers>] ");
907 strcat(buffer, "[-l <large vnodes>] ");
908 strcat(buffer, "[-s <small vnodes>] ");
909 strcat(buffer, "[-vc <volume cachesize>] ");
910 strcat(buffer, "[-w <call back wait interval>] ");
911 strcat(buffer, "[-cb <number of call backs>] ");
912 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
913 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
914 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
915 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
916 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
917 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
918 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
919 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
921 strcat(buffer, "[-m <min percentage spare in partition>] ");
923 #if defined(AFS_SGI_ENV)
924 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
926 strcat(buffer, "[-L (large server conf)] ");
927 strcat(buffer, "[-S (small server conf)] ");
928 strcat(buffer, "[-k <stack size>] ");
929 strcat(buffer, "[-realm <Kerberos realm name>] ");
930 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
931 /* strcat(buffer, "[-enable_peer_stats] "); */
932 /* strcat(buffer, "[-enable_process_stats] "); */
933 strcat(buffer, "[-help]\n");
935 ViceLog(0, ("%s", buffer));
944 static afs_int32 ParseRights(arights)
951 if (!arights || !strcmp(arights, "")) {
952 printf("Missing list of mode bits on -implicit option\n");
955 if (!strcmp(arights, "none"))
957 else if (!strcmp(arights, "read"))
958 mode = PRSFS_READ | PRSFS_LOOKUP;
959 else if (!strcmp(arights, "write"))
960 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
961 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
962 else if (!strcmp(arights, "all"))
963 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
964 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
966 len = strlen(arights);
969 if (tc == 'r') mode |= PRSFS_READ;
970 else if (tc == 'l') mode |= PRSFS_LOOKUP;
971 else if (tc == 'i') mode |= PRSFS_INSERT;
972 else if (tc == 'd') mode |= PRSFS_DELETE;
973 else if (tc == 'w') mode |= PRSFS_WRITE;
974 else if (tc == 'k') mode |= PRSFS_LOCK;
975 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
976 else if (tc == 'A') mode |= PRSFS_USR0;
977 else if (tc == 'B') mode |= PRSFS_USR1;
978 else if (tc == 'C') mode |= PRSFS_USR2;
979 else if (tc == 'D') mode |= PRSFS_USR3;
980 else if (tc == 'E') mode |= PRSFS_USR4;
981 else if (tc == 'F') mode |= PRSFS_USR5;
982 else if (tc == 'G') mode |= PRSFS_USR6;
983 else if (tc == 'H') mode |= PRSFS_USR7;
985 printf("Illegal -implicit rights character '%c'.\n", tc);
994 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
995 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
998 * AIX: sysconf() limit is real
999 * HP-UX: sysconf() limit is real
1000 * IRIX: sysconf() limit is apparently NOT real -- too small
1001 * DUX: sysconf() limit is apparently NOT real -- too big
1002 * Linux: sysconf() limit is apparently NOT real -- too big
1003 * Solaris: no sysconf() limit
1006 max_fileserver_thread(void)
1008 #if defined(AFS_PTHREAD_ENV)
1009 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
1012 ans = sysconf(_SC_THREAD_THREADS_MAX);
1013 if (0 < ans && ans < MAX_FILESERVER_THREAD)
1016 #endif /* defined(AFS_PTHREAD_ENV) */
1017 return MAX_FILESERVER_THREAD;
1020 static ParseArgs(argc, argv)
1025 int SawL=0, SawS=0, SawVC=0;
1026 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
1029 int bufSize = 0; /* temp variable to read in udp socket buf size*/
1031 for (i = 1; i < argc; i++) {
1032 if (!strcmp(argv[i], "-d")) {
1033 debuglevel = atoi(argv[++i]);
1034 LogLevel = debuglevel;
1037 if (!strcmp(argv[i], "-banner")) {
1040 if (!strcmp(argv[i], "-implicit")) {
1041 implicitAdminRights = ParseRights(argv[++i]);
1042 if (implicitAdminRights < 0) return implicitAdminRights;
1044 if (!strcmp(argv[i], "-L")) {
1047 if (!strcmp(argv[i], "-S")) {
1051 if (!strcmp(argv[i], "-p")) {
1052 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
1054 lwps = atoi(argv[++i]);
1055 if (lwps > lwps_max)
1061 if (!strcmp(argv[i], "-b")) {
1063 buffs = atoi(argv[++i]);
1066 if (!strcmp(argv[i], "-l")) {
1068 large = atoi(argv[++i]);
1071 if (!strcmp(argv[i], "-vc")) {
1073 volcache = atoi(argv[++i]);
1076 if (!strcmp(argv[i], "-novbc")) {
1080 if (!strcmp(argv[i], "-rxpck")) {
1082 rxpackets = atoi(argv[++i]);
1085 if (!strcmp(argv[i], "-s")) {
1087 nSmallVns = atoi(argv[++i]);
1090 if (!strcmp(argv[i], "-k"))
1091 stack = atoi(argv[++i]);
1092 #if defined(AFS_SGI_ENV)
1094 if (!strcmp(argv[i], "-lock")) {
1099 if (!strcmp(argv[i], "-spare")) {
1100 BlocksSpare = atoi(argv[++i]);
1104 if (!strcmp(argv[i], "-pctspare")) {
1105 PctSpare = atoi(argv[++i]);
1106 BlocksSpare = 0; /* has non-zero default */
1110 if (!strcmp(argv[i], "-w"))
1111 fiveminutes = atoi(argv[++i]);
1113 if (!strcmp(argv[i], "-hr")) {
1114 int hr = atoi(argv[++i]);
1115 if ((hr < 1) || (hr > 36)) {
1116 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
1120 hostaclRefresh = hr*60*60;
1122 if (!strcmp(argv[i], "-rxdbg"))
1125 if (!strcmp(argv[i], "-rxdbge"))
1128 if (!strcmp(argv[i], "-cb")) {
1130 numberofcbs = atoi(argv[++i]);
1131 if ((numberofcbs < 10000) || (numberofcbs > 65535)) {
1132 printf("number of cbs %d invalid; must be between 10000 and 65535\n",
1138 if (!strcmp(argv[i], "-busyat")) {
1140 busy_threshold = atoi(argv[++i]);
1141 if (busy_threshold < 10) {
1142 printf("Busy threshold %d is too low, will compute default.\n",
1147 #ifdef AFS_AIX32_ENV
1149 if (!strcmp(argv[i], "-m")) {
1150 extern int aixlow_water;
1151 aixlow_water = atoi(argv[++i]);
1152 if ((aixlow_water < 0) || (aixlow_water > 30)) {
1153 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
1159 if (!strcmp(argv[i], "-nojumbo")) {
1163 if (!strcmp(argv[i], "-realm")) {
1164 extern char local_realm[AFS_REALM_SZ];
1165 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
1166 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
1169 strncpy (local_realm, argv[i], AFS_REALM_SZ);
1172 if ( !strcmp(argv[i], "-udpsize")) {
1173 if ( (i+1) >= argc ) {
1174 printf("You have to specify -udpsize <integer value>\n");
1177 bufSize = atoi(argv[++i]);
1178 if ( bufSize < rx_GetMinUdpBufSize() )
1179 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
1180 bufSize, rx_GetMinUdpBufSize() );
1182 udpBufSize = bufSize;
1185 if (!strcmp(argv[i], "-enable_peer_stats")) {
1186 rx_enablePeerRPCStats();
1189 if (!strcmp(argv[i], "-enable_process_stats")) {
1190 rx_enableProcessRPCStats();
1192 #ifndef AFS_NT40_ENV
1194 if (strcmp(argv[i], "-syslog")==0) {
1195 /* set syslog logging flag */
1196 serverLogSyslog = 1;
1199 if (strncmp(argv[i], "-syslog=", 8)==0) {
1200 serverLogSyslog = 1;
1201 serverLogSyslogFacility = atoi(argv[i]+8);
1209 printf("Only one of -L, or -S must be specified\n");
1213 if (!Sawrxpck) rxpackets = 100;
1214 if (!Sawsmall) nSmallVns = 200;
1215 if (!Sawlarge) large = 200;
1216 if (!Sawcbs) numberofcbs = 20000;
1217 if (!Sawlwps) lwps = 6;
1218 if (!Sawbufs) buffs = 70;
1219 if (!SawVC) volcache = 200;
1222 if (!Sawrxpck) rxpackets = 200;
1223 if (!Sawsmall) nSmallVns = 600;
1224 if (!Sawlarge) large = 600;
1225 if (!Sawcbs) numberofcbs = 64000;
1226 if (!Sawlwps) lwps = 12;
1227 if (!Sawbufs) buffs = 120;
1228 if (!SawVC) volcache = 600;
1231 busy_threshold = 3*rxpackets/2;
1240 static void NewParms(initializing)
1244 static struct stat sbuf;
1247 char *argv[MAXPARMS];
1250 if (!(stat("/vice/file/parms",&sbuf))) {
1251 parms = (char *)malloc(sbuf.st_size);
1252 if(parms <= (char *)0) return;
1253 fd = open("parms", O_RDONLY, 0666);
1255 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1259 i = read(fd, parms, sbuf.st_size);
1261 if(i != sbuf.st_size) {
1263 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1266 ("Read on parms failed; expected %d bytes but read %d\n",
1272 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1274 for (argc = i = 0; i < sbuf.st_size; i++) {
1275 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1276 if(argv[argc] == 0) argv[argc] = (parms+i);
1279 *(parms + i) = '\0';
1280 if(argv[argc] != 0) {
1281 if(++argc == MAXPARMS) break;
1283 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1287 if(ParseArgs(argc, argv) == 0)
1288 ViceLog(0, ("Change parameters to:"));
1290 ViceLog(0, ("Invalid parameter in:"));
1291 for(i = 0; i < argc; i++) {
1292 ViceLog(0, (" %s", argv[i]));
1299 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1304 /* Miscellaneous routines */
1309 ViceLog (0,("%s\n", msg));
1321 * If this fails, it's because something major is wrong, and is not
1322 * likely to be time dependent.
1324 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1326 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1329 SystemId = SYSADMINID;
1330 SystemAnyUser = ANYUSERID;
1331 SystemAnyUserCPS.prlist_len = 0;
1332 SystemAnyUserCPS.prlist_val = (afs_int32 *)0;
1333 AnonCPS.prlist_len = 0;
1334 AnonCPS.prlist_val = (afs_int32 *)0;
1336 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1339 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1343 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1345 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1348 AnonymousID = ANONYMOUSID;
1351 #ifdef AFS_PTHREAD_ENV
1353 #else /* AFS_PTHREAD_ENV */
1355 #endif /* AFS_PTHREAD_ENV */
1359 struct rx_connection *serverconns[MAXSERVERS];
1360 struct ubik_client *cstruct;
1361 afs_int32 vl_Initialize(confDir)
1363 { afs_int32 code, scIndex = 0, i;
1364 struct afsconf_dir *tdir;
1365 struct rx_securityClass *sc;
1366 struct afsconf_cell info;
1368 tdir = afsconf_Open(confDir);
1370 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1373 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1375 ViceLog(0, ("Could not get security object for localAuth\n"));
1378 code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE, &info);
1379 if (info.numServers > MAXSERVERS) {
1380 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1383 for (i = 0;i<info.numServers;i++)
1384 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1385 USER_SERVICE_ID, sc, scIndex);
1386 code = ubik_ClientInit(serverconns, &cstruct);
1388 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1394 #define SYSIDMAGIC 0x88aabbcc
1395 #define SYSIDVERSION 1
1398 afs_int32 fd, nentries, i;
1399 struct versionStamp vsn;
1403 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1404 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1407 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1408 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1411 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1412 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1415 if (vsn.magic != SYSIDMAGIC) {
1416 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1419 if (vsn.version != SYSIDVERSION) {
1420 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1423 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1424 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1427 afs_ntohuuid(&uuid);
1429 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1430 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1433 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1434 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1437 FS_HostAddr_cnt = nentries;
1438 for (i = 0; i < nentries; i++) {
1439 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1440 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1441 FS_HostAddr_cnt = 0; /* reset it */
1450 afs_int32 fd, nentries, i;
1451 struct versionStamp vsn;
1455 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1457 * File exists; keep the old one around
1459 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1461 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1463 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1466 vsn.magic = SYSIDMAGIC;
1468 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1469 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1473 afs_htonuuid(&uuid);
1474 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1475 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1478 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1479 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1482 for (i = 0; i < FS_HostAddr_cnt; i++) {
1483 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1484 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1494 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1495 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1496 * and so we need to convert each of them into HBO which is what the extra
1497 * array called FS_HostAddrs_HBO is used here.
1499 Do_VLRegisterRPC() {
1502 extern int VL_RegisterAddrs();
1503 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1506 for (i=0; i < FS_HostAddr_cnt ; i++)
1507 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1508 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1509 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1510 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1512 if (code == VL_MULTIPADDR) {
1513 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1514 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1516 } else if (code == RXGEN_OPCODE) {
1517 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1518 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1520 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1524 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1531 AddrsEqual(cnt, addr1, addr2)
1533 afs_int32 *addr1, *addr2;
1537 for (i = 0; i < cnt; i++) {
1538 for (j = 0; j < cnt; j++) {
1539 if (addr1[i] == addr2[j]) break;
1541 if (j == cnt) return 0;
1550 extern int rxi_numNetAddrs;
1551 extern afs_uint32 rxi_NetAddrs[];
1554 * If this fails, it's because something major is wrong, and is not
1555 * likely to be time dependent.
1557 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1559 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1563 /* Read or create the sysid file and register the fileserver's
1564 * IP addresses with the vlserver.
1566 code = ReadSysIdFile();
1568 /* Need to create the file */
1569 ViceLog(0, ("Creating new SysID file\n"));
1570 if (code = afs_uuid_create(&FS_HostUUID)) {
1571 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1575 /* A good sysid file exists; inform the vlserver. If any conflicts,
1576 * we always use the latest interface available as the real truth.
1578 #ifndef AFS_NT40_ENV
1579 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1581 * Find addresses we are supposed to register as per the netrestrict
1582 * and netinfo files (/usr/afs/local/NetInfo and
1583 * /usr/afs/local/NetRestict)
1586 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1587 ADDRSPERSITE, reason,
1588 AFSDIR_SERVER_NETINFO_FILEPATH,
1589 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1591 ViceLog(0,("Can' register any valid addresses:%s\n",reason));
1594 FS_HostAddr_cnt = (afs_uint32) code;
1599 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1603 code = Do_VLRegisterRPC();