예제 #1
0
afs_int32
FindByID(struct ubik_trans *at, afs_int32 aid)
{
    /* returns address of entry if found, 0 otherwise */
    afs_int32 code;
    afs_int32 i;
    struct prentry tentry;
    afs_int32 entry;

    if ((aid == PRBADID) || (aid == 0))
        return 0;
    i = IDHash(aid);
    entry = ntohl(cheader.idHash[i]);
    if (entry == 0)
        return entry;
    memset(&tentry, 0, sizeof(tentry));
    code = pr_ReadEntry(at, 0, entry, &tentry);
    if (code != 0)
        return 0;
    if (aid == tentry.id)
        return entry;
    opr_Assert(entry != tentry.nextID);
    entry = tentry.nextID;
    while (entry != 0) {
        memset(&tentry, 0, sizeof(tentry));
        code = pr_ReadEntry(at, 0, entry, &tentry);
        if (code != 0)
            return 0;
        if (aid == tentry.id)
            return entry;
        opr_Assert(entry != tentry.nextID);
        entry = tentry.nextID;
    }
    return 0;
}
예제 #2
0
afs_int32
FindByName(struct ubik_trans *at, char aname[PR_MAXNAMELEN], struct prentry *tentryp)
{
    /* ditto */
    afs_int32 code;
    afs_int32 i;
    afs_int32 entry;

    i = NameHash(aname);
    entry = ntohl(cheader.nameHash[i]);
    if (entry == 0)
        return entry;
    memset(tentryp, 0, sizeof(struct prentry));
    code = pr_ReadEntry(at, 0, entry, tentryp);
    if (code != 0)
        return 0;
    if ((strncmp(aname, tentryp->name, PR_MAXNAMELEN)) == 0)
        return entry;
    opr_Assert(entry != tentryp->nextName);
    entry = tentryp->nextName;
    while (entry != 0) {
        memset(tentryp, 0, sizeof(struct prentry));
        code = pr_ReadEntry(at, 0, entry, tentryp);
        if (code != 0)
            return 0;
        if ((strncmp(aname, tentryp->name, PR_MAXNAMELEN)) == 0)
            return entry;
        opr_Assert(entry != tentryp->nextName);
        entry = tentryp->nextName;
    }
    return 0;
}
예제 #3
0
파일: vutil.c 프로젝트: jblaine/openafs
/**
 * lock a file on disk for the process.
 *
 * @param[in] lf       the struct VLockFile representing the file to lock
 * @param[in] offset   the offset in the file to lock
 * @param[in] locktype READ_LOCK or WRITE_LOCK
 * @param[in] nonblock 0 to wait for conflicting locks to clear before
 *                     obtaining the lock; 1 to fail immediately if a
 *                     conflicting lock is held by someone else
 *
 * @return operation status
 *  @retval 0 success
 *  @retval EBUSY someone else is holding a conflicting lock and nonblock=1 was
 *                specified
 *  @retval EIO   error acquiring file lock
 *
 * @note DAFS only
 *
 * @note do not try to lock/unlock the same offset in the same file from
 * different threads; use VGetDiskLock to protect threads from each other in
 * addition to other processes
 */
int
VLockFileLock(struct VLockFile *lf, afs_uint32 offset, int locktype, int nonblock)
{
    int code;

    opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);

    opr_mutex_enter(&lf->mutex);

    if (lf->fd == INVALID_FD) {
	lf->fd = _VOpenPath(lf->path);
	if (lf->fd == INVALID_FD) {
	    opr_mutex_exit(&lf->mutex);
	    return EIO;
	}
    }

    lf->refcount++;

    opr_mutex_exit(&lf->mutex);

    code = _VLockFd(lf->fd, offset, locktype, nonblock);

    if (code) {
	opr_mutex_enter(&lf->mutex);
	if (--lf->refcount < 1) {
	    _VCloseFd(lf->fd);
	    lf->fd = INVALID_FD;
	}
	opr_mutex_exit(&lf->mutex);
    }

    return code;
}
예제 #4
0
파일: recovery.c 프로젝트: vkamra/openafs
/*!
 * \brief send a Probe to all the network address of this server
 *
 * \return 0 if success, else return 1
 */
