Commit 779fec29 authored by Steven Murray's avatar Steven Murray
Browse files

Removed the now redundant work for the rmcd "super-daemon"

There will be separate rmcd and acsd daemons, therefore
removing the need for an rmcd "super-daemon" that does both
SCSI and ACS.
parent b0b03d49
......@@ -38,7 +38,6 @@ castor/tape/rechandler/rechandlerd
castor/tape/rmc/castor-tape-acs-dismount
castor/tape/rmc/castor-tape-acs-mount
castor/tape/rmc/castor-tape-acs-queryvolume
castor/tape/rmc/castor-tape-mount
castor/tape/tapebridge/tapebridged
castor/tape/tapegateway/tapegatewayd
castor/tape/tpcp/dumptp
......
......@@ -38,7 +38,6 @@ set (CASTOR_LEGACYMSG_LIB_SRC_FILES
NsProxyFactory.cpp
NsProxy_TapeAlwaysEmpty.cpp
NsProxy_TapeAlwaysEmptyFactory.cpp
RmcAcsMntMsgBody.cpp
RmcMarshal.cpp
RmcMountMsgBody.cpp
RmcProxy.cpp
......
/******************************************************************************
*
* 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/legacymsg/RmcAcsMntMsgBody.hpp"
#include <string.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::legacymsg::RmcAcsMntMsgBody::RmcAcsMntMsgBody() throw():
uid(0),
gid(0),
acs(0),
lsm(0),
panel(0),
transport(0) {
memset(vid, '\0', sizeof(vid));
}
/******************************************************************************
*
* 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 "h/Castor_limits.h"
#include <stdint.h>
namespace castor {
namespace legacymsg {
/**
* The body of an RMC_ACS_MOUNT message.
*/
struct RmcAcsMntMsgBody {
uint32_t uid;
uint32_t gid;
uint32_t acs;
uint32_t lsm;
uint32_t panel;
uint32_t transport;
char vid[CA_MAXVIDLEN + 1];
/**
* Constructor.
*
* Sets all integer member-variables to 0 and all string member-variables to
* the empty string.
*/
RmcAcsMntMsgBody() throw();
}; // struct RmcAcsMntMsgBody
} // namespace legacymsg
} // namespace castor
......@@ -29,110 +29,6 @@
#include <string.h>
//-----------------------------------------------------------------------------
// marshal
//-----------------------------------------------------------------------------
size_t castor::legacymsg::marshal(char *const dst, const size_t dstLen, const RmcAcsMntMsgBody &src) {
const char *task = "marshal RmcAcsMntMsgBody";
if(dst == NULL) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to " << task <<
": Pointer to destination buffer is NULL";
throw ex;
}
// Calculate the length of the message body
const uint32_t bodyLen =
sizeof(src.uid) +
sizeof(src.gid) +
sizeof(src.acs) +
sizeof(src.lsm) +
sizeof(src.panel) +
sizeof(src.transport) +
strlen(src.vid) + 1;
// Calculate the total length of the message (header + body)
const uint32_t totalLen =
sizeof(uint32_t) + // magic
sizeof(uint32_t) + // reqType
sizeof(uint32_t) + // len
bodyLen;
// Check that the message buffer is big enough
if(totalLen > dstLen) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to " << task <<
": Buffer too small: required=" << totalLen << " actual=" << dstLen;
throw ex;
}
// Marshal message header
char *p = dst;
try {
const uint32_t magic = RMC_MAGIC;
const uint32_t reqType = RMC_ACS_MOUNT;
io::marshalUint32(magic , p);
io::marshalUint32(reqType, p);
io::marshalUint32(bodyLen, p);
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to " << task << ": Failed to marshal header: "
<< ne.getMessage().str();
throw ex;
}
// Marshal message body
try {
io::marshalUint32(src.uid, p);
io::marshalUint32(src.gid, p);
io::marshalUint32(src.acs, p);
io::marshalUint32(src.lsm, p);
io::marshalUint32(src.panel, p);
io::marshalUint32(src.transport, p);
io::marshalString(src.vid, p);
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to " << task << ": Failed to marshal body: "
<< ne.getMessage().str();
throw ex;
}
// Calculate the number of bytes actually marshalled
const size_t nbBytesMarshalled = p - dst;
// Check that the number of bytes marshalled was what was expected
if(totalLen != nbBytesMarshalled) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to " << task <<
": Mismatch between expected total length and actual"
": expected=" << totalLen << " actual=" << nbBytesMarshalled;
throw ex;
}
return totalLen;
}
//-----------------------------------------------------------------------------
// unmarshal
//-----------------------------------------------------------------------------
void castor::legacymsg::unmarshal(const char * &src, size_t &srcLen, RmcAcsMntMsgBody &dst) {
try {
io::unmarshalUint32(src, srcLen, dst.uid);
io::unmarshalUint32(src, srcLen, dst.gid);
io::unmarshalUint32(src, srcLen, dst.acs);
io::unmarshalUint32(src, srcLen, dst.lsm);
io::unmarshalUint32(src, srcLen, dst.panel);
io::unmarshalUint32(src, srcLen, dst.transport);
io::unmarshalString(src, srcLen, dst.vid);
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to unmarshal RmcAcsMntMsgBody: " <<
ne.getMessage().str();
throw ex;
}
}
//-----------------------------------------------------------------------------
// marshal
//-----------------------------------------------------------------------------
......@@ -174,7 +70,7 @@ size_t castor::legacymsg::marshal(char *const dst, const size_t dstLen, const Rm
char *p = dst;
try {
const uint32_t magic = RMC_MAGIC;
const uint32_t reqType = RMC_SCSI_MOUNT;
const uint32_t reqType = RMC_MOUNT;
io::marshalUint32(magic , p);
io::marshalUint32(reqType, p);
io::marshalUint32(totalLen, p);
......@@ -275,7 +171,7 @@ size_t castor::legacymsg::marshal(char *const dst, const size_t dstLen, const Rm
char *p = dst;
try {
const uint32_t magic = RMC_MAGIC;
const uint32_t reqType = RMC_SCSI_UNMOUNT;
const uint32_t reqType = RMC_UNMOUNT;
io::marshalUint32(magic , p);
io::marshalUint32(reqType, p);
io::marshalUint32(totalLen, p);
......
......@@ -25,51 +25,12 @@
#pragma once
#include "castor/exception/Exception.hpp"
#include "castor/legacymsg/RmcAcsMntMsgBody.hpp"
#include "castor/legacymsg/RmcMountMsgBody.hpp"
#include "castor/legacymsg/RmcUnmountMsgBody.hpp"
namespace castor {
namespace legacymsg {
/**
* Marshals the specified source message body structure and its implicit
* header into the specified destination buffer.
*
* @param dst The destination message buffer.
* @param dstLen The length of the destination buffer.
* @param src The source structure.
* @return The total length of the message (header + body).
*/
size_t marshal(char *const dst, const size_t dstLen, const RmcAcsMntMsgBody &src) ;
/**
* Marshals the specified source message body structure and its implicit
* header into the specified destination buffer.
*
* @param dst The destination message buffer.
* @param src The source structure.
* @return The total length of the message (header + body).
*/
template<int n> size_t marshal(char (&dst)[n], const RmcAcsMntMsgBody &src) {
return marshal(dst, n, src);
}
/**
* Unmarshals a message body with the specified destination structure type
* from the specified source buffer.
*
* @param src In/out parameter, before invocation points to the source
* buffer where the message body should be unmarshalled from and on return
* points to the byte in the source buffer immediately after the
* unmarshalled message body.
* @param srcLen In/out parameter, before invocation is the length of the
* source buffer from where the message body should be unmarshalled and on
* return is the number of bytes remaining in the source buffer.
* @param dst The destination message body structure.
*/
void unmarshal(const char * &src, size_t &srcLen, RmcAcsMntMsgBody &dst) ;
/**
* Marshals the specified source message body structure and its implicit
* header into the specified destination buffer.
......
......@@ -40,64 +40,6 @@ protected:
}
};
TEST_F(castor_legacymsg_RmcMarshalTest, marshalRmcAcsMntMsgBody) {
using namespace castor::legacymsg;
char buf[40]; // Expect message (header + body) to occupy exactly 40 bytes
// Marshal entire message (header + body)
{
RmcAcsMntMsgBody srcMsgBody;
srcMsgBody.uid = 1;
srcMsgBody.gid = 2;
srcMsgBody.acs = 3;
srcMsgBody.lsm = 4;
srcMsgBody.panel = 5;
srcMsgBody.transport = 6;
castor::utils::copyString(srcMsgBody.vid, "VID");
size_t bufLen = sizeof(buf);
size_t totalLen = 0; // Total length of message (header + body)
ASSERT_NO_THROW(totalLen = marshal(buf, bufLen, srcMsgBody));
ASSERT_EQ((size_t)40, totalLen);
}
// Unmarshall message header
{
MessageHeader dstHeader;
const char *bufPtr = buf;
size_t bufLen = 12; // Length of the message header
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstHeader));
ASSERT_EQ(buf + 12, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)RMC_MAGIC, dstHeader.magic);
ASSERT_EQ((uint32_t)RMC_ACS_MOUNT, dstHeader.reqType);
ASSERT_EQ((uint32_t)28, dstHeader.lenOrStatus);
}
// Unmarshall message body
{
RmcAcsMntMsgBody dstMsgBody;
const char *bufPtr = buf + 12; // Point at beginning of message body
size_t bufLen = 28; // Length of the message body
ASSERT_NO_THROW(unmarshal(bufPtr, bufLen, dstMsgBody));
ASSERT_EQ(buf + 40, bufPtr);
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)1, dstMsgBody.uid);
ASSERT_EQ((uint32_t)2, dstMsgBody.gid);
ASSERT_EQ((uint32_t)3, dstMsgBody.acs);
ASSERT_EQ((uint32_t)4, dstMsgBody.lsm);
ASSERT_EQ((uint32_t)5, dstMsgBody.panel);
ASSERT_EQ((uint32_t)6, dstMsgBody.transport);
ASSERT_EQ(std::string("VID"), dstMsgBody.vid);
}
}
TEST_F(castor_legacymsg_RmcMarshalTest, marshalRmcMountMsgBody) {
using namespace castor::legacymsg;
char buf[29]; // Expect message (header + body) to occupy exactly 29 bytes
......@@ -130,7 +72,7 @@ TEST_F(castor_legacymsg_RmcMarshalTest, marshalRmcMountMsgBody) {
ASSERT_EQ((size_t)0, bufLen);
ASSERT_EQ((uint32_t)RMC_MAGIC, dstHeader.magic);
ASSERT_EQ((uint32_t)RMC_SCSI_MOUNT, dstHeader.reqType);
ASSERT_EQ((uint32_t)RMC_MOUNT, dstHeader.reqType);
ASSERT_EQ((uint32_t)29, dstHeader.lenOrStatus);
}
......
/******************************************************************************
*
* 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/exception/BadAlloc.hpp"
#include "castor/exception/Errnum.hpp"
#include "castor/io/io.hpp"
#include "castor/tape/rmc/AcceptHandler.hpp"
#include "castor/tape/rmc/ConnectionHandler.hpp"
#include "castor/utils/SmartFd.hpp"
#include <errno.h>
#include <memory>
#include <string.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::tape::rmc::AcceptHandler::AcceptHandler(const int fd,
reactor::ZMQReactor &reactor, log::Logger &log) throw(): m_fd(fd),
m_reactor(reactor), m_log(log) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::tape::rmc::AcceptHandler::~AcceptHandler() throw() {
{
log::Param params[] = {
log::Param("fd", m_fd)};
m_log(LOG_DEBUG, "Closing listen socket", params);
}
close(m_fd);
}
//------------------------------------------------------------------------------
// getName
//------------------------------------------------------------------------------
std::string castor::tape::rmc::AcceptHandler::getName() const throw() {
return "rmc::AcceptHandler";
}
//------------------------------------------------------------------------------
// fillPollFd
//------------------------------------------------------------------------------
void castor::tape::rmc::AcceptHandler::fillPollFd(zmq_pollitem_t &fd) throw() {
fd.fd = m_fd;
fd.events = ZMQ_POLLIN;
fd.revents = 0;
fd.socket = NULL;
}
//------------------------------------------------------------------------------
// handleEvent
//------------------------------------------------------------------------------
bool castor::tape::rmc::AcceptHandler::handleEvent(
const zmq_pollitem_t &fd) {
log::Param params[] = {
log::Param("fd", fd.fd),
log::Param("ZMQ_POLLIN", fd.revents & ZMQ_POLLIN ? "true" : "false"),
log::Param("ZMQ_POLLOUT", fd.revents & ZMQ_POLLOUT ? "true" : "false"),
log::Param("ZMQ_POLLERR", fd.revents & ZMQ_POLLERR ? "true" : "false")};
m_log(LOG_DEBUG, "I/O event on rmc listen socket", params);
checkHandleEventFd(fd.fd);
// Accept the connection
castor::utils::SmartFd connection;
try {
connection.reset(io::acceptConnection(fd.fd, 1));
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to accept a connection: " << ne.getMessage().str();
throw ex;
}
m_log(LOG_DEBUG, "Accepted a possible client connection");
// Create a new connection handler
std::auto_ptr<ConnectionHandler> connectionHandler;
try {
connectionHandler.reset(new ConnectionHandler(connection.get(),
m_reactor, m_log));
connection.release();
} catch(std::bad_alloc &ba) {
castor::exception::BadAlloc ex;
ex.getMessage() << "Failed to allocate a new connection handler"
": " << ba.what();
throw ex;
}
m_log(LOG_DEBUG, "Created a new connection handler");
// Register the new connection handler with the reactor
try {
m_reactor.registerHandler(connectionHandler.get());
connectionHandler.release();
} catch(castor::exception::Exception &ne) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to register a new connection handler"
": " << ne.getMessage().str();
}
m_log(LOG_DEBUG, "Registered the new connection handler");
return false; // Stay registered with the reactor
}
//------------------------------------------------------------------------------
// checkHandleEventFd
//------------------------------------------------------------------------------
void castor::tape::rmc::AcceptHandler::checkHandleEventFd(const int fd) {
if(m_fd != fd) {
castor::exception::Exception ex;
ex.getMessage() << "Failed to accept connection from client"
": Event handler passed wrong file descriptor"
": expected=" << m_fd << " actual=" << fd;
throw ex;
}
}
/******************************************************************************
*
* 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/log/Logger.hpp"
#include "castor/tape/reactor/PollEventHandler.hpp"
#include "castor/tape/reactor/ZMQReactor.hpp"
#include <poll.h>
namespace castor {
namespace tape {
namespace rmc {
/**
* Handles the events of the socket listening for connections from clients of
* the rmcd daemon.
*/
class AcceptHandler: public reactor::ZMQPollEventHandler {
public:
/**
* Constructor.
*
* @param fd The file descriptor of the socket listening for connections
* from clients of the rmcd daemon.
* @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.
*/
AcceptHandler(const int fd, reactor::ZMQReactor &reactor, log::Logger &log) throw();
/**
* Returns the human-readable name this event handler.
*/
std::string getName() const throw();
/**
* Fills the specified poll file-descriptor ready to be used in a call to
* poll().
*/
void fillPollFd(zmq_pollitem_t &fd) throw();
/**
* Handles the specified event.
*
* @param fd The poll file-descriptor describing the event.
* @return true if the event handler should be removed from and deleted by
* the reactor.
*/
bool handleEvent(const zmq_pollitem_t &fd);
/**
* Destructor.
*
* Closes the listen socket.
*/
~AcceptHandler() throw();
private:
/**
* Throws an exception if the specified file-descriptor is not that of the
* socket listening for client connections.
*/
void checkHandleEventFd(const int fd);
/**
* The file descriptor of the socket listening for client connections.
*/
const int m_fd;
/**
* The reactor to which new connection handlers are to be registered.
*/
reactor::ZMQReactor &m_reactor;
/**
* The object representing the API of the CASTOR logging system.
*/
log::Logger &m_log;
}; // class AcceptHandler
} // namespace rmc </