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 ...@@ -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-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-status.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-unlock.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 @@ ...@@ -22,12 +22,11 @@
*****************************************************************************/ *****************************************************************************/
#include "castor/exception/MissingOperand.hpp" #include "castor/exception/MissingOperand.hpp"
#include "serrno.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Constructor // Constructor
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
castor::exception::MissingOperand::MissingOperand(): castor::exception::MissingOperand::MissingOperand():
castor::exception::Exception(SEMISSINGOPER) { castor::exception::Exception(666) {
} }
...@@ -67,8 +67,7 @@ void castor::legacymsg::RmcProxyTcpIp::mountTapeReadWrite( ...@@ -67,8 +67,7 @@ void castor::legacymsg::RmcProxyTcpIp::mountTapeReadWrite(
castor::utils::copyString(rqstBody.vid, vid); castor::utils::copyString(rqstBody.vid, vid);
rqstBody.drvOrd = librarySlot.getDrvOrd(); rqstBody.drvOrd = librarySlot.getDrvOrd();
rmcSendRecvNbAttempts(m_maxRqstAttempts, librarySlot.getRmcHostName(), rmcSendRecvNbAttempts(m_maxRqstAttempts, rqstBody);
rqstBody);
} catch(castor::exception::Exception &ne) { } catch(castor::exception::Exception &ne) {
castor::exception::Exception ex; castor::exception::Exception ex;
ex.getMessage() << ex.getMessage() <<
...@@ -92,8 +91,7 @@ void castor::legacymsg::RmcProxyTcpIp::dismountTape(const std::string &vid, ...@@ -92,8 +91,7 @@ void castor::legacymsg::RmcProxyTcpIp::dismountTape(const std::string &vid,
rqstBody.drvOrd = librarySlot.getDrvOrd(); rqstBody.drvOrd = librarySlot.getDrvOrd();
rqstBody.force = 0; rqstBody.force = 0;
rmcSendRecvNbAttempts(m_maxRqstAttempts, librarySlot.getRmcHostName(), rmcSendRecvNbAttempts(m_maxRqstAttempts, rqstBody);
rqstBody);
} catch(castor::exception::Exception &ne) { } catch(castor::exception::Exception &ne) {
castor::exception::Exception ex; castor::exception::Exception ex;
ex.getMessage() << ex.getMessage() <<
...@@ -116,8 +114,9 @@ void castor::legacymsg::RmcProxyTcpIp::forceDismountTape(const std::string &vid, ...@@ -116,8 +114,9 @@ void castor::legacymsg::RmcProxyTcpIp::forceDismountTape(const std::string &vid,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// connectToRmc // connectToRmc
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int castor::legacymsg::RmcProxyTcpIp::connectToRmc(const std::string &rmcHost) int castor::legacymsg::RmcProxyTcpIp::connectToRmc()
const { const {
const std::string rmcHost = "localhost";
castor::utils::SmartFd smartConnectSock; castor::utils::SmartFd smartConnectSock;
try { try {
smartConnectSock.reset(io::connectWithTimeout(rmcHost, m_rmcPort, smartConnectSock.reset(io::connectWithTimeout(rmcHost, m_rmcPort,
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include "castor/utils/utils.hpp" #include "castor/utils/utils.hpp"
#include "h/rmc_constants.h" #include "h/rmc_constants.h"
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
/* /*
*------------------------------------------------------------------------ *------------------------------------------------------------------------
...@@ -39,17 +39,17 @@ ...@@ -39,17 +39,17 @@
*------------------------------------------------------------------------ *------------------------------------------------------------------------
*/ */
#define ERMBASEOFF 2200 /* RMC error base offset */ #define ERMBASEOFF 2200 /* RMC error base offset */
#define ERMCNACT ERMBASEOFF+1 /* Remote SCSI media changer server not active or service being drained */ #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 ERMCRBTERR (ERMBASEOFF+2) /* Remote SCSI media changer error */
#define ERMCUNREC ERMCRBTERR+1 /* Remote SCSI media changer unrec. error */ #define ERMCUNREC ERMCRBTERR+1 /* Remote SCSI media changer unrec. error */
#define ERMCSLOWR ERMCRBTERR+2 /* Remote SCSI media changer error (slow retry) */ #define ERMCSLOWR ERMCRBTERR+2 /* Remote SCSI media changer error (slow retry) */
#define ERMCFASTR ERMCRBTERR+3 /* Remote SCSI media changer error (fast retry) */ #define ERMCFASTR ERMCRBTERR+3 /* Remote SCSI media changer error (fast retry) */
#define ERMCDFORCE ERMCRBTERR+4 /* Remote SCSI media changer error (demount force) */ #define ERMCDFORCE ERMCRBTERR+4 /* Remote SCSI media changer error (demount force) */
#define ERMCDDOWN ERMCRBTERR+5 /* Remote SCSI media changer error (drive down) */ #define ERMCDDOWN ERMCRBTERR+5 /* Remote SCSI media changer error (drive down) */
#define ERMCOMSGN ERMCRBTERR+6 /* Remote SCSI media changer error (ops message) */ #define ERMCOMSGN ERMCRBTERR+6 /* Remote SCSI media changer error (ops message) */
#define ERMCOMSGS ERMCRBTERR+7 /* Remote SCSI media changer error (ops message + retry) */ #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 ERMCOMSGR ERMCRBTERR+8 /* Remote SCSI media changer error (ops message + wait) */
#define ERMCUNLOAD ERMCRBTERR+9 /* Remote SCSI media changer error (unload + demount) */ #define ERMCUNLOAD ERMCRBTERR+9 /* Remote SCSI media changer error (unload + demount) */
#define ERMMAXERR ERMBASEOFF+11 #define ERMMAXERR ERMBASEOFF+11
namespace castor { namespace castor {
...@@ -153,10 +153,11 @@ protected: ...@@ -153,10 +153,11 @@ protected:
/** /**
* Connects to the rmcd daemon. * 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. * @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 * Writes an RMC_SCSI_MOUNT message with the specifed body to the specified
...@@ -190,14 +191,13 @@ protected: ...@@ -190,14 +191,13 @@ protected:
* reached. * reached.
* *
* @param maxAttempts The maximum number of retriable attempts. * @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. * @param rqstBody The request to be sent.
*/ */
template<typename T> void rmcSendRecvNbAttempts(const int maxAttempts, 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++) { for(int attemptNb = 1; attemptNb <= maxAttempts; attemptNb++) {
std::ostringstream rmcErrorStream; std::ostringstream rmcErrorStream;
const int rmcRc = rmcSendRecv(rmcHost, rqstBody, rmcErrorStream); const int rmcRc = rmcSendRecv(rqstBody, rmcErrorStream);
switch(rmcRc) { switch(rmcRc) {
case 0: // Success case 0: // Success
return; return;
...@@ -232,16 +232,15 @@ protected: ...@@ -232,16 +232,15 @@ protected:
/** /**
* Sends the specified request to the rmcd daemon and receives the reply. * 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 rqstBody The request to be sent.
* @param rmcErrorStream The error stream constructed from ERR_MSG received * @param rmcErrorStream The error stream constructed from ERR_MSG received
* within the reply from the rmcd daemon. * within the reply from the rmcd daemon.
* @param The RMC return code. * @param The RMC return code.
*/ */
template<typename T> int rmcSendRecv(const std::string &rmcHost, template<typename T> int rmcSendRecv(const T &rqstBody,
const T &rqstBody, std::ostringstream &rmcErrorStream) { std::ostringstream &rmcErrorStream) {
// Connect to rmcd and send request // Connect to rmcd and send request
castor::utils::SmartFd fd(connectToRmc(rmcHost)); castor::utils::SmartFd fd(connectToRmc());
{ {
char buf[RMC_MSGBUFSIZ]; char buf[RMC_MSGBUFSIZ];
const size_t len = marshal(buf, rqstBody); const size_t len = marshal(buf, rqstBody);
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
#
# @author Castor Dev team, castor-dev@cern.ch # @author Castor Dev team, castor-dev@cern.ch
# #
cmake_minimum_required (VERSION 2.6) cmake_minimum_required (VERSION 2.6)
include_directories(${CMAKE_SOURCE_DIR}/tapeserver) include_directories(${CMAKE_SOURCE_DIR}/tapeserver)
include_directories(${PROJECT_BINARY_DIR}/tapeserver)
set (MEDIA_CHANGER_LIB_SRC_FILES set (MEDIA_CHANGER_LIB_SRC_FILES
AcsLibrarySlot.cpp AcsLibrarySlot.cpp
...@@ -37,3 +37,46 @@ add_library(ctamediachanger ${MEDIA_CHANGER_LIB_SRC_FILES}) ...@@ -37,3 +37,46 @@ add_library(ctamediachanger ${MEDIA_CHANGER_LIB_SRC_FILES})
add_library(ctamediachangerutils SHARED add_library(ctamediachangerutils SHARED
MmcProxyDummy.cpp) MmcProxyDummy.cpp)
install(TARGETS ctamediachangerutils DESTINATION usr/${CMAKE_INSTALL_LIBDIR}) 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 @@ ...@@ -24,6 +24,7 @@
#include "castor/mediachanger/CmdLine.hpp" #include "castor/mediachanger/CmdLine.hpp"
#include "castor/exception/InvalidArgument.hpp" #include "castor/exception/InvalidArgument.hpp"
#include "castor/exception/MissingOperand.hpp" #include "castor/exception/MissingOperand.hpp"
#include <getopt.h>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// handleMissingParameter // 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;