2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* viced.c - File Server main loop */
14 /* Function - This routine has the initialization code for */
17 /* ********************************************************************** */
19 #include <afsconfig.h>
20 #include <afs/param.h>
27 #include <sys/types.h>
28 #include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
34 #include <WINNT/afsevent.h>
37 #include <netinet/in.h>
39 #include <unistd.h> /* sysconf() */
51 #endif /* ITIMER_REAL */
52 #include <sys/resource.h>
53 #endif /* AFS_NT40_ENV */
58 #ifdef AFS_PTHREAD_ENV
60 #else /* AFS_PTHREAD_ENV */
61 #include <afs/assert.h>
62 #endif /* AFS_PTHREAD_ENV */
65 #include <afs/ptclient.h>
66 #include <afs/afsint.h>
67 #include <afs/vldbint.h>
68 #include <afs/errors.h>
69 #include <afs/ihandle.h>
70 #include <afs/vnode.h>
71 #include <afs/volume.h>
73 #include <afs/cellconfig.h>
75 #include <afs/prs_fs.h>
79 #include <afs/afs_args.h>
80 #include <afs/vlserver.h>
81 #include <afs/afsutil.h>
82 #include <afs/fileutil.h>
84 #include <afs/netutils.h>
88 #if defined(AFS_SGI_ENV)
89 #include "sys/schedctl.h"
92 #include <rx/rx_globals.h>
95 extern int BreakVolumeCallBacks(), InitCallBack();
96 extern int LogLevel, etext;
97 extern afs_int32 BlocksSpare, PctSpare;
100 static void ClearXStatValues(), NewParms(), PrintCounters();
101 static void ResetCheckDescriptors(void), ResetCheckSignal(void);
102 static int CheckSignal();
103 static int FiveMinuteCheckLWP(), HostCheckLWP();
104 extern int GetKeysFromToken();
105 extern int RXAFS_ExecuteRequest();
106 extern int RXSTATS_ExecuteRequest();
108 int eventlog = 0, rxlog = 0;
110 FILE * console = NULL;
113 #define AFS_QUIETFS_ENV 1
114 #define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
115 * now. We hope this will be replaced by a more
116 * intelligent estimate later. */
119 int SystemId; /* ViceID of "Administrators"*/
120 int SystemAnyUser; /* Viceid of "System:AnyUser" */
121 prlist SystemAnyUserCPS; /* CPS for "system:AnyUser */
122 int AnonymousID = 0; /* ViceId of "Anonymous"*/
123 prlist AnonCPS; /* CPS for "Anonymous"*/
125 struct afsconf_dir *confDir; /* Configuration dir object */
127 int restartMode = RESTART_ORDINARY;
129 int Testing = 0; /* for ListViceInodes */
132 * Home for the performance statistics.
134 struct afs_PerfStats afs_perfstats;
137 extern int Statistics;
144 int rxJumbograms = 1; /* default is to send and receive jumbograms. */
145 afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
147 afs_int32 readonlyServer = 0;
150 int stackSize = 24000;
151 int fiveminutes = 300; /* 5 minutes. Change this for debugging only */
152 int CurrentConnections = 0;
153 int hostaclRefresh = 7200; /* refresh host clients' acls every 2 hrs */
154 #if defined(AFS_SGI_ENV)
159 int rxpackets = 150; /* 100 */
160 int nSmallVns = 400; /* 200 */
161 int large = 400; /* 200 */
162 int volcache = 400; /* 400 */
163 int numberofcbs = 60000; /* 60000 */
164 int lwps = 9; /* 6 */
165 int buffs = 90; /* 70 */
166 int novbc = 0; /* Enable Volume Break calls */
167 int busy_threshold = 600;
168 int udpBufSize = 0; /* UDP buffer size for receive*/
173 * FileServer's name and IP address, both network byte order and
176 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
178 char FS_HostName[128] = "localhost";
179 afs_uint32 FS_HostAddr_NBO;
180 afs_uint32 FS_HostAddr_HBO;
181 afs_uint32 FS_HostAddrs[ADDRSPERSITE], FS_HostAddr_cnt = 0, FS_registered=0;
182 /* All addresses in FS_HostAddrs are in NBO */
189 * Home for the performance statistics.
193 static CheckDescriptors()
197 register int tsize = getdtablesize();
199 for (i = 0; i<tsize; i++) {
200 if (fstat(i, &status) != -1) {
201 printf("%d: dev %x, inode %u, length %u, type/mode %x\n",
202 i, status.st_dev, status.st_ino,
203 status.st_size, status.st_mode);
207 ResetCheckDescriptors();
209 } /*CheckDescriptors*/
212 #ifdef AFS_PTHREAD_ENV
213 void CheckSignal_Signal(x) {CheckSignal(0);}
214 void ShutDown_Signal(x) {ShutDown(0);}
215 void CheckDescriptors_Signal(x) {CheckDescriptors(0);}
216 #else /* AFS_PTHREAD_ENV */
217 void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
218 void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
219 void CheckDescriptors_Signal(x) {IOMGR_SoftSig(CheckDescriptors, 0);}
220 #endif /* AFS_PTHREAD_ENV */
222 /* check whether caller is authorized to manage RX statistics */
223 int fs_rxstat_userok(call)
224 struct rx_call *call;
226 return afsconf_SuperUser(confDir, call, NULL);
229 static void ResetCheckSignal(void)
232 signal(SIGPOLL, CheckSignal_Signal);
235 signal(SIGUSR2, CheckSignal_Signal);
237 signal(SIGXCPU, CheckSignal_Signal);
242 static void ResetCheckDescriptors(void)
245 signal(SIGTERM, CheckDescriptors_Signal);
250 /* proc called by rxkad module to get a key */
251 static int get_key(arock, akvno, akey)
254 register afs_int32 akvno;
258 static struct afsconf_key tkey;
259 register afs_int32 code;
262 ViceLog(0, ("conf dir not open\n"));
265 code = afsconf_GetKey(confDir, akvno, tkey.key);
268 memcpy(akey, tkey.key, sizeof(tkey.key));
274 int viced_syscall(a3, a4, a5)
281 #ifndef AFS_LINUX20_ENV
282 old = (void (*)())signal(SIGSYS, SIG_IGN);
284 rcode = syscall (AFS_SYSCALL, 28 /* AFSCALL_CALL */, a3, a4, a5);
285 #ifndef AFS_LINUX20_ENV
293 #if !defined(AFS_NT40_ENV)
294 #include "AFS_component_version_number.c"
295 #endif /* !AFS_NT40_ENV */
306 struct rx_securityClass *sc[4];
307 struct rx_service *tservice;
308 #ifdef AFS_PTHREAD_ENV
309 pthread_t parentPid, serverPid;
310 pthread_attr_t tattr;
312 #else /* AFS_PTHREAD_ENV */
313 PROCESS parentPid, serverPid;
314 #endif /* AFS_PTHREAD_ENV */
316 int minVnodesRequired; /* min size of vnode cache */
318 struct rlimit rlim; /* max number of open file descriptors */
323 struct sigaction nsa;
325 sigemptyset(&nsa.sa_mask);
326 nsa.sa_handler = SIG_DFL;
327 nsa.sa_flags = SA_FULLDUMP;
328 sigaction(SIGABRT, &nsa, NULL);
329 sigaction(SIGSEGV, &nsa, NULL);
332 /* Initialize dirpaths */
333 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
335 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
337 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
341 #ifndef AFS_QUIETFS_ENV
342 console = fopen("/dev/console","w");
345 if(ParseArgs(argc,argv)) {
350 #ifdef AFS_PTHREAD_ENV
351 assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
352 #endif /* AFS_PTHREAD_ENV */
354 #ifdef AFS_SGI_VNODE_GLUE
355 if (afs_init_kernel_config(-1) <0) {
356 printf("Can't determine NUMA configuration, not starting fileserver.\n");
360 confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
362 fprintf(stderr, "Unable to open config directory %s\n",
363 AFSDIR_SERVER_ETC_DIRPATH);
369 /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
370 OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
373 if (SawSpare && SawPctSpare) {
374 ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
378 #ifdef AFS_SGI_XFS_IOPS_ENV
379 ViceLog(0, ("XFS/EFS File server starting\n"));
381 ViceLog(0, ("File server starting\n"));
384 /* install signal handlers for controlling the fileserver process */
385 ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
386 ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
388 #if defined(AFS_SGI_ENV)
389 /* give this guy a non-degrading priority so help busy servers */
390 schedctl(NDPRI, 0, NDPNORMMAX);
395 nice(-5); /* TODO: */
398 assert(DInit(buffs) == 0);
401 if (afs_winsockInit()<0) {
402 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
403 ViceLog(0, ("File server failed to intialize winsock.\n"));
409 /* if we support more than 16 threads, then we better have the ability
410 ** to keep open a large number of files simultaneously
412 #if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
413 curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
414 #elif defined(AFS_NT40_ENV)
415 curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
418 curLimit = 0; /* the number of open file descriptors */
419 code = getrlimit(RLIMIT_NOFILE, &rlim);
421 curLimit = rlim.rlim_cur;
422 rlim.rlim_cur = rlim.rlim_max;
423 code = setrlimit(RLIMIT_NOFILE, &rlim);
425 curLimit = rlim.rlim_max;
428 ViceLog(0, ("Failed to increase open file limit, using default\n"));
430 #endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
432 curLimit -= 32; /* leave a slack of 32 file descriptors */
433 if ( lwps > curLimit ) {
436 else if ( lwps > 16 )
437 lwps = 16; /* default to a maximum of 16 threads */
438 ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
442 #ifndef AFS_PTHREAD_ENV
443 assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
444 #endif /* !AFS_PTHREAD_ENV */
446 /* Initialize volume support */
448 V_BreakVolumeCallbacks = BreakVolumeCallBacks;
451 /* initialize libacl routines */
452 acl_Initialize(ACL_VERSION);
454 /* initialize RX support */
456 rxi_syscallp = viced_syscall;
458 rx_extraPackets = rxpackets;
459 rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
460 rx_SetBusyThreshold(busy_threshold, VBUSY);
461 rx_SetCallAbortThreshold(10);
462 rx_SetConnAbortThreshold(10);
463 stackSize = lwps * 4000;
464 if (stackSize < 32000)
466 else if (stackSize > 44000)
468 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
469 rx_SetStackSize(1, stackSize);
472 rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
473 if (rx_Init((int)htons(7000))<0) {
474 ViceLog(0, ("Cannot initialize RX\n"));
478 /* Don't send and don't allow 3.4 clients to send jumbograms. */
482 rx_SetRxDeadTime(30);
483 sc[0] = rxnull_NewServerSecurityObject();
484 sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
485 sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
487 sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
489 tservice = rx_NewService
490 (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
491 /* security classes */ sc, /* numb sec classes */ 4,
492 RXAFS_ExecuteRequest);
494 ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
497 rx_SetDestroyConnProc(tservice, h_FreeConnection);
498 rx_SetMinProcs(tservice, 3);
499 rx_SetMaxProcs(tservice, lwps);
500 rx_SetCheckReach(tservice, 1);
502 tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
504 ViceLog(0, ("Failed to initialize rpc stat service.\n"));
507 rx_SetMinProcs(tservice, 2);
508 rx_SetMaxProcs(tservice, 4);
511 * Enable RX hot threads, which allows the listener thread to trade
512 * places with an idle thread and moves the context switch from listener
513 * to worker out of the critical path.
515 rx_EnableHotThread();
517 /* Some rx debugging */
518 if (rxlog || eventlog) {
519 debugFile = fopen("rx_dbg", "w");
520 if (rxlog) rx_debugFile = debugFile;
521 if (eventlog) rxevent_debugFile = debugFile;
524 h_InitHostPackage(); /* set up local cellname and realmname */
525 InitCallBack(numberofcbs);
530 ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
536 ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
540 /* allow super users to manage RX statistics */
541 rx_SetRxStatUserOk(fs_rxstat_userok);
543 rx_StartServer(0); /* now start handling requests */
545 /* we ensure that there is enough space in the vnode buffer to satisfy
546 ** requests from all concurrent threads.
547 ** the maximum number of vnodes used by a single thread at any one time
548 ** is three ( "link" uses three vnodes simultaneously, one vLarge and
549 ** two vSmall for linking files and two vLarge and one vSmall for linking
552 minVnodesRequired = 2 * lwps + 1;
553 if ( minVnodesRequired > nSmallVns ) {
554 nSmallVns = minVnodesRequired;
555 ViceLog(0, ("Overriding -s command line parameter with %d\n",
558 if ( minVnodesRequired > large ) {
559 large = minVnodesRequired;
560 ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
563 /* We now do this after getting the listener up and running, so that client
564 connections don't timeout (maybe) if a file server is restarted, since it
565 will be available "real soon now". Worry about whether we can satisfy the
566 calls in the volume package itself.
568 if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
569 ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
575 * We are done calling fopen/fdopen. It is safe to use a large
576 * of the file descriptor cache.
580 #ifdef AFS_PTHREAD_ENV
581 assert(pthread_attr_init(&tattr) == 0);
582 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
583 /* Block signals in the threads */
585 assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
586 assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
587 AFS_SIGSET_RESTORE();
588 #else /* AFS_PTHREAD_ENV */
589 assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
590 (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
592 assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
593 (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
594 #endif /* AFS_PTHREAD_ENV */
596 TM_GetTimeOfDay(&tp, 0);
598 #ifndef AFS_QUIETFS_ENV
599 if (console != NULL) {
600 fprintf(console, "File server has started at %s\r",
601 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
606 * Figure out the FileServer's name and primary address.
608 ViceLog(0, ("Getting FileServer name...\n"));
609 code = gethostname(FS_HostName, 64);
611 ViceLog(0, ("gethostname() failed\n"));
613 ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
615 ViceLog(0, ("Getting FileServer address...\n"));
616 he = gethostbyname(FS_HostName);
618 ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
622 memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
623 afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
624 FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
625 ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
626 FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
629 /* Install handler to catch the shutdown signal */
630 signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
632 ViceLog(0,("File Server started %s",
633 afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
634 #if FS_STATS_DETAILED
635 afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
637 #ifdef AFS_PTHREAD_ENV
639 sleep(1000); /* long time */
641 #else /* AFS_PTHREAD_ENV */
642 assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
643 #endif /* AFS_PTHREAD_ENV */
647 /* This LWP does things roughly every 5 minutes */
648 static FiveMinuteCheckLWP()
654 ViceLog(1, ("Starting five minute check process\n"));
656 #ifdef AFS_PTHREAD_ENV
658 #else /* AFS_PTHREAD_ENV */
659 IOMGR_Sleep(fiveminutes);
660 #endif /* AFS_PTHREAD_ENV */
662 /* close the log so it can be removed */
663 ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
664 ViceLog(2, ("Cleaning up timed out callbacks\n"));
665 if(CleanupTimedOutCallBacks())
666 ViceLog(5,("Timed out callbacks deleted\n"));
667 ViceLog(2, ("Set disk usage statistics\n"));
669 if (FS_registered == 1) Do_VLRegisterRPC();
670 if(printBanner && (++msg&1)) { /* Every 10 minutes */
671 time_t now = FT_ApproxTime();
672 if (console != NULL) {
673 #ifndef AFS_QUIETFS_ENV
674 fprintf(console,"File server is running at %s\r",
675 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
676 #endif /* AFS_QUIETFS_ENV */
677 ViceLog(2, ("File server is running at %s\n",
678 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
682 } /*FiveMinuteCheckLWP*/
685 /* This LWP does host checks every 5 minutes: it should not be used for
686 * other 5 minute activities because it may be delayed by timeouts when
687 * it probes the workstations
689 static HostCheckLWP()
692 ViceLog(1, ("Starting Host check process\n"));
694 #ifdef AFS_PTHREAD_ENV
696 #else /* AFS_PTHREAD_ENV */
697 IOMGR_Sleep(fiveminutes);
698 #endif /* AFS_PTHREAD_ENV */
699 ViceLog(2, ("Checking for dead venii & clients\n"));
705 #define MAXADMINNAME 64
706 char adminName[MAXADMINNAME];
714 if ((stat("/AdminName", &status)) || /* if file does not exist */
715 (status.st_size <= 0) || /* or it is too short */
716 (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
717 !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
718 strcpy(adminName, "System:Administrators"); /* use the default name */
721 read(fd, adminName, status.st_size); /* use name from the file */
724 close(fd); /* close fd if it was opened */
729 /*------------------------------------------------------------------------
730 * PRIVATE ClearXStatValues
733 * Initialize all of the values collected via the xstat
743 * Must be called during File Server initialization.
747 *------------------------------------------------------------------------*/
749 static void ClearXStatValues()
751 { /*ClearXStatValues*/
753 struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
754 struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
755 int i; /*Loop counter*/
758 * Zero all xstat-related structures.
760 memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
761 #if FS_STATS_DETAILED
762 memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
765 * That's not enough. We have to set reasonable minima for
766 * time and xfer values in the detailed stats.
768 opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
769 for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
770 opTimeP->minTime.tv_sec = 999999;
772 opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
773 for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
774 opXferP->minTime.tv_sec = 999999;
775 opXferP->minBytes = 999999999;
779 * There's more. We have to set our unique system identifier, as
780 * declared in param.h. If such a thing is not defined, we bitch
781 * and declare ourselves to be an unknown system type.
784 afs_perfstats.sysname_ID = SYS_NAME_ID;
787 ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
788 ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
790 afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
791 #endif /* SYS_NAME_ID */
794 } /*ClearXStatValues*/
797 static void PrintCounters()
800 int dirbuff, dircall, dirio;
802 int workstations, activeworkstations, delworkstations;
806 TM_GetTimeOfDay(&tpl, 0);
808 ViceLog(0, ("Vice was last started at %s\n",
809 afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
813 DStat(&dirbuff, &dircall, &dirio);
814 ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
815 dirbuff, dircall, dirio));
816 rx_PrintStats(stderr);
818 PrintCallBackStats();
820 processSize = -1; /* TODO: */
822 processSize = (int)((long) sbrk(0) >> 10);
824 ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
825 h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
828 ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
829 workstations, activeworkstations, delworkstations));
839 if (FS_registered > 0) {
841 * We have proper ip addresses; tell the vlserver what we got; the following
842 * routine will do the proper reporting for us
854 void ShutDownAndCore(dopanic)
857 time_t now = time(0);
861 ViceLog(0, ("Shutting down file server at %s",
862 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
864 ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
865 #ifndef AFS_QUIETFS_ENV
866 if (console != NULL) {
867 fprintf(console,"File server restart/shutdown received at %s\r",
868 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
874 /* do not allows new reqests to be served from now on, all new requests
875 are returned with an error code of RX_RESTARTING ( transient failure ) */
876 rx_SetRxTranquil(); /* dhruba */
880 rx_PrintStats(debugFile);
883 if (console != NULL) {
886 #ifndef AFS_QUIETFS_ENV
887 fprintf(console, "File server has terminated abnormally at %s\r",
888 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
890 ViceLog(0, ("File server has terminated abnormally at %s\n",
891 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
893 #ifndef AFS_QUIETFS_ENV
894 fprintf(console, "File server has terminated normally at %s\r",
895 afs_ctime(&now, tbuffer, sizeof(tbuffer)));
897 ViceLog(0, ("File server has terminated normally at %s\n",
898 afs_ctime(&now, tbuffer, sizeof(tbuffer))));
906 void ShutDown() /* backward compatibility */
908 ShutDownAndCore(DONTPANIC);
917 /* default supports help flag */
919 strcpy(buffer, "Usage: fileserver ");
920 strcat(buffer, "[-d <debug level>] ");
921 strcat(buffer, "[-p <number of processes>] ");
922 strcat(buffer, "[-spare <number of spare blocks>] ");
923 strcat(buffer, "[-pctspare <percentage spare>] ");
924 strcat(buffer, "[-b <buffers>] ");
925 strcat(buffer, "[-l <large vnodes>] ");
926 strcat(buffer, "[-s <small vnodes>] ");
927 strcat(buffer, "[-vc <volume cachesize>] ");
928 strcat(buffer, "[-w <call back wait interval>] ");
929 strcat(buffer, "[-cb <number of call backs>] ");
930 strcat(buffer, "[-banner (print banner every 10 minutes)] ");
931 strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
932 strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
933 strcat(buffer, "[-readonly (read-only file server)] ");
934 strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
935 strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
936 strcat(buffer, "[-rxpck <number of rx extra packets>] ");
937 strcat(buffer, "[-rxdbg (enable rx debugging)] ");
938 strcat(buffer, "[-rxdbge (enable rxevent debugging)] ");
940 strcat(buffer, "[-m <min percentage spare in partition>] ");
942 #if defined(AFS_SGI_ENV)
943 strcat(buffer, "[-lock (keep fileserver from swapping)] ");
945 strcat(buffer, "[-L (large server conf)] ");
946 strcat(buffer, "[-S (small server conf)] ");
947 strcat(buffer, "[-k <stack size>] ");
948 strcat(buffer, "[-realm <Kerberos realm name>] ");
949 strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
950 /* strcat(buffer, "[-enable_peer_stats] "); */
951 /* strcat(buffer, "[-enable_process_stats] "); */
952 strcat(buffer, "[-help]\n");
954 ViceLog(0, ("%s", buffer));
963 static afs_int32 ParseRights(arights)
970 if (!arights || !strcmp(arights, "")) {
971 printf("Missing list of mode bits on -implicit option\n");
974 if (!strcmp(arights, "none"))
976 else if (!strcmp(arights, "read"))
977 mode = PRSFS_READ | PRSFS_LOOKUP;
978 else if (!strcmp(arights, "write"))
979 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
980 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
981 else if (!strcmp(arights, "all"))
982 mode = PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT |
983 PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
985 len = strlen(arights);
988 if (tc == 'r') mode |= PRSFS_READ;
989 else if (tc == 'l') mode |= PRSFS_LOOKUP;
990 else if (tc == 'i') mode |= PRSFS_INSERT;
991 else if (tc == 'd') mode |= PRSFS_DELETE;
992 else if (tc == 'w') mode |= PRSFS_WRITE;
993 else if (tc == 'k') mode |= PRSFS_LOCK;
994 else if (tc == 'a') mode |= PRSFS_ADMINISTER;
995 else if (tc == 'A') mode |= PRSFS_USR0;
996 else if (tc == 'B') mode |= PRSFS_USR1;
997 else if (tc == 'C') mode |= PRSFS_USR2;
998 else if (tc == 'D') mode |= PRSFS_USR3;
999 else if (tc == 'E') mode |= PRSFS_USR4;
1000 else if (tc == 'F') mode |= PRSFS_USR5;
1001 else if (tc == 'G') mode |= PRSFS_USR6;
1002 else if (tc == 'H') mode |= PRSFS_USR7;
1004 printf("Illegal -implicit rights character '%c'.\n", tc);
1013 * Limit MAX_FILESERVER_THREAD by the system limit on the number of
1014 * pthreads (sysconf(_SC_THREAD_THREADS_MAX)), if applicable and
1017 * AIX: sysconf() limit is real
1018 * HP-UX: sysconf() limit is real
1019 * IRIX: sysconf() limit is apparently NOT real -- too small
1020 * DUX: sysconf() limit is apparently NOT real -- too big
1021 * Linux: sysconf() limit is apparently NOT real -- too big
1022 * Solaris: no sysconf() limit
1025 max_fileserver_thread(void)
1027 #if defined(AFS_PTHREAD_ENV)
1028 #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
1031 ans = sysconf(_SC_THREAD_THREADS_MAX);
1032 if (0 < ans && ans < MAX_FILESERVER_THREAD)
1035 #endif /* defined(AFS_PTHREAD_ENV) */
1036 return MAX_FILESERVER_THREAD;
1039 static ParseArgs(argc, argv)
1044 int SawL=0, SawS=0, SawVC=0;
1045 int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
1048 int bufSize = 0; /* temp variable to read in udp socket buf size*/
1050 for (i = 1; i < argc; i++) {
1051 if (!strcmp(argv[i], "-d")) {
1052 debuglevel = atoi(argv[++i]);
1053 LogLevel = debuglevel;
1056 if (!strcmp(argv[i], "-banner")) {
1059 if (!strcmp(argv[i], "-implicit")) {
1060 implicitAdminRights = ParseRights(argv[++i]);
1061 if (implicitAdminRights < 0) return implicitAdminRights;
1063 if (!strcmp(argv[i], "-readonly")) {
1066 if (!strcmp(argv[i], "-L")) {
1069 if (!strcmp(argv[i], "-S")) {
1073 if (!strcmp(argv[i], "-p")) {
1074 int lwps_max = max_fileserver_thread() - FILESERVER_HELPER_THREADS;
1076 lwps = atoi(argv[++i]);
1077 if (lwps > lwps_max)
1083 if (!strcmp(argv[i], "-b")) {
1085 buffs = atoi(argv[++i]);
1088 if (!strcmp(argv[i], "-l")) {
1090 large = atoi(argv[++i]);
1093 if (!strcmp(argv[i], "-vc")) {
1095 volcache = atoi(argv[++i]);
1098 if (!strcmp(argv[i], "-novbc")) {
1102 if (!strcmp(argv[i], "-rxpck")) {
1104 rxpackets = atoi(argv[++i]);
1107 if (!strcmp(argv[i], "-s")) {
1109 nSmallVns = atoi(argv[++i]);
1112 if (!strcmp(argv[i], "-k"))
1113 stack = atoi(argv[++i]);
1114 #if defined(AFS_SGI_ENV)
1116 if (!strcmp(argv[i], "-lock")) {
1121 if (!strcmp(argv[i], "-spare")) {
1122 BlocksSpare = atoi(argv[++i]);
1126 if (!strcmp(argv[i], "-pctspare")) {
1127 PctSpare = atoi(argv[++i]);
1128 BlocksSpare = 0; /* has non-zero default */
1132 if (!strcmp(argv[i], "-w"))
1133 fiveminutes = atoi(argv[++i]);
1135 if (!strcmp(argv[i], "-hr")) {
1136 int hr = atoi(argv[++i]);
1137 if ((hr < 1) || (hr > 36)) {
1138 printf("host acl refresh interval of %d hours is invalid; hours must be between 1 and 36\n\n",
1142 hostaclRefresh = hr*60*60;
1144 if (!strcmp(argv[i], "-rxdbg"))
1147 if (!strcmp(argv[i], "-rxdbge"))
1150 if (!strcmp(argv[i], "-cb")) {
1152 numberofcbs = atoi(argv[++i]);
1153 if ((numberofcbs < 10000) || (numberofcbs > 4294967295)) {
1154 printf("number of cbs %d invalid; must be between 10000 and 4294967295\n",
1160 if (!strcmp(argv[i], "-busyat")) {
1162 busy_threshold = atoi(argv[++i]);
1163 if (busy_threshold < 10) {
1164 printf("Busy threshold %d is too low, will compute default.\n",
1169 #ifdef AFS_AIX32_ENV
1171 if (!strcmp(argv[i], "-m")) {
1172 extern int aixlow_water;
1173 aixlow_water = atoi(argv[++i]);
1174 if ((aixlow_water < 0) || (aixlow_water > 30)) {
1175 printf("space reserved %d% invalid; must be between 0-30%\n", aixlow_water);
1181 if (!strcmp(argv[i], "-nojumbo")) {
1185 if (!strcmp(argv[i], "-realm")) {
1186 extern char local_realm[AFS_REALM_SZ];
1187 if (strlen(argv[++i]) >= AFS_REALM_SZ) {
1188 printf("-realm argument must contain fewer than %d characters.\n",AFS_REALM_SZ);
1191 strncpy (local_realm, argv[i], AFS_REALM_SZ);
1194 if ( !strcmp(argv[i], "-udpsize")) {
1195 if ( (i+1) >= argc ) {
1196 printf("You have to specify -udpsize <integer value>\n");
1199 bufSize = atoi(argv[++i]);
1200 if ( bufSize < rx_GetMinUdpBufSize() )
1201 printf("Warning:udpsize %d is less than minimum %d; ignoring\n",
1202 bufSize, rx_GetMinUdpBufSize() );
1204 udpBufSize = bufSize;
1207 if (!strcmp(argv[i], "-enable_peer_stats")) {
1208 rx_enablePeerRPCStats();
1211 if (!strcmp(argv[i], "-enable_process_stats")) {
1212 rx_enableProcessRPCStats();
1214 #ifndef AFS_NT40_ENV
1216 if (strcmp(argv[i], "-syslog")==0) {
1217 /* set syslog logging flag */
1218 serverLogSyslog = 1;
1221 if (strncmp(argv[i], "-syslog=", 8)==0) {
1222 serverLogSyslog = 1;
1223 serverLogSyslogFacility = atoi(argv[i]+8);
1231 printf("Only one of -L, or -S must be specified\n");
1235 if (!Sawrxpck) rxpackets = 100;
1236 if (!Sawsmall) nSmallVns = 200;
1237 if (!Sawlarge) large = 200;
1238 if (!Sawcbs) numberofcbs = 20000;
1239 if (!Sawlwps) lwps = 6;
1240 if (!Sawbufs) buffs = 70;
1241 if (!SawVC) volcache = 200;
1244 if (!Sawrxpck) rxpackets = 200;
1245 if (!Sawsmall) nSmallVns = 600;
1246 if (!Sawlarge) large = 600;
1247 if (!Sawcbs) numberofcbs = 64000;
1248 if (!Sawlwps) lwps = 12;
1249 if (!Sawbufs) buffs = 120;
1250 if (!SawVC) volcache = 600;
1253 busy_threshold = 3*rxpackets/2;
1262 static void NewParms(initializing)
1266 static struct stat sbuf;
1269 char *argv[MAXPARMS];
1272 if (!(stat("/vice/file/parms",&sbuf))) {
1273 parms = (char *)malloc(sbuf.st_size);
1275 fd = open("parms", O_RDONLY, 0666);
1277 ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
1281 i = read(fd, parms, sbuf.st_size);
1283 if(i != sbuf.st_size) {
1285 ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
1288 ("Read on parms failed; expected %d bytes but read %d\n",
1295 for (i = 0;i < MAXPARMS; argv[i++] = 0 );
1297 for (argc = i = 0; i < sbuf.st_size; i++) {
1298 if ((*(parms + i) != ' ') && (*(parms + i) != '\n')){
1299 if(argv[argc] == 0) argv[argc] = (parms+i);
1302 *(parms + i) = '\0';
1303 if(argv[argc] != 0) {
1304 if(++argc == MAXPARMS) break;
1306 while ((*(parms + i + 1) == ' ') || (*(parms + i + 1) == '\n'))
1310 if(ParseArgs(argc, argv) == 0) {
1311 ViceLog(0, ("Change parameters to:"));
1313 ViceLog(0, ("Invalid parameter in:"));
1315 for(i = 0; i < argc; i++) {
1316 ViceLog(0, (" %s", argv[i]));
1323 ViceLog(0, ("Received request to change parms but no parms file exists\n"));
1328 /* Miscellaneous routines */
1333 ViceLog (0,("%s\n", msg));
1345 * If this fails, it's because something major is wrong, and is not
1346 * likely to be time dependent.
1348 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
1350 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1353 SystemId = SYSADMINID;
1354 SystemAnyUser = ANYUSERID;
1355 SystemAnyUserCPS.prlist_len = 0;
1356 SystemAnyUserCPS.prlist_val = NULL;
1357 AnonCPS.prlist_len = 0;
1358 AnonCPS.prlist_val = NULL;
1360 code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
1363 ("Couldn't get CPS for AnyUser, will try again in 30 seconds; code=%d.\n",
1367 code = pr_GetCPS(ANONYMOUSID,&AnonCPS);
1369 ViceLog(0,("Couldn't get Anonymous CPS, exiting; code=%d.\n", code));
1372 AnonymousID = ANONYMOUSID;
1375 #ifdef AFS_PTHREAD_ENV
1377 #else /* AFS_PTHREAD_ENV */
1379 #endif /* AFS_PTHREAD_ENV */
1383 struct rx_connection *serverconns[MAXSERVERS];
1384 struct ubik_client *cstruct;
1385 afs_int32 vl_Initialize(confDir)
1387 { afs_int32 code, scIndex = 0, i;
1388 struct afsconf_dir *tdir;
1389 struct rx_securityClass *sc;
1390 struct afsconf_cell info;
1392 tdir = afsconf_Open(confDir);
1394 ViceLog(0, ("Could not open configuration directory (%s).\n", confDir));
1397 code = afsconf_ClientAuth(tdir, &sc, &scIndex);
1399 ViceLog(0, ("Could not get security object for localAuth\n"));
1402 code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
1403 if (info.numServers > MAXSERVERS) {
1404 ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
1407 for (i = 0;i<info.numServers;i++)
1408 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
1409 USER_SERVICE_ID, sc, scIndex);
1410 code = ubik_ClientInit(serverconns, &cstruct);
1412 ViceLog(0, ("vl_Initialize: ubik client init failed.\n"));
1418 #define SYSIDMAGIC 0x88aabbcc
1419 #define SYSIDVERSION 1
1422 afs_int32 fd, nentries, i;
1423 struct versionStamp vsn;
1427 if ((stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) || (status.st_size <= 0)) {
1428 ViceLog(0, ("%s: doesn't exist\n", AFSDIR_SERVER_SYSID_FILEPATH));
1431 if (!(fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_RDONLY, 0))) {
1432 ViceLog(0, ("%s: can't open (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1435 if ((i = read(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1436 ViceLog(0, ("%s: Read failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1439 if (vsn.magic != SYSIDMAGIC) {
1440 ViceLog(0, ("%s: wrong magic %x (we support %x)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.magic, SYSIDMAGIC));
1443 if (vsn.version != SYSIDVERSION) {
1444 ViceLog(0, ("%s: wrong version %d (we support %d)\n", AFSDIR_SERVER_SYSID_FILEPATH, vsn.version, SYSIDVERSION));
1447 if ((i = read(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1448 ViceLog(0, ("%s: read of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1451 afs_ntohuuid(&uuid);
1453 if ((i = read(fd, (char *)&nentries, sizeof(afs_int32))) != sizeof(afs_int32)) {
1454 ViceLog(0, ("%s: Read of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1457 if (nentries <= 0 || nentries > ADDRSPERSITE) {
1458 ViceLog(0, ("%s: invalid num of interfaces: %d\n", AFSDIR_SERVER_SYSID_FILEPATH, nentries));
1461 FS_HostAddr_cnt = nentries;
1462 for (i = 0; i < nentries; i++) {
1463 if (read(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1464 ViceLog(0, ("%s: Read of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1465 FS_HostAddr_cnt = 0; /* reset it */
1474 afs_int32 fd, nentries, i;
1475 struct versionStamp vsn;
1479 if (!stat(AFSDIR_SERVER_SYSID_FILEPATH, &status)) {
1481 * File exists; keep the old one around
1483 renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
1485 fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
1487 ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1490 vsn.magic = SYSIDMAGIC;
1492 if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
1493 ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1497 afs_htonuuid(&uuid);
1498 if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
1499 ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1502 if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
1503 ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1506 for (i = 0; i < FS_HostAddr_cnt; i++) {
1507 if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
1508 ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
1518 * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
1519 * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
1520 * and so we need to convert each of them into HBO which is what the extra
1521 * array called FS_HostAddrs_HBO is used here.
1523 Do_VLRegisterRPC() {
1526 extern int VL_RegisterAddrs();
1527 afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
1530 for (i=0; i < FS_HostAddr_cnt ; i++)
1531 FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
1532 addrs.bulkaddrs_len = FS_HostAddr_cnt;
1533 addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
1534 code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
1536 if (code == VL_MULTIPADDR) {
1537 ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
1538 ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
1540 } else if (code == RXGEN_OPCODE) {
1541 ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
1542 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1544 ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
1548 FS_registered = 2; /* So we don't have to retry in the gc daemon */
1556 static int AddrsEqual(cnt, addr1, addr2)
1558 afs_int32 *addr1, *addr2;
1562 for (i = 0; i < cnt; i++) {
1563 for (j = 0; j < cnt; j++) {
1564 if (addr1[i] == addr2[j]) break;
1566 if (j == cnt) return 0;
1576 extern int rxi_numNetAddrs;
1577 extern afs_uint32 rxi_NetAddrs[];
1580 * If this fails, it's because something major is wrong, and is not
1581 * likely to be time dependent.
1583 code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
1585 ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
1589 /* Read or create the sysid file and register the fileserver's
1590 * IP addresses with the vlserver.
1592 code = ReadSysIdFile();
1594 /* Need to create the file */
1595 ViceLog(0, ("Creating new SysID file\n"));
1596 if ((code = afs_uuid_create(&FS_HostUUID))) {
1597 ViceLog(0, ("Failed to create new uuid: %d\n", code));
1601 /* A good sysid file exists; inform the vlserver. If any conflicts,
1602 * we always use the latest interface available as the real truth.
1604 #ifndef AFS_NT40_ENV
1605 if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
1607 * Find addresses we are supposed to register as per the netrestrict
1608 * and netinfo files (/usr/afs/local/NetInfo and
1609 * /usr/afs/local/NetRestict)
1612 afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
1613 ADDRSPERSITE, reason,
1614 AFSDIR_SERVER_NETINFO_FILEPATH,
1615 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1617 ViceLog(0,("Can't register any valid addresses: %s\n",reason));
1620 FS_HostAddr_cnt = (afs_uint32) code;
1625 FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
1629 code = Do_VLRegisterRPC();