/* */
/* ********************************************************************** */
+#include <afsconfig.h>
#include <afs/param.h>
+
+RCSID("$Header$");
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
-#include <sys/resource.h>
#include <unistd.h> /* sysconf() */
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
#ifndef ITIMER_REAL
#include <sys/time.h>
#endif /* ITIMER_REAL */
+#include <sys/resource.h>
#endif /* AFS_NT40_ENV */
#include <afs/stds.h>
#undef SHARED
#endif
#include "viced.h"
#include "host.h"
+#ifdef AFS_PTHREAD_ENV
+#include "softsig.h"
+#endif
#if defined(AFS_SGI_ENV)
#include "sys/schedctl.h"
#include "sys/lock.h"
extern int BreakVolumeCallBacks(), InitCallBack();
+extern int BreakVolumeCallBacks(), InitCallBack(), BreakLaterCallBacks();
+extern int BreakVolumeCallBacksLater();
extern int LogLevel, etext;
extern afs_int32 BlocksSpare, PctSpare;
-void ShutDown();
+void ShutDown(void);
static void ClearXStatValues(), NewParms(), PrintCounters();
static void ResetCheckDescriptors(void), ResetCheckSignal(void);
-static int CheckSignal();
-static int FiveMinuteCheckLWP(), HostCheckLWP();
+static void CheckSignal(void);
extern int GetKeysFromToken();
-extern struct rx_securityClass *rxnull_NewServerSecurityObject();
extern int RXAFS_ExecuteRequest();
extern int RXSTATS_ExecuteRequest();
FILE *debugFile;
FILE * console = NULL;
+#ifdef AFS_PTHREAD_ENV
+pthread_mutex_t fsync_glock_mutex;
+pthread_cond_t fsync_cond;
+#else
+char fsync_wait[1];
+#endif /* AFS_PTHREAD_ENV */
+
#ifdef AFS_NT40_ENV
#define AFS_QUIETFS_ENV 1
#define NT_OPEN_MAX 1024 /* This is an arbitrary no. we came up with for
int rxJumbograms = 1; /* default is to send and receive jumbograms. */
afs_int32 implicitAdminRights = PRSFS_LOOKUP; /* The ADMINISTER right is
already implied */
+afs_int32 readonlyServer = 0;
int stack = 24;
int stackSize = 24000;
int novbc = 0; /* Enable Volume Break calls */
int busy_threshold = 600;
int udpBufSize = 0; /* UDP buffer size for receive*/
+int sendBufSize = 16384; /* send buffer size */
struct timeval tp;
/* All addresses in FS_HostAddrs are in NBO */
afsUUID FS_HostUUID;
-static ParseArgs();
-static FlagMsg();
+static void FlagMsg();
/*
* Home for the performance statistics.
*/
/* DEBUG HACK */
-static CheckDescriptors()
+static void CheckDescriptors()
{
#ifndef AFS_NT40_ENV
struct stat status;
#ifdef AFS_PTHREAD_ENV
-void CheckSignal_Signal(x) {CheckSignal(0);}
-void ShutDown_Signal(x) {ShutDown(0);}
-void CheckDescriptors_Signal(x) {CheckDescriptors(0);}
+void CheckSignal_Signal(x) {CheckSignal();}
+void ShutDown_Signal(x) {ShutDown();}
+void CheckDescriptors_Signal(x) {CheckDescriptors();}
#else /* AFS_PTHREAD_ENV */
void CheckSignal_Signal(x) {IOMGR_SoftSig(CheckSignal, 0);}
void ShutDown_Signal(x) {IOMGR_SoftSig(ShutDown, 0);}
#endif /* AFS_PTHREAD_ENV */
/* check whether caller is authorized to manage RX statistics */
-int fs_rxstat_userok(call)
- struct rx_call *call;
+int fs_rxstat_userok(struct rx_call *call)
{
- return afsconf_SuperUser(confDir, call, (char *)0);
+ return afsconf_SuperUser(confDir, call, NULL);
}
static void ResetCheckSignal(void)
{
-#ifdef AFS_HPUX_ENV
- signal(SIGPOLL, CheckSignal_Signal);
-#else
-#ifdef AFS_NT40_ENV
- signal(SIGUSR2, CheckSignal_Signal);
+ int signo;
+
+#if defined(AFS_HPUX_ENV)
+ signo = SIGPOLL;
+#elsif defined(AFS_NT40_ENV)
+ signo = SIGUSR2;
#else
- signal(SIGXCPU, CheckSignal_Signal);
+ signo = SIGXCPU;
#endif
+
+#if defined(AFS_PTHREAD_ENV)
+ softsig_signal(signo, CheckSignal_Signal);
+#else
+ signal(signo, CheckSignal_Signal);
#endif
}
static void ResetCheckDescriptors(void)
{
#ifndef AFS_NT40_ENV
+#if defined(AFS_PTHREAD_ENV)
+ softsig_signal(SIGTERM, CheckDescriptors_Signal);
+#else
signal(SIGTERM, CheckDescriptors_Signal);
#endif
+#endif
}
/* proc called by rxkad module to get a key */
-static int get_key(arock, akvno, akey)
- char *akey;
- char *arock;
- register afs_int32 akvno;
-
+static int get_key(char *arock, register afs_int32 akvno, char *akey)
{
/* find the key */
static struct afsconf_key tkey;
code = afsconf_GetKey(confDir, akvno, tkey.key);
if (code)
return code;
- bcopy(tkey.key, akey, sizeof(tkey.key));
+ memcpy(akey, tkey.key, sizeof(tkey.key));
return 0;
} /*get_key*/
#ifndef AFS_NT40_ENV
-int viced_syscall(a3, a4, a5)
-afs_uint32 a3, a4;
-void * a5;
+int viced_syscall(afs_uint32 a3, afs_uint32 a4, void * a5)
{
afs_uint32 rcode;
void (*old)();
#include "AFS_component_version_number.c"
#endif /* !AFS_NT40_ENV */
-main(argc, argv)
- int argc;
- char * argv[];
+#define MAXADMINNAME 64
+char adminName[MAXADMINNAME];
+static void
+CheckAdminName()
{
- int i;
- afs_int32 code;
- FILE *file;
+ int fd = 0;
+ struct stat status;
+
+ if ((stat("/AdminName", &status)) || /* if file does not exist */
+ (status.st_size <= 0) || /* or it is too short */
+ (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
+ !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
+ strcpy(adminName, "System:Administrators"); /* use the default name */
+ }
+ else {
+ read(fd, adminName, status.st_size); /* use name from the file */
+ }
+ if (fd)
+ close(fd); /* close fd if it was opened */
+
+} /*CheckAdminName*/
+
+
+/* This LWP does things roughly every 5 minutes */
+static void FiveMinuteCheckLWP()
+{
+ static int msg = 0;
char tbuffer[32];
- struct rx_securityClass *sc[4];
- struct rx_service *tservice;
+
+ ViceLog(1, ("Starting five minute check process\n"));
+ while (1) {
#ifdef AFS_PTHREAD_ENV
- pthread_t parentPid, serverPid;
- pthread_attr_t tattr;
- AFS_SIGSET_DECL;
+ sleep(fiveminutes);
#else /* AFS_PTHREAD_ENV */
- PROCESS parentPid, serverPid;
+ IOMGR_Sleep(fiveminutes);
#endif /* AFS_PTHREAD_ENV */
- struct hostent *he;
- int minVnodesRequired; /* min size of vnode cache */
-#ifndef AFS_NT40_ENV
- struct rlimit rlim; /* max number of open file descriptors */
-#endif
- int curLimit;
-#ifdef AFS_AIX32_ENV
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGABRT, &nsa, NULL);
- sigaction(SIGSEGV, &nsa, NULL);
+ /* close the log so it can be removed */
+ ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
+ ViceLog(2, ("Cleaning up timed out callbacks\n"));
+ if(CleanupTimedOutCallBacks())
+ ViceLog(5,("Timed out callbacks deleted\n"));
+ ViceLog(2, ("Set disk usage statistics\n"));
+ VSetDiskUsage();
+ if (FS_registered == 1) Do_VLRegisterRPC();
+ /* Force wakeup in case we missed something; pthreads does timedwait */
+#ifndef AFS_PTHREAD_ENV
+ LWP_NoYieldSignal(&fsync_wait);
#endif
+ if(printBanner && (++msg&1)) { /* Every 10 minutes */
+ time_t now = FT_ApproxTime();
+ if (console != NULL) {
+#ifndef AFS_QUIETFS_ENV
+ fprintf(console,"File server is running at %s\r",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer)));
+#endif /* AFS_QUIETFS_ENV */
+ ViceLog(2, ("File server is running at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
+ }
+ }
+ }
+} /*FiveMinuteCheckLWP*/
- /* Initialize dirpaths */
- if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
-#ifdef AFS_NT40_ENV
- ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
-#endif
- fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
- exit(2);
+
+/* This LWP does host checks every 5 minutes: it should not be used for
+ * other 5 minute activities because it may be delayed by timeouts when
+ * it probes the workstations
+ */
+static void HostCheckLWP()
+{
+ ViceLog(1, ("Starting Host check process\n"));
+ while(1) {
+#ifdef AFS_PTHREAD_ENV
+ sleep(fiveminutes);
+#else /* AFS_PTHREAD_ENV */
+ IOMGR_Sleep(fiveminutes);
+#endif /* AFS_PTHREAD_ENV */
+ ViceLog(2, ("Checking for dead venii & clients\n"));
+ h_CheckHosts();
}
+} /*HostCheckLWP*/
-#ifndef AFS_QUIETFS_ENV
- console = fopen("/dev/console","w");
+/* This LWP does fsync checks every 5 minutes: it should not be used for
+ * other 5 minute activities because it may be delayed by timeouts when
+ * it probes the workstations
+ */
+static FsyncCheckLWP()
+{
+ afs_int32 code;
+#ifdef AFS_PTHREAD_ENV
+ struct timespec fsync_next;
#endif
+ ViceLog(1, ("Starting fsync check process\n"));
- if(ParseArgs(argc,argv)) {
- FlagMsg();
- exit(-1);
- }
+#ifdef AFS_PTHREAD_ENV
+ assert(pthread_cond_init(&fsync_cond, NULL) == 0);
+ assert(pthread_mutex_init(&fsync_glock_mutex, NULL) == 0);
+#endif
+ FSYNC_LOCK
+ while(1) {
#ifdef AFS_PTHREAD_ENV
- assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
+ /* rounding is fine */
+ fsync_next.tv_nsec = 0;
+ fsync_next.tv_sec = time(0) + fiveminutes;
+
+ code = pthread_cond_timedwait(&fsync_cond, &fsync_glock_mutex,
+ &fsync_next);
+ if (code != 0 && code != ETIMEDOUT)
+ ViceLog(0, ("pthread_cond_timedwait returned %d\n", code));
+#else /* AFS_PTHREAD_ENV */
+ if (( code = LWP_WaitProcess(&fsync_wait)) != LWP_SUCCESS)
+ ViceLog(0, ("LWP_WaitProcess returned %d\n", code));
#endif /* AFS_PTHREAD_ENV */
-
-#ifdef AFS_SGI_VNODE_GLUE
- if (afs_init_kernel_config(-1) <0) {
- printf("Can't determine NUMA configuration, not starting fileserver.\n");
- exit(1);
+ ViceLog(2, ("Checking for fsync events\n"));
+ do {
+ code = BreakLaterCallBacks();
+ } while (code != 0);
}
-#endif
- confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
+}
- NewParms(1);
+/*------------------------------------------------------------------------
+ * PRIVATE ClearXStatValues
+ *
+ * Description:
+ * Initialize all of the values collected via the xstat
+ * interface.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Environment:
+ * Must be called during File Server initialization.
+ *
+ * Side Effects:
+ * As advertised.
+ *------------------------------------------------------------------------*/
- /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
- OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
- SetupLogSignals();
+static void ClearXStatValues()
+{ /*ClearXStatValues*/
- if (SawSpare && SawPctSpare) {
- ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
- exit(-1);
- }
+ struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
+ struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
+ int i; /*Loop counter*/
-#ifdef AFS_SGI_XFS_IOPS_ENV
- ViceLog(0, ("XFS/EFS File server starting\n"));
-#else
- ViceLog(0, ("File server starting\n"));
-#endif
+ /*
+ * Zero all xstat-related structures.
+ */
+ memset((char *)(&afs_perfstats), 0, sizeof(struct afs_PerfStats));
+#if FS_STATS_DETAILED
+ memset((char *)(&afs_FullPerfStats), 0, sizeof(struct fs_stats_FullPerfStats));
- /* install signal handlers for controlling the fileserver process */
- ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
- ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
+ /*
+ * That's not enough. We have to set reasonable minima for
+ * time and xfer values in the detailed stats.
+ */
+ opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
+ for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
+ opTimeP->minTime.tv_sec = 999999;
-#if defined(AFS_SGI_ENV)
- /* give this guy a non-degrading priority so help busy servers */
- schedctl(NDPRI, 0, NDPNORMMAX);
- if (SawLock)
- plock(PROCLOCK);
+ opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
+ for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
+ opXferP->minTime.tv_sec = 999999;
+ opXferP->minBytes = 999999999;
+ }
+
+ /*
+ * There's more. We have to set our unique system identifier, as
+ * declared in param.h. If such a thing is not defined, we bitch
+ * and declare ourselves to be an unknown system type.
+ */
+#ifdef SYS_NAME_ID
+ afs_perfstats.sysname_ID = SYS_NAME_ID;
#else
#ifndef AFS_NT40_ENV
- nice(-5); /* TODO: */
-#endif
+ ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
+ ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
#endif
- assert(DInit(buffs) == 0);
-
-#ifdef AFS_NT40_ENV
- if (afs_winsockInit()<0) {
- ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
- ViceLog(0, ("File server failed to intialize winsock.\n"));
- exit(1);
- }
+ afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
+#endif /* SYS_NAME_ID */
#endif
- CheckAdminName();
- /* if we support more than 16 threads, then we better have the ability
- ** to keep open a large number of files simultaneously
- */
-#if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
- curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
-#elif defined(AFS_NT40_ENV)
- curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
-#else
+} /*ClearXStatValues*/
- curLimit = 0; /* the number of open file descriptors */
- code = getrlimit(RLIMIT_NOFILE, &rlim);
- if (code == 0) {
- curLimit = rlim.rlim_cur;
- rlim.rlim_cur = rlim.rlim_max;
- code = setrlimit(RLIMIT_NOFILE, &rlim);
- if ( code == 0 )
- curLimit = rlim.rlim_max;
- }
- if ( code != 0 )
- ViceLog(0, ("Failed to increase open file limit, using default\n"));
-#endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
+static void PrintCounters()
+{
+ int dirbuff, dircall, dirio;
+ struct timeval tpl;
+ int workstations, activeworkstations, delworkstations;
+ int processSize = 0;
+ char tbuffer[32];
- curLimit -= 32; /* leave a slack of 32 file descriptors */
- if ( lwps > curLimit ) {
- if ( curLimit > 0)
- lwps = curLimit;
- else if ( lwps > 16 )
- lwps = 16; /* default to a maximum of 16 threads */
- ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
- }
-
-
-#ifndef AFS_PTHREAD_ENV
- assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
-#endif /* !AFS_PTHREAD_ENV */
-
- /* Initialize volume support */
- if (!novbc) {
- V_BreakVolumeCallbacks = BreakVolumeCallBacks;
- }
-
- /* initialize libacl routines */
- acl_Initialize(ACL_VERSION);
+ TM_GetTimeOfDay(&tpl, 0);
+ Statistics = 1;
+ ViceLog(0, ("Vice was last started at %s\n",
+ afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
- /* initialize RX support */
-#ifndef AFS_NT40_ENV
- rxi_syscallp = viced_syscall;
-#endif
- rx_extraPackets = rxpackets;
- rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
- rx_SetBusyThreshold(busy_threshold, VBUSY);
- rx_SetCallAbortThreshold(10);
- rx_SetConnAbortThreshold(10);
- stackSize = lwps * 4000;
- if (stackSize < 32000)
- stackSize = 32000;
- else if (stackSize > 44000)
- stackSize = 44000;
-#if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
- rx_SetStackSize(1, stackSize);
+ VPrintCacheStats();
+ VPrintDiskStats();
+ DStat(&dirbuff, &dircall, &dirio);
+ ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
+ dirbuff, dircall, dirio));
+ rx_PrintStats(stderr);
+ h_PrintStats();
+ PrintCallBackStats();
+#ifdef AFS_NT40_ENV
+ processSize = -1; /* TODO: */
+#else
+ processSize = (int)((long) sbrk(0) >> 10);
#endif
- if ( udpBufSize )
- rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
- if (rx_Init((int)htons(7000))<0) {
- ViceLog(0, ("Cannot initialize RX\n"));
- exit(1);
- }
- if (!rxJumbograms) {
- /* Don't send and don't allow 3.4 clients to send jumbograms. */
- rx_SetNoJumbo();
- }
- rx_GetIFInfo();
- rx_SetRxDeadTime(30);
- sc[0] = rxnull_NewServerSecurityObject();
- sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
- sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, (char *) 0,
- get_key, (char *) 0);
- sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, (char *) 0,
- get_key, (char *) 0);
- tservice = rx_NewService
- (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
- /* security classes */ sc, /* numb sec classes */ 4,
- RXAFS_ExecuteRequest);
- if (!tservice) {
- ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
- exit(-1);
- }
- rx_SetDestroyConnProc(tservice, (char (*)()) h_FreeConnection);
- rx_SetMinProcs(tservice, 3);
- rx_SetMaxProcs(tservice, lwps);
-
- tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
- if (!tservice) {
- ViceLog(0, ("Failed to initialize rpc stat service.\n"));
- exit(-1);
- }
- rx_SetMinProcs(tservice, 2);
- rx_SetMaxProcs(tservice, 4);
-
- /*
- * Enable RX hot threads, which allows the listener thread to trade
- * places with an idle thread and moves the context switch from listener
- * to worker out of the critical path.
- */
- rx_EnableHotThread();
-
- /* Some rx debugging */
- if (rxlog || eventlog) {
- debugFile = fopen("rx_dbg", "w");
- if (rxlog) rx_debugFile = debugFile;
- if (eventlog) rxevent_debugFile = debugFile;
- }
-
- h_InitHostPackage(); /* set up local cellname and realmname */
- InitCallBack(numberofcbs);
- ClearXStatValues();
-
- code = InitVL();
- if (code) {
- ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
- exit(1);
- }
-
- code = InitPR();
- if (code) {
- ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
- exit(1);
- }
+ ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
+ h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
+ tpl.tv_sec-15*60);
+ ViceLog(0,
+ ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
+ workstations, activeworkstations, delworkstations));
+ Statistics = 0;
- /* allow super users to manage RX statistics */
- rx_SetRxStatUserOk(fs_rxstat_userok);
+} /*PrintCounters*/
- rx_StartServer(0); /* now start handling requests */
- /* we ensure that there is enough space in the vnode buffer to satisfy
- ** requests from all concurrent threads.
- ** the maximum number of vnodes used by a single thread at any one time
- ** is three ( "link" uses three vnodes simultaneously, one vLarge and
- ** two vSmall for linking files and two vLarge and one vSmall for linking
- ** files ) : dhruba
- */
- minVnodesRequired = 2 * lwps + 1;
- if ( minVnodesRequired > nSmallVns ) {
- nSmallVns = minVnodesRequired;
- ViceLog(0, ("Overriding -s command line parameter with %d\n",
- nSmallVns));
- }
- if ( minVnodesRequired > large ) {
- large = minVnodesRequired;
- ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
- }
- /* We now do this after getting the listener up and running, so that client
- connections don't timeout (maybe) if a file server is restarted, since it
- will be available "real soon now". Worry about whether we can satisfy the
- calls in the volume package itself.
- */
- if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
- ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
- VShutdown();
- exit(1);
+static void CheckSignal()
+{
+ if (FS_registered > 0) {
+ /*
+ * We have proper ip addresses; tell the vlserver what we got; the following
+ * routine will do the proper reporting for us
+ */
+ Do_VLRegisterRPC();
}
+ h_DumpHosts();
+ h_PrintClients();
+ DumpCallBackState();
+ PrintCounters();
+ ResetCheckSignal();
- /*
- * We are done calling fopen/fdopen. It is safe to use a large
- * of the file descriptor cache.
- */
- ih_UseLargeCache();
-
-#ifdef AFS_PTHREAD_ENV
- assert(pthread_attr_init(&tattr) == 0);
- assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
- /* Block signals in the threads */
- AFS_SIGSET_CLEAR();
- assert(pthread_create(&serverPid, &tattr, FiveMinuteCheckLWP, &fiveminutes) == 0);
- assert(pthread_create(&serverPid, &tattr, HostCheckLWP, &fiveminutes) == 0);
- AFS_SIGSET_RESTORE();
-#else /* AFS_PTHREAD_ENV */
- assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
- &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
-
- assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
- &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
-#endif /* AFS_PTHREAD_ENV */
+} /*CheckSignal*/
- TM_GetTimeOfDay(&tp, 0);
+void ShutDownAndCore(int dopanic)
+{
+ time_t now = time(0);
+ char *tstr;
+ char tbuffer[32];
+ ViceLog(0, ("Shutting down file server at %s",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
+ if (dopanic)
+ ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
#ifndef AFS_QUIETFS_ENV
if (console != NULL) {
- fprintf(console, "File server has started at %s\r",
- afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
+ fprintf(console,"File server restart/shutdown received at %s\r",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer)));
}
#endif
+ DFlush();
+ PrintCounters();
- /*
- * Figure out the FileServer's name and primary address.
- */
- ViceLog(0, ("Getting FileServer name...\n"));
- code = gethostname(FS_HostName, 64);
- if (code) {
- ViceLog(0, ("gethostname() failed\n"));
- }
- ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
+ /* do not allows new reqests to be served from now on, all new requests
+ are returned with an error code of RX_RESTARTING ( transient failure ) */
+ rx_SetRxTranquil(); /* dhruba */
+ VShutdown();
- ViceLog(0, ("Getting FileServer address...\n"));
- he = gethostbyname(FS_HostName);
- if (!he) {
- ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
- }
- else {
- bcopy(he->h_addr, &FS_HostAddr_NBO, 4);
- FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
- ViceLog(0,("FileServer %s has address 0x%x (0x%x in host byte order)\n",
- FS_HostName, FS_HostAddr_NBO, FS_HostAddr_HBO));
+ if (debugFile) {
+ rx_PrintStats(debugFile);
+ fflush(debugFile);
}
-
- /* Install handler to catch the shutdown signal */
- signal(SIGQUIT, ShutDown_Signal); /* bosserver assumes SIGQUIT shutdown */
-
- ViceLog(0,("File Server started %s",
- afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
-#if FS_STATS_DETAILED
- afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
+ if (console != NULL) {
+ now = time(0);
+ if (dopanic) {
+#ifndef AFS_QUIETFS_ENV
+ fprintf(console, "File server has terminated abnormally at %s\r",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer)));
#endif
-#ifdef AFS_PTHREAD_ENV
- while(1) {
- sleep(1000); /* long time */
+ ViceLog(0, ("File server has terminated abnormally at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
+ } else {
+#ifndef AFS_QUIETFS_ENV
+ fprintf(console, "File server has terminated normally at %s\r",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer)));
+#endif
+ ViceLog(0, ("File server has terminated normally at %s\n",
+ afs_ctime(&now, tbuffer, sizeof(tbuffer))));
+ }
}
-#else /* AFS_PTHREAD_ENV */
- assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
-#endif /* AFS_PTHREAD_ENV */
-}
+ exit(0);
-/* This LWP does things roughly every 5 minutes */
-static FiveMinuteCheckLWP()
+} /*ShutDown*/
+void ShutDown(void) /* backward compatibility */
{
- static int msg = 0;
- char tbuffer[32];
+ ShutDownAndCore(DONTPANIC);
+}
- ViceLog(1, ("Starting five minute check process\n"));
- while (1) {
-#ifdef AFS_PTHREAD_ENV
- sleep(fiveminutes);
-#else /* AFS_PTHREAD_ENV */
- IOMGR_Sleep(fiveminutes);
-#endif /* AFS_PTHREAD_ENV */
-
- /* close the log so it can be removed */
- ReOpenLog(AFSDIR_SERVER_FILELOG_FILEPATH); /* don't trunc, just append */
- ViceLog(2, ("Cleaning up timed out callbacks\n"));
- if(CleanupTimedOutCallBacks())
- ViceLog(5,("Timed out callbacks deleted\n"));
- ViceLog(2, ("Set disk usage statistics\n"));
- VSetDiskUsage();
- if (FS_registered == 1) Do_VLRegisterRPC();
-#ifndef AFS_QUIETFS_ENV
- if(printBanner && (++msg&1)) { /* Every 10 minutes */
- time_t now = FT_ApproxTime();
- if (console != NULL) {
- fprintf(console,"File server is running at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
- }
- }
-#endif /* AFS_QUIETFS_ENV */
- }
-} /*FiveMinuteCheckLWP*/
-
-
-/* This LWP does host checks every 5 minutes: it should not be used for
- * other 5 minute activities because it may be delayed by timeouts when
- * it probes the workstations
- */
-static HostCheckLWP()
-
-{
- ViceLog(1, ("Starting Host check process\n"));
- while(1) {
-#ifdef AFS_PTHREAD_ENV
- sleep(fiveminutes);
-#else /* AFS_PTHREAD_ENV */
- IOMGR_Sleep(fiveminutes);
-#endif /* AFS_PTHREAD_ENV */
- ViceLog(2, ("Checking for dead venii & clients\n"));
- h_CheckHosts();
- }
-} /*HostCheckLWP*/
-
-
-#define MAXADMINNAME 64
-char adminName[MAXADMINNAME];
-
-CheckAdminName()
-
-{
- int fd = 0;
- struct stat status;
-
- if ((stat("/AdminName", &status)) || /* if file does not exist */
- (status.st_size <= 0) || /* or it is too short */
- (status.st_size >= (MAXADMINNAME)) || /* or it is too long */
- !(fd = open("/AdminName", O_RDONLY, 0))) { /* or the open fails */
- strcpy(adminName, "System:Administrators"); /* use the default name */
- }
- else {
- read(fd, adminName, status.st_size); /* use name from the file */
- }
- if (fd)
- close(fd); /* close fd if it was opened */
-
-} /*CheckAdminName*/
-
-
-/*------------------------------------------------------------------------
- * PRIVATE ClearXStatValues
- *
- * Description:
- * Initialize all of the values collected via the xstat
- * interface.
- *
- * Arguments:
- * None.
- *
- * Returns:
- * Nothing.
- *
- * Environment:
- * Must be called during File Server initialization.
- *
- * Side Effects:
- * As advertised.
- *------------------------------------------------------------------------*/
-
-static void ClearXStatValues()
-
-{ /*ClearXStatValues*/
-
- struct fs_stats_opTimingData *opTimeP; /*Ptr to timing struct*/
- struct fs_stats_xferData *opXferP; /*Ptr to xfer struct*/
- int i; /*Loop counter*/
-
- /*
- * Zero all xstat-related structures.
- */
- bzero((char *)(&afs_perfstats), sizeof(struct afs_PerfStats));
-#if FS_STATS_DETAILED
- bzero((char *)(&afs_FullPerfStats), sizeof(struct fs_stats_FullPerfStats));
-
- /*
- * That's not enough. We have to set reasonable minima for
- * time and xfer values in the detailed stats.
- */
- opTimeP = &(afs_FullPerfStats.det.rpcOpTimes[0]);
- for (i = 0; i < FS_STATS_NUM_RPC_OPS; i++, opTimeP++)
- opTimeP->minTime.tv_sec = 999999;
-
- opXferP = &(afs_FullPerfStats.det.xferOpTimes[0]);
- for (i = 0; i < FS_STATS_NUM_XFER_OPS; i++, opXferP++) {
- opXferP->minTime.tv_sec = 999999;
- opXferP->minBytes = 999999999;
- }
-
- /*
- * There's more. We have to set our unique system identifier, as
- * declared in param.h. If such a thing is not defined, we bitch
- * and declare ourselves to be an unknown system type.
- */
-#ifdef SYS_NAME_ID
- afs_perfstats.sysname_ID = SYS_NAME_ID;
-#else
-#ifndef AFS_NT40_ENV
- ViceLog(0, ("Sys name ID constant not defined in param.h!!\n"));
- ViceLog(0, ("[Choosing ``undefined'' sys name ID.\n"));
-#endif
- afs_perfstats.sysname_ID = SYS_NAME_ID_UNDEFINED;
-#endif /* SYS_NAME_ID */
-#endif
-
-} /*ClearXStatValues*/
-
-
-static void PrintCounters()
-
-{
- int dirbuff, dircall, dirio;
- struct timeval tpl;
- int workstations, activeworkstations, delworkstations;
- int processSize = 0;
- char tbuffer[32];
-
- TM_GetTimeOfDay(&tpl, 0);
- Statistics = 1;
- ViceLog(0, ("Vice was last started at %s\n",
- afs_ctime(&StartTime, tbuffer, sizeof(tbuffer))));
-
- VPrintCacheStats();
- VPrintDiskStats();
- DStat(&dirbuff, &dircall, &dirio);
- ViceLog(0,("With %d directory buffers; %d reads resulted in %d read I/Os\n",
- dirbuff, dircall, dirio));
- rx_PrintStats(stderr);
- h_PrintStats();
- PrintCallBackStats();
-#ifdef AFS_NT40_ENV
- processSize = -1; /* TODO: */
-#else
- processSize = (int)((long) sbrk(0) >> 10);
-#endif
- ViceLog(0,("There are %d connections, process size %d\n", CurrentConnections, processSize));
- h_GetWorkStats(&workstations, &activeworkstations, &delworkstations,
- tpl.tv_sec-15*60);
- ViceLog(0,
- ("There are %d workstations, %d are active (req in < 15 mins), %d marked \"down\"\n",
- workstations, activeworkstations, delworkstations));
- Statistics = 0;
-
-} /*PrintCounters*/
-
-
-
-static CheckSignal()
-
-{
- if (FS_registered > 0) {
- /*
- * We have proper ip addresses; tell the vlserver what we got; the following
- * routine will do the proper reporting for us
- */
- Do_VLRegisterRPC();
- }
- h_DumpHosts();
- h_PrintClients();
- DumpCallBackState();
- PrintCounters();
- ResetCheckSignal();
-
-} /*CheckSignal*/
-
-void ShutDownAndCore(dopanic)
-int dopanic;
-{
- time_t now = time(0);
- char *tstr;
- char tbuffer[32];
-
- ViceLog(0, ("Shutting down file server at %s",
- afs_ctime(&now, tbuffer, sizeof(tbuffer))));
- if (dopanic)
- ViceLog(0, ("ABNORMAL SHUTDOWN, see core file.\n"));
-#ifndef AFS_QUIETFS_ENV
- if (console != NULL) {
- fprintf(console,"File server restart/shutdown received at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
- }
-#endif
- DFlush();
- PrintCounters();
-
- /* do not allows new reqests to be served from now on, all new requests
- are returned with an error code of RX_RESTARTING ( transient failure ) */
- rx_SetRxTranquil(); /* dhruba */
- VShutdown();
-
- if (debugFile) {
- rx_PrintStats(debugFile);
- fflush(debugFile);
- }
-#ifndef AFS_QUIETFS_ENV
- if (console != NULL) {
- now = time(0);
- if (dopanic)
- fprintf(console, "File server has terminated abnormally at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
- else
- fprintf(console, "File server has terminated normally at %s\r",
- afs_ctime(&now, tbuffer, sizeof(tbuffer)));
- }
-#endif
-
- exit(0);
-
-} /*ShutDown*/
-
-void ShutDown() /* backward compatibility */
-{
- ShutDownAndCore(DONTPANIC);
-}
-
-
-static FlagMsg()
+static void FlagMsg()
{
char buffer[1024];
strcat(buffer, "[-banner (print banner every 10 minutes)] ");
strcat(buffer, "[-novbc (whole volume cbs disabled)] ");
strcat(buffer, "[-implicit <admin mode bits: rlidwka>] ");
+ strcat(buffer, "[-readonly (read-only file server)] ");
strcat(buffer, "[-hr <number of hours between refreshing the host cps>] ");
strcat(buffer, "[-busyat <redirect clients when queue > n>] ");
strcat(buffer, "[-rxpck <number of rx extra packets>] ");
strcat(buffer, "[-k <stack size>] ");
strcat(buffer, "[-realm <Kerberos realm name>] ");
strcat(buffer, "[-udpsize <size of socket buffer in bytes>] ");
+ strcat(buffer, "[-sendsize <size of send buffer in bytes>] ");
/* strcat(buffer, "[-enable_peer_stats] "); */
/* strcat(buffer, "[-enable_process_stats] "); */
strcat(buffer, "[-help]\n");
} /*FlagMsg*/
-static afs_int32 ParseRights(arights)
- char *arights;
+static afs_int32 ParseRights(char *arights)
{
afs_int32 mode = 0;
int i, len;
return MAX_FILESERVER_THREAD;
}
-static ParseArgs(argc, argv)
- int argc;
- char *argv[];
-
+static int ParseArgs(int argc, char *argv[])
{
int SawL=0, SawS=0, SawVC=0;
int Sawrxpck = 0, Sawsmall=0, Sawlarge=0, Sawcbs=0, Sawlwps=0, Sawbufs=0;
implicitAdminRights = ParseRights(argv[++i]);
if (implicitAdminRights < 0) return implicitAdminRights;
} else
+ if (!strcmp(argv[i], "-readonly")) {
+ readonlyServer = 1;
+ } else
if (!strcmp(argv[i], "-L")) {
SawL = 1;
} else
if (!strcmp(argv[i], "-cb")) {
Sawcbs = 1;
numberofcbs = atoi(argv[++i]);
- if ((numberofcbs < 10000) || (numberofcbs > 65535)) {
- printf("number of cbs %d invalid; must be between 10000 and 65535\n",
+ if ((numberofcbs < 10000) || (numberofcbs > 2147483647)) {
+ printf("number of cbs %d invalid; must be between 10000 and 2147483647\n",
numberofcbs);
return -1;
}
udpBufSize = bufSize;
}
else
+ if ( !strcmp(argv[i], "-sendsize")) {
+ if ( (i+1) >= argc ) {
+ printf("You have to specify -sendsize <integer value>\n");
+ return -1;
+ }
+ bufSize = atoi(argv[++i]);
+ if ( bufSize < 16384 )
+ printf("Warning:sendsize %d is less than minimum %d; ignoring\n",
+ bufSize, 16384);
+ else
+ sendBufSize = bufSize;
+ }
+ else
if (!strcmp(argv[i], "-enable_peer_stats")) {
rx_enablePeerRPCStats();
}
#define MAXPARMS 15
-static void NewParms(initializing)
- int initializing;
-
+static void NewParms(int initializing)
{
static struct stat sbuf;
- register int i, fd;
+ register afs_offs_t i;
+ register int fd;
char *parms;
char *argv[MAXPARMS];
register int argc;
if (!(stat("/vice/file/parms",&sbuf))) {
parms = (char *)malloc(sbuf.st_size);
- if(parms <= (char *)0) return;
+ if(!parms) return;
fd = open("parms", O_RDONLY, 0666);
if(fd <= 0) {
ViceLog(0, ("Open for parms failed with errno = %d\n", errno));
i = read(fd, parms, sbuf.st_size);
close(fd);
if(i != sbuf.st_size) {
- if (i < 0 )
+ if (i < 0 ) {
ViceLog(0, ("Read on parms failed with errno = %d\n", errno));
- else
+ } else {
ViceLog(0,
("Read on parms failed; expected %d bytes but read %d\n",
sbuf.st_size, i));
+ }
free(parms);
return;
}
i++;
}
}
- if(ParseArgs(argc, argv) == 0)
+ if(ParseArgs(argc, argv) == 0) {
ViceLog(0, ("Change parameters to:"));
- else
+ } else {
ViceLog(0, ("Invalid parameter in:"));
+ }
for(i = 0; i < argc; i++) {
ViceLog(0, (" %s", argv[i]));
}
/* Miscellaneous routines */
-Die (msg)
- char *msg;
-
+void Die (char *msg)
{
ViceLog (0,("%s\n", msg));
assert(0);
} /*Die*/
-InitPR()
-
+afs_int32 InitPR()
{
register code;
SystemId = SYSADMINID;
SystemAnyUser = ANYUSERID;
SystemAnyUserCPS.prlist_len = 0;
- SystemAnyUserCPS.prlist_val = (afs_int32 *)0;
+ SystemAnyUserCPS.prlist_val = NULL;
AnonCPS.prlist_len = 0;
- AnonCPS.prlist_val = (afs_int32 *)0;
+ AnonCPS.prlist_val = NULL;
while (1) {
code = pr_GetCPS(SystemAnyUser, &SystemAnyUserCPS);
if (code != 0) {
struct rx_connection *serverconns[MAXSERVERS];
struct ubik_client *cstruct;
-afs_int32 vl_Initialize(confDir)
-char *confDir;
+
+afs_int32 vl_Initialize(char *confDir)
{ afs_int32 code, scIndex = 0, i;
struct afsconf_dir *tdir;
struct rx_securityClass *sc;
ViceLog(0, ("Could not get security object for localAuth\n"));
exit(1);
}
- code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE, &info);
+ code = afsconf_GetCellInfo(tdir,NULL, AFSCONF_VLDBSERVICE, &info);
if (info.numServers > MAXSERVERS) {
ViceLog(0, ("vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n",info.numServers, MAXSERVERS));
exit(1);
#define SYSIDMAGIC 0x88aabbcc
#define SYSIDVERSION 1
+afs_int32
ReadSysIdFile() {
afs_int32 fd, nentries, i;
struct versionStamp vsn;
return 0;
}
+afs_int32
WriteSysIdFile() {
afs_int32 fd, nentries, i;
struct versionStamp vsn;
*/
renamefile(AFSDIR_SERVER_SYSID_FILEPATH, AFSDIR_SERVER_OLDSYSID_FILEPATH);
}
- fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
- if (fd < 1) {
- ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
- return EIO;
+ fd = open(AFSDIR_SERVER_SYSID_FILEPATH, O_WRONLY|O_TRUNC|O_CREAT, 0666);
+ if (fd < 1) {
+ ViceLog(0, ("%s: can't create (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
+ return EIO;
+ }
+ vsn.magic = SYSIDMAGIC;
+ vsn.version = 1;
+ if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
+ ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
+ return EIO;
+ }
+ uuid = FS_HostUUID;
+ afs_htonuuid(&uuid);
+ if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
+ ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
+ return EIO;
+ }
+ if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
+ ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
+ return EIO;
+ }
+ for (i = 0; i < FS_HostAddr_cnt; i++) {
+ if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
+ ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
+ return EIO;
+ }
+ }
+ close(fd);
+ return 0;
+}
+
+/*
+ * defect 10966
+ * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
+ * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
+ * and so we need to convert each of them into HBO which is what the extra
+ * array called FS_HostAddrs_HBO is used here.
+ */
+afs_int32
+Do_VLRegisterRPC() {
+ register int code;
+ bulkaddrs addrs;
+ extern int VL_RegisterAddrs();
+ afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
+ int i=0;
+
+ for (i=0; i < FS_HostAddr_cnt ; i++)
+ FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
+ addrs.bulkaddrs_len = FS_HostAddr_cnt;
+ addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
+ code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
+ if (code) {
+ if (code == VL_MULTIPADDR) {
+ ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
+ ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
+ return code;
+ } else if (code == RXGEN_OPCODE) {
+ ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
+ FS_registered = 2; /* So we don't have to retry in the gc daemon */
+ } else {
+ ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
+ code, errno));
+ }
+ } else {
+ FS_registered = 2; /* So we don't have to retry in the gc daemon */
+ WriteSysIdFile();
+ }
+
+ return 0;
+}
+
+#if 0
+static int AddrsEqual(cnt, addr1, addr2)
+ int cnt;
+ afs_int32 *addr1, *addr2;
+{
+ register int i, j;
+
+ for (i = 0; i < cnt; i++) {
+ for (j = 0; j < cnt; j++) {
+ if (addr1[i] == addr2[j]) break;
+ }
+ if (j == cnt) return 0;
+ }
+ return 1;
+}
+#endif
+
+afs_int32
+InitVL() {
+ int (*old)();
+ afs_int32 code;
+ afs_int32 cnt, i;
+ extern int rxi_numNetAddrs;
+ extern afs_uint32 rxi_NetAddrs[];
+
+ /*
+ * If this fails, it's because something major is wrong, and is not
+ * likely to be time dependent.
+ */
+ code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
+ if (code != 0) {
+ ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
+ return code;
+ }
+
+ /* Read or create the sysid file and register the fileserver's
+ * IP addresses with the vlserver.
+ */
+ code = ReadSysIdFile();
+ if (code) {
+ /* Need to create the file */
+ ViceLog(0, ("Creating new SysID file\n"));
+ if ((code = afs_uuid_create(&FS_HostUUID))) {
+ ViceLog(0, ("Failed to create new uuid: %d\n", code));
+ exit(1);
+ }
+ }
+ /* A good sysid file exists; inform the vlserver. If any conflicts,
+ * we always use the latest interface available as the real truth.
+ */
+#ifndef AFS_NT40_ENV
+ if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
+ /*
+ * Find addresses we are supposed to register as per the netrestrict
+ * and netinfo files (/usr/afs/local/NetInfo and
+ * /usr/afs/local/NetRestict)
+ */
+ char reason[1024];
+ afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
+ ADDRSPERSITE, reason,
+ AFSDIR_SERVER_NETINFO_FILEPATH,
+ AFSDIR_SERVER_NETRESTRICT_FILEPATH);
+ if (code < 0) {
+ ViceLog(0,("Can't register any valid addresses: %s\n",reason));
+ exit(1);
+ }
+ FS_HostAddr_cnt = (afs_uint32) code;
+ }
+ else
+#endif
+ {
+ FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
+ }
+
+ FS_registered = 1;
+ code = Do_VLRegisterRPC();
+ return code;
+}
+
+int
+main(int argc, char * argv[])
+{
+ int i;
+ afs_int32 code;
+ FILE *file;
+ char tbuffer[32];
+ struct rx_securityClass *sc[4];
+ struct rx_service *tservice;
+#ifdef AFS_PTHREAD_ENV
+ pthread_t parentPid, serverPid;
+ pthread_attr_t tattr;
+#else /* AFS_PTHREAD_ENV */
+ PROCESS parentPid, serverPid;
+#endif /* AFS_PTHREAD_ENV */
+ struct hostent *he;
+ int minVnodesRequired; /* min size of vnode cache */
+#ifndef AFS_NT40_ENV
+ struct rlimit rlim; /* max number of open file descriptors */
+#endif
+ int curLimit;
+
+#ifdef AFS_AIX32_ENV
+ struct sigaction nsa;
+
+ sigemptyset(&nsa.sa_mask);
+ nsa.sa_handler = SIG_DFL;
+ nsa.sa_flags = SA_FULLDUMP;
+ sigaction(SIGABRT, &nsa, NULL);
+ sigaction(SIGSEGV, &nsa, NULL);
+#endif
+
+ /* Initialize dirpaths */
+ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
+#ifdef AFS_NT40_ENV
+ ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
+#endif
+ fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
+ exit(2);
+ }
+
+#ifndef AFS_QUIETFS_ENV
+ console = fopen("/dev/console","w");
+#endif
+
+ if(ParseArgs(argc,argv)) {
+ FlagMsg();
+ exit(-1);
+ }
+
+#ifdef AFS_PTHREAD_ENV
+ assert(pthread_mutex_init(&fileproc_glock_mutex, NULL) == 0);
+#endif /* AFS_PTHREAD_ENV */
+
+#ifdef AFS_SGI_VNODE_GLUE
+ if (afs_init_kernel_config(-1) <0) {
+ printf("Can't determine NUMA configuration, not starting fileserver.\n");
+ exit(1);
+ }
+#endif
+ confDir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
+ if (!confDir) {
+ fprintf(stderr, "Unable to open config directory %s\n",
+ AFSDIR_SERVER_ETC_DIRPATH);
+ exit(-1);
+ }
+
+ NewParms(1);
+
+ /* Open FileLog on stdout, stderr, fd 1 and fd2 (for perror), sigh. */
+ OpenLog(AFSDIR_SERVER_FILELOG_FILEPATH);
+ SetupLogSignals();
+
+ if (SawSpare && SawPctSpare) {
+ ViceLog(0, ("Both -spare and -pctspare specified, exiting.\n"));
+ exit(-1);
+ }
+
+#ifdef AFS_SGI_XFS_IOPS_ENV
+ ViceLog(0, ("XFS/EFS File server starting\n"));
+#else
+ ViceLog(0, ("File server starting\n"));
+#endif
+
+#if defined(AFS_PTHREAD_ENV)
+ /* initialize the pthread soft signal handler thread */
+ softsig_init();
+#endif
+
+ /* install signal handlers for controlling the fileserver process */
+ ResetCheckSignal(); /* set CheckSignal_Signal() sig handler */
+ ResetCheckDescriptors(); /* set CheckDescriptors_Signal() sig handler */
+
+#if defined(AFS_SGI_ENV)
+ /* give this guy a non-degrading priority so help busy servers */
+ schedctl(NDPRI, 0, NDPNORMMAX);
+ if (SawLock)
+ plock(PROCLOCK);
+#else
+#ifndef AFS_NT40_ENV
+ nice(-5); /* TODO: */
+#endif
+#endif
+ assert(DInit(buffs) == 0);
+
+#ifdef AFS_NT40_ENV
+ if (afs_winsockInit()<0) {
+ ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
+ ViceLog(0, ("File server failed to intialize winsock.\n"));
+ exit(1);
+ }
+#endif
+ CheckAdminName();
+
+ /* if we support more than 16 threads, then we better have the ability
+ ** to keep open a large number of files simultaneously
+ */
+#if defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV)
+ curLimit = OPEN_MAX; /* for pre AIX 4.2 systems */
+#elif defined(AFS_NT40_ENV)
+ curLimit = NT_OPEN_MAX; /* open file descriptor limit on NT */
+#else
+
+ curLimit = 0; /* the number of open file descriptors */
+ code = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (code == 0) {
+ curLimit = rlim.rlim_cur;
+ rlim.rlim_cur = rlim.rlim_max;
+ code = setrlimit(RLIMIT_NOFILE, &rlim);
+ if ( code == 0 )
+ curLimit = rlim.rlim_max;
+ }
+ if ( code != 0 )
+ ViceLog(0, ("Failed to increase open file limit, using default\n"));
+
+#endif /* defined(AFS_AIX_ENV) && !defined(AFS_AIX42_ENV) */
+
+ curLimit -= 32; /* leave a slack of 32 file descriptors */
+ if ( lwps > curLimit ) {
+ if ( curLimit > 0)
+ lwps = curLimit;
+ else if ( lwps > 16 )
+ lwps = 16; /* default to a maximum of 16 threads */
+ ViceLog(0, ("The system supports a max of %d open files and we are starting %d threads\n", curLimit, lwps));
+ }
+
+
+#ifndef AFS_PTHREAD_ENV
+ assert(LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid) == LWP_SUCCESS);
+#endif /* !AFS_PTHREAD_ENV */
+
+ /* Initialize volume support */
+ if (!novbc) {
+ V_BreakVolumeCallbacks = BreakVolumeCallBacksLater;
+ }
+
+ /* initialize libacl routines */
+ acl_Initialize(ACL_VERSION);
+
+ /* initialize RX support */
+#ifndef AFS_NT40_ENV
+ rxi_syscallp = viced_syscall;
+#endif
+ rx_extraPackets = rxpackets;
+ rx_extraQuota = 4; /* for outgoing prserver calls from R threads */
+ rx_SetBusyThreshold(busy_threshold, VBUSY);
+ rx_SetCallAbortThreshold(10);
+ rx_SetConnAbortThreshold(10);
+ stackSize = lwps * 4000;
+ if (stackSize < 32000)
+ stackSize = 32000;
+ else if (stackSize > 44000)
+ stackSize = 44000;
+#if defined(AFS_HPUX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_SGI51_ENV)
+ rx_SetStackSize(1, stackSize);
+#endif
+ if ( udpBufSize )
+ rx_SetUdpBufSize(udpBufSize);/* set the UDP buffer size for receive */
+ if (rx_Init((int)htons(7000))<0) {
+ ViceLog(0, ("Cannot initialize RX\n"));
+ exit(1);
+ }
+ if (!rxJumbograms) {
+ /* Don't send and don't allow 3.4 clients to send jumbograms. */
+ rx_SetNoJumbo();
}
- vsn.magic = SYSIDMAGIC;
- vsn.version = 1;
- if ((i = write(fd, (char *)&vsn, sizeof(vsn))) != sizeof(vsn)) {
- ViceLog(0, ("%s: write failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
- return EIO;
+ rx_GetIFInfo();
+ rx_SetRxDeadTime(30);
+ sc[0] = rxnull_NewServerSecurityObject();
+ sc[1] = 0; /* rxvab_NewServerSecurityObject(key1, 0) */
+ sc[2] = rxkad_NewServerSecurityObject (rxkad_clear, NULL,
+ get_key, NULL);
+ sc[3] = rxkad_NewServerSecurityObject (rxkad_crypt, NULL,
+ get_key, NULL);
+ tservice = rx_NewService
+ (/* port */ 0, /* service id */ 1, /*service name */ "AFS",
+ /* security classes */ sc, /* numb sec classes */ 4,
+ RXAFS_ExecuteRequest);
+ if (!tservice) {
+ ViceLog(0, ("Failed to initialize RX, probably two servers running.\n"));
+ exit(-1);
}
- uuid = FS_HostUUID;
- afs_htonuuid(&uuid);
- if ((i = write(fd, (char *)&uuid, sizeof(struct afsUUID))) != sizeof(struct afsUUID)) {
- ViceLog(0, ("%s: write of uuid failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
- return EIO;
+ rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
+ rx_SetMinProcs(tservice, 3);
+ rx_SetMaxProcs(tservice, lwps);
+ rx_SetCheckReach(tservice, 1);
+
+ tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4, RXSTATS_ExecuteRequest);
+ if (!tservice) {
+ ViceLog(0, ("Failed to initialize rpc stat service.\n"));
+ exit(-1);
}
- if ((i = write(fd, (char *)&FS_HostAddr_cnt, sizeof(afs_int32))) != sizeof(afs_int32)) {
- ViceLog(0, ("%s: write of # of entries failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
- return EIO;
+ rx_SetMinProcs(tservice, 2);
+ rx_SetMaxProcs(tservice, 4);
+
+ /*
+ * Enable RX hot threads, which allows the listener thread to trade
+ * places with an idle thread and moves the context switch from listener
+ * to worker out of the critical path.
+ */
+ rx_EnableHotThread();
+
+ /* Some rx debugging */
+ if (rxlog || eventlog) {
+ debugFile = fopen("rx_dbg", "w");
+ if (rxlog) rx_debugFile = debugFile;
+ if (eventlog) rxevent_debugFile = debugFile;
}
- for (i = 0; i < FS_HostAddr_cnt; i++) {
- if (write(fd, (char *)&FS_HostAddrs[i], sizeof(afs_int32)) != sizeof(afs_int32)) {
- ViceLog(0, ("%s: write of addresses failed (%d)\n", AFSDIR_SERVER_SYSID_FILEPATH, errno));
- return EIO;
- }
+
+ h_InitHostPackage(); /* set up local cellname and realmname */
+ InitCallBack(numberofcbs);
+ ClearXStatValues();
+
+ code = InitVL();
+ if (code) {
+ ViceLog(0,("Fatal error in library initialization, exiting!!\n"));
+ exit(1);
}
- close(fd);
- return 0;
-}
-/*
- * defect 10966
- * This routine sets up the buffers for the VL_RegisterAddrs RPC. All addresses
- * in FS_HostAddrs[] are in NBO, while the RPC treats them as a "blob" of data
- * and so we need to convert each of them into HBO which is what the extra
- * array called FS_HostAddrs_HBO is used here.
- */
-Do_VLRegisterRPC() {
- register int code;
- bulkaddrs addrs;
- extern int VL_RegisterAddrs();
- afs_uint32 FS_HostAddrs_HBO[ADDRSPERSITE];
- int i=0;
-
- for (i=0; i < FS_HostAddr_cnt ; i++)
- FS_HostAddrs_HBO[i]=ntohl(FS_HostAddrs[i]);
- addrs.bulkaddrs_len = FS_HostAddr_cnt;
- addrs.bulkaddrs_val = (afs_uint32 *)FS_HostAddrs_HBO;
- code = ubik_Call(VL_RegisterAddrs, cstruct, 0, &FS_HostUUID, 0, &addrs);
+ code = InitPR();
if (code) {
- if (code == VL_MULTIPADDR) {
- ViceLog(0, ("VL_RegisterAddrs rpc failed; The ethernet address exist on a different server; repair it\n"));
- ViceLog(0, ("VL_RegisterAddrs rpc failed; See VLLog for details\n"));
- return code;
- } else if (code == RXGEN_OPCODE) {
- ViceLog(0, ("vlserver doesn't support VL_RegisterAddrs rpc; ignored\n"));
- FS_registered = 2; /* So we don't have to retry in the gc daemon */
- } else {
- ViceLog(0, ("VL_RegisterAddrs rpc failed; will retry periodically (code=%d, err=%d)\n",
- code, errno));
- }
- } else {
- FS_registered = 2; /* So we don't have to retry in the gc daemon */
- WriteSysIdFile();
+ ViceLog(0,("Fatal error in protection initialization, exiting!!\n"));
+ exit(1);
}
- return 0;
-}
+ /* allow super users to manage RX statistics */
+ rx_SetRxStatUserOk(fs_rxstat_userok);
-AddrsEqual(cnt, addr1, addr2)
- int cnt;
- afs_int32 *addr1, *addr2;
-{
- register int i, j;
+ rx_StartServer(0); /* now start handling requests */
- for (i = 0; i < cnt; i++) {
- for (j = 0; j < cnt; j++) {
- if (addr1[i] == addr2[j]) break;
- }
- if (j == cnt) return 0;
+ /* we ensure that there is enough space in the vnode buffer to satisfy
+ ** requests from all concurrent threads.
+ ** the maximum number of vnodes used by a single thread at any one time
+ ** is three ( "link" uses three vnodes simultaneously, one vLarge and
+ ** two vSmall for linking files and two vLarge and one vSmall for linking
+ ** files ) : dhruba
+ */
+ minVnodesRequired = 2 * lwps + 1;
+ if ( minVnodesRequired > nSmallVns ) {
+ nSmallVns = minVnodesRequired;
+ ViceLog(0, ("Overriding -s command line parameter with %d\n",
+ nSmallVns));
+ }
+ if ( minVnodesRequired > large ) {
+ large = minVnodesRequired;
+ ViceLog(0, ("Overriding -l command line parameter with %d\n", large));
}
- return 1;
-}
-InitVL() {
- int (*old)();
- afs_int32 code;
- afs_int32 cnt, i;
- extern int rxi_numNetAddrs;
- extern afs_uint32 rxi_NetAddrs[];
+ /* We now do this after getting the listener up and running, so that client
+ connections don't timeout (maybe) if a file server is restarted, since it
+ will be available "real soon now". Worry about whether we can satisfy the
+ calls in the volume package itself.
+ */
+ if (VInitVolumePackage(fileServer,large,nSmallVns,0, volcache)) {
+ ViceLog(0, ("Shutting down: errors encountered initializing volume package\n"));
+ VShutdown();
+ exit(1);
+ }
/*
- * If this fails, it's because something major is wrong, and is not
- * likely to be time dependent.
+ * We are done calling fopen/fdopen. It is safe to use a large
+ * of the file descriptor cache.
*/
- code = vl_Initialize(AFSDIR_SERVER_ETC_DIRPATH);
- if (code != 0) {
- ViceLog(0, ("Couldn't initialize protection library; code=%d.\n", code));
- return code;
+ ih_UseLargeCache();
+
+#ifdef AFS_PTHREAD_ENV
+ assert(pthread_attr_init(&tattr) == 0);
+ assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
+
+ assert(pthread_create(&serverPid, &tattr, (void *)FiveMinuteCheckLWP, &fiveminutes) == 0);
+ assert(pthread_create(&serverPid, &tattr, (void *)HostCheckLWP, &fiveminutes) == 0);
+ assert(pthread_create(&serverPid, &tattr, (void *)FsyncCheckLWP, &fiveminutes) == 0);
+#else /* AFS_PTHREAD_ENV */
+ assert(LWP_CreateProcess(FiveMinuteCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
+ (void *) &fiveminutes, "FiveMinuteChecks", &serverPid) == LWP_SUCCESS);
+
+ assert(LWP_CreateProcess(HostCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
+ (void *) &fiveminutes, "HostCheck", &serverPid) == LWP_SUCCESS);
+ assert(LWP_CreateProcess(FsyncCheckLWP, stack*1024, LWP_MAX_PRIORITY - 2,
+ (void *) &fiveminutes, "FsyncCheck", &serverPid) == LWP_SUCCESS);
+#endif /* AFS_PTHREAD_ENV */
+
+ TM_GetTimeOfDay(&tp, 0);
+
+#ifndef AFS_QUIETFS_ENV
+ if (console != NULL) {
+ fprintf(console, "File server has started at %s\r",
+ afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)));
}
+#endif
- /* Read or create the sysid file and register the fileserver's
- * IP addresses with the vlserver.
+ /*
+ * Figure out the FileServer's name and primary address.
*/
- code = ReadSysIdFile();
+ ViceLog(0, ("Getting FileServer name...\n"));
+ code = gethostname(FS_HostName, 64);
if (code) {
- /* Need to create the file */
- ViceLog(0, ("Creating new SysID file\n"));
- if (code = afs_uuid_create(&FS_HostUUID)) {
- ViceLog(0, ("Failed to create new uuid: %d\n", code));
- exit(1);
- }
+ ViceLog(0, ("gethostname() failed\n"));
}
- /* A good sysid file exists; inform the vlserver. If any conflicts,
- * we always use the latest interface available as the real truth.
- */
-#ifndef AFS_NT40_ENV
- if(AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) {
- /*
- * Find addresses we are supposed to register as per the netrestrict
- * and netinfo files (/usr/afs/local/NetInfo and
- * /usr/afs/local/NetRestict)
- */
- char reason[1024];
- afs_int32 code = parseNetFiles(FS_HostAddrs,NULL, NULL,
- ADDRSPERSITE, reason,
- AFSDIR_SERVER_NETINFO_FILEPATH,
- AFSDIR_SERVER_NETRESTRICT_FILEPATH);
- if (code < 0) {
- ViceLog(0,("Can' register any valid addresses:%s\n",reason));
- exit(1);
- }
- FS_HostAddr_cnt = (afs_uint32) code;
+ ViceLog(0, ("FileServer host name is '%s'\n", FS_HostName));
+
+ ViceLog(0, ("Getting FileServer address...\n"));
+ he = gethostbyname(FS_HostName);
+ if (!he) {
+ ViceLog(0, ("Can't find address for FileServer '%s'\n", FS_HostName));
}
- else
+ else {
+ char hoststr[16];
+ memcpy(&FS_HostAddr_NBO, he->h_addr, 4);
+ afs_inet_ntoa_r(FS_HostAddr_NBO, hoststr);
+ FS_HostAddr_HBO = ntohl(FS_HostAddr_NBO);
+ ViceLog(0,("FileServer %s has address %s (0x%x or 0x%x in host byte order)\n",
+ FS_HostName, hoststr, FS_HostAddr_NBO, FS_HostAddr_HBO));
+ }
+
+ /* Install handler to catch the shutdown signal;
+ * bosserver assumes SIGQUIT shutdown
+ */
+#if defined(AFS_PTHREAD_ENV)
+ softsig_signal(SIGQUIT, ShutDown_Signal);
+#else
+ signal(SIGQUIT, ShutDown_Signal);
#endif
- {
- FS_HostAddr_cnt = rx_getAllAddr(FS_HostAddrs, ADDRSPERSITE);
+
+ ViceLog(0,("File Server started %s",
+ afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))));
+#if FS_STATS_DETAILED
+ afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec;
+#endif
+#ifdef AFS_PTHREAD_ENV
+ while(1) {
+ sleep(1000); /* long time */
}
+#else /* AFS_PTHREAD_ENV */
+ assert(LWP_WaitProcess(&parentPid) == LWP_SUCCESS);
+#endif /* AFS_PTHREAD_ENV */
+}
- FS_registered = 1;
- code = Do_VLRegisterRPC();
- return code;
-}