Exemplo n.º 1
0
afs_int32
FreeLock(struct rx_call *call, afs_uint32 lockHandle)
{
    db_lockP lockPtr = 0;
    struct ubik_trans *ut;
    afs_int32 code;

    if (callPermitted(call) == 0)
	return (BUDB_NOTPERMITTED);

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	return (code);

    if (checkLockHandle(ut, lockHandle) == 0)
	ABORT(BUDB_BADARGUMENT);

    lockPtr = &db.h.textLocks[lockHandle - 1];

    lockPtr->lockState = 0;	/* unlock it */
    lockPtr->lockTime = 0;
    lockPtr->expires = 0;
    lockPtr->instanceId = 0;
    dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));

    code = ubik_EndTrans(ut);
    return (code);

  abort_exit:
    ubik_AbortTrans(ut);
    return (code);
}
Exemplo n.º 2
0
afs_int32
FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
{
    db_lockP startPtr, endPtr;
    struct ubik_trans *ut;
    afs_int32 code;

    if (callPermitted(call) == 0)
	return (BUDB_NOTPERMITTED);

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	return (code);

    startPtr = &db.h.textLocks[0];
    endPtr = &db.h.textLocks[TB_NUM - 1];
    while (startPtr <= endPtr) {
	if ((ntohl(startPtr->lockState) == 1)
	    && (ntohl(startPtr->instanceId) == instanceId)
	    ) {
	    /* release the lock */
	    startPtr->lockState = 0;	/* unlock it */
	    startPtr->lockTime = 0;
	    startPtr->expires = 0;
	    startPtr->instanceId = 0;
	    dbwrite(ut, DBH_POS(startPtr), (char *)startPtr,
		    sizeof(db_lockT));
	}
	startPtr++;
    }
    code = ubik_EndTrans(ut);
    return (code);
}
Exemplo n.º 3
0
afs_int32
STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
{
    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    tciptr->tcVersion = CUR_BUTC_VERSION;
    return (0);
}
Exemplo n.º 4
0
afs_int32
GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
	afs_int32 expiration, afs_uint32 *lockHandle)
{
    struct timeval tv;
    db_lockP lockPtr;
    struct ubik_trans *ut;

    afs_int32 code;

    if (callPermitted(call) == 0)
	return (BUDB_NOTPERMITTED);

    if ((lockName < 0) || (lockName >= TB_NUM))
	return (BUDB_BADARGUMENT);

    /* get the current time */
    gettimeofday(&tv, 0);

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	return (code);

    lockPtr = &db.h.textLocks[lockName];

    if ((ntohl(lockPtr->lockState) != 0)	/* lock set */
	&&(ntohl(lockPtr->expires) > tv.tv_sec)	/* not expired */
	) {
	if (ntohl(lockPtr->instanceId) == instanceId)
	    code = BUDB_SELFLOCKED;
	else
	    code = BUDB_LOCKED;
	goto abort_exit;
    }

    lockPtr->lockState = htonl(1);	/* lock it */
    lockPtr->lockTime = htonl(tv.tv_sec);	/* when locked */
    lockPtr->expires = htonl(tv.tv_sec + expiration);
    lockPtr->instanceId = htonl(instanceId);
    code = dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
    if (code)
	ABORT(code);

    *lockHandle = (afs_uint32) (lockName + 1);
    code = ubik_EndTrans(ut);
    return (code);

  abort_exit:
    ubik_AbortTrans(ut);
    return (code);
}
Exemplo n.º 5
0
afs_int32
STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
    afs_int32 code;

#ifdef xbsa
    if (CONF_XBSA)
	return (TC_BADTASK);	/* ReadLabel does not apply if XBSA */
