Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
52fc9d28
Commit
52fc9d28
authored
Jul 02, 2014
by
Steven Murray
Browse files
Various code improvements.
parent
861e5355
Changes
12
Hide whitespace changes
Inline
Side-by-side
castor/tape/tapeserver/daemon/DataTransferSession.hpp
View file @
52fc9d28
...
...
@@ -112,7 +112,7 @@ namespace daemon {
std
::
string
getVid
()
{
return
m_volInfo
.
vid
;
}
/**
* Return the global shared zmq context for the
mount
session
* Return the global shared zmq context for the
data-transfer
session
* THIS FUNCTION SHALL ONLY BE CALLED IN THE FORKED PROCESS
*
* @return The global shared zmq context for the data-transfer session.
...
...
castor/tape/tapeserver/daemon/DriveCatalogueEntry.cpp
View file @
52fc9d28
...
...
@@ -488,11 +488,12 @@ void castor::tape::tapeserver::daemon::DriveCatalogueEntry::receivedLabelJob(
void
castor
::
tape
::
tapeserver
::
daemon
::
DriveCatalogueEntry
::
forkedDataTransferSession
(
const
pid_t
sessionPid
)
{
std
::
ostringstream
task
;
task
<<
"handle fork of mount session for tape drive "
<<
m_config
.
unitName
;
task
<<
"handle fork of data-transfer session for tape drive "
<<
m_config
.
unitName
;
switch
(
getSession
()
->
getState
())
{
case
castor
::
tape
::
tapeserver
::
daemon
::
DriveCatalogueSession
::
SESSION_STATE_WAITFORK
:
getSession
()
->
setState
(
castor
::
tape
::
tapeserver
::
daemon
::
DriveCatalogueSession
::
SESSION_STATE_RUNNING
);
case
DriveCatalogueSession
::
SESSION_STATE_WAITFORK
:
getSession
()
->
setState
(
DriveCatalogueSession
::
SESSION_STATE_RUNNING
);
getSession
()
->
setPid
(
sessionPid
);
break
;
default:
...
...
castor/tape/tapeserver/daemon/DriveCatalogueEntry.hpp
View file @
52fc9d28
...
...
@@ -106,12 +106,13 @@ public:
*
* The DRIVE_STATE_WAITFORKTRANSFER state allows the object responsible for
* handling the connection from the vdqmd daemon (an instance of
* VdqmConnectionHandler) to delegate the task of forking a mount session.
* VdqmConnectionHandler) to delegate the task of forking a data-transfer
* session.
*
* Once the child process is forked the drive enters the DRIVE_STATE_RUNNING
* state. The child process is responsible for running a
mount session.
* During such a sesion a tape will be mounted, data will be
transfered to
* and/or from the tape and finally the tape will be dismounted.
* state. The child process is responsible for running a
data-transfer
*
session.
During such a sesion a tape will be mounted, data will be
*
transfered to
and/or from the tape and finally the tape will be dismounted.
*
* Once the vdqm job has been carried out, the child process completes
* and the state of the tape drive either returns to DRIVE_STATE_UP if there
...
...
@@ -326,7 +327,7 @@ public:
* not DRIVE_STATE_WAITFORK.
*
* @param sessionPid The process ID of the child process responsible for
* running the
mount
session.
* running the
data-transfer
session.
*/
void
forkedDataTransferSession
(
const
pid_t
sessionPid
);
...
...
@@ -381,12 +382,12 @@ public:
const
legacymsg
::
TapeLabelRqstMsgBody
getLabelJob
()
const
;
/**
* The process ID of the child process running the
mount
session.
* The process ID of the child process running the
data-transfer
session.
*
* This method throws a castor::exception::Exception if the tape drive is not
* in a state for which there is a session process-ID.
*
* @return The process ID of the child process running the
mount
session.
* @return The process ID of the child process running the
data-transfer
session.
*/
pid_t
getSessionPid
()
const
;
...
...
@@ -474,7 +475,7 @@ private:
DriveState
m_state
;
/**
* The type of
mount
session.
* The type of
data-transfer
session.
*/
SessionType
m_sessionType
;
...
...
castor/tape/tapeserver/daemon/DriveCatalogueTest.cpp
View file @
52fc9d28
...
...
@@ -149,7 +149,7 @@ TEST_F(castor_tape_tapeserver_daemon_DriveCatalogueTest, completeFSTN) {
ASSERT_NO_THROW
(
unit
->
configureUp
());
ASSERT_EQ
(
DriveCatalogueEntry
::
DRIVE_STATE_UP
,
unit
->
getState
());
// Check that there are no tape drives waiting for their
mount
sessions to
// Check that there are no tape drives waiting for their
data-transfer
sessions to
// be forked
{
std
::
list
<
std
::
string
>
unitNames
;
...
...
@@ -182,7 +182,7 @@ TEST_F(castor_tape_tapeserver_daemon_DriveCatalogueTest, completeFSTN) {
ASSERT_EQ
(
std
::
string
(
job
.
clientUserName
),
std
::
string
(
unit
->
getVdqmJob
().
clientUserName
));
// Check that there is one tape drive waiting for a
mount
session to be forked
// Check that there is one tape drive waiting for a
data-transfer
session to be forked
{
std
::
list
<
std
::
string
>
unitNames
;
ASSERT_NO_THROW
(
unitNames
=
...
...
@@ -191,7 +191,7 @@ TEST_F(castor_tape_tapeserver_daemon_DriveCatalogueTest, completeFSTN) {
ASSERT_EQ
(
std
::
string
(
"UNIT"
),
unitNames
.
front
());
}
// Fork the
mount
session
// Fork the
data-transfer
session
const
pid_t
sessionPid
=
1234
;
ASSERT_NO_THROW
(
unit
->
forkedDataTransferSession
(
sessionPid
));
ASSERT_EQ
(
castor
::
tape
::
tapeserver
::
daemon
::
DriveCatalogueSession
::
SESSION_STATE_RUNNING
,
unit
->
getSessionState
());
...
...
@@ -217,11 +217,12 @@ TEST_F(castor_tape_tapeserver_daemon_DriveCatalogueTest, completeFSTN) {
ASSERT_EQ
(
unit
,
constUnitFoundByPid
);
}
// Configure the tape drive DOWN whilst the
mount
session is running
// Configure the tape drive DOWN whilst the
data-transfer
session is running
ASSERT_NO_THROW
(
unit
->
configureDown
());
ASSERT_EQ
(
DriveCatalogueEntry
::
DRIVE_STATE_WAITDOWN
,
unit
->
getState
());
// Configure the tape drive back UP whilst the mount session is running
// Configure the tape drive back UP whilst the data-transfer session is
// running
ASSERT_NO_THROW
(
unit
->
configureUp
());
ASSERT_EQ
(
castor
::
tape
::
tapeserver
::
daemon
::
DriveCatalogueSession
::
SESSION_STATE_RUNNING
,
unit
->
getSessionState
());
...
...
castor/tape/tapeserver/daemon/LabelCmdAcceptHandler.hpp
View file @
52fc9d28
...
...
@@ -45,7 +45,7 @@ public:
* Constructor.
*
* @param fd The file descriptor of the socket listening for
* connections from the
mount
session
* connections from the
data-transfer
session
* @param reactor The reactor to which new connection handlers are to be
* registered.
* @param log The object representing the API of the CASTOR logging system.
...
...
castor/tape/tapeserver/daemon/LabelCmdConnectionHandler.cpp
View file @
52fc9d28
...
...
@@ -223,8 +223,8 @@ void castor::tape::tapeserver::daemon::LabelCmdConnectionHandler::
m_thisEventHandlerOwnsFd
=
false
;
{
log
::
Param
params
[]
=
{
log
::
Param
(
"fd"
,
m_fd
)};
m_log
(
LOG_DEBUG
,
"Mount-session handler released label connection"
,
params
);
m_log
(
LOG_DEBUG
,
"Label-command connection handler released label connection"
,
params
);
}
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
log
::
Param
params
[]
=
{
log
::
Param
(
"message"
,
ex
.
getMessage
().
str
())};
...
...
castor/tape/tapeserver/daemon/LabelCmdConnectionHandler.hpp
View file @
52fc9d28
...
...
@@ -36,7 +36,8 @@ namespace tapeserver {
namespace
daemon
{
/**
* Handles the events of the socket listening for connection from the mount session
* Handles the events of the socket listening for connection from the
* data-transfer session
*/
class
LabelCmdConnectionHandler
:
public
reactor
::
ZMQPollEventHandler
{
public:
...
...
@@ -45,7 +46,7 @@ public:
* Constructor.
*
* @param fd The file descriptor of the socket listening for
* connections from the
mount
session
* connections from the
data-transfer
session
* @param reactor The reactor to which new connection handlers are to be
* registered.
* @param log The object representing the API of the CASTOR logging system.
...
...
@@ -89,13 +90,13 @@ public:
private:
/**
* Logs the specifed IO event of the
mount
session connection.
* Logs the specifed IO event of the
data-transfer
session connection.
*/
void
logLabelCmdConnectionEvent
(
const
zmq_pollitem_t
&
fd
);
/**
* Throws an exception if the specified file-descriptor is not that of the
* socket listening for connections from the
mount
session.
* socket listening for connections from the
data-transfer
session.
*/
void
checkHandleEventFd
(
const
int
fd
);
...
...
@@ -114,7 +115,8 @@ private:
void
handleRequest
(
const
legacymsg
::
MessageHeader
&
header
);
/**
* Handles the case when the status of the tape is TAPE_STATUS_MOUNTED in the update drive message
* Handles the case when the status of the tape is TAPE_STATUS_MOUNTED in the
* update drive message
*
* @param vid Volume ID of the tape mounted
* @param mode The mode in which the tape is mounted
...
...
@@ -122,12 +124,14 @@ private:
void
tellVMGRTapeWasMounted
(
const
std
::
string
&
vid
,
const
uint32_t
mode
);
/**
* Checks that a tape mounted for migration by request of the tapegateway is marked as BUSY in the VMGR
* Checks that a tape mounted for migration by request of the tapegateway is
* marked as BUSY in the VMGR
*
* @param vid Volume ID of the tape to be mounted
* @param type The client type of this
mount
session
* @param type The client type of this
data-transfer
session
*/
void
checkTapeConsistencyWithVMGR
(
const
std
::
string
&
vid
,
const
uint32_t
type
,
const
uint32_t
mode
);
void
checkTapeConsistencyWithVMGR
(
const
std
::
string
&
vid
,
const
uint32_t
type
,
const
uint32_t
mode
);
/**
* Marshals the specified source tape label reply message structure into the
...
...
castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp
View file @
52fc9d28
...
...
@@ -42,17 +42,17 @@ public:
virtual
~
ProcessForkerProxy
()
throw
()
=
0
;
/**
* Forks a
mount-session process
.
* Forks a
data-transfer session
.
*/
virtual
void
fork
Mount
Session
()
=
0
;
virtual
void
fork
DataTransfer
Session
()
=
0
;
/**
* Forks a label
-
session
process
.
* Forks a label
session.
*/
virtual
void
forkLabelSession
()
=
0
;
/**
* Forks a cleanup
-
session
process
.
* Forks a cleanup
session.
*/
virtual
void
forkCleanupSession
()
=
0
;
...
...
castor/tape/tapeserver/daemon/ProcessForkerProxySocket.cpp
View file @
52fc9d28
...
...
@@ -51,10 +51,32 @@ castor::tape::tapeserver::daemon::ProcessForkerProxySocket::
}
//------------------------------------------------------------------------------
// fork
Mount
Session
// fork
DataTransfer
Session
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
ProcessForkerProxySocket
::
forkMountSession
()
{
forkDataTransferSession
()
{
}
//------------------------------------------------------------------------------
// writeMsg
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
ProcessForkerProxySocket
::
writeMsg
()
{
writeMsgHeader
();
writeMsgBody
();
}
//------------------------------------------------------------------------------
// writeMsgHeader
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
ProcessForkerProxySocket
::
writeMsgHeader
()
{
}
//------------------------------------------------------------------------------
// writeMsgBody
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
ProcessForkerProxySocket
::
writeMsgBody
()
{
}
//------------------------------------------------------------------------------
...
...
castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp
View file @
52fc9d28
...
...
@@ -59,9 +59,9 @@ public:
~
ProcessForkerProxySocket
()
throw
();
/**
* Forks a
mount-session
process.
* Forks a
data-transfer
process.
*/
void
fork
Mount
Session
();
void
fork
DataTransfer
Session
();
/**
* Forks a label-session process.
...
...
@@ -86,6 +86,12 @@ private:
*/
const
int
m_socketFd
;
void
writeMsg
();
void
writeMsgHeader
();
void
writeMsgBody
();
};
// class ProcessForkerProxySocket
}
// namespace daemon
...
...
castor/tape/tapeserver/daemon/TapeDaemon.cpp
View file @
52fc9d28
...
...
@@ -113,6 +113,15 @@ std::string
// destructor
//------------------------------------------------------------------------------
castor
::
tape
::
tapeserver
::
daemon
::
TapeDaemon
::~
TapeDaemon
()
throw
()
{
closeProcessForkerCmdSenderSocket
();
destroyZmqContext
();
}
//------------------------------------------------------------------------------
// closeProcessForkerCmdSenderSocket
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
TapeDaemon
::
closeProcessForkerCmdSenderSocket
()
throw
()
{
if
(
-
1
!=
m_processForkerCmdSenderSocket
)
{
std
::
list
<
log
::
Param
>
params
;
params
.
push_back
(
...
...
@@ -124,17 +133,26 @@ castor::tape::tapeserver::daemon::TapeDaemon::~TapeDaemon() throw() {
m_log
(
LOG_ERR
,
"Failed to close the socket used for sending copmmands to"
" the ProcessForker"
,
params
);
}
else
{
m_log
(
LOG_INFO
,
"Succesffuly closed the socket used for sending commands"
m_processForkerCmdSenderSocket
=
-
1
;
m_log
(
LOG_INFO
,
"Successfully closed the socket used for sending commands"
" to the ProcessForker"
,
params
);
}
}
}
//------------------------------------------------------------------------------
// destroyZmqContext
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
TapeDaemon
::
destroyZmqContext
()
throw
()
{
if
(
NULL
!=
m_zmqContext
)
{
if
(
zmq_term
(
m_zmqContext
))
{
char
message
[
100
];
sstrerror_r
(
errno
,
message
,
sizeof
(
message
));
castor
::
log
::
Param
params
[]
=
{
castor
::
log
::
Param
(
"message"
,
message
)};
m_log
(
LOG_ERR
,
"Failed to destroy ZMQ context"
,
params
);
}
else
{
m_zmqContext
=
NULL
;
m_log
(
LOG_INFO
,
"Successfully destroyed ZMQ context"
);
}
}
}
...
...
@@ -579,8 +597,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterLabelCmdAcce
std
::
auto_ptr
<
LabelCmdAcceptHandler
>
labelCmdAcceptHandler
;
try
{
labelCmdAcceptHandler
.
reset
(
new
LabelCmdAcceptHandler
(
listenSock
.
get
(),
m_reactor
,
m_log
,
m_driveCatalogue
,
m_hostName
,
m_vdqm
,
m_vmgr
));
labelCmdAcceptHandler
.
reset
(
new
LabelCmdAcceptHandler
(
listenSock
.
get
(),
m_reactor
,
m_log
,
m_driveCatalogue
,
m_hostName
,
m_vdqm
,
m_vmgr
));
listenSock
.
release
();
}
catch
(
std
::
bad_alloc
&
ba
)
{
castor
::
exception
::
BadAlloc
ex
;
...
...
@@ -937,8 +955,10 @@ void castor::tape::tapeserver::daemon::TapeDaemon::handleReapedLabelSession(
//------------------------------------------------------------------------------
// forkDataTransferSessions
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
TapeDaemon
::
forkDataTransferSessions
()
throw
()
{
const
std
::
list
<
std
::
string
>
unitNames
=
m_driveCatalogue
.
getUnitNamesWaitingForTransferFork
();
void
castor
::
tape
::
tapeserver
::
daemon
::
TapeDaemon
::
forkDataTransferSessions
()
throw
()
{
const
std
::
list
<
std
::
string
>
unitNames
=
m_driveCatalogue
.
getUnitNamesWaitingForTransferFork
();
for
(
std
::
list
<
std
::
string
>::
const_iterator
itor
=
unitNames
.
begin
();
itor
!=
unitNames
.
end
();
itor
++
)
{
...
...
@@ -968,7 +988,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::forkDataTransferSession(
char
message
[
100
];
sstrerror_r
(
errno
,
message
,
sizeof
(
message
));
params
.
push_back
(
log
::
Param
(
"message"
,
message
));
m_log
(
LOG_ERR
,
"Failed to fork mount session for tape drive"
,
params
);
m_log
(
LOG_ERR
,
"Failed to fork data-transfer session for tape drive"
,
params
);
return
;
// Else if this is the parent process
...
...
@@ -988,9 +1009,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::forkDataTransferSession(
m_log
(
LOG_INFO
,
"Assigned the drive in the vdqm"
);
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
log
::
Param
params
[]
=
{
log
::
Param
(
"message"
,
ex
.
getMessage
().
str
())};
m_log
(
LOG_ERR
,
"Data-transfer session could not be started: Failed to assign drive in vdqm"
,
params
);
m_log
(
LOG_ERR
,
"Data-transfer session could not be started"
": Failed to assign drive in vdqm"
,
params
);
}
runDataTransferSession
(
drive
);
...
...
@@ -1006,7 +1026,7 @@ void castor::tape::tapeserver::daemon::TapeDaemon::runDataTransferSession(
std
::
list
<
log
::
Param
>
params
;
params
.
push_back
(
log
::
Param
(
"unitName"
,
driveConfig
.
unitName
));
m_log
(
LOG_INFO
,
"
Mount-session
child-process started"
,
params
);
m_log
(
LOG_INFO
,
"
Data-transfer
child-process started"
,
params
);
try
{
DataTransferSession
::
CastorConf
castorConf
;
...
...
@@ -1047,13 +1067,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::runDataTransferSession(
"RTCPD"
,
"THREAD_POOL"
,
(
uint32_t
)
RTCPD_THREAD_POOL
,
&
m_log
);
rmc
.
reset
(
m_rmcFactory
.
create
());
try
{
tapeserver
.
reset
(
m_tapeserverFactory
.
create
(
DataTransferSession
::
getZmqContext
()));
}
catch
(
const
std
::
exception
&
e
){
m_log
(
LOG_ERR
,
"Failed to connect ZMQ/REQ socket in DataTransferSession"
);
}
tapeserver
.
reset
(
m_tapeserverFactory
.
create
(
DataTransferSession
::
getZmqContext
()));
dataTransferSession
.
reset
(
new
DataTransferSession
(
m_argc
,
m_argv
,
...
...
@@ -1076,46 +1091,46 @@ void castor::tape::tapeserver::daemon::TapeDaemon::runDataTransferSession(
params
.
push_back
(
log
::
Param
(
"errorMessage"
,
ex
.
getMessageValue
()));
params
.
push_back
(
log
::
Param
(
"errorCode"
,
ex
.
code
()));
m_log
(
LOG_ERR
,
"Failed to notify the client of the failed session"
" when setting up the
mount
session"
,
params
);
" when setting up the
data-transfer
session"
,
params
);
}
throw
;
}
catch
(...)
{
try
{
m_log
(
LOG_ERR
,
"got non castor exception error while constructing mount session"
,
params
);
m_log
(
LOG_ERR
,
"Got non castor exception error while constructing"
" data-transfer session"
,
params
);
client
::
ClientProxy
cl
(
drive
->
getVdqmJob
());
client
::
ClientInterface
::
RequestReport
rep
;
cl
.
reportEndOfSessionWithError
(
"Non-Castor exception when setting up the
mount session"
,
SEINTERNAL
,
rep
);
"Non-Castor exception when setting up the
data-transfer session"
,
SEINTERNAL
,
rep
);
}
catch
(...)
{
params
.
push_back
(
log
::
Param
(
"errorMessage"
,
"Non-Castor exception when setting up the
mount
session"
));
"Non-Castor exception when setting up the
data-transfer
session"
));
m_log
(
LOG_ERR
,
"Failed to notify the client of the failed session"
" when setting up the
mount
session"
,
params
);
" when setting up the
data-transfer
session"
,
params
);
}
throw
;
}
m_log
(
LOG_INFO
,
"Going to execute
Mount S
ession"
);
m_log
(
LOG_INFO
,
"Going to execute
data-transfer s
ession"
);
int
result
=
dataTransferSession
->
execute
();
exit
(
result
);
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
params
.
push_back
(
log
::
Param
(
"message"
,
ex
.
getMessageValue
()));
m_log
(
LOG_ERR
,
"
Aborting mount session
: Caught an unexpected CASTOR exception"
,
params
);
m_log
(
LOG_ERR
,
"Aborting data-transfer session"
": Caught an unexpected CASTOR exception"
,
params
);
castor
::
log
::
LogContext
lc
(
m_log
);
lc
.
logBacktrace
(
LOG_ERR
,
ex
.
backtrace
());
exit
(
1
);
}
catch
(
std
::
exception
&
se
)
{
params
.
push_back
(
log
::
Param
(
"message"
,
se
.
what
()));
m_log
(
LOG_ERR
,
"Aborting
mount
session: Caught an unexpected standard exception"
,
"Aborting
data-transfer
session: Caught an unexpected standard exception"
,
params
);
exit
(
1
);
}
catch
(...)
{
m_log
(
LOG_ERR
,
"Aborting mount session: Caught an unexpected and unknown exception"
,
params
);
m_log
(
LOG_ERR
,
"Aborting data-transfer session"
": Caught an unexpected and unknown exception"
,
params
);
exit
(
1
);
}
}
...
...
castor/tape/tapeserver/daemon/TapeDaemon.hpp
View file @
52fc9d28
...
...
@@ -135,6 +135,17 @@ protected:
std
::
string
argvToString
(
const
int
argc
,
const
char
*
const
*
const
argv
)
throw
();
/**
* Idempotent method that closes the socket used to send commands to the
* ProcessForker.
*/
void
closeProcessForkerCmdSenderSocket
()
throw
();
/**
* Idempotent method that destroys the ZMQ context.
*/
void
destroyZmqContext
()
throw
();
/**
* Sets the dumpable attribute of the current process to true.
*/
...
...
@@ -292,9 +303,9 @@ protected:
/**
* Sets the state of the tape drive asscoiated with the specified
*
mount-session
process to down within the vdqmd daemon.
*
child
process to down within the vdqmd daemon.
*
* @param pid The process ID of the
mount-session
child
-
process.
* @param pid The process ID of the child
process.
* @param driveConfig The configuration of the tape drive.
*/
void
setDriveDownInVdqm
(
const
pid_t
pid
,
...
...
@@ -342,7 +353,7 @@ protected:
const
std
::
string
&
vid
,
const
pid_t
pid
);
/**
* Forks a
mount-session child-
process for every tape drive entry in the
* Forks a
data-transfer
process for every tape drive entry in the
* tape drive catalogue that is waiting for such a fork to be carried out.
*
* There may be more than one child-process to fork because there may be
...
...
@@ -353,15 +364,15 @@ protected:
void
forkDataTransferSessions
()
throw
();
/**
* Forks a
mount-session child-
process for the specified tape drive.
* Forks a
data-transfer
process for the specified tape drive.
*
* @param drive The tape-drive entry in the tape-drive catalogue.
*/
void
forkDataTransferSession
(
DriveCatalogueEntry
*
drive
)
throw
();
/**
* Runs the
mount
session. This method is to be called within the
child
* process responsible for running the
mount
session.
* Runs the
data-transfer
session. This method is to be called within the
*
child
process responsible for running the
data-transfer
session.
*
* @param drive The catalogue entry of the tape drive to be used during the
* session.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment