From 1910ef3808e7688181e0cfb78ae274ee4e8000b7 Mon Sep 17 00:00:00 2001 From: Steven Murray <Steven.Murray@cern.ch> Date: Wed, 9 Jul 2014 17:37:43 +0200 Subject: [PATCH] DataTransferSession is now ran by the ProcessForker --- castor/legacymsg/VdqmProxyTcpIp.cpp | 61 +- castor/messages/CMakeLists.txt | 4 +- .../{Status.pb.cc => Exception.pb.cc} | 158 +-- .../messages/{Status.pb.h => Exception.pb.h} | 92 +- .../{Status.proto => Exception.proto} | 11 +- castor/messages/ForkDataTransfer.pb.cc | 1025 ++++++++++++++++- castor/messages/ForkDataTransfer.pb.h | 753 +++++++++++- castor/messages/ForkDataTransfer.proto | 26 + castor/messages/ProcessCrashed.pb.cc | 348 ++++++ castor/messages/ProcessCrashed.pb.h | 191 +++ castor/messages/ProcessCrashed.proto | 26 + castor/messages/ProcessExited.pb.cc | 348 ++++++ castor/messages/ProcessExited.pb.h | 191 +++ castor/messages/ProcessExited.proto | 26 + castor/tape/tapeserver/daemon/CMakeLists.txt | 1 + .../tapeserver/daemon/DataTransferSession.cpp | 79 +- .../tapeserver/daemon/DataTransferSession.hpp | 25 +- .../tape/tapeserver/daemon/ProcessForker.cpp | 428 ++++++- .../tape/tapeserver/daemon/ProcessForker.hpp | 134 ++- .../daemon/ProcessForkerConnectionHandler.cpp | 488 ++++++++ .../daemon/ProcessForkerConnectionHandler.hpp | 279 +++++ .../daemon/ProcessForkerMsgType.cpp | 6 +- .../daemon/ProcessForkerMsgType.hpp | 4 +- .../tapeserver/daemon/ProcessForkerProxy.hpp | 20 +- .../daemon/ProcessForkerProxySocket.cpp | 74 +- .../daemon/ProcessForkerProxySocket.hpp | 31 +- .../tapeserver/daemon/ProcessForkerTest.cpp | 42 +- .../tapeserver/daemon/ProcessForkerUtils.cpp | 141 ++- .../tapeserver/daemon/ProcessForkerUtils.hpp | 98 +- castor/tape/tapeserver/daemon/TapeDaemon.cpp | 625 +++++----- castor/tape/tapeserver/daemon/TapeDaemon.hpp | 161 ++- .../tapeserver/daemon/TapeMessageHandler.cpp | 335 ++++-- .../tapeserver/daemon/TapeMessageHandler.hpp | 78 +- .../daemon/VdqmConnectionHandler.cpp | 6 +- .../daemon/VdqmConnectionHandler.hpp | 8 +- castor/tape/utils/CMakeLists.txt | 1 + castor/tape/utils/SmartZmqContext.cpp | 103 ++ castor/tape/utils/SmartZmqContext.hpp | 124 ++ castor/utils/SmartFILEPtr.cpp | 13 +- castor/utils/SmartFILEPtr.hpp | 5 +- 40 files changed, 5799 insertions(+), 770 deletions(-) rename castor/messages/{Status.pb.cc => Exception.pb.cc} (69%) rename castor/messages/{Status.pb.h => Exception.pb.h} (69%) rename castor/messages/{Status.proto => Exception.proto} (71%) create mode 100644 castor/messages/ProcessCrashed.pb.cc create mode 100644 castor/messages/ProcessCrashed.pb.h create mode 100644 castor/messages/ProcessCrashed.proto create mode 100644 castor/messages/ProcessExited.pb.cc create mode 100644 castor/messages/ProcessExited.pb.h create mode 100644 castor/messages/ProcessExited.proto create mode 100644 castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.cpp create mode 100644 castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.hpp create mode 100644 castor/tape/utils/SmartZmqContext.cpp create mode 100644 castor/tape/utils/SmartZmqContext.hpp diff --git a/castor/legacymsg/VdqmProxyTcpIp.cpp b/castor/legacymsg/VdqmProxyTcpIp.cpp index 04e127b8f6..cd65089b9a 100644 --- a/castor/legacymsg/VdqmProxyTcpIp.cpp +++ b/castor/legacymsg/VdqmProxyTcpIp.cpp @@ -32,7 +32,9 @@ //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ -castor::legacymsg::VdqmProxyTcpIp::VdqmProxyTcpIp(log::Logger &log, const std::string &vdqmHostName, const unsigned short vdqmPort, const int netTimeout) throw(): +castor::legacymsg::VdqmProxyTcpIp::VdqmProxyTcpIp(log::Logger &log, + const std::string &vdqmHostName, const unsigned short vdqmPort, + const int netTimeout) throw(): m_log(log), m_vdqmHostName(vdqmHostName), m_vdqmPort(vdqmPort), @@ -48,7 +50,8 @@ castor::legacymsg::VdqmProxyTcpIp::~VdqmProxyTcpIp() throw() { //------------------------------------------------------------------------------ // setDriveDown //------------------------------------------------------------------------------ -void castor::legacymsg::VdqmProxyTcpIp::setDriveDown(const std::string &server, const std::string &unitName, const std::string &dgn) { +void castor::legacymsg::VdqmProxyTcpIp::setDriveDown(const std::string &server, + const std::string &unitName, const std::string &dgn) { try { legacymsg::VdqmDrvRqstMsgBody body; body.status = VDQM_UNIT_DOWN; @@ -59,8 +62,9 @@ void castor::legacymsg::VdqmProxyTcpIp::setDriveDown(const std::string &server, setDriveStatus(body); } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; - ex.getMessage() << "Failed to set status of tape drive " << unitName << - " to down: " << ne.getMessage().str(); + ex.getMessage() << "Failed to set state of tape drive" + ": server=" << server << " unitName=" << unitName << " dgn=" << dgn << + " state=down: " << ne.getMessage().str(); throw ex; } } @@ -68,7 +72,8 @@ void castor::legacymsg::VdqmProxyTcpIp::setDriveDown(const std::string &server, //------------------------------------------------------------------------------ // setDriveUp //------------------------------------------------------------------------------ -void castor::legacymsg::VdqmProxyTcpIp::setDriveUp(const std::string &server, const std::string &unitName, const std::string &dgn) { +void castor::legacymsg::VdqmProxyTcpIp::setDriveUp(const std::string &server, + const std::string &unitName, const std::string &dgn) { try { legacymsg::VdqmDrvRqstMsgBody body; body.status = VDQM_UNIT_UP; @@ -79,8 +84,9 @@ void castor::legacymsg::VdqmProxyTcpIp::setDriveUp(const std::string &server, co setDriveStatus(body); } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; - ex.getMessage() << "Failed to set status of tape drive " << unitName << - " to up: " << ne.getMessage().str(); + ex.getMessage() << "Failed to set state of tape drive" + ": server=" << server << " unitName=" << unitName << " dgn=" << dgn << + " state=up: " << ne.getMessage().str(); throw ex; } } @@ -88,7 +94,9 @@ void castor::legacymsg::VdqmProxyTcpIp::setDriveUp(const std::string &server, co //------------------------------------------------------------------------------ // assignDrive //------------------------------------------------------------------------------ -void castor::legacymsg::VdqmProxyTcpIp::assignDrive(const std::string &server, const std::string &unitName, const std::string &dgn, const uint32_t mountTransactionId, const pid_t sessionPid) { +void castor::legacymsg::VdqmProxyTcpIp::assignDrive(const std::string &server, + const std::string &unitName, const std::string &dgn, + const uint32_t mountTransactionId, const pid_t sessionPid) { try { legacymsg::VdqmDrvRqstMsgBody body; body.status = VDQM_UNIT_ASSIGN; @@ -101,8 +109,10 @@ void castor::legacymsg::VdqmProxyTcpIp::assignDrive(const std::string &server, c setDriveStatus(body); } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; - ex.getMessage() << "Failed to assign mount-session with process ID " << - sessionPid << "to tape drive " << unitName << ": " << ne.getMessage().str(); + ex.getMessage() << "Failed to assign drive" + ": server=" << server << " unitName=" << unitName << " dgn=" << dgn << + " mountTransactionId=" << mountTransactionId << " sessionPid=" << + sessionPid << ": " << ne.getMessage().str(); throw ex; } } @@ -126,8 +136,10 @@ void castor::legacymsg::VdqmProxyTcpIp::tapeMounted(const std::string &server, setDriveStatus(body); } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; - ex.getMessage() << "Failed to notify vdqm that tape " << vid << - " was mounted on tape drive " << unitName << ": " << ne.getMessage().str(); + ex.getMessage() << "Failed to notify vdqm that tape is mounted" + ": server=" << server << " unitName=" << unitName << " dgn=" << dgn << + " vid=" << vid << " sessionPid=" << sessionPid << ": " << + ne.getMessage().str(); throw ex; } } @@ -155,8 +167,10 @@ void castor::legacymsg::VdqmProxyTcpIp::releaseDrive(const std::string &server, setDriveStatus(body); } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; - ex.getMessage() << "Failed to release tape drive " << unitName << ": " << - ne.getMessage().str(); + ex.getMessage() << "Failed to release tape drive" + ": server=" << server << " unitName=" << unitName << " dgn=" << dgn << + " forceUnmount=" << forceUnmount << " sessionPid=" << sessionPid << ": " + << ne.getMessage().str(); throw ex; } } @@ -164,7 +178,8 @@ void castor::legacymsg::VdqmProxyTcpIp::releaseDrive(const std::string &server, //------------------------------------------------------------------------------ // setDriveStatus //------------------------------------------------------------------------------ -void castor::legacymsg::VdqmProxyTcpIp::setDriveStatus(const legacymsg::VdqmDrvRqstMsgBody &body) { +void castor::legacymsg::VdqmProxyTcpIp::setDriveStatus( + const legacymsg::VdqmDrvRqstMsgBody &body) { castor::utils::SmartFd fd(connectToVdqm()); writeDriveStatusMsg(fd.get(), body); readCommitAck(fd.get()); @@ -194,7 +209,8 @@ int castor::legacymsg::VdqmProxyTcpIp::connectToVdqm() const { //----------------------------------------------------------------------------- // writeDriveStatusMsg //----------------------------------------------------------------------------- -void castor::legacymsg::VdqmProxyTcpIp::writeDriveStatusMsg(const int fd, const legacymsg::VdqmDrvRqstMsgBody &body) { +void castor::legacymsg::VdqmProxyTcpIp::writeDriveStatusMsg(const int fd, + const legacymsg::VdqmDrvRqstMsgBody &body) { char buf[VDQM_MSGBUFSIZ]; const size_t len = legacymsg::marshal(buf, body); @@ -252,7 +268,8 @@ void castor::legacymsg::VdqmProxyTcpIp::readCommitAck(const int fd) { //----------------------------------------------------------------------------- // readAck //----------------------------------------------------------------------------- -castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp::readAck(const int fd) { +castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp::readAck( + const int fd) { char buf[12]; // Magic + type + len legacymsg::MessageHeader ack; @@ -275,7 +292,8 @@ castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp::readAck(cons //----------------------------------------------------------------------------- // readDriveStatusMsgHeader //----------------------------------------------------------------------------- -castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp::readDriveStatusMsgHeader(const int fd) { +castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp:: + readDriveStatusMsgHeader(const int fd) { char buf[12]; // Magic + type + len legacymsg::MessageHeader header; @@ -316,7 +334,8 @@ castor::legacymsg::MessageHeader castor::legacymsg::VdqmProxyTcpIp::readDriveSta //----------------------------------------------------------------------------- // readDriveStatusMsgBody //----------------------------------------------------------------------------- -castor::legacymsg::VdqmDrvRqstMsgBody castor::legacymsg::VdqmProxyTcpIp::readDriveStatusMsgBody(const int fd, const uint32_t bodyLen) { +castor::legacymsg::VdqmDrvRqstMsgBody castor::legacymsg::VdqmProxyTcpIp:: + readDriveStatusMsgBody(const int fd, const uint32_t bodyLen) { char buf[VDQM_MSGBUFSIZ]; if(sizeof(buf) < bodyLen) { @@ -368,7 +387,9 @@ void castor::legacymsg::VdqmProxyTcpIp::writeCommitAck(const int fd) { //----------------------------------------------------------------------------- // tapeUnmounted //----------------------------------------------------------------------------- -void castor::legacymsg::VdqmProxyTcpIp::tapeUnmounted(const std::string &server, const std::string &unitName, const std::string &dgn, const std::string &vid) { +void castor::legacymsg::VdqmProxyTcpIp::tapeUnmounted( + const std::string &server, const std::string &unitName, + const std::string &dgn, const std::string &vid) { int status = VDQM_VOL_UNMOUNT; try { diff --git a/castor/messages/CMakeLists.txt b/castor/messages/CMakeLists.txt index 9db3e7871c..7e495ecdee 100644 --- a/castor/messages/CMakeLists.txt +++ b/castor/messages/CMakeLists.txt @@ -1,4 +1,5 @@ add_library(castormessages SHARED + Exception.pb.cc ForkCleaner.pb.cc ForkDataTransfer.pb.cc ForkLabel.pb.cc @@ -7,8 +8,9 @@ add_library(castormessages SHARED Heartbeat.pb.cc messages.cpp NotifyDrive.pb.cc + ProcessCrashed.pb.cc + ProcessExited.pb.cc ReplyContainer.cpp - Status.pb.cc StopProcessForker.pb.cc TapeserverProxy.cpp TapeserverProxyDummy.cpp diff --git a/castor/messages/Status.pb.cc b/castor/messages/Exception.pb.cc similarity index 69% rename from castor/messages/Status.pb.cc rename to castor/messages/Exception.pb.cc index 639d2b444a..c22c5ae607 100644 --- a/castor/messages/Status.pb.cc +++ b/castor/messages/Exception.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "Status.pb.h" +#include "Exception.pb.h" #include <google/protobuf/stubs/once.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/wire_format_lite_inl.h> @@ -15,35 +15,35 @@ namespace messages { namespace { -const ::google::protobuf::Descriptor* Status_descriptor_ = NULL; +const ::google::protobuf::Descriptor* Exception_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* - Status_reflection_ = NULL; + Exception_reflection_ = NULL; } // namespace -void protobuf_AssignDesc_Status_2eproto() { - protobuf_AddDesc_Status_2eproto(); +void protobuf_AssignDesc_Exception_2eproto() { + protobuf_AddDesc_Exception_2eproto(); const ::google::protobuf::FileDescriptor* file = ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "Status.proto"); + "Exception.proto"); GOOGLE_CHECK(file != NULL); - Status_descriptor_ = file->message_type(0); - static const int Status_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, status_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, message_), + Exception_descriptor_ = file->message_type(0); + static const int Exception_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Exception, code_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Exception, message_), }; - Status_reflection_ = + Exception_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( - Status_descriptor_, - Status::default_instance_, - Status_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, _unknown_fields_), + Exception_descriptor_, + Exception::default_instance_, + Exception_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Exception, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Exception, _unknown_fields_), -1, ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), - sizeof(Status)); + sizeof(Exception)); } namespace { @@ -51,80 +51,80 @@ namespace { GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); inline void protobuf_AssignDescriptorsOnce() { ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_Status_2eproto); + &protobuf_AssignDesc_Exception_2eproto); } void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Status_descriptor_, &Status::default_instance()); + Exception_descriptor_, &Exception::default_instance()); } } // namespace -void protobuf_ShutdownFile_Status_2eproto() { - delete Status::default_instance_; - delete Status_reflection_; +void protobuf_ShutdownFile_Exception_2eproto() { + delete Exception::default_instance_; + delete Exception_reflection_; } -void protobuf_AddDesc_Status_2eproto() { +void protobuf_AddDesc_Exception_2eproto() { static bool already_here = false; if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\014Status.proto\022\017castor.messages\")\n\006Statu" - "s\022\016\n\006status\030\001 \002(\r\022\017\n\007message\030\002 \002(\t", 74); + "\n\017Exception.proto\022\017castor.messages\"*\n\tEx" + "ception\022\014\n\004code\030\001 \002(\r\022\017\n\007message\030\002 \002(\t", 78); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "Status.proto", &protobuf_RegisterTypes); - Status::default_instance_ = new Status(); - Status::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_Status_2eproto); + "Exception.proto", &protobuf_RegisterTypes); + Exception::default_instance_ = new Exception(); + Exception::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_Exception_2eproto); } // Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_Status_2eproto { - StaticDescriptorInitializer_Status_2eproto() { - protobuf_AddDesc_Status_2eproto(); +struct StaticDescriptorInitializer_Exception_2eproto { + StaticDescriptorInitializer_Exception_2eproto() { + protobuf_AddDesc_Exception_2eproto(); } -} static_descriptor_initializer_Status_2eproto_; +} static_descriptor_initializer_Exception_2eproto_; // =================================================================== -const ::std::string Status::_default_message_; +const ::std::string Exception::_default_message_; #ifndef _MSC_VER -const int Status::kStatusFieldNumber; -const int Status::kMessageFieldNumber; +const int Exception::kCodeFieldNumber; +const int Exception::kMessageFieldNumber; #endif // !_MSC_VER -Status::Status() +Exception::Exception() : ::google::protobuf::Message() { SharedCtor(); } -void Status::InitAsDefaultInstance() { +void Exception::InitAsDefaultInstance() { } -Status::Status(const Status& from) +Exception::Exception(const Exception& from) : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } -void Status::SharedCtor() { +void Exception::SharedCtor() { _cached_size_ = 0; - status_ = 0u; + code_ = 0u; message_ = const_cast< ::std::string*>(&_default_message_); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } -Status::~Status() { +Exception::~Exception() { SharedDtor(); } -void Status::SharedDtor() { +void Exception::SharedDtor() { if (message_ != &_default_message_) { delete message_; } @@ -132,29 +132,29 @@ void Status::SharedDtor() { } } -void Status::SetCachedSize(int size) const { +void Exception::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); } -const ::google::protobuf::Descriptor* Status::descriptor() { +const ::google::protobuf::Descriptor* Exception::descriptor() { protobuf_AssignDescriptorsOnce(); - return Status_descriptor_; + return Exception_descriptor_; } -const Status& Status::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_Status_2eproto(); return *default_instance_; +const Exception& Exception::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_Exception_2eproto(); return *default_instance_; } -Status* Status::default_instance_ = NULL; +Exception* Exception::default_instance_ = NULL; -Status* Status::New() const { - return new Status; +Exception* Exception::New() const { + return new Exception; } -void Status::Clear() { +void Exception::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - status_ = 0u; + code_ = 0u; if (_has_bit(1)) { if (message_ != &_default_message_) { message_->clear(); @@ -165,19 +165,19 @@ void Status::Clear() { mutable_unknown_fields()->Clear(); } -bool Status::MergePartialFromCodedStream( +bool Exception::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required uint32 status = 1; + // required uint32 code = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &status_))); + input, &code_))); _set_bit(0); } else { goto handle_uninterpreted; @@ -219,11 +219,11 @@ bool Status::MergePartialFromCodedStream( #undef DO_ } -void Status::SerializeWithCachedSizes( +void Exception::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required uint32 status = 1; + // required uint32 code = 1; if (_has_bit(0)) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->status(), output); + ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->code(), output); } // required string message = 2; @@ -241,11 +241,11 @@ void Status::SerializeWithCachedSizes( } } -::google::protobuf::uint8* Status::SerializeWithCachedSizesToArray( +::google::protobuf::uint8* Exception::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required uint32 status = 1; + // required uint32 code = 1; if (_has_bit(0)) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->status(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->code(), target); } // required string message = 2; @@ -265,15 +265,15 @@ void Status::SerializeWithCachedSizes( return target; } -int Status::ByteSize() const { +int Exception::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required uint32 status = 1; - if (has_status()) { + // required uint32 code = 1; + if (has_code()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->status()); + this->code()); } // required string message = 2; @@ -295,10 +295,10 @@ int Status::ByteSize() const { return total_size; } -void Status::MergeFrom(const ::google::protobuf::Message& from) { +void Exception::MergeFrom(const ::google::protobuf::Message& from) { GOOGLE_CHECK_NE(&from, this); - const Status* source = - ::google::protobuf::internal::dynamic_cast_if_available<const Status*>( + const Exception* source = + ::google::protobuf::internal::dynamic_cast_if_available<const Exception*>( &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); @@ -307,11 +307,11 @@ void Status::MergeFrom(const ::google::protobuf::Message& from) { } } -void Status::MergeFrom(const Status& from) { +void Exception::MergeFrom(const Exception& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from._has_bit(0)) { - set_status(from.status()); + set_code(from.code()); } if (from._has_bit(1)) { set_message(from.message()); @@ -320,27 +320,27 @@ void Status::MergeFrom(const Status& from) { mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } -void Status::CopyFrom(const ::google::protobuf::Message& from) { +void Exception::CopyFrom(const ::google::protobuf::Message& from) { if (&from == this) return; Clear(); MergeFrom(from); } -void Status::CopyFrom(const Status& from) { +void Exception::CopyFrom(const Exception& from) { if (&from == this) return; Clear(); MergeFrom(from); } -bool Status::IsInitialized() const { +bool Exception::IsInitialized() const { if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; return true; } -void Status::Swap(Status* other) { +void Exception::Swap(Exception* other) { if (other != this) { - std::swap(status_, other->status_); + std::swap(code_, other->code_); std::swap(message_, other->message_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); @@ -348,11 +348,11 @@ void Status::Swap(Status* other) { } } -::google::protobuf::Metadata Status::GetMetadata() const { +::google::protobuf::Metadata Exception::GetMetadata() const { protobuf_AssignDescriptorsOnce(); ::google::protobuf::Metadata metadata; - metadata.descriptor = Status_descriptor_; - metadata.reflection = Status_reflection_; + metadata.descriptor = Exception_descriptor_; + metadata.reflection = Exception_reflection_; return metadata; } diff --git a/castor/messages/Status.pb.h b/castor/messages/Exception.pb.h similarity index 69% rename from castor/messages/Status.pb.h rename to castor/messages/Exception.pb.h index 719d7c6e93..556407a847 100644 --- a/castor/messages/Status.pb.h +++ b/castor/messages/Exception.pb.h @@ -1,8 +1,8 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: Status.proto +// source: Exception.proto -#ifndef PROTOBUF_Status_2eproto__INCLUDED -#define PROTOBUF_Status_2eproto__INCLUDED +#ifndef PROTOBUF_Exception_2eproto__INCLUDED +#define PROTOBUF_Exception_2eproto__INCLUDED #include <string> @@ -29,22 +29,22 @@ namespace castor { namespace messages { // Internal implementation detail -- do not call these. -void protobuf_AddDesc_Status_2eproto(); -void protobuf_AssignDesc_Status_2eproto(); -void protobuf_ShutdownFile_Status_2eproto(); +void protobuf_AddDesc_Exception_2eproto(); +void protobuf_AssignDesc_Exception_2eproto(); +void protobuf_ShutdownFile_Exception_2eproto(); -class Status; +class Exception; // =================================================================== -class Status : public ::google::protobuf::Message { +class Exception : public ::google::protobuf::Message { public: - Status(); - virtual ~Status(); + Exception(); + virtual ~Exception(); - Status(const Status& from); + Exception(const Exception& from); - inline Status& operator=(const Status& from) { + inline Exception& operator=(const Exception& from) { CopyFrom(from); return *this; } @@ -58,17 +58,17 @@ class Status : public ::google::protobuf::Message { } static const ::google::protobuf::Descriptor* descriptor(); - static const Status& default_instance(); + static const Exception& default_instance(); - void Swap(Status* other); + void Swap(Exception* other); // implements Message ---------------------------------------------- - Status* New() const; + Exception* New() const; void CopyFrom(const ::google::protobuf::Message& from); void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Status& from); - void MergeFrom(const Status& from); + void CopyFrom(const Exception& from); + void MergeFrom(const Exception& from); void Clear(); bool IsInitialized() const; @@ -91,12 +91,12 @@ class Status : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required uint32 status = 1; - inline bool has_status() const; - inline void clear_status(); - static const int kStatusFieldNumber = 1; - inline ::google::protobuf::uint32 status() const; - inline void set_status(::google::protobuf::uint32 value); + // required uint32 code = 1; + inline bool has_code() const; + inline void clear_code(); + static const int kCodeFieldNumber = 1; + inline ::google::protobuf::uint32 code() const; + inline void set_code(::google::protobuf::uint32 value); // required string message = 2; inline bool has_message() const; @@ -108,17 +108,17 @@ class Status : public ::google::protobuf::Message { inline void set_message(const char* value, size_t size); inline ::std::string* mutable_message(); - // @@protoc_insertion_point(class_scope:castor.messages.Status) + // @@protoc_insertion_point(class_scope:castor.messages.Exception) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; - ::google::protobuf::uint32 status_; + ::google::protobuf::uint32 code_; ::std::string* message_; static const ::std::string _default_message_; - friend void protobuf_AddDesc_Status_2eproto(); - friend void protobuf_AssignDesc_Status_2eproto(); - friend void protobuf_ShutdownFile_Status_2eproto(); + friend void protobuf_AddDesc_Exception_2eproto(); + friend void protobuf_AssignDesc_Exception_2eproto(); + friend void protobuf_ShutdownFile_Exception_2eproto(); ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; @@ -134,66 +134,66 @@ class Status : public ::google::protobuf::Message { } void InitAsDefaultInstance(); - static Status* default_instance_; + static Exception* default_instance_; }; // =================================================================== // =================================================================== -// Status +// Exception -// required uint32 status = 1; -inline bool Status::has_status() const { +// required uint32 code = 1; +inline bool Exception::has_code() const { return _has_bit(0); } -inline void Status::clear_status() { - status_ = 0u; +inline void Exception::clear_code() { + code_ = 0u; _clear_bit(0); } -inline ::google::protobuf::uint32 Status::status() const { - return status_; +inline ::google::protobuf::uint32 Exception::code() const { + return code_; } -inline void Status::set_status(::google::protobuf::uint32 value) { +inline void Exception::set_code(::google::protobuf::uint32 value) { _set_bit(0); - status_ = value; + code_ = value; } // required string message = 2; -inline bool Status::has_message() const { +inline bool Exception::has_message() const { return _has_bit(1); } -inline void Status::clear_message() { +inline void Exception::clear_message() { if (message_ != &_default_message_) { message_->clear(); } _clear_bit(1); } -inline const ::std::string& Status::message() const { +inline const ::std::string& Exception::message() const { return *message_; } -inline void Status::set_message(const ::std::string& value) { +inline void Exception::set_message(const ::std::string& value) { _set_bit(1); if (message_ == &_default_message_) { message_ = new ::std::string; } message_->assign(value); } -inline void Status::set_message(const char* value) { +inline void Exception::set_message(const char* value) { _set_bit(1); if (message_ == &_default_message_) { message_ = new ::std::string; } message_->assign(value); } -inline void Status::set_message(const char* value, size_t size) { +inline void Exception::set_message(const char* value, size_t size) { _set_bit(1); if (message_ == &_default_message_) { message_ = new ::std::string; } message_->assign(reinterpret_cast<const char*>(value), size); } -inline ::std::string* Status::mutable_message() { +inline ::std::string* Exception::mutable_message() { _set_bit(1); if (message_ == &_default_message_) { message_ = new ::std::string; @@ -218,4 +218,4 @@ namespace protobuf { // @@protoc_insertion_point(global_scope) -#endif // PROTOBUF_Status_2eproto__INCLUDED +#endif // PROTOBUF_Exception_2eproto__INCLUDED diff --git a/castor/messages/Status.proto b/castor/messages/Exception.proto similarity index 71% rename from castor/messages/Status.proto rename to castor/messages/Exception.proto index c414fa2e18..db47f7be67 100644 --- a/castor/messages/Status.proto +++ b/castor/messages/Exception.proto @@ -18,13 +18,10 @@ package castor.messages; -message Status { - // Status value where 0 means success and non-zero means error. - required uint32 status = 1; +message Exception { + // The error code + required uint32 code = 1; - // In the event of an error, in other words when the status field is set to a - // non-zero value, this field should contain a human-readable error-message. - // This field should explicitly be set to the empty string when the status - // field is 0. + // The error message required string message = 2; } diff --git a/castor/messages/ForkDataTransfer.pb.cc b/castor/messages/ForkDataTransfer.pb.cc index 506a2db0a6..b2af4c635f 100644 --- a/castor/messages/ForkDataTransfer.pb.cc +++ b/castor/messages/ForkDataTransfer.pb.cc @@ -29,8 +29,29 @@ void protobuf_AssignDesc_ForkDataTransfer_2eproto() { "ForkDataTransfer.proto"); GOOGLE_CHECK(file != NULL); ForkDataTransfer_descriptor_ = file->message_type(0); - static const int ForkDataTransfer_offsets_[1] = { + static const int ForkDataTransfer_offsets_[22] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, unitname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, dgn_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, devfilename_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, density_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, libraryslot_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, devtype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, mounttransactionid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, clientport_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, clienteuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, clientegid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, clienthost_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, clientusername_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, memblocksize_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, nbmemblocks_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, badmirhandling_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, bulkrequestmigrationmaxbytes_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, bulkrequestmigrationmaxfiles_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, bulkrequestrecallmaxbytes_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, bulkrequestrecallmaxfiles_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, maxbytesbeforeflush_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, maxfilesbeforeflush_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ForkDataTransfer, diskthreadpoolsize_), }; ForkDataTransfer_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -74,7 +95,20 @@ void protobuf_AddDesc_ForkDataTransfer_2eproto() { ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\026ForkDataTransfer.proto\022\017castor.message" - "s\"$\n\020ForkDataTransfer\022\020\n\010unitname\030\001 \002(\t", 79); + "s\"\254\004\n\020ForkDataTransfer\022\020\n\010unitname\030\001 \002(\t" + "\022\013\n\003dgn\030\002 \002(\t\022\023\n\013devfilename\030\003 \002(\t\022\017\n\007de" + "nsity\030\004 \003(\t\022\023\n\013libraryslot\030\005 \002(\t\022\017\n\007devt" + "ype\030\006 \002(\t\022\032\n\022mounttransactionid\030\007 \002(\r\022\022\n" + "\nclientport\030\010 \002(\r\022\022\n\nclienteuid\030\t \002(\r\022\022\n" + "\nclientegid\030\n \002(\r\022\022\n\nclienthost\030\013 \002(\t\022\026\n" + "\016clientusername\030\014 \002(\t\022\024\n\014memblocksize\030\r " + "\002(\r\022\023\n\013nbmemblocks\030\016 \002(\r\022\026\n\016badmirhandli" + "ng\030\017 \002(\t\022$\n\034bulkrequestmigrationmaxbytes" + "\030\020 \002(\004\022$\n\034bulkrequestmigrationmaxfiles\030\021" + " \002(\004\022!\n\031bulkrequestrecallmaxbytes\030\022 \002(\004\022" + "!\n\031bulkrequestrecallmaxfiles\030\023 \002(\004\022\033\n\023ma" + "xbytesbeforeflush\030\024 \002(\004\022\033\n\023maxfilesbefor" + "eflush\030\025 \002(\004\022\032\n\022diskthreadpoolsize\030\026 \002(\r", 600); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "ForkDataTransfer.proto", &protobuf_RegisterTypes); ForkDataTransfer::default_instance_ = new ForkDataTransfer(); @@ -93,8 +127,36 @@ struct StaticDescriptorInitializer_ForkDataTransfer_2eproto { // =================================================================== const ::std::string ForkDataTransfer::_default_unitname_; +const ::std::string ForkDataTransfer::_default_dgn_; +const ::std::string ForkDataTransfer::_default_devfilename_; +const ::std::string ForkDataTransfer::_default_libraryslot_; +const ::std::string ForkDataTransfer::_default_devtype_; +const ::std::string ForkDataTransfer::_default_clienthost_; +const ::std::string ForkDataTransfer::_default_clientusername_; +const ::std::string ForkDataTransfer::_default_badmirhandling_; #ifndef _MSC_VER const int ForkDataTransfer::kUnitnameFieldNumber; +const int ForkDataTransfer::kDgnFieldNumber; +const int ForkDataTransfer::kDevfilenameFieldNumber; +const int ForkDataTransfer::kDensityFieldNumber; +const int ForkDataTransfer::kLibraryslotFieldNumber; +const int ForkDataTransfer::kDevtypeFieldNumber; +const int ForkDataTransfer::kMounttransactionidFieldNumber; +const int ForkDataTransfer::kClientportFieldNumber; +const int ForkDataTransfer::kClienteuidFieldNumber; +const int ForkDataTransfer::kClientegidFieldNumber; +const int ForkDataTransfer::kClienthostFieldNumber; +const int ForkDataTransfer::kClientusernameFieldNumber; +const int ForkDataTransfer::kMemblocksizeFieldNumber; +const int ForkDataTransfer::kNbmemblocksFieldNumber; +const int ForkDataTransfer::kBadmirhandlingFieldNumber; +const int ForkDataTransfer::kBulkrequestmigrationmaxbytesFieldNumber; +const int ForkDataTransfer::kBulkrequestmigrationmaxfilesFieldNumber; +const int ForkDataTransfer::kBulkrequestrecallmaxbytesFieldNumber; +const int ForkDataTransfer::kBulkrequestrecallmaxfilesFieldNumber; +const int ForkDataTransfer::kMaxbytesbeforeflushFieldNumber; +const int ForkDataTransfer::kMaxfilesbeforeflushFieldNumber; +const int ForkDataTransfer::kDiskthreadpoolsizeFieldNumber; #endif // !_MSC_VER ForkDataTransfer::ForkDataTransfer() @@ -114,6 +176,26 @@ ForkDataTransfer::ForkDataTransfer(const ForkDataTransfer& from) void ForkDataTransfer::SharedCtor() { _cached_size_ = 0; unitname_ = const_cast< ::std::string*>(&_default_unitname_); + dgn_ = const_cast< ::std::string*>(&_default_dgn_); + devfilename_ = const_cast< ::std::string*>(&_default_devfilename_); + libraryslot_ = const_cast< ::std::string*>(&_default_libraryslot_); + devtype_ = const_cast< ::std::string*>(&_default_devtype_); + mounttransactionid_ = 0u; + clientport_ = 0u; + clienteuid_ = 0u; + clientegid_ = 0u; + clienthost_ = const_cast< ::std::string*>(&_default_clienthost_); + clientusername_ = const_cast< ::std::string*>(&_default_clientusername_); + memblocksize_ = 0u; + nbmemblocks_ = 0u; + badmirhandling_ = const_cast< ::std::string*>(&_default_badmirhandling_); + bulkrequestmigrationmaxbytes_ = GOOGLE_ULONGLONG(0); + bulkrequestmigrationmaxfiles_ = GOOGLE_ULONGLONG(0); + bulkrequestrecallmaxbytes_ = GOOGLE_ULONGLONG(0); + bulkrequestrecallmaxfiles_ = GOOGLE_ULONGLONG(0); + maxbytesbeforeflush_ = GOOGLE_ULONGLONG(0); + maxfilesbeforeflush_ = GOOGLE_ULONGLONG(0); + diskthreadpoolsize_ = 0u; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -125,6 +207,27 @@ void ForkDataTransfer::SharedDtor() { if (unitname_ != &_default_unitname_) { delete unitname_; } + if (dgn_ != &_default_dgn_) { + delete dgn_; + } + if (devfilename_ != &_default_devfilename_) { + delete devfilename_; + } + if (libraryslot_ != &_default_libraryslot_) { + delete libraryslot_; + } + if (devtype_ != &_default_devtype_) { + delete devtype_; + } + if (clienthost_ != &_default_clienthost_) { + delete clienthost_; + } + if (clientusername_ != &_default_clientusername_) { + delete clientusername_; + } + if (badmirhandling_ != &_default_badmirhandling_) { + delete badmirhandling_; + } if (this != default_instance_) { } } @@ -156,7 +259,60 @@ void ForkDataTransfer::Clear() { unitname_->clear(); } } + if (_has_bit(1)) { + if (dgn_ != &_default_dgn_) { + dgn_->clear(); + } + } + if (_has_bit(2)) { + if (devfilename_ != &_default_devfilename_) { + devfilename_->clear(); + } + } + if (_has_bit(4)) { + if (libraryslot_ != &_default_libraryslot_) { + libraryslot_->clear(); + } + } + if (_has_bit(5)) { + if (devtype_ != &_default_devtype_) { + devtype_->clear(); + } + } + mounttransactionid_ = 0u; + clientport_ = 0u; } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + clienteuid_ = 0u; + clientegid_ = 0u; + if (_has_bit(10)) { + if (clienthost_ != &_default_clienthost_) { + clienthost_->clear(); + } + } + if (_has_bit(11)) { + if (clientusername_ != &_default_clientusername_) { + clientusername_->clear(); + } + } + memblocksize_ = 0u; + nbmemblocks_ = 0u; + if (_has_bit(14)) { + if (badmirhandling_ != &_default_badmirhandling_) { + badmirhandling_->clear(); + } + } + bulkrequestmigrationmaxbytes_ = GOOGLE_ULONGLONG(0); + } + if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + bulkrequestmigrationmaxfiles_ = GOOGLE_ULONGLONG(0); + bulkrequestrecallmaxbytes_ = GOOGLE_ULONGLONG(0); + bulkrequestrecallmaxfiles_ = GOOGLE_ULONGLONG(0); + maxbytesbeforeflush_ = GOOGLE_ULONGLONG(0); + maxfilesbeforeflush_ = GOOGLE_ULONGLONG(0); + diskthreadpoolsize_ = 0u; + } + density_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); } @@ -179,6 +335,351 @@ bool ForkDataTransfer::MergePartialFromCodedStream( } else { goto handle_uninterpreted; } + if (input->ExpectTag(18)) goto parse_dgn; + break; + } + + // required string dgn = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_dgn: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_dgn())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dgn().data(), this->dgn().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_devfilename; + break; + } + + // required string devfilename = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_devfilename: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_devfilename())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devfilename().data(), this->devfilename().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_density; + break; + } + + // repeated string density = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_density: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_density())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->density(0).data(), this->density(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_density; + if (input->ExpectTag(42)) goto parse_libraryslot; + break; + } + + // required string libraryslot = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_libraryslot: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_libraryslot())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->libraryslot().data(), this->libraryslot().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(50)) goto parse_devtype; + break; + } + + // required string devtype = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_devtype: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_devtype())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devtype().data(), this->devtype().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(56)) goto parse_mounttransactionid; + break; + } + + // required uint32 mounttransactionid = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_mounttransactionid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &mounttransactionid_))); + _set_bit(6); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(64)) goto parse_clientport; + break; + } + + // required uint32 clientport = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_clientport: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &clientport_))); + _set_bit(7); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(72)) goto parse_clienteuid; + break; + } + + // required uint32 clienteuid = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_clienteuid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &clienteuid_))); + _set_bit(8); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(80)) goto parse_clientegid; + break; + } + + // required uint32 clientegid = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_clientegid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &clientegid_))); + _set_bit(9); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(90)) goto parse_clienthost; + break; + } + + // required string clienthost = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_clienthost: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_clienthost())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clienthost().data(), this->clienthost().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(98)) goto parse_clientusername; + break; + } + + // required string clientusername = 12; + case 12: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_clientusername: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_clientusername())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clientusername().data(), this->clientusername().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(104)) goto parse_memblocksize; + break; + } + + // required uint32 memblocksize = 13; + case 13: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_memblocksize: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &memblocksize_))); + _set_bit(12); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(112)) goto parse_nbmemblocks; + break; + } + + // required uint32 nbmemblocks = 14; + case 14: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_nbmemblocks: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &nbmemblocks_))); + _set_bit(13); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_badmirhandling; + break; + } + + // required string badmirhandling = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_badmirhandling: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_badmirhandling())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->badmirhandling().data(), this->badmirhandling().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(128)) goto parse_bulkrequestmigrationmaxbytes; + break; + } + + // required uint64 bulkrequestmigrationmaxbytes = 16; + case 16: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_bulkrequestmigrationmaxbytes: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &bulkrequestmigrationmaxbytes_))); + _set_bit(15); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(136)) goto parse_bulkrequestmigrationmaxfiles; + break; + } + + // required uint64 bulkrequestmigrationmaxfiles = 17; + case 17: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_bulkrequestmigrationmaxfiles: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &bulkrequestmigrationmaxfiles_))); + _set_bit(16); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(144)) goto parse_bulkrequestrecallmaxbytes; + break; + } + + // required uint64 bulkrequestrecallmaxbytes = 18; + case 18: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_bulkrequestrecallmaxbytes: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &bulkrequestrecallmaxbytes_))); + _set_bit(17); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(152)) goto parse_bulkrequestrecallmaxfiles; + break; + } + + // required uint64 bulkrequestrecallmaxfiles = 19; + case 19: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_bulkrequestrecallmaxfiles: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &bulkrequestrecallmaxfiles_))); + _set_bit(18); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(160)) goto parse_maxbytesbeforeflush; + break; + } + + // required uint64 maxbytesbeforeflush = 20; + case 20: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_maxbytesbeforeflush: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &maxbytesbeforeflush_))); + _set_bit(19); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(168)) goto parse_maxfilesbeforeflush; + break; + } + + // required uint64 maxfilesbeforeflush = 21; + case 21: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_maxfilesbeforeflush: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &maxfilesbeforeflush_))); + _set_bit(20); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(176)) goto parse_diskthreadpoolsize; + break; + } + + // required uint32 diskthreadpoolsize = 22; + case 22: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_diskthreadpoolsize: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &diskthreadpoolsize_))); + _set_bit(21); + } else { + goto handle_uninterpreted; + } if (input->ExpectAtEnd()) return true; break; } @@ -210,6 +711,143 @@ void ForkDataTransfer::SerializeWithCachedSizes( 1, this->unitname(), output); } + // required string dgn = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dgn().data(), this->dgn().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->dgn(), output); + } + + // required string devfilename = 3; + if (_has_bit(2)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devfilename().data(), this->devfilename().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->devfilename(), output); + } + + // repeated string density = 4; + for (int i = 0; i < this->density_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->density(i).data(), this->density(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->density(i), output); + } + + // required string libraryslot = 5; + if (_has_bit(4)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->libraryslot().data(), this->libraryslot().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->libraryslot(), output); + } + + // required string devtype = 6; + if (_has_bit(5)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devtype().data(), this->devtype().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 6, this->devtype(), output); + } + + // required uint32 mounttransactionid = 7; + if (_has_bit(6)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->mounttransactionid(), output); + } + + // required uint32 clientport = 8; + if (_has_bit(7)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->clientport(), output); + } + + // required uint32 clienteuid = 9; + if (_has_bit(8)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->clienteuid(), output); + } + + // required uint32 clientegid = 10; + if (_has_bit(9)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(10, this->clientegid(), output); + } + + // required string clienthost = 11; + if (_has_bit(10)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clienthost().data(), this->clienthost().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 11, this->clienthost(), output); + } + + // required string clientusername = 12; + if (_has_bit(11)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clientusername().data(), this->clientusername().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 12, this->clientusername(), output); + } + + // required uint32 memblocksize = 13; + if (_has_bit(12)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(13, this->memblocksize(), output); + } + + // required uint32 nbmemblocks = 14; + if (_has_bit(13)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(14, this->nbmemblocks(), output); + } + + // required string badmirhandling = 15; + if (_has_bit(14)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->badmirhandling().data(), this->badmirhandling().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 15, this->badmirhandling(), output); + } + + // required uint64 bulkrequestmigrationmaxbytes = 16; + if (_has_bit(15)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(16, this->bulkrequestmigrationmaxbytes(), output); + } + + // required uint64 bulkrequestmigrationmaxfiles = 17; + if (_has_bit(16)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(17, this->bulkrequestmigrationmaxfiles(), output); + } + + // required uint64 bulkrequestrecallmaxbytes = 18; + if (_has_bit(17)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(18, this->bulkrequestrecallmaxbytes(), output); + } + + // required uint64 bulkrequestrecallmaxfiles = 19; + if (_has_bit(18)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(19, this->bulkrequestrecallmaxfiles(), output); + } + + // required uint64 maxbytesbeforeflush = 20; + if (_has_bit(19)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(20, this->maxbytesbeforeflush(), output); + } + + // required uint64 maxfilesbeforeflush = 21; + if (_has_bit(20)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(21, this->maxfilesbeforeflush(), output); + } + + // required uint32 diskthreadpoolsize = 22; + if (_has_bit(21)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(22, this->diskthreadpoolsize(), output); + } + if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); @@ -228,6 +866,150 @@ void ForkDataTransfer::SerializeWithCachedSizes( 1, this->unitname(), target); } + // required string dgn = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dgn().data(), this->dgn().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->dgn(), target); + } + + // required string devfilename = 3; + if (_has_bit(2)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devfilename().data(), this->devfilename().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->devfilename(), target); + } + + // repeated string density = 4; + for (int i = 0; i < this->density_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->density(i).data(), this->density(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(4, this->density(i), target); + } + + // required string libraryslot = 5; + if (_has_bit(4)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->libraryslot().data(), this->libraryslot().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->libraryslot(), target); + } + + // required string devtype = 6; + if (_has_bit(5)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->devtype().data(), this->devtype().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->devtype(), target); + } + + // required uint32 mounttransactionid = 7; + if (_has_bit(6)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->mounttransactionid(), target); + } + + // required uint32 clientport = 8; + if (_has_bit(7)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->clientport(), target); + } + + // required uint32 clienteuid = 9; + if (_has_bit(8)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->clienteuid(), target); + } + + // required uint32 clientegid = 10; + if (_has_bit(9)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(10, this->clientegid(), target); + } + + // required string clienthost = 11; + if (_has_bit(10)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clienthost().data(), this->clienthost().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 11, this->clienthost(), target); + } + + // required string clientusername = 12; + if (_has_bit(11)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->clientusername().data(), this->clientusername().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 12, this->clientusername(), target); + } + + // required uint32 memblocksize = 13; + if (_has_bit(12)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(13, this->memblocksize(), target); + } + + // required uint32 nbmemblocks = 14; + if (_has_bit(13)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(14, this->nbmemblocks(), target); + } + + // required string badmirhandling = 15; + if (_has_bit(14)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->badmirhandling().data(), this->badmirhandling().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 15, this->badmirhandling(), target); + } + + // required uint64 bulkrequestmigrationmaxbytes = 16; + if (_has_bit(15)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(16, this->bulkrequestmigrationmaxbytes(), target); + } + + // required uint64 bulkrequestmigrationmaxfiles = 17; + if (_has_bit(16)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(17, this->bulkrequestmigrationmaxfiles(), target); + } + + // required uint64 bulkrequestrecallmaxbytes = 18; + if (_has_bit(17)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(18, this->bulkrequestrecallmaxbytes(), target); + } + + // required uint64 bulkrequestrecallmaxfiles = 19; + if (_has_bit(18)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(19, this->bulkrequestrecallmaxfiles(), target); + } + + // required uint64 maxbytesbeforeflush = 20; + if (_has_bit(19)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(20, this->maxbytesbeforeflush(), target); + } + + // required uint64 maxfilesbeforeflush = 21; + if (_has_bit(20)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(21, this->maxfilesbeforeflush(), target); + } + + // required uint32 diskthreadpoolsize = 22; + if (_has_bit(21)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(22, this->diskthreadpoolsize(), target); + } + if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -246,7 +1028,158 @@ int ForkDataTransfer::ByteSize() const { this->unitname()); } + // required string dgn = 2; + if (has_dgn()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->dgn()); + } + + // required string devfilename = 3; + if (has_devfilename()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->devfilename()); + } + + // required string libraryslot = 5; + if (has_libraryslot()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->libraryslot()); + } + + // required string devtype = 6; + if (has_devtype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->devtype()); + } + + // required uint32 mounttransactionid = 7; + if (has_mounttransactionid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->mounttransactionid()); + } + + // required uint32 clientport = 8; + if (has_clientport()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->clientport()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required uint32 clienteuid = 9; + if (has_clienteuid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->clienteuid()); + } + + // required uint32 clientegid = 10; + if (has_clientegid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->clientegid()); + } + + // required string clienthost = 11; + if (has_clienthost()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->clienthost()); + } + + // required string clientusername = 12; + if (has_clientusername()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->clientusername()); + } + + // required uint32 memblocksize = 13; + if (has_memblocksize()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->memblocksize()); + } + + // required uint32 nbmemblocks = 14; + if (has_nbmemblocks()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->nbmemblocks()); + } + + // required string badmirhandling = 15; + if (has_badmirhandling()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->badmirhandling()); + } + + // required uint64 bulkrequestmigrationmaxbytes = 16; + if (has_bulkrequestmigrationmaxbytes()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->bulkrequestmigrationmaxbytes()); + } + } + if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + // required uint64 bulkrequestmigrationmaxfiles = 17; + if (has_bulkrequestmigrationmaxfiles()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->bulkrequestmigrationmaxfiles()); + } + + // required uint64 bulkrequestrecallmaxbytes = 18; + if (has_bulkrequestrecallmaxbytes()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->bulkrequestrecallmaxbytes()); + } + + // required uint64 bulkrequestrecallmaxfiles = 19; + if (has_bulkrequestrecallmaxfiles()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->bulkrequestrecallmaxfiles()); + } + + // required uint64 maxbytesbeforeflush = 20; + if (has_maxbytesbeforeflush()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->maxbytesbeforeflush()); + } + + // required uint64 maxfilesbeforeflush = 21; + if (has_maxfilesbeforeflush()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->maxfilesbeforeflush()); + } + + // required uint32 diskthreadpoolsize = 22; + if (has_diskthreadpoolsize()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->diskthreadpoolsize()); + } + + } + // repeated string density = 4; + total_size += 1 * this->density_size(); + for (int i = 0; i < this->density_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->density(i)); + } + if (!unknown_fields().empty()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( @@ -272,10 +1205,75 @@ void ForkDataTransfer::MergeFrom(const ::google::protobuf::Message& from) { void ForkDataTransfer::MergeFrom(const ForkDataTransfer& from) { GOOGLE_CHECK_NE(&from, this); + density_.MergeFrom(from.density_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from._has_bit(0)) { set_unitname(from.unitname()); } + if (from._has_bit(1)) { + set_dgn(from.dgn()); + } + if (from._has_bit(2)) { + set_devfilename(from.devfilename()); + } + if (from._has_bit(4)) { + set_libraryslot(from.libraryslot()); + } + if (from._has_bit(5)) { + set_devtype(from.devtype()); + } + if (from._has_bit(6)) { + set_mounttransactionid(from.mounttransactionid()); + } + if (from._has_bit(7)) { + set_clientport(from.clientport()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from._has_bit(8)) { + set_clienteuid(from.clienteuid()); + } + if (from._has_bit(9)) { + set_clientegid(from.clientegid()); + } + if (from._has_bit(10)) { + set_clienthost(from.clienthost()); + } + if (from._has_bit(11)) { + set_clientusername(from.clientusername()); + } + if (from._has_bit(12)) { + set_memblocksize(from.memblocksize()); + } + if (from._has_bit(13)) { + set_nbmemblocks(from.nbmemblocks()); + } + if (from._has_bit(14)) { + set_badmirhandling(from.badmirhandling()); + } + if (from._has_bit(15)) { + set_bulkrequestmigrationmaxbytes(from.bulkrequestmigrationmaxbytes()); + } + } + if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) { + if (from._has_bit(16)) { + set_bulkrequestmigrationmaxfiles(from.bulkrequestmigrationmaxfiles()); + } + if (from._has_bit(17)) { + set_bulkrequestrecallmaxbytes(from.bulkrequestrecallmaxbytes()); + } + if (from._has_bit(18)) { + set_bulkrequestrecallmaxfiles(from.bulkrequestrecallmaxfiles()); + } + if (from._has_bit(19)) { + set_maxbytesbeforeflush(from.maxbytesbeforeflush()); + } + if (from._has_bit(20)) { + set_maxfilesbeforeflush(from.maxfilesbeforeflush()); + } + if (from._has_bit(21)) { + set_diskthreadpoolsize(from.diskthreadpoolsize()); + } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -293,7 +1291,7 @@ void ForkDataTransfer::CopyFrom(const ForkDataTransfer& from) { } bool ForkDataTransfer::IsInitialized() const { - if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + if ((_has_bits_[0] & 0x003ffff7) != 0x003ffff7) return false; return true; } @@ -301,6 +1299,27 @@ bool ForkDataTransfer::IsInitialized() const { void ForkDataTransfer::Swap(ForkDataTransfer* other) { if (other != this) { std::swap(unitname_, other->unitname_); + std::swap(dgn_, other->dgn_); + std::swap(devfilename_, other->devfilename_); + density_.Swap(&other->density_); + std::swap(libraryslot_, other->libraryslot_); + std::swap(devtype_, other->devtype_); + std::swap(mounttransactionid_, other->mounttransactionid_); + std::swap(clientport_, other->clientport_); + std::swap(clienteuid_, other->clienteuid_); + std::swap(clientegid_, other->clientegid_); + std::swap(clienthost_, other->clienthost_); + std::swap(clientusername_, other->clientusername_); + std::swap(memblocksize_, other->memblocksize_); + std::swap(nbmemblocks_, other->nbmemblocks_); + std::swap(badmirhandling_, other->badmirhandling_); + std::swap(bulkrequestmigrationmaxbytes_, other->bulkrequestmigrationmaxbytes_); + std::swap(bulkrequestmigrationmaxfiles_, other->bulkrequestmigrationmaxfiles_); + std::swap(bulkrequestrecallmaxbytes_, other->bulkrequestrecallmaxbytes_); + std::swap(bulkrequestrecallmaxfiles_, other->bulkrequestrecallmaxfiles_); + std::swap(maxbytesbeforeflush_, other->maxbytesbeforeflush_); + std::swap(maxfilesbeforeflush_, other->maxfilesbeforeflush_); + std::swap(diskthreadpoolsize_, other->diskthreadpoolsize_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); diff --git a/castor/messages/ForkDataTransfer.pb.h b/castor/messages/ForkDataTransfer.pb.h index e5db556d38..32c20ceece 100644 --- a/castor/messages/ForkDataTransfer.pb.h +++ b/castor/messages/ForkDataTransfer.pb.h @@ -101,6 +101,183 @@ class ForkDataTransfer : public ::google::protobuf::Message { inline void set_unitname(const char* value, size_t size); inline ::std::string* mutable_unitname(); + // required string dgn = 2; + inline bool has_dgn() const; + inline void clear_dgn(); + static const int kDgnFieldNumber = 2; + inline const ::std::string& dgn() const; + inline void set_dgn(const ::std::string& value); + inline void set_dgn(const char* value); + inline void set_dgn(const char* value, size_t size); + inline ::std::string* mutable_dgn(); + + // required string devfilename = 3; + inline bool has_devfilename() const; + inline void clear_devfilename(); + static const int kDevfilenameFieldNumber = 3; + inline const ::std::string& devfilename() const; + inline void set_devfilename(const ::std::string& value); + inline void set_devfilename(const char* value); + inline void set_devfilename(const char* value, size_t size); + inline ::std::string* mutable_devfilename(); + + // repeated string density = 4; + inline int density_size() const; + inline void clear_density(); + static const int kDensityFieldNumber = 4; + inline const ::std::string& density(int index) const; + inline ::std::string* mutable_density(int index); + inline void set_density(int index, const ::std::string& value); + inline void set_density(int index, const char* value); + inline void set_density(int index, const char* value, size_t size); + inline ::std::string* add_density(); + inline void add_density(const ::std::string& value); + inline void add_density(const char* value); + inline void add_density(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& density() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_density(); + + // required string libraryslot = 5; + inline bool has_libraryslot() const; + inline void clear_libraryslot(); + static const int kLibraryslotFieldNumber = 5; + inline const ::std::string& libraryslot() const; + inline void set_libraryslot(const ::std::string& value); + inline void set_libraryslot(const char* value); + inline void set_libraryslot(const char* value, size_t size); + inline ::std::string* mutable_libraryslot(); + + // required string devtype = 6; + inline bool has_devtype() const; + inline void clear_devtype(); + static const int kDevtypeFieldNumber = 6; + inline const ::std::string& devtype() const; + inline void set_devtype(const ::std::string& value); + inline void set_devtype(const char* value); + inline void set_devtype(const char* value, size_t size); + inline ::std::string* mutable_devtype(); + + // required uint32 mounttransactionid = 7; + inline bool has_mounttransactionid() const; + inline void clear_mounttransactionid(); + static const int kMounttransactionidFieldNumber = 7; + inline ::google::protobuf::uint32 mounttransactionid() const; + inline void set_mounttransactionid(::google::protobuf::uint32 value); + + // required uint32 clientport = 8; + inline bool has_clientport() const; + inline void clear_clientport(); + static const int kClientportFieldNumber = 8; + inline ::google::protobuf::uint32 clientport() const; + inline void set_clientport(::google::protobuf::uint32 value); + + // required uint32 clienteuid = 9; + inline bool has_clienteuid() const; + inline void clear_clienteuid(); + static const int kClienteuidFieldNumber = 9; + inline ::google::protobuf::uint32 clienteuid() const; + inline void set_clienteuid(::google::protobuf::uint32 value); + + // required uint32 clientegid = 10; + inline bool has_clientegid() const; + inline void clear_clientegid(); + static const int kClientegidFieldNumber = 10; + inline ::google::protobuf::uint32 clientegid() const; + inline void set_clientegid(::google::protobuf::uint32 value); + + // required string clienthost = 11; + inline bool has_clienthost() const; + inline void clear_clienthost(); + static const int kClienthostFieldNumber = 11; + inline const ::std::string& clienthost() const; + inline void set_clienthost(const ::std::string& value); + inline void set_clienthost(const char* value); + inline void set_clienthost(const char* value, size_t size); + inline ::std::string* mutable_clienthost(); + + // required string clientusername = 12; + inline bool has_clientusername() const; + inline void clear_clientusername(); + static const int kClientusernameFieldNumber = 12; + inline const ::std::string& clientusername() const; + inline void set_clientusername(const ::std::string& value); + inline void set_clientusername(const char* value); + inline void set_clientusername(const char* value, size_t size); + inline ::std::string* mutable_clientusername(); + + // required uint32 memblocksize = 13; + inline bool has_memblocksize() const; + inline void clear_memblocksize(); + static const int kMemblocksizeFieldNumber = 13; + inline ::google::protobuf::uint32 memblocksize() const; + inline void set_memblocksize(::google::protobuf::uint32 value); + + // required uint32 nbmemblocks = 14; + inline bool has_nbmemblocks() const; + inline void clear_nbmemblocks(); + static const int kNbmemblocksFieldNumber = 14; + inline ::google::protobuf::uint32 nbmemblocks() const; + inline void set_nbmemblocks(::google::protobuf::uint32 value); + + // required string badmirhandling = 15; + inline bool has_badmirhandling() const; + inline void clear_badmirhandling(); + static const int kBadmirhandlingFieldNumber = 15; + inline const ::std::string& badmirhandling() const; + inline void set_badmirhandling(const ::std::string& value); + inline void set_badmirhandling(const char* value); + inline void set_badmirhandling(const char* value, size_t size); + inline ::std::string* mutable_badmirhandling(); + + // required uint64 bulkrequestmigrationmaxbytes = 16; + inline bool has_bulkrequestmigrationmaxbytes() const; + inline void clear_bulkrequestmigrationmaxbytes(); + static const int kBulkrequestmigrationmaxbytesFieldNumber = 16; + inline ::google::protobuf::uint64 bulkrequestmigrationmaxbytes() const; + inline void set_bulkrequestmigrationmaxbytes(::google::protobuf::uint64 value); + + // required uint64 bulkrequestmigrationmaxfiles = 17; + inline bool has_bulkrequestmigrationmaxfiles() const; + inline void clear_bulkrequestmigrationmaxfiles(); + static const int kBulkrequestmigrationmaxfilesFieldNumber = 17; + inline ::google::protobuf::uint64 bulkrequestmigrationmaxfiles() const; + inline void set_bulkrequestmigrationmaxfiles(::google::protobuf::uint64 value); + + // required uint64 bulkrequestrecallmaxbytes = 18; + inline bool has_bulkrequestrecallmaxbytes() const; + inline void clear_bulkrequestrecallmaxbytes(); + static const int kBulkrequestrecallmaxbytesFieldNumber = 18; + inline ::google::protobuf::uint64 bulkrequestrecallmaxbytes() const; + inline void set_bulkrequestrecallmaxbytes(::google::protobuf::uint64 value); + + // required uint64 bulkrequestrecallmaxfiles = 19; + inline bool has_bulkrequestrecallmaxfiles() const; + inline void clear_bulkrequestrecallmaxfiles(); + static const int kBulkrequestrecallmaxfilesFieldNumber = 19; + inline ::google::protobuf::uint64 bulkrequestrecallmaxfiles() const; + inline void set_bulkrequestrecallmaxfiles(::google::protobuf::uint64 value); + + // required uint64 maxbytesbeforeflush = 20; + inline bool has_maxbytesbeforeflush() const; + inline void clear_maxbytesbeforeflush(); + static const int kMaxbytesbeforeflushFieldNumber = 20; + inline ::google::protobuf::uint64 maxbytesbeforeflush() const; + inline void set_maxbytesbeforeflush(::google::protobuf::uint64 value); + + // required uint64 maxfilesbeforeflush = 21; + inline bool has_maxfilesbeforeflush() const; + inline void clear_maxfilesbeforeflush(); + static const int kMaxfilesbeforeflushFieldNumber = 21; + inline ::google::protobuf::uint64 maxfilesbeforeflush() const; + inline void set_maxfilesbeforeflush(::google::protobuf::uint64 value); + + // required uint32 diskthreadpoolsize = 22; + inline bool has_diskthreadpoolsize() const; + inline void clear_diskthreadpoolsize(); + static const int kDiskthreadpoolsizeFieldNumber = 22; + inline ::google::protobuf::uint32 diskthreadpoolsize() const; + inline void set_diskthreadpoolsize(::google::protobuf::uint32 value); + // @@protoc_insertion_point(class_scope:castor.messages.ForkDataTransfer) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -108,11 +285,39 @@ class ForkDataTransfer : public ::google::protobuf::Message { ::std::string* unitname_; static const ::std::string _default_unitname_; + ::std::string* dgn_; + static const ::std::string _default_dgn_; + ::std::string* devfilename_; + static const ::std::string _default_devfilename_; + ::google::protobuf::RepeatedPtrField< ::std::string> density_; + ::std::string* libraryslot_; + static const ::std::string _default_libraryslot_; + ::std::string* devtype_; + static const ::std::string _default_devtype_; + ::google::protobuf::uint32 mounttransactionid_; + ::google::protobuf::uint32 clientport_; + ::google::protobuf::uint32 clienteuid_; + ::google::protobuf::uint32 clientegid_; + ::std::string* clienthost_; + static const ::std::string _default_clienthost_; + ::std::string* clientusername_; + static const ::std::string _default_clientusername_; + ::google::protobuf::uint32 memblocksize_; + ::google::protobuf::uint32 nbmemblocks_; + ::std::string* badmirhandling_; + static const ::std::string _default_badmirhandling_; + ::google::protobuf::uint64 bulkrequestmigrationmaxbytes_; + ::google::protobuf::uint64 bulkrequestmigrationmaxfiles_; + ::google::protobuf::uint64 bulkrequestrecallmaxbytes_; + ::google::protobuf::uint64 bulkrequestrecallmaxfiles_; + ::google::protobuf::uint64 maxbytesbeforeflush_; + ::google::protobuf::uint64 maxfilesbeforeflush_; + ::google::protobuf::uint32 diskthreadpoolsize_; friend void protobuf_AddDesc_ForkDataTransfer_2eproto(); friend void protobuf_AssignDesc_ForkDataTransfer_2eproto(); friend void protobuf_ShutdownFile_ForkDataTransfer_2eproto(); - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + ::google::protobuf::uint32 _has_bits_[(22 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? inline bool _has_bit(int index) const { @@ -177,6 +382,552 @@ inline ::std::string* ForkDataTransfer::mutable_unitname() { return unitname_; } +// required string dgn = 2; +inline bool ForkDataTransfer::has_dgn() const { + return _has_bit(1); +} +inline void ForkDataTransfer::clear_dgn() { + if (dgn_ != &_default_dgn_) { + dgn_->clear(); + } + _clear_bit(1); +} +inline const ::std::string& ForkDataTransfer::dgn() const { + return *dgn_; +} +inline void ForkDataTransfer::set_dgn(const ::std::string& value) { + _set_bit(1); + if (dgn_ == &_default_dgn_) { + dgn_ = new ::std::string; + } + dgn_->assign(value); +} +inline void ForkDataTransfer::set_dgn(const char* value) { + _set_bit(1); + if (dgn_ == &_default_dgn_) { + dgn_ = new ::std::string; + } + dgn_->assign(value); +} +inline void ForkDataTransfer::set_dgn(const char* value, size_t size) { + _set_bit(1); + if (dgn_ == &_default_dgn_) { + dgn_ = new ::std::string; + } + dgn_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_dgn() { + _set_bit(1); + if (dgn_ == &_default_dgn_) { + dgn_ = new ::std::string; + } + return dgn_; +} + +// required string devfilename = 3; +inline bool ForkDataTransfer::has_devfilename() const { + return _has_bit(2); +} +inline void ForkDataTransfer::clear_devfilename() { + if (devfilename_ != &_default_devfilename_) { + devfilename_->clear(); + } + _clear_bit(2); +} +inline const ::std::string& ForkDataTransfer::devfilename() const { + return *devfilename_; +} +inline void ForkDataTransfer::set_devfilename(const ::std::string& value) { + _set_bit(2); + if (devfilename_ == &_default_devfilename_) { + devfilename_ = new ::std::string; + } + devfilename_->assign(value); +} +inline void ForkDataTransfer::set_devfilename(const char* value) { + _set_bit(2); + if (devfilename_ == &_default_devfilename_) { + devfilename_ = new ::std::string; + } + devfilename_->assign(value); +} +inline void ForkDataTransfer::set_devfilename(const char* value, size_t size) { + _set_bit(2); + if (devfilename_ == &_default_devfilename_) { + devfilename_ = new ::std::string; + } + devfilename_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_devfilename() { + _set_bit(2); + if (devfilename_ == &_default_devfilename_) { + devfilename_ = new ::std::string; + } + return devfilename_; +} + +// repeated string density = 4; +inline int ForkDataTransfer::density_size() const { + return density_.size(); +} +inline void ForkDataTransfer::clear_density() { + density_.Clear(); +} +inline const ::std::string& ForkDataTransfer::density(int index) const { + return density_.Get(index); +} +inline ::std::string* ForkDataTransfer::mutable_density(int index) { + return density_.Mutable(index); +} +inline void ForkDataTransfer::set_density(int index, const ::std::string& value) { + density_.Mutable(index)->assign(value); +} +inline void ForkDataTransfer::set_density(int index, const char* value) { + density_.Mutable(index)->assign(value); +} +inline void ForkDataTransfer::set_density(int index, const char* value, size_t size) { + density_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::add_density() { + return density_.Add(); +} +inline void ForkDataTransfer::add_density(const ::std::string& value) { + density_.Add()->assign(value); +} +inline void ForkDataTransfer::add_density(const char* value) { + density_.Add()->assign(value); +} +inline void ForkDataTransfer::add_density(const char* value, size_t size) { + density_.Add()->assign(reinterpret_cast<const char*>(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +ForkDataTransfer::density() const { + return density_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +ForkDataTransfer::mutable_density() { + return &density_; +} + +// required string libraryslot = 5; +inline bool ForkDataTransfer::has_libraryslot() const { + return _has_bit(4); +} +inline void ForkDataTransfer::clear_libraryslot() { + if (libraryslot_ != &_default_libraryslot_) { + libraryslot_->clear(); + } + _clear_bit(4); +} +inline const ::std::string& ForkDataTransfer::libraryslot() const { + return *libraryslot_; +} +inline void ForkDataTransfer::set_libraryslot(const ::std::string& value) { + _set_bit(4); + if (libraryslot_ == &_default_libraryslot_) { + libraryslot_ = new ::std::string; + } + libraryslot_->assign(value); +} +inline void ForkDataTransfer::set_libraryslot(const char* value) { + _set_bit(4); + if (libraryslot_ == &_default_libraryslot_) { + libraryslot_ = new ::std::string; + } + libraryslot_->assign(value); +} +inline void ForkDataTransfer::set_libraryslot(const char* value, size_t size) { + _set_bit(4); + if (libraryslot_ == &_default_libraryslot_) { + libraryslot_ = new ::std::string; + } + libraryslot_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_libraryslot() { + _set_bit(4); + if (libraryslot_ == &_default_libraryslot_) { + libraryslot_ = new ::std::string; + } + return libraryslot_; +} + +// required string devtype = 6; +inline bool ForkDataTransfer::has_devtype() const { + return _has_bit(5); +} +inline void ForkDataTransfer::clear_devtype() { + if (devtype_ != &_default_devtype_) { + devtype_->clear(); + } + _clear_bit(5); +} +inline const ::std::string& ForkDataTransfer::devtype() const { + return *devtype_; +} +inline void ForkDataTransfer::set_devtype(const ::std::string& value) { + _set_bit(5); + if (devtype_ == &_default_devtype_) { + devtype_ = new ::std::string; + } + devtype_->assign(value); +} +inline void ForkDataTransfer::set_devtype(const char* value) { + _set_bit(5); + if (devtype_ == &_default_devtype_) { + devtype_ = new ::std::string; + } + devtype_->assign(value); +} +inline void ForkDataTransfer::set_devtype(const char* value, size_t size) { + _set_bit(5); + if (devtype_ == &_default_devtype_) { + devtype_ = new ::std::string; + } + devtype_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_devtype() { + _set_bit(5); + if (devtype_ == &_default_devtype_) { + devtype_ = new ::std::string; + } + return devtype_; +} + +// required uint32 mounttransactionid = 7; +inline bool ForkDataTransfer::has_mounttransactionid() const { + return _has_bit(6); +} +inline void ForkDataTransfer::clear_mounttransactionid() { + mounttransactionid_ = 0u; + _clear_bit(6); +} +inline ::google::protobuf::uint32 ForkDataTransfer::mounttransactionid() const { + return mounttransactionid_; +} +inline void ForkDataTransfer::set_mounttransactionid(::google::protobuf::uint32 value) { + _set_bit(6); + mounttransactionid_ = value; +} + +// required uint32 clientport = 8; +inline bool ForkDataTransfer::has_clientport() const { + return _has_bit(7); +} +inline void ForkDataTransfer::clear_clientport() { + clientport_ = 0u; + _clear_bit(7); +} +inline ::google::protobuf::uint32 ForkDataTransfer::clientport() const { + return clientport_; +} +inline void ForkDataTransfer::set_clientport(::google::protobuf::uint32 value) { + _set_bit(7); + clientport_ = value; +} + +// required uint32 clienteuid = 9; +inline bool ForkDataTransfer::has_clienteuid() const { + return _has_bit(8); +} +inline void ForkDataTransfer::clear_clienteuid() { + clienteuid_ = 0u; + _clear_bit(8); +} +inline ::google::protobuf::uint32 ForkDataTransfer::clienteuid() const { + return clienteuid_; +} +inline void ForkDataTransfer::set_clienteuid(::google::protobuf::uint32 value) { + _set_bit(8); + clienteuid_ = value; +} + +// required uint32 clientegid = 10; +inline bool ForkDataTransfer::has_clientegid() const { + return _has_bit(9); +} +inline void ForkDataTransfer::clear_clientegid() { + clientegid_ = 0u; + _clear_bit(9); +} +inline ::google::protobuf::uint32 ForkDataTransfer::clientegid() const { + return clientegid_; +} +inline void ForkDataTransfer::set_clientegid(::google::protobuf::uint32 value) { + _set_bit(9); + clientegid_ = value; +} + +// required string clienthost = 11; +inline bool ForkDataTransfer::has_clienthost() const { + return _has_bit(10); +} +inline void ForkDataTransfer::clear_clienthost() { + if (clienthost_ != &_default_clienthost_) { + clienthost_->clear(); + } + _clear_bit(10); +} +inline const ::std::string& ForkDataTransfer::clienthost() const { + return *clienthost_; +} +inline void ForkDataTransfer::set_clienthost(const ::std::string& value) { + _set_bit(10); + if (clienthost_ == &_default_clienthost_) { + clienthost_ = new ::std::string; + } + clienthost_->assign(value); +} +inline void ForkDataTransfer::set_clienthost(const char* value) { + _set_bit(10); + if (clienthost_ == &_default_clienthost_) { + clienthost_ = new ::std::string; + } + clienthost_->assign(value); +} +inline void ForkDataTransfer::set_clienthost(const char* value, size_t size) { + _set_bit(10); + if (clienthost_ == &_default_clienthost_) { + clienthost_ = new ::std::string; + } + clienthost_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_clienthost() { + _set_bit(10); + if (clienthost_ == &_default_clienthost_) { + clienthost_ = new ::std::string; + } + return clienthost_; +} + +// required string clientusername = 12; +inline bool ForkDataTransfer::has_clientusername() const { + return _has_bit(11); +} +inline void ForkDataTransfer::clear_clientusername() { + if (clientusername_ != &_default_clientusername_) { + clientusername_->clear(); + } + _clear_bit(11); +} +inline const ::std::string& ForkDataTransfer::clientusername() const { + return *clientusername_; +} +inline void ForkDataTransfer::set_clientusername(const ::std::string& value) { + _set_bit(11); + if (clientusername_ == &_default_clientusername_) { + clientusername_ = new ::std::string; + } + clientusername_->assign(value); +} +inline void ForkDataTransfer::set_clientusername(const char* value) { + _set_bit(11); + if (clientusername_ == &_default_clientusername_) { + clientusername_ = new ::std::string; + } + clientusername_->assign(value); +} +inline void ForkDataTransfer::set_clientusername(const char* value, size_t size) { + _set_bit(11); + if (clientusername_ == &_default_clientusername_) { + clientusername_ = new ::std::string; + } + clientusername_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_clientusername() { + _set_bit(11); + if (clientusername_ == &_default_clientusername_) { + clientusername_ = new ::std::string; + } + return clientusername_; +} + +// required uint32 memblocksize = 13; +inline bool ForkDataTransfer::has_memblocksize() const { + return _has_bit(12); +} +inline void ForkDataTransfer::clear_memblocksize() { + memblocksize_ = 0u; + _clear_bit(12); +} +inline ::google::protobuf::uint32 ForkDataTransfer::memblocksize() const { + return memblocksize_; +} +inline void ForkDataTransfer::set_memblocksize(::google::protobuf::uint32 value) { + _set_bit(12); + memblocksize_ = value; +} + +// required uint32 nbmemblocks = 14; +inline bool ForkDataTransfer::has_nbmemblocks() const { + return _has_bit(13); +} +inline void ForkDataTransfer::clear_nbmemblocks() { + nbmemblocks_ = 0u; + _clear_bit(13); +} +inline ::google::protobuf::uint32 ForkDataTransfer::nbmemblocks() const { + return nbmemblocks_; +} +inline void ForkDataTransfer::set_nbmemblocks(::google::protobuf::uint32 value) { + _set_bit(13); + nbmemblocks_ = value; +} + +// required string badmirhandling = 15; +inline bool ForkDataTransfer::has_badmirhandling() const { + return _has_bit(14); +} +inline void ForkDataTransfer::clear_badmirhandling() { + if (badmirhandling_ != &_default_badmirhandling_) { + badmirhandling_->clear(); + } + _clear_bit(14); +} +inline const ::std::string& ForkDataTransfer::badmirhandling() const { + return *badmirhandling_; +} +inline void ForkDataTransfer::set_badmirhandling(const ::std::string& value) { + _set_bit(14); + if (badmirhandling_ == &_default_badmirhandling_) { + badmirhandling_ = new ::std::string; + } + badmirhandling_->assign(value); +} +inline void ForkDataTransfer::set_badmirhandling(const char* value) { + _set_bit(14); + if (badmirhandling_ == &_default_badmirhandling_) { + badmirhandling_ = new ::std::string; + } + badmirhandling_->assign(value); +} +inline void ForkDataTransfer::set_badmirhandling(const char* value, size_t size) { + _set_bit(14); + if (badmirhandling_ == &_default_badmirhandling_) { + badmirhandling_ = new ::std::string; + } + badmirhandling_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* ForkDataTransfer::mutable_badmirhandling() { + _set_bit(14); + if (badmirhandling_ == &_default_badmirhandling_) { + badmirhandling_ = new ::std::string; + } + return badmirhandling_; +} + +// required uint64 bulkrequestmigrationmaxbytes = 16; +inline bool ForkDataTransfer::has_bulkrequestmigrationmaxbytes() const { + return _has_bit(15); +} +inline void ForkDataTransfer::clear_bulkrequestmigrationmaxbytes() { + bulkrequestmigrationmaxbytes_ = GOOGLE_ULONGLONG(0); + _clear_bit(15); +} +inline ::google::protobuf::uint64 ForkDataTransfer::bulkrequestmigrationmaxbytes() const { + return bulkrequestmigrationmaxbytes_; +} +inline void ForkDataTransfer::set_bulkrequestmigrationmaxbytes(::google::protobuf::uint64 value) { + _set_bit(15); + bulkrequestmigrationmaxbytes_ = value; +} + +// required uint64 bulkrequestmigrationmaxfiles = 17; +inline bool ForkDataTransfer::has_bulkrequestmigrationmaxfiles() const { + return _has_bit(16); +} +inline void ForkDataTransfer::clear_bulkrequestmigrationmaxfiles() { + bulkrequestmigrationmaxfiles_ = GOOGLE_ULONGLONG(0); + _clear_bit(16); +} +inline ::google::protobuf::uint64 ForkDataTransfer::bulkrequestmigrationmaxfiles() const { + return bulkrequestmigrationmaxfiles_; +} +inline void ForkDataTransfer::set_bulkrequestmigrationmaxfiles(::google::protobuf::uint64 value) { + _set_bit(16); + bulkrequestmigrationmaxfiles_ = value; +} + +// required uint64 bulkrequestrecallmaxbytes = 18; +inline bool ForkDataTransfer::has_bulkrequestrecallmaxbytes() const { + return _has_bit(17); +} +inline void ForkDataTransfer::clear_bulkrequestrecallmaxbytes() { + bulkrequestrecallmaxbytes_ = GOOGLE_ULONGLONG(0); + _clear_bit(17); +} +inline ::google::protobuf::uint64 ForkDataTransfer::bulkrequestrecallmaxbytes() const { + return bulkrequestrecallmaxbytes_; +} +inline void ForkDataTransfer::set_bulkrequestrecallmaxbytes(::google::protobuf::uint64 value) { + _set_bit(17); + bulkrequestrecallmaxbytes_ = value; +} + +// required uint64 bulkrequestrecallmaxfiles = 19; +inline bool ForkDataTransfer::has_bulkrequestrecallmaxfiles() const { + return _has_bit(18); +} +inline void ForkDataTransfer::clear_bulkrequestrecallmaxfiles() { + bulkrequestrecallmaxfiles_ = GOOGLE_ULONGLONG(0); + _clear_bit(18); +} +inline ::google::protobuf::uint64 ForkDataTransfer::bulkrequestrecallmaxfiles() const { + return bulkrequestrecallmaxfiles_; +} +inline void ForkDataTransfer::set_bulkrequestrecallmaxfiles(::google::protobuf::uint64 value) { + _set_bit(18); + bulkrequestrecallmaxfiles_ = value; +} + +// required uint64 maxbytesbeforeflush = 20; +inline bool ForkDataTransfer::has_maxbytesbeforeflush() const { + return _has_bit(19); +} +inline void ForkDataTransfer::clear_maxbytesbeforeflush() { + maxbytesbeforeflush_ = GOOGLE_ULONGLONG(0); + _clear_bit(19); +} +inline ::google::protobuf::uint64 ForkDataTransfer::maxbytesbeforeflush() const { + return maxbytesbeforeflush_; +} +inline void ForkDataTransfer::set_maxbytesbeforeflush(::google::protobuf::uint64 value) { + _set_bit(19); + maxbytesbeforeflush_ = value; +} + +// required uint64 maxfilesbeforeflush = 21; +inline bool ForkDataTransfer::has_maxfilesbeforeflush() const { + return _has_bit(20); +} +inline void ForkDataTransfer::clear_maxfilesbeforeflush() { + maxfilesbeforeflush_ = GOOGLE_ULONGLONG(0); + _clear_bit(20); +} +inline ::google::protobuf::uint64 ForkDataTransfer::maxfilesbeforeflush() const { + return maxfilesbeforeflush_; +} +inline void ForkDataTransfer::set_maxfilesbeforeflush(::google::protobuf::uint64 value) { + _set_bit(20); + maxfilesbeforeflush_ = value; +} + +// required uint32 diskthreadpoolsize = 22; +inline bool ForkDataTransfer::has_diskthreadpoolsize() const { + return _has_bit(21); +} +inline void ForkDataTransfer::clear_diskthreadpoolsize() { + diskthreadpoolsize_ = 0u; + _clear_bit(21); +} +inline ::google::protobuf::uint32 ForkDataTransfer::diskthreadpoolsize() const { + return diskthreadpoolsize_; +} +inline void ForkDataTransfer::set_diskthreadpoolsize(::google::protobuf::uint32 value) { + _set_bit(21); + diskthreadpoolsize_ = value; +} + // @@protoc_insertion_point(namespace_scope) diff --git a/castor/messages/ForkDataTransfer.proto b/castor/messages/ForkDataTransfer.proto index 9f68f3a6c0..22aa1f76fe 100644 --- a/castor/messages/ForkDataTransfer.proto +++ b/castor/messages/ForkDataTransfer.proto @@ -21,5 +21,31 @@ package castor.messages; message ForkDataTransfer { + // Description of the tape drive required string unitname = 1; + required string dgn = 2; + required string devfilename = 3; + repeated string density = 4; + required string libraryslot = 5; + required string devtype = 6; + + // The job from the VDQM + required uint32 mounttransactionid = 7; + required uint32 clientport = 8; + required uint32 clienteuid = 9; + required uint32 clientegid = 10; + required string clienthost = 11; + required string clientusername = 12; + + // Configuration parameters of the session + required uint32 memblocksize = 13; + required uint32 nbmemblocks = 14; + required string badmirhandling = 15; + required uint64 bulkrequestmigrationmaxbytes = 16; + required uint64 bulkrequestmigrationmaxfiles = 17; + required uint64 bulkrequestrecallmaxbytes = 18; + required uint64 bulkrequestrecallmaxfiles = 19; + required uint64 maxbytesbeforeflush = 20; + required uint64 maxfilesbeforeflush = 21; + required uint32 diskthreadpoolsize = 22; } diff --git a/castor/messages/ProcessCrashed.pb.cc b/castor/messages/ProcessCrashed.pb.cc new file mode 100644 index 0000000000..660455da03 --- /dev/null +++ b/castor/messages/ProcessCrashed.pb.cc @@ -0,0 +1,348 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "ProcessCrashed.pb.h" +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace castor { +namespace messages { + +namespace { + +const ::google::protobuf::Descriptor* ProcessCrashed_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ProcessCrashed_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_ProcessCrashed_2eproto() { + protobuf_AddDesc_ProcessCrashed_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "ProcessCrashed.proto"); + GOOGLE_CHECK(file != NULL); + ProcessCrashed_descriptor_ = file->message_type(0); + static const int ProcessCrashed_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessCrashed, pid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessCrashed, signal_), + }; + ProcessCrashed_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ProcessCrashed_descriptor_, + ProcessCrashed::default_instance_, + ProcessCrashed_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessCrashed, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessCrashed, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ProcessCrashed)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_ProcessCrashed_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ProcessCrashed_descriptor_, &ProcessCrashed::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_ProcessCrashed_2eproto() { + delete ProcessCrashed::default_instance_; + delete ProcessCrashed_reflection_; +} + +void protobuf_AddDesc_ProcessCrashed_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\024ProcessCrashed.proto\022\017castor.messages\"" + "-\n\016ProcessCrashed\022\013\n\003pid\030\001 \002(\004\022\016\n\006signal" + "\030\002 \002(\r", 86); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "ProcessCrashed.proto", &protobuf_RegisterTypes); + ProcessCrashed::default_instance_ = new ProcessCrashed(); + ProcessCrashed::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_ProcessCrashed_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_ProcessCrashed_2eproto { + StaticDescriptorInitializer_ProcessCrashed_2eproto() { + protobuf_AddDesc_ProcessCrashed_2eproto(); + } +} static_descriptor_initializer_ProcessCrashed_2eproto_; + + +// =================================================================== + +#ifndef _MSC_VER +const int ProcessCrashed::kPidFieldNumber; +const int ProcessCrashed::kSignalFieldNumber; +#endif // !_MSC_VER + +ProcessCrashed::ProcessCrashed() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ProcessCrashed::InitAsDefaultInstance() { +} + +ProcessCrashed::ProcessCrashed(const ProcessCrashed& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ProcessCrashed::SharedCtor() { + _cached_size_ = 0; + pid_ = GOOGLE_ULONGLONG(0); + signal_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ProcessCrashed::~ProcessCrashed() { + SharedDtor(); +} + +void ProcessCrashed::SharedDtor() { + if (this != default_instance_) { + } +} + +void ProcessCrashed::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ProcessCrashed::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ProcessCrashed_descriptor_; +} + +const ProcessCrashed& ProcessCrashed::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_ProcessCrashed_2eproto(); return *default_instance_; +} + +ProcessCrashed* ProcessCrashed::default_instance_ = NULL; + +ProcessCrashed* ProcessCrashed::New() const { + return new ProcessCrashed; +} + +void ProcessCrashed::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + pid_ = GOOGLE_ULONGLONG(0); + signal_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ProcessCrashed::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 pid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &pid_))); + _set_bit(0); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_signal; + break; + } + + // required uint32 signal = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_signal: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &signal_))); + _set_bit(1); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ProcessCrashed::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required uint64 pid = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->pid(), output); + } + + // required uint32 signal = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->signal(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ProcessCrashed::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required uint64 pid = 1; + if (_has_bit(0)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->pid(), target); + } + + // required uint32 signal = 2; + if (_has_bit(1)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->signal(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ProcessCrashed::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 pid = 1; + if (has_pid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->pid()); + } + + // required uint32 signal = 2; + if (has_signal()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->signal()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ProcessCrashed::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ProcessCrashed* source = + ::google::protobuf::internal::dynamic_cast_if_available<const ProcessCrashed*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ProcessCrashed::MergeFrom(const ProcessCrashed& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from._has_bit(0)) { + set_pid(from.pid()); + } + if (from._has_bit(1)) { + set_signal(from.signal()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ProcessCrashed::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ProcessCrashed::CopyFrom(const ProcessCrashed& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ProcessCrashed::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void ProcessCrashed::Swap(ProcessCrashed* other) { + if (other != this) { + std::swap(pid_, other->pid_); + std::swap(signal_, other->signal_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ProcessCrashed::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ProcessCrashed_descriptor_; + metadata.reflection = ProcessCrashed_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace messages +} // namespace castor + +// @@protoc_insertion_point(global_scope) diff --git a/castor/messages/ProcessCrashed.pb.h b/castor/messages/ProcessCrashed.pb.h new file mode 100644 index 0000000000..1dbac5418b --- /dev/null +++ b/castor/messages/ProcessCrashed.pb.h @@ -0,0 +1,191 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ProcessCrashed.proto + +#ifndef PROTOBUF_ProcessCrashed_2eproto__INCLUDED +#define PROTOBUF_ProcessCrashed_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 2003000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_reflection.h> +// @@protoc_insertion_point(includes) + +namespace castor { +namespace messages { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ProcessCrashed_2eproto(); +void protobuf_AssignDesc_ProcessCrashed_2eproto(); +void protobuf_ShutdownFile_ProcessCrashed_2eproto(); + +class ProcessCrashed; + +// =================================================================== + +class ProcessCrashed : public ::google::protobuf::Message { + public: + ProcessCrashed(); + virtual ~ProcessCrashed(); + + ProcessCrashed(const ProcessCrashed& from); + + inline ProcessCrashed& operator=(const ProcessCrashed& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ProcessCrashed& default_instance(); + + void Swap(ProcessCrashed* other); + + // implements Message ---------------------------------------------- + + ProcessCrashed* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ProcessCrashed& from); + void MergeFrom(const ProcessCrashed& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 pid = 1; + inline bool has_pid() const; + inline void clear_pid(); + static const int kPidFieldNumber = 1; + inline ::google::protobuf::uint64 pid() const; + inline void set_pid(::google::protobuf::uint64 value); + + // required uint32 signal = 2; + inline bool has_signal() const; + inline void clear_signal(); + static const int kSignalFieldNumber = 2; + inline ::google::protobuf::uint32 signal() const; + inline void set_signal(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:castor.messages.ProcessCrashed) + private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; + mutable int _cached_size_; + + ::google::protobuf::uint64 pid_; + ::google::protobuf::uint32 signal_; + friend void protobuf_AddDesc_ProcessCrashed_2eproto(); + friend void protobuf_AssignDesc_ProcessCrashed_2eproto(); + friend void protobuf_ShutdownFile_ProcessCrashed_2eproto(); + + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? + inline bool _has_bit(int index) const { + return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + } + inline void _set_bit(int index) { + _has_bits_[index / 32] |= (1u << (index % 32)); + } + inline void _clear_bit(int index) { + _has_bits_[index / 32] &= ~(1u << (index % 32)); + } + + void InitAsDefaultInstance(); + static ProcessCrashed* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// ProcessCrashed + +// required uint64 pid = 1; +inline bool ProcessCrashed::has_pid() const { + return _has_bit(0); +} +inline void ProcessCrashed::clear_pid() { + pid_ = GOOGLE_ULONGLONG(0); + _clear_bit(0); +} +inline ::google::protobuf::uint64 ProcessCrashed::pid() const { + return pid_; +} +inline void ProcessCrashed::set_pid(::google::protobuf::uint64 value) { + _set_bit(0); + pid_ = value; +} + +// required uint32 signal = 2; +inline bool ProcessCrashed::has_signal() const { + return _has_bit(1); +} +inline void ProcessCrashed::clear_signal() { + signal_ = 0u; + _clear_bit(1); +} +inline ::google::protobuf::uint32 ProcessCrashed::signal() const { + return signal_; +} +inline void ProcessCrashed::set_signal(::google::protobuf::uint32 value) { + _set_bit(1); + signal_ = value; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace messages +} // namespace castor + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ProcessCrashed_2eproto__INCLUDED diff --git a/castor/messages/ProcessCrashed.proto b/castor/messages/ProcessCrashed.proto new file mode 100644 index 0000000000..542b71b463 --- /dev/null +++ b/castor/messages/ProcessCrashed.proto @@ -0,0 +1,26 @@ +// 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 + +package castor.messages; + +message ProcessCrashed { + required uint64 pid = 1; + required uint32 signal = 2; +} diff --git a/castor/messages/ProcessExited.pb.cc b/castor/messages/ProcessExited.pb.cc new file mode 100644 index 0000000000..a5537411c0 --- /dev/null +++ b/castor/messages/ProcessExited.pb.cc @@ -0,0 +1,348 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "ProcessExited.pb.h" +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace castor { +namespace messages { + +namespace { + +const ::google::protobuf::Descriptor* ProcessExited_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ProcessExited_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_ProcessExited_2eproto() { + protobuf_AddDesc_ProcessExited_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "ProcessExited.proto"); + GOOGLE_CHECK(file != NULL); + ProcessExited_descriptor_ = file->message_type(0); + static const int ProcessExited_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessExited, pid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessExited, exitcode_), + }; + ProcessExited_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ProcessExited_descriptor_, + ProcessExited::default_instance_, + ProcessExited_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessExited, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProcessExited, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ProcessExited)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_ProcessExited_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ProcessExited_descriptor_, &ProcessExited::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_ProcessExited_2eproto() { + delete ProcessExited::default_instance_; + delete ProcessExited_reflection_; +} + +void protobuf_AddDesc_ProcessExited_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\023ProcessExited.proto\022\017castor.messages\"." + "\n\rProcessExited\022\013\n\003pid\030\001 \002(\004\022\020\n\010exitcode" + "\030\002 \002(\005", 86); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "ProcessExited.proto", &protobuf_RegisterTypes); + ProcessExited::default_instance_ = new ProcessExited(); + ProcessExited::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_ProcessExited_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_ProcessExited_2eproto { + StaticDescriptorInitializer_ProcessExited_2eproto() { + protobuf_AddDesc_ProcessExited_2eproto(); + } +} static_descriptor_initializer_ProcessExited_2eproto_; + + +// =================================================================== + +#ifndef _MSC_VER +const int ProcessExited::kPidFieldNumber; +const int ProcessExited::kExitcodeFieldNumber; +#endif // !_MSC_VER + +ProcessExited::ProcessExited() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ProcessExited::InitAsDefaultInstance() { +} + +ProcessExited::ProcessExited(const ProcessExited& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ProcessExited::SharedCtor() { + _cached_size_ = 0; + pid_ = GOOGLE_ULONGLONG(0); + exitcode_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ProcessExited::~ProcessExited() { + SharedDtor(); +} + +void ProcessExited::SharedDtor() { + if (this != default_instance_) { + } +} + +void ProcessExited::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ProcessExited::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ProcessExited_descriptor_; +} + +const ProcessExited& ProcessExited::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_ProcessExited_2eproto(); return *default_instance_; +} + +ProcessExited* ProcessExited::default_instance_ = NULL; + +ProcessExited* ProcessExited::New() const { + return new ProcessExited; +} + +void ProcessExited::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + pid_ = GOOGLE_ULONGLONG(0); + exitcode_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ProcessExited::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 pid = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &pid_))); + _set_bit(0); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_exitcode; + break; + } + + // required int32 exitcode = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_exitcode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &exitcode_))); + _set_bit(1); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ProcessExited::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required uint64 pid = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->pid(), output); + } + + // required int32 exitcode = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->exitcode(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ProcessExited::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required uint64 pid = 1; + if (_has_bit(0)) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->pid(), target); + } + + // required int32 exitcode = 2; + if (_has_bit(1)) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->exitcode(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ProcessExited::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint64 pid = 1; + if (has_pid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->pid()); + } + + // required int32 exitcode = 2; + if (has_exitcode()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->exitcode()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ProcessExited::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ProcessExited* source = + ::google::protobuf::internal::dynamic_cast_if_available<const ProcessExited*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ProcessExited::MergeFrom(const ProcessExited& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from._has_bit(0)) { + set_pid(from.pid()); + } + if (from._has_bit(1)) { + set_exitcode(from.exitcode()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ProcessExited::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ProcessExited::CopyFrom(const ProcessExited& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ProcessExited::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void ProcessExited::Swap(ProcessExited* other) { + if (other != this) { + std::swap(pid_, other->pid_); + std::swap(exitcode_, other->exitcode_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ProcessExited::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ProcessExited_descriptor_; + metadata.reflection = ProcessExited_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace messages +} // namespace castor + +// @@protoc_insertion_point(global_scope) diff --git a/castor/messages/ProcessExited.pb.h b/castor/messages/ProcessExited.pb.h new file mode 100644 index 0000000000..a135427d1f --- /dev/null +++ b/castor/messages/ProcessExited.pb.h @@ -0,0 +1,191 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ProcessExited.proto + +#ifndef PROTOBUF_ProcessExited_2eproto__INCLUDED +#define PROTOBUF_ProcessExited_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 2003000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_reflection.h> +// @@protoc_insertion_point(includes) + +namespace castor { +namespace messages { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ProcessExited_2eproto(); +void protobuf_AssignDesc_ProcessExited_2eproto(); +void protobuf_ShutdownFile_ProcessExited_2eproto(); + +class ProcessExited; + +// =================================================================== + +class ProcessExited : public ::google::protobuf::Message { + public: + ProcessExited(); + virtual ~ProcessExited(); + + ProcessExited(const ProcessExited& from); + + inline ProcessExited& operator=(const ProcessExited& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ProcessExited& default_instance(); + + void Swap(ProcessExited* other); + + // implements Message ---------------------------------------------- + + ProcessExited* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ProcessExited& from); + void MergeFrom(const ProcessExited& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 pid = 1; + inline bool has_pid() const; + inline void clear_pid(); + static const int kPidFieldNumber = 1; + inline ::google::protobuf::uint64 pid() const; + inline void set_pid(::google::protobuf::uint64 value); + + // required int32 exitcode = 2; + inline bool has_exitcode() const; + inline void clear_exitcode(); + static const int kExitcodeFieldNumber = 2; + inline ::google::protobuf::int32 exitcode() const; + inline void set_exitcode(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:castor.messages.ProcessExited) + private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; + mutable int _cached_size_; + + ::google::protobuf::uint64 pid_; + ::google::protobuf::int32 exitcode_; + friend void protobuf_AddDesc_ProcessExited_2eproto(); + friend void protobuf_AssignDesc_ProcessExited_2eproto(); + friend void protobuf_ShutdownFile_ProcessExited_2eproto(); + + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? + inline bool _has_bit(int index) const { + return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + } + inline void _set_bit(int index) { + _has_bits_[index / 32] |= (1u << (index % 32)); + } + inline void _clear_bit(int index) { + _has_bits_[index / 32] &= ~(1u << (index % 32)); + } + + void InitAsDefaultInstance(); + static ProcessExited* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// ProcessExited + +// required uint64 pid = 1; +inline bool ProcessExited::has_pid() const { + return _has_bit(0); +} +inline void ProcessExited::clear_pid() { + pid_ = GOOGLE_ULONGLONG(0); + _clear_bit(0); +} +inline ::google::protobuf::uint64 ProcessExited::pid() const { + return pid_; +} +inline void ProcessExited::set_pid(::google::protobuf::uint64 value) { + _set_bit(0); + pid_ = value; +} + +// required int32 exitcode = 2; +inline bool ProcessExited::has_exitcode() const { + return _has_bit(1); +} +inline void ProcessExited::clear_exitcode() { + exitcode_ = 0; + _clear_bit(1); +} +inline ::google::protobuf::int32 ProcessExited::exitcode() const { + return exitcode_; +} +inline void ProcessExited::set_exitcode(::google::protobuf::int32 value) { + _set_bit(1); + exitcode_ = value; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace messages +} // namespace castor + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ProcessExited_2eproto__INCLUDED diff --git a/castor/messages/ProcessExited.proto b/castor/messages/ProcessExited.proto new file mode 100644 index 0000000000..5c8d8ff31f --- /dev/null +++ b/castor/messages/ProcessExited.proto @@ -0,0 +1,26 @@ +// 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 + +package castor.messages; + +message ProcessExited { + required uint64 pid = 1; + required int32 exitcode = 2; +} diff --git a/castor/tape/tapeserver/daemon/CMakeLists.txt b/castor/tape/tapeserver/daemon/CMakeLists.txt index 3df2074699..e21e27ca2a 100644 --- a/castor/tape/tapeserver/daemon/CMakeLists.txt +++ b/castor/tape/tapeserver/daemon/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(castorTapeServerDaemon MigrationTaskInjector.cpp DataTransferSession.cpp ProcessForker.cpp + ProcessForkerConnectionHandler.cpp ProcessForkerProxy.cpp ProcessForkerMsgType.cpp ProcessForkerProxySocket.cpp diff --git a/castor/tape/tapeserver/daemon/DataTransferSession.cpp b/castor/tape/tapeserver/daemon/DataTransferSession.cpp index 190cfcc617..2b3826dd2b 100644 --- a/castor/tape/tapeserver/daemon/DataTransferSession.cpp +++ b/castor/tape/tapeserver/daemon/DataTransferSession.cpp @@ -21,35 +21,28 @@ * @author Castor Dev team, castor-dev@cern.ch *****************************************************************************/ -#include "castor/tape/tapeserver/daemon/DataTransferSession.hpp" #include "castor/log/LogContext.hpp" -#include "castor/tape/tapeserver/exception/Exception.hpp" -#include "castor/tape/tapeserver/client/ClientProxy.hpp" -#include "log.h" -#include "stager_client_commandline.h" -#include "castor/tape/utils/utils.hpp" #include "castor/System.hpp" -#include "castor/tape/tapeserver/SCSI/Device.hpp" -#include "castor/tape/tapeserver/drive/Drive.hpp" -#include "castor/tape/tapeserver/daemon/RecallTaskInjector.hpp" -#include "castor/tape/tapeserver/daemon/RecallReportPacker.hpp" -#include "castor/tape/tapeserver/daemon/TapeWriteSingleThread.hpp" +#include "castor/tape/tapeserver/client/ClientProxy.hpp" +#include "castor/tape/tapeserver/daemon/DataTransferSession.hpp" #include "castor/tape/tapeserver/daemon/DiskReadThreadPool.hpp" -#include "castor/tape/tapeserver/daemon/MigrationTaskInjector.hpp" #include "castor/tape/tapeserver/daemon/DiskWriteThreadPool.hpp" -#include "castor/tape/tapeserver/daemon/TapeServerReporter.hpp" +#include "castor/tape/tapeserver/daemon/MigrationTaskInjector.hpp" +#include "castor/tape/tapeserver/daemon/RecallReportPacker.hpp" +#include "castor/tape/tapeserver/daemon/RecallTaskInjector.hpp" +#include "castor/tape/tapeserver/daemon/TapeWriteSingleThread.hpp" #include "castor/tape/tapeserver/daemon/TapeReadSingleThread.hpp" -#include "castor/tape/tapeserver/daemon/DataTransferSession.hpp" +#include "castor/tape/tapeserver/daemon/TapeServerReporter.hpp" +#include "castor/tape/tapeserver/drive/Drive.hpp" +#include "castor/tape/tapeserver/exception/Exception.hpp" +#include "castor/tape/tapeserver/SCSI/Device.hpp" +#include "castor/tape/utils/utils.hpp" +#include "h/log.h" #include "h/serrno.h" +#include "h/stager_client_commandline.h" + #include <google/protobuf/stubs/common.h> #include <memory> -#include <zmq.h> - -//------------------------------------------------------------------------------ -// m_zmqContext -//------------------------------------------------------------------------------ -void *castor::tape::tapeserver::daemon::DataTransferSession::m_zmqContext = - NULL; //------------------------------------------------------------------------------ //Constructor @@ -57,14 +50,15 @@ void *castor::tape::tapeserver::daemon::DataTransferSession::m_zmqContext = castor::tape::tapeserver::daemon::DataTransferSession::DataTransferSession( const std::string & hostname, const legacymsg::RtcpJobRqstMsgBody & clientRequest, - castor::log::Logger& logger, System::virtualWrapper & sysWrapper, + castor::log::Logger & log, + System::virtualWrapper & sysWrapper, const utils::DriveConfig & driveConfig, castor::legacymsg::RmcProxy & rmc, castor::messages::TapeserverProxy & initialProcess, - castor::server::ProcessCap &capUtils, + castor::server::ProcessCap & capUtils, const CastorConf & castorConf): m_request(clientRequest), - m_logger(logger), + m_log(log), m_clientProxy(clientRequest), m_sysWrapper(sysWrapper), m_driveConfig(driveConfig), @@ -88,7 +82,7 @@ castor::tape::tapeserver::daemon::DataTransferSession::DataTransferSession( int castor::tape::tapeserver::daemon::DataTransferSession::execute() { // 1) Prepare the logging environment - log::LogContext lc(m_logger); + log::LogContext lc(m_log); // Create a sticky thread name, which will be overridden by the other threads lc.pushOrReplace(log::Param("thread", "mainThread")); log::LogContext::ScopedParam sp01(lc, log::Param("clientHost", m_request.clientHost)); @@ -187,11 +181,12 @@ int castor::tape::tapeserver::daemon::DataTransferSession::executeRead(log::LogC RecallReportPacker rrp(m_clientProxy, m_castorConf.tapebridgeBulkRequestMigrationMaxFiles, lc); + // If we talk to a command line client, we do not batch report if (tapegateway::READ_TP == m_volInfo.clientType) { rrp.disableBulk(); } - TaskWatchDog<detail::Recall> watchdog(m_intialProcess,rrp,m_logger); + TaskWatchDog<detail::Recall> watchdog(m_intialProcess, rrp , m_log); RecallMemoryManager mm(m_castorConf.rtcopydNbBufs, m_castorConf.rtcopydBufsz,lc); TapeServerReporter tsr(m_intialProcess, m_driveConfig, @@ -485,33 +480,15 @@ castor::tape::tapeserver::daemon::DataTransferSession::findDrive(const utils::Dr } } -//------------------------------------------------------------------------------ -// getZmqContext -//------------------------------------------------------------------------------ -void *castor::tape::tapeserver::daemon::DataTransferSession::getZmqContext() { - // Create the ZMQ context if it does not already exist - if(NULL == m_zmqContext) { - const int sizeOfIOThreadPoolForZMQ = 1; - m_zmqContext = zmq_init(sizeOfIOThreadPoolForZMQ); - if(NULL == m_zmqContext) { - char message[100]; - sstrerror_r(errno, message, sizeof(message)); - castor::exception::Exception ex; - ex.getMessage() << "Failed to instantiate ZMQ context: " << message; - throw ex; - } - } - - return m_zmqContext; -} - //------------------------------------------------------------------------------ // destructor //------------------------------------------------------------------------------ -castor::tape::tapeserver::daemon::DataTransferSession::~DataTransferSession(){ - if(NULL != m_zmqContext) { - zmq_term(m_zmqContext); - m_zmqContext = NULL; +castor::tape::tapeserver::daemon::DataTransferSession::~DataTransferSession() + throw () { + try { + google::protobuf::ShutdownProtobufLibrary(); + } catch(...) { + m_log(LOG_ERR, "google::protobuf::ShutdownProtobufLibrary() threw an" + " unexpected exception"); } - google::protobuf::ShutdownProtobufLibrary(); } diff --git a/castor/tape/tapeserver/daemon/DataTransferSession.hpp b/castor/tape/tapeserver/daemon/DataTransferSession.hpp index f31bae59fd..fa950dfe2a 100644 --- a/castor/tape/tapeserver/daemon/DataTransferSession.hpp +++ b/castor/tape/tapeserver/daemon/DataTransferSession.hpp @@ -92,11 +92,15 @@ namespace daemon { // Additions for tapeserverd uint32_t tapeserverdDiskThreads; }; - /** Constructor */ + /** + * Constructor. + * + * @param log Object representing the API of the CASTOR logging system. + */ DataTransferSession( const std::string & hostname, const legacymsg::RtcpJobRqstMsgBody & clientRequest, - castor::log::Logger & logger, + castor::log::Logger & log, System::virtualWrapper & sysWrapper, const utils::DriveConfig & driveConfig, castor::legacymsg::RmcProxy & rmc, @@ -109,24 +113,19 @@ namespace daemon { std::string getVid() { return m_volInfo.vid; } /** - * Return the global shared zmq context for the data-transfer session - * THIS FUNCTION SHALL ONLY BE CALLED IN THE FORKED PROCESS - * - * @return The global shared zmq context for the data-transfer session. + * Destructor. */ - static void *getZmqContext(); - - ~DataTransferSession(); + ~DataTransferSession() throw(); private: + legacymsg::RtcpJobRqstMsgBody m_request; + /** - * The global shared zmq context for the date-transfer session. + * Object representing the API of the CASTOR logging system. */ - static void *m_zmqContext; + castor::log::Logger & m_log; - legacymsg::RtcpJobRqstMsgBody m_request; - castor::log::Logger & m_logger; client::ClientProxy m_clientProxy; client::ClientProxy::VolumeInfo m_volInfo; System::virtualWrapper & m_sysWrapper; diff --git a/castor/tape/tapeserver/daemon/ProcessForker.cpp b/castor/tape/tapeserver/daemon/ProcessForker.cpp index 54d10462e5..887cd1b95f 100644 --- a/castor/tape/tapeserver/daemon/ProcessForker.cpp +++ b/castor/tape/tapeserver/daemon/ProcessForker.cpp @@ -22,16 +22,23 @@ *****************************************************************************/ #include "castor/exception/Exception.hpp" +#include "castor/legacymsg/RmcProxyTcpIp.hpp" #include "castor/messages/ForkCleaner.pb.h" #include "castor/messages/ForkDataTransfer.pb.h" #include "castor/messages/ForkLabel.pb.h" #include "castor/messages/ForkSucceeded.pb.h" -#include "castor/messages/Status.pb.h" +#include "castor/messages/ProcessCrashed.pb.h" +#include "castor/messages/ProcessExited.pb.h" #include "castor/messages/StopProcessForker.pb.h" +#include "castor/messages/TapeserverProxyZmq.hpp" +#include "castor/tape/tapeserver/daemon/Constants.hpp" #include "castor/tape/tapeserver/daemon/ProcessForker.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp" +#include "castor/tape/utils/DriveConfig.hpp" +#include "castor/tape/utils/SmartZmqContext.hpp" #include "castor/utils/SmartArrayPtr.hpp" +#include "castor/utils/utils.hpp" #include "h/serrno.h" #include <errno.h> @@ -44,21 +51,41 @@ //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ -castor::tape::tapeserver::daemon::ProcessForker::ProcessForker(log::Logger &log, - const int socketFd) throw(): m_log(log), m_socketFd(socketFd) { +castor::tape::tapeserver::daemon::ProcessForker::ProcessForker( + log::Logger &log, + const int cmdSocket, + const int reaperSocket, + const std::string &hostName) throw(): + m_log(log), + m_cmdSocket(cmdSocket), + m_reaperSocket(reaperSocket), + m_hostName(hostName) { } //------------------------------------------------------------------------------ // destructor //------------------------------------------------------------------------------ castor::tape::tapeserver::daemon::ProcessForker::~ProcessForker() throw() { - if(-1 == close(m_socketFd)) { - char message[100]; - sstrerror_r(errno, message, sizeof(message)); - log::Param params[] = {log::Param("socketFd", m_socketFd), - log::Param("message", message)}; - m_log(LOG_ERR, "Failed to close file-descriptor of ProcessForkerSocket", - params); + closeCmdReceiverSocket(); +} + +//------------------------------------------------------------------------------ +// closeCmdReceiverSocket +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker::closeCmdReceiverSocket() + throw() { + if(-1 != m_cmdSocket) { + std::list<log::Param> params; + params.push_back(log::Param("cmdSocket", m_cmdSocket)); + if(-1 == close(m_cmdSocket)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + params.push_back(log::Param("message", message)); + m_log(LOG_ERR, "Failed to close command receiver socket", + params); + } else { + m_log(LOG_INFO, "Closed command receiver socket", params); + } } } @@ -68,6 +95,7 @@ castor::tape::tapeserver::daemon::ProcessForker::~ProcessForker() throw() { void castor::tape::tapeserver::daemon::ProcessForker::execute() { try { while(handleEvents()) { + reapZombies(); } } catch(castor::exception::Exception &ne) { castor::exception::Exception ex; @@ -94,7 +122,7 @@ bool castor::tape::tapeserver::daemon::ProcessForker::thereIsAPendingMsg() { // Call poll() in orer to see if there is any data to be read struct pollfd fds; - fds.fd = m_socketFd; + fds.fd = m_cmdSocket; fds.events = POLLIN; fds.revents = 0; const int timeout = 100; // Timeout in milliseconds @@ -136,7 +164,7 @@ bool castor::tape::tapeserver::daemon::ProcessForker::thereIsAPendingMsg() { bool castor::tape::tapeserver::daemon::ProcessForker::handleMsg() { ProcessForkerFrame frame; try { - frame = ProcessForkerUtils::readFrame(m_socketFd); + frame = ProcessForkerUtils::readFrame(m_cmdSocket); } catch(castor::exception::Exception &ne) { log::Param params[] = {log::Param("message", ne.getMessage().str())}; m_log(LOG_ERR, "Failed to handle message", params); @@ -161,31 +189,31 @@ bool castor::tape::tapeserver::daemon::ProcessForker::handleMsg() { log::Param("message", ex.getMessage().str()); m_log(LOG_ERR, "ProcessForker::dispatchMsgHandler() threw an exception", params); - messages::Status msg; - msg.set_status(ex.code()); + messages::Exception msg; + msg.set_code(ex.code()); msg.set_message(ex.getMessage().str()); - ProcessForkerUtils::writeFrame(m_socketFd, msg); + ProcessForkerUtils::writeFrame(m_cmdSocket, msg); return true; // The main event loop should continue } catch(std::exception &se) { log::Param("message", se.what()); m_log(LOG_ERR, "ProcessForker::dispatchMsgHandler() threw an exception", params); - messages::Status msg; - msg.set_status(SEINTERNAL); + messages::Exception msg; + msg.set_code(SEINTERNAL); msg.set_message(se.what()); - ProcessForkerUtils::writeFrame(m_socketFd, msg); + ProcessForkerUtils::writeFrame(m_cmdSocket, msg); return true; // The main event loop should continue } catch(...) { m_log(LOG_ERR, "ProcessForker::dispatchMsgHandler() threw an unknown exception"); - messages::Status msg; - msg.set_status(SEINTERNAL); + messages::Exception msg; + msg.set_code(SEINTERNAL); msg.set_message("Caught and unknown and unexpected exception"); - ProcessForkerUtils::writeFrame(m_socketFd, msg); + ProcessForkerUtils::writeFrame(m_cmdSocket, msg); return true; // The main event loop should continue } - ProcessForkerUtils::writeFrame(m_socketFd, result.reply); + ProcessForkerUtils::writeFrame(m_cmdSocket, result.reply); { log::Param params[] = { log::Param("payloadType", @@ -252,8 +280,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult params); // Create and return the result of handling the incomming request - messages::Status reply; - reply.set_status(SEINTERNAL); + messages::Exception reply; + reply.set_code(SEINTERNAL); reply.set_message("Failed to fork cleaner session for tape drive"); MsgHandlerResult result; result.continueMainEventLoop = true; @@ -278,13 +306,14 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult // Else this is the child process } else { + closeCmdReceiverSocket(); // TO BE DONE exit(0); } } //------------------------------------------------------------------------------ -// handleDataTransferMsg +// handleForkDataTransferMsg //------------------------------------------------------------------------------ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult castor::tape::tapeserver::daemon::ProcessForker::handleForkDataTransferMsg( @@ -313,8 +342,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult params); // Create and return the result of handling the incomming request - messages::Status reply; - reply.set_status(SEINTERNAL); + messages::Exception reply; + reply.set_code(SEINTERNAL); reply.set_message("Failed to fork data-transfer session for tape drive"); MsgHandlerResult result; result.continueMainEventLoop = true; @@ -326,9 +355,6 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult log::Param params[] = {log::Param("pid", forkRc)}; m_log(LOG_INFO, "ProcessForker forked data-transfer session", params); - // TO BE DONE - waitpid(forkRc, NULL, 0); - // Create and return the result of handling the incomming request messages::ForkSucceeded reply; reply.set_pid(forkRc); @@ -339,8 +365,22 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult // Else this is the child process } else { - // TO BE DONE - exit(0); + closeCmdReceiverSocket(); + + try { + exit(runDataTransferSession(rqst)); + } catch(castor::exception::Exception &ne) { + log::Param params[] = {log::Param("message", ne.getMessage().str())}; + m_log(LOG_ERR, "Failed to run data-transfer session", params); + } catch(std::exception &ne) { + log::Param params[] = {log::Param("message", ne.what())}; + m_log(LOG_ERR, "Failed to run data-transfer session", params); + } catch(...) { + log::Param params[] = {log::Param("message", + "Caught an unknown exception")}; + m_log(LOG_ERR, "Failed to run data-transfer session", params); + } + exit(1); } } @@ -373,8 +413,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult params); // Create and return the result of handling the incomming request - messages::Status reply; - reply.set_status(SEINTERNAL); + messages::Exception reply; + reply.set_code(SEINTERNAL); reply.set_message("Failed to fork label session for tape drive"); MsgHandlerResult result; result.continueMainEventLoop = true; @@ -399,6 +439,8 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult // Else this is the child process } else { + closeCmdReceiverSocket(); + // TO BE DONE exit(0); } @@ -420,11 +462,325 @@ castor::tape::tapeserver::daemon::ProcessForker::MsgHandlerResult m_log(LOG_INFO, "Gracefully stopping ProcessForker", params); // Create and return the result of handling the incomming request - messages::Status reply; - reply.set_status(0); + messages::Exception reply; + reply.set_code(0); reply.set_message(""); MsgHandlerResult result; result.continueMainEventLoop = false; ProcessForkerUtils::serializePayload(result.reply, reply); return result; } + +//------------------------------------------------------------------------------ +// runDataTransferSession +//------------------------------------------------------------------------------ +int castor::tape::tapeserver::daemon::ProcessForker::runDataTransferSession( + const messages::ForkDataTransfer &rqst) { + const utils::DriveConfig driveConfig = getDriveConfig(rqst); + + std::list<log::Param> params; + params.push_back(log::Param("unitName", driveConfig.unitName)); + m_log(LOG_INFO, "Data-transfer child-process started", params); + + const legacymsg::RtcpJobRqstMsgBody vdqmJob = getVdqmJob(rqst); + + castor::server::ProcessCap capUtils; + const DataTransferSession::CastorConf dataTransferConfig = + getDataTransferConfig(rqst); + + const int netTimeout = 10; // Timeout in seconds + legacymsg::RmcProxyTcpIp rmc(m_log, netTimeout); + + const int sizeOfIOThreadPoolForZMQ = 1; + utils::SmartZmqContext + zmqContext(instantiateZmqContext(sizeOfIOThreadPoolForZMQ)); + + messages::TapeserverProxyZmq tapeserver(m_log, + TAPE_SERVER_INTERNAL_LISTENING_PORT, netTimeout, zmqContext.get()); + + castor::tape::System::realWrapper sysWrapper; + + // This try bloc will allow us to send a failure notification to the client + // if we fail before the DataTransferSession has an opportunity to do so. + std::auto_ptr<DataTransferSession> dataTransferSession; + try { + dataTransferSession.reset(new DataTransferSession ( + m_hostName, + vdqmJob, + m_log, + sysWrapper, + driveConfig, + rmc, + tapeserver, + capUtils, + dataTransferConfig)); + } catch (castor::exception::Exception & ex) { + try { + client::ClientProxy cl(vdqmJob); + client::ClientInterface::RequestReport rep; + cl.reportEndOfSessionWithError(ex.getMessageValue(), ex.code(), rep); + } catch (...) { + params.push_back(log::Param("errorMessage", ex.getMessageValue())); + params.push_back(log::Param("errorCode", ex.code())); + m_log(LOG_ERR, "Failed to notify the client of the failed session" + " when setting up the data-transfer session", params); + } + throw; + } catch (...) { + try { + m_log(LOG_ERR, "Got non castor exception error while constructing" + " data-transfer session", params); + client::ClientProxy cl(vdqmJob); + client::ClientInterface::RequestReport rep; + cl.reportEndOfSessionWithError( + "Non-Castor exception when setting up the data-transfer session", + SEINTERNAL, rep); + } catch (...) { + params.push_back(log::Param("errorMessage", + "Non-Castor exception when setting up the data-transfer session")); + m_log(LOG_ERR, "Failed to notify the client of the failed session" + " when setting up the data-transfer session", params); + } + throw; + } + m_log(LOG_INFO, "Going to execute data-transfer session"); + return dataTransferSession->execute(); +} + +//------------------------------------------------------------------------------ +// getDriveConfig +//------------------------------------------------------------------------------ +castor::tape::utils::DriveConfig + castor::tape::tapeserver::daemon::ProcessForker::getDriveConfig( + const messages::ForkDataTransfer &msg) { + utils::DriveConfig config; + config.unitName = msg.unitname(); + config.dgn = msg.dgn(); + config.devFilename = msg.devfilename(); + for(int i=0; i < msg.density_size(); i++) { + config.densities.push_back(msg.density(i)); + } + config.librarySlot = msg.libraryslot(); + config.devType = msg.devtype(); + + return config; +} + +//------------------------------------------------------------------------------ +// getDataTransferConfig +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::DataTransferSession::CastorConf + castor::tape::tapeserver::daemon::ProcessForker::getDataTransferConfig( + const messages::ForkDataTransfer &msg) { + DataTransferSession::CastorConf config; + config.rtcopydBufsz = msg.memblocksize(); + config.rtcopydNbBufs = msg.nbmemblocks(); + config.tapeBadMIRHandlingRepair = msg.badmirhandling(); + config.tapebridgeBulkRequestMigrationMaxBytes = + msg.bulkrequestmigrationmaxbytes(); + config.tapebridgeBulkRequestMigrationMaxFiles = + msg.bulkrequestmigrationmaxfiles(); + config.tapebridgeBulkRequestRecallMaxBytes = msg.bulkrequestrecallmaxbytes(); + config.tapebridgeBulkRequestRecallMaxFiles = msg.bulkrequestrecallmaxfiles(); + config.tapebridgeMaxBytesBeforeFlush = msg.maxbytesbeforeflush(); + config.tapebridgeMaxFilesBeforeFlush = msg.maxfilesbeforeflush(); + config.tapeserverdDiskThreads = msg.diskthreadpoolsize(); + + return config; +} + +//------------------------------------------------------------------------------ +// getVdqmJob +//------------------------------------------------------------------------------ +castor::legacymsg::RtcpJobRqstMsgBody + castor::tape::tapeserver::daemon::ProcessForker::getVdqmJob( + const messages::ForkDataTransfer &msg) { + castor::legacymsg::RtcpJobRqstMsgBody job; + job.volReqId = msg.mounttransactionid(); + job.clientPort = msg.clientport(); + job.clientEuid = msg.clienteuid(); + job.clientEgid = msg.clientegid(); + castor::utils::copyString(job.clientHost, msg.clienthost()); + castor::utils::copyString(job.dgn, msg.dgn()); + castor::utils::copyString(job.driveUnit, msg.unitname()); + castor::utils::copyString(job.clientUserName, msg.clientusername()); + + return job; +} + +//------------------------------------------------------------------------------ +// instantiateZmqContext +//------------------------------------------------------------------------------ +void *castor::tape::tapeserver::daemon::ProcessForker::instantiateZmqContext( + const int sizeOfIOThreadPoolForZMQ) { + void *const zmqContext = zmq_init(sizeOfIOThreadPoolForZMQ); + if(NULL == zmqContext) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to instantiate ZMQ context: " << message; + throw ex; + } + std::ostringstream contextAddr; + contextAddr << std::hex << zmqContext; + log::Param params[] = {log::Param("contextAddr", contextAddr.str())}; + m_log(LOG_INFO, "ProcessForker instantiated a ZMQ context", params); + + return zmqContext; +} + +//------------------------------------------------------------------------------ +// reapZombies +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker::reapZombies() throw() { + pid_t pid = 0; + int waitpidStat = 0; + while (0 < (pid = waitpid(-1, &waitpidStat, WNOHANG))) { + handleReapedZombie(pid, waitpidStat); + } +} + +//------------------------------------------------------------------------------ +// handleReapedZombie +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker::handleReapedZombie( + const pid_t pid, const int waitpidStat) throw() { + try { + logChildProcessTerminated(pid, waitpidStat); + notifyTapeDaemonOfTerminatedProcess(pid, waitpidStat); + } catch(castor::exception::Exception &ex) { + log::Param params[] = {log::Param("message", ex.getMessage().str())}; + m_log(LOG_ERR, "Failed to handle reaped zombie", params); + } catch(std::exception &se) { + log::Param params[] = {log::Param("message", se.what())}; + m_log(LOG_ERR, "Failed to handle reaped zombie", params); + } catch(...) { + log::Param params[] = { + log::Param("message", "Caught an unknown exception")}; + m_log(LOG_ERR, "Failed to handle reaped zombie", params); + } +} + +//------------------------------------------------------------------------------ +// logChildProcessTerminated +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker::logChildProcessTerminated( + const pid_t pid, const int waitpidStat) throw() { + std::list<log::Param> params; + params.push_back(log::Param("terminatedPid", pid)); + + if(WIFEXITED(waitpidStat)) { + params.push_back(log::Param("WEXITSTATUS", WEXITSTATUS(waitpidStat))); + } + + if(WIFSIGNALED(waitpidStat)) { + params.push_back(log::Param("WTERMSIG", WTERMSIG(waitpidStat))); + } + + if(WCOREDUMP(waitpidStat)) { + params.push_back(log::Param("WCOREDUMP", "true")); + } else { + params.push_back(log::Param("WCOREDUMP", "false")); + } + + if(WIFSTOPPED(waitpidStat)) { + params.push_back(log::Param("WSTOPSIG", WSTOPSIG(waitpidStat))); + } + + if(WIFCONTINUED(waitpidStat)) { + params.push_back(log::Param("WIFCONTINUED", "true")); + } else { + params.push_back(log::Param("WIFCONTINUED", "false")); + } + + m_log(LOG_INFO, "ProcessForker child process terminated", params); +} + +//------------------------------------------------------------------------------ +// notifyTapeDaemonOfTerminatedProcess +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker:: + notifyTapeDaemonOfTerminatedProcess(const pid_t pid, const int waitpidStat) { + try { + if(WIFEXITED(waitpidStat)) { + notifyTapeDaemonOfExitedProcess(pid, waitpidStat); + } else if(WIFSIGNALED(waitpidStat)) { + notifyTapeDaemonOfCrashedProcess(pid, waitpidStat); + } else { + castor::exception::Exception ex; + ex.getMessage() << "Process died of unknown causes" << pid; + throw ex; + } + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process termination" + ": pid=" << pid << ": " << ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// notifyTapeDaemonOfExitedProcess +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker:: + notifyTapeDaemonOfExitedProcess(const pid_t pid, const int waitpidStat) { + try { + messages::ProcessExited msg; + msg.set_pid(pid); + msg.set_exitcode(WEXITSTATUS(waitpidStat)); + + log::Param params[] = {log::Param("pid", msg.pid()), + log::Param("exitCode", msg.exitcode())}; + m_log(LOG_INFO, "Notifying TapeDaemon of process exit", params); + + ProcessForkerUtils::writeFrame(m_reaperSocket, msg); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process exit: " << + ne.getMessage().str(); + throw ex; + } catch(std::exception &se) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process exit: " << + se.what(); + throw ex; + } catch(...) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process exit: " + "Caught an unknown exception"; + throw ex; + } +} + +//------------------------------------------------------------------------------ +// notifyTapeDaemonOfCrashedProcess +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForker:: + notifyTapeDaemonOfCrashedProcess(const pid_t pid, const int waitpidStat) { + try { + messages::ProcessCrashed msg; + msg.set_pid(pid); + msg.set_signal(WTERMSIG(waitpidStat)); + + log::Param params[] = {log::Param("pid", msg.pid()), + log::Param("signal", msg.signal())}; + m_log(LOG_INFO, "Notifying TapeDaemon of process crash", params); + + ProcessForkerUtils::writeFrame(m_reaperSocket, msg); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process crash: " << + ne.getMessage().str(); + throw ex; + } catch(std::exception &se) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process crash: " << + se.what(); + throw ex; + } catch(...) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to notify TapeDaemon of process crash: " + "Caught an unknown exception"; + throw ex; + } +} diff --git a/castor/tape/tapeserver/daemon/ProcessForker.hpp b/castor/tape/tapeserver/daemon/ProcessForker.hpp index 0c77e277d2..2e902f6121 100644 --- a/castor/tape/tapeserver/daemon/ProcessForker.hpp +++ b/castor/tape/tapeserver/daemon/ProcessForker.hpp @@ -24,6 +24,8 @@ #pragma once #include "castor/log/Logger.hpp" +#include "castor/messages/ForkDataTransfer.pb.h" +#include "castor/tape/tapeserver/daemon/DataTransferSession.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerFrame.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp" @@ -47,10 +49,16 @@ public: * client. The destructor of this class will close the file-descriptor. * * @param log Object representing the API of the CASTOR logging system. - * @param socketFd The file-descriptor of the socket used to communicate with - * the client. + * @param cmdSocket The file-descriptor of the socket used to receive commands + * from the ProcessForker proxy. + * @param reaperSocket The file-descriptor of the socket used to notify the + * TapeDaemon parent process of the termination of a process forked by the + * ProcessForker. + * @param hostName The name of the host on which the tapeserverd daemon is + * running. */ - ProcessForker(log::Logger &log, const int socketFd) throw(); + ProcessForker(log::Logger &log, const int cmdSocket, const int reaperSocket, + const std::string &hostName) throw(); /** * Destructor. @@ -79,9 +87,27 @@ private: log::Logger &m_log; /** - * The file-descriptor of the socket used to communicate with the client. + * The file-descriptor of the socket used to receive commands from the + * ProcessForker proxy. */ - const int m_socketFd; + const int m_cmdSocket; + + /** + * The file-descriptor of the socket used to notify the TapeDaemon parent + * process of the termination of a process forked by the ProcessForker. + */ + const int m_reaperSocket; + + /** + * The name of the host on which the tapeserverd daemon is running. + */ + const std::string m_hostName; + + /** + * Idempotent method that closes the socket used for receving commands + * from the ProcessForker proxy. + */ + void closeCmdReceiverSocket() throw(); /** * Structure defining the result of a message handler. @@ -163,6 +189,104 @@ private: */ MsgHandlerResult handleForkCleanerMsg(const ProcessForkerFrame &frame); + /** + * Runs the data-transfer session. This method is to be called within the + * child process responsible for running the data-transfer session. + * + * @param rqst The ForkDataTransfer message. + * @return The value to be used when exiting the child process. + */ + int runDataTransferSession(const messages::ForkDataTransfer &rqst); + + /** + * Gets the drve configuration information from the specified ForkDataTransfer + * message. + * + * @param msg The ForkDataTransfer message. + * @return The drive configuration. + */ + utils::DriveConfig getDriveConfig(const messages::ForkDataTransfer &msg); + + /** + * Gets the configuration of the data-transfer session from the specified + * ForkDataTransfer message. + * + * @param msg The ForkDataTransfer message. + * @return The configuration of the data-transfer session. + */ + castor::tape::tapeserver::daemon::DataTransferSession::CastorConf + getDataTransferConfig(const messages::ForkDataTransfer &msg); + + /** + * Gets the VDQM job from the specified ForkDataTransfer message. + * + * @param msg The ForkDataTransfer message. + * @return The VDQM job. + */ + castor::legacymsg::RtcpJobRqstMsgBody getVdqmJob( + const messages::ForkDataTransfer &msg); + + /** + * Instantiates a ZMQ context. + * + * @param sizeOfIOThreadPoolForZMQ The size of the IO thread pool to be used + * by ZMQ. + * @return The ZMQ context. + */ + void *instantiateZmqContext(const int sizeOfIOThreadPoolForZMQ); + + /** + * Reaps any zombie processes. + */ + void reapZombies() throw(); + + /** + * Handles the specified reaped zombie. + * + * @param pid The process ID of the reaped zombie. + * @param waitpidStat The status information given by a call to waitpid(). + */ + void handleReapedZombie(const pid_t pid, const int waitpidStat) throw(); + + /** + * Logs the fact that the specified child process has terminated. + * + * @param pid The process ID of the child process. + * @param waitpidStat The status information given by a call to waitpid(). + */ + void logChildProcessTerminated(const pid_t pid, const int waitpidStat) + throw(); + + /** + * Notifies the TapeDaemon parent process that a child process of the + * ProcessForker has terminated. + * + * @param pid The process ID of the child process. + * @param waitpidStat The status information given by a call to waitpid(). + */ + void notifyTapeDaemonOfTerminatedProcess(const pid_t pid, + const int waitpidStat); + + /** + * Notifies the TapeDaemon parent process that a child process of the + * ProcessForker exited. + * + * @param pid The process ID of the child process. + * @param waitpidStat The status information given by a call to waitpid(). + */ + void notifyTapeDaemonOfExitedProcess(const pid_t pid, + const int waitpidStat); + + /** + * Notifies the TapeDaemon parent process that a child process of the + * ProcessForker crashed. + * + * @param pid The process ID of the child process. + * @param waitpidStat The status information given by a call to waitpid(). + */ + void notifyTapeDaemonOfCrashedProcess(const pid_t pid, + const int waitpidStat); + }; // class ProcessForker } // namespace daemon diff --git a/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.cpp b/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.cpp new file mode 100644 index 0000000000..ace3c928d3 --- /dev/null +++ b/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.cpp @@ -0,0 +1,488 @@ +/****************************************************************************** + * + * 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/ProcessForkerConnectionHandler.hpp" +#include "castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp" +#include "castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp" +#include "h/common.h" +#include "h/serrno.h" + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + ProcessForkerConnectionHandler( + const int fd, + reactor::ZMQReactor &reactor, + log::Logger &log, + DriveCatalogue &driveCatalogue, + const std::string &hostName, + legacymsg::VdqmProxy &vdqm) throw(): + m_fd(fd), + m_reactor(reactor), + m_log(log), + m_driveCatalogue(driveCatalogue), + m_hostName(hostName), + m_vdqm(vdqm), + m_netTimeout(1) // Timeout in seconds +{ +} + +//------------------------------------------------------------------------------ +// destructor +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + ~ProcessForkerConnectionHandler() throw() { + log::Param params[] = {log::Param("fd", m_fd)}; + m_log(LOG_DEBUG, "Closing incoming connection from the ProcessForker", + params); + close(m_fd); +} + +//------------------------------------------------------------------------------ +// getName +//------------------------------------------------------------------------------ +std::string castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + getName() const throw() { + return "ProcessForkerConnectionHandler"; +} + +//------------------------------------------------------------------------------ +// fillPollFd +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + fillPollFd(zmq_pollitem_t &fd) throw() { + fd.fd = m_fd; + fd.events = ZMQ_POLLIN; + fd.revents = 0; + fd.socket = NULL; +} + +//------------------------------------------------------------------------------ +// handleEvent +//------------------------------------------------------------------------------ +bool castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleEvent(const zmq_pollitem_t &fd) { + logConnectionEvent(fd); + + checkHandleEventFd(fd.fd); + + handleMsg(); + + return false; // Ask reactor to keep this handler registered +} + +//------------------------------------------------------------------------------ +// logConnectionEvent +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + logConnectionEvent(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 incoming ProcessForker connection", params); +} + +//------------------------------------------------------------------------------ +// checkHandleEventFd +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + checkHandleEventFd(const int fd) { + if(m_fd != fd) { + castor::exception::Exception ex; + ex.getMessage() << + "ProcessForkerConnectionHandler passed wrong file descriptor" + ": expected=" << m_fd << " actual=" << fd; + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleMsg() { + ProcessForkerFrame frame; + try { + frame = ProcessForkerUtils::readFrame(m_fd); + } catch(castor::exception::Exception &ne) { + log::Param params[] = {log::Param("message", ne.getMessage().str())}; + m_log(LOG_ERR, "Failed to handle message", params); + sleep(1); // Sleep a moment to avoid going into a tight error loop + } + + log::Param params[] = { + log::Param("type", ProcessForkerMsgType::toString(frame.type)), + log::Param("len", frame.payload.length())}; + m_log(LOG_INFO, "ProcessForkerConnectionHandler handling a message", params); + + dispatchMsgHandler(frame); +} + +//------------------------------------------------------------------------------ +// dispatchMsgHandler +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + dispatchMsgHandler(const ProcessForkerFrame &frame) { + switch(frame.type) { + case ProcessForkerMsgType::MSG_PROCESSCRASHED: + return handleProcessCrashedMsg(frame); + case ProcessForkerMsgType::MSG_PROCESSEXITED: + return handleProcessExitedMsg(frame); + default: + { + castor::exception::Exception ex; + ex.getMessage() << "Failed to dispatch message handler" + ": Unexpected message type" + ": type=" << ProcessForkerMsgType::toString(frame.type); + throw ex; + } + } +} + +//------------------------------------------------------------------------------ +// handleProcessCrashedMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleProcessCrashedMsg(const ProcessForkerFrame &frame) { + try { + // Parse the message + messages::ProcessCrashed msg; + ProcessForkerUtils::parsePayload(frame, msg); + + // Log the contents of the message + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("signal", msg.signal())); + m_log(LOG_INFO, + "ProcessForkerConnectionHandler handling ProcessCrashed message", params); + + DriveCatalogueEntry *const drive = m_driveCatalogue.findDrive(msg.pid()); + dispatchCrashedProcessHandler(*drive, msg); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle ProcessCrashed message: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// dispatchCrashedProcessHandler +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + dispatchCrashedProcessHandler(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg) { + + switch(drive.getSessionType()) { + case DriveCatalogueEntry::SESSION_TYPE_DATATRANSFER: + return handleCrashedDataTransferSession(drive, msg); + case DriveCatalogueEntry::SESSION_TYPE_LABEL: + return handleCrashedLabelSession(drive, msg); + case DriveCatalogueEntry::SESSION_TYPE_CLEANER: + return handleCrashedCleanerSession(drive, msg); + default: + { + castor::exception::Exception ex; + ex.getMessage() << "Failed to dispatch handler for crashed process" + ": Unexpected session type: sessionType=" << drive.getSessionType(); + throw ex; + } + } +} + +//------------------------------------------------------------------------------ +// handleCrashedDataTransferSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleCrashedDataTransferSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("signal", msg.signal())); + + try { + drive.sessionFailed(); + m_log(LOG_WARNING, "Data-transfer session failed", params); + drive.toBeCleaned(); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle crashed data-transfer session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleCrashedCleanerSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleCrashedCleanerSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("signal", msg.signal())); + + try { + drive.sessionFailed(); + m_log(LOG_WARNING, "Cleaner session failed", params); + setDriveDownInVdqm(msg.pid(), drive.getConfig()); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle crashed cleaner session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleCrashedLabelSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleCrashedLabelSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("signal", msg.signal())); + + try { + drive.sessionFailed(); + m_log(LOG_WARNING, "Label session failed", params); + setDriveDownInVdqm(msg.pid(), drive.getConfig()); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle crashed label session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleProcessExitedMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleProcessExitedMsg(const ProcessForkerFrame &frame) { + try { + // Parse the message + messages::ProcessExited msg; + ProcessForkerUtils::parsePayload(frame, msg); + + // Log the contents of the message + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("exitCode", msg.exitcode())); + m_log(LOG_INFO, + "ProcessForkerConnectionHandler handling ProcessExited message", params); + + DriveCatalogueEntry *const drive = m_driveCatalogue.findDrive(msg.pid()); + dispatchExitedProcessHandler(*drive, msg); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle ProcessCrashed message: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// dispatchExitedProcessHandler +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + dispatchExitedProcessHandler(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg) { + + switch(drive.getSessionType()) { + case DriveCatalogueEntry::SESSION_TYPE_DATATRANSFER: + return handleExitedDataTransferSession(drive, msg); + case DriveCatalogueEntry::SESSION_TYPE_LABEL: + return handleExitedLabelSession(drive, msg); + case DriveCatalogueEntry::SESSION_TYPE_CLEANER: + return handleExitedCleanerSession(drive, msg); + default: + { + castor::exception::Exception ex; + ex.getMessage() << "Failed to dispatch handler for exited process" + ": Unexpected session type: sessionType=" << drive.getSessionType(); + throw ex; + } + } +} + +//------------------------------------------------------------------------------ +// handleExitedDataTransferSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleExitedDataTransferSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("exitCode", msg.exitcode())); + + try { + if(0 == msg.exitcode()) { + const std::string vid = drive.getVid(); + drive.sessionSucceeded(); + m_log(LOG_INFO, "Data-transfer session succeeded", params); + requestVdqmToReleaseDrive(drive.getConfig(), msg.pid()); + notifyVdqmTapeUnmounted(drive.getConfig(), vid, msg.pid()); + } else { + drive.sessionFailed(); + m_log(LOG_WARNING, "Data-transfer session failed", params); + setDriveDownInVdqm(msg.pid(), drive.getConfig()); + } + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle exited data-transfer session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleExitedCleanerSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleExitedCleanerSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("exitCode", msg.exitcode())); + + try { + if(0 == msg.exitcode()) { + drive.sessionSucceeded(); + m_log(LOG_INFO, "Cleaner session succeeded", params); + const std::string &vid = drive.getVid(); + requestVdqmToReleaseDrive(drive.getConfig(), msg.pid()); + notifyVdqmTapeUnmounted(drive.getConfig(), vid, msg.pid()); + } else { + drive.sessionFailed(); + m_log(LOG_WARNING, "Cleaner session failed", params); + setDriveDownInVdqm(msg.pid(), drive.getConfig()); + } + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle exited cleaner session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleExitedLabelSession +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + handleExitedLabelSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg) { + std::list<log::Param> params; + params.push_back(log::Param("pid", msg.pid())); + params.push_back(log::Param("exitCode", msg.exitcode())); + + try { + if(0 == msg.exitcode()) { + drive.sessionSucceeded(); + m_log(LOG_INFO, "Label session succeeded", params); + } else { + drive.sessionFailed(); + m_log(LOG_WARNING, "Label session failed", params); + setDriveDownInVdqm(msg.pid(), drive.getConfig()); + } + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle exited label session: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// requestVdqmToReleaseDrive +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + requestVdqmToReleaseDrive(const utils::DriveConfig &driveConfig, + const pid_t pid) { + std::list<log::Param> params; + try { + const bool forceUnmount = true; + + params.push_back(log::Param("pid", pid)); + params.push_back(log::Param("unitName", driveConfig.unitName)); + params.push_back(log::Param("dgn", driveConfig.dgn)); + params.push_back(log::Param("forceUnmount", forceUnmount)); + + m_vdqm.releaseDrive(m_hostName, driveConfig.unitName, driveConfig.dgn, + forceUnmount, pid); + m_log(LOG_INFO, "Requested vdqm to release drive", params); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to request vdqm to release drive: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// notifyVdqmTapeUnmounted +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + notifyVdqmTapeUnmounted(const utils::DriveConfig &driveConfig, + const std::string &vid, const pid_t pid) { + try { + std::list<log::Param> params; + params.push_back(log::Param("pid", pid)); + params.push_back(log::Param("unitName", driveConfig.unitName)); + params.push_back(log::Param("vid", vid)); + params.push_back(log::Param("dgn", driveConfig.dgn)); + + m_vdqm.tapeUnmounted(m_hostName, driveConfig.unitName, driveConfig.dgn, + vid); + m_log(LOG_INFO, "Notified vdqm that a tape was unmounted", params); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed notify vdqm that a tape was unmounted: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// setDriveDownInVdqm +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerConnectionHandler:: + setDriveDownInVdqm(const pid_t pid, const utils::DriveConfig &driveConfig) { + std::list<log::Param> params; + params.push_back(log::Param("pid", pid)); + + try { + params.push_back(log::Param("unitName", driveConfig.unitName)); + params.push_back(log::Param("dgn", driveConfig.dgn)); + + m_vdqm.setDriveDown(m_hostName, driveConfig.unitName, driveConfig.dgn); + m_log(LOG_INFO, "Set tape-drive down in vdqm", params); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to set tape-drive down in vdqm: " << + ne.getMessage().str(); + throw ex; + } +} diff --git a/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.hpp b/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.hpp new file mode 100644 index 0000000000..e55709a130 --- /dev/null +++ b/castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.hpp @@ -0,0 +1,279 @@ +/****************************************************************************** + * + * 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/io/io.hpp" +#include "castor/log/Logger.hpp" +#include "castor/messages/ProcessCrashed.pb.h" +#include "castor/messages/ProcessExited.pb.h" +#include "castor/legacymsg/CommonMarshal.hpp" +#include "castor/legacymsg/MessageHeader.hpp" +#include "castor/legacymsg/VdqmProxy.hpp" +#include "castor/tape/reactor/PollEventHandler.hpp" +#include "castor/tape/reactor/ZMQReactor.hpp" +#include "castor/tape/tapeserver/daemon/DriveCatalogue.hpp" +#include "castor/tape/tapeserver/daemon/ProcessForkerFrame.hpp" + +namespace castor { +namespace tape { +namespace tapeserver { +namespace daemon { + +/** + * Handles the events of the incoming connection from the ProcessForker. + */ +class ProcessForkerConnectionHandler: + public reactor::ZMQPollEventHandler { +public: + + /** + * Constructor. + * + * @param fd The file descriptor of the incomming connection from the + * ProcessForker + * @param reactor The reactor with which this event handler is registered. + * @param log The object representing the API of the CASTOR logging system. + * @param driveCatalogue The catalogue of tape drives controlled by the tape + * server daemon. + * @param hostName The name of the host on which the tape-server daemon is + * running. + * @param vdqm Proxy object representing the vdqmd daemon. + */ + ProcessForkerConnectionHandler( + const int fd, + reactor::ZMQReactor &reactor, + log::Logger &log, + DriveCatalogue &driveCatalogue, + const std::string &hostName, + legacymsg::VdqmProxy &vdqm) throw(); + + /** + * Destructor. + * + * Closes the incoming connection with the ProcessForker. + */ + ~ProcessForkerConnectionHandler() 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 + * zmq_poll(). + */ + void fillPollFd(zmq_pollitem_t &fd) throw(); + + /** + * Handles the specified event. + * + * @param fd The poll file-descriptor describing the event. + */ + bool handleEvent(const zmq_pollitem_t &fd) ; + +private: + + /** + * The file descriptor of the incomming connection from the ProcessForker. + */ + const int m_fd; + + /** + * The reactor with which this event handler is registered. + */ + reactor::ZMQReactor &m_reactor; + + /** + * The object representing the API of the CASTOR logging system. + */ + log::Logger &m_log; + + /** + * The catalogue of tape drives controlled by the tape server daemon. + */ + DriveCatalogue &m_driveCatalogue; + + /** + * The name of th ehost on which the tape-server daemon is running. + */ + const std::string m_hostName; + + /** + * Proxy object representing the vdqmd daemon. + */ + castor::legacymsg::VdqmProxy &m_vdqm; + + /** + * The timeout in seconds to be applied when performing network read and + * write operations. + */ + const int m_netTimeout; + + /** + * Logs the specifed IO event of the incoming ProcessForker connection. + */ + void logConnectionEvent(const zmq_pollitem_t &fd); + + /** + * Throws an exception if the specified file-descriptor is not that of the + * connection with the client. + */ + void checkHandleEventFd(const int fd) ; + + /** + * Handles an incoming message from the ProcessForker. + */ + void handleMsg(); + + /** + * Dispatches the appropriate message handler for the message contained + * within the specified frame. + * + * @param frame The frame containing the message. + */ + void dispatchMsgHandler(const ProcessForkerFrame &frame); + + /** + * Handles the specified ProcessCrashedMsg. + * + * @param frame The frame containing the message. + */ + void handleProcessCrashedMsg(const ProcessForkerFrame &frame); + + /** + * Dispatches the appropriate handler for the specified crashed process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void dispatchCrashedProcessHandler(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg); + + /** + * Handles the specified crashed process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleCrashedDataTransferSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg); + + /** + * Handles the specified crashed process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleCrashedCleanerSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg); + + /** + * Handles the specified crashed process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleCrashedLabelSession(DriveCatalogueEntry &drive, + const messages::ProcessCrashed &msg); + + /** + * Handles the specified ProcessExitedMsg. + * + * @param frame The frame containing the message. + */ + void handleProcessExitedMsg(const ProcessForkerFrame &frame); + + /** + * Dispatches the appropriate handler for the specified exited process. + * + * @param drive The drive associated with the exited process. + * @param msg The ProcessExited message. + */ + void dispatchExitedProcessHandler(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg); + + /** + * Handles the specified exited process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleExitedDataTransferSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg); + + /** + * Handles the specified exited process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleExitedCleanerSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg); + + /** + * Handles the specified exited process. + * + * @param drive The drive associated with the crashed process. + * @param msg The ProcessCrashed message. + */ + void handleExitedLabelSession(DriveCatalogueEntry &drive, + const messages::ProcessExited &msg); + + /** + * Request the vdqmd daemon to release the tape drive associated with the + * session child-process with the specified process ID. + * + * @param driveConfig The configuration of the tape drive. + * @param pid The process ID of the session child-process. + */ + void requestVdqmToReleaseDrive(const utils::DriveConfig &driveConfig, + const pid_t pid); + + /** + * Sets the state of the tape drive asscoiated with the specified + * child process to down within the vdqmd daemon. + * + * @param pid The process ID of the child process. + * @param driveConfig The configuration of the tape drive. + */ + void setDriveDownInVdqm(const pid_t pid, + const utils::DriveConfig &driveConfig); + + /** + * Notifies the vdqm that the tape associated with the session child-process + * with the specified process ID has been unmounted. + * + * @param driveConfig The configuration of the tape drive. + * @param vid The identifier of the unmounted volume. + * @param pid The process ID of the session child-process. + */ + void notifyVdqmTapeUnmounted(const utils::DriveConfig &driveConfig, + const std::string &vid, const pid_t pid); + +}; // class ProcessForkerConnectionHandler + +} // namespace daemon +} // namespace tapeserver +} // namespace tape +} // namespace castor + diff --git a/castor/tape/tapeserver/daemon/ProcessForkerMsgType.cpp b/castor/tape/tapeserver/daemon/ProcessForkerMsgType.cpp index 6169849146..885b1a7763 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerMsgType.cpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerMsgType.cpp @@ -30,11 +30,13 @@ const char *castor::tape::tapeserver::daemon::ProcessForkerMsgType:: toString(const Enum value) throw() { switch(value) { case MSG_NONE : return "None"; - case MSG_FORKCLEANER : return "Cleaner"; + case MSG_EXCEPTION : return "Exception"; + case MSG_FORKCLEANER : return "ForkCleaner"; case MSG_FORKDATATRANSFER : return "ForkDataTransfer"; case MSG_FORKLABEL : return "ForkLabel"; case MSG_FORKSUCCEEDED : return "ForkSucceeded"; - case MSG_STATUS : return "Status"; + case MSG_PROCESSCRASHED : return "ProcessCrashed"; + case MSG_PROCESSEXITED : return "ProcessExited"; case MSG_STOPPROCESSFORKER: return "StopProcessForker"; default : return "Unknown"; } diff --git a/castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp b/castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp index d296ca271b..9610f29511 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp @@ -41,11 +41,13 @@ public: */ enum Enum { MSG_NONE, + MSG_EXCEPTION, MSG_FORKCLEANER, MSG_FORKDATATRANSFER, MSG_FORKLABEL, MSG_FORKSUCCEEDED, - MSG_STATUS, + MSG_PROCESSCRASHED, + MSG_PROCESSEXITED, MSG_STOPPROCESSFORKER }; diff --git a/castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp b/castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp index ac674af090..2b8df71561 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp @@ -23,7 +23,10 @@ #pragma once +#include "castor/legacymsg/RtcpJobRqstMsgBody.hpp" #include "castor/log/Logger.hpp" +#include "castor/tape/tapeserver/daemon/DataTransferSession.hpp" +#include "castor/tape/utils/DriveConfig.hpp" namespace castor { namespace tape { @@ -52,18 +55,24 @@ public: /** * Forks a data-transfer session for the specified tape drive. * - * @param unitName The unit name of the tape drive. + * @param driveConfig The configuration of the tape drive. + * @param vdqmJob The job received from the vdqmd daemon. + * @param conf The configuration of the data-transfer session. + * @return The process identifier of the newly forked session. */ - virtual void forkDataTransfer(const std::string &unitName) = 0; + virtual pid_t forkDataTransfer(const utils::DriveConfig &driveConfig, + const legacymsg::RtcpJobRqstMsgBody vdqmJob, + const DataTransferSession::CastorConf &conf) = 0; /** * Forks a label session for the specified tape drive. * * @param unitName The unit name of the tape drive. * @param vid The volume identifier of the tape. + * @return The process identifier of the newly forked session. */ - virtual void forkLabel(const std::string &unitName, const std::string &vid) = - 0; + virtual pid_t forkLabel(const std::string &unitName, + const std::string &vid) = 0; /** * Forks a cleaner session for the specified tape drive. @@ -73,8 +82,9 @@ public: * tape in the drive if there is in fact a tape in the drive and its volume * identifier is known. If the volume identifier is not known then this * parameter should be set to an empty string. + * @return The process identifier of the newly forked session. */ - virtual void forkCleaner(const std::string &unitName, + virtual pid_t forkCleaner(const std::string &unitName, const std::string &vid) = 0; }; // class ProcessForkerProxy diff --git a/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.cpp b/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.cpp index 5b46f0a34b..6c9a88d2c3 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.cpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.cpp @@ -22,7 +22,6 @@ *****************************************************************************/ #include "castor/messages/ForkCleaner.pb.h" -#include "castor/messages/ForkDataTransfer.pb.h" #include "castor/messages/ForkLabel.pb.h" #include "castor/messages/ForkSucceeded.pb.h" #include "castor/messages/StopProcessForker.pb.h" @@ -74,12 +73,15 @@ void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: //------------------------------------------------------------------------------ // forkDataTransfer //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: - forkDataTransfer(const std::string &unitName) { +pid_t castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: + forkDataTransfer(const utils::DriveConfig &driveConfig, + const legacymsg::RtcpJobRqstMsgBody vdqmJob, + const DataTransferSession::CastorConf &conf) { + + const messages::ForkDataTransfer rqst = createForkDataTransferMsg(driveConfig, + vdqmJob, conf); // Request the process forker to fork a data-transfer session - messages::ForkDataTransfer rqst; - rqst.set_unitname(unitName); ProcessForkerUtils::writeFrame(m_socketFd, rqst); // Read back the reply @@ -89,12 +91,66 @@ void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: m_log(LOG_INFO, "Got process ID of the data-transfer session from the ProcessForker", params); + + return reply.pid(); +} + +//------------------------------------------------------------------------------ +// createForkDataTransferMsg +//------------------------------------------------------------------------------ +castor::messages::ForkDataTransfer + castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: + createForkDataTransferMsg(const utils::DriveConfig &driveConfig, + const legacymsg::RtcpJobRqstMsgBody vdqmJob, + const DataTransferSession::CastorConf &config) { + messages::ForkDataTransfer msg; + + // Description of the tape drive + msg.set_unitname(driveConfig.unitName); + msg.set_dgn(driveConfig.dgn); + msg.set_devfilename(driveConfig.devFilename); + const std::list<std::string> &densities = driveConfig.densities; + for(std::list<std::string>::const_iterator itor = densities.begin(); + itor != densities.end(); itor++) { + msg.add_density(*itor); + } + msg.set_libraryslot(driveConfig.librarySlot); + msg.set_devtype(driveConfig.devType); + + // Description of the client request + msg.set_mounttransactionid(vdqmJob.volReqId); + msg.set_clientport(vdqmJob.clientPort); + msg.set_clienteuid(vdqmJob.clientEuid); + msg.set_clientegid(vdqmJob.clientEgid); + msg.set_clienthost(vdqmJob.clientHost); + msg.set_clientusername(vdqmJob.clientUserName); + + // Configuration parameters of the session + msg.set_memblocksize(config.rtcopydBufsz); + msg.set_nbmemblocks(config.rtcopydNbBufs); + msg.set_badmirhandling(config.tapeBadMIRHandlingRepair); + msg.set_bulkrequestmigrationmaxbytes( + config.tapebridgeBulkRequestMigrationMaxBytes); + msg.set_bulkrequestmigrationmaxfiles( + config.tapebridgeBulkRequestMigrationMaxFiles); + msg.set_bulkrequestrecallmaxbytes( + config.tapebridgeBulkRequestRecallMaxBytes); + msg.set_bulkrequestrecallmaxfiles( + config.tapebridgeBulkRequestRecallMaxFiles); + msg.set_maxbytesbeforeflush( + config.tapebridgeMaxBytesBeforeFlush); + msg.set_maxfilesbeforeflush( + config.tapebridgeMaxFilesBeforeFlush); + msg.set_diskthreadpoolsize( + config.tapeserverdDiskThreads); + + return msg; } //------------------------------------------------------------------------------ // forkLabel //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: +pid_t castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: forkLabel(const std::string &unitName, const std::string &vid) { // Request the process forker to fork a label session @@ -109,12 +165,14 @@ void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: log::Param params[] = {log::Param("pid", reply.pid())}; m_log(LOG_INFO, "Got process ID of the label session from the ProcessForker", params); + + return reply.pid(); } //------------------------------------------------------------------------------ // forkCleaner //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: +pid_t castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: forkCleaner(const std::string &unitName, const std::string &vid) { // Request the process forker to fork a label session @@ -129,4 +187,6 @@ void castor::tape::tapeserver::daemon::ProcessForkerProxySocket:: log::Param params[] = {log::Param("pid", reply.pid())}; m_log(LOG_INFO, "Got process ID of the cleaner session from the ProcessForker", params); + + return reply.pid(); } diff --git a/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp b/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp index cd71f13854..755b66e1ee 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp @@ -24,6 +24,7 @@ #pragma once #include "castor/log/Logger.hpp" +#include "castor/messages/ForkDataTransfer.pb.h" #include "castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerProxy.hpp" @@ -71,19 +72,25 @@ public: void stopProcessForker(const std::string &reason); /** - * Forks a data-transfer process for the specified tape drive. + * Forks a data-transfer session for the specified tape drive. * - * @param unitName The unit name of the tape drive. + * @param driveConfig The configuration of the tape drive. + * @param vdqmJob The job received from the vdqmd daemon. + * @param conf The configuration of the data-transfer session. + * @return The process identifier of the newly forked session. */ - void forkDataTransfer(const std::string &unitName); + pid_t forkDataTransfer(const utils::DriveConfig &driveConfig, + const legacymsg::RtcpJobRqstMsgBody vdqmJob, + const DataTransferSession::CastorConf &conf); /** * Forks a label-session process for the specified tape drive. * * @param unitName The unit name of the tape drive. * @param vid The volume identifier of the tape. + * @return The process identifier of the newly forked session. */ - void forkLabel(const std::string &unitName, const std::string &vid); + pid_t forkLabel(const std::string &unitName, const std::string &vid); /** * Forks a cleaner session for the specified tape drive. @@ -93,8 +100,9 @@ public: * tape in the drive if there is in fact a tape in the drive and its volume * identifier is known. If the volume identifier is not known then this * parameter should be set to an empty string. + * @return The process identifier of the newly forked session. */ - void forkCleaner(const std::string &unitName, const std::string &vid); + pid_t forkCleaner(const std::string &unitName, const std::string &vid); private: @@ -109,6 +117,19 @@ private: */ const int m_socketFd; + /** + * Creates a ForkDataTransfer message from the specified tape-drive + * configuration, VDQM job and data-transfer session configuration. + * + * @param driveConfig The configuration of the tape drive. + * @param vdqmJob The job received from the vdqmd daemon. + * @param config The configuration of the data-transfer session. + */ + messages::ForkDataTransfer createForkDataTransferMsg( + const utils::DriveConfig &driveConfig, + const legacymsg::RtcpJobRqstMsgBody vdqmJob, + const DataTransferSession::CastorConf &config); + }; // class ProcessForkerProxySocket } // namespace daemon diff --git a/castor/tape/tapeserver/daemon/ProcessForkerTest.cpp b/castor/tape/tapeserver/daemon/ProcessForkerTest.cpp index 43e9969563..377ced2250 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerTest.cpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerTest.cpp @@ -46,38 +46,52 @@ protected: TEST_F(castor_tape_tapeserver_daemon_ProcessForkerTest, constructor) { using namespace castor::tape::tapeserver::daemon; - int sv[2] = {-1, -1}; - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sv)); - castor::utils::SmartFd proxySocketfd(sv[0]); - castor::utils::SmartFd processForkerSocketfd(sv[1]); + int cmdPair[2] = {-1, -1}; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, cmdPair)); + castor::utils::SmartFd cmdSenderSocket(cmdPair[0]); + castor::utils::SmartFd cmdReceiverSocket(cmdPair[1]); + + int reaperPair[2] = {-1, -1}; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, reaperPair)); + castor::utils::SmartFd reaperSenderSocket(reaperPair[0]); + castor::utils::SmartFd reaperReceiverSocket(reaperPair[1]); const std::string programName = "unittests"; + const std::string hostName = "hostName"; castor::log::DummyLogger log(programName); std::auto_ptr<ProcessForker> processForker; ASSERT_NO_THROW(processForker.reset( - new ProcessForker(log, processForkerSocketfd.get()))); - processForkerSocketfd.release(); + new ProcessForker(log, cmdReceiverSocket.get(), reaperSenderSocket.get(), + hostName))); + cmdReceiverSocket.release(); } TEST_F(castor_tape_tapeserver_daemon_ProcessForkerTest, socketproxy) { using namespace castor::tape::tapeserver::daemon; - int sv[2] = {-1, -1}; - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sv)); - castor::utils::SmartFd proxySocketfd(sv[0]); - castor::utils::SmartFd processForkerSocketfd(sv[1]); + int cmdPair[2] = {-1, -1}; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, cmdPair)); + castor::utils::SmartFd cmdSenderSocket(cmdPair[0]); + castor::utils::SmartFd cmdReceiverSocket(cmdPair[1]); + + int reaperPair[2] = {-1, -1}; + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, reaperPair)); + castor::utils::SmartFd reaperSenderSocket(reaperPair[0]); + castor::utils::SmartFd reaperReceiverSocket(reaperPair[1]); const std::string programName = "unittests"; + const std::string hostName = "hostName"; castor::log::DummyLogger log(programName); std::auto_ptr<ProcessForker> processForker; ASSERT_NO_THROW(processForker.reset( - new ProcessForker(log, processForkerSocketfd.get()))); - processForkerSocketfd.release(); + new ProcessForker(log, cmdReceiverSocket.get(), reaperSenderSocket.get(), + hostName))); + cmdReceiverSocket.release(); std::auto_ptr<ProcessForkerProxySocket> processForkerProxy; ASSERT_NO_THROW(processForkerProxy.reset( - new ProcessForkerProxySocket(log, proxySocketfd.get()))); - proxySocketfd.release(); + new ProcessForkerProxySocket(log, cmdSenderSocket.get()))); + cmdSenderSocket.release(); } } // namespace unitTests diff --git a/castor/tape/tapeserver/daemon/ProcessForkerUtils.cpp b/castor/tape/tapeserver/daemon/ProcessForkerUtils.cpp index 2d03b15966..28a78e8fd5 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerUtils.cpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerUtils.cpp @@ -22,7 +22,6 @@ *****************************************************************************/ #include "castor/exception/Exception.hpp" -#include "castor/messages/Status.pb.h" #include "castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp" #include "castor/utils/SmartArrayPtr.hpp" #include "h/serrno.h" @@ -85,6 +84,34 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils::serializePayload( } } +//------------------------------------------------------------------------------ +// serializePayload +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils::serializePayload( + ProcessForkerFrame &frame, const messages::ProcessCrashed &msg) { + frame.type = ProcessForkerMsgType::MSG_PROCESSCRASHED; + if(!msg.SerializeToString(&frame.payload)) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to serialize ProcessCrashed payload" + ": SerializeToString() returned false"; + throw ex; + } +} + +//------------------------------------------------------------------------------ +// serializePayload +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils::serializePayload( + ProcessForkerFrame &frame, const messages::ProcessExited &msg) { + frame.type = ProcessForkerMsgType::MSG_PROCESSEXITED; + if(!msg.SerializeToString(&frame.payload)) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to serialize ProcessExited payload" + ": SerializeToString() returned false"; + throw ex; + } +} + //------------------------------------------------------------------------------ // serializePayload //------------------------------------------------------------------------------ @@ -103,11 +130,11 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils::serializePayload( // serializePayload //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::ProcessForkerUtils::serializePayload( - ProcessForkerFrame &frame, const messages::Status &msg) { - frame.type = ProcessForkerMsgType::MSG_STATUS; + ProcessForkerFrame &frame, const messages::Exception &msg) { + frame.type = ProcessForkerMsgType::MSG_EXCEPTION; if(!msg.SerializeToString(&frame.payload)) { castor::exception::Exception ex; - ex.getMessage() << "Failed to serialize Status payload" + ex.getMessage() << "Failed to serialize Exception payload" ": SerializeToString() returned false"; throw ex; } @@ -141,8 +168,24 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils::writeFrame( // writeFrame //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::ProcessForkerUtils:: - writeFrame(const int fd, const messages::Status &msg) { - writeFrame(fd, ProcessForkerMsgType::MSG_STATUS, msg); + writeFrame(const int fd, const messages::Exception &msg) { + writeFrame(fd, ProcessForkerMsgType::MSG_EXCEPTION, msg); +} + +//------------------------------------------------------------------------------ +// writeFrame +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils:: + writeFrame(const int fd, const messages::ProcessCrashed &msg) { + writeFrame(fd, ProcessForkerMsgType::MSG_PROCESSCRASHED, msg); +} + +//------------------------------------------------------------------------------ +// writeFrame +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils:: + writeFrame(const int fd, const messages::ProcessExited &msg) { + writeFrame(fd, ProcessForkerMsgType::MSG_PROCESSEXITED, msg); } //------------------------------------------------------------------------------ @@ -168,8 +211,22 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils:: //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::ProcessForkerUtils:: writeFrame(const int fd, const ProcessForkerFrame &frame) { - writeFrameHeader(fd, frame.type, frame.payload.length()); - writeFramePayload(fd, frame.payload); + try { + if(0 > fd) { + castor::exception::Exception ex; + ex.getMessage() << "Invalid file-descriptor"; + throw ex; + } + + writeFrameHeader(fd, frame.type, frame.payload.length()); + writeFramePayload(fd, frame.payload); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to write ProcessForkerFrame: fd=" << fd << + " type=" << ProcessForkerMsgType::toString(frame.type) << " payloadLen=" + << frame.payload.length() << ": " << ne.getMessage().str(); + throw ex; + } } //------------------------------------------------------------------------------ @@ -179,6 +236,12 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils:: writeFrameHeader(const int fd, const ProcessForkerMsgType::Enum type, const uint32_t payloadLen) { try { + if(0 == payloadLen) { + castor::exception::Exception ex; + ex.getMessage() << "Payload length must be greater than 0"; + throw ex; + } + writeUint32(fd, type); writeUint32(fd, payloadLen); } catch(castor::exception::Exception &ne) { @@ -406,23 +469,44 @@ std::string castor::tape::tapeserver::daemon::ProcessForkerUtils:: void castor::tape::tapeserver::daemon::ProcessForkerUtils::readAck( const int fd) { const ProcessForkerFrame frame = readFrame(fd); - messages::Status msg; + messages::Exception msg; if(!msg.ParseFromString(frame.payload)) { castor::exception::Exception ex; - ex.getMessage() << "Failed to parse Status message" + ex.getMessage() << "Failed to parse Exception message" ": ParseFromString() returned false"; throw ex; } // Throw an exception if the acknowledge is negative - if(0 != msg.status()) { - castor::exception::Exception ex(msg.status()); + if(0 != msg.code()) { + castor::exception::Exception ex(msg.code()); ex.getMessage() << msg.message(); throw ex; } } +//------------------------------------------------------------------------------ +// parsePayload +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils::parsePayload( + const ProcessForkerFrame &frame, messages::Exception &msg) { + if(ProcessForkerMsgType::MSG_EXCEPTION != frame.type) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to parse Exception payload" + ": Unexpected message type: type=" << + ProcessForkerMsgType::toString(frame.type); + throw ex; + } + + if(!msg.ParseFromString(frame.payload)) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to parse Exception payload" + ": ParseString() returned false: payloadLen=" << frame.payload.length(); + throw ex; + } +} + //------------------------------------------------------------------------------ // parsePayload //------------------------------------------------------------------------------ @@ -511,23 +595,44 @@ void castor::tape::tapeserver::daemon::ProcessForkerUtils::parsePayload( // parsePayload //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::ProcessForkerUtils::parsePayload( - const ProcessForkerFrame &frame, messages::Status &msg) { - if(ProcessForkerMsgType::MSG_STATUS != frame.type) { + const ProcessForkerFrame &frame, messages::ProcessCrashed &msg) { + if(ProcessForkerMsgType::MSG_PROCESSCRASHED != frame.type) { castor::exception::Exception ex; - ex.getMessage() << "Failed to parse Status payload" + ex.getMessage() << "Failed to parse ProcessCrashed payload" ": Unexpected message type: type=" << ProcessForkerMsgType::toString(frame.type); throw ex; - } - + } + if(!msg.ParseFromString(frame.payload)) { castor::exception::Exception ex; - ex.getMessage() << "Failed to parse Status payload" + ex.getMessage() << "Failed to parse ProcessCrashed payload" ": ParseString() returned false: payloadLen=" << frame.payload.length(); throw ex; } } +//------------------------------------------------------------------------------ +// parsePayload +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::ProcessForkerUtils::parsePayload( + const ProcessForkerFrame &frame, messages::ProcessExited &msg) { + if(ProcessForkerMsgType::MSG_PROCESSEXITED != frame.type) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to parse ProcessExited payload" + ": Unexpected message type: type=" << + ProcessForkerMsgType::toString(frame.type); + throw ex; + } + + if(!msg.ParseFromString(frame.payload)) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to parse ProcessExited payload" + ": ParseString() returned false: payloadLen=" << frame.payload.length(); + throw ex; + } +} + //------------------------------------------------------------------------------ // parsePayload //------------------------------------------------------------------------------ diff --git a/castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp b/castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp index 7ef740fa64..8a1e4498f4 100644 --- a/castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp +++ b/castor/tape/tapeserver/daemon/ProcessForkerUtils.hpp @@ -23,11 +23,13 @@ #pragma once +#include "castor/messages/Exception.pb.h" #include "castor/messages/ForkCleaner.pb.h" #include "castor/messages/ForkDataTransfer.pb.h" #include "castor/messages/ForkLabel.pb.h" #include "castor/messages/ForkSucceeded.pb.h" -#include "castor/messages/Status.pb.h" +#include "castor/messages/ProcessCrashed.pb.h" +#include "castor/messages/ProcessExited.pb.h" #include "castor/messages/StopProcessForker.pb.h" #include "castor/tape/tapeserver/daemon/ProcessForkerFrame.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerMsgType.hpp" @@ -48,6 +50,18 @@ namespace daemon { class ProcessForkerUtils { public: + /** + * Serializes the specified message into the specified frame. + * + * Please note that this method sets both the type and payload fields of the + * frame. + * + * @param frame Output parameter: The frame. + * @param msg The message. + */ + static void serializePayload(ProcessForkerFrame &frame, + const messages::Exception &msg); + /** * Serializes the specified message into the specified frame. * @@ -97,8 +111,20 @@ public: const messages::ForkSucceeded &msg); /** - * Serializes the specified message into the specified frame. + * Serializes the specified message into the specified frame. + * + * Please note that this method sets both the type and payload fields of the + * frame. * + * @param frame Output parameter: The frame. + * @param msg The message. + */ + static void serializePayload(ProcessForkerFrame &frame, + const messages::ProcessCrashed &msg); + + /** + * Serializes the specified message into the specified frame. + * * Please note that this method sets both the type and payload fields of the * frame. * @@ -106,7 +132,7 @@ public: * @param msg The message. */ static void serializePayload(ProcessForkerFrame &frame, - const messages::Status &msg); + const messages::ProcessExited &msg); /** * Serializes the specified message into the specified frame. @@ -120,6 +146,15 @@ public: static void serializePayload(ProcessForkerFrame &frame, const messages::StopProcessForker &msg); + /** + * Writes a frame with the specified message as its payload to the specified + * file descriptor. + * + * @param fd The file descriptor to be written to. + * @param msg The message to sent as the payload of the frame. + */ + static void writeFrame(const int fd, const messages::Exception &msg); + /** * Writes a frame with the specified message as its payload to the specified * file descriptor. @@ -154,7 +189,16 @@ public: * @param fd The file descriptor to be written to. * @param msg The message to sent as the payload of the frame. */ - static void writeFrame(const int fd, const messages::Status &msg); + static void writeFrame(const int fd, const messages::ProcessCrashed &msg); + + /** + * Writes a frame with the specified message as its payload to the specified + * file descriptor. + * + * @param fd The file descriptor to be written to. + * @param msg The message to sent as the payload of the frame. + */ + static void writeFrame(const int fd, const messages::ProcessExited &msg); /** * Writes a frame with the specified message as its payload to the specified @@ -184,12 +228,12 @@ public: * Reads a good-day reply or an exception from the specified file descriptor. * * This method deals with two types of message, the one the caller wishes to - * read in the good-day scenario and the messages::Status message in the - * bad-day scenario where the ProcessForker replies with an error/exception. + * read in the good-day scenario and the messages::Exception message in the + * bad-day scenario where the ProcessForker replies with an exception. * - * If the ProcessForker replies with an error/exception in the form of a - * messages::Status message, then this method will convert the message into - * an exception. + * If the ProcessForker replies with an exception in the form of a + * messages::Exception message, then this method will convert the message into + * a C++ exception. * * @param fd The file descriptor to be read from. * @param msgType The type of the message. @@ -198,17 +242,17 @@ public: template<typename T> static void readReplyOrEx(const int fd, T &msg) { const ProcessForkerFrame frame = readFrame(fd); - // Throw an exception if the ProcessForker replies with an error - if(ProcessForkerMsgType::MSG_STATUS == frame.type) { - messages::Status errMsg; - if(!errMsg.ParseFromString(frame.payload)) { + // Throw an exception if the ProcessForker replied with one + if(ProcessForkerMsgType::MSG_EXCEPTION == frame.type) { + messages::Exception exMsg; + if(!exMsg.ParseFromString(frame.payload)) { castor::exception::Exception ex; - ex.getMessage() << "Failed to parse Status message" + ex.getMessage() << "Failed to parse Exception message" ": ParseFromString() returned false"; throw ex; } - castor::exception::Exception ex(errMsg.status()); - ex.getMessage() << errMsg.message(); + castor::exception::Exception ex(exMsg.code()); + ex.getMessage() << exMsg.message(); throw ex; } @@ -223,6 +267,16 @@ public: */ static ProcessForkerFrame readFrame(const int fd); + /** + * Parses the payload of the specified frame. + * + * @param frame The frame. + * @param msg Output parameter: The message contained within the payload of + * the frame. + */ + static void parsePayload(const ProcessForkerFrame &frame, + messages::Exception &msg); + /** * Parses the payload of the specified frame. * @@ -271,7 +325,17 @@ public: * the frame. */ static void parsePayload(const ProcessForkerFrame &frame, - messages::Status &msg); + messages::ProcessCrashed &msg); + + /** + * Parses the payload of the specified frame. + * + * @param frame The frame. + * @param msg Output parameter: The message contained within the payload of + * the frame. + */ + static void parsePayload(const ProcessForkerFrame &frame, + messages::ProcessExited &msg); /** * Parses the payload of the specified frame. diff --git a/castor/tape/tapeserver/daemon/TapeDaemon.cpp b/castor/tape/tapeserver/daemon/TapeDaemon.cpp index 8c3b91a570..853e5d30de 100644 --- a/castor/tape/tapeserver/daemon/TapeDaemon.cpp +++ b/castor/tape/tapeserver/daemon/TapeDaemon.cpp @@ -34,6 +34,7 @@ #include "castor/tape/tapeserver/daemon/LabelCmdAcceptHandler.hpp" #include "castor/tape/tapeserver/daemon/LabelSession.hpp" #include "castor/tape/tapeserver/daemon/ProcessForker.hpp" +#include "castor/tape/tapeserver/daemon/ProcessForkerConnectionHandler.hpp" #include "castor/tape/tapeserver/daemon/ProcessForkerProxySocket.hpp" #include "castor/tape/tapeserver/daemon/TapeDaemon.hpp" #include "castor/tape/tapeserver/daemon/TapeMessageHandler.hpp" @@ -265,36 +266,21 @@ void castor::tape::tapeserver::daemon::TapeDaemon::setProcessCapabilities( //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::TapeDaemon::forkProcessForker() { m_log.prepareForFork(); - // Create a socket pair for controlling the ProcessForker - int sv[2] = {-1 , -1}; - if(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { - char message[100]; - strerror_r(errno, message, sizeof(message)); - castor::exception::Exception ex; - ex.getMessage() << "Failed to fork process forker: Failed to create socket" - " pair for controlling the ProcessForker: " << message; - throw ex; - } - const int processForkerCmdSenderSocket = sv[0]; - const int processForkerCmdReceiverSocket = sv[1]; - - { - log::Param params[] = { - log::Param("cmdSenderSocket", processForkerCmdSenderSocket), - log::Param("cmdReceiverSocket", processForkerCmdReceiverSocket)}; - m_log(LOG_INFO, "TapeDaemon parent process succesfully created socket" - " pair for controlling the ProcessForker", params); - } + // Create two socket pairs for ProcessForker communications + const ForkerCmdPair cmdPair = createForkerCmdPair(); + const ForkerReaperPair reaperPair = createForkerReaperPair(); const pid_t forkRc = fork(); // If fork failed if(0 > forkRc) { - close(processForkerCmdReceiverSocket); - char message[100]; sstrerror_r(errno, message, sizeof(message)); + + closeForkerCmdPair(cmdPair); + closeForkerReaperPair(reaperPair); + castor::exception::Exception ex; ex.getMessage() << "Failed to fork ProcessForker: " << message; throw ex; @@ -309,24 +295,16 @@ void castor::tape::tapeserver::daemon::TapeDaemon::forkProcessForker() { m_log(LOG_INFO, "Successfully forked the ProcessForker", params); } - if(close(processForkerCmdReceiverSocket)) { - char message[100]; - sstrerror_r(errno, message, sizeof(message)); - castor::exception::Exception ex; - ex.getMessage() << "TapeDaemon parent process failed to close the socket" - " used to receive ProcessForker commands: " << message; - throw ex; - } + closeProcessForkerSideOfCmdPair(cmdPair); + closeProcessForkerSideOfReaperPair(reaperPair); - { - log::Param params[] = - {log::Param("cmdReceiverSocket", processForkerCmdReceiverSocket)}; - m_log(LOG_INFO, "TapeDaemon parent process successfully closed the socket" - " used to receive ProcessForker commands", params); - } + m_processForker = new ProcessForkerProxySocket(m_log, cmdPair.tapeDaemon); + log::Param params[] = + {log::Param("cmdPair.tapeDaemon", cmdPair.tapeDaemon)}; + m_log(LOG_INFO, "TapeDaemon parent process created ProcessForker proxy", + params); - m_processForker = - new ProcessForkerProxySocket(m_log, processForkerCmdSenderSocket); + createAndRegisterProcessForkerConnectionHandler(reaperPair.tapeDaemon); return; @@ -336,48 +314,260 @@ void castor::tape::tapeserver::daemon::TapeDaemon::forkProcessForker() { // file-descriptors owned by the event handlers m_reactor.clear(); - if(close(processForkerCmdSenderSocket)) { - char message[100]; - sstrerror_r(errno, message, sizeof(message)); - castor::exception::Exception ex; - ex.getMessage() << "ProcessForker process failed to close the socket" - " used to send ProcessForker commands: " << message; - throw ex; - } + closeTapeDaemonSideOfCmdPair(cmdPair); + closeTapeDaemonSideOfReaperPair(reaperPair); - { - log::Param params[] = - {log::Param("cmdSenderSocket", processForkerCmdSenderSocket)}; - m_log(LOG_INFO, "ProcessForker process successfully closed the socket" - " used to send ProcessForker commands", params); - } + exit(runProcessForker(cmdPair.processForker, reaperPair.processForker)); + } +} + +//------------------------------------------------------------------------------ +// createForkerCmdPair +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::TapeDaemon::ForkerCmdPair + castor::tape::tapeserver::daemon::TapeDaemon::createForkerCmdPair() { + ForkerCmdPair cmdPair; + + try { + const std::pair<int, int> socketPair = createSocketPair(); + cmdPair.tapeDaemon = socketPair.first; + cmdPair.processForker = socketPair.second; + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to create socket pair to control the" + " ProcessForker: " << ne.getMessage().str(); + throw ex; + } + + { + log::Param params[] = { + log::Param("cmdPair.tapeDaemon", cmdPair.tapeDaemon), + log::Param("cmdPair.processForker", cmdPair.processForker)}; + m_log(LOG_INFO, "TapeDaemon parent process succesfully created socket" + " pair to control the ProcessForker", params); + } + + return cmdPair; +} + +//------------------------------------------------------------------------------ +// createForkerReaperPair +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::TapeDaemon::ForkerReaperPair + castor::tape::tapeserver::daemon::TapeDaemon::createForkerReaperPair() { + ForkerReaperPair reaperPair; + + try { + const std::pair<int, int> socketPair = createSocketPair(); + reaperPair.tapeDaemon = socketPair.first; + reaperPair.processForker = socketPair.second; + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to create socket pair for the ProcessForker" + " to report terminated processes: " << ne.getMessage().str(); + throw ex; + } + + { + log::Param params[] = { + log::Param("reaperPair.tapeDaemon", reaperPair.tapeDaemon), + log::Param("reaperPair.processForker", reaperPair.processForker)}; + m_log(LOG_INFO, "TapeDaemon parent process succesfully created socket" + " pair for ProcessForker to report terminated processes", params); + } + + return reaperPair; +} + +//------------------------------------------------------------------------------ +// createSocketPair +//------------------------------------------------------------------------------ +std::pair<int, int> + castor::tape::tapeserver::daemon::TapeDaemon::createSocketPair() { + int sv[2] = {-1, -1}; + if(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { + char message[100]; + strerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to create socket pair: " << message; + throw ex; + } + + return std::pair<int, int> (sv[0], sv[1]); +} + +//------------------------------------------------------------------------------ +// closeForkerCmdPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon::closeForkerCmdPair( + const ForkerCmdPair &cmdPair) { + if(close(cmdPair.tapeDaemon)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to close TapeDaemon side of cmdPair" + ": cmdPair.tapeDaemon=" << cmdPair.tapeDaemon << ": " << message; + throw ex; + } else { + log::Param params[] = + {log::Param("cmdPair.tapeDaemon", cmdPair.tapeDaemon)}; + m_log(LOG_INFO, "Successfully closed TapeDaemon side of cmdPair", + params); + } + + if(close(cmdPair.processForker)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to close ProcessForker side of cmdPair" + ": cmdPair.processForker=" << cmdPair.processForker << ": " << message; + throw ex; + } else { + log::Param params[] = + {log::Param("cmdPair.processForker", cmdPair.processForker)}; + m_log(LOG_INFO, "Successfully closed ProcessForker side of cmdPair", + params); + } +} + +//------------------------------------------------------------------------------ +// closeForkerReaperPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon::closeForkerReaperPair( + const ForkerReaperPair &reaperPair) { + if(close(reaperPair.tapeDaemon)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to close TapeDaemon side of reaperPair" + ": reaperPair.tapeDaemon=" << reaperPair.tapeDaemon << ": " << message; + throw ex; + } else { + log::Param params[] = + {log::Param("reaperPair.tapeDaemon", reaperPair.tapeDaemon)}; + m_log(LOG_INFO, "Successfully closed TapeDaemon side of reaperPair", + params); + } + + if(close(reaperPair.processForker)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "Failed to close ProcessForker side of reaperPair" + ": reaperPair.processForker=" << reaperPair.processForker << ": " << + message; + throw ex; + } else { + log::Param params[] = + {log::Param("reaperPair.processForker", reaperPair.processForker)}; + m_log(LOG_INFO, "Successfully closed ProcessForker side of reaperPair", + params); + } +} - exit(runProcessForker(processForkerCmdReceiverSocket)); +//------------------------------------------------------------------------------ +// closeProcessForkerSideOfCmdPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon:: + closeProcessForkerSideOfCmdPair(const ForkerCmdPair &cmdPair) { + if(close(cmdPair.processForker)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "TapeDaemon parent process failed to close" + " ProcessForker side of cmdPair: cmdPair.processForker=" << + cmdPair.processForker << ": " << message; + throw ex; } + + log::Param params[] = + {log::Param("cmdPair.processForker", cmdPair.processForker)}; + m_log(LOG_INFO, "TapeDaemon parent process successfully closed" + " ProcessForker side of cmdPair", params); +} + +//------------------------------------------------------------------------------ +// closeProcessForkerSideOfReaperPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon:: + closeProcessForkerSideOfReaperPair(const ForkerReaperPair &reaperPair) { + if(close(reaperPair.processForker)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "TapeDaemon parent process failed to close" + " ProcessForker side of reaperPair: reaperPair.processForker=" << + reaperPair.processForker << ": " << message; + throw ex; + } + + log::Param params[] = + {log::Param("reaperPair.processForker)", reaperPair.processForker)}; + m_log(LOG_INFO, "TapeDaemon parent process successfully closed" + " ProcessForker side of reaperPair", params); +} + +//------------------------------------------------------------------------------ +// closeTapeDaemonSideOfCmdPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon:: + closeTapeDaemonSideOfCmdPair(const ForkerCmdPair &cmdPair) { + if(close(cmdPair.tapeDaemon)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "ProcessForker process failed to close" + " TapeDaemon side of cmdPair: cmdPair.tapeDaemon=" << cmdPair.tapeDaemon + << ": " << message; + throw ex; + } + + log::Param params[] = {log::Param("cmdPair.tapeDaemon", cmdPair.tapeDaemon)}; + m_log(LOG_INFO, "ProcessForker process successfully closed" + " TapeDaemon side of cmdPair", params); +} + +//------------------------------------------------------------------------------ +// closeTapeDaemonSideOfReaperPair +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon:: + closeTapeDaemonSideOfReaperPair(const ForkerReaperPair &reaperPair) { + if(close(reaperPair.tapeDaemon)) { + char message[100]; + sstrerror_r(errno, message, sizeof(message)); + castor::exception::Exception ex; + ex.getMessage() << "ProcessForker process failed to close" + " TapeDaemon side of reaperPair: reaperPair.tapeDaemon=" << + reaperPair.tapeDaemon << ": " << message; + throw ex; + } + + log::Param params[] = + {log::Param("reaperPair.tapeDaemon", reaperPair.tapeDaemon)}; + m_log(LOG_INFO, "ProcessForker parent process successfully closed" + " TapeDaemon side of reaperPair", params); } //------------------------------------------------------------------------------ // runProcessForker //------------------------------------------------------------------------------ int castor::tape::tapeserver::daemon::TapeDaemon::runProcessForker( - const int cmdReceiverSocket) throw() { + const int cmdReceiverSocket, const int reaperSenderSocket) throw() { try { - ProcessForker processForker(m_log, cmdReceiverSocket); + ProcessForker processForker(m_log, cmdReceiverSocket, reaperSenderSocket, + m_hostName); processForker.execute(); + return 0; } catch(castor::exception::Exception &ex) { log::Param params[] = {log::Param("message", ex.getMessage().str())}; m_log(LOG_ERR, "ProcessForker threw an unexpected exception", params); - return 1; } catch(std::exception &se) { log::Param params[] = {log::Param("message", se.what())}; m_log(LOG_ERR, "ProcessForker threw an unexpected exception", params); - return 1; } catch(...) { m_log(LOG_ERR, "ProcessForker threw an unknown and unexpected exception"); - return 1; } - - return 0; + return 1; } //------------------------------------------------------------------------------ @@ -483,7 +673,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::setUpReactor() { //------------------------------------------------------------------------------ // createAndRegisterVdqmAcceptHandler //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterVdqmAcceptHandler() { +void castor::tape::tapeserver::daemon::TapeDaemon:: + createAndRegisterVdqmAcceptHandler() { castor::utils::SmartFd listenSock; try { listenSock.reset(io::createListenerSock(TAPE_SERVER_VDQM_LISTENING_PORT)); @@ -499,10 +690,10 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterVdqmAcceptHa m_log(LOG_INFO, "Listening for connections from the vdqmd daemon", params); } - std::auto_ptr<VdqmAcceptHandler> vdqmAcceptHandler; + std::auto_ptr<VdqmAcceptHandler> handler; try { - vdqmAcceptHandler.reset(new VdqmAcceptHandler(listenSock.get(), m_reactor, - m_log, m_driveCatalogue)); + handler.reset(new VdqmAcceptHandler(listenSock.get(), m_reactor, m_log, + m_driveCatalogue)); listenSock.release(); } catch(std::bad_alloc &ba) { castor::exception::BadAlloc ex; @@ -511,14 +702,15 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterVdqmAcceptHa ": " << ba.what(); throw ex; } - m_reactor.registerHandler(vdqmAcceptHandler.get()); - vdqmAcceptHandler.release(); + m_reactor.registerHandler(handler.get()); + handler.release(); } //------------------------------------------------------------------------------ // createAndRegisterAdminAcceptHandler //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterAdminAcceptHandler() { +void castor::tape::tapeserver::daemon::TapeDaemon:: + createAndRegisterAdminAcceptHandler() { castor::utils::SmartFd listenSock; try { listenSock.reset(io::createListenerSock(TAPE_SERVER_ADMIN_LISTENING_PORT)); @@ -536,10 +728,10 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterAdminAcceptH params); } - std::auto_ptr<AdminAcceptHandler> adminAcceptHandler; + std::auto_ptr<AdminAcceptHandler> handler; try { - adminAcceptHandler.reset(new AdminAcceptHandler(listenSock.get(), m_reactor, - m_log, m_vdqm, m_driveCatalogue, m_hostName)); + handler.reset(new AdminAcceptHandler(listenSock.get(), m_reactor, m_log, + m_vdqm, m_driveCatalogue, m_hostName)); listenSock.release(); } catch(std::bad_alloc &ba) { castor::exception::BadAlloc ex; @@ -548,8 +740,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterAdminAcceptH ": " << ba.what(); throw ex; } - m_reactor.registerHandler(adminAcceptHandler.get()); - adminAcceptHandler.release(); + m_reactor.registerHandler(handler.get()); + handler.release(); } //------------------------------------------------------------------------------ @@ -573,10 +765,10 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterLabelCmdAcce params); } - std::auto_ptr<LabelCmdAcceptHandler> labelCmdAcceptHandler; + std::auto_ptr<LabelCmdAcceptHandler> handler; try { - labelCmdAcceptHandler.reset(new LabelCmdAcceptHandler(listenSock.get(), - m_reactor, m_log, m_driveCatalogue, m_hostName, m_vdqm, m_vmgr)); + handler.reset(new LabelCmdAcceptHandler(listenSock.get(), m_reactor, m_log, + m_driveCatalogue, m_hostName, m_vdqm, m_vmgr)); listenSock.release(); } catch(std::bad_alloc &ba) { castor::exception::BadAlloc ex; @@ -585,8 +777,8 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterLabelCmdAcce ": " << ba.what(); throw ex; } - m_reactor.registerHandler(labelCmdAcceptHandler.get()); - labelCmdAcceptHandler.release(); + m_reactor.registerHandler(handler.get()); + handler.release(); } //------------------------------------------------------------------------------ @@ -594,10 +786,10 @@ void castor::tape::tapeserver::daemon::TapeDaemon::createAndRegisterLabelCmdAcce //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::TapeDaemon:: createAndRegisterTapeMessageHandler() { - std::auto_ptr<TapeMessageHandler> tapeMessageHandler; + std::auto_ptr<TapeMessageHandler> handler; try { - tapeMessageHandler.reset(new TapeMessageHandler(m_reactor, m_log, - m_driveCatalogue, m_hostName, m_vdqm, m_vmgr, m_zmqContext)); + handler.reset(new TapeMessageHandler(m_reactor, m_log, m_driveCatalogue, + m_hostName, m_vdqm, m_vmgr, m_zmqContext)); } catch(std::bad_alloc &ba) { castor::exception::BadAlloc ex; ex.getMessage() << @@ -605,8 +797,28 @@ void castor::tape::tapeserver::daemon::TapeDaemon:: ": " << ba.what(); throw ex; } - m_reactor.registerHandler(tapeMessageHandler.get()); - tapeMessageHandler.release(); + m_reactor.registerHandler(handler.get()); + handler.release(); +} + +//------------------------------------------------------------------------------ +// createAndRegisterProcessForkerConnectionHandler +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeDaemon:: + createAndRegisterProcessForkerConnectionHandler(const int reaperSocket) { + std::auto_ptr<ProcessForkerConnectionHandler> handler; + try { + handler.reset(new ProcessForkerConnectionHandler(reaperSocket, m_reactor, + m_log, m_driveCatalogue, m_hostName, m_vdqm)); + } catch(std::bad_alloc &ba) { + castor::exception::BadAlloc ex; + ex.getMessage() << + "Failed to create event handler for communicating with the ProcessForker" + ": " << ba.what(); + throw ex; + } + m_reactor.registerHandler(handler.get()); + handler.release(); } //------------------------------------------------------------------------------ @@ -640,8 +852,8 @@ bool castor::tape::tapeserver::daemon::TapeDaemon::handleEvents() log::Param("message", ex.getMessage().str()), log::Param("backtrace", ex.backtrace()) }; - m_log(LOG_ERR, "Unexpected castor exception thrown when handling an I/O event", - params); + m_log(LOG_ERR, + "Unexpected castor exception thrown when handling an I/O event", params); } catch(std::exception &se) { // Log exception and continue log::Param params[] = {log::Param("message", se.what())}; @@ -792,8 +1004,6 @@ void castor::tape::tapeserver::daemon::TapeDaemon:: const int waitpidStat) { switch(sessionType) { - case DriveCatalogueEntry::SESSION_TYPE_DATATRANSFER: - return handleReapedDataTransferSession(pid, waitpidStat); case DriveCatalogueEntry::SESSION_TYPE_LABEL: return handleReapedLabelSession(pid, waitpidStat); case DriveCatalogueEntry::SESSION_TYPE_CLEANER: @@ -808,37 +1018,6 @@ void castor::tape::tapeserver::daemon::TapeDaemon:: } } -//------------------------------------------------------------------------------ -// handleReapedDataTransferSession -//------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeDaemon::handleReapedDataTransferSession( - const pid_t pid, const int waitpidStat) { - try { - std::list<log::Param> params; - params.push_back(log::Param("dataTransferPid", pid)); - DriveCatalogueEntry *const drive = m_driveCatalogue.findDrive(pid); - const utils::DriveConfig &driveConfig = drive->getConfig(); - - if(WIFEXITED(waitpidStat) && 0 == WEXITSTATUS(waitpidStat)) { - const std::string vid = drive->getVid(); - drive->sessionSucceeded(); - m_log(LOG_INFO, "Data-transfer session succeeded", params); - requestVdqmToReleaseDrive(driveConfig, pid); - notifyVdqmTapeUnmounted(driveConfig, vid, pid); - } else { - drive->sessionFailed(); //deletes the session - m_log(LOG_INFO, "Data-transfer session failed. Going to try to clean the drive.", params); - requestVdqmToReleaseDrive(driveConfig, pid); - drive->toBeCleaned(); - } - } catch(castor::exception::Exception &ne) { - castor::exception::Exception ex; - ex.getMessage() << "Failed to handle reaped data transfer session: " << - ne.getMessage().str(); - throw ex; - } -} - //------------------------------------------------------------------------------ // handleReapedCleanerSession //------------------------------------------------------------------------------ @@ -987,166 +1166,84 @@ void castor::tape::tapeserver::daemon::TapeDaemon::forkDataTransferSessions() //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::TapeDaemon::forkDataTransferSession( DriveCatalogueEntry *drive) throw() { - const utils::DriveConfig &driveConfig = drive->getConfig(); - - std::list<log::Param> params; - params.push_back(log::Param("unitName", driveConfig.unitName)); - - m_processForker->forkDataTransfer(driveConfig.unitName); - - m_log.prepareForFork(); - - const pid_t forkRc = fork(); - - // If fork failed - if(0 > forkRc) { - // Log an error message and return - char message[100]; - sstrerror_r(errno, message, sizeof(message)); - params.push_back(log::Param("message", message)); - m_log(LOG_ERR, "Failed to fork data-transfer session for tape drive", - params); - return; + try { + const utils::DriveConfig &driveConfig = drive->getConfig(); + const legacymsg::RtcpJobRqstMsgBody &vdqmJob = drive->getVdqmJob(); + const DataTransferSession::CastorConf dataTransferConfig = + getDataTransferConf(); - // Else if this is the parent process - } else if(0 < forkRc) { - drive->forkedDataTransferSession(forkRc); - return; - - // Else this is the child process - } else { - // Clear the reactor which in turn will close all of the open - // file-descriptors owned by the event handlers - m_reactor.clear(); + const pid_t dataTransferPid = m_processForker->forkDataTransfer(driveConfig, + vdqmJob, dataTransferConfig); + drive->forkedDataTransferSession(dataTransferPid); try { m_vdqm.assignDrive(m_hostName, driveConfig.unitName, - drive->getVdqmJob().dgn, drive->getVdqmJob().volReqId, getpid()); - m_log(LOG_INFO, "Assigned the drive in the vdqm"); + drive->getVdqmJob().dgn, drive->getVdqmJob().volReqId, dataTransferPid); + log::Param params[] = { + log::Param("server", m_hostName), + log::Param("unitName", driveConfig.unitName), + log::Param("dgn", std::string(drive->getVdqmJob().dgn)), + log::Param("volReqId", drive->getVdqmJob().volReqId), + log::Param("dataTransferPid", dataTransferPid)}; + m_log(LOG_INFO, "Assigned the drive in the vdqm", params); } catch(castor::exception::Exception &ex) { log::Param params[] = {log::Param("message", ex.getMessage().str())}; m_log(LOG_ERR, "Data-transfer session could not be started" ": Failed to assign drive in vdqm", params); } - - runDataTransferSession(drive); + } catch(castor::exception::Exception &ex) { + log::Param params[] = {log::Param("message", ex.getMessage().str())}; + m_log(LOG_ERR, "Caught an exception when requesting ProcessForker to fork a" + " data-transfer session", params); + drive->sessionFailed(); + } catch(std::exception &se) { + log::Param params[] = {log::Param("message", se.what())}; + m_log(LOG_ERR, "Caught an exception when requesting ProcessForker to fork a" + " data-transfer session", params); + drive->sessionFailed(); + } catch(...) { + m_log(LOG_ERR, "Caught an unknown exception when requesting ProcessForker" + " to fork a data-transfer session"); + drive->sessionFailed(); } } //------------------------------------------------------------------------------ -// runDataTransferSession -//------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeDaemon::runDataTransferSession( - const DriveCatalogueEntry *drive) throw() { - const utils::DriveConfig &driveConfig = drive->getConfig(); - std::list<log::Param> params; - params.push_back(log::Param("unitName", driveConfig.unitName)); - - m_log(LOG_INFO, "Data-transfer child-process started", params); - - try { - DataTransferSession::CastorConf castorConf; - // This try bloc will allow us to send a failure notification to the client - // if we fail before the DataTransferSession has an opportunity to do so. - std::auto_ptr<DataTransferSession> dataTransferSession; - castor::tape::System::realWrapper sysWrapper; - std::auto_ptr<legacymsg::RmcProxy> rmc; - std::auto_ptr<messages::TapeserverProxy> tapeserver; - try { - common::CastorConfiguration &config = - common::CastorConfiguration::getConfig(); - castorConf.rtcopydBufsz = config.getConfEntInt( - "RTCOPYD", "BUFSZ", (uint32_t)RTCP_BUFSZ, &m_log); - castorConf.rtcopydNbBufs = config.getConfEntInt( - "RTCOPYD", "NB_BUFS", (uint32_t)NB_RTCP_BUFS, &m_log); - castorConf.tapeBadMIRHandlingRepair = config.getConfEntString( - "TAPE", "BADMIR_HANDLING", "CANCEL", &m_log); - castorConf.tapebridgeBulkRequestMigrationMaxBytes = config.getConfEntInt( - "TAPEBRIDGE", "BULKREQUESTMIGRATIONMAXBYTES", - (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTMIGRATIONMAXBYTES, &m_log); - castorConf.tapebridgeBulkRequestMigrationMaxFiles = config.getConfEntInt( - "TAPEBRIDGE", "BULKREQUESTMIGRATIONMAXFILES", - (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTMIGRATIONMAXFILES, &m_log); - castorConf.tapebridgeBulkRequestRecallMaxBytes = config.getConfEntInt( - "TAPEBRIDGE", "BULKREQUESTRECALLMAXBYTES", - (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTRECALLMAXBYTES, &m_log); - castorConf.tapebridgeBulkRequestRecallMaxFiles = config.getConfEntInt( - "TAPEBRIDGE", "BULKREQUESTRECALLMAXFILES", - (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTRECALLMAXFILES, &m_log); - castorConf.tapebridgeMaxBytesBeforeFlush = config.getConfEntInt( - "TAPEBRIDGE", "MAXBYTESBEFOREFLUSH", - (uint64_t)tapebridge::TAPEBRIDGE_MAXBYTESBEFOREFLUSH, &m_log); - castorConf.tapebridgeMaxFilesBeforeFlush = config.getConfEntInt( - "TAPEBRIDGE", "MAXFILESBEFOREFLUSH", - (uint64_t)tapebridge::TAPEBRIDGE_MAXFILESBEFOREFLUSH, &m_log); - castorConf.tapeserverdDiskThreads = config.getConfEntInt( - "RTCPD", "THREAD_POOL", (uint32_t)RTCPD_THREAD_POOL, &m_log); - - rmc.reset(m_rmcFactory.create()); - tapeserver.reset(m_tapeserverFactory.create( - DataTransferSession::getZmqContext())); - dataTransferSession.reset(new DataTransferSession ( - m_hostName, - drive->getVdqmJob(), - m_log, - sysWrapper, - driveConfig, - *(rmc.get()), - *(tapeserver.get()), - m_capUtils, - castorConf - )); - } catch (castor::exception::Exception & ex) { - try { - client::ClientProxy cl(drive->getVdqmJob()); - client::ClientInterface::RequestReport rep; - cl.reportEndOfSessionWithError(ex.getMessageValue(), ex.code(), rep); - } catch (...) { - params.push_back(log::Param("errorMessage", ex.getMessageValue())); - params.push_back(log::Param("errorCode", ex.code())); - m_log(LOG_ERR, "Failed to notify the client of the failed session" - " when setting up the data-transfer session", params); - } - throw; - } - catch (...) { - try { - m_log(LOG_ERR, "Got non castor exception error while constructing" - " data-transfer session", params); - client::ClientProxy cl(drive->getVdqmJob()); - client::ClientInterface::RequestReport rep; - cl.reportEndOfSessionWithError( - "Non-Castor exception when setting up the data-transfer session", - SEINTERNAL, rep); - } catch (...) { - params.push_back(log::Param("errorMessage", - "Non-Castor exception when setting up the data-transfer session")); - m_log(LOG_ERR, "Failed to notify the client of the failed session" - " when setting up the data-transfer session", params); - } - throw; - } - m_log(LOG_INFO, "Going to execute data-transfer session"); - int result = dataTransferSession->execute(); - exit(result); - } catch(castor::exception::Exception & ex) { - params.push_back(log::Param("message", ex.getMessageValue())); - m_log(LOG_ERR, "Aborting data-transfer session" - ": Caught an unexpected CASTOR exception", params); - castor::log::LogContext lc(m_log); - lc.logBacktrace(LOG_ERR, ex.backtrace()); - exit(1); - } catch(std::exception &se) { - params.push_back(log::Param("message", se.what())); - m_log(LOG_ERR, - "Aborting data-transfer session: Caught an unexpected standard exception", - params); - exit(1); - } catch(...) { - m_log(LOG_ERR, "Aborting data-transfer session" - ": Caught an unexpected and unknown exception", params); - exit(1); - } +// getDataTransferConf +//------------------------------------------------------------------------------ +castor::tape::tapeserver::daemon::DataTransferSession::CastorConf + castor::tape::tapeserver::daemon::TapeDaemon::getDataTransferConf() { + DataTransferSession::CastorConf castorConf; + common::CastorConfiguration &config = + common::CastorConfiguration::getConfig(); + castorConf.rtcopydBufsz = config.getConfEntInt( + "RTCOPYD", "BUFSZ", (uint32_t)RTCP_BUFSZ, &m_log); + castorConf.rtcopydNbBufs = config.getConfEntInt( + "RTCOPYD", "NB_BUFS", (uint32_t)NB_RTCP_BUFS, &m_log); + castorConf.tapeBadMIRHandlingRepair = config.getConfEntString( + "TAPE", "BADMIR_HANDLING", "CANCEL", &m_log); + castorConf.tapebridgeBulkRequestMigrationMaxBytes = config.getConfEntInt( + "TAPEBRIDGE", "BULKREQUESTMIGRATIONMAXBYTES", + (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTMIGRATIONMAXBYTES, &m_log); + castorConf.tapebridgeBulkRequestMigrationMaxFiles = config.getConfEntInt( + "TAPEBRIDGE", "BULKREQUESTMIGRATIONMAXFILES", + (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTMIGRATIONMAXFILES, &m_log); + castorConf.tapebridgeBulkRequestRecallMaxBytes = config.getConfEntInt( + "TAPEBRIDGE", "BULKREQUESTRECALLMAXBYTES", + (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTRECALLMAXBYTES, &m_log); + castorConf.tapebridgeBulkRequestRecallMaxFiles = config.getConfEntInt( + "TAPEBRIDGE", "BULKREQUESTRECALLMAXFILES", + (uint64_t)tapebridge::TAPEBRIDGE_BULKREQUESTRECALLMAXFILES, &m_log); + castorConf.tapebridgeMaxBytesBeforeFlush = config.getConfEntInt( + "TAPEBRIDGE", "MAXBYTESBEFOREFLUSH", + (uint64_t)tapebridge::TAPEBRIDGE_MAXBYTESBEFOREFLUSH, &m_log); + castorConf.tapebridgeMaxFilesBeforeFlush = config.getConfEntInt( + "TAPEBRIDGE", "MAXFILESBEFOREFLUSH", + (uint64_t)tapebridge::TAPEBRIDGE_MAXFILESBEFOREFLUSH, &m_log); + castorConf.tapeserverdDiskThreads = config.getConfEntInt( + "RTCPD", "THREAD_POOL", (uint32_t)RTCPD_THREAD_POOL, &m_log); + + return castorConf; } //------------------------------------------------------------------------------ diff --git a/castor/tape/tapeserver/daemon/TapeDaemon.hpp b/castor/tape/tapeserver/daemon/TapeDaemon.hpp index 7bacdecfca..51493bb48e 100644 --- a/castor/tape/tapeserver/daemon/TapeDaemon.hpp +++ b/castor/tape/tapeserver/daemon/TapeDaemon.hpp @@ -158,14 +158,145 @@ protected: */ void forkProcessForker(); + /** + * Socket pair used to control the ProcessForker. + */ + struct ForkerCmdPair { + + /** + * Bi-directional socket used by the TapeDaemon parent process to send + * commands to the process forker and receive replies in return. + */ + int tapeDaemon; + + /** + * Bi-directional socket used by the ProcessForker to receive commands + * from the TapeDaemon parent process and send back replies. + */ + int processForker; + + /** + * Constructor. + * + * This constructor sets both members to -1 which represents an invalid + * file descriptor. + */ + ForkerCmdPair(): tapeDaemon(-1), processForker(-1) { + } + }; // struct ForkerCmdPair + + /** + * Creates the socket pair to be used to control the ProcessForker. + * + * @return The socket pair. + */ + ForkerCmdPair createForkerCmdPair(); + + /** + * Socket pair used by the ProcessForker to notify the TapeDaemon parent + * process of the termination of ProcessForker child processes. + */ + struct ForkerReaperPair { + + /** + * Socket used by the TapeDaemon receive process termination notifications + * from the ProcessForker. + */ + int tapeDaemon; + + /** + * Socket used by the ProcessForker to send process termination + * notifications to the TapeDaemon parent process. + */ + int processForker; + + /** + * Constructor. + * + * This constructor sets both members to -1 which represents an invalid + * file descriptor. + */ + ForkerReaperPair(): tapeDaemon(-1), processForker(-1) { + } + }; // struct ForkerReaperPair + + /** + * Creates the socket pair to be used by the ProcessForker to notify the + * TapeDaemon parent process of the termination of ProcessForker processes. + * + * @return The socket pair. + */ + ForkerReaperPair createForkerReaperPair(); + + /** + * C++ wrapper around socketpair() that converts a failure into a C++ + * exception. + * + * @return The socket pair. + */ + std::pair<int, int> createSocketPair(); + + /** + * Closes both the sockets of the specified socket pair. + * + * @param cmdPair The socket pair to be close. + */ + void closeForkerCmdPair(const ForkerCmdPair &cmdPair); + + /** + * Closes both the sockets of the specified socket pair. + * + * @param reaperPair The socket pair to be close. + */ + void closeForkerReaperPair(const ForkerReaperPair &reaperPair); + + /** + * Acting on behalf of the TapeDaemon parent process this method closes the + * ProcessForker side of the socket pair used to control the ProcessForker. + * + * @param cmdPair The socket pair used to control the ProcessForker. + */ + void closeProcessForkerSideOfCmdPair(const ForkerCmdPair &cmdPair); + + /** + * Acting on behalf of the TapeDaemon parent process this method closes the + * ProcessForker side of the socket pair used by the ProcessForker to report + * process terminations. + * + * @param reaperPair The socket pair used by the ProcessForker to report + * process terminations. + */ + void closeProcessForkerSideOfReaperPair(const ForkerReaperPair &reaperPair); + + /** + * Acting on behalf of the ProcessForker process this method closes the + * TapeDaemon side of the socket pair used to control the ProcessForker. + * + * @param cmdPair The socket pair used to control the ProcessForker. + */ + void closeTapeDaemonSideOfCmdPair(const ForkerCmdPair &cmdPair); + + /** + * Acting on behalf of the ProcessForker process this method closes the + * TapeDaemon side of the socket pair used by the ProcessForker to report + * process terminations. + * + * @param reaperPair The socket pair used by the ProcessForker to report + * process terminations. + */ + void closeTapeDaemonSideOfReaperPair(const ForkerReaperPair &reaperPair); + /** * Runs the ProcessForker. * * @param cmdReceiverSocket The socket used to receive commands for the * ProcessForker. + * @param reaperSenderSocket The socket used to send process termination + * reports to the TapeDaemon parent process. * @return the exit code to be used for the process running the ProcessForker. */ - int runProcessForker(const int cmdReceiverSocket) throw(); + int runProcessForker(const int cmdReceiverSocket, + const int reaperSenderSocket) throw(); /** * Blocks the signals that should not asynchronously disturb the daemon. @@ -212,9 +343,18 @@ protected: void createAndRegisterLabelCmdAcceptHandler(); /** - * Creates the handler to discuss through zmq socket to the forked sessions + * Creates the handler to handle messages from forked sessions. */ void createAndRegisterTapeMessageHandler(); + + /** + * Creates the handler to handle the incoming connection from the + * ProcessForker. + * + * @param reaperSocket The TapeDaemon side of the socket pair used by the + * ProcessForker to report the termination of its child processes. + */ + void createAndRegisterProcessForkerConnectionHandler(const int reaperSocket); /** * The main event loop of the daemon. @@ -287,15 +427,6 @@ protected: const pid_t pid, const int waitpidStat); - /** - * Does the required post processing for the specified reaped session. - * - * @param pid The process ID of the reaped session. - * @param waitpidStat The status information given by a call to waitpid(). - */ - void handleReapedDataTransferSession(const pid_t pid, - const int waitpidStat); - /** * Does the required post processing for the specified reaped session. * @@ -375,13 +506,11 @@ protected: void forkDataTransferSession(DriveCatalogueEntry *drive) throw(); /** - * Runs the data-transfer session. This method is to be called within the - * child process responsible for running the data-transfer session. + * Gets the configuration of a data-transfer session. * - * @param drive The catalogue entry of the tape drive to be used during the - * session. + * @return The configuration. */ - void runDataTransferSession(const DriveCatalogueEntry *drive) throw(); + DataTransferSession::CastorConf getDataTransferConf(); /** * Forks a label-session child-process for every tape drive entry in the diff --git a/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp b/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp index bbe73d7f6f..2c42a7fe36 100644 --- a/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp +++ b/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp @@ -96,29 +96,54 @@ void castor::tape::tapeserver::daemon::TapeMessageHandler::fillPollFd( // handleEvent //------------------------------------------------------------------------------ bool castor::tape::tapeserver::daemon::TapeMessageHandler::handleEvent( - const zmq_pollitem_t &fd) { - checkSocket(fd); - m_log(LOG_DEBUG,"handling event in TapeMessageHandler"); - messages::Header header; + const zmq_pollitem_t &fd) throw() { + try { + checkSocket(fd); + m_log(LOG_INFO,"handling event in TapeMessageHandler"); - try{ - tape::utils::ZmqMsg headerBlob; - m_socket.recv(&headerBlob.getZmqMsg()); + messages::Header header; + try { + tape::utils::ZmqMsg headerBlob; + m_socket.recv(&headerBlob.getZmqMsg()); + + if(!zmq_msg_more(&headerBlob.getZmqMsg())){ + castor::exception::Exception ex; + ex.getMessage() << "No message body after reading the header"; + throw ex; + } - if(!zmq_msg_more(&headerBlob.getZmqMsg())){ + header = buildHeader(headerBlob); + } catch(castor::exception::Exception &ne){ castor::exception::Exception ex; - ex.getMessage() <<"Read header blob, expecting a multi parts message but nothing to come"; + ex.getMessage() << "Error handling message header: " << + ne.getMessage().str(); + throw ex; + } + + tape::utils::ZmqMsg bodyBlob; + try { + m_socket.recv(&bodyBlob.getZmqMsg()); + } catch(castor::exception::Exception &ne){ + castor::exception::Exception ex; + ex.getMessage() << "Failed to receive message body: " << + ne.getMessage().str(); throw ex; } - - header = buildHeader(headerBlob); - } - catch(const castor::exception::Exception& ex){ - m_log(LOG_ERR,"Error while dealing the message's header"); - return false; - } - dispatchEvent(header); + dispatchMsgHandler(header, bodyBlob); + + } catch(castor::exception::Exception &ex) { + log::Param params[] = {log::Param("message", ex.getMessage().str())}; + m_log(LOG_ERR, "TapeMessageHandler failed to handle event", params); + } catch(std::exception &se) { + log::Param params[] = {log::Param("message", se.what())}; + m_log(LOG_ERR, "TapeMessageHandler failed to handle event", params); + } catch(...) { + log::Param params[] = { + log::Param("message", "Caught an unknown exception")}; + m_log(LOG_ERR, "TapeMessageHandler failed to handle event", params); + } + return false; // Ask reactor to remove and delete this handler } @@ -164,115 +189,133 @@ castor::messages::Header castor::tape::tapeserver::daemon::TapeMessageHandler::b } //------------------------------------------------------------------------------ -// dispatchEvent +// dispatchMsgHandler //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeMessageHandler::dispatchEvent( - messages::Header& header) { - m_log(LOG_DEBUG,"dispatching event in TapeMessageHandler"); - tape::utils::ZmqMsg bodyBlob; - m_socket.recv(&bodyBlob.getZmqMsg()); +void castor::tape::tapeserver::daemon::TapeMessageHandler::dispatchMsgHandler( + messages::Header& header, const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO,"dispatching event in TapeMessageHandler"); switch(header.reqtype()){ - case messages::reqType::Heartbeat: + case messages::reqType::Heartbeat: + return handleHeartbeatMsg(header, bodyBlob); + case messages::reqType::NotifyDriveBeforeMountStarted: + return handleNotifyDriveBeforeMountStartedMsg(header, bodyBlob); + case messages::reqType::NotifyDriveTapeMounted: + return handleNotifyDriveTapeMountedMsg(header, bodyBlob); + case messages::reqType::NotifyDriveTapeUnmounted: + return handleNotifyDriveTapeUnmountedMsg(header, bodyBlob); + case messages::reqType::NotifyDriveUnmountStarted: + return handleNotifyDriveUnmountStartedMsg(header, bodyBlob); + default: { - castor::messages::Heartbeat body; - unserialize(body,bodyBlob); - castor::messages::checkSHA1(header,bodyBlob); - dealWith(header,body); - } - break; - case messages::reqType::NotifyDriveBeforeMountStarted: - { - castor::messages::NotifyDriveBeforeMountStarted body; - unserialize(body,bodyBlob); - castor::messages::checkSHA1(header,bodyBlob); - dealWith(header,body); - } - break; - case messages::reqType::NotifyDriveTapeMounted: - { - castor::messages::NotifyDriveTapeMounted body; - unserialize(body,bodyBlob); - castor::messages::checkSHA1(header,bodyBlob); - dealWith(header,body); + castor::exception::Exception ex; + ex.getMessage() << "Failed to dispatch message handler" + ": Unknown request type: reqtype=" << header.reqtype(); + throw ex; } - break; - case messages::reqType::NotifyDriveTapeUnmounted: - sendSuccessReplyToClient(); - break; - case messages::reqType::NotifyDriveUnmountStarted: - sendSuccessReplyToClient(); - break; - default: - m_log(LOG_ERR,"default dispatch in TapeMessageHandler"); - break; } } //------------------------------------------------------------------------------ -// dealWith +// handleHeartbeatMsg //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeMessageHandler::dealWith( -const castor::messages::Header& header, const castor::messages::Heartbeat& body){ +void castor::tape::tapeserver::daemon::TapeMessageHandler::handleHeartbeatMsg( + const messages::Header& header, const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO, "Handling Heartbeat message"); + + try { + castor::messages::Heartbeat body; + parseMsgBlob(body, bodyBlob); + castor::messages::checkSHA1(header, bodyBlob); - std::vector<log::Param> param; - param.push_back(log::Param("bytesMoved",body.bytesmoved())); - m_log(LOG_DEBUG,"IT IS ALIVE",param); + std::vector<log::Param> param; + param.push_back(log::Param("bytesMoved",body.bytesmoved())); - sendSuccessReplyToClient(); + sendSuccessReplyToClient(); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle Heartbeat message: " << + ne.getMessage().str(); + throw ex; + } } -void castor::tape::tapeserver::daemon::TapeMessageHandler::dealWith( -const castor::messages::Header& header, -const castor::messages::NotifyDriveBeforeMountStarted& body){ - m_log(LOG_INFO,"NotifyDriveBeforeMountStarted-dealWith"); - //check castor consistensy - if(body.mode()==castor::messages::TAPE_MODE_READWRITE) { - legacymsg::VmgrTapeInfoMsgBody tapeInfo; - m_vmgr.queryTape(body.vid(), tapeInfo); - // If the client is the tape gateway and the volume is not marked as BUSY - if(body.clienttype() == castor::messages::NotifyDriveBeforeMountStarted::CLIENT_TYPE_GATEWAY - && !(tapeInfo.status & TAPE_BUSY)) { - castor::exception::Exception ex; - ex.getMessage() << "The tape gateway is the client and the tape to be mounted is not BUSY: vid=" << body.vid(); +//------------------------------------------------------------------------------ +// handleNotifyDriveBeforeMountStartedMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeMessageHandler:: + handleNotifyDriveBeforeMountStartedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO, "Handling NotifyDriveBeforeMountStarted message"); + + try { + castor::messages::NotifyDriveBeforeMountStarted body; + parseMsgBlob(body, bodyBlob); + castor::messages::checkSHA1(header, bodyBlob); + + //check castor consistensy + if(body.mode()==castor::messages::TAPE_MODE_READWRITE) { + legacymsg::VmgrTapeInfoMsgBody tapeInfo; + m_vmgr.queryTape(body.vid(), tapeInfo); + // If the client is the tape gateway and the volume is not marked as BUSY + if(body.clienttype() == castor::messages::NotifyDriveBeforeMountStarted::CLIENT_TYPE_GATEWAY + && !(tapeInfo.status & TAPE_BUSY)) { + castor::exception::Exception ex; + ex.getMessage() << + "The tape gateway is the client and the tape to be mounted is not BUSY" + ": vid=" << body.vid(); - //send an error to the client - sendErrorReplyToClient(ex); - throw ex; - } + // send an error to the client + sendErrorReplyToClient(ex); + throw ex; + } - castor::messages::NotifyDriveBeforeMountStartedAnswer body; - body.set_howmanyfilesontape(tapeInfo.nbFiles); + castor::messages::NotifyDriveBeforeMountStartedAnswer body; + body.set_howmanyfilesontape(tapeInfo.nbFiles); - castor::messages::Header header = castor::messages::preFillHeader(); - header.set_reqtype(messages::reqType::NotifyDriveBeforeMountStartedAnswer); - header.set_bodyhashvalue(castor::messages::computeSHA1Base64(body)); - header.set_bodysignature("PIPO"); + castor::messages::Header header = castor::messages::preFillHeader(); + header.set_reqtype(messages::reqType::NotifyDriveBeforeMountStartedAnswer); + header.set_bodyhashvalue(castor::messages::computeSHA1Base64(body)); + header.set_bodysignature("PIPO"); - //send the number of files on the tape to the client - castor::messages::sendMessage(m_socket,header,ZMQ_SNDMORE); - castor::messages::sendMessage(m_socket,body); - } else { - //we were not event in castor::messages::TAPE_MODE_READWRITE mpde - //so send empty answer - sendSuccessReplyToClient(); + //send the number of files on the tape to the client + castor::messages::sendMessage(m_socket,header,ZMQ_SNDMORE); + castor::messages::sendMessage(m_socket,body); + } else { + //we were not event in castor::messages::TAPE_MODE_READWRITE mpde + //so send empty answer + sendSuccessReplyToClient(); + } + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << + "Failed to handle NotifyDriveBeforeMountStarted message: " << + ne.getMessage().str(); + throw ex; } } + //------------------------------------------------------------------------------ -// dealWith +// handleNotifyDriveTapeMountedMsg //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeMessageHandler::dealWith( -const castor::messages::Header& header, -const castor::messages::NotifyDriveTapeMounted& body){ - m_log(LOG_INFO,"NotifyDriveTapeMounted-dealWith"); - DriveCatalogueEntry *const drive = m_driveCatalogue.findDrive(body.unitname()); - drive->updateVolumeInfo(body); - const utils::DriveConfig &driveConfig = drive->getConfig(); +void castor::tape::tapeserver::daemon::TapeMessageHandler:: + handleNotifyDriveTapeMountedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO, "Handling NotifyDriveTapeMounted message"); + + try { + castor::messages::NotifyDriveTapeMounted body; + parseMsgBlob(body, bodyBlob); + castor::messages::checkSHA1(header, bodyBlob); + + DriveCatalogueEntry *const drive = + m_driveCatalogue.findDrive(body.unitname()); + drive->updateVolumeInfo(body); + const utils::DriveConfig &driveConfig = drive->getConfig(); - const std::string vid = body.vid(); - try - { - switch(body.mode()) { + const std::string vid = body.vid(); + try { + switch(body.mode()) { case castor::messages::TAPE_MODE_READ: m_vmgr.tapeMountedForRead(vid, drive->getSessionPid()); break; @@ -288,22 +331,67 @@ const castor::messages::NotifyDriveTapeMounted& body){ castor::exception::Exception ex; ex.getMessage() << "Unknown tape mode: " << body.mode(); throw ex; + } + m_vdqm.tapeMounted(m_hostName, body.unitname(), driveConfig.dgn, + body.vid(), drive->getSessionPid()); + } catch(const castor::exception::Exception& ex) { + sendErrorReplyToClient(ex); + throw; } - m_vdqm.tapeMounted(m_hostName, body.unitname(), driveConfig.dgn, body.vid(), - drive->getSessionPid()); - }catch(const castor::exception::Exception& ex){ - sendErrorReplyToClient(ex); - throw; + sendSuccessReplyToClient(); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle NotifyDriveTapeMounted message: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// handleNotifyDriveTapeUnmountedMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeMessageHandler:: + handleNotifyDriveTapeUnmountedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO, "Handling NotifyDriveTapeUnmounted message"); + + try { + sendSuccessReplyToClient(); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle NotifyDriveTapeUnmounted message: " << + ne.getMessage().str(); + throw ex; } - sendSuccessReplyToClient(); } + +//------------------------------------------------------------------------------ +// handleNotifyDriveUnmountStartedMsg +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::TapeMessageHandler:: + handleNotifyDriveUnmountStartedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob) { + m_log(LOG_INFO, "Handling handleNotifyDriveUnmountStarted message"); + + try { + sendSuccessReplyToClient(); + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to handle NotifyDriveUnmountStarted message: " << + ne.getMessage().str(); + throw ex; + } +} + //------------------------------------------------------------------------------ // sendSuccessReplyToClient //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeMessageHandler::sendSuccessReplyToClient(){ - castor::messages::ReturnValue body; - sendReplyToClient(0,""); +void castor::tape::tapeserver::daemon::TapeMessageHandler:: + sendSuccessReplyToClient() { + castor::messages::ReturnValue body; + sendReplyToClient(0,""); } + //------------------------------------------------------------------------------ // sendErrorReplyToClient //------------------------------------------------------------------------------ @@ -312,20 +400,21 @@ sendErrorReplyToClient(const castor::exception::Exception& ex){ //any positive value will trigger an exception in the client side sendReplyToClient(ex.code(),ex.getMessageValue()); } + //------------------------------------------------------------------------------ // sendReplyToClient //------------------------------------------------------------------------------ -void castor::tape::tapeserver::daemon::TapeMessageHandler:: -sendReplyToClient(int returnValue,const std::string& msg){ - castor::messages::ReturnValue body; - body.set_returnvalue(returnValue); - body.set_message(msg); +void castor::tape::tapeserver::daemon::TapeMessageHandler::sendReplyToClient( + const int returnValue, const std::string& msg) { + castor::messages::ReturnValue body; + body.set_returnvalue(returnValue); + body.set_message(msg); - castor::messages::Header header = castor::messages::preFillHeader(); - header.set_reqtype(messages::reqType::ReturnValue); - header.set_bodyhashvalue(castor::messages::computeSHA1Base64(body)); - header.set_bodysignature("PIPO"); + messages::Header header = castor::messages::preFillHeader(); + header.set_reqtype(messages::reqType::ReturnValue); + header.set_bodyhashvalue(messages::computeSHA1Base64(body)); + header.set_bodysignature("PIPO"); - castor::messages::sendMessage(m_socket,header,ZMQ_SNDMORE); - castor::messages::sendMessage(m_socket,body); + messages::sendMessage(m_socket, header,ZMQ_SNDMORE); + messages::sendMessage(m_socket, body); } diff --git a/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp b/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp index 5d88a984f5..fad224c97f 100644 --- a/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp +++ b/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp @@ -56,6 +56,7 @@ public: * @param driveCatalogue The tape-drive catalogue. * @param hostName The name of the host. * @param vdqm Proxy object representing the vdqmd daemon. + * @param vmgr Proxy object representing the vmgrd daemon. * @param zmqContext The ZMQ context. */ TapeMessageHandler( @@ -90,7 +91,7 @@ public: * @return true if the event handler should be removed from and deleted by * the reactor. */ - bool handleEvent(const zmq_pollitem_t &fd); + bool handleEvent(const zmq_pollitem_t &fd) throw(); private: /** @@ -117,12 +118,14 @@ private: * @param msg * @param blob */ - template <class T> void unserialize(T& msg, tape::utils::ZmqMsg& blob){ - std::string logMessage="Cant parse " ; - logMessage+=castor::utils::demangledNameOf(msg)+" from binary data. Wrong body"; - if(!msg.ParseFromArray(zmq_msg_data(&blob.getZmqMsg()),zmq_msg_size(&blob.getZmqMsg()))){ - m_log(LOG_ERR,logMessage); - } + template <class T> void parseMsgBlob(T& msg, const tape::utils::ZmqMsg& blob) { + if(!msg.ParseFromArray(blob.data(), blob.size())) { + castor::exception::Exception ex; + ex.getMessage() << "Failed to parse a " << + castor::utils::demangledNameOf(msg) << " message blob" + ": ParseFromArray() returned false"; + throw ex; + } } /** @@ -167,19 +170,58 @@ private: void checkSocket(const zmq_pollitem_t &fd); /** - * Call the right dealWith according to header.reqType() - * @param header + * Dispatches the appropriate handler method for the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. */ - void dispatchEvent(castor::messages::Header& header); - - void dealWith(const castor::messages::Header&, - const castor::messages::Heartbeat& body); - - void dealWith(const castor::messages::Header& header, - const castor::messages::NotifyDriveBeforeMountStarted& body); + void dispatchMsgHandler(castor::messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); + + /** + * Handles the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. + */ + void handleHeartbeatMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); + + /** + * Handles the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. + */ + void handleNotifyDriveBeforeMountStartedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); - void dealWith(const castor::messages::Header& header, - const castor::messages::NotifyDriveTapeMounted& body); + /** + * Handles the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. + */ + void handleNotifyDriveTapeMountedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); + + /** + * Handles the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. + */ + void handleNotifyDriveTapeUnmountedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); + + /** + * Handles the specified message. + * + * @param header The header of the message. + * @param bodyBlob The serialized body of the message. + */ + void handleNotifyDriveUnmountStartedMsg(const messages::Header& header, + const tape::utils::ZmqMsg &bodyBlob); /** * Unserialize the blob and check the header diff --git a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp index e3a600f52c..8127a5b1e5 100644 --- a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp +++ b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp @@ -71,7 +71,7 @@ void castor::tape::tapeserver::daemon::VdqmConnectionHandler::fillPollFd(zmq_pol //------------------------------------------------------------------------------ bool castor::tape::tapeserver::daemon::VdqmConnectionHandler::handleEvent( const zmq_pollitem_t &fd) { - logVdqmConnectionEvent(fd); + logConnectionEvent(fd); checkHandleEventFd(fd.fd); @@ -99,10 +99,10 @@ bool castor::tape::tapeserver::daemon::VdqmConnectionHandler::handleEvent( } //------------------------------------------------------------------------------ -// logVdqmConnectionEvent +// logConnectionEvent //------------------------------------------------------------------------------ void castor::tape::tapeserver::daemon::VdqmConnectionHandler:: - logVdqmConnectionEvent(const zmq_pollitem_t &fd) { + logConnectionEvent(const zmq_pollitem_t &fd) { log::Param params[] = { log::Param("fd", fd.fd), log::Param("ZMQ_POLLIN", fd.revents & ZMQ_POLLIN ? "true" : "false"), diff --git a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp index f58b8cbf22..0096cd8cdd 100644 --- a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp +++ b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp @@ -34,8 +34,6 @@ #include "h/vdqm_constants.h" #include "h/rtcp_constants.h" -#include <poll.h> - namespace castor { namespace tape { namespace tapeserver { @@ -70,7 +68,7 @@ public: /** * Fills the specified poll file-descriptor ready to be used in a call to - * poll(). + * zmq_poll(). */ void fillPollFd(zmq_pollitem_t &fd) throw(); @@ -118,8 +116,10 @@ private: /** * Logs the specifed IO event of the vdqm connection. + * + * @param fd File descriptor describing the event. */ - void logVdqmConnectionEvent(const zmq_pollitem_t &fd); + void logConnectionEvent(const zmq_pollitem_t &fd); /** * Throws an exception if the specified file-descriptor is not that of the diff --git a/castor/tape/utils/CMakeLists.txt b/castor/tape/utils/CMakeLists.txt index 624ffffb06..65e8390162 100644 --- a/castor/tape/utils/CMakeLists.txt +++ b/castor/tape/utils/CMakeLists.txt @@ -29,6 +29,7 @@ set (TAPE_UTILS_LIB_SRC_FILES BoolFunctor.cpp DriveConfigMap.cpp ShutdownBoolFunctor.cpp + SmartZmqContext.cpp Timer.cpp TpconfigLine.cpp utils.cpp diff --git a/castor/tape/utils/SmartZmqContext.cpp b/castor/tape/utils/SmartZmqContext.cpp new file mode 100644 index 0000000000..c46c566bef --- /dev/null +++ b/castor/tape/utils/SmartZmqContext.cpp @@ -0,0 +1,103 @@ +/****************************************************************************** + * + * 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/utils/SmartZmqContext.hpp" + +#include <errno.h> +#include <unistd.h> +#include <zmq.h> + +//----------------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------------- +castor::tape::utils::SmartZmqContext::SmartZmqContext() throw() : + m_zmqContext(NULL) { +} + +//----------------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------------- +castor::tape::utils::SmartZmqContext::SmartZmqContext(void *const zmqContext) + throw() : m_zmqContext(zmqContext) { +} + +//----------------------------------------------------------------------------- +// reset +//----------------------------------------------------------------------------- +void castor::tape::utils::SmartZmqContext::reset(void *const zmqContext) + throw() { + // If the new ZMQ context is not the one already owned + if(zmqContext != m_zmqContext) { + + // If this smart pointer still owns a ZMQ context, then terminate it + if(m_zmqContext != NULL) { + zmq_term(m_zmqContext); + } + + // Take ownership of the new ZMQ context + m_zmqContext = zmqContext; + } +} + +//----------------------------------------------------------------------------- +// SmartZmqContext assignment operator +//----------------------------------------------------------------------------- +castor::tape::utils::SmartZmqContext + &castor::tape::utils::SmartZmqContext::operator=(SmartZmqContext& obj) { + reset(obj.release()); + return *this; +} + +//----------------------------------------------------------------------------- +// destructor +//----------------------------------------------------------------------------- +castor::tape::utils::SmartZmqContext::~SmartZmqContext() throw() { + reset(); +} + +//----------------------------------------------------------------------------- +// get +//----------------------------------------------------------------------------- +void *castor::tape::utils::SmartZmqContext::get() const throw() { + return m_zmqContext; +} + +//----------------------------------------------------------------------------- +// release +//----------------------------------------------------------------------------- +void *castor::tape::utils::SmartZmqContext::release() { + // If this smart pointer does not own a ZMQ context + if(NULL == m_zmqContext) { + castor::exception::NotAnOwner ex; + ex.getMessage() << "Smart pointer does not own a ZMQ context"; + throw ex; + } + + void *const tmp = m_zmqContext; + + // A NULL value indicates this smart pointer does not own a ZMQ context + m_zmqContext = NULL; + + return tmp; +} diff --git a/castor/tape/utils/SmartZmqContext.hpp b/castor/tape/utils/SmartZmqContext.hpp new file mode 100644 index 0000000000..8be23a59f4 --- /dev/null +++ b/castor/tape/utils/SmartZmqContext.hpp @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * 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/exception/NotAnOwner.hpp" + +#include <stdio.h> + + +namespace castor { +namespace tape { +namespace utils { + +/** + * A smart pointer that owns a ZMQ context. If the smart pointer goes out of + * scope and it owns a ZMQ context, then it will terminate that context by + * calling zmq_term(). + */ +class SmartZmqContext { + +public: + + /** + * Constructor. + */ + SmartZmqContext() throw(); + + /** + * Constructor. + * + * @param zmqContext The ZMQ context to be owned by the smart pointer. + */ + SmartZmqContext(void *const zmqContext) throw(); + + /** + * Take ownership of the specified ZMQ context, terminating the previously + * owned ZMQ context if there is one and it is not the same as the one + * specified. + * + * @param zmqContext The ZMQ context to be owned, defaults to NULL if not + * specified, where NULL means this smart pointer will not own a ZMQ context + * after the reset() method returns. + */ + void reset(void *const zmqContext = NULL) throw(); + + /** + * SmartZmqContext assignment operator. + * + * This function does the following: + * <ul> + * <li> Calls release on the previous owner (obj); + * <li> Terminates the ZMQ context of this object if it already owns one. + * <li> Makes this object the owner of the ZMQ context released from the + * previous owner (obj). + * </ul> + */ + SmartZmqContext &operator=(SmartZmqContext& obj); + + /** + * Destructor. + * + * If the smart pointer owns a ZMQ context, then the destructor will + * terminate it by calling zmq_term(). + */ + ~SmartZmqContext() throw(); + + /** + * Returns the owned ZMQ context or NULL if this smart pointer does not own + * one. + * + * @return The owned ZMQ context or NULL. + */ + void *get() const throw(); + + /** + * Releases the owned ZMQ context. + * + * @return The released ZMQ context. + */ + void *release() ; + +private: + + /** + * The owned ZMQ context. A value of NULL means this smart pointer does not + * own a ZMQ context. + */ + void *m_zmqContext; + + /** + * Private copy-constructor to prevent users from trying to create a new + * copy of an object of this class. + * + * Not implemented so that it cannot be called. + */ + SmartZmqContext(const SmartZmqContext &obj) throw(); + +}; // class SmartZmqContext + +} // namespace utils +} // namespace tape +} // namespace castor + diff --git a/castor/utils/SmartFILEPtr.cpp b/castor/utils/SmartFILEPtr.cpp index 6bb04b68ed..230531cf2f 100644 --- a/castor/utils/SmartFILEPtr.cpp +++ b/castor/utils/SmartFILEPtr.cpp @@ -44,8 +44,7 @@ castor::utils::SmartFILEPtr::SmartFILEPtr(FILE *const file) throw() : //----------------------------------------------------------------------------- // reset //----------------------------------------------------------------------------- -void castor::utils::SmartFILEPtr::reset(FILE *const file = NULL) - throw() { +void castor::utils::SmartFILEPtr::reset(FILE *const file) throw() { // If the new pointer is not the one already owned if(file != m_file) { @@ -62,9 +61,8 @@ void castor::utils::SmartFILEPtr::reset(FILE *const file = NULL) //----------------------------------------------------------------------------- // SmartFILEPtr assignment operator //----------------------------------------------------------------------------- -castor::utils::SmartFILEPtr - &castor::utils::SmartFILEPtr::operator=(SmartFILEPtr& obj) - { +castor::utils::SmartFILEPtr &castor::utils::SmartFILEPtr::operator=( + SmartFILEPtr& obj) { reset(obj.release()); return *this; } @@ -86,10 +84,9 @@ FILE *castor::utils::SmartFILEPtr::get() const throw() { //----------------------------------------------------------------------------- // release //----------------------------------------------------------------------------- -FILE *castor::utils::SmartFILEPtr::release() - { +FILE *castor::utils::SmartFILEPtr::release() { // If this smart pointer does not own a pointer - if(m_file == NULL) { + if(NULL == m_file) { castor::exception::NotAnOwner ex; ex.getMessage() << "Smart pointer does not own a FILE pointer"; throw ex; diff --git a/castor/utils/SmartFILEPtr.hpp b/castor/utils/SmartFILEPtr.hpp index 9c41796bed..9003e0ff31 100644 --- a/castor/utils/SmartFILEPtr.hpp +++ b/castor/utils/SmartFILEPtr.hpp @@ -60,7 +60,7 @@ public: * specified, where NULL means this smart pointer will not own a * pointer after the reset() method returns. */ - void reset(FILE *const file) throw(); + void reset(FILE *const file = NULL) throw(); /** * SmartFILEPtr assignment operator. @@ -73,8 +73,7 @@ public: * previous owner (obj). * </ul> */ - SmartFILEPtr &operator=(SmartFILEPtr& obj) - ; + SmartFILEPtr &operator=(SmartFILEPtr& obj); /** * Destructor. -- GitLab