#endif

    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    code = ReadLabel(label);	/* Synchronous */
    return code;
}
Exemplo n.º 6
0
afs_int32
GetTextVersion(struct rx_call *call, afs_int32 textType, 
	       afs_uint32 *tversion)
{
    afs_int32 code;
    struct ubik_trans *ut;

    if (callPermitted(call) == 0)
	return (BUDB_NOTPERMITTED);

    if ((textType < 0) || (textType >= TB_NUM))
	return (BUDB_BADARGUMENT);

    code = InitRPC(&ut, LOCKREAD, 1);
    if (code)
	return (code);

    *tversion = ntohl(db.h.textBlock[textType].version);
    code = ubik_EndTrans(ut);
    return (code);
}
Exemplo n.º 7
0
afs_int32
RestoreDbHeader(struct rx_call *call, struct DbHeader *header)
{
    struct ubik_trans *ut = 0;
    afs_int32 code = 0;

    extern struct memoryDB db;

    if (callPermitted(call) == 0)
        ERROR(BUDB_NOTPERMITTED);

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
        goto error_exit;

    if (header->dbversion != ntohl(db.h.version))
        ERROR(BUDB_VERSIONMISMATCH);

    /* merge rather than replace the header information */
    if (db.h.lastDumpId < htonl(header->lastDumpId))
        db.h.lastDumpId = htonl(header->lastDumpId);

    if (db.h.lastTapeId < htonl(header->lastTapeId))
        db.h.lastTapeId = htonl(header->lastTapeId);

    if (db.h.lastInstanceId < htonl(header->lastInstanceId))
        db.h.lastInstanceId = htonl(header->lastInstanceId);

    code = dbwrite(ut, 0, (char *)&db.h, sizeof(db.h));
    if (code)
        code = BUDB_IO;

error_exit:
    if (ut)
        ubik_EndTrans(ut);
    return (code);
}
Exemplo n.º 8
0
afs_int32
STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
{
    struct dumpNode *newNode;
    statusP statusPtr;
    afs_int32 code = 0;
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif

    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    /* should  verify parameter validity */

    /* this creates a node in list, alots an id for it and prepares it for locking */
    CreateNode(&newNode);

    newNode->restores = (struct tc_restoreDesc *)
	malloc(sizeof(struct tc_restoreDesc) *
	       arestores->tc_restoreArray_len);
    newNode->arraySize = arestores->tc_restoreArray_len;
    CopyRestoreDesc(newNode->restores, arestores);
    *taskID = newNode->taskID;

    /* should log the intent */

    /* create the status node */
    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = newNode->taskID;
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    statusPtr->lastPolled = time(0);
    strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName));
    unlock_Status();

    newNode->statusNodePtr = statusPtr;

    /* create the LWP to do the real work behind the scenes */
#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, Restorer, newNode);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
			  "restorer process", &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	FreeNode(newNode->taskID);	/*  failed to create LWP to do the dump. */
    }

    return (code);
}
Exemplo n.º 9
0
/* STC_DeleteDump
 */
afs_int32
STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
{
    afs_int32 code = TC_BADTASK;	/* If not compiled -Dxbsa then fail */
#ifdef xbsa
    struct deleteDumpIf *ptr = 0;
    statusP statusPtr = 0;
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
#endif

    *taskId = 0;
    if (!CONF_XBSA)
	return (TC_BADTASK);	/* Only do if butc is started as XBSA */

#ifdef xbsa
    code = 0;
    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
    if (!ptr)
	ERROR_EXIT(TC_NOMEMORY);

    *taskId = allocTaskId();
    ptr->dumpID = dumpID;
    ptr->taskId = *taskId;

    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = *taskId;
    statusPtr->lastPolled = time(0);
    statusPtr->flags &= ~STARTING;
    strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
    unlock_Status();

#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, DeleteDump, ptr);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
			  &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	if (ptr)
	    free(ptr);
    }
