Example #1
0
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 */
}
Example #2
0
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 */
}
Example #3
0
/*!
 * 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 */
Example #4
0
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;
}
Example #5
0
/* 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 */
    }
}
Example #6
0
/* 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 */
    }
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
0
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
}
Example #10
0
static void
InitServerLogMutex(void)
{
    opr_Verify(pthread_mutex_init(&serverLogMutex, NULL) == 0);
}
Example #11
0
static void
afs_random_once(void)
{
    opr_Verify(pthread_key_create(&random_number_key, NULL) == 0);
    called_afs_random_once = 1;
}
Example #12
0
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);
    }
}
Example #13
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();
}
Example #14
0
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 */
Example #15
0
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);
	}
    }
}
Example #16
0
static void
et_mutex_once(void)
{
    opr_Verify(!pthread_mutex_init(&et_list_mutex, NULL));
    et_list_done = 1;
}
Example #17
0
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);
}