int
DoProbe(struct ubik_server *server)
{
    struct rx_connection *conns[UBIK_MAX_INTERFACE_ADDR];
    struct rx_connection *connSuccess = 0;
    int i, j, success_i = -1;
    afs_uint32 addr;
    char buffer[32];
    char hoststr[16];

    UBIK_ADDR_LOCK;
    for (i = 0; (addr = server->addr[i]) && (i < UBIK_MAX_INTERFACE_ADDR);
	 i++) {
	conns[i] =
	    rx_NewConnection(addr, ubik_callPortal, DISK_SERVICE_ID,
			     addr_globals.ubikSecClass, addr_globals.ubikSecIndex);

	/* user requirement to use only the primary interface */
	if (ubikPrimaryAddrOnly) {
	    i = 1;
	    break;
	}
    }
    UBIK_ADDR_UNLOCK;
    opr_Assert(i);			/* at least one interface address for this server */

    multi_Rx(conns, i) {
	multi_DISK_Probe();
	if (!multi_error) {	/* first success */
	    success_i = multi_i;

	    multi_Abort;
	}
    } multi_End_Ignore;
예제 #5
0
파일: casestrcpy.c 프로젝트: bagdxk/openafs
/* strcompose - concatenate strings passed to it.
 * Input:
 *   buf: storage for the composed string. Any data in it will be lost.
 *   len: length of the buffer.
 *   ...: variable number of string arguments. The last argument must be
 *        (char *)NULL.
 * Returns buf or NULL if the buffer was not sufficiently large.
 */
char *
strcompose(char *buf, size_t len, ...)
{
    va_list ap;
    size_t spaceleft = len - 1;
    char *str;
    size_t slen;

    opr_Assert(buf != NULL);
    if (len <= 0)
	return NULL;

    *buf = '\0';
    va_start(ap, len);
    str = va_arg(ap, char *);
    while (str) {
	slen = strlen(str);
	if (spaceleft < slen)	/* not enough space left */
	    return NULL;

	strcat(buf, str);
	spaceleft -= slen;

	str = va_arg(ap, char *);
    }
    va_end(ap);

    return buf;
}
예제 #6
0
void
LogCommandLine(int argc, char **argv, const char *progname,
	       const char *version, const char *logstring,
	       void (*log) (const char *format, ...))
{
    int i, l;
    char *commandLine, *cx;

    opr_Assert(argc != 0);

    for (l = i = 0; i < argc; i++)
	l += strlen(argv[i]) + 1;
    if ((commandLine = malloc(l))) {
	for (cx = commandLine, i = 0; i < argc; i++) {
	    strcpy(cx, argv[i]);
	    cx += strlen(cx);
	    *(cx++) = ' ';
	}
	commandLine[l-1] = '\0';
	(*log)("%s %s %s%s(%s)\n", logstring, progname,
		    version, strlen(version)>0?" ":"", commandLine);
	free(commandLine);
    } else {
	/* What, we're out of memory already!? */
	(*log)("%s %s%s%s\n", logstring,
	      progname, strlen(version)>0?" ":"", version);
    }
}
예제 #7
0
파일: serverLog.c 프로젝트: bagdxk/openafs
/*!
 * 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 */
예제 #8
0
파일: vutil.c 프로젝트: jblaine/openafs
/**
 * initialize a struct VDiskLock.
 *
 * @param[in] dl struct VDiskLock to initialize
 * @param[in] lf the struct VLockFile to associate with this disk lock
 */
void
VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf, afs_uint32 offset)
{
    opr_Assert(lf);
    memset(dl, 0, sizeof(*dl));
    Lock_Init(&dl->rwlock);
    opr_mutex_init(&dl->mutex);
    opr_cv_init(&dl->cv);
    dl->lockfile = lf;
    dl->offset = offset;
}
예제 #9
0
파일: vutil.c 프로젝트: vkamra/openafs
/**
 * initialize a struct VDiskLock.
 *
 * @param[in] dl struct VDiskLock to initialize
 * @param[in] lf the struct VLockFile to associate with this disk lock
 */
void
VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf, afs_uint32 offset)
{
    opr_Assert(lf);
    memset(dl, 0, sizeof(*dl));
    Lock_Init(&dl->rwlock);
    MUTEX_INIT(&dl->mutex, "disklock", MUTEX_DEFAULT, 0);
    CV_INIT(&dl->cv, "disklock cv", CV_DEFAULT, 0);
    dl->lockfile = lf;
    dl->offset = offset;
}
예제 #10
0
파일: softsig.c 프로젝트: haught/openafs
void
softsig_init(void)
{
    int rc;
    AFS_SIGSET_DECL;
    AFS_SIGSET_CLEAR();
    rc = pthread_create(&softsig_tid, NULL, &softsig_thread, NULL);
    opr_Assert(0 == rc);
    AFS_SIGSET_RESTORE();
    signal (SIGUSR1, softsig_usr1);
}
예제 #11
0
파일: serverLog.c 프로젝트: bagdxk/openafs
/*!
 * Open the log file.
 *
 * Open the log file using the options given in OpenLog().
 *
 * \returns 0 on success
 */