#endif /* xbsa */

    return (code);
}
Exemplo n.º 10
0
afs_int32
DumpDB(struct rx_call *call,
       int firstcall,		/* 1 - init.  0 - no init */
       afs_int32 maxLength,
       charListT *charListPtr,
       afs_int32 *done)
{
#ifdef AFS_PTHREAD_ENV
    pthread_t dumperPid, watcherPid;
    pthread_attr_t dumperPid_tattr;
    pthread_attr_t watcherPid_tattr;
#else
    PROCESS dumperPid, watcherPid;
#endif
    int readSize;
    afs_int32 code = 0;

    if (callPermitted(call) == 0)
        ERROR(BUDB_NOTPERMITTED);

    ObtainWriteLock(&dumpSyncPtr->ds_lock);

    /* If asking for zero bytes, then this is a call to reset the timeToLive
     * timer. Reset it if there is a dump in progress.
     */
    if (maxLength == 0) {
        charListPtr->charListT_val = NULL;
        charListPtr->charListT_len = 0;

        *done = ((dumpSyncPtr->statusFlags == 0) ? 1 : 0);

        /* reset the clock on dump timeout */
        dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC;
        goto error_exit;
    }

    if (dumpSyncPtr->statusFlags == 0) {
        if (!firstcall)
            ERROR(BUDB_DUMPFAILED);

        LogDebug(5, "Setup dump\n");

        /* no dump in progress - setup and retake lock */
        memset(dumpSyncPtr, 0, sizeof(*dumpSyncPtr));
        /*	ObtainWriteLock(&dumpSyncPtr->ds_lock); */

        /* mark dump in progress */
        dumpSyncPtr->statusFlags = 1;

        code = pipe(dumpSyncPtr->pipeFid);
        if (code)
            ERROR(errno);

#ifdef AFS_PTHREAD_ENV
        /* Initialize the condition variables and the mutexes we use
         * to signal and synchronize the reader and writer threads.
         */
        assert(pthread_cond_init(&dumpSyncPtr->ds_readerStatus_cond, (const pthread_condattr_t *)0) == 0);
        assert(pthread_cond_init(&dumpSyncPtr->ds_writerStatus_cond, (const pthread_condattr_t *)0) == 0);
        assert(pthread_mutex_init(&dumpSyncPtr->ds_readerStatus_mutex, (const pthread_mutexattr_t *)0) == 0);
        assert(pthread_mutex_init(&dumpSyncPtr->ds_writerStatus_mutex, (const pthread_mutexattr_t *)0) == 0);

        /* Initialize the thread attributes and launch the thread */

        assert(pthread_attr_init(&dumperPid_tattr) == 0);
        assert(pthread_attr_setdetachstate(&dumperPid_tattr, PTHREAD_CREATE_DETACHED) == 0);
        assert(pthread_create(&dumperPid, &dumperPid_tattr, (void *)setupDbDump, NULL) == 0);

#else
        code =
            LWP_CreateProcess(setupDbDump, 16384, 1,
                              (void *)(intptr_t)dumpSyncPtr->pipeFid[1],
                              "Database Dumper", &dumperPid);
        if (code)
            goto error_exit;
#endif

        dumpSyncPtr->dumperPid = dumperPid;
        dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC;

#ifdef AFS_PTHREAD_ENV
        /* Initialize the thread attributes and launch the thread */

        assert(pthread_attr_init(&watcherPid_tattr) == 0);
        assert(pthread_attr_setdetachstate(&watcherPid_tattr, PTHREAD_CREATE_DETACHED) == 0);
        assert(pthread_create(&watcherPid, &watcherPid_tattr, (void *)dumpWatcher, NULL) == 0);
#else
        /* now create the watcher thread */
        code =
            LWP_CreateProcess(dumpWatcher, 16384, 1, 0,
                              "Database Dump Watchdog", &watcherPid);
#endif
    } else if (firstcall)
        ERROR(BUDB_LOCKED);

    /* now read the database and feed it to the rpc connection */

    /* wait for data */
    while (dumpSyncPtr->ds_bytes == 0) {
        /* if no more data */
        if ((dumpSyncPtr->ds_writerStatus == DS_DONE)
                || (dumpSyncPtr->ds_writerStatus == DS_DONE_ERROR)) {
            break;
        }

        if (dumpSyncPtr->ds_writerStatus == DS_WAITING) {
            LogDebug(6, "wakup writer\n");
            dumpSyncPtr->ds_writerStatus = 0;
#ifdef AFS_PTHREAD_ENV
            assert(pthread_cond_broadcast(&dumpSyncPtr->ds_writerStatus_cond) == 0);
#else
            code = LWP_SignalProcess(&dumpSyncPtr->ds_writerStatus);
            if (code)
                LogError(code, "BUDB_DumpDB: signal delivery failed\n");
#endif
        }
        LogDebug(6, "wait for writer\n");
        dumpSyncPtr->ds_readerStatus = DS_WAITING;
        ReleaseWriteLock(&dumpSyncPtr->ds_lock);
#ifdef AFS_PTHREAD_ENV
        assert(pthread_mutex_lock(&dumpSyncPtr->ds_readerStatus_mutex) == 0);
        assert(pthread_cond_wait(&dumpSyncPtr->ds_readerStatus_cond, &dumpSyncPtr->ds_readerStatus_mutex) == 0);
        assert(pthread_mutex_unlock(&dumpSyncPtr->ds_readerStatus_mutex) == 0);
#else
        LWP_WaitProcess(&dumpSyncPtr->ds_readerStatus);
#endif
        ObtainWriteLock(&dumpSyncPtr->ds_lock);
    }

    charListPtr->charListT_val = (char *)malloc(maxLength);
    readSize =
        read(dumpSyncPtr->pipeFid[0], charListPtr->charListT_val, maxLength);

    /* reset the clock on dump timeout */
    dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC;

    LogDebug(4, "read of len %d returned %d\n", maxLength, readSize);

    charListPtr->charListT_len = readSize;

    if (readSize == 0) {	/* last chunk */
        *done = 1;
        close(dumpSyncPtr->pipeFid[0]);
        dumpSyncPtr->statusFlags = 0;
    } else
        *done = 0;

    dumpSyncPtr->ds_bytes -= readSize;
    if (dumpSyncPtr->ds_writerStatus == DS_WAITING) {
        dumpSyncPtr->ds_writerStatus = 0;
#ifdef AFS_PTHREAD_ENV
        assert(pthread_cond_broadcast(&dumpSyncPtr->ds_writerStatus_cond) == 0);
#else
        code = LWP_SignalProcess(&dumpSyncPtr->ds_writerStatus);
        if (code)
            LogError(code, "BUDB_DumpDB: signal delivery failed\n");
#endif
    }

error_exit:
    if (!code && (dumpSyncPtr->ds_writerStatus == DS_DONE_ERROR))
        code = -1;
    ReleaseWriteLock(&dumpSyncPtr->ds_lock);
    return (code);
}
Exemplo n.º 11
0
afs_int32
STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
    struct scanTapeIf *ptr;
    statusP statusPtr = NULL;
    afs_int32 code = 0;

