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
c8408633
Commit
c8408633
authored
Jun 11, 2018
by
Anastasia Karachaliou
Browse files
acsd daemon working also with the new tool cta-tape-acs-querydrive
parent
6be4f031
Changes
8
Hide whitespace changes
Inline
Side-by-side
common/exception/QueryVolumeFailed.hpp
View file @
c8408633
...
...
@@ -41,5 +41,5 @@ namespace cta { namespace exception {
};
// class QueryVolumeFailed
}
}
// namespace ca
stor
exception
}
}
// namespace c
t
a exception
cta.spec.in
View file @
c8408633
...
...
@@ -376,6 +376,7 @@ castor (Cern Advanced STORage system)
%attr(0755,root,root) /usr/bin/cta-tape-acs-queryvolume
%attr(0755,root,root) /usr/bin/cta-tape-acs-dismount
%attr(0755,root,root) /usr/bin/cta-tape-acs-mount
%attr(0755,root,root) /usr/bin/cta-tape-acs-querydrive
%attr(0644,root,root) %doc /usr/share/man/man1/cta-tape-acs-queryvolume.1cta.gz
%attr(0644,root,root) %doc /usr/share/man/man1/cta-tape-acs-mount.1cta.gz
%attr(0644,root,root) %doc /usr/share/man/man1/cta-tape-acs-dismount.1cta.gz
mediachanger/acs/AcsQueryDriveCmd.cpp
0 → 100644
View file @
c8408633
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include
"AcsQueryDriveCmd.hpp"
#include
"AcsQueryDriveCmdLine.hpp"
#include
"common/exception/QueryVolumeFailed.hpp"
#include
<getopt.h>
#include
<iostream>
#include
<string.h>
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
AcsQueryDriveCmd
(
std
::
istream
&
inStream
,
std
::
ostream
&
outStream
,
std
::
ostream
&
errStream
,
Acs
&
acs
)
throw
()
:
AcsCmd
(
inStream
,
outStream
,
errStream
,
acs
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::~
AcsQueryDriveCmd
()
throw
()
{
// Do nothing
}
//------------------------------------------------------------------------------
// exceptionThrowingMain
//------------------------------------------------------------------------------
int
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
exceptionThrowingMain
(
const
int
argc
,
char
*
const
*
const
argv
)
{
try
{
m_cmdLine
=
AcsQueryDriveCmdLine
(
argc
,
argv
);
}
catch
(
cta
::
exception
::
Exception
&
ex
)
{
m_err
<<
ex
.
getMessage
().
str
()
<<
std
::
endl
;
m_err
<<
std
::
endl
;
m_err
<<
m_cmdLine
.
getUsage
()
<<
std
::
endl
;
return
1
;
}
// Display the usage message to standard out and exit with success if the
// user requested help
if
(
m_cmdLine
.
help
)
{
m_out
<<
AcsQueryDriveCmdLine
::
getUsage
();
return
0
;
}
// Setup debug mode to be on or off depending on the command-line arguments
m_debugBuf
.
setDebug
(
m_cmdLine
.
debug
);
m_dbg
<<
"query = "
<<
m_cmdLine
.
queryInterval
<<
std
::
endl
;
m_dbg
<<
"timeout = "
<<
m_cmdLine
.
timeout
<<
std
::
endl
;
m_dbg
<<
"DRIVE_SLOT = "
<<
m_acs
.
driveId2Str
(
m_cmdLine
.
libraryDriveSlot
);
syncQueryDrive
();
return
0
;
}
//------------------------------------------------------------------------------
// syncQueryDrive
//------------------------------------------------------------------------------
void
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
syncQueryDrive
()
{
const
SEQ_NO
requestSeqNumber
=
1
;
ALIGNED_BYTES
buf
[
MAX_MESSAGE_SIZE
/
sizeof
(
ALIGNED_BYTES
)];
try
{
sendQueryDriveRequest
(
requestSeqNumber
);
requestResponsesUntilFinal
(
requestSeqNumber
,
buf
,
m_cmdLine
.
queryInterval
,
m_cmdLine
.
timeout
);
processQueryResponse
(
m_out
,
buf
);
}
catch
(
cta
::
exception
::
Exception
&
ex
)
{
cta
::
exception
::
QueryVolumeFailed
qf
;
qf
.
getMessage
()
<<
"Failed to query drive "
<<
m_acs
.
driveId2Str
(
m_cmdLine
.
libraryDriveSlot
)
<<
": "
<<
ex
.
getMessage
().
str
();
throw
qf
;
}
}
//------------------------------------------------------------------------------
// sendQueryDriveRequest
//------------------------------------------------------------------------------
void
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
sendQueryDriveRequest
(
const
SEQ_NO
sequence
)
{
m_dbg
<<
"Calling Acs::queryDrive()"
<<
std
::
endl
;
const
STATUS
s
=
acs_query_drive
(
sequence
,
&
(
m_cmdLine
.
libraryDriveSlot
),
1
);
m_dbg
<<
"Acs::queryDrive() returned "
<<
acs_status
(
s
)
<<
std
::
endl
;
if
(
STATUS_SUCCESS
!=
s
)
{
cta
::
exception
::
QueryVolumeFailed
ex
;
ex
.
getMessage
()
<<
"Failed to send query request for drive "
<<
m_acs
.
driveId2Str
(
m_cmdLine
.
libraryDriveSlot
)
<<
": "
<<
acs_status
(
s
);
throw
ex
;
}
}
//------------------------------------------------------------------------------
// processQueryResponse
//------------------------------------------------------------------------------
void
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
processQueryResponse
(
std
::
ostream
&
os
,
ALIGNED_BYTES
(
&
buf
)[
MAX_MESSAGE_SIZE
/
sizeof
(
ALIGNED_BYTES
)])
{
const
ACS_QUERY_DRV_RESPONSE
*
const
msg
=
(
ACS_QUERY_DRV_RESPONSE
*
)
buf
;
if
(
STATUS_SUCCESS
!=
msg
->
query_drv_status
)
{
cta
::
exception
::
QueryVolumeFailed
ex
;
ex
.
getMessage
()
<<
"Status of query response is not success: "
<<
acs_status
(
msg
->
query_drv_status
);
throw
ex
;
}
if
((
unsigned
short
)
1
!=
msg
->
count
)
{
cta
::
exception
::
QueryVolumeFailed
ex
;
ex
.
getMessage
()
<<
"Query response does not contain a single drive: count="
<<
msg
->
count
;
throw
ex
;
}
// count is 1 so it is safe to make a reference to the single drive status
const
QU_DRV_STATUS
&
drvStatus
=
msg
->
drv_status
[
0
];
if
(
m_acs
.
driveId2Str
(
m_cmdLine
.
libraryDriveSlot
)
!=
m_acs
.
driveId2Str
(
drvStatus
.
drive_id
))
{
cta
::
exception
::
QueryVolumeFailed
ex
;
ex
.
getMessage
()
<<
"Drive identifier of query response does not match that of request"
" requestDriveID="
<<
m_acs
.
driveId2Str
(
m_cmdLine
.
libraryDriveSlot
)
<<
" responseDriveID="
<<
m_acs
.
driveId2Str
(
drvStatus
.
drive_id
);
throw
ex
;
}
writeDriveStatus
(
os
,
drvStatus
);
}
//------------------------------------------------------------------------------
// writeDriveStatus
//------------------------------------------------------------------------------
void
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmd
::
writeDriveStatus
(
std
::
ostream
&
os
,
const
QU_DRV_STATUS
&
s
)
throw
()
{
os
<<
"Drive identifier: "
<<
m_acs
.
driveId2Str
(
s
.
drive_id
)
<<
std
::
endl
;
os
<<
"Drive type: "
<<
acs_type
((
TYPE
)
s
.
drive_type
)
<<
std
::
endl
;
os
<<
"Drive state: "
<<
acs_state
(
s
.
state
)
<<
std
::
endl
;
os
<<
"Drive status: "
<<
acs_status
(
s
.
status
)
<<
std
::
endl
;
os
<<
"Volume identifier: "
<<
s
.
vol_id
.
external_label
<<
std
::
endl
;
}
mediachanger/acs/AcsQueryDriveCmd.hpp
0 → 100644
View file @
c8408633
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include
"AcsCmd.hpp"
#include
"AcsQueryDriveCmdLine.hpp"
#include
"common/exception/InvalidArgument.hpp"
#include
"common/exception/MissingOperand.hpp"
#include
"mediachanger/CmdLineTool.hpp"
#include
<stdint.h>
namespace
cta
{
namespace
mediachanger
{
namespace
acs
{
/**
* The class implementing the mount command.
*/
class
AcsQueryDriveCmd
:
public
AcsCmd
{
public:
/**
* Constructor.
*
* @param inStream Standard input stream.
* @param outStream Standard output stream.
* @param errStream Standard error stream.
* @param acs Wrapper around the ACSLS C-API.
*/
AcsQueryDriveCmd
(
std
::
istream
&
inStream
,
std
::
ostream
&
outStream
,
std
::
ostream
&
errStream
,
Acs
&
acs
)
throw
();
/**
* Destructor.
*/
virtual
~
AcsQueryDriveCmd
()
throw
();
/**
* The entry function of the command.
*
* @param argc The number of command-line arguments.
* @param argv The command-line arguments.
* @return The exit value of the program.
*/
int
exceptionThrowingMain
(
const
int
argc
,
char
*
const
*
const
argv
);
protected:
/**
* Queries ACS for information about the drive identifier specified on the
* command-line.
*
* This method does not return until the information has been successfully
* retrieved, an error has occurred or the specified timeout has been
* reached.
*
* @return The drive status of the drive identifier specified on the
* command-line.
*/
void
syncQueryDrive
();
/**
* Sends the query drive request to ACSLS.
*
* @param seqNumber The sequence number to be used in the request.
*/
void
sendQueryDriveRequest
(
const
SEQ_NO
seqNumber
);
/**
* Extracts the drive status from the specified query-response message and
* writes it in human-readable form to the specified output stream.
*
* @param os The output stream.
* @param buf The query-response message.
*/
void
processQueryResponse
(
std
::
ostream
&
os
,
ALIGNED_BYTES
(
&
buf
)[
MAX_MESSAGE_SIZE
/
sizeof
(
ALIGNED_BYTES
)]);
/**
* Writes a human readable representation of the specified drive status to
* the specified output stream.
*
* @param os The output stream.
* @param s The drive status.
*/
void
writeDriveStatus
(
std
::
ostream
&
os
,
const
QU_DRV_STATUS
&
s
)
throw
();
private:
/**
* The parsed command-line.
*
* The value of this member variable is set within the main() method of this
* class.
*/
AcsQueryDriveCmdLine
m_cmdLine
;
};
// class AcsQueryDriveCmd
}
// namespace acs
}
// namepsace mediachanger
}
// namespace cta
mediachanger/acs/AcsQueryDriveCmdLine.cpp
0 → 100644
View file @
c8408633
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include
"Acs.hpp"
#include
"AcsQueryDriveCmdLine.hpp"
#include
"Constants.hpp"
#include
"common/exception/InvalidArgument.hpp"
#include
"common/exception/MissingOperand.hpp"
#include
<getopt.h>
#include
<stdlib.h>
#include
<string.h>
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmdLine
::
AcsQueryDriveCmdLine
()
throw
()
:
debug
(
false
),
help
(
false
),
queryInterval
(
0
),
timeout
(
0
)
{
libraryDriveSlot
.
panel_id
.
lsm_id
.
acs
=
(
ACS
)
0
;
libraryDriveSlot
.
panel_id
.
lsm_id
.
lsm
=
(
LSM
)
0
;
libraryDriveSlot
.
panel_id
.
panel
=
(
PANEL
)
0
;
libraryDriveSlot
.
drive
=
(
DRIVE
)
0
;
memset
(
volId
.
external_label
,
'\0'
,
sizeof
(
volId
.
external_label
));
}
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmdLine
::
AcsQueryDriveCmdLine
(
const
int
argc
,
char
*
const
*
const
argv
)
:
debug
(
false
),
help
(
false
),
queryInterval
(
ACS_QUERY_INTERVAL
),
timeout
(
ACS_CMD_TIMEOUT
)
{
libraryDriveSlot
.
panel_id
.
lsm_id
.
acs
=
(
ACS
)
0
;
libraryDriveSlot
.
panel_id
.
lsm_id
.
lsm
=
(
LSM
)
0
;
libraryDriveSlot
.
panel_id
.
panel
=
(
PANEL
)
0
;
libraryDriveSlot
.
drive
=
(
DRIVE
)
0
;
memset
(
volId
.
external_label
,
'\0'
,
sizeof
(
volId
.
external_label
));
static
struct
option
longopts
[]
=
{
{
"debug"
,
0
,
NULL
,
'd'
},
{
"help"
,
0
,
NULL
,
'h'
},
{
"query"
,
required_argument
,
NULL
,
'q'
},
{
"timeout"
,
required_argument
,
NULL
,
't'
},
{
NULL
,
0
,
NULL
,
0
}
};
// Prevent getopt() from printing an error message if it does not recognize
// an option character
opterr
=
0
;
int
opt
=
0
;
while
((
opt
=
getopt_long
(
argc
,
argv
,
":dhq:t:"
,
longopts
,
NULL
))
!=
-
1
)
{
processOption
(
opt
);
}
// There is no need to continue parsing when the help option is set
if
(
help
)
{
return
;
}
// Check that DRIVE_SLOT has been specified
if
(
argc
<
1
)
{
cta
::
exception
::
MissingOperand
ex
;
ex
.
getMessage
()
<<
"DRIVE_SLOT must be specified"
;
throw
ex
;
}
// Parse DRIVE_SLOT
libraryDriveSlot
=
Acs
::
str2DriveId
(
argv
[
1
]);
}
//------------------------------------------------------------------------------
// processOption
//------------------------------------------------------------------------------
void
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmdLine
::
processOption
(
const
int
opt
)
{
switch
(
opt
)
{
case
'd'
:
debug
=
true
;
break
;
case
'h'
:
help
=
true
;
break
;
case
'q'
:
queryInterval
=
parseQueryInterval
(
optarg
);
break
;
case
't'
:
timeout
=
parseTimeout
(
optarg
);
break
;
case
':'
:
return
handleMissingParameter
(
optopt
);
case
'?'
:
return
handleUnknownOption
(
optopt
);
default:
{
cta
::
exception
::
Exception
ex
;
ex
.
getMessage
()
<<
"getopt_long returned the following unknown value: 0x"
<<
std
::
hex
<<
(
int
)
opt
;
throw
ex
;
}
}
// switch(opt)
}
//------------------------------------------------------------------------------
// getUsage
//------------------------------------------------------------------------------
std
::
string
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmdLine
::
getUsage
()
throw
()
{
std
::
ostringstream
usage
;
usage
<<
"Usage:
\n
"
"
\n
"
<<
getProgramName
()
<<
" [options] DRIVE_SLOT
\n
"
"
\n
"
"Where:
\n
"
"
\n
"
" DRIVE_SLOT The slot in the tape library where the drive is located.
\n
"
" DRIVE_SLOT must be in one of the following two forms:
\n
"
"
\n
"
" acsACS_NUMBER,LSM_NUMBER,PANEL_NUMBER,TRANSPORT_NUMBER
\n
"
" smcDRIVE_ORDINAL
\n
"
"
\n
"
"Options:
\n
"
"
\n
"
" -d|--debug Turn on the printing of debug information.
\n
"
"
\n
"
" -h|--help Print this help message and exit.
\n
"
"
\n
"
;
return
usage
.
str
();
}
//------------------------------------------------------------------------------
// getProgramName
//------------------------------------------------------------------------------
std
::
string
cta
::
mediachanger
::
acs
::
AcsQueryDriveCmdLine
::
getProgramName
()
{
return
"cta-tape-acs-querydrive"
;
}
mediachanger/acs/AcsQueryDriveCmdLine.hpp
0 → 100644
View file @
c8408633
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include
"AcsCmdLine.hpp"
#include
"mediachanger/AcsLibrarySlot.hpp"
#include
"mediachanger/LibrarySlotParser.hpp"
extern
"C"
{
#include
"acssys.h"
#include
"acsapi.h"
}
#include
<string>
namespace
cta
{
namespace
mediachanger
{
namespace
acs
{
/**
* Data type used to store the results of parsing the command-line.
*/
struct
AcsQueryDriveCmdLine
:
public
AcsCmdLine
{
/**
* True if the debug option has been set.
*/
BOOLEAN
debug
;
/**
* True if the help option has been set.
*/
BOOLEAN
help
;
/**
* Time in seconds to wait between queries to ACS for responses.
*/
int
queryInterval
;
/**
* Time in seconds to wait for the dismount to conclude.
*/
int
timeout
;
/**
* The volume identifier of the tape to be mounted.
*/
VOLID
volId
;
/**
* Constructor.
*
* Initialises all BOOLEAN member-variables to FALSE, all integer
* member-variables to 0 and the volume identifier to an empty string.
*/
AcsQueryDriveCmdLine
()
throw
();
/**
* Constructor.
*
* Parses the specified command-line arguments.
*
* @param argc Argument count from the executable's entry function: main().
* @param argv Argument vector from the executable's entry function: main().
*/
AcsQueryDriveCmdLine
(
const
int
argc
,
char
*
const
*
const
argv
);
/**
* Gets the usage message that describes the command line.
*
* @return The usage message.
*/
static
std
::
string
getUsage
()
throw
();
/**
* Return sthe program name.
*
* @return sthe program name.
*/
static
std
::
string
getProgramName
();
/**
* The slot in the tape library where the drive is located.
*/
DRIVEID
libraryDriveSlot
;
private:
/**
* Processes the specified option that was returned by getopt_long().
*
* @param opt The option that was returned by getopt_long().
*/
void
processOption
(
const
int
opt
);
};
// class AcsQueryDriveCmdLine
}
// namespace acs
}
// namespace mediachanger
}
// namespace cta
mediachanger/acs/AcsQueryDriveCmdMain.cpp
0 → 100644
View file @
c8408633
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include
"AcsImpl.hpp"
#include
"AcsQueryDriveCmd.hpp"
#include
"AcsQueryDriveCmdLine.hpp"
#include
<iostream>
/**
* An exception throwing version of main().
*
* @param argc The number of command-line arguments including the program name.
* @param argv The command-line arguments.
* @param The exit value of the program.
*/
static
int
exceptionThrowingMain
(
const
int
argc
,
char
*
const
*
const
argv
);
//------------------------------------------------------------------------------
// main
//------------------------------------------------------------------------------
int
main
(
const
int
argc
,
char
*
const
*
const
argv
)
{
using
namespace
cta
;
std
::
string
errorMessage
;