/* 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); }
/* 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); }
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); }
/* 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); }
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); }
static l_ref* get_instance(lua_State *l, int n) { return *static_cast<l_ref **>(luaL_checkudata(l, n, TNAME(C))); }
virtual void debug(std::ostream &out) { out << "[" << TNAME(C) << "] "; }
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); }
/* 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); }
/* Empty reference */ l_ref() : val(NULL), owner_ref(NULL), c_name(TNAME(C)) {}
/* 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); }
/* 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); }
/* New Lua object */ l_ref(C *instance, lua_State *l, const char *classname = TNAME(C)) : c_name(classname), ref(instance), owner(instance) { push(l); }