#ifdef xbsa
    if (CONF_XBSA)
	return (TC_BADTASK);	/* ScanDumps does not apply if XBSA */
#endif

    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    *taskId = allocTaskId();

    ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
    if (!ptr)
	ERROR_EXIT(TC_NOMEMORY);
    ptr->addDbFlag = addDbFlag;
    ptr->taskId = *taskId;

    /* create the status node */
    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = *taskId;
    statusPtr->lastPolled = time(0);
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
    unlock_Status();

#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, ScanDumps, ptr);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	if (ptr)
	    free(ptr);
    }

    return code;
}
Exemplo n.º 12
0
afs_int32
GetText(struct rx_call *call, afs_uint32 lockHandle, afs_int32 textType, 
	afs_int32 maxLength, afs_int32 offset, afs_int32 *nextOffset,
	charListT *charListPtr)
{
    struct ubik_trans *ut = 0;
    struct block block;
    afs_int32 transferSize, chunkSize;
    afs_int32 blockOffset;
    dbadr lastBlockAddr;
    afs_int32 nblocks;
    struct textBlock *tbPtr;
    afs_int32 textRemaining;
    char *textPtr;
    afs_int32 code;

    LogDebug(5, "GetText: type %d, offset %d, nextOffset %"AFS_PTR_FMT
	     ", maxLength %d\n", textType, offset, nextOffset, maxLength);

    if (callPermitted(call) == 0) {
	code = BUDB_NOTPERMITTED;
	goto no_xfer_abort;
    }

    /* check parameters */
    if ((offset < 0)
	|| (textType < 0)
	|| (textType >= TB_NUM)
	) {
	code = BUDB_BADARGUMENT;
	goto no_xfer_abort;
    }

    /* start the transaction */
    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	goto no_xfer_abort;

    /* fetch the lock state */
    if (checkLockHandle(ut, lockHandle) == 0) {
	code = BUDB_NOTLOCKED;
	goto no_xfer_abort;
    }

    tbPtr = &db.h.textBlock[textType];

    if ((ntohl(tbPtr->size) > 0)
	&& (offset >= ntohl(tbPtr->size))
	) {
	code = BUDB_BADARGUMENT;
	goto no_xfer_abort;
    }

    LogDebug(5, "GetText: store size is %d\n", ntohl(tbPtr->size));

    /* compute minimum of remaining text or user buffer */
    textRemaining = ntohl(tbPtr->size) - offset;
    transferSize = MIN(textRemaining, maxLength);

    /* allocate the transfer storage */
    if (transferSize <= 0) {
	charListPtr->charListT_len = 0L;
	charListPtr->charListT_val = NULL;
    } else {
	charListPtr->charListT_len = transferSize;
	charListPtr->charListT_val = (char *)malloc(transferSize);
	if (charListPtr->charListT_val == 0)
	    ABORT(BUDB_NOMEM);
    }

    textPtr = charListPtr->charListT_val;
    *nextOffset = offset + transferSize;

    /* setup the datablock. read and discard all blocks up to the one the
     * offset specifies
     */
    nblocks = offset / BLOCK_DATA_SIZE;
    lastBlockAddr = ntohl(tbPtr->textAddr);

    while (nblocks--) {
	code = dbread(ut, lastBlockAddr, (char *)&block, sizeof(block));
	if (code)
	    ABORT(BUDB_IO);
	lastBlockAddr = ntohl(block.h.next);
    }

    while (transferSize > 0) {
	code = dbread(ut, lastBlockAddr, (char *)&block, sizeof(block));
	if (code)
	    ABORT(BUDB_IO);

	LogDebug(5, "fetched block %d\n", lastBlockAddr);

	/* compute the data size to extract */
	blockOffset = offset % BLOCK_DATA_SIZE;
	textRemaining = BLOCK_DATA_SIZE - blockOffset;
	chunkSize = min(textRemaining, transferSize);

	memcpy(textPtr, &block.a[blockOffset], chunkSize);

	/* LogDebug(5, "transfering %d bytes: %s\n", chunkSize, textPtr); */

	transferSize -= chunkSize;
	offset += chunkSize;
	textPtr += chunkSize;

	if (transferSize) {
	    /* setup lastBlockAddr */
	    lastBlockAddr = ntohl(block.h.next);
	}
    }

    if (*nextOffset == ntohl(tbPtr->size)) {
	/* all done */
	*nextOffset = -1;
    }

  /* error_exit: */
    code = ubik_EndTrans(ut);
/*  printf("in error exit, code=%ld\n", code); */
    return (code);

  no_xfer_abort:
    charListPtr->charListT_len = 0;
    charListPtr->charListT_val = (char *)malloc(0);

  abort_exit:
    if (ut)
	ubik_AbortTrans(ut);
/*  printf("in abort exit, code=%ld\n", code); */
    return (code);
}
Exemplo n.º 13
0
afs_int32
STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
    statusP statusPtr = NULL;
    afs_int32 code = 0;
    struct saveDbIf *ptr;

