Esempio n. 1
0
	/* Called to initialize this reference kind metatable */
	static void register_members(lua_State *l)
	{
		metatable_bind<const char*>(l, l_classname_field, l_data_type<const char*>(TNAME(C)));
		meta_bind_func(l, "__gc", destroy);
		meta_bind_func(l, "__cpp_ref_count", _get_ref_count);
		meta_bind_func(l, "__cpp_ownerref_count", _get_ownerref_count);
	}
Esempio n. 2
0
	/* Copy reference */
	l_ref(l_ref *r, lua_State *l, const char *classname = TNAME(C))
			: _ref_base(*r), val(r->val), owner_ref(r->owner_ref), c_name(classname)
	{
		if (owner_ref)
			owner_ref->retain();
		_push_noretain(l);
	}
Esempio n. 3
0
afs_int32
readDbTape(struct butm_tapeInfo *tapeInfoPtr,
	   struct rstTapeInfo *rstTapeInfoPtr, int query)
{
    afs_int32 code = 0;
    int interactiveFlag;
    afs_int32 taskId;
    struct butm_tapeLabel oldTapeLabel;
    char AFStapeName[BU_MAXTAPELEN], tapeName[BU_MAXTAPELEN];
    struct tapeEntryList *endList;
    int tapecount = 1;
    struct budb_dumpEntry de;
    struct budb_tapeEntry te;

    taskId = rstTapeInfoPtr->taskId;
    interactiveFlag = query;

    /* construct the name of the tape */
    sprintf(AFStapeName, "%s.%-d", DUMP_TAPE_NAME, rstTapeInfoPtr->tapeSeq);
    strcpy(tapeName, AFStapeName);

    /* Will prompt for the latest saved database tape, but will accept any one */
    if (rstTapeInfoPtr->tapeSeq == 1) {
	code = bcdb_FindLatestDump("", "", &de);
	if (!code)
	    rstTapeInfoPtr->dumpid = de.id;
    }
    if (rstTapeInfoPtr->dumpid) {
	code =
	    bcdb_FindTapeSeq(rstTapeInfoPtr->dumpid, rstTapeInfoPtr->tapeSeq,
			     &te);
	if (!code)
	    strcpy(tapeName, te.name);
    }
    code = 0;

    while (1) {			/*w */
	if (interactiveFlag) {	/* need a tape to read */
	    code =
		PromptForTape(RESTOREDBOPCODE, tapeName,
			      rstTapeInfoPtr->dumpid, taskId, tapecount);
	    if (code)
		ERROR_EXIT(code);
	}
	interactiveFlag = 1;
	tapecount++;

	code = butm_Mount(tapeInfoPtr, tapeName);
	if (code) {
	    TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
	    goto getNewTape;
	}

	code = butm_ReadLabel(tapeInfoPtr, &oldTapeLabel, 1);	/* will rewind the tape */
	if (code) {
	    TapeLog(0, taskId, code, tapeInfoPtr->error,
		    "Can't read tape label\n");
	    goto getNewTape;
	}

	/* Check for name of tape and matching dump id (if applicable). */
	if ((strcmp(oldTapeLabel.AFSName, AFStapeName) != 0)
	    || ((rstTapeInfoPtr->tapeSeq != 1)
		&& (oldTapeLabel.dumpid != rstTapeInfoPtr->dumpid))) {
	    char expTape[BU_MAXTAPELEN + 32];
	    char gotTape[BU_MAXTAPELEN + 32];

	    TAPENAME(expTape, tapeName, rstTapeInfoPtr->dumpid);
	    TAPENAME(gotTape, oldTapeLabel.AFSName, oldTapeLabel.dumpid);

	    TLog(taskId, "Tape label expected %s, label seen %s\n", expTape,
		 gotTape);
	    goto getNewTape;
	}

	if (rstTapeInfoPtr->tapeSeq == 1)	/* Remember this dumpId */
	    rstTapeInfoPtr->dumpid = oldTapeLabel.dumpid;

	break;

      getNewTape:
	unmountTape(taskId, tapeInfoPtr);
    }				/*w */