static int
OpenLogFile(const char *fileName)
{
    /*
     * This function should allow various libraries that inconsistently
     * use stdout/stderr to all go to the same place
     */
    int tempfd;
    int flags = O_WRONLY | O_CREAT | O_APPEND;

    opr_Assert(serverLogOpts.dest == logDest_file);

    opr_Assert(fileName != NULL);

    if (IsFIFO(fileName)) {
	/* Support named pipes as logs by not rotating them. */
	flags |= O_NONBLOCK;
    } else if (serverLogOpts.lopt_rotateOnOpen) {
	/* Old style logging always started a new log file. */
	flags |= O_TRUNC;
	RenameLogFile(fileName);
    }

    tempfd = open(fileName, flags, 0666);
    if (tempfd < 0) {
	printf("Unable to open log file %s\n", fileName);
	return -1;
    }
    RedirectStdStreams(fileName);

    /* Save our name for reopening. */
    free(ourName);
    ourName = strdup(fileName);
    opr_Assert(ourName != NULL);

    serverLogFD = tempfd;

    return 0;
}
예제 #12
0
afs_int32
RemoveFromIDHash(struct ubik_trans *tt, afs_int32 aid, afs_int32 *loc)		/* ??? in case ID hashed twice ??? */
{
    /* remove entry designated by aid from id hash table */
    afs_int32 code;
    afs_int32 current, trail, i;
    struct prentry tentry;
    struct prentry bentry;

    if ((aid == PRBADID) || (aid == 0))
        return PRINCONSISTENT;
    i = IDHash(aid);
    current = ntohl(cheader.idHash[i]);
    memset(&tentry, 0, sizeof(tentry));
    memset(&bentry, 0, sizeof(bentry));
    trail = 0;
    if (current == 0)
        return PRSUCCESS;	/* already gone */
    code = pr_ReadEntry(tt, 0, current, &tentry);
    if (code)
        return PRDBFAIL;
    while (aid != tentry.id) {
        opr_Assert(trail != current);
        trail = current;
        current = tentry.nextID;
        if (current == 0)
            break;
        code = pr_ReadEntry(tt, 0, current, &tentry);
        if (code)
            return PRDBFAIL;
    }
    if (current == 0)
        return PRSUCCESS;	/* we didn't find him, so he's already gone */
    if (trail == 0) {
        /* it's the first entry! */
        cheader.idHash[i] = htonl(tentry.nextID);
        code =
            pr_Write(tt, 0, 72 + HASHSIZE * 4 + i * 4,
                     (char *)&cheader.idHash[i], sizeof(cheader.idHash[i]));
        if (code)
            return PRDBFAIL;
    } else {
        code = pr_ReadEntry(tt, 0, trail, &bentry);
        if (code)
            return PRDBFAIL;
        bentry.nextID = tentry.nextID;
        code = pr_WriteEntry(tt, 0, trail, &bentry);
    }
    *loc = current;
    return PRSUCCESS;
}
예제 #13
0
static void *
SalvageChildReaperThread(void * args)
{
    int slot, pid, status;
    struct log_cleanup_node * cleanup;

    MUTEX_ENTER(&worker_lock);

    /* loop reaping our children */
    while (1) {
	/* wait() won't block unless we have children, so
	 * block on the cond var if we're childless */
	while (current_workers == 0) {
	    CV_WAIT(&worker_cv, &worker_lock);
	}

	MUTEX_EXIT(&worker_lock);

	cleanup = malloc(sizeof(struct log_cleanup_node));

	while (Reap_Child("salvageserver", &pid, &status) < 0) {
	    /* try to prevent livelock if something goes wrong */
	    sleep(1);
	}

	VOL_LOCK;
	for (slot = 0; slot < Parallel; slot++) {
	    if (child_slot[slot] == pid)
		break;
	}
	opr_Assert(slot < Parallel);
	child_slot[slot] = 0;
	VOL_UNLOCK;

	SALVSYNC_doneWorkByPid(pid, status);

	MUTEX_ENTER(&worker_lock);

	if (cleanup) {
	    cleanup->pid = pid;
	    queue_Append(&log_cleanup_queue, cleanup);
	    CV_SIGNAL(&log_cleanup_queue.queue_change_cv);
	}

	/* ok, we've reaped a child */
	current_workers--;
	CV_BROADCAST(&worker_cv);
    }

    return NULL;
}
예제 #14
0
파일: vutil.c 프로젝트: jblaine/openafs
/**
 * release a lock on a file on local disk.
 *
 * @param[in] dl the struct VDiskLock to release
 * @param[in] locktype READ_LOCK if you are unlocking a read lock, or
 *                     WRITE_LOCK if you are unlocking a write lock
 *
 * @return operation status
 *  @retval 0 success
 */
