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

Added the cta-mediachanger-mount and dismount utilities

parent b944306c
......@@ -218,3 +218,15 @@ Scripts and utilities to faciliate working with the CTA catalogue
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-lock.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-status.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-unlock.1cta.gz
%package -n cta-mediachangerutils
Summary: Utilities to faciliate working with mediachangers
Group: Application/CTA
%description -n cta-mediachangerutils
CERN Tape Archive:
Utilities to faciliate working with the mediachangers
%files -n cta-mediachangerutils
%attr(0755,root,root) %{_bindir}/cta-mediachanger-dismount
%attr(0755,root,root) %{_bindir}/cta-mediachanger-mount
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-mediachanger-dismount.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-mediachanger-mount.1cta.gz
......@@ -22,12 +22,11 @@
*****************************************************************************/
#include "castor/exception/MissingOperand.hpp"
#include "serrno.h"
// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
castor::exception::MissingOperand::MissingOperand():
castor::exception::Exception(SEMISSINGOPER) {
castor::exception::Exception(666) {
}
......@@ -67,8 +67,7 @@ void castor::legacymsg::RmcProxyTcpIp::mountTapeReadWrite(
castor::utils::copyString(rqstBody.vid, vid);
rqstBody.drvOrd = librarySlot.getDrvOrd();
rmcSendRecvNbAttempts(m_maxRqstAttempts, librarySlot.getRmcHostName(),
rqstBody);
rmcSendRecvNbAttempts(m_maxRqstAttempts, rqstBody);
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() <<
......@@ -92,8 +91,7 @@ void castor::legacymsg::RmcProxyTcpIp::dismountTape(const std::string &vid,
rqstBody.drvOrd = librarySlot.getDrvOrd();
rqstBody.force = 0;
rmcSendRecvNbAttempts(m_maxRqstAttempts, librarySlot.getRmcHostName(),
rqstBody);
rmcSendRecvNbAttempts(m_maxRqstAttempts, rqstBody);
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() <<
......@@ -116,8 +114,9 @@ void castor::legacymsg::RmcProxyTcpIp::forceDismountTape(const std::string &vid,
//-----------------------------------------------------------------------------
// connectToRmc
//-----------------------------------------------------------------------------
int castor::legacymsg::RmcProxyTcpIp::connectToRmc(const std::string &rmcHost)
int castor::legacymsg::RmcProxyTcpIp::connectToRmc()
const {
const std::string rmcHost = "localhost";
castor::utils::SmartFd smartConnectSock;
try {
smartConnectSock.reset(io::connectWithTimeout(rmcHost, m_rmcPort,
......
......@@ -30,8 +30,8 @@
#include "castor/utils/utils.hpp"
#include "h/rmc_constants.h"
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
/*
*------------------------------------------------------------------------
......@@ -39,17 +39,17 @@
*------------------------------------------------------------------------
*/
#define ERMBASEOFF 2200 /* RMC error base offset */
#define ERMCNACT ERMBASEOFF+1 /* Remote SCSI media changer server not active or service being drained */
#define ERMCRBTERR (ERMBASEOFF+2) /* Remote SCSI media changer error */
#define ERMCUNREC ERMCRBTERR+1 /* Remote SCSI media changer unrec. error */
#define ERMCSLOWR ERMCRBTERR+2 /* Remote SCSI media changer error (slow retry) */
#define ERMCFASTR ERMCRBTERR+3 /* Remote SCSI media changer error (fast retry) */
#define ERMCDFORCE ERMCRBTERR+4 /* Remote SCSI media changer error (demount force) */
#define ERMCDDOWN ERMCRBTERR+5 /* Remote SCSI media changer error (drive down) */
#define ERMCOMSGN ERMCRBTERR+6 /* Remote SCSI media changer error (ops message) */
#define ERMCOMSGS ERMCRBTERR+7 /* Remote SCSI media changer error (ops message + retry) */
#define ERMCOMSGR ERMCRBTERR+8 /* Remote SCSI media changer error (ops message + wait) */
#define ERMCUNLOAD ERMCRBTERR+9 /* Remote SCSI media changer error (unload + demount) */
#define ERMCNACT ERMBASEOFF+1 /* Remote SCSI media changer server not active or service being drained */
#define ERMCRBTERR (ERMBASEOFF+2) /* Remote SCSI media changer error */
#define ERMCUNREC ERMCRBTERR+1 /* Remote SCSI media changer unrec. error */
#define ERMCSLOWR ERMCRBTERR+2 /* Remote SCSI media changer error (slow retry) */
#define ERMCFASTR ERMCRBTERR+3 /* Remote SCSI media changer error (fast retry) */
#define ERMCDFORCE ERMCRBTERR+4 /* Remote SCSI media changer error (demount force) */
#define ERMCDDOWN ERMCRBTERR+5 /* Remote SCSI media changer error (drive down) */
#define ERMCOMSGN ERMCRBTERR+6 /* Remote SCSI media changer error (ops message) */
#define ERMCOMSGS ERMCRBTERR+7 /* Remote SCSI media changer error (ops message + retry) */
#define ERMCOMSGR ERMCRBTERR+8 /* Remote SCSI media changer error (ops message + wait) */
#define ERMCUNLOAD ERMCRBTERR+9 /* Remote SCSI media changer error (unload + demount) */
#define ERMMAXERR ERMBASEOFF+11
namespace castor {
......@@ -153,10 +153,11 @@ protected:
/**
* Connects to the rmcd daemon.
*
* @param rmcHost The name of the host on which the rmcd daemon is running.
* Please note that the rmcd daemon only listens on loopback interface.
*
* @return The socket-descriptor of the connection with the rmcd daemon.
*/
int connectToRmc(const std::string &rmcHost) const ;
int connectToRmc() const ;
/**
* Writes an RMC_SCSI_MOUNT message with the specifed body to the specified
......@@ -190,14 +191,13 @@ protected:
* reached.
*
* @param maxAttempts The maximum number of retriable attempts.
* @param rmcHost The name of the host on which the rmcd daemon is running.
* @param rqstBody The request to be sent.
*/
template<typename T> void rmcSendRecvNbAttempts(const int maxAttempts,
const std::string &rmcHost, const T &rqstBody) {
const T &rqstBody) {
for(int attemptNb = 1; attemptNb <= maxAttempts; attemptNb++) {
std::ostringstream rmcErrorStream;
const int rmcRc = rmcSendRecv(rmcHost, rqstBody, rmcErrorStream);
const int rmcRc = rmcSendRecv(rqstBody, rmcErrorStream);
switch(rmcRc) {
case 0: // Success
return;
......@@ -232,16 +232,15 @@ protected:
/**
* Sends the specified request to the rmcd daemon and receives the reply.
*
* @param rmcHost The name of the host on which the rmcd daemon is running.
* @param rqstBody The request to be sent.
* @param rmcErrorStream The error stream constructed from ERR_MSG received
* within the reply from the rmcd daemon.
* @param The RMC return code.
*/
template<typename T> int rmcSendRecv(const std::string &rmcHost,
const T &rqstBody, std::ostringstream &rmcErrorStream) {
template<typename T> int rmcSendRecv(const T &rqstBody,
std::ostringstream &rmcErrorStream) {
// Connect to rmcd and send request
castor::utils::SmartFd fd(connectToRmc(rmcHost));
castor::utils::SmartFd fd(connectToRmc());
{
char buf[RMC_MSGBUFSIZ];
const size_t len = marshal(buf, rqstBody);
......
......@@ -14,12 +14,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# @author Castor Dev team, castor-dev@cern.ch
#
cmake_minimum_required (VERSION 2.6)
include_directories(${CMAKE_SOURCE_DIR}/tapeserver)
include_directories(${PROJECT_BINARY_DIR}/tapeserver)
set (MEDIA_CHANGER_LIB_SRC_FILES
AcsLibrarySlot.cpp
......@@ -37,3 +37,46 @@ add_library(ctamediachanger ${MEDIA_CHANGER_LIB_SRC_FILES})
add_library(ctamediachangerutils SHARED
MmcProxyDummy.cpp)
install(TARGETS ctamediachangerutils DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
set (MEDIA_CHANGER_MOUNT_SRC_FILES
CmdLine.cpp
CmdLineTool.cpp
DebugBuf.cpp
MountCmd.cpp
MountCmdLine.cpp
MountCmdMain.cpp)
add_executable (cta-mediachanger-mount ${MEDIA_CHANGER_MOUNT_SRC_FILES})
set_target_properties (cta-mediachanger-mount PROPERTIES
COMPILE_FLAGS -I/usr/include/CDK
COMPILE_DEFINITIONS LINUX)
target_link_libraries (cta-mediachanger-mount
ctacommon
ctalegacymsg
ctamediachanger
ctamessages
ctautils
ctaio)
install (TARGETS cta-mediachanger-mount DESTINATION /usr/bin)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-mediachanger-mount.1cta DESTINATION /usr/share/man/man1)
set (MEDIA_CHANGER_DISMOUNT_SRC_FILES
CmdLine.cpp
CmdLineTool.cpp
DebugBuf.cpp
DismountCmd.cpp
DismountCmdLine.cpp
DismountCmdMain.cpp)
add_executable (cta-mediachanger-dismount
${MEDIA_CHANGER_DISMOUNT_SRC_FILES})
set_target_properties (cta-mediachanger-dismount PROPERTIES
COMPILE_FLAGS -I/usr/include/CDK
COMPILE_DEFINITIONS LINUX)
target_link_libraries (cta-mediachanger-dismount
ctacommon
ctalegacymsg
ctamediachanger
ctamessages
ctautils
ctaio)
install (TARGETS cta-mediachanger-dismount DESTINATION /usr/bin)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-mediachanger-dismount.1cta DESTINATION /usr/share/man/man1)
......@@ -24,6 +24,7 @@
#include "castor/mediachanger/CmdLine.hpp"
#include "castor/exception/InvalidArgument.hpp"
#include "castor/exception/MissingOperand.hpp"
#include <getopt.h>
//------------------------------------------------------------------------------
// handleMissingParameter
......
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/mediachanger/CmdLineTool.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::mediachanger::CmdLineTool::CmdLineTool(
std::istream &inStream,
std::ostream &outStream,
std::ostream &errStream,
MediaChangerFacade &mc) throw():
m_in(inStream),
m_out(outStream),
m_err(errStream),
m_mc(mc),
m_debugBuf(outStream),
m_dbg(&m_debugBuf) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::mediachanger::CmdLineTool::~CmdLineTool() throw() {
}
//------------------------------------------------------------------------------
// bool2Str
//------------------------------------------------------------------------------
std::string castor::mediachanger::CmdLineTool::bool2Str(const bool value)
const throw() {
return value ? "TRUE" : "FALSE";
}
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include "castor/mediachanger/MediaChangerFacade.hpp"
#include "castor/mediachanger/DebugBuf.hpp"
#include <istream>
#include <ostream>
#include <string>
namespace castor {
namespace mediachanger {
/**
* Abstract class implementing common code and data structures for a
* command-line tool.
*/
class CmdLineTool {
public:
/**
* Constructor.
*
* @param inStream Standard input stream.
* @param outStream Standard output stream.
* @param errStream Standard error stream.
* @param mc Interface to the media changer.
*/
CmdLineTool(std::istream &inStream, std::ostream &outStream,
std::ostream &errStream, MediaChangerFacade &mc)
throw();
/**
* Pure-virtual destructor to guarantee this class is abstract.
*/
virtual ~CmdLineTool() throw() = 0;
protected:
/**
* Standard input stream.
*/
std::istream &m_in;
/**
* Standard output stream.
*/
std::ostream &m_out;
/**
* Standard error stream.
*/
std::ostream &m_err;
/**
* Interface to the media changer.
*/
MediaChangerFacade &m_mc;
/**
* Debug stream buffer that inserts a standard debug preamble before each
* message-line written to it.
*/
DebugBuf m_debugBuf;
/**
* Stream used to write debug messages.
*
* This stream will insert a standard debug preamble before each message-line
* written to it.
*/
std::ostream m_dbg;
/**
* Returns the string representation of the specfied boolean value.
*
* @param value The boolean value.
*/
std::string bool2Str(const bool value) const throw();
}; // class CmdLineTool
} // namespace mediachanger
} // namespace castor
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/mediachanger/DebugBuf.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::mediachanger::DebugBuf::DebugBuf(std::ostream &os):
m_debug(false), m_os(os), m_writePreamble(true) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::mediachanger::DebugBuf::~DebugBuf() {
}
//------------------------------------------------------------------------------
// setDebug
//------------------------------------------------------------------------------
void castor::mediachanger::DebugBuf::setDebug(const bool value) throw() {
m_debug = value;
}
//------------------------------------------------------------------------------
// overflow
//------------------------------------------------------------------------------
std::streambuf::int_type castor::mediachanger::DebugBuf::overflow(
const int_type c) {
// Only write something if debug mode is on
if(m_debug) {
if(m_writePreamble) {
writePreamble();
m_writePreamble = false;
}
m_os << (char)c;
}
// If an end of line was encountered then the next write should be preceeded
// with a preamble
if('\n' == (char)c) {
m_writePreamble = true;
}
return c;
}
//------------------------------------------------------------------------------
// writePreamble
//------------------------------------------------------------------------------
void castor::mediachanger::DebugBuf::writePreamble() throw() {
m_os << "DEBUG: ";
}
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include <ostream>
#include <streambuf>
namespace castor {
namespace mediachanger {
/**
* Stream buffer class used to prepend a standard preamble to debug
* message-lines.
*
* This stream buffer does not write any output if debug mode has not been
* turned on by calling setDebugMode(true). Any debug message written to this
* stream buffer will be discarded if debug mode is off.
*/
class DebugBuf : public std::streambuf {
public:
/**
* Constructor.
*
* Initialises the the debug mode to be off.
*
* @param os The output stream to which each debug message-line togther with
* its standard preamble shall be written.
*/
DebugBuf(std::ostream &os);
/**
* Destructor.
*/
~DebugBuf();
/**
* Set the debug mode to be on (true) or off (false).
*
* The default set in the constructor is off (false).
*/
void setDebug(const bool value) throw();
protected:
/**
* Sends the specified character to the output channnel.
*/
int_type overflow (const int_type c);
/**
* Writes the standard preamble to the output stream.
*/
void writePreamble() throw();
private:
/**
* True if debug mode is on.
*/
bool m_debug;
/**
* The output stream to which each debug message-line togther with its
* standard preamble shall be written.
*/
std::ostream &m_os;
/**
* True is a preamble should be written.
*/
bool m_writePreamble;
}; // class DebugBuf
} // namespace mediachanger
} // namespace castor
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/mediachanger/DismountCmd.hpp"
#include <getopt.h>
#include <iostream>
#include <memory>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::mediachanger::DismountCmd::DismountCmd(
std::istream &inStream, std::ostream &outStream, std::ostream &errStream,
MediaChangerFacade &mc) throw():
CmdLineTool(inStream, outStream, errStream, mc) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::mediachanger::DismountCmd::~DismountCmd() throw() {
// Do nothing
}
//------------------------------------------------------------------------------
// exceptionThrowingMain
//------------------------------------------------------------------------------
int castor::mediachanger::DismountCmd::exceptionThrowingMain(const int argc,
char *const *const argv) {
try {
m_cmdLine = DismountCmdLine(argc, argv);
} catch(castor::exception::Exception &ex) {
m_err << ex.getMessage().str() << std::endl;