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

Added castor::tape::rmc::RmcDaemon

parent 40c96c76
......@@ -43,7 +43,7 @@ struct AcsDismountCmdLine {
/**
* Constructor.
*
* Initialises all BOOLEAN member-variables to FALSE, all integer
* Initialises all boolean member-variables to false, all integer
* member-variables to 0 and the volume identifier to an empty string.
*/
AcsDismountCmdLine() throw();
......
/* This file was generated by ./DlfMessagesCodeGenerator on Fri Nov 29 14:25:47 CET 2013
*/
/******************************************************************************
* castor/tape/tapebridge/DlfMessageConstants.hpp
*
* 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 Steven Murray Steven.Murray@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP
#define CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP 1
namespace castor {
namespace tape {
namespace rmc {
enum RmcDlfMessages {
RMCD_NULL=0, /* " - " */
RMCD_STARTED=1, /* "rmcd started" */
RMCD_FAILED_TO_START=2 /* "rmcd failed to start" */
}; // enum RmcdDlfMessages
} // namespace rmc
} // namespace tape
} // namespace castor
#endif // CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP
/******************************************************************************
* castor/tape/tapebridge/DlfMessageConstants.hpp
*
* 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 Steven Murray Steven.Murray@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP
#define CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP 1
namespace castor {
namespace tape {
namespace rmc {
enum RmcDlfMessages {
}; // enum RmcdDlfMessages
} // namespace rmc
} // namespace tape
} // namespace castor
#endif // CASTOR_TAPE_RMC_DLFMESSAGECONSTANTS_HPP
/* This file was generated by ./DlfMessagesCodeGenerator on Fri Nov 29 14:25:47 CET 2013
*/
/******************************************************************************
* castor/tape/rmc/DlfMessageStrings.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 Steven Murray Steven.Murray@cern.ch
*****************************************************************************/
#include "castor/tape/rmc/DlfMessageConstants.hpp"
#include "castor/tape/rmc/RmcDaemon.hpp"
castor::dlf::Message castor::tape::rmc::RmcDaemon::s_dlfMessages[] = {
{RMCD_NULL, " - "},
{RMCD_STARTED, "rmcd started"},
{RMCD_FAILED_TO_START, "rmcd failed to start"},
{-1, ""}};
/******************************************************************************
* castor/tape/rmc/DlfMessageStrings.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 Steven Murray Steven.Murray@cern.ch
*****************************************************************************/
#include "castor/tape/rmc/DlfMessageConstants.hpp"
#include "castor/tape/rmc/RmcDaemon.hpp"
castor::dlf::Message castor::tape::rmc::RmcDaemon::s_dlfMessages[] = {
0,RMCD_NULL," - "
1,RMCD_STARTED,"rmcd started"
2,RMCD_FAILED_TO_START,"rmcd failed to start"
#!/usr/bin/perl -w
use strict;
my $constants_filename = "DlfMessageConstants.hpp";
my $constants_head_filename = "DlfMessageConstantsHeader.txt";
my $messages_filename = "DlfMessages.csv";
my $constants_tail_filename = "DlfMessageConstantsTrailer.txt";
my $strings_filename = "DlfMessageStrings.cpp";
my $strings_head_filename = "DlfMessageStringsHeader.txt";
sub writeConstantsFile {
my $date = $_[0];
# Open the constants file for writing
open(CONSTANTS, ">$constants_filename")
or die("Could not open $constants_filename for writing: $!\n");
print(CONSTANTS "/* This file was generated by $0 on $date */\n\n");
# Write the header text
open(CONSTANTSHEAD, "<$constants_head_filename")
or die("Could not open $constants_head_filename for reading: $!\n");
while(<CONSTANTSHEAD>) {
print(CONSTANTS);
}
close(CONSTANTSHEAD);
my $const_name;
my $const_val;
my $msg;
# Count the number of messages and check message constants
open(MESSAGES, "<$messages_filename")
or die("Could not open $messages_filename for reading: $!\n");
my $nbMessages = 0;
while(<MESSAGES>) {
m/^(\d*),([A-Z0-9_]*),(.*)/;
$const_val = $1;
$const_name = $2;
$msg = $3;
if($const_val != $nbMessages) {
close(MESSAGES);
die("Message constant not in sequence: actual=$const_val expected=$nbMessages\n");
}
$nbMessages = $nbMessages + 1;
}
close(MESSAGES);
# Write the body text
open(MESSAGES, "<$messages_filename")
or die("Could not open $messages_filename for reading: $!\n");
my $currentMessageNb = 0;
while(<MESSAGES>) {
$currentMessageNb = $currentMessageNb + 1;
m/^(\d*),([A-Z0-9_]*),(.*)/;
$const_val = $1;
$const_name = $2;
$msg = $3;
# If this is not the last message
if($currentMessageNb != $nbMessages) {
# Terminate the enumeration item with a comma
print(CONSTANTS "${const_name}=${const_val}, /* ${msg} */\n");
} else {
# Don't terminate the enumeration item with a comma
print(CONSTANTS "${const_name}=${const_val} /* ${msg} */\n");
}
}
close(MESSAGES);
# Write the trailer text
open(CONSTANTSTAIL, "<$constants_tail_filename")
or die("Could not open $constants_tail_filename for reading: $!\n");
while(<CONSTANTSTAIL>) {
print(CONSTANTS);
}
close(CONSTANTSTAIL);
# Close the constants file
close(CONSTANTS);
}
sub writeStringsFile {
my $date = $_[0];
# Open the strings file for writing
open(STRINGS, ">$strings_filename")
or die("Could not open $strings_filename for writing: $!\n");
print(STRINGS "/* This file was generated by $0 on $date */\n\n");
# Write the header text
open(STRINGSHEAD, "<$strings_head_filename")
or die("Could not open $strings_head_filename for reading: $!\n");
while(<STRINGSHEAD>) {
print(STRINGS);
}
close(STRINGSHEAD);
# Write the body text
open(MESSAGES, "<$messages_filename")
or die("Could not open $messages_filename for reading: $!\n");
my $const_name;
my $const_val;
my $msg;
while(<MESSAGES>) {
m/^(\d*),([A-Z0-9_]*),(".*")$/;
$const_val = $1;
$const_name = $2;
$msg = $3;
print(STRINGS "{${const_name}, ${msg}},\n");
}
close(MESSAGES);
# Write the trailer text
print(STRINGS "{-1, \"\"}};\n");
# Close the strings file
close(STRINGS);
}
my $date = `date`;
print("\n");
print("Source code generator for DLF messages\n");
print("===========================================\n\n");
print("Generating $constants_filename\n");
&writeConstantsFile($date);
print("Generating $strings_filename\n");
&writeStringsFile($date);
print("Finished\n\n");
/******************************************************************************
* castor/tape/rmc/RmcDaemon.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 Nicola.Bessone@cern.ch Steven.Murray@cern.ch
*****************************************************************************/
#include "castor/PortNumbers.hpp"
#include "castor/exception/Internal.hpp"
#include "castor/exception/InvalidArgument.hpp"
#include "castor/server/TCPListenerThreadPool.hpp"
#include "castor/tape/rmc/DlfMessageConstants.hpp"
#include "castor/tape/rmc/RmcDaemon.hpp"
//#include "castor/tape/tapebridge/ConfigParamLogger.hpp"
//#include "castor/tape/tapebridge/Constants.hpp"
#include "castor/tape/utils/utils.hpp"
#include "h/Cgetopt.h"
#include "h/common.h"
#include "h/Cuuid.h"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::tape::rmc::RmcDaemon::RmcDaemon()
throw(castor::exception::Exception) :
castor::server::BaseDaemon("rmcd"),
m_vdqmRequestHandlerThreadPool(0) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::tape::rmc::RmcDaemon::~RmcDaemon() throw() {
}
//------------------------------------------------------------------------------
// main
//------------------------------------------------------------------------------
int castor::tape::rmc::RmcDaemon::main(const int argc,
char **argv) {
// Try to initialize the DLF logging system, quitting with an error message
// to stderr if the initialization fails
try {
castor::server::BaseServer::dlfInit(s_dlfMessages);
} catch(castor::exception::Exception &ex) {
std::cerr << std::endl <<
"Failed to start daemon"
": Failed to initialize DLF"
": " << ex.getMessage().str() << std::endl << std::endl;
return 1;
}
// Try to start the daemon, quitting with an error message to stderr and DLF
// if the start fails
try {
exceptionThrowingMain(argc, argv);
} catch (castor::exception::Exception &ex) {
std::cerr << std::endl << "Failed to start daemon: "
<< ex.getMessage().str() << std::endl << std::endl;
usage(std::cerr, "rmcd");
std::cerr << std::endl;
castor::dlf::Param params[] = {
castor::dlf::Param("Message", ex.getMessage().str()),
castor::dlf::Param("Code" , ex.code() )};
CASTOR_DLF_WRITEPC(nullCuuid, DLF_LVL_ERROR,
RMCD_FAILED_TO_START, params);
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
// exceptionThrowingMain
//------------------------------------------------------------------------------
int castor::tape::rmc::RmcDaemon::exceptionThrowingMain(
const int argc, char **argv) throw(castor::exception::Exception) {
logStartOfDaemon(argc, argv);
parseCommandLine(argc, argv);
// Display usage message and exit if help option found on command-line
if(m_cmdLine.help) {
std::cout << std::endl;
castor::tape::rmc::RmcDaemon::usage(std::cout, "rmcd");
std::cout << std::endl;
return 0;
}
// Pass the foreground option to the super class BaseDaemon
m_foreground = m_cmdLine.foreground;
/*
// Determine and log the configuration parameters used by the tapebridged
// daemon to know how many files should be bulk requested per request for
// migration to or recall from tape.
BulkRequestConfigParams bulkRequestConfigParams;
bulkRequestConfigParams.determineConfigParams();
ConfigParamLogger::writeToDlf(nullCuuid,
bulkRequestConfigParams.getBulkRequestMigrationMaxBytes());
ConfigParamLogger::writeToDlf(nullCuuid,
bulkRequestConfigParams.getBulkRequestMigrationMaxFiles());
ConfigParamLogger::writeToDlf(nullCuuid,
bulkRequestConfigParams.getBulkRequestRecallMaxBytes());
ConfigParamLogger::writeToDlf(nullCuuid,
bulkRequestConfigParams.getBulkRequestRecallMaxFiles());
// Determine and log the values of the tape-bridge configuration-parameters.
// Only log the maximum number of bytes and files before a flush to tape if
// the tape flush mode requires them.
TapeFlushConfigParams tapeFlushConfigParams;
tapeFlushConfigParams.determineConfigParams();
{
const char *const tapeFlushModeStr = tapebridge_tapeFlushModeToStr(
tapeFlushConfigParams.getTapeFlushMode().getValue());
ConfigParamLogger::writeToDlf(
nullCuuid,
tapeFlushConfigParams.getTapeFlushMode().getCategory(),
tapeFlushConfigParams.getTapeFlushMode().getName(),
tapeFlushModeStr,
tapeFlushConfigParams.getTapeFlushMode().getSource());
}
if(TAPEBRIDGE_ONE_FLUSH_PER_N_FILES ==
tapeFlushConfigParams.getTapeFlushMode().getValue()) {
ConfigParamLogger::writeToDlf(nullCuuid,
tapeFlushConfigParams.getMaxBytesBeforeFlush());
ConfigParamLogger::writeToDlf(nullCuuid,
tapeFlushConfigParams.getMaxFilesBeforeFlush());
}
// Extract the tape-drive names from the TPCONFIG file
utils::TpconfigLines tpconfigLines;
utils::parseTpconfigFile(TPCONFIGPATH, tpconfigLines);
std::list<std::string> driveNames;
utils::extractTpconfigDriveNames(tpconfigLines, driveNames);
// Put the tape-drive names into a string stream ready to make a log message
std::stringstream driveNamesStream;
for(std::list<std::string>::const_iterator itor = driveNames.begin();
itor != driveNames.end(); itor++) {
if(itor != driveNames.begin()) {
driveNamesStream << ",";
}
driveNamesStream << *itor;
}
// Log the result of parsing the TPCONFIG file to extract the drive unit
// names
castor::dlf::Param params[] = {
castor::dlf::Param("filename" , TPCONFIGPATH ),
castor::dlf::Param("nbDrives" , driveNames.size() ),
castor::dlf::Param("unitNames", driveNamesStream.str())};
castor::dlf::dlf_writep(nullCuuid, DLF_LVL_SYSTEM,
TAPEBRIDGE_PARSED_TPCONFIG, params);
createVdqmRequestHandlerPool(
bulkRequestConfigParams,
tapeFlushConfigParams,
driveNames.size());
// Start the threads
start();
*/
return 0;
}
//------------------------------------------------------------------------------
// usage
//------------------------------------------------------------------------------
void castor::tape::rmc::RmcDaemon::usage(std::ostream &os,
const std::string &programName) throw() {
os << "\nUsage: "<< programName << " [options]\n"
"\n"
"where options can be:\n"
"\n"
"\t-f, --foreground Remain in the Foreground\n"
"\t-h, --help Print this help and exit\n"
"\n"
"Comments to: Castor.Support@cern.ch" << std::endl;
}
//------------------------------------------------------------------------------
// logStartOfDaemon
//------------------------------------------------------------------------------
void castor::tape::rmc::RmcDaemon::logStartOfDaemon(
const int argc, const char *const *const argv) throw() {
const std::string concatenatedArgs = argvToString(argc, argv);
castor::dlf::Param params[] = {
castor::dlf::Param("argv", concatenatedArgs)};
castor::dlf::dlf_writep(nullCuuid, DLF_LVL_SYSTEM, RMCD_STARTED,
params);
}
//------------------------------------------------------------------------------
// argvToString
//------------------------------------------------------------------------------
std::string castor::tape::rmc::RmcDaemon::argvToString(const int argc,
const char *const *const argv) throw() {
std::string str;
for(int i=0; i < argc; i++) {
if(i != 0) {
str += " ";
}
str += argv[i];
}
return str;
}
//------------------------------------------------------------------------------
// parseCommandLine
//------------------------------------------------------------------------------
void castor::tape::rmc::RmcDaemon::parseCommandLine(
const int argc, char **argv) throw(castor::exception::Exception) {
static struct Coptions longopts[] = {
{"foreground", NO_ARGUMENT, NULL, 'f'},
{"help" , NO_ARGUMENT, NULL, 'h'},
{NULL , 0 , NULL, 0 }
};
Coptind = 1;
Copterr = 0;
char c;
while ((c = Cgetopt_long(argc, argv, "fh", longopts, NULL)) != -1) {
switch (c) {
case 'f':
m_cmdLine.foreground = true;
break;
case 'h':
m_cmdLine.help = true;
break;
case '?':
{
std::stringstream oss;
oss <<
"Failed to parse the command-line"
": Unknown command-line option"
": option='" << (char)Coptopt << "'";
// Throw an exception
castor::exception::InvalidArgument ex;
ex.getMessage() << oss.str();
throw(ex);
}
break;
case ':':
{
std::stringstream oss;
oss <<
"Failed to parse the command-line"
": An option is missing a parameter";
// Throw an exception
castor::exception::InvalidArgument ex;
ex.getMessage() << oss.str();
throw(ex);
}
break;
default:
{
std::stringstream oss;
oss <<
"Failed to parse the command-line"
": Cgetopt_long returned an unknown value"
": value=0x" << std::hex << (int)c;
// Throw an exception
TAPE_THROW_EX(castor::exception::Internal,
": " << oss.str());
}
}
}
if(Coptind > argc) {
std::stringstream oss;
oss <<
"Failed to parse the command-line"