#ifdef xbsa
    if (CONF_XBSA)
	return (TC_BADTASK);	/* LabelTape does not apply if XBSA */
#endif

    if (callPermitted(rxCall) == 0)
	return (TC_NOTPERMITTED);

    *taskId = allocTaskId();

    ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
    if (!ptr)
	ERROR_EXIT(TC_NOMEMORY);
    ptr->archiveTime = archiveTime;
    ptr->taskId = *taskId;

    /* create the status node */
    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = *taskId;
    statusPtr->lastPolled = time(0);
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
    unlock_Status();

    ptr->statusPtr = statusPtr;

#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
    AFS_SIGSET_RESTORE();
#else
    code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	if (ptr)
	    free(ptr);
    }

    return (code);
}
Exemplo n.º 14
0
afs_int32
STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
    statusP statusPtr;
    afs_int32 code = 0;

#ifdef xbsa
    if (CONF_XBSA)
	return (TC_BADTASK);	/* LabelTape does not apply if XBSA */
#endif

    if (callPermitted(rxCall) == 0)
	return (TC_NOTPERMITTED);

    *taskId = allocTaskId();

    /* create the status node */
    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = *taskId;
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    statusPtr->lastPolled = time(0);
    strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
    unlock_Status();

#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId,
			  "Db restore", &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
    }

    return (code);
}
Exemplo n.º 15
0
afs_int32
STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
{
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
    struct labelTapeIf *ptr;
    statusP statusPtr = NULL;
    afs_int32 code;

#ifdef xbsa
    if (CONF_XBSA)
	return (TC_BADTASK);	/* LabelTape does not apply if XBSA */
#endif

    if (callPermitted(acid) == 0)
	return (TC_NOTPERMITTED);

    ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
    if (!ptr)
	ERROR_EXIT(TC_NOMEMORY);
    memcpy(&ptr->label, label, sizeof(ptr->label));

    /* set up the status node */
    *taskId = allocTaskId();	/* for bucoord */
    ptr->taskId = *taskId;

    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = *taskId;
    statusPtr->lastPolled = time(0);
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
    unlock_Status();

    /* create the LWP to do the real work behind the scenes */
#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, Labeller, ptr);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
			  &pid);