void
VReleaseDiskLock(struct VDiskLock *dl, int locktype)
{
    opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);

    opr_mutex_enter(&dl->mutex);
    opr_Assert(dl->lockers > 0);

    if (--dl->lockers < 1) {
	/* no threads are holding this lock anymore, so we can release the
	 * actual disk lock */
	VLockFileUnlock(dl->lockfile, dl->offset);
	dl->flags &= ~VDISKLOCK_ACQUIRED;
    }

    opr_mutex_exit(&dl->mutex);

    if (locktype == READ_LOCK) {
	ReleaseReadLock(&dl->rwlock);
    } else {
	ReleaseWriteLock(&dl->rwlock);
    }
}
예제 #15
0
파일: partition.c 프로젝트: openafs/openafs
struct DiskPartition64 *
VGetPartitionById_r(afs_int32 id, int abortp)
{
    struct DiskPartition64 *dp = NULL;

    if ((id >= 0) && (id <= VOLMAXPARTS)) {
	dp = DiskPartitionTable[id];
    }

    if (abortp) {
	opr_Assert(dp != NULL);
    }
    return dp;
}
예제 #16
0
afs_int32
RemoveFromNameHash(struct ubik_trans *tt, char *aname, afs_int32 *loc)
{
    /* remove from name hash */
    afs_int32 code;
    afs_int32 current, trail, i;
    struct prentry tentry;
    struct prentry bentry;

    i = NameHash(aname);
    current = ntohl(cheader.nameHash[i]);
    memset(&tentry, 0, sizeof(tentry));
    memset(&bentry, 0, sizeof(bentry));
    trail = 0;
    if (current == 0)
        return PRSUCCESS;	/* already gone */
    code = pr_ReadEntry(tt, 0, current, &tentry);
    if (code)
        return PRDBFAIL;
    while (strcmp(aname, tentry.name)) {
        opr_Assert(trail != current);
        trail = current;
        current = tentry.nextName;
        if (current == 0)
            break;
        code = pr_ReadEntry(tt, 0, current, &tentry);
        if (code)
            return PRDBFAIL;
    }
    if (current == 0)
        return PRSUCCESS;	/* we didn't find him, already gone */
    if (trail == 0) {
        /* it's the first entry! */
        cheader.nameHash[i] = htonl(tentry.nextName);
        code =
            pr_Write(tt, 0, 72 + i * 4, (char *)&cheader.nameHash[i],
                     sizeof(cheader.nameHash[i]));
        if (code)
            return PRDBFAIL;
    } else {
        code = pr_ReadEntry(tt, 0, trail, &bentry);
        if (code)
            return PRDBFAIL;
        bentry.nextName = tentry.nextName;
        code = pr_WriteEntry(tt, 0, trail, &bentry);
    }
    *loc = current;
    return PRSUCCESS;
}
예제 #17
0
파일: partition.c 프로젝트: openafs/openafs
void
VLockPartition_r(char *name)
{
    struct DiskPartition64 *dp = VGetPartition_r(name, 0);
    OVERLAPPED lap;

    if (!dp)
	return;
    if (dp->lock_fd == INVALID_FD) {
	char path[64];
	int rc;
	(void)sprintf(path, "%s\\%s", VPartitionPath(dp), LOCKFILE);
	dp->lock_fd =
	    (FD_t)CreateFile(path, GENERIC_WRITE,
			    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			    CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
	opr_Assert(dp->lock_fd != INVALID_FD);

	memset(&lap, 0, sizeof(lap));
	rc = LockFileEx((HANDLE) dp->lock_fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1,
			0, &lap);
	opr_Assert(rc);
    }
}
예제 #18
0
파일: vutil.c 프로젝트: jblaine/openafs
void
VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset)
{
    opr_mutex_enter(&lf->mutex);

    opr_Assert(lf->fd != INVALID_FD);

    if (--lf->refcount < 1) {
	_VCloseFd(lf->fd);
	lf->fd = INVALID_FD;
    } else {
	_VUnlockFd(lf->fd, offset);
    }

    opr_mutex_exit(&lf->mutex);
}
예제 #19
0
파일: partition.c 프로젝트: openafs/openafs
/* get partition structure, abortp tells us if we should abort on failure */
struct DiskPartition64 *
VGetPartition_r(char *name, int abortp)
{
    struct DiskPartition64 *dp;
#ifdef AFS_DEMAND_ATTACH_FS
    dp = VLookupPartition_r(name);
#else /* AFS_DEMAND_ATTACH_FS */
    for (dp = DiskPartitionList; dp; dp = dp->next) {
	if (strcmp(dp->name, name) == 0)
	    break;
    }
#endif /* AFS_DEMAND_ATTACH_FS */
    if (abortp)
	opr_Assert(dp != NULL);
    return dp;
}
예제 #20
0
파일: vutil.c 프로젝트: vkamra/openafs
void
VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset)
{
    MUTEX_ENTER(&lf->mutex);

    opr_Assert(lf->fd != INVALID_FD);

    if (--lf->refcount < 1) {
	_VCloseFd(lf->fd);
	lf->fd = INVALID_FD;
    } else {
	_VUnlockFd(lf->fd, offset);
    }

    MUTEX_EXIT(&lf->mutex);
}
예제 #21
0
/*
 * Given two arrays of addresses, masks and mtus find the common ones
 * and return them in the first buffer. Return number of common
 * entries.
 */
static int
filterAddrs(afs_uint32 addr1[], afs_uint32 addr2[], afs_uint32 mask1[],
            afs_uint32 mask2[], afs_uint32 mtu1[], afs_uint32 mtu2[], int n1,
            int n2)
{
    afs_uint32 taddr[MAXIPADDRS];
    afs_uint32 tmask[MAXIPADDRS];
    afs_uint32 tmtu[MAXIPADDRS];
    int count = 0, i = 0, j = 0, found = 0;

    opr_Assert(addr1);
    opr_Assert(addr2);
    opr_Assert(mask1);
    opr_Assert(mask2);
    opr_Assert(mtu1);
    opr_Assert(mtu2);

    for (i = 0; i < n1; i++) {
        found = 0;
        for (j = 0; j < n2; j++) {
            if (addr1[i] == addr2[j]) {
                found = 1;
                break;
            }
        }

        /* Always mask loopback address */
        if (found && rx_IsLoopbackAddr(addr1[i]))
            found = 0;

        if (found) {
            taddr[count] = addr1[i];
            tmask[count] = mask1[i];
            tmtu[count] = mtu1[i];
            count++;
        }
    }
    /* copy everything into addr1, mask1 and mtu1 */
    for (i = 0; i < count; i++) {
        addr1[i] = taddr[i];
        if (mask1) {
            mask1[i] = tmask[i];
            mtu1[i] = tmtu[i];
        }
    }
    /* and zero out the rest */
    for (i = count; i < n1; i++) {
        addr1[i] = 0;
        if (mask1) {
            mask1[i] = 0;
            mtu1[i] = 0;
        }
    }
    return count;
}
예제 #22
0
파일: serverLog.c 프로젝트: bagdxk/openafs
/*!
 * Move the current log file out of the way so a new one can be started.
 *
 * The format of the new name depends on the logging style.  The traditional
 * Transarc style appends ".old" to the log file name.  When MR-AFS style
 * logging is in effect, a time stamp is appended to the log file name instead
 * of ".old".
 *
 * \bug  Unfortunately, no check is made to avoid overwriting
 *       old logs in the traditional Transarc mode.
 *
 * \param fileName  fully qualified log file path
 */
