Commit 5181643c authored by Eric Cano's avatar Eric Cano
Browse files

Removed cta-tapeserverd which is superseded by cta-taped.

This will allow the simplification of data structures and the enventual removal of the castor namespace.
parent 9f2c6144
......@@ -124,18 +124,6 @@ The tape server daemon
%attr(0755,root,root) %{_bindir}/cta-taped
%attr(0755,root,root) %{_libdir}/libctamessages.so
%package -n cta-tapeserverd
Summary: CERN Tape Archive: tapeserver daemon (demo only)
Group: Application/CTA
requires: cta-lib
%description -n cta-tapeserverd
CERN Tape Archive:
The tape server daemon
%files -n cta-tapeserverd
%defattr(-,root,root)
%attr(0755,root,root) %{_bindir}/cta-tapeserverd
%attr(0755,root,root) %{_libdir}/libctamessages.so
%package -n cta-frontend
Summary: CERN Tape Archive: Xrootd plugin
Group: Application/CTA
......@@ -183,7 +171,6 @@ The shared libraries
%attr(0755,root,root) %{_libdir}/libctamessagesutils.so
%attr(0755,root,root) %{_libdir}/libctardbms.so
%attr(0755,root,root) %{_libdir}/libctatapereactorutils.so
%attr(0755,root,root) %{_libdir}/libctatapeserverdaemonutils.so
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cta/cta_catalogue_db.conf.example
%package -n cta-doc
......@@ -205,7 +192,6 @@ Requires: cta-taped = %{ctaVersion}-%{ctaRelease}%{mydist}
CERN Tape Archive:
Unit tests and system tests with virtual tape drives
%files -n cta-systemtests
%attr(0755,root,root) %{_bindir}/cta-systemTests
%attr(0755,root,root) %{_libdir}/libsystemTestHelperTests.so
%attr(0755,root,root) %{_libdir}/libcta-tapedSystemTests.so
%attr(0755,root,root) %{_bindir}/cta-catalogueUnitTests
......
......@@ -30,14 +30,6 @@ find_package(Protobuf REQUIRED)
find_package( ZLIB REQUIRED )
set(CTATAPESERVERDAEMON_LIBRARY_SRCS
Catalogue.cpp
CatalogueDrive.cpp
CatalogueDriveState.cpp
CatalogueSession.cpp
CatalogueLabelSession.cpp
CatalogueTransferSession.cpp
CatalogueCleanerSession.cpp
CatalogueConfig.cpp
CleanerSession.cpp
DataTransferConfig.cpp
LabelSessionConfig.cpp
......@@ -55,18 +47,10 @@ set(CTATAPESERVERDAEMON_LIBRARY_SRCS
MigrationReportPacker.cpp
MigrationTaskInjector.cpp
DataTransferSession.cpp
ProcessForker.cpp
ProcessForkerConnectionHandler.cpp
ProcessForkerProxy.cpp
ProcessForkerProxySocket.cpp
ProcessForkerUtils.cpp
RecallMemoryManager.cpp
RecallTaskInjector.cpp
RecallReportPacker.cpp
Session.cpp
TapeMessageHandler.cpp
TapeDaemonConfig.cpp
TapeDaemonMain.cpp
TapeReadSingleThread.cpp
TapeWriteSingleThread.cpp
TapeWriteTask.cpp
......@@ -86,9 +70,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
MigrationReportPackerTest.cpp
ProcessForkerProxyDummy.cpp
ProcessForkerTest.cpp
RecallTaskInjectorTest.cpp
TapeDaemon.cpp
TapeDaemonTest.cpp)
RecallTaskInjectorTest.cpp)
set_property(SOURCE ${CTATAPESERVERDAEMON_LIBRARY_SRC}
PROPERTY COMPILE_FLAGS " -Wno-unused-local-typedefs")
endforeach(CTATAPESERVERDAEMON_LIBRARY_SRC)
......@@ -101,37 +83,20 @@ add_library(ctaTapeServerDaemon
target_link_libraries(ctaTapeServerDaemon ctamessages ctatapereactor ctacommon ctaremotens protobuf ctascheduler ctalegacymsg ctacatalogue)
add_dependencies(ctaTapeServerDaemon ctamessagesprotobuf)
add_executable(cta-tapeserverd TapeDaemon.cpp)
target_link_libraries(cta-tapeserverd ctaTapeServerDaemon SCSI System Utils
File TapeDrive ctacommon ctatapereactor ${LIBCAP_LIB} ${ZLIB_LIBRARIES}
ctamessages zmq ctaio ctautils)
install (TARGETS cta-tapeserverd DESTINATION usr/bin)
add_library(ctatapeserverdaemonutils SHARED
ProcessForkerProxyDummy.cpp)
install(TARGETS ctatapeserverdaemonutils DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
add_library(ctatapeserverdaemonunittests SHARED
CatalogueDriveStateTest.cpp
CatalogueTest.cpp
DataTransferSessionTest.cpp
DiskReadTaskTest.cpp
DiskWriteTaskTest.cpp
DiskWriteThreadPoolTest.cpp
DriveConfigTest.cpp
MigrationReportPackerTest.cpp
ProcessForkerTest.cpp
RecallReportPackerTest.cpp
RecallTaskInjectorTest.cpp
TapeDaemon.cpp
TapeDaemonTest.cpp
TaskWatchDogTest.cpp
)
target_link_libraries(ctatapeserverdaemonunittests
ctamessagesutils
ctatapeserverdaemonutils)
ctamessagesutils)
#ctaschedulerutils
install(TARGETS ctatapeserverdaemonunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
/******************************************************************************
*
* 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/tape/tapeserver/daemon/Catalogue.hpp"
#include "castor/tape/tapeserver/daemon/Constants.hpp"
#include "castor/utils/utils.hpp"
#include <string.h>
#include <time.h>
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::Catalogue::Catalogue(
const int netTimeout,
cta::log::Logger &log,
ProcessForkerProxy &processForker,
const std::string &hostName,
const CatalogueConfig &catalogueConfig,
System::virtualWrapper &sysWrapper):
m_netTimeout(netTimeout),
m_log(log),
m_processForker(processForker),
m_hostName(hostName),
m_catalogueConfig(catalogueConfig),
m_sysWrapper(sysWrapper) {
}
//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::Catalogue::~Catalogue() throw() {
// Close any label-command connections that are still owned by the
// tape-drive catalogue
for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
itor++) {
const CatalogueDrive *const drive = itor->second;
delete drive;
}
}
//-----------------------------------------------------------------------------
// handleTick
//-----------------------------------------------------------------------------
bool castor::tape::tapeserver::daemon::Catalogue::handleTick() {
for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
itor++) {
CatalogueDrive *const drive = itor->second;
if(!drive->handleTick()) {
return false; // Do not continue the main event loop
}
}
return true; // Continue the main event loop
}
//------------------------------------------------------------------------------
// allDrivesAreShutdown
//------------------------------------------------------------------------------
bool castor::tape::tapeserver::daemon::Catalogue::allDrivesAreShutdown()
const throw() {
try {
for(DriveMap::const_iterator itor = m_drives.begin();
itor != m_drives.end(); itor++) {
CatalogueDrive *const drive = itor->second;
if(DRIVE_STATE_SHUTDOWN != drive->getState()) {
return false;
}
}
return true;
} catch(...) {
return false;
}
}
//-----------------------------------------------------------------------------
// populate
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::Catalogue::populate(
const DriveConfigMap &driveConfigs) {
try {
for(DriveConfigMap::const_iterator itor = driveConfigs.begin();
itor != driveConfigs.end(); itor++) {
const std::string &unitName = itor->first;
const DriveConfig &driveConfig = itor->second;
// Sanity check
if(unitName != driveConfig.getUnitName()) {
// This should never happen
cta::exception::Exception ex;
ex.getMessage() << "Unit name mismatch: expected=" << unitName <<
" actual=" << driveConfig.getUnitName();
throw ex;
}
enterDriveConfig(driveConfig);
}
} catch(cta::exception::Exception &ne) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to populate tape-drive catalogue: " <<
ne.getMessage().str();
throw ex;
}
}
//-----------------------------------------------------------------------------
// enterDriveConfig
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::Catalogue::enterDriveConfig(
const DriveConfig &driveConfig) {
DriveMap::iterator itor = m_drives.find(driveConfig.getUnitName());
// If the drive is not in the catalogue
if(m_drives.end() == itor) {
// Insert it
m_drives[driveConfig.getUnitName()] = new CatalogueDrive(m_netTimeout,
m_log, m_processForker, m_hostName, driveConfig,
DRIVE_STATE_UP, m_catalogueConfig, m_sysWrapper);
// TODO: This has to be changed to DRIVE_STATE_DOWN in production which is the default for all tape drives.
// Daniele changed this to DRIVE_STATE_UP while doing the full system test ,because the tpconfig command is
// not working properly.
// Else the drive is already in the catalogue
} else {
cta::exception::Exception ex;
ex.getMessage() <<
"Failed to enter tape-drive configuration into tape-drive catalogue"
": Duplicate drive-entry: unitName=" << driveConfig.getUnitName();
throw ex;
}
}
//-----------------------------------------------------------------------------
// getUnitNames
//-----------------------------------------------------------------------------
std::list<std::string>
castor::tape::tapeserver::daemon::Catalogue::getUnitNames() const {
std::list<std::string> unitNames;
for(DriveMap::const_iterator itor = m_drives.begin();
itor != m_drives.end(); itor++) {
unitNames.push_back(itor->first);
}
return unitNames;
}
//-----------------------------------------------------------------------------
// shutdown
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::Catalogue::shutdown() {
// Request sessions to shutdown
for(DriveMap::iterator itor = m_drives.begin();
itor != m_drives.end(); itor++) {
CatalogueDrive *const drive = itor->second;
try {
drive->shutdown();
} catch(cta::exception::Exception &ex) {
std::list<cta::log::Param> params = {cta::log::Param("message", ex.getMessage().str())};
m_log(cta::log::ERR, "Failed to shutdown session", params);
}
}
}
//-----------------------------------------------------------------------------
// killSessions
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::Catalogue::killSessions() {
for(DriveMap::iterator itor = m_drives.begin();
itor != m_drives.end(); itor++) {
CatalogueDrive *const drive = itor->second;
try {
drive->killSession();
} catch(cta::exception::Exception &ex) {
std::list<cta::log::Param> params = {cta::log::Param("message", ex.getMessage().str())};
m_log(cta::log::ERR, "Failed to kill session", params);
}
}
}
//-----------------------------------------------------------------------------
// findDrive
//-----------------------------------------------------------------------------
const castor::tape::tapeserver::daemon::CatalogueDrive
&castor::tape::tapeserver::daemon::Catalogue::findDrive(
const std::string &unitName) const {
std::ostringstream task;
task << "find tape drive in catalogue by unit name: unitName=" << unitName;
DriveMap::const_iterator itor = m_drives.find(unitName);
if(m_drives.end() == itor) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
throw ex;
}
if(NULL == itor->second) {
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Pointer to drive entry is unexpectedly NULL";
throw ex;
}
const CatalogueDrive &drive = *(itor->second);
const DriveConfig &driveConfig = drive.getConfig();
// Sanity check
if(unitName != driveConfig.getUnitName()) {
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Found inconsistent entry in tape-drive catalogue"
": Unit name mismatch: actual=" << driveConfig.getUnitName();
throw ex;
}
return drive;
}
//-----------------------------------------------------------------------------
// findDrive
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::CatalogueDrive
&castor::tape::tapeserver::daemon::Catalogue::findDrive(
const std::string &unitName) {
std::ostringstream task;
task << "find tape drive in catalogue by unit name: unitName=" << unitName;
DriveMap::iterator itor = m_drives.find(unitName);
if(m_drives.end() == itor) {
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
throw ex;
}
if(NULL == itor->second) {
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Pointer to drive entry is unexpectedly NULL";
throw ex;
}
CatalogueDrive &drive = *(itor->second);
const DriveConfig &driveConfig = drive.getConfig();
// Sanity check
if(unitName != driveConfig.getUnitName()) {
// This should never happen
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Found inconsistent entry in tape-drive catalogue"
": Unit name mismatch: expected=" << unitName <<
" actual=" << driveConfig.getUnitName();
throw ex;
}
return drive;
}
//-----------------------------------------------------------------------------
// findDrive
//-----------------------------------------------------------------------------
const castor::tape::tapeserver::daemon::CatalogueDrive
&castor::tape::tapeserver::daemon::Catalogue::findDrive(
const pid_t sessionPid) const {
std::ostringstream task;
task << "find tape drive in catalogue by session pid: sessionPid=" <<
sessionPid;
for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
itor++) {
if(NULL == itor->second) {
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Encountered NULL drive-entry pointer: unitName=" << itor->first;
throw ex;
}
const CatalogueDrive &drive = *(itor->second);
try {
const CatalogueSession &session = drive.getSession();
if(sessionPid == session.getPid()) {
return drive;
}
} catch(...) {
// Ignore any exceptions thrown by getSession()
}
}
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
throw ex;
}
//-----------------------------------------------------------------------------
// findDrive
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::CatalogueDrive
&castor::tape::tapeserver::daemon::Catalogue::findDrive(
const pid_t sessionPid) {
std::ostringstream task;
task << "find tape drive in catalogue by session pid: sessionPid=" <<
sessionPid;
for(DriveMap::iterator itor = m_drives.begin(); itor != m_drives.end();
itor++) {
if(NULL == itor->second) {
// Should never get here
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() <<
": Encountered NULL drive-entry pointer: unitName=" << itor->first;
throw ex;
}
CatalogueDrive &drive = *(itor->second);
try {
const CatalogueSession &session = drive.getSession();
if(sessionPid == session.getPid()) {
return drive;
}
} catch(...) {
// Ignore any exceptions thrown by getSessionPid()
}
}
cta::exception::Exception ex;
ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
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/legacymsg/TapeLabelRqstMsgBody.hpp"
#include "common/log/Logger.hpp"
#include "castor/tape/tapeserver/daemon/CatalogueConfig.hpp"
#include "castor/tape/tapeserver/daemon/CatalogueDrive.hpp"
#include "castor/tape/tapeserver/daemon/DriveConfigMap.hpp"
#include "castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp"
#include "common/exception/Exception.hpp"
#include <map>
#include <string>
#include <string.h>
namespace castor {
namespace tape {
namespace tapeserver {
namespace daemon {
/**
* Class responsible for keeping track of the tape drive being controlled by
* the tapeserverd daemon.
*/
class Catalogue {
public:
/**
* Constructor.
*
* @param netTimeout Timeout in seconds to be used when performing network
* I/O.
* @param log Object representing the API of the CASTOR logging system.
* @param processForker Proxy object representing the ProcessForker.
* @param hostName The name of the host on which the daemon is running. This
* name is needed to fill in messages to be sent to the vdqmd daemon.
* @param catalogueConfig The CASTOR configuration parameters to be used by
* the catalogue.
* @param sysWrapper Object representing the operating system.
*/
Catalogue(
const int netTimeout,
cta::log::Logger &log,
ProcessForkerProxy &processForker,
const std::string &hostName,
const CatalogueConfig &catalogueConfig,
System::virtualWrapper &sysWrapper);
/**
* Destructor.
*
* Closes the connection with the label command if the drive catalogue owns
* the connection at the time of destruction.
*/
~Catalogue() throw();
/**
* Handles a tick in time. Time driven actions such as alarms should be
* implemented here.
*
* This method does not have to be called at any time precise interval,
* though it should be called at least twice as fast as the quickest reaction
* time imposed on the catalogue.
*
* @return True if the main event loop should continue, else false.
*/
bool handleTick();
/**
* Returns true if all of teh tape-drives are shutdown.
*/
bool allDrivesAreShutdown() const throw();
/**
* Poplates the catalogue using the specified tape-drive configurations.
*
* @param driveConfigs Tape-drive configurations.
*/
void populate(const DriveConfigMap &driveConfigs);
/**
* Returns a const reference to the tape-drive entry corresponding to the
* tape drive with the specified unit name.
*
* This method throws an exception if the tape-drive entry cannot be found.
*
* @param unitName The unit name of the tape drive.
*/
const CatalogueDrive &findDrive(const std::string &unitName)
const;
/**
* Returns a const reference to the tape-drive entry associated with the
* session with the specified process ID.
*
* This method throws an exception if the tape-drive entry cannot be found.
*
* @param sessionPid The process ID of the session.
*/
const CatalogueDrive &findDrive(const pid_t sessionPid) const;
/**
* Returns a reference to the tape-drive entry corresponding to the tape
* drive with the specified unit name.
*