Commit ce487dc6 authored by Steven Murray's avatar Steven Murray
Browse files

bug #82673: RFE: Tapebridged and rtcpd should support buffered tape-marks over multiple files

Added assertions to tapebridged that check the tape-file sequence-number of
the flush messages from rtcpd.
parent d64ff96b
......@@ -83,7 +83,10 @@ castor::tape::tapebridge::BridgeProtocolEngine::BridgeProtocolEngine(
m_stoppingGracefully(stoppingGracefully),
m_tapebridgeTransactionCounter(tapebridgeTransactionCounter),
m_nbReceivedENDOF_REQs(0),
m_pendingTransferIds(MAXPENDINGTRANSFERS) {
m_pendingTransferIds(MAXPENDINGTRANSFERS),
m_pendingMigrationsStore(
tapeFlushConfigParams.getMaxBytesBeforeFlush().value,
tapeFlushConfigParams.getMaxFilesBeforeFlush().value) {
// Store the listen socket and initial rtcpd connection in the socket
// catalogue
......@@ -1650,8 +1653,7 @@ void castor::tape::tapebridge::BridgeProtocolEngine::
fileMigratedNotifications;
try {
fileMigratedNotifications =
m_pendingMigrationsStore.getAndRemoveFilesWrittenWithoutFlush(
body.tapeFseq);
m_pendingMigrationsStore.dataFlushedToTape(body.tapeFseq);
} catch(castor::exception::Exception &ex) {
TAPE_THROW_CODE(ECANCELED,
": Failed to process TAPEBRIDGE_FLUSHEDTOTAPE message"
......@@ -2140,6 +2142,8 @@ void
m_jobRequest.volReqId, reply->mountTransactionId(),
tapebridgeTransId , reply->aggregatorTransactionId());
m_pendingMigrationsStore.noMoreFilesToMigrate();
// Tell RTCPD there is no file by sending an empty file list
RtcpTxRx::tellRtcpdEndOfFileList(m_cuuid, m_jobRequest.volReqId, rtcpdSock,
RTCPDNETRWTIMEOUT);
......
......@@ -162,7 +162,7 @@ namespace tapebridge {
* used over multiple files as defined by the parameter named
* TAPEBRIDGE/USEBUFFEREDTAPEMARKSOVERMULTIPLEFILES.
*/
const uint64_t TAPEBRIDGE_MAXFILESBEFOREFLUSH = 2;
const uint64_t TAPEBRIDGE_MAXFILESBEFOREFLUSH = 1;
} // namespace tapebridge
} // namespace tape
......
......@@ -32,7 +32,10 @@
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
castor::tape::tapebridge::PendingMigrationsStore::PendingMigrationsStore() {
castor::tape::tapebridge::PendingMigrationsStore::PendingMigrationsStore(
const uint64_t maxBytesBeforeFlush, const uint64_t maxFilesBeforeFlush):
m_maxBytesBeforeFlush(maxBytesBeforeFlush),
m_maxFilesBeforeFlush(maxFilesBeforeFlush) {
clear();
}
......@@ -41,7 +44,9 @@ castor::tape::tapebridge::PendingMigrationsStore::PendingMigrationsStore() {
// Copy constructor
//-----------------------------------------------------------------------------
castor::tape::tapebridge::PendingMigrationsStore::PendingMigrationsStore(
PendingMigrationsStore &) {
PendingMigrationsStore &other):
m_maxBytesBeforeFlush(other.m_maxBytesBeforeFlush),
m_maxFilesBeforeFlush(other.m_maxFilesBeforeFlush) {
// Should never be called, therefore do nothing
}
......@@ -95,6 +100,14 @@ void castor::tape::tapebridge::PendingMigrationsStore::add(
": value=" << fileToMigrate.fseq());
}
// Throw an exception if the file size of the file to migrate message is
// invalid
if(0 == fileToMigrate.fileSize()) {
TAPE_THROW_CODE(EBADMSG,
": Failed to add pending file-migration to pending file-migration store"
": File to migrate message contains the invalid file-size of 0");
}
// Throw an exception if the store already contains the pending
// file-migration that should be added
PendingMigrationMap::iterator itor = m_pendingMigrations.find(
......@@ -121,15 +134,35 @@ void castor::tape::tapebridge::PendingMigrationsStore::add(
// Add the pending file-migration
{
PendingMigration pendingMigration(
const PendingMigration pendingMigration(
PendingMigration::PENDINGMIGRATION_SENT_TO_RTCPD,
fileToMigrate);
m_pendingMigrations[fileToMigrate.fseq()] = pendingMigration;
}
// Update internal tracking variables
m_tapeFseqOfLastFileAdded = fileToMigrate.fseq();
}
//-----------------------------------------------------------------------------
// noMoreFilesToMigrate
//-----------------------------------------------------------------------------
void castor::tape::tapebridge::PendingMigrationsStore::noMoreFilesToMigrate()
throw(castor::exception::Exception) {
const bool endOfSessionFileIsKnown = 0 != m_tapeFseqOfEndOfSessionFile;
if(endOfSessionFileIsKnown) {
TAPE_THROW_CODE(EINVAL,
": Failed to register no more files to migrate"
": Already received no-more-files notification"
": tapeFseqOfLastFileAdded=" << m_tapeFseqOfLastFileAdded);
}
m_tapeFseqOfEndOfSessionFile = m_tapeFseqOfLastFileAdded;
}
//-----------------------------------------------------------------------------
// markAsWrittenWithoutFlush
//-----------------------------------------------------------------------------
......@@ -147,6 +180,14 @@ void
": value=" << fileMigratedNotification.fseq());
}
// Throw an exception if the file size of the file migrated message is
// invalid
if(0 == fileMigratedNotification.fileSize()) {
TAPE_THROW_CODE(EBADMSG,
": Failed to mark pending file-migration as written without flush"
": File migrated message contains the invalid file-size of 0");
}
// Try to find the pending file-migration whose state is to be updated
PendingMigrationMap::iterator itor = m_pendingMigrations.find(
fileMigratedNotification.fseq());
......@@ -180,8 +221,8 @@ void
checkForMismatches(itor->second.fileToMigrate, fileMigratedNotification);
} catch(castor::exception::Exception &ex) {
TAPE_THROW_EX(castor::exception::InvalidArgument,
": Failed to mark pending file-migration as written without flush" <<
ex.getMessage().str());
": Failed to mark pending file-migration as written without flush"
": " << ex.getMessage().str());
}
// Copy into the pending file-migration the file-migrated notification
......@@ -196,6 +237,43 @@ void
// Update the tape-file sequence-number of the last file marked as written
// without a flush
m_tapeFseqOfLastFileWrittenWithoutFlush = fileMigratedNotification.fseq();
// Update the number of bytes and files written to tape without a flush
m_nbBytesWrittenWithoutFlush += fileMigratedNotification.fileSize();
m_nbFilesWrittenWithoutFlush++;
// Determine whether or not the current file is the one that matches or
// immediately exceeds the maximum number of bytes to be written to tape
// before a flush
if(m_maxBytesBeforeFlush <= m_nbBytesWrittenWithoutFlush) {
if(0 != m_tapeFseqOfMaxBytesFile) {
TAPE_THROW_EX(castor::exception::InvalidArgument,
": Failed to mark pending file-migration as written without flush"
": Already matched or exceed maximum number of bytes before flush"
": maxBytesBeforeFlush=" << m_maxBytesBeforeFlush <<
" nbBytesWrittenWithoutFlush=" << m_nbBytesWrittenWithoutFlush <<
" tapeFseqOfMaxBytesFile=" << m_tapeFseqOfMaxBytesFile <<
" illegalTapeFseqOfMaxBytesFile=" << fileMigratedNotification.fseq());
}
m_tapeFseqOfMaxBytesFile = fileMigratedNotification.fseq();
}
// Determine whether or not the current file is the one that matches the
// the maximum number of files to be written to tape before a flush
if(m_maxFilesBeforeFlush <= m_nbFilesWrittenWithoutFlush) {
if(0 != m_tapeFseqOfMaxFilesFile) {
TAPE_THROW_EX(castor::exception::InvalidArgument,
": Failed to mark pending file-migration as written without flush"
": Already matched maximum number of files before flush"
": maxFilesBeforeFlush=" << m_maxFilesBeforeFlush <<
" nbFilesWrittenWithoutFlush=" << m_nbFilesWrittenWithoutFlush <<
" tapeFseqOfMaxFilesFile=" << m_tapeFseqOfMaxFilesFile <<
" illegalTapeFseqOfMaxFilesFile=" << fileMigratedNotification.fseq());
}
m_tapeFseqOfMaxFilesFile = fileMigratedNotification.fseq();
}
}
......@@ -288,31 +366,62 @@ void castor::tape::tapebridge::PendingMigrationsStore::checkForMismatches(
//-----------------------------------------------------------------------------
// getAndRemoveFilesWrittenWithoutFlush
// dataFlushedToTape
//-----------------------------------------------------------------------------
std::list<castor::tape::tapegateway::FileMigratedNotification>
castor::tape::tapebridge::PendingMigrationsStore::
getAndRemoveFilesWrittenWithoutFlush(const uint32_t maxFseq)
dataFlushedToTape(const uint32_t tapeFseqOfFlush)
throw(castor::exception::Exception) {
const char *const methodTask = "accept flush to tape";
std::list<castor::tape::tapegateway::FileMigratedNotification> outputList;
// Check method arguments
if(0 == maxFseq) {
if(0 == tapeFseqOfFlush) {
TAPE_THROW_CODE(EINVAL,
": Failed to get and remove pending file-migrations written without"
" flush"
": maxFseq contains the invalid value of 0");
": Failed to " << methodTask <<
": tapeFseqOfFlush contains the invalid value of 0");
}
// Determine whether or not the tape-file sequence-number of the flush to
// tape is valid taking into account the fact that
// m_tapeFseqOfEndOfSessionFile can only be used when neither
// m_tapeFseqOfMaxBytesFile and m_tapeFseqOfMaxFilesFile are known
bool tapeFseqOfFlushIsValid = false;
if(0 == m_tapeFseqOfMaxBytesFile && 0 == m_tapeFseqOfMaxFilesFile &&
tapeFseqOfFlush == m_tapeFseqOfEndOfSessionFile) {
tapeFseqOfFlushIsValid = true;
} else if(tapeFseqOfFlush == m_tapeFseqOfMaxBytesFile ||
tapeFseqOfFlush == m_tapeFseqOfMaxFilesFile) {
tapeFseqOfFlushIsValid = true;
}
// Throw an exception if the flush has occured on an invalid tape-file
// sequence-number
if(!tapeFseqOfFlushIsValid) {
TAPE_THROW_CODE(EINVAL,
": Failed to " << methodTask <<
": Invalid tapeFseqOfFlush"
": tapeFseqOfMaxFilesFile=" << m_tapeFseqOfMaxFilesFile <<
" tapeFseqOfMaxBytesFile=" << m_tapeFseqOfMaxBytesFile <<
" tapeFseqOfEndOfSessionFile=" << m_tapeFseqOfEndOfSessionFile <<
" tapeFseqOfFlush=" << tapeFseqOfFlush);
}
// Reset the appropriate member-variables used to determine the tape-file
// sequence-number of the next flush to tape
m_nbBytesWrittenWithoutFlush = 0;
m_nbFilesWrittenWithoutFlush = 0;
m_tapeFseqOfMaxBytesFile = 0;
m_tapeFseqOfMaxFilesFile = 0;
// For each pending file-migration in the store in ascending order of
// tape-file sequence-number
for(PendingMigrationMap::iterator itor = m_pendingMigrations.begin();
itor != m_pendingMigrations.end();) {
// Break out of the loop if we have reached a pending file-migration with
// a tape-file sequence-number greater than the maximum to be got and
// removed
if(maxFseq < (uint32_t)(itor->second.fileToMigrate.fseq())) {
// a tape-file sequence-number greater than that of the flush to tape
if(tapeFseqOfFlush < (uint32_t)(itor->second.fileToMigrate.fseq())) {
break;
}
......@@ -321,9 +430,8 @@ std::list<castor::tape::tapegateway::FileMigratedNotification>
if(itor->second.status !=
PendingMigration::PENDINGMIGRATION_WRITTEN_WITHOUT_FLUSH) {
TAPE_THROW_CODE(ECANCELED,
": Failed to get and remove pending file-migrations written without"
" flush"
": maxFseq=" << maxFseq <<
": Failed to " << methodTask <<
": tapeFseqOfFlush=" << tapeFseqOfFlush <<
": Found pending file-migration not marked as being written without"
" flush"
": badFseq=" << itor->second.fileToMigrate.fseq());
......@@ -345,8 +453,13 @@ std::list<castor::tape::tapegateway::FileMigratedNotification>
// clear
//-----------------------------------------------------------------------------
void castor::tape::tapebridge::PendingMigrationsStore::clear() {
m_nbBytesWrittenWithoutFlush = 0;
m_nbFilesWrittenWithoutFlush = 0;
m_tapeFseqOfEndOfSessionFile = 0;
m_tapeFseqOfLastFileAdded = 0;
m_tapeFseqOfLastFileWrittenWithoutFlush = 0;
m_tapeFseqOfMaxBytesFile = 0;
m_tapeFseqOfMaxFilesFile = 0;
m_pendingMigrations.clear();
}
......
......@@ -44,10 +44,22 @@ namespace tapebridge {
*/
class PendingMigrationsStore {
public:
/**
* Constructor.
*
* @param maxBytesBeforeFlush The maximum number of bytes that can be written
* to tape before a flush to tape should be
* executed. Please note that flushes to tape
* occur on file boundaries, therefore more bytes
* will most probably be written to tape before
* the actual flush takes place.
* @param maxFilesBeforeFlush The maximum number of files that can be written
* to tape before a flush to tape should be
* executed.
*/
PendingMigrationsStore();
PendingMigrationsStore(const uint64_t maxBytesBeforeFlush,
const uint64_t maxFilesBeforeFlush);
/**
* Adds the specified pending file-migration to the store.
......@@ -96,9 +108,20 @@ public:
const tapegateway::FileMigratedNotification &fileMigratedNotification)
throw(castor::exception::Exception);
/**
* To be called when there are no more files to be migrated.
*
* The pending-migrations store uses this notification to determine the
* tape-file sequence-number of the very last file that is going to be
* written to tape. The pending-migrations store uses this knowledge to
* check the validity of the tape-file sequence-number of flushes to tape.
*/
void noMoreFilesToMigrate() throw(castor::exception::Exception);
/**
* Gets and removes the pending file-migrations that have a tape-file
* sequence-number less than or equal to the specified maximum.
* sequence-number less than or equal to the specified tape-file
* sequence-number of the flush to tape.
*
* The pending file-migrations are returned as a list of file-migrated
* notification messages that require their aggregatorTransactionId members
......@@ -111,17 +134,76 @@ public:
* flush.
*/
std::list<tapegateway::FileMigratedNotification>
getAndRemoveFilesWrittenWithoutFlush(const uint32_t maxFseq)
dataFlushedToTape(const uint32_t tapeFseqOfFlush)
throw(castor::exception::Exception);
/**
* Retruns the total number of pending file-grations currently inside the
* Returns the total number of pending file-grations currently inside the
* store.
*/
uint32_t getNbPendingMigrations() const;
private:
/**
* The maximum number of bytes that can be written to tape before a flush to
* tape should be executed. Please note that flushes to tape occur on file
* boundaries, therefore more bytes will most probably be written to tape
* before the actual flush takes place.
*/
const uint64_t m_maxBytesBeforeFlush;
/**
* The maximum number of files that can be written to tape before a flush to
* tape should be executed.
*/
const uint64_t m_maxFilesBeforeFlush;
/**
* The current number of bytes written to tape without a flush to tape.
*/
uint64_t m_nbBytesWrittenWithoutFlush;
/**
* The current number of files written to tape without a flush to tape.
*/
uint64_t m_nbFilesWrittenWithoutFlush;
/**
* The tape-file sequence-number of the very last file that will be written
* to tape at the end of the current tape session. If the file is not yet
* known then the value of this member-variable will be 0.
*/
uint32_t m_tapeFseqOfEndOfSessionFile;
/**
* The tape-file sequence-number of the last pending file-migration to be
* marked as written without a flush, or 0 if no pending file-migration
* has yet been marked as such.
*/
uint32_t m_tapeFseqOfLastFileWrittenWithoutFlush;
/**
* The tape-file sequence-number of the last pending file-migration added to
* the store, or 0 if the store is currently empty.
*/
uint32_t m_tapeFseqOfLastFileAdded;
/**
* The sequence-number of the file written to tape that matched or
* immediately exceeded the maximum number of bytes to be written to tape
* before a flush. If the file is not known then the value of this
* member-variable is 0.
*/
uint32_t m_tapeFseqOfMaxBytesFile;
/**
* The sequence-number of the file written to tape that matched the maximum
* number of files to be written to tape before a flush. If the file is not
* known then the value of this member-variable is 0.
*/
uint32_t m_tapeFseqOfMaxFilesFile;
/**
* Data structure used to store a pending migration and its status.
*/
......@@ -196,19 +278,6 @@ private:
*/
PendingMigrationMap m_pendingMigrations;
/**
* The tape-file sequence-number of the last pending file-migration added to
* the store, or 0 if the store is currently empty.
*/
uint32_t m_tapeFseqOfLastFileAdded;
/**
* The tape-file sequence-number of the last pending file-migration to be
* marked as written without a flush, or 0 if no pending file-migration
* has yet been marked as such.
*/
uint32_t m_tapeFseqOfLastFileWrittenWithoutFlush;
/**
* Private copy-constructor to prevent copies being made.
*/
......
......@@ -86,16 +86,13 @@ void castor::tape::tapebridge::TapeFlushConfigParams::determineTapeFlushMode()
if(NULL != paramCStr) {
if(0 == strcmp("N_FLUSHES_PER_FILE", paramCStr)) {
m_tapeFlushMode.value = TAPEBRIDGE_N_FLUSHES_PER_FILE;
} else if(0 == strcmp("ONE_FLUSH_PER_FILE", paramCStr)) {
m_tapeFlushMode.value = TAPEBRIDGE_ONE_FLUSH_PER_FILE;
} else if(0 == strcmp("ONE_FLUSH_PER_N_FILES", paramCStr)) {
m_tapeFlushMode.value = TAPEBRIDGE_ONE_FLUSH_PER_N_FILES;
} else {
castor::exception::InvalidArgument ex;
ex.getMessage() <<
"Value of configuration parameter is not valid"
": expected N_FLUSHES_PER_FILE, ONE_FLUSH_PER_FILE or"
" ONE_FLUSH_PER_N_FILES"
": expected N_FLUSHES_PER_FILE or ONE_FLUSH_PER_N_FILES"
": category=" << m_tapeFlushMode.category <<
" name=" << m_tapeFlushMode.name <<
" value=" << paramCStr <<
......
#####################################################################################
################################################################################
#
# CASTOR2 Sample Configuration File
# $Id: castor.conf,v 1.170 2009/08/18 09:42:57 waldron Exp $
#
#####################################################################################
################################################################################
#
# Service to Host/Port Mapping
......@@ -28,7 +28,7 @@
#REPACK HOST castorrepack
## Client configuration #############################################################
## Client configuration ########################################################
# The port range to be used by clients for the stager callbacks. If not present a
# port range of 30000-30100 is used. You can disable the port range by setting both
......@@ -63,7 +63,7 @@ FILEQUERY MAXNBRESPONSES 10000
#STAGER TIMEOUT 2592000
## Service Configuration ############################################################
## Service Configuration #######################################################
# The following option defines the maximum possible length of a log message that can
# be sent to syslog. By default the value is empty, instructing the logging
......@@ -513,7 +513,7 @@ JobManager SharedLSFResource http://castorscheduler.cern.ch/lsf
#GC DisableStagerSync no
## Security Configuration ###########################################################
## Security Configuration ######################################################
# The following option defines the list of security protocols which are supported by
# CASTOR headnodes (e.g. rhd and nsd) and diskservers
......@@ -540,7 +540,7 @@ JobManager SharedLSFResource http://castorscheduler.cern.ch/lsf
#CSEC TRACEFILE location /var/log/castor/rfiod.csec.log
## Transfer Protocols ###############################################################
## Transfer Protocols ##########################################################
# The rootsys configuration option points to the directory where the rootd binary is
# located. The default is /usr/local/bin
......@@ -641,7 +641,7 @@ RFIOD FTRUST castoradm4.cern.ch
# recorded value. If it differs the transfer will fail.
#GSIFTP USE_CKSUM YES
## Tape #############################################################################
## Tape ########################################################################
ACCT RTCOPY YES # Rtcopy accounting
ACCT TAPE YES # Tape accounting
......@@ -790,23 +790,40 @@ TAPE ACS_UNMOUNT_LIBRARY_FAILURE_HANDLING retry 1 300
#
#TAPE RELAX_BLANKTAPE_CHECK NO
# The following option allows to enable buffered tape marks support in taped. The two
# of three tape marks per file will be written to tape in immediate mode. In order to
# successfully use this function, loading the appropriate st driver is required.
# The following option enables buffered tape mark support when rtcpclientd
# and tpwrite are clients of rtcpd. This option is explicitly ignored when
# tapegatewayd and writetp are clients of rtcpd (via tapebridged).
#
# If the option is omitted, the default value (NO) will be used.
# When this option is set to YES and the aul label format is used, the first
# two of the three tape marks per file will be written to tape in immediate
# mode therefore giving the behaviour of flushing to tape once per file as
# opposed to 3 times.
#
# The appropriate st driver must be loaded in order to successfully use this
# option.
#
# If this option is omitted, then the default value of NO will be used.
#
# Internally and for logging the rtcpd daemon uses the following three
# variables to store the mode of tape-flush behaviour to be used:
#
# tapeFlushMode : N_FLUSHES_PER_FILE or ONE_FLUSH_PER_N_FILES
# maxBytesPerFlush: Unsigned integer greater than 0
# maxFilesPerFlush: Unsigned integer greater than 0
#
# The maxBytesPerFlush and maxFilesPerFlush variables are only applicable when
# tapeFlushMode equals ONE_FLUSH_PER_N_FILES.
#
# If the tapebridged daemon is not the client of the rtcpd daemon and the value of
# this parameter is not YES then the tape-flush mode used will be
# TAPEBRIDGE_N_FLUSHES_PER_FILE.
# The rtcpd daemon translates the TAPE/BUFFER_TAPMARK option as follows:
#
# If the tapebridged daemon is not the client of the rtcpd daemon and the value of
# this parameter is YES then the tape-flush mode used will be
# TAPEBRIDGE_ONE_FLUSH_PER_FILE.
# TAPE BUFFER_TAPEMARK NO => tapeFlushMode=N_FLUSHES_PER_FILE,
#
# TAPE BUFFER_TAPEMARK YES => tapeFlushMode=ONE_FLUSH_PER_N_FILES,
# maxBytesPerFlush=1, maxFilesPerFlush=1
#
#TAPE BUFFER_TAPEMARK NO
## Mighunter ########################################################################
## Mighunter ###################################################################
# The name of the Python module used by the mighunter daemon to decide which
# tape pools to attach to which tape copies. The module should contain Python
......@@ -848,7 +865,7 @@ MIGHUNTER STREAM_POLICY stream
MIGHUNTER SIZECEILING 10G
## Rechandler #######################################################################
## Rechandler ##################################################################
# The name of the Python module used by the rechandler daemon to decide when
# to start recalling files from a tape. The module should contain the function
......@@ -875,7 +892,7 @@ RECHANDLER RECALL_POLICY rechandler
RECHANDLER RECALL_POLICY_FUN globalRecallPolicy
## Tape Gateway #####################################################################
## Tape Gateway ################################################################
# The minimum number of threads in the Worker thread pool.
TAPEGATEWAY MINWORKERTHREADS 60
......@@ -906,7 +923,7 @@ TAPEGATEWAY MIG_RETRY_POLICY migrationRetry
TAPEGATEWAY REC_RETRY_POLICY recallRetry
## Tape Bridge ######################################################################
## Tape Bridge #################################################################
# The port on which the tapebridge will listen for RTCOPY jobs from the VDQM.
#
......@@ -924,8 +941,12 @@ TAPEBRIDGE RTCPDLOWPORT 30101
# The default value of this parameter is 30200.
TAPEBRIDGE RTCPDHIGHPORT 30200
# The value of this parameter defines the mode of tape flush behaviour to be
# used when writing data to tape. Possible case-sensitive values are:
# The value of this parameter defines the mode of tape-flush behaviour to be
# used when tapegatewayd and writetp are clients of rtcpd (via tapebridged).
# This option is explicitly ignored when rtcpclientd and tpwrite are the
# clients of rtpcd.
#
# The possible case-sensitive values for this option are:
#
# Value: N_FLUSHES_PER_FILE
# Description: If the AUL tape format is used then data will be flushed to tape
......@@ -934,19 +955,15 @@ TAPEBRIDGE RTCPDHIGHPORT 30200
# file. If the NL format is used then data will be flushed to tape after the
# end of the data of each file.
#
# Value: ONE_FLUSH_PER_FILE
# Description: If the AUL tape format is used then data will be flushed to tape
# after the AUL trailer of each file. If the NL format is used then data will
# be flushed to tape after the end of the data of each file. In order to
# successfully use this mode, loading of the appropriate st driver is required.
#
# Value: ONE_FLUSH_PER_N_FILES
# Description: If the AUL tape format is used then data will be flushed to tape
# after the AUL trailer of the Nth file, where the Nth file is the one that
# reaches either the maximum number of bytes allowed before a flush or the
# maximum number of files before a flush. If the NL format is used then data
# will be flushed to tape after the end of the data of the Nth file. In order to
# successfully use this mode, loading of the appropriate st driver is required.
# will be flushed to tape after the end of the data of the Nth file.
#
# The appropriate st driver must be loaded in order to successfully use the
# ONE_FLUSH_PER_N_FILES tape-flush mode.
#
# The default value of this parameter is N_FLUSHES_PER_FILE.
#TAPEBRIDGE TAPEFLUSHMODE N_FLUSHES_PER_FILE
......@@ -963,15 +980,15 @@ TAPEBRIDGE RTCPDHIGHPORT 30200
#TAPEBRIDGE MAXBYTESBEFOREFLUSH 8589934592
# The value of this parameter defines the maximum number of files to be written
# to tape before a flush to tape (synchronised tape-mark).
# to tape before a flush to tape (synchronised or non-immediate tape-mark).
#
# The value of this parameter is only used when TAPEBRIDGE/TAPEFLUSHMODE is set
# to ONE_FLUSH_PER_N_FILES.
#
# The default value of this parameter is 2.
#TAPEBRIDGE MAXFILESBEFOREFLUSH 2