static void
RenameLogFile(const char *fileName)
{
    int code;
    char *nextName = NULL;
    int tries;
    time_t t;
    struct stat buf;
    struct tm *timeFields;

    switch (serverLogOpts.lopt_rotateStyle) {
    case logRotate_none:
	break;
    case logRotate_old:
	code = asprintf(&nextName, "%s.old", fileName);
	if (code < 0) {
	    nextName = NULL;
	}
	break;
    case logRotate_timestamp:
	time(&t);
	for (tries = 0; nextName == NULL && tries < 100; t++, tries++) {
	    timeFields = localtime(&t);
	    code = asprintf(&nextName, "%s.%d%02d%02d%02d%02d%02d",
			    fileName, timeFields->tm_year + 1900,
			    timeFields->tm_mon + 1, timeFields->tm_mday,
			    timeFields->tm_hour, timeFields->tm_min,
			    timeFields->tm_sec);
	    if (code < 0) {
		nextName = NULL;
		break;
	    }
	    if (lstat(nextName, &buf) == 0) {
		/* Avoid clobbering a log. */
		free(nextName);
		nextName = NULL;
	    }
	}
	break;
    default:
	opr_Assert(0);
    }
    if (nextName != NULL) {
	rk_rename(fileName, nextName);	/* Don't check the error code. */
	free(nextName);
    }
}
예제 #23
0
파일: casestrcpy.c 프로젝트: bagdxk/openafs
char *
ucstring(char *d, const char *s, int n)
{
    char *original_d = d;
    char c;

    opr_Assert(s != NULL && d != NULL);
    while (n) {
	c = *s++;
	if (islower(c))
	    c = toupper(c);
	*d++ = c;
	if (c == 0)
	    break;
	if (--n == 0)
	    *(d - 1) = 0;	/* make sure null terminated */
    }
    return original_d;
}
예제 #24
0
static int
common_volop_prolog(struct cmd_syndesc * as, struct fssync_state * state)
{
    struct cmd_item *ti;

    state->vop = (struct volop_state *) calloc(1, sizeof(struct volop_state));
    opr_Assert(state->vop != NULL);

    if ((ti = as->parms[COMMON_VOLOP_PARMS_OFFSET].items)) {	/* -volumeid */
	state->vop->volume = atoi(ti->data);
    } else {
	fprintf(stderr, "required argument -volumeid not given\n");
    }

    if ((ti = as->parms[COMMON_VOLOP_PARMS_OFFSET+1].items)) {	/* -partition */
	strlcpy(state->vop->partName, ti->data, sizeof(state->vop->partName));
    } else {
	memset(state->vop->partName, 0, sizeof(state->vop->partName));
    }

    return 0;
}
예제 #25
0
파일: vutil.c 프로젝트: jblaine/openafs
/**
 * acquire a lock on a file on local disk.
 *
 * @param[in] dl       the VDiskLock structure corresponding to the file on disk
 * @param[in] locktype READ_LOCK if you want a read lock, or WRITE_LOCK if
 *                     you want a write lock
 * @param[in] nonblock 0 to wait for conflicting locks to clear before
 *                     obtaining the lock; 1 to fail immediately if a
 *                     conflicting lock is held by someone else
 *
 * @return operation status
 *  @retval 0 success
 *  @retval EBUSY someone else is holding a conflicting lock and nonblock=1 was
 *                specified
 *  @retval EIO   error acquiring file lock
 *
 * @note DAFS only
 *
 * @note while normal fcntl-y locks on Unix systems generally only work per-
 * process, this interface also deals with locks between threads in the
 * process in addition to different processes acquiring the lock
 */
