Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
7d1450bd
Commit
7d1450bd
authored
Apr 02, 2014
by
Daniele Kruse
Browse files
First draft of server-side tpconfig handler
parent
3ff6a95a
Changes
11
Hide whitespace changes
Inline
Side-by-side
castor/tape/legacymsg/AdminMarshal.cpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/legacymsg/AdminMarshal.cpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
*
* @author dkruse@cern.ch
*****************************************************************************/
#include
"castor/exception/Internal.hpp"
#include
"castor/io/io.hpp"
#include
"castor/tape/legacymsg/CommonMarshal.hpp"
#include
"castor/tape/legacymsg/AdminMarshal.hpp"
#include
"castor/tape/utils/utils.hpp"
#include
"h/rtcp_constants.h"
#include
"h/vdqm_constants.h"
#include
<errno.h>
#include
<string.h>
//-----------------------------------------------------------------------------
// unmarshal
//-----------------------------------------------------------------------------
void
castor
::
tape
::
legacymsg
::
unmarshal
(
const
char
*
&
src
,
size_t
&
srcLen
,
TapeMsgBody
&
dst
)
throw
(
castor
::
exception
::
Exception
)
{
io
::
unmarshalUint32
(
src
,
srcLen
,
dst
.
uid
);
io
::
unmarshalUint32
(
src
,
srcLen
,
dst
.
gid
);
io
::
unmarshalString
(
src
,
srcLen
,
dst
.
drive
);
io
::
unmarshalInt16
(
src
,
srcLen
,
dst
.
status
);
}
\ No newline at end of file
castor/tape/legacymsg/AdminMarshal.hpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/legacymsg/AdminMarshall.hpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
*
* @author dkruse@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_LEGACYMSG_ADMINMARSHAL_HPP
#define CASTOR_TAPE_LEGACYMSG_ADMINMARSHAL_HPP 1
#include
"castor/exception/Exception.hpp"
#include
"castor/tape/legacymsg/TapeMsgBody.hpp"
#include
<errno.h>
#include
<stdint.h>
#include
<string>
namespace
castor
{
namespace
tape
{
namespace
legacymsg
{
/**
* Unmarshals a message body with the specified destination structure type
* from the specified source buffer.
*
* @param src In/out parameter, before invocation points to the source
* buffer where the message body should be unmarshalled from and on return
* points to the byte in the source buffer immediately after the
* unmarshalled message body.
* @param srcLen In/our parameter, before invocation is the length of the
* source buffer from where the message body should be unmarshalled and on
* return is the number of bytes remaining in the source buffer.
* @param dst The destination message body structure.
*/
void
unmarshal
(
const
char
*
&
src
,
size_t
&
srcLen
,
TapeMsgBody
&
dst
)
throw
(
castor
::
exception
::
Exception
);
}
// namespace legacymsg
}
// namespace tape
}
// namespace castor
#endif // CASTOR_TAPE_LEGACYMSG_ADMINMARSHAL_HPP
castor/tape/legacymsg/CMakeLists.txt
View file @
7d1450bd
...
...
@@ -26,6 +26,7 @@ cmake_minimum_required (VERSION 2.6)
# Rules to build and install libcastortapelegacymsg.so
################################################################################
set
(
TAPE_LEGACYMSG_LIB_SRC_FILES
AdminMarshal.cpp
CommonMarshal.cpp
GiveOutpMsgBody.cpp
MessageHeader.cpp
...
...
@@ -38,6 +39,7 @@ set (TAPE_LEGACYMSG_LIB_SRC_FILES
RtcpSegmentAttributes.cpp
RtcpTapeRqstMsgBody.cpp
TapeBridgeMarshal.cpp
TapeMsgBody.cpp
VdqmDrvRqstMsgBody.cpp
VdqmMarshal.cpp
VmgrMarshal.cpp
...
...
castor/tape/legacymsg/TapeMsgBody.cpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/legacymsg/TapeMsgBody.cpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author dkruse@cern.ch
*****************************************************************************/
#include
"castor/tape/legacymsg/TapeMsgBody.hpp"
#include
<string.h>
castor
::
tape
::
legacymsg
::
TapeMsgBody
::
TapeMsgBody
()
throw
()
:
uid
(
0
),
gid
(
0
),
status
(
0
)
{
memset
(
drive
,
'\0'
,
sizeof
(
drive
));
}
castor/tape/legacymsg/TapeMsgBody.hpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/legacymsg/TapeMsgBody.hpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author dkruse@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_LEGACYMSG_TAPEMSGBODY_HPP
#define CASTOR_TAPE_LEGACYMSG_TAPEMSGBODY_HPP 1
#include
"castor/tape/legacymsg/RtcpErrorAppendix.hpp"
#include
"h/Castor_limits.h"
#include
"h/Cuuid.h"
#include
<stdint.h>
namespace
castor
{
namespace
tape
{
namespace
legacymsg
{
/**
* An admin command message.
*/
struct
TapeMsgBody
{
uid_t
uid
;
gid_t
gid
;
char
drive
[
CA_MAXUNMLEN
+
1
];
int16_t
status
;
/**
* Constructor.
*/
TapeMsgBody
()
throw
();
};
// struct RtcpTapeRqstMsgBody
}
// namespace legacymsg
}
// namespace tape
}
// namespace castor
#endif // CASTOR_TAPE_LEGACYMSG_TAPEMSGBODY
castor/tape/tapeserver/daemon/AdminAcceptHandler.cpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/tapeserver/daemon/AdminAcceptHandler.cpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @author dkruse@cern.ch
*****************************************************************************/
#include
"castor/exception/BadAlloc.hpp"
#include
"castor/exception/Errnum.hpp"
#include
"castor/exception/Internal.hpp"
#include
"castor/io/io.hpp"
#include
"castor/tape/tapeserver/daemon/AdminAcceptHandler.hpp"
#include
"castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp"
#include
"castor/utils/SmartFd.hpp"
#include
"h/common.h"
#include
"h/serrno.h"
#include
"h/Ctape.h"
#include
"castor/tape/legacymsg/CommonMarshal.hpp"
#include
"castor/tape/legacymsg/AdminMarshal.hpp"
#include
<vdqm_api.h>
#include
<errno.h>
#include
<memory>
#include
<string.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
AdminAcceptHandler
(
const
int
listenSock
,
io
::
PollReactor
&
reactor
,
log
::
Logger
&
log
,
Vdqm
&
vdqm
,
DriveCatalogue
&
driveCatalogue
,
const
std
::
string
&
hostName
)
throw
()
:
m_listenSock
(
listenSock
),
m_reactor
(
reactor
),
m_log
(
log
),
m_vdqm
(
vdqm
),
m_driveCatalogue
(
driveCatalogue
),
m_hostName
(
hostName
),
m_netTimeout
(
1
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::~
AdminAcceptHandler
()
throw
()
{
}
//------------------------------------------------------------------------------
// getFd
//------------------------------------------------------------------------------
int
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
getFd
()
throw
()
{
return
m_listenSock
;
}
//------------------------------------------------------------------------------
// fillPollFd
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
fillPollFd
(
struct
pollfd
&
fd
)
throw
()
{
fd
.
fd
=
m_listenSock
;
fd
.
events
=
POLLRDNORM
;
fd
.
revents
=
0
;
}
//------------------------------------------------------------------------------
// handleEvent
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
handleEvent
(
const
struct
pollfd
&
fd
)
throw
(
castor
::
exception
::
Exception
)
{
checkHandleEventFd
(
fd
.
fd
);
// Do nothing if there is no data to read
//
// POLLIN is unfortuntaley not the logical or of POLLRDNORM and POLLRDBAND
// on SLC 5. I therefore replaced POLLIN with the logical or. I also
// added POLLPRI into the mix to cover all possible types of read event.
if
(
0
==
(
fd
.
revents
&
POLLRDNORM
)
&&
0
==
(
fd
.
revents
&
POLLRDBAND
)
&&
0
==
(
fd
.
revents
&
POLLPRI
))
{
return
;
}
// Accept the connection from the admin command
castor
::
utils
::
SmartFd
connection
;
try
{
connection
.
reset
(
io
::
acceptConnection
(
fd
.
fd
,
1
));
}
catch
(
castor
::
exception
::
Exception
&
ne
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Failed to accept a connection from the admin command"
": "
<<
ne
.
getMessage
().
str
();
}
const
legacymsg
::
TapeMsgBody
job
=
readJobMsg
(
fd
.
fd
);
logAdminJobReception
(
job
);
const
std
::
string
unitName
(
job
.
drive
);
const
std
::
string
dgn
=
m_driveCatalogue
.
getDgn
(
unitName
);
if
(
CONF_UP
==
job
.
status
)
{
m_vdqm
.
setTapeDriveStatusUp
(
m_hostName
,
unitName
,
dgn
);
}
else
if
(
CONF_DOWN
==
job
.
status
)
{
m_vdqm
.
setTapeDriveStatusDown
(
m_hostName
,
unitName
,
dgn
);
}
else
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Wrong drive status requested:"
<<
job
.
status
;
throw
ex
;
}
m_reactor
.
removeHandler
(
this
);
close
(
fd
.
fd
);
}
//------------------------------------------------------------------------------
// checkHandleEventFd
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
checkHandleEventFd
(
const
int
fd
)
throw
(
castor
::
exception
::
Exception
)
{
if
(
m_listenSock
!=
fd
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Failed to accept connection from the admin command"
": Event handler passed wrong file descriptor"
": expected="
<<
m_listenSock
<<
" actual="
<<
fd
;
throw
ex
;
}
}
//------------------------------------------------------------------------------
// logAdminJobReception
//------------------------------------------------------------------------------
void
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
logAdminJobReception
(
const
legacymsg
::
TapeMsgBody
&
job
)
const
throw
()
{
log
::
Param
params
[]
=
{
log
::
Param
(
"drive"
,
job
.
drive
),
log
::
Param
(
"gid"
,
job
.
gid
),
log
::
Param
(
"uid"
,
job
.
uid
),
log
::
Param
(
"status"
,
job
.
status
)};
m_log
(
LOG_INFO
,
"Received message from admin command"
,
params
);
}
//------------------------------------------------------------------------------
// readJob
//------------------------------------------------------------------------------
castor
::
tape
::
legacymsg
::
TapeMsgBody
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
readJobMsg
(
const
int
connection
)
throw
(
castor
::
exception
::
Exception
)
{
const
legacymsg
::
MessageHeader
header
=
readJobMsgHeader
(
connection
);
const
legacymsg
::
TapeMsgBody
body
=
readJobMsgBody
(
connection
,
header
.
lenOrStatus
);
return
body
;
}
//------------------------------------------------------------------------------
// readJobMsgHeader
//------------------------------------------------------------------------------
castor
::
tape
::
legacymsg
::
MessageHeader
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
readJobMsgHeader
(
const
int
connection
)
throw
(
castor
::
exception
::
Exception
)
{
// Read in the message header
char
buf
[
3
*
sizeof
(
uint32_t
)];
// magic + request type + len
io
::
readBytes
(
connection
,
m_netTimeout
,
sizeof
(
buf
),
buf
);
const
char
*
bufPtr
=
buf
;
size_t
bufLen
=
sizeof
(
buf
);
legacymsg
::
MessageHeader
header
;
memset
(
&
header
,
'\0'
,
sizeof
(
header
));
legacymsg
::
unmarshal
(
bufPtr
,
bufLen
,
header
);
if
(
TPMAGIC
!=
header
.
magic
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Invalid admin job message: Invalid magic"
": expected=0x"
<<
std
::
hex
<<
TPMAGIC
<<
" actual=0x"
<<
header
.
magic
;
throw
ex
;
}
if
(
TPCONF
!=
header
.
reqType
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Invalid admin job message: Invalid request type"
": expected=0x"
<<
std
::
hex
<<
TPCONF
<<
" actual=0x"
<<
header
.
reqType
;
throw
ex
;
}
// The length of the message body is checked later, just before it is read in
// to memory
return
header
;
}
//------------------------------------------------------------------------------
// readJobMsgBody
//------------------------------------------------------------------------------
castor
::
tape
::
legacymsg
::
TapeMsgBody
castor
::
tape
::
tapeserver
::
daemon
::
AdminAcceptHandler
::
readJobMsgBody
(
const
int
connection
,
const
uint32_t
len
)
throw
(
castor
::
exception
::
Exception
)
{
char
buf
[
VDQM_MSGBUFSIZ
];
if
(
sizeof
(
buf
)
<
len
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Failed to read body of job message"
": Maximum body length exceeded"
": max="
<<
sizeof
(
buf
)
<<
" actual="
<<
len
;
throw
ex
;
}
try
{
io
::
readBytes
(
connection
,
m_netTimeout
,
len
,
buf
);
}
catch
(
castor
::
exception
::
Exception
&
ne
)
{
castor
::
exception
::
Internal
ex
;
ex
.
getMessage
()
<<
"Failed to read body of job message"
": "
<<
ne
.
getMessage
().
str
();
throw
ex
;
}
legacymsg
::
TapeMsgBody
body
;
const
char
*
bufPtr
=
buf
;
size_t
bufLen
=
sizeof
(
buf
);
legacymsg
::
unmarshal
(
bufPtr
,
bufLen
,
body
);
return
body
;
}
castor/tape/tapeserver/daemon/AdminAcceptHandler.hpp
0 → 100644
View file @
7d1450bd
/******************************************************************************
* castor/tape/tapeserver/daemon/AdminAcceptHandler.hpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @author dkruse@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_TAPESERVER_DAEMON_ADMINACCEPTHANDLER_HPP
#define CASTOR_TAPE_TAPESERVER_DAEMON_ADMINACCEPTHANDLER_HPP 1
#include
"castor/io/PollEventHandler.hpp"
#include
"castor/io/PollReactor.hpp"
#include
"castor/log/Logger.hpp"
#include
"castor/tape/tapeserver/daemon/DriveCatalogue.hpp"
#include
"castor/tape/tapeserver/daemon/Vdqm.hpp"
#include
"castor/tape/legacymsg/MessageHeader.hpp"
#include
"castor/tape/legacymsg/TapeMsgBody.hpp"
#include
<poll.h>
namespace
castor
{
namespace
tape
{
namespace
tapeserver
{
namespace
daemon
{
/**
* Handles the events of the socket listening for connection from the admin
* commands.
*/
class
AdminAcceptHandler
:
public
io
::
PollEventHandler
{
public:
/**
* Constructor.
*
* @param listenSock The file descriptor of the socket listening for
* connections from the vdqmd daemon.
* @param reactor The reactor to which new Vdqm connection handlers are to be
* registered.
* @param log The object representing the API of the CASTOR logging system.
* @param vdqm The object representing the vdqmd daemon.
* @param driveCatalogue The catalogue of tape drives controlled by the tape
* server daemon.
*/
AdminAcceptHandler
(
const
int
listenSock
,
io
::
PollReactor
&
reactor
,
log
::
Logger
&
log
,
Vdqm
&
vdqm
,
DriveCatalogue
&
driveCatalogue
,
const
std
::
string
&
hostName
)
throw
();
/**
* Returns the integer file descriptor of this event handler.
*/
int
getFd
()
throw
();
/**
* Fills the specified poll file-descriptor ready to be used in a call to
* poll().
*/
void
fillPollFd
(
struct
pollfd
&
fd
)
throw
();
/**
* Handles the specified event.
*
* @param fd The poll file-descriptor describing the event.
*/
void
handleEvent
(
const
struct
pollfd
&
fd
)
throw
(
castor
::
exception
::
Exception
);
/**
* Destructor.
*/
~
AdminAcceptHandler
()
throw
();
private:
/**
* Throws an exception if the specified file-descriptor is not that of the
* socket listening for connections from the vdqmd daemon.
*/
void
checkHandleEventFd
(
const
int
fd
)
throw
(
castor
::
exception
::
Exception
);
/**
* Logs the reception of the specified job message from the vdqmd daemon.
*/
void
logAdminJobReception
(
const
legacymsg
::
TapeMsgBody
&
job
)
const
throw
();
/**
* Reads a job message from the specified connection, sends back a positive
* acknowledgement and closes the connection.
*
* @param connection The file descriptor of the connection with the vdqm
* daemon.
* @return The job request from the vdqm.
*/
legacymsg
::
TapeMsgBody
readJobMsg
(
const
int
connection
)
throw
(
castor
::
exception
::
Exception
);
/**
* Reads the header of a job message from the specified connection.
*
* @param connection The file descriptor of the connection with the vdqm
* daemon.
* @return The message header.
*/
legacymsg
::
MessageHeader
readJobMsgHeader
(
const
int
connection
)
throw
(
castor
::
exception
::
Exception
);
/**
* Reads the body of a job message from the specified connection.
*
* @param connection The file descriptor of the connection with the vdqm
* daemon.
* @param len The length of the message body in bytes.
* @return The message body.
*/
legacymsg
::
TapeMsgBody
readJobMsgBody
(
const
int
connection
,
const
uint32_t
len
)
throw
(
castor
::
exception
::
Exception
);
/**
* The file descriptor of the socket listening for connections from the vdqmd
* daemon.
*/
const
int
m_listenSock
;
/**
* The reactor to which new Vdqm connection handlers are to be registered.
*/