    /* Initialize a tapeEntry for later inclusion into the database */
    listEntryPtr =
	(struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
    if (!listEntryPtr)
	ERROR_EXIT(TC_NOMEMORY);
    memset(listEntryPtr, 0, sizeof(struct tapeEntryList));

    /* Fill in tape entry so we can save it later */
    strcpy(tapeEntryPtr->name, TNAME(&oldTapeLabel));
    tapeEntryPtr->dump = oldTapeLabel.dumpid;
    tapeEntryPtr->flags = BUDB_TAPE_BEINGWRITTEN;
    tapeEntryPtr->written = oldTapeLabel.creationTime;
    tapeEntryPtr->expires = oldTapeLabel.expirationDate;
    tapeEntryPtr->seq = extractTapeSeq(oldTapeLabel.AFSName);
    tapeEntryPtr->useCount = oldTapeLabel.useCount;
    tapeEntryPtr->useKBytes = 0;
    tapeEntryPtr->labelpos = 0;

    /* Thread onto end of single-linked list */
    if (listEntryHead) {
	endList = listEntryHead;
	while (endList->next)
	    endList = endList->next;
	endList->next = listEntryPtr;
    } else
	listEntryHead = listEntryPtr;

  error_exit:
    return (code);
}
Esempio n. 4
0
/* GetDBTape
 *      Load a DB tape, read and over write its label.
 *      Leave the tape mounted.
 */
afs_int32
GetDBTape(afs_int32 taskId, Date expires, struct butm_tapeInfo *tapeInfoPtr,
	  afs_uint32 dumpid, afs_int32 sequence, int queryFlag,
	  int *wroteLabel)
{
    afs_int32 code = 0;
    int interactiveFlag;
    char tapeName[BU_MAXTAPELEN];
    char strlevel[5];
    struct timeval tp;
    struct timezone tzp;
    afs_int32 curTime;
    int tapecount = 1;

    struct butm_tapeLabel oldTapeLabel, newLabel;
    struct tapeEntryList *endList;

    /* construct the name of the tape */
    sprintf(tapeName, "%s.%-d", DUMP_TAPE_NAME, sequence);

    interactiveFlag = queryFlag;
    *wroteLabel = 0;

    while (!*wroteLabel) {	/*w */
	if (interactiveFlag) {	/* need a tape to write */
	    code =
		PromptForTape(SAVEDBOPCODE, tapeName, dumpid, taskId,
			      tapecount);
	    if (code)
		ERROR_EXIT(code);
	}
	interactiveFlag = 1;
	tapecount++;

	code = butm_Mount(tapeInfoPtr, tapeName);
	if (code) {
	    TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
	    goto getNewTape;
	}

	memset(&oldTapeLabel, 0, sizeof(oldTapeLabel));
	code = butm_ReadLabel(tapeInfoPtr, &oldTapeLabel, 1);	/* rewind tape */
	if (code) {
	    oldTapeLabel.useCount = 0;	/* no label exists */
	    oldTapeLabel.structVersion = 0;
	    strcpy(oldTapeLabel.pName, "");
	} else {
	    /* If tape has a name, it must be null or database tape name */
	    if (dump_namecheck && strcmp(oldTapeLabel.AFSName, "")
		&& !databaseTape(oldTapeLabel.AFSName)) {
		char gotName[BU_MAXTAPELEN + 32];

		LABELNAME(gotName, &oldTapeLabel);
		TLog(taskId,
		     "This tape %s must be a database tape or NULL tape\n",
		     gotName);

	      getNewTape:
		unmountTape(taskId, tapeInfoPtr);
		continue;
	    }

	    /* Do not overwrite a tape that belongs to this dump */
	    if (oldTapeLabel.dumpid && (oldTapeLabel.dumpid == dumpid)) {
		ErrorLog(0, taskId, 0, 0,
			 "Can't overwrite tape containing the dump in progress\n");
		goto getNewTape;
	    }

	    /* On first tape, the savedb has not started yet, so the database is not locked 
	     * and we can therefore, access information from it. This is easier to do because
	     * database dumps don't have appended dumps (nor appended).
	     */
	    if (sequence == 1) {
		afs_uint32 dmp;
		struct budb_dumpEntry de, de2;

		/* Verify the tape has not expired
		 * Early database dumps don't have a dumpid 
		 */
		if (!tapeExpired(&oldTapeLabel)) {
		    TLog(taskId, "This tape has not expired\n");
		    goto getNewTape;
		}

		/* Since the dumpset on this tape will be deleted from database, check if
		 * any of the dumps in this dumpset are most-recent-dumps.
		 */
		for (dmp = oldTapeLabel.dumpid; dmp; dmp = de.appendedDumpID) {
		    if (dmp == lastDump.id) {
			memcpy(&de, &lastDump, sizeof(de));
			memcpy(&de2, &lastDump, sizeof(de2));
		    } else {
			code = bcdb_FindDumpByID(dmp, &de);
			if (code)
			    break;
			sprintf(strlevel, "%d", de.level);
			code =
			    bcdb_FindLatestDump(de.volumeSetName, strlevel,
						&de2);
			if (code)
			    continue;
		    }

		    if (de.id == de2.id) {
			if (strcmp(DUMP_TAPE_NAME, de2.name) == 0) {
			    ErrorLog(0, taskId, 0, 0,
				     "Warning: Overwriting most recent dump %s (DumpID %u)\n",
				     de.name, de.id);
			} else {
			    ErrorLog(0, taskId, 0, 0,
				     "Warning: Overwriting most recent dump of the '%s' volumeset: %s (DumpID %u)\n",
				     de.volumeSetName, de.name, de.id);
			}
		    }
		}
	    }

	    /* Otherwise, the savedb is in progress and we can't
	     * access the database (it's locked). So we rely on the 
	     * information available (and not the backup database).
	     */
	    else {
		/* Check the tape's expiration date. Use the expiration on the label */
		gettimeofday(&tp, &tzp);
		curTime = tp.tv_sec;
		if (curTime < oldTapeLabel.expirationDate) {
		    TLog(taskId, "This tape has not expired\n");
		    goto getNewTape;
		}

		/* Check if this previous-dump of the dump-in-progress is on this tape */
		if (oldTapeLabel.dumpid
		    && (oldTapeLabel.dumpid == lastDump.id)) {
		    ErrorLog(0, taskId, 0, 0,
			     "Warning: Overwriting most recent dump %s (DumpID %u)\n",
			     lastDump.name, lastDump.id);
		}

	    }
	}

	GetNewLabel(tapeInfoPtr, oldTapeLabel.pName, tapeName, &newLabel);
	newLabel.expirationDate = expires;
	newLabel.useCount = oldTapeLabel.useCount + 1;
	newLabel.dumpid = dumpid;
	newLabel.size = tapeInfoPtr->tapeSize;

	code = butm_Create(tapeInfoPtr, &newLabel, 1);	/* rewind tape */
	if (code) {
	    TapeLog(0, taskId, code, tapeInfoPtr->error,
		    "Can't label tape\n");
	    goto getNewTape;
	}

	*wroteLabel = 1;

	/* Initialize a tapeEntry for later inclusion into the database */
	listEntryPtr =
	    (struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
	if (!listEntryPtr)
	    ERROR_EXIT(TC_NOMEMORY);
	memset(listEntryPtr, 0, sizeof(struct tapeEntryList));

	/* Remember dumpid so we can delete it later */
	if ((oldTapeLabel.structVersion >= TAPE_VERSION_3)
	    && oldTapeLabel.dumpid)
	    listEntryPtr->oldDumpId = oldTapeLabel.dumpid;

	/* Fill in tape entry so we can save it later */
	strcpy(tapeEntryPtr->name, TNAME(&newLabel));
	tapeEntryPtr->flags = BUDB_TAPE_BEINGWRITTEN;
	tapeEntryPtr->written = newLabel.creationTime;
	tapeEntryPtr->expires = expires;
	tapeEntryPtr->seq = sequence;
	tapeEntryPtr->useCount = oldTapeLabel.useCount + 1;
	tapeEntryPtr->dump = dumpid;
	tapeEntryPtr->useKBytes = 0;
	tapeEntryPtr->labelpos = 0;

	/* Thread onto end of single-linked list */
	if (listEntryHead) {
	    endList = listEntryHead;
	    while (endList->next)
		endList = endList->next;
	    endList->next = listEntryPtr;
	} else
	    listEntryHead = listEntryPtr;
    }				/*w */

  error_exit:
    return (code);
}
Esempio n. 5
0
static int
readDump(afs_uint32 taskId, struct butm_tapeInfo *tapeInfoPtr,
         struct tapeScanInfo *scanInfoPtr)
{
    int moreTapes = 1;
    afs_int32 flags, seq;
    afs_uint32 nbytes = 0;
    int newDump = 1, newTape = 1;
    afs_int32 tapePosition;
    afs_int32 code = 0, tcode;
    int badscan;
    struct volumeHeader volHeader, volTrailer;
    struct budb_tapeEntry tapeEntry;
    struct budb_volumeEntry volEntry;

    volEntry.dump = 0;
    PrintDumpLabel(&scanInfoPtr->dumpLabel);

    while (moreTapes) {
        /* While there is a tape to read *//*t */
        badscan = 0;
        while (1) {
            /* Read each volume on the tape *//*w */
            moreTapes = -1;
            tapePosition = tapeInfoPtr->position;	/* remember position */

            /*
             * Skip the volume data
             */
            tcode =
                scanVolData(taskId, tapeInfoPtr,
                            scanInfoPtr->tapeLabel.structVersion, &volHeader,
                            &volTrailer, &nbytes);
            if (tcode) {
                badscan++;

                if (tcode == TC_ABORTEDBYREQUEST) {	/* Aborted */
                    ERROR_EXIT(tcode);
                }

                if (tcode == BUTM_EOD) {
                    moreTapes = 0;	/* the end of the dump */
                    break;
                }

                /* Found a volume but it's incomplete. Skip over these */
                if (volHeader.volumeID) {
                    TapeLog(0, taskId, tcode, 0,
                            "Warning: volume %s (%u) ignored. Incomplete\n",
                            volHeader.volumeName, volHeader.volumeID);
                    continue;
                }

                /* No volume was found. We may have hit the EOT or a
                 * bad-spot. Try to skip over this spot.
                 */
                if (badscan < 2) {	/* allow 2 errors, then fail */
                    TapeLog(0, taskId, tcode, 0,
                            "Warning: Error in scanning tape - will try skipping volume\n");
                    continue;
                }
                if (scanInfoPtr->tapeLabel.structVersion >= TAPE_VERSION_4) {
                    TapeLog(0, taskId, tcode, 0,
                            "Warning: Error in scanning tape - end-of-tape inferred\n");
                    moreTapes = 1;	/* then assume next tape */
                } else {
                    ErrorLog(0, taskId, tcode, 0, "Error in scanning tape\n");
                    /* will ask if there is a next tape */
                }
                break;
            }

            PrintVolumeHeader(&volHeader);

            /* If this is not the first volume fragment, make sure it follows
             * the last volume fragment
             */
            if (volEntry.dump) {
                if ((volEntry.dump != volHeader.dumpID)
                        || (volEntry.id != volHeader.volumeID)
                        || (volEntry.seq != volHeader.frag - 2)
                        || (strcmp(volEntry.name, volHeader.volumeName))) {
                    TLog(taskId,
                         "Warning: volume %s (%u) ignored. Incomplete - no last fragment\n",
                         volEntry.name, volEntry.id);

                    if (scanInfoPtr->addDbFlag) {
                        tcode = flushSavedEntries(DUMP_FAILED);
                        if (tcode)
                            ERROR_EXIT(tcode);
                        volEntry.dump = 0;
                    }
                }
            }

            /* If this is the first volume fragment, make sure says so */
            if (scanInfoPtr->addDbFlag && !volEntry.dump
                    && (volHeader.frag != 1)) {
                TLog(taskId,
                     "Warning: volume %s (%u) ignored. Incomplete - no first fragment\n",
                     volHeader.volumeName, volHeader.volumeID);
            }

            /* Check that this volume belongs to the dump we are scanning */
            else if (scanInfoPtr->dumpLabel.dumpid
                     && (volHeader.dumpID != scanInfoPtr->dumpLabel.dumpid)) {
                TLog(taskId,
                     "Warning: volume %s (%u) ignored. Expected DumpId %u, got %u\n",
                     volHeader.volumeName, volHeader.volumeID,
                     scanInfoPtr->dumpLabel.dumpid, volHeader.dumpID);
            }

            /* Passed tests, Now add to the database (if dbadd flag is set) */
            else if (scanInfoPtr->addDbFlag) {
                /* Have enough information to create a dump entry */
                if (newDump) {
                    tcode = RcreateDump(scanInfoPtr, &volHeader);
                    if (tcode) {
                        ErrorLog(0, taskId, tcode, 0,
                                 "Can't add dump %u to database\n",
                                 volHeader.dumpID);
                        ERROR_EXIT(tcode);
                    }
                    newDump = 0;
                }

                /* Have enough information to create a tape entry */
                if (newTape) {
                    seq = extractTapeSeq(scanInfoPtr->tapeLabel.AFSName);
                    if (seq < 0)
                        ERROR_EXIT(TC_INTERNALERROR);

                    tcode =
                        useTape(&tapeEntry, volHeader.dumpID,
                                TNAME(&scanInfoPtr->tapeLabel), seq,
                                scanInfoPtr->tapeLabel.useCount,
                                scanInfoPtr->dumpLabel.creationTime,
                                scanInfoPtr->dumpLabel.expirationDate,
                                tapepos);
                    if (tcode) {
                        char gotName[BU_MAXTAPELEN + 32];

                        LABELNAME(gotName, &scanInfoPtr->tapeLabel);
                        ErrorLog(0, taskId, tcode, 0,
                                 "Can't add tape %s for dump %u to database\n",
                                 gotName, volHeader.dumpID);
                        ERROR_EXIT(tcode);
                    }
                    newTape = 0;
                }

                /* Create the volume entry */
                flags = ((volHeader.frag == 1) ? BUDB_VOL_FIRSTFRAG : 0);
                if (!volTrailer.contd)
                    flags |= BUDB_VOL_LASTFRAG;
                tcode =
                    addVolume(&volEntry, volHeader.dumpID,
                              TNAME(&scanInfoPtr->tapeLabel),
                              volHeader.volumeName, volHeader.volumeID,
                              volHeader.cloneDate, tapePosition, nbytes,
                              (volHeader.frag - 1), flags);
                if (tcode) {
                    ErrorLog(0, taskId, tcode, 0,
                             "Can't add volume %s (%u) for dump %u to database\n",
                             volHeader.volumeName, volHeader.volumeID,
                             volHeader.dumpID);
                    ERROR_EXIT(tcode);
                }
            }

            if (volTrailer.contd) {
                /* No need to read the EOD marker, we know there is a next tape */
                moreTapes = 1;
                break;
            } else {
                if (scanInfoPtr->addDbFlag) {
                    tcode = flushSavedEntries(DUMP_SUCCESS);
                    if (tcode)
                        ERROR_EXIT(tcode);
                    volEntry.dump = 0;
                }
            }
        }			/*w */

        if (!newTape) {
            if (scanInfoPtr->addDbFlag) {
                tcode =
                    finishTape(&tapeEntry,
                               (tapeInfoPtr->kBytes +
                                (tapeInfoPtr->nBytes ? 1 : 0)));
                if (tcode) {
                    char gotName[BU_MAXTAPELEN + 32];

                    LABELNAME(gotName, &scanInfoPtr->tapeLabel);
                    ErrorLog(0, taskId, tcode, 0,
                             "Can't mark tape %s 'completed' for dump %u in database\n",
                             gotName, tapeEntry.dump);
                    ERROR_EXIT(tcode);
                }
            }
        }

        /* Ask if there is another tape if we can't figure it out */
        if (moreTapes == -1)
            moreTapes = (queryoperator ? Ask("Are there more tapes") : 1);

        /* Get the next tape label */
        if (moreTapes) {
            char *tapeName;
            afs_int32 dumpid;

            unmountTape(taskId, tapeInfoPtr);

            tapeName = nextTapeLabel(scanInfoPtr->tapeLabel.AFSName);
            dumpid = scanInfoPtr->tapeLabel.dumpid;
            tcode =
                getScanTape(taskId, tapeInfoPtr, tapeName, dumpid, 1,
                            &scanInfoPtr->tapeLabel);
            if (tcode)
                ERROR_EXIT(tcode);
            newTape = 1;
        }
    }				/*t */

    if (!newDump) {
        if (scanInfoPtr->addDbFlag) {
            tcode = finishDump(&scanInfoPtr->dumpEntry);
            if (tcode) {
                ErrorLog(0, taskId, tcode, 0,
                         "Can't mark dump %u 'completed' in database\n",
                         scanInfoPtr->dumpEntry.id);
            }

            tcode = flushSavedEntries(DUMP_SUCCESS);
            if (tcode)
                ERROR_EXIT(tcode);
        }
    }

error_exit:
    return (code);
}
Esempio n. 6
0
	static l_ref* get_instance(lua_State *l, int n)
	{
		return *static_cast<l_ref **>(luaL_checkudata(l, n, TNAME(C)));
	}
Esempio n. 7
0
	virtual void debug(std::ostream &out)
	{
		out << "[" << TNAME(C) << "] ";
	}
Esempio n. 8
0
	l_ref(l_ref<T> *r, C *i, lua_State *l, const char *classname = TNAME(C))
		: val(i), owner_ref(r), c_name(classname)
	{
		owner_ref->retain();
		_push_noretain(l);
	}
Esempio n. 9
0
	/* New reference */
	l_ref(C *instance, lua_State *l, const char *classname = TNAME(C))
		: val(instance), owner_ref(NULL), c_name(classname)
	{
		_push_noretain(l);
	}
Esempio n. 10
0
	/* Empty reference */
	l_ref() : val(NULL), owner_ref(NULL), c_name(TNAME(C)) {}
Esempio n. 11
0
	/* Register dependent objects */
	l_ref(C *instance, std::shared_ptr<void> owner, lua_State *l,
			const char *classname = TNAME(C))
		: c_name(classname), ref(instance), owner(owner)
	{
		push(l);
	}
Esempio n. 12
0
	/* Copy existing object */
	l_ref(std::shared_ptr<C> ref, lua_State *l,
			const char *classname = TNAME(C))
		: c_name(classname), ref(ref.get()), owner(ref)
	{
		push(l);
	}
Esempio n. 13
0
	/* New Lua object */
	l_ref(C *instance, lua_State *l, const char *classname = TNAME(C))
		: c_name(classname), ref(instance), owner(instance)
	{
		push(l);
	}