int
VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock)
{
    int code = 0;
    opr_Assert(locktype == READ_LOCK || locktype == WRITE_LOCK);

    if (nonblock) {
	if (locktype == READ_LOCK) {
	    ObtainReadLockNoBlock(&dl->rwlock, code);
	} else {
	    ObtainWriteLockNoBlock(&dl->rwlock, code);
	}

	if (code) {
	    return EBUSY;
	}

    } else if (locktype == READ_LOCK) {
	ObtainReadLock(&dl->rwlock);
    } else {
	ObtainWriteLock(&dl->rwlock);
    }

    opr_mutex_enter(&dl->mutex);

    if ((dl->flags & VDISKLOCK_ACQUIRING)) {
	/* Some other thread is waiting to acquire an fs lock. If nonblock=1,
	 * we can return immediately, since we know we'll need to wait to
	 * acquire. Otherwise, wait for the other thread to finish acquiring
	 * the fs lock */
	if (nonblock) {
	    code = EBUSY;
	} else {
	    while ((dl->flags & VDISKLOCK_ACQUIRING)) {
		opr_cv_wait(&dl->cv, &dl->mutex);
	    }
	}
    }

    if (code == 0 && !(dl->flags & VDISKLOCK_ACQUIRED)) {
	/* no other thread holds the lock on the actual file; so grab one */

	/* first try, don't block on the lock to see if we can get it without
	 * waiting */
	code = VLockFileLock(dl->lockfile, dl->offset, locktype, 1);

	if (code == EBUSY && !nonblock) {

	    /* mark that we are waiting on the fs lock */
	    dl->flags |= VDISKLOCK_ACQUIRING;

	    opr_mutex_exit(&dl->mutex);
	    code = VLockFileLock(dl->lockfile, dl->offset, locktype, nonblock);
	    opr_mutex_enter(&dl->mutex);

	    dl->flags &= ~VDISKLOCK_ACQUIRING;

	    if (code == 0) {
		dl->flags |= VDISKLOCK_ACQUIRED;
	    }

	    opr_cv_broadcast(&dl->cv);
	}
    }

    if (code) {
	if (locktype == READ_LOCK) {
	    ReleaseReadLock(&dl->rwlock);
	} else {
	    ReleaseWriteLock(&dl->rwlock);
	}
    } else {
	/* successfully got the lock, so inc the number of unlocks we need
	 * to do before we can unlock the actual file */
	++dl->lockers;
    }

    opr_mutex_exit(&dl->mutex);

    return code;
}
예제 #26
0
/**
 * Get a list of IP addresses for this host allowing only addresses found
 * in the config file (fileName parameter): /usr/vice/etc/NetInfo for
 * clients and /usr/afs/local/NetInfo for servers.
 *
 * All addresses should be in network byte order as returned by
 * rx_getAllAddrMaskMtu() and parsed by extract_Addr().
 *
 * @param[out] outAddrs
 *     All the address that are found to be valid.
 * @param[out] outMask
 *     Associated netmask for interface
 * @param[out] outMtu
 *     Associated MTU for interface
 * @param[in] max
 *     Length of the output above arrays
 * @param[out] reason
 *     Reason for the parsing failure
 * @param[in] fileName
 *     File to parse
 * @param[in] fakeonly
 *     Only return addresses if they are marked as fake
 *
 * @return
 *     The number of valid address on success or < 0 on fatal failure.
 */
static int
ParseNetInfoFile_int(afs_uint32 outAddrs[], afs_uint32 outMask[], afs_uint32 outMtu[],
                     int max, char reason[], const char *fileName,
                     int fakeonly)
{

    afs_uint32 existingAddr[MAXIPADDRS], existingMask[MAXIPADDRS],
               existingMtu[MAXIPADDRS];
    char line[MAX_NETFILE_LINE];
    FILE *fp;
    int i, existNu, count = 0;
    afs_uint32 addr;
    int lineNo = 0;
    int l;

    opr_Assert(fileName);
    opr_Assert(outAddrs);
    opr_Assert(outMask);
    opr_Assert(outMtu);
    opr_Assert(reason);

    /* get all network interfaces from the kernel */
    existNu =
        rx_getAllAddrMaskMtu(existingAddr, existingMask, existingMtu,
                             MAXIPADDRS);
    if (existNu < 0)
        return existNu;

    if ((fp = fopen(fileName, "r")) == 0) {
        /* If file does not exist or is not readable, then
         * use all interface addresses.
         */
        sprintf(reason,
                "Failed to open %s(%s)\nUsing all configured addresses\n",
                fileName, strerror(errno));
        for (i = 0; i < existNu; i++) {
            outAddrs[i] = existingAddr[i];
            outMask[i] = existingMask[i];
            outMtu[i] = existingMtu[i];
        }
        return existNu;
    }

    /* For each line in the NetInfo file */
    while (fgets(line, MAX_NETFILE_LINE, fp) != NULL) {
        int fake = 0;

        /* See if first char is an 'F' for fake */
        /* Added to allow the fileserver to advertise fake IPS for use with
         * the translation tables for NAT-like firewalls - defect 12462 */
        for (fake = 0; ((fake < strlen(line)) && isspace(line[fake]));
                fake++);
        if ((fake < strlen(line))
                && ((line[fake] == 'f') || (line[fake] == 'F'))) {
            fake++;
        } else {
            fake = 0;
        }

        lineNo++;		/* input line number */
        addr = extract_Addr(&line[fake], strlen(&line[fake]));

        if (addr == AFS_IPINVALID) {	/* syntactically invalid */
            fprintf(stderr, "afs:%s : line %d : parse error\n", fileName,
                    lineNo);
            continue;
        }
        if (addr == AFS_IPINVALIDIGNORE) {	/* ignore error */
            continue;
        }

        /* See if it is an address that really exists */
        for (i = 0; i < existNu; i++) {
            if (existingAddr[i] == addr)
                break;
        }
        if ((i >= existNu) && (!fake))
            continue;		/* not found/fake - ignore */

        /* Check if it is a duplicate address we alread have */
        for (l = 0; l < count; l++) {
            if (outAddrs[l] == addr)
                break;
        }
        if (l < count) {
            fprintf(stderr, "afs:%x specified twice in NetInfo file\n",
                    ntohl(addr));
            continue;		/* duplicate addr - ignore */
        }

        if (count > max) {	/* no more space */
            fprintf(stderr,
                    "afs:Too many interfaces. The current kernel configuration supports a maximum of %d interfaces\n",
                    max);
        } else if (fake) {
            if (!fake)
                fprintf(stderr, "Client (2) also has address %s\n", line);
            outAddrs[count] = addr;
            outMask[count] = 0xffffffff;
            outMtu[count] = htonl(1500);
            count++;
        } else if (!fakeonly) {
            outAddrs[count] = existingAddr[i];
            outMask[count] = existingMask[i];
            outMtu[count] = existingMtu[i];
            count++;
        }
    }				/* while */

    /* in case of any error, we use all the interfaces present */
    if (count <= 0) {
        sprintf(reason,
                "Error in reading/parsing Interface file\nUsing all configured interface addresses \n");
        for (i = 0; i < existNu; i++) {
            outAddrs[i] = existingAddr[i];
            outMask[i] = existingMask[i];
            outMtu[i] = existingMtu[i];
        }
        return existNu;
    }
    return count;
}
예제 #27
0
/**
 * Get a list of IP addresses for this host removing any address found
 * in the config file (fileName parameter): /usr/vice/etc/NetRestrict
 * for clients and /usr/afs/local/NetRestrict for servers.
 *
 * Returns the number of valid addresses in outAddrs[] and count in
 * nAddrs.  Returns 0 on success; or 1 if the config file was not
 * there or empty (we still return the host's IP addresses). Returns
 * -1 on fatal failure with reason in the reason argument (so the
 * caller can choose to ignore the entire file but should write
 * something to a log file).
 *
 * All addresses should be in network byte order as returned by
 * rx_getAllAddrMaskMtu() and parsed by extract_Addr().
 *
 * @param[out] outAddrs
 *     All the address that are found to be valid.
 * @param[out] outMask
 *     Optional associated netmask for address
 * @param[out] outMtu
 *     Optional associated MTU for address
 * @param[in] maxAddres
 *     Length of the above output arrays
 * @param[out] nAddrs
 *     Count of valid addresses
 * @param[out] reason
 *     Reason (if any) for the parsing failure
 * @param[in] fileName
 *     Configuration file to parse
 *
 * @return
 *     0 on success; 1 if the config file was not used; -1 on
 *     fatal failure.
 */
