void Lock_Destroy(struct Lock *lock) { #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_mutex_destroy(&lock->mutex) == 0); opr_Verify(pthread_cond_destroy(&lock->read_cv) == 0); opr_Verify(pthread_cond_destroy(&lock->write_cv) == 0); #endif /* AFS_PTHREAD_ENV */ }
void Lock_Init(struct Lock *lock) { lock->readers_reading = 0; lock->excl_locked = 0; lock->wait_states = 0; lock->num_waiting = 0; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_mutex_init(&lock->mutex, NULL) == 0); opr_Verify(pthread_cond_init(&lock->read_cv, NULL) == 0); opr_Verify(pthread_cond_init(&lock->write_cv, NULL) == 0); #endif /* AFS_PTHREAD_ENV */ }
/*! * Open the log file descriptor or a connection to the system log. * * This function should be called once during program initialization and * must be called before calling FSLog() or WriteLogBuffer(). The * fields of the given argument specify the logging destination and * various optional features. * * The lopt_logLevel value specifies the initial logging level. * * The lopt_dest enum specifies the logging destination; either * file based (logDest_file) or the system log (logDest_syslog). * * File Based Logging * ------------------ * * A file will be opened for log messages when the lopt_dest enum is set * to logDest_file. The file specified by lopt_filename will be opened * for appending log messages. A new file will be created if the log * file does not exist. * * The lopt_rotateOnOpen flag specifies whether an existing log file is * to be renamed and a new log file created during the call to OpenLog. * The lopt_rotateOnOpen flag has no effect if the file given by * lopt_filename is a named pipe (fifo). * * The lopt_rotateOnReset flag specifies whether the log file is renamed * and then reopened when the reset signal (SIGHUP) is caught. * * The lopt_rotateStyle enum specifies how the new log file is renamed when * lopt_rotateOnOpen or lopt_rotateOnReset are set. The lopt_rotateStyle * may be the traditional Transarc style (logRotate_old) or the MR-AFS * style (logRotate_timestamp). * * When lopt_rotateStyle is set to logRotate_old, the suffix ".old" is * appended to the log file name. The existing ".old" log file is * removed. * * When lopt_rotateStyle is set to logRotate_timestamp, a timestamp * string is appended to the log file name and existing files are not * removed. * * \note Messages written to stdout and stderr are redirected to the log * file when file-based logging is in effect. * * System Logging * -------------- * * A connection to the system log (syslog) will be established for log * messages when the lopt_dest enum is set to logDest_syslog. * * The lopt_facility specifies the system log facility to be used when * writing messages to the system log. * * The lopt_tag string specifies the indentification string to be used * when writing messages to the system log. * * \param opts logging options. A copy of the logging * options will be made before returning to * the caller. * * \returns 0 on success */ int OpenLog(struct logOptions *opts) { int code; #if defined(AFS_PTHREAD_ENV) opr_Verify(pthread_once(&serverLogOnce, InitServerLogMutex) == 0); #endif /* AFS_PTHREAD_ENV */ LogLevel = serverLogOpts.logLevel = opts->logLevel; serverLogOpts.dest = opts->dest; switch (serverLogOpts.dest) { case logDest_file: serverLogOpts.lopt_rotateOnOpen = opts->lopt_rotateOnOpen; serverLogOpts.lopt_rotateOnReset = opts->lopt_rotateOnReset; serverLogOpts.lopt_rotateStyle = opts->lopt_rotateStyle; /* OpenLogFile() sets ourName; don't cache filename here. */ code = OpenLogFile(opts->lopt_filename); break; #ifdef HAVE_SYSLOG case logDest_syslog: serverLogOpts.lopt_rotateOnOpen = 0; serverLogOpts.lopt_rotateOnReset = 0; serverLogOpts.lopt_rotateStyle = logRotate_none; openlog(opts->lopt_tag, LOG_PID, opts->lopt_facility); code = 0; break; #endif default: opr_Assert(0); } return code; } /*OpenLog */
static void * signalHandler(void *arg) { int receivedSignal; sigset_t set; softsigSignalSet(&set); while (1) { opr_Verify(sigwait(&set, &receivedSignal) == 0); opr_Verify(sigismember(&set, receivedSignal) == 1); if (handlers[receivedSignal].handler != NULL) { handlers[receivedSignal].handler(receivedSignal); } } return NULL; }
/* release a lock, giving preference to new writers */ void Afs_Lock_ReleaseW(struct Lock *lock) { if (lock->wait_states & EXCL_LOCKS) { lock->wait_states &= ~EXCL_LOCKS; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_broadcast(&lock->write_cv) == 0); #else /* AFS_PTHREAD_ENV */ LWP_NoYieldSignal(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } else { lock->wait_states &= ~READ_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_broadcast(&lock->read_cv) == 0); #else /* AFS_PTHREAD_ENV */ LWP_NoYieldSignal(&lock->readers_reading); #endif /* AFS_PTHREAD_ENV */ } }
/* wake up readers waiting for this lock */ void Afs_Lock_WakeupR(struct Lock *lock) { if (lock->wait_states & READ_LOCK) { lock->wait_states &= ~READ_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_broadcast(&lock->read_cv) == 0); #else /* AFS_PTHREAD_ENV */ LWP_NoYieldSignal(&lock->readers_reading); #endif /* AFS_PTHREAD_ENV */ } }
int opr_softsig_Init(void) { sigset_t set; pthread_t handlerThread; /* Block all signals in the main thread, and in any threads which are created * after us. Only the signal handler thread will receive signals. */ softsigSignalSet(&set); pthread_sigmask(SIG_BLOCK, &set, NULL); /* Register a few handlers so that we keep the usual behaviour for CTRL-C and * CTRL-Z, unless the application replaces them. */ opr_Verify(opr_softsig_Register(SIGINT, ExitHandler) == 0); opr_Verify(opr_softsig_Register(SIGTERM, ExitHandler) == 0); opr_Verify(opr_softsig_Register(SIGQUIT, ExitHandler) == 0); opr_Verify(opr_softsig_Register(SIGTSTP, StopHandler) == 0); /* Create a signal handler thread which will respond to any incoming signals * for us. */ opr_Verify(pthread_create(&handlerThread, NULL, signalHandler, NULL) == 0); opr_Verify(pthread_detach(handlerThread) == 0); return 0; }
struct gwin * gtx_Init(int astartInput, int atype) /* type of window to create */ { pthread_t thread_id; struct onode_initparams oi_params; /* object init params */ struct gwin_initparams wi_params; /* window initialization params */ struct gwin *twin; int code; /* setup the main window structure */ wi_params.i_type = GATOR_WIN_CURSES; wi_params.i_x = 0; wi_params.i_y = 0; wi_params.i_width = 80; wi_params.i_height = 200; wi_params.i_debug = 0; /* or 1 if we want debugging done */ /* * Set up the basic onode initialization parameters, throwing in * the graphics-specific stuff. */ oi_params.i_debug = 0; /* or 1 if we want debugging */ oi_params.i_gwparams = &wi_params; code = gator_objects_init(&oi_params); if (code) return NULL; /* if we start input thread */ if (astartInput) { opr_Verify(pthread_create(&thread_id, NULL, gtx_InputServer, NULL) == 0); } /* all done */ twin = &gator_basegwin; return twin; }
void VLockPartition_r(char *name) { struct DiskPartition64 *dp = VGetPartition_r(name, 0); char *partitionName; int retries, code; struct timeval pausing; #if defined(AFS_HPUX_ENV) int lockfRtn; struct privgrp_map privGrpList[PRIV_MAXGRPS]; unsigned int *globalMask; int globalMaskIndex; #endif /* defined(AFS_HPUX_ENV) */ #if defined(AFS_DARWIN_ENV) char lockfile[MAXPATHLEN]; #endif /* defined(AFS_DARWIN_ENV) */ #ifdef AFS_NAMEI_ENV #ifdef AFS_AIX42_ENV char LockFileName[MAXPATHLEN + 1]; sprintf((char *)&LockFileName, "%s/AFSINODE_FSLock", name); partitionName = (char *)&LockFileName; #endif #endif if (!dp) return; /* no partition, will fail later */ if (dp->lock_fd != INVALID_FD) return; #if defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) #if !defined(AFS_AIX42_ENV) || !defined(AFS_NAMEI_ENV) partitionName = dp->devName; #endif code = O_RDWR; #elif defined(AFS_DARWIN_ENV) strlcpy((partitionName = lockfile), dp->name, sizeof(lockfile)); strlcat(lockfile, "/.lock.afs", sizeof(lockfile)); code = O_RDONLY | O_CREAT; #else partitionName = dp->name; code = O_RDONLY; #endif for (retries = 25; retries; retries--) { if (code & O_CREAT) dp->lock_fd = afs_open(partitionName, code, 0644); else dp->lock_fd = afs_open(partitionName, code); if (dp->lock_fd != INVALID_FD) break; if (errno == ENOENT) code |= O_CREAT; pausing.tv_sec = 0; pausing.tv_usec = 500000; select(0, NULL, NULL, NULL, &pausing); } opr_Assert(retries != 0); #if defined (AFS_HPUX_ENV) opr_Verify(getprivgrp(privGrpList) == 0); /* * In general, it will difficult and time-consuming ,if not impossible, * to try to find the privgroup to which this process belongs that has the * smallest membership, to minimise the security hole. So, we use the privgrp * to which everybody belongs. */ /* first, we have to find the global mask */ for (globalMaskIndex = 0; globalMaskIndex < PRIV_MAXGRPS; globalMaskIndex++) { if (privGrpList[globalMaskIndex].priv_groupno == PRIV_GLOBAL) { globalMask = &(privGrpList[globalMaskIndex].priv_mask[LOCKRDONLY_OFFSET]); break; } } if (((*globalMask) & privmask(PRIV_LOCKRDONLY)) == 0) { /* allow everybody to set a lock on a read-only file descriptor */ (*globalMask) |= privmask(PRIV_LOCKRDONLY); opr_Verify(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask) == 0); lockfRtn = lockf(dp->lock_fd, F_LOCK, 0); /* remove the privilege granted to everybody to lock a read-only fd */ (*globalMask) &= ~(privmask(PRIV_LOCKRDONLY)); opr_Verify(setprivgrp(PRIV_GLOBAL, privGrpList[globalMaskIndex].priv_mask) == 0); } else { /* in this case, we should be able to do this with impunity, anyway */ lockfRtn = lockf(dp->lock_fd, F_LOCK, 0); } opr_Assert(lockfRtn != -1); #else #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) opr_Verify(lockf(dp->lock_fd, F_LOCK, 0) != -1); #else opr_Verify(flock(dp->lock_fd, LOCK_EX) == 0); #endif /* defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) */ #endif }
static void InitServerLogMutex(void) { opr_Verify(pthread_mutex_init(&serverLogMutex, NULL) == 0); }
static void afs_random_once(void) { opr_Verify(pthread_key_create(&random_number_key, NULL) == 0); called_afs_random_once = 1; }
void Afs_Lock_Obtain(struct Lock *lock, int how) { switch (how) { case READ_LOCK: lock->num_waiting++; do { lock->wait_states |= READ_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->read_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->readers_reading); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked & WRITE_LOCK); lock->num_waiting--; lock->readers_reading++; break; case WRITE_LOCK: lock->num_waiting++; do { lock->wait_states |= WRITE_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked || lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; case SHARED_LOCK: lock->num_waiting++; do { lock->wait_states |= SHARED_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked); lock->num_waiting--; lock->excl_locked = SHARED_LOCK; break; case BOOSTED_LOCK: lock->num_waiting++; do { lock->wait_states |= WRITE_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; default: printf("Can't happen, bad LOCK type: %d\n", how); opr_Assert(0); } }
void afsd_mount_afs(const char *rn, const char *cacheMountDir) { int mountFlags; /*Flags passed to mount() */ char *mountDir; /* For HandleMTab() */ mountFlags = 0; /* Read/write file system, can do setuid() */ #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV) #ifdef AFS_SUN5_ENV mountFlags |= MS_DATA; #else mountFlags |= M_NEWTYPE; /* This searches by name in vfs_conf.c so don't need to recompile vfs.c because MOUNT_MAXTYPE has changed; it seems that Sun fixed this at last... */ #endif #endif #if defined(AFS_HPUX100_ENV) mountFlags |= MS_DATA; #endif if (afsd_verbose) printf("%s: Mounting the AFS root on '%s', flags: %d.\n", rn, cacheMountDir, mountFlags); #if defined(AFS_FBSD60_ENV) /* data must be non-NULL but is otherwise ignored */ if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, rn)) < 0) { #elif defined(AFS_FBSD_ENV) if ((mount("AFS", cacheMountDir, mountFlags, (caddr_t) 0)) < 0) { #elif defined(AFS_AIX_ENV) if (aix_vmount(cacheMountDir)) { #elif defined(AFS_HPUX100_ENV) if ((mount("", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) { #elif defined(AFS_SUN5_ENV) if ((mount("AFS", cacheMountDir, mountFlags, "afs", NULL, 0)) < 0) { #elif defined(AFS_SGI_ENV) mountFlags = MS_FSS; if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) MOUNT_AFS)) < 0) { #elif defined(AFS_LINUX20_ENV) if ((mount("AFS", cacheMountDir, MOUNT_AFS, 0, NULL)) < 0) { #elif defined(AFS_NBSD50_ENV) if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, NULL, 0)) < 0) { #else /* This is the standard mount used by the suns and rts */ if ((mount(MOUNT_AFS, cacheMountDir, mountFlags, (caddr_t) 0)) < 0) { #endif printf("%s: Can't mount AFS on %s(%d)\n", rn, cacheMountDir, errno); exit(1); } mountDir = strdup(cacheMountDir); HandleMTab(mountDir); free(mountDir); } int afsd_fork(int wait, afsd_callback_func cb, void *rock) { int code; code = fork(); if (code == 0) { (*cb) (rock); exit(1); } else { assert(code > 0); if (wait) { opr_Verify(waitpid(code, NULL, 0) != -1); } } return 0; } int afsd_daemon(int nochdir, int noclose) { return daemon(nochdir, noclose); } int afsd_check_mount(const char *rn, const char *mountdir) { struct stat statbuf; if (stat(mountdir, &statbuf)) { printf("%s: Mountpoint %s missing.\n", rn, mountdir); return -1; } else if (!S_ISDIR(statbuf.st_mode)) { printf("%s: Mountpoint %s is not a directory.\n", rn, mountdir); return -1; } return 0; } int main(int argc, char **argv) { int code; afsd_init(); code = afsd_parse(argc, argv); if (code) { return -1; } return afsd_run(); }
int OpenLog(const char *fileName) { /* * This function should allow various libraries that inconsistently * use stdout/stderr to all go to the same place */ int tempfd, isfifo = 0; char oldName[MAXPATHLEN]; struct timeval Start; struct tm *TimeFields; char FileName[MAXPATHLEN]; #ifndef AFS_NT40_ENV struct stat statbuf; if (serverLogSyslog) { openlog(serverLogSyslogTag, LOG_PID, serverLogSyslogFacility); return (0); } /* Support named pipes as logs by not rotating them */ if ((lstat(fileName, &statbuf) == 0) && (S_ISFIFO(statbuf.st_mode))) { isfifo = 1; } #endif if (mrafsStyleLogs) { time_t t; struct stat buf; gettimeofday(&Start, NULL); t = Start.tv_sec; TimeFields = localtime(&t); if (fileName) { if (strncmp(fileName, (char *)&ourName, strlen(fileName))) strcpy((char *)&ourName, (char *)fileName); } makefilename: snprintf(FileName, MAXPATHLEN, "%s.%d%02d%02d%02d%02d%02d", ourName, TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday, TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec); if(lstat(FileName, &buf) == 0) { /* avoid clobbering a log */ TimeFields->tm_sec++; goto makefilename; } if (!isfifo) rk_rename(fileName, FileName); /* don't check error code */ tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | (isfifo?O_NONBLOCK:0), 0666); } else { strcpy(oldName, fileName); strcat(oldName, ".old"); /* don't check error */ if (!isfifo) rk_rename(fileName, oldName); tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND | (isfifo?O_NONBLOCK:0), 0666); } if (tempfd < 0) { printf("Unable to open log file %s\n", fileName); return -1; } /* redirect stdout and stderr so random printf's don't write to data */ if (freopen(fileName, "a", stdout) == NULL) ; /* don't care */ if (freopen(fileName, "a", stderr) != NULL) { #ifdef HAVE_SETVBUF setvbuf(stderr, NULL, _IONBF, 0); #else setbuf(stderr, NULL); #endif } #if defined(AFS_PTHREAD_ENV) opr_Verify(pthread_mutex_init(&serverLogMutex, NULL) == 0); #endif /* AFS_PTHREAD_ENV */ serverLogFD = tempfd; return 0; } /*OpenLog */
static void SalvageServer(int argc, char **argv) { int pid, ret; struct SalvageQueueNode * node; pthread_t tid; pthread_attr_t attrs; int slot; VolumePackageOptions opts; /* All entries to the log will be appended. Useful if there are * multiple salvagers appending to the log. */ CheckLogFile((char *)AFSDIR_SERVER_SALSRVLOG_FILEPATH); #ifndef AFS_NT40_ENV #ifdef AFS_LINUX20_ENV fcntl(fileno(logFile), F_SETFL, O_APPEND); /* Isn't this redundant? */ #else fcntl(fileno(logFile), F_SETFL, FAPPEND); /* Isn't this redundant? */ #endif #endif setlinebuf(logFile); fprintf(logFile, "%s\n", cml_version_number); LogCommandLine(argc, argv, "Online Salvage Server", SalvageVersion, "Starting OpenAFS", Log); /* Get and hold a lock for the duration of the salvage to make sure * that no other salvage runs at the same time. The routine * VInitVolumePackage2 (called below) makes sure that a file server or * other volume utilities don't interfere with the salvage. */ /* even demand attach online salvager * still needs this because we don't want * a stand-alone salvager to conflict with * the salvager daemon */ ObtainSharedSalvageLock(); child_slot = calloc(Parallel, sizeof(int)); opr_Assert(child_slot != NULL); /* initialize things */ VOptDefaults(salvageServer, &opts); if (VInitVolumePackage2(salvageServer, &opts)) { Log("Shutting down: errors encountered initializing volume package\n"); Exit(1); } DInit(10); queue_Init(&pending_q); queue_Init(&log_cleanup_queue); MUTEX_INIT(&worker_lock, "worker", MUTEX_DEFAULT, 0); CV_INIT(&worker_cv, "worker", CV_DEFAULT, 0); CV_INIT(&log_cleanup_queue.queue_change_cv, "queuechange", CV_DEFAULT, 0); opr_Verify(pthread_attr_init(&attrs) == 0); /* start up the reaper and log cleaner threads */ opr_Verify(pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED) == 0); opr_Verify(pthread_create(&tid, &attrs, &SalvageChildReaperThread, NULL) == 0); opr_Verify(pthread_create(&tid, &attrs, &SalvageLogCleanupThread, NULL) == 0); opr_Verify(pthread_create(&tid, &attrs, &SalvageLogScanningThread, NULL) == 0); /* loop forever serving requests */ while (1) { node = SALVSYNC_getWork(); opr_Assert(node != NULL); Log("dispatching child to salvage volume %u...\n", node->command.sop.parent); VOL_LOCK; /* find a slot */ for (slot = 0; slot < Parallel; slot++) { if (!child_slot[slot]) break; } opr_Assert (slot < Parallel); do_fork: pid = Fork(); if (pid == 0) { VOL_UNLOCK; ret = DoSalvageVolume(node, slot); Exit(ret); } else if (pid < 0) { Log("failed to fork child worker process\n"); sleep(1); goto do_fork; } else { child_slot[slot] = pid; node->pid = pid; VOL_UNLOCK; MUTEX_ENTER(&worker_lock); current_workers++; /* let the reaper thread know another worker was spawned */ CV_BROADCAST(&worker_cv); /* if we're overquota, wait for the reaper */ while (current_workers >= Parallel) { CV_WAIT(&worker_cv, &worker_lock); } MUTEX_EXIT(&worker_lock); } } }
static void et_mutex_once(void) { opr_Verify(!pthread_mutex_init(&et_list_mutex, NULL)); et_list_done = 1; }
int main(int argc, char **argv) { afs_int32 code; struct rx_securityClass **securityClasses; afs_int32 numClasses; struct rx_service *service; int rxpackets = 100; char hoststr[16]; afs_uint32 host = ntohl(INADDR_ANY); VolumePackageOptions opts; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ 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 osi_audit_init(); osi_audit(VS_StartEvent, 0, AUD_END); /* 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); } configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH); if (ParseArgs(argc, argv)) { exit(1); } if (auditFileName) { osi_audit_file(auditFileName); osi_audit(VS_StartEvent, 0, AUD_END); } #ifdef AFS_SGI_VNODE_GLUE if (afs_init_kernel_config(-1) < 0) { printf ("Can't determine NUMA configuration, not starting volserver.\n"); exit(1); } #endif InitErrTabs(); #ifdef AFS_PTHREAD_ENV SetLogThreadNumProgram( rx_GetThreadNum ); #endif #ifdef AFS_NT40_ENV if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); printf("Volume server unable to start winsock, exiting.\n"); exit(1); } #endif OpenLog(&logopts); VOptDefaults(volumeServer, &opts); if (VInitVolumePackage2(volumeServer, &opts)) { Log("Shutting down: errors encountered initializing volume package\n"); exit(1); } /* For nuke() */ Lock_Init(&localLock); DInit(40); #ifndef AFS_PTHREAD_ENV vol_PollProc = IOMGR_Poll; /* tell vol pkg to poll io system periodically */ #endif #if !defined( AFS_NT40_ENV ) && !defined(AFS_DARWIN160_ENV) rxi_syscallp = volser_syscall; #endif rx_nPackets = rxpackets; /* set the max number of packets */ if (udpBufSize) rx_SetUdpBufSize(udpBufSize); /* set the UDP buffer size for receive */ if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } Log("Volserver binding rx to %s:%d\n", afs_inet_ntoa_r(host, hoststr), AFSCONF_VOLUMEPORT); code = rx_InitHost(host, (int)htons(AFSCONF_VOLUMEPORT)); if (code) { fprintf(stderr, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n", AFSCONF_VOLUMEPORT); VS_EXIT(1); } if (!rxJumbograms) { /* Don't allow 3.4 vos clients to send jumbograms and we don't send. */ rx_SetNoJumbo(); } if (rxMaxMTU != -1) { if (rx_SetMaxMTU(rxMaxMTU) != 0) { fprintf(stderr, "rxMaxMTU %d is invalid\n", rxMaxMTU); VS_EXIT(1); } } rx_GetIFInfo(); rx_SetRxDeadTime(420); memset(busyFlags, 0, sizeof(busyFlags)); #ifdef AFS_PTHREAD_ENV opr_softsig_Init(); SetupLogSoftSignals(); #else SetupLogSignals(); #endif { #ifdef AFS_PTHREAD_ENV pthread_t tid; pthread_attr_t tattr; opr_Verify(pthread_attr_init(&tattr) == 0); opr_Verify(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0); opr_Verify(pthread_create(&tid, &tattr, BKGLoop, NULL) == 0); #else PROCESS pid; LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid); #endif } /* Create a single security object, in this case the null security object, for unauthenticated connections, which will be used to control security on connections made to this server */ tdir = afsconf_Open(configDir); if (!tdir) { Abort("volser: could not open conf files in %s\n", configDir); AFS_UNREACHED(VS_EXIT(1)); } /* initialize audit user check */ osi_audit_set_user_check(tdir, vol_IsLocalRealmMatch); afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses); if (securityClasses[0] == NULL) Abort("rxnull_NewServerSecurityObject"); service = rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityClasses, numClasses, AFSVolExecuteRequest); if (service == (struct rx_service *)0) Abort("rx_NewService"); rx_SetBeforeProc(service, MyBeforeProc); rx_SetAfterProc(service, MyAfterProc); rx_SetIdleDeadTime(service, 0); /* never timeout */ if (lwps < 4) lwps = 4; rx_SetMaxProcs(service, lwps); #if defined(AFS_XBSD_ENV) rx_SetStackSize(service, (128 * 1024)); #elif defined(AFS_SGI_ENV) rx_SetStackSize(service, (48 * 1024)); #else rx_SetStackSize(service, (32 * 1024)); #endif if (rxkadDisableDotCheck) { code = rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); if (code) { fprintf(stderr, "volser: failed to allow dotted principals: code %d\n", code); VS_EXIT(1); } } service = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); if (service == (struct rx_service *)0) Abort("rx_NewService"); rx_SetMinProcs(service, 2); rx_SetMaxProcs(service, 4); LogCommandLine(argc, argv, "Volserver", VolserVersion, "Starting AFS", Log); if (afsconf_GetLatestKey(tdir, NULL, NULL) == 0) { LogDesWarning(); } /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(vol_rxstat_userok); rx_StartServer(1); /* Donate this process to the server process pool */ osi_audit(VS_FinishEvent, (-1), AUD_END); Abort("StartServer returned?"); AFS_UNREACHED(return 0); }