#endif

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	if (ptr)
	    free(ptr);
    }

    return (code);
}
Exemplo n.º 16
0
afs_int32
SaveText(struct rx_call *call, afs_uint32 lockHandle, afs_int32 textType, 
	 afs_int32 offset, afs_int32 flags, charListT *charListPtr)
{
    struct ubik_trans *ut;
    struct block diskBlock;
    dbadr diskBlockAddr;
    afs_int32 remainingInBlock, chunkSize;
    struct textBlock *tbPtr;
    afs_int32 textLength = charListPtr->charListT_len;
    char *textptr = charListPtr->charListT_val;
    afs_int32 code;

    LogDebug(5, "SaveText: type %d, offset %d, length %d\n", textType, offset,
	     textLength);

    if (callPermitted(call) == 0)
	return (BUDB_NOTPERMITTED);

    if ((textLength > BLOCK_DATA_SIZE) || (offset < 0))
	return (BUDB_BADARGUMENT);

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	return (code);

    /* fetch the lock state */
    if (checkLockHandle(ut, lockHandle) == 0)
	ABORT(BUDB_NOTLOCKED);

    if ((textType < 0) || (textType >= TB_NUM))
	ABORT(BUDB_BADARGUMENT);

    tbPtr = &db.h.textBlock[textType];

    LogDebug(5,
	     "SaveText: lockHandle %d textType %d offset %d flags %d txtlength %d\n",
	     lockHandle, textType, offset, flags, textLength);

    if (offset == 0) {
	/* release any blocks from previous transactions */
	diskBlockAddr = ntohl(tbPtr->newTextAddr);
	freeOldBlockChain(ut, diskBlockAddr);

	if (textLength) {
	    code = AllocBlock(ut, &diskBlock, &diskBlockAddr);
	    if (code)
		ABORT(code);

	    LogDebug(5, "allocated block %d\n", diskBlockAddr);

	    /* set block type */
	    diskBlock.h.type = text_BLOCK;

	    /* save it in the database header */
	    tbPtr->newsize = 0;
	    tbPtr->newTextAddr = htonl(diskBlockAddr);
	    dbwrite(ut, (char *)tbPtr - (char *)&db.h, (char *)tbPtr,
		    sizeof(struct textBlock));
	} else {
	    tbPtr->newsize = 0;
	    tbPtr->newTextAddr = 0;
	}
    } else {
	/* non-zero offset */
	int nblocks;

	if (offset != ntohl(tbPtr->newsize))
	    ABORT(BUDB_BADARGUMENT);

	/* locate the block to which offset refers */
	nblocks = offset / BLOCK_DATA_SIZE;

	diskBlockAddr = ntohl(tbPtr->newTextAddr);
	if (diskBlockAddr == 0)
	    ABORT(BUDB_BADARGUMENT);

	code =
	    dbread(ut, diskBlockAddr, (char *)&diskBlock, sizeof(diskBlock));
	if (code)
	    ABORT(code);

	while (nblocks--) {
	    diskBlockAddr = ntohl(diskBlock.h.next);
	    code =
		dbread(ut, diskBlockAddr, (char *)&diskBlock,
		       sizeof(diskBlock));
	    if (code)
		ABORT(code);
	}
    }

    /* diskBlock and diskBlockAddr now point to the last block in the chain */

    while (textLength) {
	/* compute the transfer size */
	remainingInBlock = (BLOCK_DATA_SIZE - (offset % BLOCK_DATA_SIZE));
	chunkSize = MIN(remainingInBlock, textLength);

	/* copy in the data */
	memcpy(&diskBlock.a[offset % BLOCK_DATA_SIZE], textptr, chunkSize);

	/* LogDebug(5, "text is %s\n", textptr); */

	textLength -= chunkSize;
	textptr += chunkSize;
	offset += chunkSize;
	tbPtr->newsize = htonl(ntohl(tbPtr->newsize) + chunkSize);

	if (textLength > 0) {
	    afs_int32 prevBlockAddr;
	    afs_int32 linkOffset;
	    afs_int32 linkValue;

	    /* have to add another block to the chain */

	    code =
		dbwrite(ut, diskBlockAddr, (char *)&diskBlock,
			sizeof(diskBlock));
	    if (code)
		ABORT(code);

	    prevBlockAddr = (afs_int32) diskBlockAddr;
	    code = AllocBlock(ut, &diskBlock, &diskBlockAddr);
	    if (code)
		ABORT(code);

	    LogDebug(5, "allocated block %d\n", diskBlockAddr);

	    /* set block type */
	    diskBlock.h.type = text_BLOCK;

	    /* now have to update the previous block's link */
	    linkOffset =
		(afs_int32) ((char*)& diskBlock.h.next - (char*)& diskBlock);
	    linkValue = htonl(diskBlockAddr);

	    code =
		dbwrite(ut, (afs_int32) prevBlockAddr + linkOffset,
			(char *)&linkValue, sizeof(afs_int32));
	    if (code)
		ABORT(code);
	} else {
	    /* just write the old block */
	    code =
		dbwrite(ut, diskBlockAddr, (char *)&diskBlock,
			sizeof(diskBlock));
	    if (code)
		ABORT(code);
	}
    }

    if (flags & BUDB_TEXT_COMPLETE) {	/* done */
	/* this was the last chunk of text */
	diskBlockAddr = ntohl(tbPtr->textAddr);
	freeOldBlockChain(ut, diskBlockAddr);

	tbPtr->textAddr = tbPtr->newTextAddr;
	tbPtr->newTextAddr = 0;
	tbPtr->size = tbPtr->newsize;
	tbPtr->newsize = 0;
	tbPtr->version = htonl(ntohl(tbPtr->version) + 1);

	/* saveTextToFile(ut, tbPtr); */
    }

    /* update size and other text header info */
    code =
	dbwrite(ut, (char *)tbPtr - (char *)&db.h, (char *)tbPtr,
		sizeof(struct textBlock));
    if (code)
	ABORT(code);

/*error_exit: */
    code = ubik_EndTrans(ut);
    return (code);

  abort_exit:
    ubik_AbortTrans(ut);
    return (code);
}
Exemplo n.º 17
0
afs_int32
STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
{
    struct dumpNode *newNode = 0;
    statusP statusPtr = 0;
#ifdef AFS_PTHREAD_ENV
    pthread_t pid;
    pthread_attr_t tattr;
    AFS_SIGSET_DECL;
#else
    PROCESS pid;
#endif
    afs_int32 code = 0;

    if (callPermitted(rxCallId) == 0)
	return (TC_NOTPERMITTED);

    /* should be verifying parameter validity */
    *taskId = 0;

    /* this creates a node in list, alots an id for it and prepares it for locking */
    CreateNode(&newNode);

    /*set up the parameters in the node, to be used by LWP */
    strcpy(newNode->dumpSetName, tcdiPtr->dumpName);

    newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1);
    strcpy(newNode->dumpName, tcdiPtr->dumpPath);

    newNode->volumeSetName =
	(char *)malloc(strlen(tcdiPtr->volumeSetName) + 1);
    strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName);

    CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet);

    newNode->dumps = (struct tc_dumpDesc *)
	malloc(sizeof(struct tc_dumpDesc) *
	       tc_dumpArrayPtr->tc_dumpArray_len);
    newNode->arraySize = tc_dumpArrayPtr->tc_dumpArray_len;
    CopyDumpDesc(newNode->dumps, tc_dumpArrayPtr);

    newNode->parent = tcdiPtr->parentDumpId;
    newNode->level = tcdiPtr->dumpLevel;
    newNode->doAppend = tcdiPtr->doAppend;