static int
parseNetRestrictFile_int(afs_uint32 outAddrs[], afs_uint32 outMask[],
                         afs_uint32 outMtu[], afs_uint32 maxAddrs,
                         afs_uint32 *nAddrs, char reason[],
                         const char *fileName, const char *fileName_ni)
{
    FILE *fp;
    char line[MAX_NETFILE_LINE];
    int lineNo, usedfile = 0;
    afs_uint32 i, neaddrs, nOutaddrs;
    afs_uint32 addr, eAddrs[MAXIPADDRS], eMask[MAXIPADDRS], eMtu[MAXIPADDRS];

    opr_Assert(outAddrs);
    opr_Assert(reason);
    opr_Assert(fileName);
    opr_Assert(nAddrs);
    if (outMask)
        opr_Assert(outMtu);

    /* Initialize */
    *nAddrs = 0;
    for (i = 0; i < maxAddrs; i++)
        outAddrs[i] = 0;
    strcpy(reason, "");

    /* get all network interfaces from the kernel */
    neaddrs = rx_getAllAddrMaskMtu(eAddrs, eMask, eMtu, MAXIPADDRS);
    if (neaddrs <= 0) {
        sprintf(reason, "No existing IP interfaces found");
        return -1;
    }
    i = 0;
    if ((neaddrs < MAXIPADDRS) && fileName_ni)
        i = ParseNetInfoFile_int(&(eAddrs[neaddrs]), &(eMask[neaddrs]),
                                 &(eMtu[neaddrs]), MAXIPADDRS-neaddrs, reason,
                                 fileName_ni, 1);

    if (i > 0)
        neaddrs += i;

    if ((fp = fopen(fileName, "r")) == 0) {
        sprintf(reason, "Could not open file %s for reading:%s", fileName,
                strerror(errno));
        goto done;
    }

    /* For each line in the NetRestrict file */
    lineNo = 0;
    usedfile = 0;
    while (fgets(line, MAX_NETFILE_LINE, fp) != NULL) {
        lineNo++;		/* input line number */
        addr = extract_Addr(line, strlen(line));
        if (addr == AFS_IPINVALID) {	/* syntactically invalid */
            fprintf(stderr, "%s : line %d : parse error - invalid IP\n",
                    fileName, lineNo);
            continue;
        }
        if (addr == AFS_IPINVALIDIGNORE) {	/* ignore error */
            fprintf(stderr, "%s : line %d : invalid address ... ignoring\n",
                    fileName, lineNo);
            continue;
        }
        usedfile = 1;

        /* Check if we need to exclude this address */
        for (i = 0; i < neaddrs; i++) {
            if (eAddrs[i] && (eAddrs[i] == addr)) {
                eAddrs[i] = 0;	/* Yes - exclude it by zeroing it for now */
            }
        }
    }				/* while */

    fclose(fp);

    if (!usedfile) {
        sprintf(reason, "No valid IP addresses in %s\n", fileName);
        goto done;
    }

done:
    /* Collect the addresses we have left to return */
    nOutaddrs = 0;
    for (i = 0; i < neaddrs; i++) {
        if (!eAddrs[i])
            continue;
        outAddrs[nOutaddrs] = eAddrs[i];
        if (outMask) {
            outMask[nOutaddrs] = eMask[i];
            outMtu[nOutaddrs] = eMtu[i];
        }
        if (++nOutaddrs >= maxAddrs)
            break;
    }
    if (nOutaddrs == 0) {
        sprintf(reason, "No addresses to use after parsing %s", fileName);
        return -1;
    }
    *nAddrs = nOutaddrs;
    return (usedfile ? 0 : 1);	/* 0=>used the file.  1=>didn't use file */
}
예제 #28
0
파일: lock.c 프로젝트: vkamra/openafs
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);
    }
}
예제 #29
0
void
opr_rbtree_remove(struct opr_rbtree *head, struct opr_rbtree_node *node)
{
    struct opr_rbtree_node *child, *parent;
    int red;


    if (node->left == NULL && node->right == NULL) {
	/* A node with no non-leaf children */
	update_parent_ptr(head, node, NULL);

	if (!node->red)
	    remove_recolour(head, node->parent, NULL);

	return;
    }

    if (node->left != NULL && node->right != NULL) {
	/* A node with two children.
	 *
         * Move the next node in the tree (which will be a leaf node)
	 * onto our tree current position, then rebalance as required
	 */
	struct opr_rbtree_node *old, *left;

	old = node;

	/* Set node to the next node in the tree from the current
	 * position, where the next node is the left-most leaf node
	 * in our right child */
	node = node->right;
	while ((left = node->left) != NULL)
	    node = left;

	/* Move 'node' into the position occupied by 'old', which is being
	 * removed */

	update_parent_ptr(head, old, node);

	child = node->right;
	parent = node->parent;
	red = node->red;

	/* As we're logically just copying the value, must preserve the
	 * old node's colour */
	node->red = old->red;

	/* ... and the old node's linkage */
	if (parent == old)
	    parent = node;
	else {
	    if (child)
		child->parent = parent;
	    parent->left = child;

	    node->right = old->right;
	    old->right->parent = node;
	}

	node->parent = old->parent;
	node->left = old->left;
	old->left->parent = node;

	/* If the node being removed was black, then we must recolour the
	 * tree to maintain balance */
	if (!red)
	    remove_recolour(head, parent, child);

	return;
    }

    /* Only remaining option - node with a single child */

    if (node->left == NULL)
        child = node->right;
    else {
	opr_Assert(node->right == NULL);
	child = node->left;
    }

    child->parent = node->parent;

    update_parent_ptr(head, node, child);

    if (!node->red)
	remove_recolour(head, node->parent, child);
}
예제 #30
0
static int
usd_FileOpen(const char *path, int flags, int mode, usd_handle_t * usdP)
{
    int fd;
    int oflags;
    usd_handle_t usd;
    int code;

    if (usdP)
	*usdP = NULL;

    oflags = (flags & USD_OPEN_RDWR) ? O_RDWR : O_RDONLY;

#ifdef O_SYNC			/* AFS_DARWIN_ENV XXX */
    if (flags & USD_OPEN_SYNC)
	oflags |= O_SYNC;
#endif

    if (flags & USD_OPEN_CREATE)
	oflags |= O_CREAT;

#ifdef O_LARGEFILE
    fd = open64(path, oflags | O_LARGEFILE, mode);
#else /* O_LARGEFILE */
    fd = open(path, oflags, mode);
#endif /* O_LARGEFILE */
    if (fd == -1)
	return errno;

    usd = calloc(1, sizeof(*usd));
    usd->handle = (void *)(intptr_t)fd;
    usd->read = usd_FileRead;
    usd->write = usd_FileWrite;
    usd->seek = usd_FileSeek;
    usd->ioctl = usd_FileIoctl;
    usd->close = usd_FileClose;
    usd->fullPathName = strdup(path);
    usd->openFlags = flags;

    code = 0;
    if (flags & (USD_OPEN_RLOCK | USD_OPEN_WLOCK)) {
#ifdef O_LARGEFILE
	struct flock64 fl;
#else /* O_LARGEFILE */
	struct flock fl;
#endif /* O_LARGEFILE */

	/* make sure both lock bits aren't set */
	opr_Assert(~flags & (USD_OPEN_RLOCK | USD_OPEN_WLOCK));

	fl.l_type = ((flags & USD_OPEN_RLOCK) ? F_RDLCK : F_WRLCK);
	fl.l_whence = SEEK_SET;
	fl.l_start = (osi_lloff_t) 0;
	fl.l_len = (osi_lloff_t) 0;	/* whole file */
#ifdef O_LARGEFILE
	code = fcntl(fd, F_SETLK64, &fl);
#else /* O_LARGEFILE */
	code = fcntl(fd, F_SETLK, &fl);
#endif /* O_LARGEFILE */
	if (code == -1)
	    code = errno;

	/* If we're trying to obtain a write lock on a real disk, then the
	 * aggregate must not be attached by the kernel.  If so, unlock it
	 * and fail.
	 * WARNING: The code to check for the above has been removed when this
	 * file was ported from DFS src. It should be put back if
	 * this library is used to access hard disks
	 */
    }

    if (code == 0 && usdP)
	*usdP = usd;
    else
	usd_FileClose(usd);
    return code;
}