Commit d31fdf33 authored by Eric Cano's avatar Eric Cano
Browse files

Moved Errnum exception and related thrower helper functions to the main castor exceptions location.

Adapted the tape code.
Moved the Errnum unit tests and covered all the throwers.
parent 487b48c8
/******************************************************************************
* Errnum.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 castor dev team
*****************************************************************************/
#include "Errnum.hpp"
#include <errno.h>
#include <string.h>
using namespace castor::exception;
Errnum::Errnum(std::string what):Exception("") {
m_errnum = errno;
ErrnumConstructorBottomHalf(what);
}
Errnum::Errnum(int err, std::string what):Exception("") {
m_errnum = err;
ErrnumConstructorBottomHalf(what);
}
void Errnum::ErrnumConstructorBottomHalf(const std::string & what) {
char s[1000];
/* _XOPEN_SOURCE seems not to work. */
char * errorStr = ::strerror_r(m_errnum, s, sizeof(s));
if (!errorStr) {
int new_errno = errno;
std::stringstream w;
w << "Errno=" << m_errnum << ". In addition, failed to read the corresponding error string (strerror gave errno="
<< new_errno << ")";
m_strerror = w.str();
} else {
m_strerror = errorStr;
}
std::stringstream w2;
if (what.size())
w2 << what << " ";
w2 << "Errno=" << m_errnum << ": " << m_strerror;
getMessage().str(w2.str());
}
void Errnum::throwOnReturnedErrno (int err, std::string context) {
if (err) throw Errnum(err, context);
}
void Errnum::throwOnNonZero(int status, std::string context) {
if (status) throw Errnum(context);
}
void Errnum::throwOnZero(int status, std::string context) {
if (!status) throw Errnum(context);
}
void Errnum::throwOnNull(void * f, std::string context) {
if (NULL == f) throw Errnum(context);
}
void Errnum::throwOnNegative(int ret, std::string context) {
if (ret < 0) throw Errnum(context);
}
void Errnum::throwOnMinusOne(int ret, std::string context) {
if (-1 == ret) throw Errnum(context);
}
/******************************************************************************
* Errnum.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 castor dev team
*****************************************************************************/
#pragma once
#include "Exception.hpp"
namespace castor {
namespace exception {
class Errnum: public castor::exception::Exception {
public:
Errnum(std::string what = "");
Errnum (int err, std::string what = "");
virtual ~Errnum() throw() {};
int ErrorNumber() { return m_errnum; }
std::string strError() { return m_strerror; }
static void throwOnReturnedErrno(int err, std::string context = "");
static void throwOnNonZero(int status, std::string context = "");
static void throwOnZero(int status, std::string context = "");
static void throwOnNull(void * f, std::string context = "");
static void throwOnNegative(int ret, std::string context = "");
static void throwOnMinusOne(int ret, std::string context = "");
protected:
void ErrnumConstructorBottomHalf(const std::string & what);
int m_errnum;
std::string m_strerror;
};
}
}
\ No newline at end of file
......@@ -29,7 +29,14 @@
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::exception::Exception::Exception(int se) : m_serrno(se) {}
castor::exception::Exception::Exception(int se, std::string context) :
m_message(context), m_serrno(se){}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::exception::Exception::Exception(std::string context) :
m_message(context), m_serrno(0){}
//------------------------------------------------------------------------------
// copy constructor
......
......@@ -47,9 +47,18 @@ namespace castor {
/**
* Empty Constructor
* @param serrno the serrno code of the corresponding C error
* @param context optional context string added to the message
* at initialisation time.
*/
Exception(int se);
Exception(int se, std::string context="");
/**
* Empty Constructor with implicit serrno = 0;
* @param context optional context string added to the message
* at initialisation time.
*/
Exception(std::string context="");
/**
* Copy Constructor
*/
......
/******************************************************************************
* ExceptionTest.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 Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "Exception.hpp"
#include "Errnum.hpp"
#include <errno.h>
#include <gtest/gtest.h>
#include <gmock/gmock-cardinalities.h>
namespace UnitTests {
class Nested {
public:
void f1();
void f2();
Nested();
};
/* Prevent inlining: it makes this test fail! */
void __attribute__((noinline)) Nested::f1() {
throw castor::exception::Exception("Throwing in Nested::f1()");
}
/* Prevent inlining: it makes this test fail!
* Even with that, f2 does not show up in the trace */
void __attribute__((noinline)) Nested::f2() {
f1();
}
/* Prevent inlining: it makes this test fail! */
__attribute__((noinline)) Nested::Nested() {
f2();
}
TEST(castor_exceptions, stacktrace_with_demangling) {
try {
Nested x;
} catch (castor::exception::Exception & e) {
std::string bt = e.backtrace();
ASSERT_NE(std::string::npos, bt.find("Nested::f1"));
ASSERT_NE(std::string::npos, bt.find("castor::exception::Backtrace::Backtrace"));
ASSERT_EQ("Throwing in Nested::f1()", std::string(e.getMessageValue()));
std::string fullWhat(e.what());
ASSERT_NE(std::string::npos, fullWhat.find("Nested::f2"));
}
}
TEST(castor_exceptions, stacktrace_in_std_exception) {
try {
Nested x;
} catch (std::exception & e) {
std::string fullWhat(e.what());
ASSERT_NE(std::string::npos, fullWhat.find("Nested::f2"));
ASSERT_NE(std::string::npos, fullWhat.find("Throwing in Nested::f1()"));
}
}
TEST(castor_exceptions, errnum_throwing) {
/* Mickey Mouse test as we had trouble which throwing Errnum (with errno=ENOENT)*/
errno = ENOENT;
try {
throw castor::exception::Errnum("Test ENOENT");
} catch (std::exception & e) {
std::string temp = e.what();
temp += " ";
}
}
TEST(castor_exceptions, Errnum_throwers) {
/* throwOnReturnedErrno */
ASSERT_NO_THROW(castor::exception::Errnum::throwOnReturnedErrno(0, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnReturnedErrno(ENOSPC, "Context"),
castor::exception::Errnum);
/* throwOnNonZero */
errno = ENOENT;
ASSERT_NO_THROW(castor::exception::Errnum::throwOnNonZero(0, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnNonZero(-1, "Context"),
castor::exception::Errnum);
/* throwOnMinusOne */
errno = ENOENT;
ASSERT_NO_THROW(castor::exception::Errnum::throwOnMinusOne(0, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnMinusOne(-1, "Context"),
castor::exception::Errnum);
/* throwOnNegative */
errno = ENOENT;
ASSERT_NO_THROW(castor::exception::Errnum::throwOnNegative(0, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnNegative(-1, "Context"),
castor::exception::Errnum);
/* throwOnNull */
errno = ENOENT;
ASSERT_NO_THROW(castor::exception::Errnum::throwOnNull(this, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnNull(NULL, "Context"),
castor::exception::Errnum);
/* throwOnZero */
errno = ENOENT;
ASSERT_NO_THROW(castor::exception::Errnum::throwOnZero(1, "Context"));
ASSERT_THROW(castor::exception::Errnum::throwOnZero(0, "Context"),
castor::exception::Errnum);
}
}
\ No newline at end of file
......@@ -26,6 +26,7 @@
#include <scsi/sg.h>
#include "Device.hpp"
#include "castor/exception/Errnum.hpp"
using namespace castor::tape;
......@@ -39,8 +40,10 @@ SCSI::DeviceVector::DeviceVector(System::virtualWrapper& sysWrapper) : m_sysWrap
std::string sysDevsPath = "/sys/bus/scsi/devices";
utils::Regex ifFirstCharIsDigit("^[[:digit:]]");
std::vector<std::string> checkResult;
DIR* dirp = m_sysWrapper.opendir(sysDevsPath.c_str());
if (!dirp) throw exceptions::Errnum("Error opening sysfs scsi devs");
DIR* dirp;
castor::exception::Errnum::throwOnNull(
dirp = m_sysWrapper.opendir(sysDevsPath.c_str()),
"Error opening sysfs scsi devs");
while (struct dirent * dent = m_sysWrapper.readdir(dirp)) {
std::string dn(dent->d_name);
if ("." == dn || ".." == dn) continue;
......@@ -49,27 +52,29 @@ SCSI::DeviceVector::DeviceVector(System::virtualWrapper& sysWrapper) : m_sysWrap
std::string fullpath = sysDevsPath + "/" + std::string(dent->d_name);
/* We expect only symbolic links in this directory, */
char rp[PATH_MAX];
if (NULL == m_sysWrapper.realpath(fullpath.c_str(), rp))
throw exceptions::Errnum("Could not find realpath for " + fullpath);
castor::exception::Errnum::throwOnNull(
m_sysWrapper.realpath(fullpath.c_str(), rp),
"Could not find realpath for " + fullpath);
this->push_back(getDeviceInfo(rp));
}
sysWrapper.closedir(dirp);
}
std::string SCSI::DeviceVector::readfile(std::string path) {
int fd = m_sysWrapper.open(path.c_str(), 0);
if (-1 == fd) {
throw exceptions::Errnum("Could not open file " + path);
}
int fd;
castor::exception::Errnum::throwOnMinusOne(
fd = m_sysWrapper.open(path.c_str(), 0),
std::string("Could not open file ") + path);
char buf[readfileBlockSize];
std::string ret;
while (ssize_t sread = m_sysWrapper.read(fd, buf, readfileBlockSize)) {
if (-1 == sread)
throw exceptions::Errnum("Could not read from open file " + path);
castor::exception::Errnum::throwOnMinusOne(sread,
std::string("Could not read from open file ") + path);
ret.append(buf, sread);
}
if (m_sysWrapper.close(fd))
throw exceptions::Errnum("Error closing file " + path);
castor::exception::Errnum::throwOnNonZero(
m_sysWrapper.close(fd),
std::string("Error closing file ") + path);
return ret;
}
......@@ -83,8 +88,9 @@ SCSI::DeviceInfo::DeviceFile SCSI::DeviceVector::readDeviceFile(std::string path
SCSI::DeviceInfo::DeviceFile SCSI::DeviceVector::statDeviceFile(std::string path) {
struct stat sbuf;
if (m_sysWrapper.stat(path.c_str(), &sbuf))
throw exceptions::Errnum("Could not stat file " + path);
castor::exception::Errnum::throwOnNonZero(
m_sysWrapper.stat(path.c_str(), &sbuf),
std::string("Could not stat file ") + path);
if (!S_ISCHR(sbuf.st_mode))
throw Exception("Device file " + path + " is not a character device");
DeviceInfo::DeviceFile ret;
......@@ -114,15 +120,13 @@ void SCSI::DeviceVector::getTapeInfo(DeviceInfo & devinfo) {
if (!dirp) {
/* here we open sysfs_entry for SLC5 */
dirp = m_sysWrapper.opendir(devinfo.sysfs_entry.c_str());
if (!dirp) throw exceptions::Errnum(
std::string("Error opening tape device directory ") +
devinfo.sysfs_entry + tapeDir+" or "+devinfo.sysfs_entry);
else {
/* we are not on SLC6 */
scsiPrefix="^scsi_tape:";
tapeDir ="";
}
castor::exception::Errnum::throwOnNull(
dirp = m_sysWrapper.opendir(devinfo.sysfs_entry.c_str()),
std::string("Error opening tape device directory ") +
devinfo.sysfs_entry + tapeDir+" or "+devinfo.sysfs_entry);
/* we are not on SLC6 */
scsiPrefix="^scsi_tape:";
tapeDir ="";
}
utils::Regex st_re((scsiPrefix+"(st[[:digit:]]+)$").c_str());
......@@ -216,8 +220,9 @@ SCSI::DeviceInfo SCSI::DeviceVector::getDeviceInfo(const char * path) {
char rl[PATH_MAX];
std::string lp = ret.sysfs_entry + "/generic";
ssize_t rlSize;
if (-1 == (rlSize = m_sysWrapper.readlink(lp.c_str(), rl, sizeof (rl) - 1)))
throw exceptions::Errnum("Could not read link " + lp);
castor::exception::Errnum::throwOnMinusOne(
rlSize = m_sysWrapper.readlink(lp.c_str(), rl, sizeof (rl) - 1),
std::string("Could not read link ") + lp);
rl[rlSize] = '\0';
std::string gl(rl);
size_t pos = gl.find_last_of("/");
......
......@@ -36,6 +36,7 @@
#include "castor/log/LoggerImplementation.hpp"
#include "log.h"
#include "castor/io/AbstractSocket.hpp"
#include "castor/exception/Errnum.hpp"
int main(int argc, char ** argv) {
return castor::tape::Server::Daemon::main(argc, argv);
......@@ -136,7 +137,7 @@ void castor::tape::Server::Daemon::daemonize()
if (getppid() == 1) return;
/* Fork off the parent process */
castor::tape::exceptions::throwOnNegativeWithErrno(pid = fork(),
castor::exception::Errnum::throwOnNegative(pid = fork(),
"Failed to fork in castor::tape::Server::Daemon::daemonize");
/* If we got a good PID, then we can exit the parent process. */
if (pid > 0) {
......@@ -145,7 +146,7 @@ void castor::tape::Server::Daemon::daemonize()
/* Change the file mode mask */
umask(0);
/* Create a new session for the child process */
castor::tape::exceptions::throwOnNegativeWithErrno(sid = setsid(),
castor::exception::Errnum::throwOnNegative(sid = setsid(),
"Failed to create new session in castor::tape::Server::Daemon::daemonize");
/* At this point we are executing as the child process, and parent process should be init */
if (getppid() != 1) {
......@@ -154,18 +155,18 @@ void castor::tape::Server::Daemon::daemonize()
}
/* Change the current working directory. This prevents the current
directory from being locked; hence not being able to remove it. */
castor::tape::exceptions::throwOnNegativeWithErrno(
castor::exception::Errnum::throwOnNegative(
chdir(m_option_run_directory.c_str()),
std::string("Failed to chdir in castor::tape::Server::Daemon::daemonize"
" ( destination directory: ") + m_option_run_directory + ")");
/* Redirect standard files to /dev/null */
castor::tape::exceptions::throwOnNullWithErrno(
castor::exception::Errnum::throwOnNull(
freopen("/dev/null", "r", stdin),
"Failed to freopen stdin in castor::tape::Server::Daemon::daemonize");
castor::tape::exceptions::throwOnNullWithErrno(
castor::exception::Errnum::throwOnNull(
freopen("/dev/null", "r", stdout),
"Failed to freopen stdout in castor::tape::Server::Daemon::daemonize");
castor::tape::exceptions::throwOnNullWithErrno(
castor::exception::Errnum::throwOnNull(
freopen("/dev/null", "r", stderr),
"Failed to freopen stderr in castor::tape::Server::Daemon::daemonize");
}
......@@ -192,7 +193,7 @@ void castor::tape::Server::Daemon::blockSignals()
sigaddset(&sigs, SIGPOLL);
sigaddset(&sigs, SIGURG);
sigaddset(&sigs, SIGVTALRM);
castor::tape::exceptions::throwOnNonZeroWithErrno(
castor::exception::Errnum::throwOnNonZero(
sigprocmask(SIG_BLOCK, &sigs, NULL),
"Failed to sigprocmask in castor::tape::Server::Daemon::blockSignals");
}
......@@ -4,7 +4,7 @@ set_property(SOURCE Drive.cpp
)
add_executable(TapeDriveReadWriteTest TapeDriveReadWriteTest.cpp)
target_link_libraries(TapeDriveReadWriteTest TapeDrive Exception SCSI System Utils castorcommon ${GTEST_LIBRARY} gmock pthread)
target_link_libraries(TapeDriveReadWriteTest TapeDrive Exception SCSI System Utils
castorcommon castorclient ${GTEST_LIBRARY} gmock pthread)
#install(TARGETS TapeDriveReadWriteTest
# RUNTIME DESTINATION bin)
......@@ -23,6 +23,7 @@
*****************************************************************************/
#include "Drive.hpp"
#include "castor/exception/Errnum.hpp"
using namespace castor::tape;
......@@ -32,12 +33,13 @@ m_tapeFD(-1), m_sysWrapper(sw) {
/* We open the tape device file non-blocking as blocking open on rewind tapes (at least)
* will fail after a long timeout when no tape is present (at least with mhvtl)
*/
m_tapeFD = m_sysWrapper.open(m_SCSIInfo.nst_dev.c_str(), O_RDWR | O_NONBLOCK);
if (-1 == m_tapeFD)
throw exceptions::Errnum(std::string("Could not open device file: " + m_SCSIInfo.nst_dev));
castor::exception::Errnum::throwOnMinusOne(
m_tapeFD = m_sysWrapper.open(m_SCSIInfo.nst_dev.c_str(), O_RDWR | O_NONBLOCK),
std::string("Could not open device file: ") + m_SCSIInfo.nst_dev);
/* Read drive status */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, MTIOCGET, &m_mtInfo))
throw exceptions::Errnum(std::string("Could not read drive status: " + m_SCSIInfo.nst_dev));
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, MTIOCGET, &m_mtInfo),
std::string("Could not read drive status: ") + m_SCSIInfo.nst_dev);
}
/**
......@@ -58,8 +60,9 @@ void drives::DriveGeneric::clearCompressionStats() throw (Exception) {
sgh.dxfer_direction = SG_DXFER_NONE;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::clearCompressionStats");
SCSI::ExceptionLauncher(sgh, "SCSI error in clearCompressionStats:");
}
......@@ -80,8 +83,9 @@ drives::deviceInfo drives::DriveGeneric::getDeviceInfo() throw (Exception) {
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::getDeviceInfo");
SCSI::ExceptionLauncher(sgh, std::string("SCSI error in getDeviceInfo: ") +
SCSI::statusToString(sgh.status));
......@@ -114,8 +118,9 @@ std::string drives::DriveGeneric::getSerialNumber() throw (Exception) {
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::getSerialNumber");
SCSI::ExceptionLauncher(sgh, std::string("SCSI error in getSerialNumber: ") +
SCSI::statusToString(sgh.status));
std::string serialNumber;
......@@ -147,8 +152,9 @@ throw (Exception) {
sgh.timeout = 180000; // TODO castor.conf LOCATE_TIMEOUT or default
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::positionToLogicalObject");
SCSI::ExceptionLauncher(sgh, "SCSI error in positionToLogicalObject:");
}
......@@ -173,8 +179,9 @@ throw (Exception) {
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::getPositionInfo");
SCSI::ExceptionLauncher(sgh, std::string("SCSI error in getPositionInfo: ") +
SCSI::statusToString(sgh.status));
......@@ -218,8 +225,9 @@ std::vector<std::string> drives::DriveGeneric::getTapeAlerts() throw (Exception)
sgh.setSenseBuffer(&senseBuff);
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::getTapeAlerts");
SCSI::ExceptionLauncher(sgh, std::string("SCSI error in getTapeAlerts: ") +
SCSI::statusToString(sgh.status));
/* Return the ACTIVE tape alerts (this is indicated by "flag" (see
......@@ -264,8 +272,9 @@ void drives::DriveGeneric::setDensityAndCompression(unsigned char densityCode,
sgh.dxfer_direction = SG_DXFER_FROM_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::setDensityAndCompression");
SCSI::ExceptionLauncher(sgh,
std::string("SCSI error in setDensityAndCompression: ") +
SCSI::statusToString(sgh.status));
......@@ -290,8 +299,9 @@ void drives::DriveGeneric::setDensityAndCompression(unsigned char densityCode,
sgh.dxfer_direction = SG_DXFER_TO_DEV;
/* Manage both system error and SCSI errors. */
if (-1 == m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh))
throw exceptions::Errnum("Failed SG_IO ioctl");
castor::exception::Errnum::throwOnMinusOne(
m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
"Failed SG_IO ioctl in DriveGeneric::setDensityAndCompression");
SCSI::ExceptionLauncher(sgh,
std::string("SCSI error in setDensityAndCompression: ") +
SCSI::statusToString(sgh.status));
......@@ -308,8 +318,9 @@ void drives::DriveGeneric::setSTBufferWrite(bool bufWrite) throw (Exception) {
struct mtop m_mtCmd;
m_mtCmd.mt_op = MTSETDRVBUFFER;