Commit 2603eb76 authored by David COME's avatar David COME
Browse files

Merge remote branch 'origin/tapeserver' into tapeserver

Conflicts:
	castor/tape/tapeserver/daemon/LabelSession.cpp
	castor/tape/tapeserver/daemon/MountSession.cpp
	castor/tape/tapeserver/daemon/MountSessionAcceptHandler.cpp
	castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
parents 61253b15 383d3694
......@@ -391,6 +391,9 @@ size_t castor::legacymsg::marshal(char *const dst, const size_t dstLen, const Ta
// Calculate the length of the message body
const uint32_t bodyLen =
sizeof(uint32_t) + // event
sizeof(uint32_t) + // mode
sizeof(uint32_t) + // clientType
strlen(src.vid) + 1 + // vid
strlen(src.drive) + 1; // drive
......@@ -426,6 +429,9 @@ size_t castor::legacymsg::marshal(char *const dst, const size_t dstLen, const Ta
// Marshal message body
try {
io::marshalUint32(src.event, p);
io::marshalUint32(src.mode, p);
io::marshalUint32(src.clientType, p);
io::marshalString(src.vid, p);
io::marshalString(src.drive, p);
} catch(castor::exception::Exception &ne) {
......@@ -484,6 +490,9 @@ void castor::legacymsg::unmarshal(const char * &src, size_t &srcLen, TapeStatRep
//-----------------------------------------------------------------------------
void castor::legacymsg::unmarshal(const char * &src, size_t &srcLen, TapeUpdateDriveRqstMsgBody &dst) {
try {
io::unmarshalUint32(src, srcLen, dst.event);
io::unmarshalUint32(src, srcLen, dst.mode);
io::unmarshalUint32(src, srcLen, dst.clientType);
io::unmarshalString(src, srcLen, dst.vid);
io::unmarshalString(src, srcLen, dst.drive);
} catch(castor::exception::Exception &ne) {
......
......@@ -141,11 +141,15 @@ TEST_F(castor_legacymsg_TapeMarshalTest, marshalTapeStatRequestMsgBody) {
TEST_F(castor_legacymsg_TapeMarshalTest, marshalTapeUpdateDriveRqstMsgBody) {
using namespace castor::legacymsg;
char buf[25]; // Expect message (header + body) to occupy exactly 25 bytes
char buf[37]; // Expect message (header + body) to occupy exactly 25 bytes
TapeUpdateDriveRqstMsgBody srcMsgBody;
// Marshal entire message (header + body)
{
srcMsgBody.event = 1;
srcMsgBody.mode = 2;
srcMsgBody.clientType = 3;
castor::utils::copyString(srcMsgBody.vid, "VIDVID");
castor::utils::copyString(srcMsgBody.drive, "DRIVE");
......@@ -153,7 +157,7 @@ TEST_F(castor_legacymsg_TapeMarshalTest, marshalTapeUpdateDriveRqstMsgBody) {
size_t totalLen = 0; // Total length of message (header + body)
ASSERT_NO_THROW(totalLen = marshal(buf, bufLen, srcMsgBody));
ASSERT_EQ((uint32_t)25, totalLen);
ASSERT_EQ((uint32_t)37, totalLen);
}
// Unmarshall message header
......@@ -167,7 +171,7 @@ TEST_F(castor_legacymsg_TapeMarshalTest, marshalTapeUpdateDriveRqstMsgBody) {
ASSERT_EQ((uint32_t)TPMAGIC, dstHeader.magic);
ASSERT_EQ((uint32_t)SETVID, dstHeader.reqType);
ASSERT_EQ((uint32_t)25, dstHeader.lenOrStatus);
ASSERT_EQ((uint32_t)37, dstHeader.lenOrStatus);
}
// Unmarshall message body
......@@ -175,11 +179,15 @@ TEST_F(castor_legacymsg_TapeMarshalTest, marshalTapeUpdateDriveRqstMsgBody) {
TapeUpdateDriveRqstMsgBody dstMsgBody;
const char *bufPtr = buf + 12; // Point at beginning of message body
size_t bufLen = 13; // Length of the message body
size_t bufLen = 25; // Length of the message body
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstMsgBody));
ASSERT_EQ(buf + 25, bufPtr);
ASSERT_EQ(buf + 37, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)1, dstMsgBody.event);
ASSERT_EQ((uint32_t)2, dstMsgBody.mode);
ASSERT_EQ((uint32_t)3, dstMsgBody.clientType);
ASSERT_EQ(std::string("VIDVID"), dstMsgBody.vid);
ASSERT_EQ(std::string("DRIVE"), dstMsgBody.drive);
}
......
......@@ -26,7 +26,11 @@
#include <string.h>
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeUpdateDriveRqstMsgBody() throw() {
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeUpdateDriveRqstMsgBody() throw():
event(TAPE_STATUS_NONE),
mode(TAPE_MODE_NONE),
clientType(CLIENT_TYPE_NONE)
{
memset(vid, '\0', sizeof(vid));
memset(drive, '\0', sizeof(drive));
}
......@@ -24,6 +24,8 @@
#pragma once
#include "castor/tape/tapegateway/ClientType.hpp"
#include "castor/tape/tapegateway/VolumeMode.hpp"
#include "h/Castor_limits.h"
#include <stdint.h>
......@@ -36,6 +38,44 @@ namespace legacymsg {
*/
struct TapeUpdateDriveRqstMsgBody {
/**
* The status of the tape with respect to the drive mount and unmount operations
*/
enum tapeEvent {
TAPE_STATUS_NONE,
TAPE_STATUS_MOUNT_STARTED,
TAPE_STATUS_MOUNTED,
TAPE_STATUS_UNMOUNT_STARTED,
TAPE_STATUS_UNMOUNTED
};
uint32_t event;
/**
* Are we mounting for read, write (read/write), or dump
*/
enum tapeMode {
TAPE_MODE_NONE,
TAPE_MODE_READ,
TAPE_MODE_READWRITE,
TAPE_MODE_DUMP
};
uint32_t mode;
/**
* The client could be the gateway, readtp, writetp, or dumptp
*/
enum tapeClientType {
CLIENT_TYPE_NONE,
CLIENT_TYPE_GATEWAY,
CLIENT_TYPE_READTP,
CLIENT_TYPE_WRITETP,
CLIENT_TYPE_DUMPTP
};
uint32_t clientType;
/**
* The VID of the tape inside the drive ("" if empty)
*/
......
......@@ -25,6 +25,7 @@
#include "castor/log/Logger.hpp"
#include "castor/legacymsg/MessageHeader.hpp"
#include "castor/legacymsg/TapeUpdateDriveRqstMsgBody.hpp"
#include "castor/tape/tapeserver/client/ClientProxy.hpp"
namespace castor {
namespace legacymsg {
......@@ -47,70 +48,60 @@ public:
* Notifies the tapeserverd daemon that the mount-session child-process got
* the mount details from the client.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void gotReadMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void gotReadMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the mount-session child-process got
* the mount details from the client.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void gotWriteMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void gotWriteMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the mount-session child-process got
* the mount details from the client.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void gotDumpMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void gotDumpMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the specified tape has been mounted.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void tapeMountedForRead(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void tapeMountedForRead(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the specified tape has been mounted.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void tapeMountedForWrite(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void tapeMountedForWrite(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the specified tape is unmounting.
*
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void tapeUnmounting(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
/**
* Notifies the tapeserverd daemon that the specified tape has been unmounted.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
* @param volInfo The volume information of the tape the session is working with
* @param unitName The unit name of the tape drive.
*/
virtual void tapeUnmounted(
const std::string &unitName,
const std::string &vid)
= 0;
virtual void tapeUnmounted(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName) = 0;
}; // class TapeserverProxy
......
......@@ -37,53 +37,48 @@ castor::legacymsg::TapeserverProxyDummy::~TapeserverProxyDummy() throw() {
//------------------------------------------------------------------------------
// gotReadMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::gotReadMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::gotReadMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// gotWriteMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::gotWriteMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::gotWriteMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// gotDumpMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::gotDumpMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::gotDumpMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// tapeMountedForRead
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::tapeMountedForRead(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::tapeMountedForRead(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// tapeMountedForWrite
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::tapeMountedForWrite(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::tapeMountedForWrite(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// tapeUnmounting
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::tapeUnmounting(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
//------------------------------------------------------------------------------
// tapeUnmounted
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyDummy::tapeUnmounted(
const std::string &unitName,
const std::string &vid)
void castor::legacymsg::TapeserverProxyDummy::tapeUnmounted(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
}
......@@ -53,10 +53,7 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void gotReadMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
;
void gotReadMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Informs the tapeserverd daemon that the mount-session child-process got
......@@ -65,10 +62,7 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void gotWriteMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
;
void gotWriteMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Informs the tapeserverd daemon that the mount-session child-process got
......@@ -77,10 +71,7 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void gotDumpMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
;
void gotDumpMountDetailsFromClient(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Notifies the tapeserverd daemon that the specified tape has been mounted.
......@@ -88,10 +79,7 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void tapeMountedForRead(
const std::string &unitName,
const std::string &vid)
;
void tapeMountedForRead(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Notifies the tapeserverd daemon that the specified tape has been mounted.
......@@ -99,10 +87,15 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void tapeMountedForWrite(
const std::string &unitName,
const std::string &vid)
;
void tapeMountedForWrite(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Notifies the tapeserverd daemon that the specified tape is unmounting.
*
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void tapeUnmounting(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
/**
* Notifies the tapeserverd daemon that the specified tape has been unmounted.
......@@ -110,10 +103,7 @@ public:
* @param unitName The unit name of the tape drive.
* @param vid The Volume ID of the tape to be mounted.
*/
void tapeUnmounted(
const std::string &unitName,
const std::string &vid)
;
void tapeUnmounted(castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName);
}; // class TapeserverProxyDummy
......
......@@ -22,8 +22,13 @@
#include "castor/io/io.hpp"
#include "castor/legacymsg/CommonMarshal.hpp"
#include "castor/legacymsg/GenericReplyMsgBody.hpp"
#include "castor/legacymsg/GenericMarshal.hpp"
#include "castor/legacymsg/TapeMarshal.hpp"
#include "castor/legacymsg/TapeserverProxyTcpIp.hpp"
#include "castor/legacymsg/legacymsg.hpp"
#include "castor/tape/tapegateway/ClientType.hpp"
#include "castor/tape/tapegateway/VolumeMode.hpp"
#include "castor/utils/SmartFd.hpp"
#include "castor/utils/utils.hpp"
#include "h/rtcp_constants.h"
......@@ -47,14 +52,51 @@ castor::legacymsg::TapeserverProxyTcpIp::~TapeserverProxyTcpIp() throw() {
}
//------------------------------------------------------------------------------
// gotReadMountDetailsFromClient
// updateDrive
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::gotReadMountDetailsFromClient(
void castor::legacymsg::TapeserverProxyTcpIp::updateDriveInfo(
const castor::legacymsg::TapeUpdateDriveRqstMsgBody::tapeEvent event,
const castor::tape::tapegateway::VolumeMode mode,
const castor::tape::tapegateway::ClientType clientType,
const std::string &unitName,
const std::string &vid)
{
try {
legacymsg::TapeUpdateDriveRqstMsgBody body;
{
legacymsg::TapeUpdateDriveRqstMsgBody body;
try {
switch(clientType) {
case castor::tape::tapegateway::TAPE_GATEWAY:
body.clientType=castor::legacymsg::TapeUpdateDriveRqstMsgBody::CLIENT_TYPE_GATEWAY;
break;
case castor::tape::tapegateway::READ_TP:
body.clientType=castor::legacymsg::TapeUpdateDriveRqstMsgBody::CLIENT_TYPE_READTP;
break;
case castor::tape::tapegateway::WRITE_TP:
body.clientType=castor::legacymsg::TapeUpdateDriveRqstMsgBody::CLIENT_TYPE_WRITETP;
break;
case castor::tape::tapegateway::DUMP_TP:
body.clientType=castor::legacymsg::TapeUpdateDriveRqstMsgBody::CLIENT_TYPE_DUMPTP;
break;
default:
body.clientType=castor::legacymsg::TapeUpdateDriveRqstMsgBody::CLIENT_TYPE_NONE;
break;
}
switch(mode) {
case castor::tape::tapegateway::READ:
body.mode=castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_MODE_READ;
break;
case castor::tape::tapegateway::WRITE:
body.mode=castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_MODE_READWRITE;
break;
case castor::tape::tapegateway::DUMP:
body.mode=castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_MODE_DUMP;
break;
default:
body.mode=castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_MODE_NONE;
break;
}
body.event=event;
castor::utils::copyString(body.vid, vid.c_str());
castor::utils::copyString(body.drive, unitName.c_str());
castor::utils::SmartFd fd(connectToTapeserver());
......@@ -62,81 +104,113 @@ void castor::legacymsg::TapeserverProxyTcpIp::gotReadMountDetailsFromClient(
readReplyMsg(fd.get());
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to notify tapeserverd of read mount: unitName="
<< unitName << " vid=" << vid << ": " << ne.getMessage().str();
ex.getMessage() << "Failed to notify tapeserverd of drive info update: "
<< " event = "<< body.event
<< " mode = " << body.mode
<< " clientType = " << body.clientType
<< " unitName = " << body.drive
<< " vid = " << body.vid
<< ": " << ne.getMessage().str();
throw ex;
}
}
//------------------------------------------------------------------------------
// gotReadMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::gotReadMountDetailsFromClient(
castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
updateDriveInfo(
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_MOUNT_STARTED,
volInfo.volumeMode,
volInfo.clientType,
unitName,
volInfo.vid);
}
//------------------------------------------------------------------------------
// gotWriteMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::gotWriteMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
{
try {
legacymsg::TapeUpdateDriveRqstMsgBody body;
castor::utils::copyString(body.vid, vid.c_str());
castor::utils::copyString(body.drive, unitName.c_str());
castor::utils::SmartFd fd(connectToTapeserver());
writeTapeUpdateDriveRqstMsg(fd.get(), body);
readReplyMsg(fd.get());
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to notify tapeserverd of read mount: unitName="
<< unitName << " vid=" << vid << ": " << ne.getMessage().str();
throw ex;
}
castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
updateDriveInfo(
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_MOUNT_STARTED,
volInfo.volumeMode,
volInfo.clientType,
unitName,
volInfo.vid);
}
//------------------------------------------------------------------------------
// gotDumpMountDetailsFromClient
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::gotDumpMountDetailsFromClient(
const std::string &unitName,
const std::string &vid)
{
try {
legacymsg::TapeUpdateDriveRqstMsgBody body;
castor::utils::copyString(body.vid, vid.c_str());
castor::utils::copyString(body.drive, unitName.c_str());
castor::utils::SmartFd fd(connectToTapeserver());
writeTapeUpdateDriveRqstMsg(fd.get(), body);
readReplyMsg(fd.get());
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to notify tapeserverd of read mount: unitName="
<< unitName << " vid=" << vid << ": " << ne.getMessage().str();
throw ex;
}
castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
updateDriveInfo(
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_MOUNT_STARTED,
volInfo.volumeMode,
volInfo.clientType,
unitName,
volInfo.vid);
}
//------------------------------------------------------------------------------
// tapeMountedForRead
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::tapeMountedForRead(
const std::string &unitName,
const std::string &vid)
{
castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
updateDriveInfo(
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_MOUNTED,
volInfo.volumeMode,
volInfo.clientType,
unitName,
volInfo.vid);
}
//------------------------------------------------------------------------------
// tapeMountedForWrite
//------------------------------------------------------------------------------
void castor::legacymsg::TapeserverProxyTcpIp::tapeMountedForWrite(
const std::string &unitName,
const std::string &vid)
{
}
castor::tape::tapeserver::client::ClientProxy::VolumeInfo volInfo, const std::string &unitName)
{
updateDriveInfo(
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_MOUNTED,
volInfo.volumeMode,
volInfo.clientType,
unitName,
volInfo.vid);
}
//------------------------------------------------------------------------------
// tapeUnmounting
//------------------------------------------------------------------------------