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
adafff00
Commit
adafff00
authored
Aug 22, 2016
by
Steven Murray
Browse files
Added the cta-mediachanger-mount and dismount utilities
parent
b944306c
Changes
31
Hide whitespace changes
Inline
Side-by-side
cta.spec.in
View file @
adafff00
...
...
@@ -218,3 +218,15 @@ Scripts and utilities to faciliate working with the CTA catalogue
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-lock.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-status.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-catalogue-schema-unlock.1cta.gz
%package -n cta-mediachangerutils
Summary: Utilities to faciliate working with mediachangers
Group: Application/CTA
%description -n cta-mediachangerutils
CERN Tape Archive:
Utilities to faciliate working with the mediachangers
%files -n cta-mediachangerutils
%attr(0755,root,root) %{_bindir}/cta-mediachanger-dismount
%attr(0755,root,root) %{_bindir}/cta-mediachanger-mount
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-mediachanger-dismount.1cta.gz
%attr(0644,root,bin) %doc /usr/share/man/man1/cta-mediachanger-mount.1cta.gz
tapeserver/castor/exception/MissingOperand.cpp
View file @
adafff00
...
...
@@ -22,12 +22,11 @@
*****************************************************************************/
#include
"castor/exception/MissingOperand.hpp"
#include
"serrno.h"
// -----------------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------------
castor
::
exception
::
MissingOperand
::
MissingOperand
()
:
castor
::
exception
::
Exception
(
SEMISSINGOPER
)
{
castor
::
exception
::
Exception
(
666
)
{
}
tapeserver/castor/legacymsg/RmcProxyTcpIp.cpp
View file @
adafff00
...
...
@@ -67,8 +67,7 @@ void castor::legacymsg::RmcProxyTcpIp::mountTapeReadWrite(
castor
::
utils
::
copyString
(
rqstBody
.
vid
,
vid
);
rqstBody
.
drvOrd
=
librarySlot
.
getDrvOrd
();
rmcSendRecvNbAttempts
(
m_maxRqstAttempts
,
librarySlot
.
getRmcHostName
(),
rqstBody
);
rmcSendRecvNbAttempts
(
m_maxRqstAttempts
,
rqstBody
);
}
catch
(
castor
::
exception
::
Exception
&
ne
)
{
castor
::
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
...
...
@@ -92,8 +91,7 @@ void castor::legacymsg::RmcProxyTcpIp::dismountTape(const std::string &vid,
rqstBody
.
drvOrd
=
librarySlot
.
getDrvOrd
();
rqstBody
.
force
=
0
;
rmcSendRecvNbAttempts
(
m_maxRqstAttempts
,
librarySlot
.
getRmcHostName
(),
rqstBody
);
rmcSendRecvNbAttempts
(
m_maxRqstAttempts
,
rqstBody
);
}
catch
(
castor
::
exception
::
Exception
&
ne
)
{
castor
::
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
...
...
@@ -116,8 +114,9 @@ void castor::legacymsg::RmcProxyTcpIp::forceDismountTape(const std::string &vid,
//-----------------------------------------------------------------------------
// connectToRmc
//-----------------------------------------------------------------------------
int
castor
::
legacymsg
::
RmcProxyTcpIp
::
connectToRmc
(
const
std
::
string
&
rmcHost
)
int
castor
::
legacymsg
::
RmcProxyTcpIp
::
connectToRmc
()
const
{
const
std
::
string
rmcHost
=
"localhost"
;
castor
::
utils
::
SmartFd
smartConnectSock
;
try
{
smartConnectSock
.
reset
(
io
::
connectWithTimeout
(
rmcHost
,
m_rmcPort
,
...
...
tapeserver/castor/legacymsg/RmcProxyTcpIp.hpp
View file @
adafff00
...
...
@@ -30,8 +30,8 @@
#include
"castor/utils/utils.hpp"
#include
"h/rmc_constants.h"
#include
<sys/types.h>
#include
<unistd.h>
#include
<sys/types.h>
/*
*------------------------------------------------------------------------
...
...
@@ -39,17 +39,17 @@
*------------------------------------------------------------------------
*/
#define ERMBASEOFF 2200
/* RMC error base offset */
#define
ERMCNACT
ERMBASEOFF+1
/* Remote SCSI media changer server not active or service being drained */
#define
ERMCRBTERR
(ERMBASEOFF+2)
/* Remote SCSI media changer error */
#define
ERMCUNREC
ERMCRBTERR+1
/* Remote SCSI media changer unrec. error */
#define
ERMCSLOWR
ERMCRBTERR+2
/* Remote SCSI media changer error (slow retry) */
#define
ERMCFASTR
ERMCRBTERR+3
/* Remote SCSI media changer error (fast retry) */
#define
ERMCDFORCE
ERMCRBTERR+4
/* Remote SCSI media changer error (demount force) */
#define
ERMCDDOWN
ERMCRBTERR+5
/* Remote SCSI media changer error (drive down) */
#define
ERMCOMSGN
ERMCRBTERR+6
/* Remote SCSI media changer error (ops message) */
#define
ERMCOMSGS
ERMCRBTERR+7
/* Remote SCSI media changer error (ops message + retry) */
#define
ERMCOMSGR
ERMCRBTERR+8
/* Remote SCSI media changer error (ops message + wait) */
#define
ERMCUNLOAD
ERMCRBTERR+9
/* Remote SCSI media changer error (unload + demount) */
#define
ERMCNACT
ERMBASEOFF+1
/* Remote SCSI media changer server not active or service being drained */
#define
ERMCRBTERR
(ERMBASEOFF+2)
/* Remote SCSI media changer error */
#define
ERMCUNREC
ERMCRBTERR+1
/* Remote SCSI media changer unrec. error */
#define
ERMCSLOWR
ERMCRBTERR+2
/* Remote SCSI media changer error (slow retry) */
#define
ERMCFASTR
ERMCRBTERR+3
/* Remote SCSI media changer error (fast retry) */
#define
ERMCDFORCE
ERMCRBTERR+4
/* Remote SCSI media changer error (demount force) */
#define
ERMCDDOWN
ERMCRBTERR+5
/* Remote SCSI media changer error (drive down) */
#define
ERMCOMSGN
ERMCRBTERR+6
/* Remote SCSI media changer error (ops message) */
#define
ERMCOMSGS
ERMCRBTERR+7
/* Remote SCSI media changer error (ops message + retry) */
#define
ERMCOMSGR
ERMCRBTERR+8
/* Remote SCSI media changer error (ops message + wait) */
#define
ERMCUNLOAD
ERMCRBTERR+9
/* Remote SCSI media changer error (unload + demount) */
#define ERMMAXERR ERMBASEOFF+11
namespace
castor
{
...
...
@@ -153,10 +153,11 @@ protected:
/**
* Connects to the rmcd daemon.
*
* @param rmcHost The name of the host on which the rmcd daemon is running.
* Please note that the rmcd daemon only listens on loopback interface.
*
* @return The socket-descriptor of the connection with the rmcd daemon.
*/
int
connectToRmc
(
const
std
::
string
&
rmcHost
)
const
;
int
connectToRmc
()
const
;
/**
* Writes an RMC_SCSI_MOUNT message with the specifed body to the specified
...
...
@@ -190,14 +191,13 @@ protected:
* reached.
*
* @param maxAttempts The maximum number of retriable attempts.
* @param rmcHost The name of the host on which the rmcd daemon is running.
* @param rqstBody The request to be sent.
*/
template
<
typename
T
>
void
rmcSendRecvNbAttempts
(
const
int
maxAttempts
,
const
std
::
string
&
rmcHost
,
const
T
&
rqstBody
)
{
const
T
&
rqstBody
)
{
for
(
int
attemptNb
=
1
;
attemptNb
<=
maxAttempts
;
attemptNb
++
)
{
std
::
ostringstream
rmcErrorStream
;
const
int
rmcRc
=
rmcSendRecv
(
rmcHost
,
rqstBody
,
rmcErrorStream
);
const
int
rmcRc
=
rmcSendRecv
(
rqstBody
,
rmcErrorStream
);
switch
(
rmcRc
)
{
case
0
:
// Success
return
;
...
...
@@ -232,16 +232,15 @@ protected:
/**
* Sends the specified request to the rmcd daemon and receives the reply.
*
* @param rmcHost The name of the host on which the rmcd daemon is running.
* @param rqstBody The request to be sent.
* @param rmcErrorStream The error stream constructed from ERR_MSG received
* within the reply from the rmcd daemon.
* @param The RMC return code.
*/
template
<
typename
T
>
int
rmcSendRecv
(
const
std
::
string
&
rmcHost
,
const
T
&
rqstBody
,
std
::
ostringstream
&
rmcErrorStream
)
{
template
<
typename
T
>
int
rmcSendRecv
(
const
T
&
rqstBody
,
std
::
ostringstream
&
rmcErrorStream
)
{
// Connect to rmcd and send request
castor
::
utils
::
SmartFd
fd
(
connectToRmc
(
rmcHost
));
castor
::
utils
::
SmartFd
fd
(
connectToRmc
());
{
char
buf
[
RMC_MSGBUFSIZ
];
const
size_t
len
=
marshal
(
buf
,
rqstBody
);
...
...
tapeserver/castor/mediachanger/CMakeLists.txt
View file @
adafff00
...
...
@@ -14,12 +14,12 @@
# 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
#
cmake_minimum_required
(
VERSION 2.6
)
include_directories
(
${
CMAKE_SOURCE_DIR
}
/tapeserver
)
include_directories
(
${
PROJECT_BINARY_DIR
}
/tapeserver
)
set
(
MEDIA_CHANGER_LIB_SRC_FILES
AcsLibrarySlot.cpp
...
...
@@ -37,3 +37,46 @@ add_library(ctamediachanger ${MEDIA_CHANGER_LIB_SRC_FILES})
add_library
(
ctamediachangerutils SHARED
MmcProxyDummy.cpp
)
install
(
TARGETS ctamediachangerutils DESTINATION usr/
${
CMAKE_INSTALL_LIBDIR
}
)
set
(
MEDIA_CHANGER_MOUNT_SRC_FILES
CmdLine.cpp
CmdLineTool.cpp
DebugBuf.cpp
MountCmd.cpp
MountCmdLine.cpp
MountCmdMain.cpp
)
add_executable
(
cta-mediachanger-mount
${
MEDIA_CHANGER_MOUNT_SRC_FILES
}
)
set_target_properties
(
cta-mediachanger-mount PROPERTIES
COMPILE_FLAGS -I/usr/include/CDK
COMPILE_DEFINITIONS LINUX
)
target_link_libraries
(
cta-mediachanger-mount
ctacommon
ctalegacymsg
ctamediachanger
ctamessages
ctautils
ctaio
)
install
(
TARGETS cta-mediachanger-mount DESTINATION /usr/bin
)
install
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/cta-mediachanger-mount.1cta DESTINATION /usr/share/man/man1
)
set
(
MEDIA_CHANGER_DISMOUNT_SRC_FILES
CmdLine.cpp
CmdLineTool.cpp
DebugBuf.cpp
DismountCmd.cpp
DismountCmdLine.cpp
DismountCmdMain.cpp
)
add_executable
(
cta-mediachanger-dismount
${
MEDIA_CHANGER_DISMOUNT_SRC_FILES
}
)
set_target_properties
(
cta-mediachanger-dismount PROPERTIES
COMPILE_FLAGS -I/usr/include/CDK
COMPILE_DEFINITIONS LINUX
)
target_link_libraries
(
cta-mediachanger-dismount
ctacommon
ctalegacymsg
ctamediachanger
ctamessages
ctautils
ctaio
)
install
(
TARGETS cta-mediachanger-dismount DESTINATION /usr/bin
)
install
(
FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/cta-mediachanger-dismount.1cta DESTINATION /usr/share/man/man1
)
tapeserver/castor/mediachanger/CmdLine.cpp
View file @
adafff00
...
...
@@ -24,6 +24,7 @@
#include
"castor/mediachanger/CmdLine.hpp"
#include
"castor/exception/InvalidArgument.hpp"
#include
"castor/exception/MissingOperand.hpp"
#include
<getopt.h>
//------------------------------------------------------------------------------
// handleMissingParameter
...
...
tapeserver/castor/mediachanger/CmdLineTool.cpp
0 → 100644
View file @
adafff00
/******************************************************************************
*
* 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/mediachanger/CmdLineTool.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
CmdLineTool
::
CmdLineTool
(
std
::
istream
&
inStream
,
std
::
ostream
&
outStream
,
std
::
ostream
&
errStream
,
MediaChangerFacade
&
mc
)
throw
()
:
m_in
(
inStream
),
m_out
(
outStream
),
m_err
(
errStream
),
m_mc
(
mc
),
m_debugBuf
(
outStream
),
m_dbg
(
&
m_debugBuf
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
CmdLineTool
::~
CmdLineTool
()
throw
()
{
}
//------------------------------------------------------------------------------
// bool2Str
//------------------------------------------------------------------------------
std
::
string
castor
::
mediachanger
::
CmdLineTool
::
bool2Str
(
const
bool
value
)
const
throw
()
{
return
value
?
"TRUE"
:
"FALSE"
;
}
tapeserver/castor/mediachanger/CmdLineTool.hpp
0 → 100644
View file @
adafff00
/******************************************************************************
*
* 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/mediachanger/MediaChangerFacade.hpp"
#include
"castor/mediachanger/DebugBuf.hpp"
#include
<istream>
#include
<ostream>
#include
<string>
namespace
castor
{
namespace
mediachanger
{
/**
* Abstract class implementing common code and data structures for a
* command-line tool.
*/
class
CmdLineTool
{
public:
/**
* Constructor.
*
* @param inStream Standard input stream.
* @param outStream Standard output stream.
* @param errStream Standard error stream.
* @param mc Interface to the media changer.
*/
CmdLineTool
(
std
::
istream
&
inStream
,
std
::
ostream
&
outStream
,
std
::
ostream
&
errStream
,
MediaChangerFacade
&
mc
)
throw
();
/**
* Pure-virtual destructor to guarantee this class is abstract.
*/
virtual
~
CmdLineTool
()
throw
()
=
0
;
protected:
/**
* Standard input stream.
*/
std
::
istream
&
m_in
;
/**
* Standard output stream.
*/
std
::
ostream
&
m_out
;
/**
* Standard error stream.
*/
std
::
ostream
&
m_err
;
/**
* Interface to the media changer.
*/
MediaChangerFacade
&
m_mc
;
/**
* Debug stream buffer that inserts a standard debug preamble before each
* message-line written to it.
*/
DebugBuf
m_debugBuf
;
/**
* Stream used to write debug messages.
*
* This stream will insert a standard debug preamble before each message-line
* written to it.
*/
std
::
ostream
m_dbg
;
/**
* Returns the string representation of the specfied boolean value.
*
* @param value The boolean value.
*/
std
::
string
bool2Str
(
const
bool
value
)
const
throw
();
};
// class CmdLineTool
}
// namespace mediachanger
}
// namespace castor
tapeserver/castor/mediachanger/DebugBuf.cpp
0 → 100644
View file @
adafff00
/******************************************************************************
*
* 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/mediachanger/DebugBuf.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
DebugBuf
::
DebugBuf
(
std
::
ostream
&
os
)
:
m_debug
(
false
),
m_os
(
os
),
m_writePreamble
(
true
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
DebugBuf
::~
DebugBuf
()
{
}
//------------------------------------------------------------------------------
// setDebug
//------------------------------------------------------------------------------
void
castor
::
mediachanger
::
DebugBuf
::
setDebug
(
const
bool
value
)
throw
()
{
m_debug
=
value
;
}
//------------------------------------------------------------------------------
// overflow
//------------------------------------------------------------------------------
std
::
streambuf
::
int_type
castor
::
mediachanger
::
DebugBuf
::
overflow
(
const
int_type
c
)
{
// Only write something if debug mode is on
if
(
m_debug
)
{
if
(
m_writePreamble
)
{
writePreamble
();
m_writePreamble
=
false
;
}
m_os
<<
(
char
)
c
;
}
// If an end of line was encountered then the next write should be preceeded
// with a preamble
if
(
'\n'
==
(
char
)
c
)
{
m_writePreamble
=
true
;
}
return
c
;
}
//------------------------------------------------------------------------------
// writePreamble
//------------------------------------------------------------------------------
void
castor
::
mediachanger
::
DebugBuf
::
writePreamble
()
throw
()
{
m_os
<<
"DEBUG: "
;
}
tapeserver/castor/mediachanger/DebugBuf.hpp
0 → 100644
View file @
adafff00
/******************************************************************************
*
* 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
<ostream>
#include
<streambuf>
namespace
castor
{
namespace
mediachanger
{
/**
* Stream buffer class used to prepend a standard preamble to debug
* message-lines.
*
* This stream buffer does not write any output if debug mode has not been
* turned on by calling setDebugMode(true). Any debug message written to this
* stream buffer will be discarded if debug mode is off.
*/
class
DebugBuf
:
public
std
::
streambuf
{
public:
/**
* Constructor.
*
* Initialises the the debug mode to be off.
*
* @param os The output stream to which each debug message-line togther with
* its standard preamble shall be written.
*/
DebugBuf
(
std
::
ostream
&
os
);
/**
* Destructor.
*/
~
DebugBuf
();
/**
* Set the debug mode to be on (true) or off (false).
*
* The default set in the constructor is off (false).
*/
void
setDebug
(
const
bool
value
)
throw
();
protected:
/**
* Sends the specified character to the output channnel.
*/
int_type
overflow
(
const
int_type
c
);
/**
* Writes the standard preamble to the output stream.
*/
void
writePreamble
()
throw
();
private:
/**
* True if debug mode is on.
*/
bool
m_debug
;
/**
* The output stream to which each debug message-line togther with its
* standard preamble shall be written.
*/
std
::
ostream
&
m_os
;
/**
* True is a preamble should be written.
*/
bool
m_writePreamble
;
};
// class DebugBuf
}
// namespace mediachanger
}
// namespace castor
tapeserver/castor/mediachanger/DismountCmd.cpp
0 → 100644
View file @
adafff00
/******************************************************************************
*
* 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/mediachanger/DismountCmd.hpp"
#include
<getopt.h>
#include
<iostream>
#include
<memory>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
DismountCmd
::
DismountCmd
(
std
::
istream
&
inStream
,
std
::
ostream
&
outStream
,
std
::
ostream
&
errStream
,
MediaChangerFacade
&
mc
)
throw
()
:
CmdLineTool
(
inStream
,
outStream
,
errStream
,
mc
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor
::
mediachanger
::
DismountCmd
::~
DismountCmd
()
throw
()
{
// Do nothing
}
//------------------------------------------------------------------------------
// exceptionThrowingMain
//------------------------------------------------------------------------------
int
castor
::
mediachanger
::
DismountCmd
::
exceptionThrowingMain
(
const
int
argc
,
char
*
const
*
const
argv
)
{
try
{
m_cmdLine
=
DismountCmdLine
(
argc
,
argv
);
}
catch
(
castor
::
exception
::
Exception
&
ex
)
{
m_err
<<
ex
.
getMessage
().
str
()
<<
std
::
endl
;