#ifdef xbsa
    if (CONF_XBSA)
	newNode->doAppend = 0;	/* Append flag is ignored if talking to XBSA */
#endif

    /* create the status node */
    statusPtr = createStatusNode();
    if (!statusPtr)
	ERROR_EXIT(TC_INTERNALERROR);

    lock_Status();
    statusPtr->taskId = newNode->taskID;
    statusPtr->lastPolled = time(0);
    statusPtr->flags &= ~STARTING;	/* ok to examine */
    strncpy(statusPtr->taskName, "Dump", sizeof(statusPtr->taskName));
    unlock_Status();

    newNode->statusNodePtr = statusPtr;

    /* create the LWP to do the real work behind the scenes */
#ifdef AFS_PTHREAD_ENV
    code = pthread_attr_init(&tattr);
    if (code)
	ERROR_EXIT(code);

    code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    if (code)
	ERROR_EXIT(code);

    AFS_SIGSET_CLEAR();
    code = pthread_create(&pid, &tattr, Dumper, newNode);
    AFS_SIGSET_RESTORE();
#else
    code =
	LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process",
			  &pid);
#endif
    if (code)
	ERROR_EXIT(code);

    *taskId = newNode->taskID;

  error_exit:
    if (code) {
	if (statusPtr)
	    deleteStatusNode(statusPtr);
	FreeNode(newNode->taskID);	/*  failed to create LWP to do the dump. */
    }

    return (code);
}