* Note that we are getting a new, non-cached file handle for
* specific use by this method.
*/
handle = makeFileHandle(fileNum, getAppropriateReadWriteMode());
} catch (ChecksumException e) {
throw new EnvironmentFailureException
(envImpl, EnvironmentFailureReason.LOG_CHECKSUM,
"Opening file " + fileNum + " for invisible marking ", e);
} catch (FileNotFoundException e) {
throw new EnvironmentFailureException
(envImpl, EnvironmentFailureReason.LOG_FILE_NOT_FOUND,
"Opening file " + fileNum + " for invisible marking ", e);
}
RandomAccessFile file = handle.getFile();
/* Set the invisible bit for each entry. */
try {
for (Long lsn : lsns) {
if (DbLsn.getFileNumber(lsn) != fileNum) {
/*
* This failure will not invalidate the environment right
* away. But since it causes replication syncup to fail,
* the environment will shutdown, which is the effect we
* want.
*/
throw new EnvironmentFailureException
(envImpl, EnvironmentFailureReason.UNEXPECTED_STATE,
"LSN of " + DbLsn.getNoFormatString(lsn) +
" did not match file number" + fileNum);
}
int entryFlagsOffset = (int)
(DbLsn.getFileOffset(lsn) + LogEntryHeader.FLAGS_OFFSET);
file.seek(entryFlagsOffset);
byte flags = file.readByte();
byte newFlags = LogEntryHeader.makeInvisible(flags);
file.seek(entryFlagsOffset);
file.writeByte(newFlags);
}
} catch (IOException e) {
throw new EnvironmentFailureException
(envImpl, EnvironmentFailureReason.LOG_WRITE,
"Flipping invisibility in file " + fileNum, e);
} finally {
/*
* Just close the file. Fsyncs will be done later on, in the hope
* that the OS has already synced asynchronously.
*/
try {
file.close();
} catch (IOException e) {
throw new EnvironmentFailureException
(envImpl, EnvironmentFailureReason.LOG_WRITE,
"Closing after invisibility cloaking: file " + fileNum, e);
}
}
}