diff --git a/mediachanger/castorrmc/h/rmc_smcsubr.h b/mediachanger/castorrmc/h/rmc_smcsubr.h index 24228c43a0916f747be56a57ef20f3022f3f53db..a109f29886ac134a59239457beaec6b792a6ecf2 100644 --- a/mediachanger/castorrmc/h/rmc_smcsubr.h +++ b/mediachanger/castorrmc/h/rmc_smcsubr.h @@ -49,7 +49,8 @@ EXTERN_C int smc_find_cartridge( const int type, const int start, const int nbelem, - struct smc_element_info element_info[]); + struct smc_element_info element_info[], + struct robot_info *const robot_info); EXTERN_C int smc_lasterror( struct smc_status *const smc_stat, diff --git a/mediachanger/castorrmc/h/spectra_like_libs.h b/mediachanger/castorrmc/h/spectra_like_libs.h new file mode 100644 index 0000000000000000000000000000000000000000..be7be63dc49dbd6a02df96b80e30926d30ecba90 --- /dev/null +++ b/mediachanger/castorrmc/h/spectra_like_libs.h @@ -0,0 +1,22 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2003-2021 CERN + * @license 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 "smc_struct.h" + +int is_library_spectra_like(const struct robot_info *const robot_info); diff --git a/mediachanger/castorrmc/rmc/CMakeLists.txt b/mediachanger/castorrmc/rmc/CMakeLists.txt index 63e53e84d66553a2fed1239cff30e528f8f73e8f..f95cc575dd7f0654061de326056d239fb989f9a1 100644 --- a/mediachanger/castorrmc/rmc/CMakeLists.txt +++ b/mediachanger/castorrmc/rmc/CMakeLists.txt @@ -25,6 +25,7 @@ set (RMCD_SRC_FILES rmc_send_scsi_cmd.c rmc_serv.c rmc_smcsubr.c + spectra_like_libs.c ) if(CMAKE_COMPILER_IS_GNUCC) @@ -55,6 +56,7 @@ set (SMC_SRC_FILES rmc_mount.c rmc_read_elem_status.c send2rmc.c + spectra_like_libs.c smc.c) add_executable(cta-smc ${SMC_SRC_FILES}) target_link_libraries(cta-smc ctarmccommon) diff --git a/mediachanger/castorrmc/rmc/rmc_procreq.c b/mediachanger/castorrmc/rmc/rmc_procreq.c index aa8298fae49d7ccf9d216ecee50d9f748c539a0d..8f058f3e8bb813e63ea3cf256d3c4ed358517e9e 100644 --- a/mediachanger/castorrmc/rmc/rmc_procreq.c +++ b/mediachanger/castorrmc/rmc/rmc_procreq.c @@ -137,7 +137,7 @@ int rmc_srv_findcart(const struct rmc_srv_rqst_context *const rqst_context) { } c = smc_find_cartridge (extended_robot_info.smc_fd, extended_robot_info.smc_ldr, template, type, startaddr, - nbelem, element_info); + nbelem, element_info, &extended_robot_info.robot_info); if (c < 0) { c = smc_lasterror (&smc_status, &msgaddr); free (element_info); diff --git a/mediachanger/castorrmc/rmc/rmc_smcsubr.c b/mediachanger/castorrmc/rmc/rmc_smcsubr.c index 0d8d5b8740e69244c057503e89dc25928fa31d1c..95cfec32b5fa92f40521ea6e17dfd570efda0e0f 100644 --- a/mediachanger/castorrmc/rmc/rmc_smcsubr.c +++ b/mediachanger/castorrmc/rmc/rmc_smcsubr.c @@ -34,9 +34,9 @@ #include "scsictl.h" #include "serrno.h" #include "smc_constants.h" +#include "spectra_like_libs.h" #define RBT_XTRA_PROC 10 -#define PATH_CONF "/etc/cta/cta-smc.conf" static struct smc_status smc_status; static const char *smc_msgaddr; @@ -437,7 +437,8 @@ int smc_find_cartridge( const int type, const int start, const int nbelem, - struct smc_element_info element_info[]) + struct smc_element_info element_info[], + struct robot_info *const robot_info) { unsigned char cdb[12]; char func[16]; @@ -448,15 +449,12 @@ int smc_find_cartridge( char sense[MAXSENSE]; int pause_mode = 1; int nretries = 0; - char *smcLibraryType; strncpy(func, "findWithVT", sizeof(func)); func[sizeof(func) - 1] = '\0'; /* Skip the 0xB6 cdb command if the tape library is Spectra like */ - smcLibraryType = getconfent_fromfile(PATH_CONF,"SMC","LIBRARY_TYPE",0); - if (NULL != smcLibraryType && - 0 == strcasecmp(smcLibraryType,"SPECTRA")) { + if (is_library_spectra_like(robot_info)) { rc = smc_find_cartridgeWithoutSendVolumeTag (fd, rbtdev, find_template, type, start, nbelem, element_info); if (rc >= 0) @@ -757,7 +755,7 @@ int smc_dismount ( /* check that the vid is in a slot before returning */ while (1) { struct smc_element_info vol_element_info; - if (0 > smc_find_cartridge (fd, loader, drive_element_info.name, 0, 0, 1, &vol_element_info)) { + if (0 > smc_find_cartridge (fd, loader, drive_element_info.name, 0, 0, 1, &vol_element_info, robot_info)) { const int smc_error = smc_lasterror (&smc_status, &msgaddr); rmc_usrmsg ( rpfd, func, SR017, "find_cartridge", drive_element_info.name, msgaddr); return (smc_error); @@ -791,7 +789,7 @@ int smc_export ( func[sizeof(func) - 1] = '\0'; { - const int smc_find_cartridge_rc = smc_find_cartridge (fd, loader, vid, 0, 0, 1, &element_info); + const int smc_find_cartridge_rc = smc_find_cartridge (fd, loader, vid, 0, 0, 1, &element_info, robot_info); if (0 > smc_find_cartridge_rc) { const int smc_lasterror_rc = smc_lasterror (&smc_status, &msgaddr); rmc_usrmsg ( rpfd, func, SR017, "find_cartridge", vid, msgaddr); @@ -958,7 +956,7 @@ int smc_mount ( strncpy (func, "smc_mount", sizeof(func)); func[sizeof(func) - 1] = '\0'; - if ((c = smc_find_cartridge (fd, loader, vid, 0, 0, 1, &element_info)) < 0) { + if ((c = smc_find_cartridge (fd, loader, vid, 0, 0, 1, &element_info, robot_info)) < 0) { c = smc_lasterror (&smc_status, &msgaddr); rmc_usrmsg ( rpfd, func, SR017, "find_cartridge", vid, msgaddr); return (c); diff --git a/mediachanger/castorrmc/rmc/smc.c b/mediachanger/castorrmc/rmc/smc.c index 2058a6dbf8917d8d23e8af4f54928ab93c4fcb9f..949e8e9175b9e0ac46dfe1c84daf97c7392dcc84 100644 --- a/mediachanger/castorrmc/rmc/smc.c +++ b/mediachanger/castorrmc/rmc/smc.c @@ -27,12 +27,12 @@ #include "smc_constants.h" #include "getconfent.h" #include "getopt.h" +#include "spectra_like_libs.h" #include <ctype.h> /* exit codes */ #define USERR 1 -#define PATH_CONF "/etc/cta/cta-smc.conf" #define TEXT_RED "\x1b[31;1m" #define TEXT_NORMAL "\x1b[0m" @@ -122,7 +122,6 @@ static int smc_qdrive ( int c; struct smc_element_info *element_info; int nbelem; - char *smcLibraryType; char useSpectraLib; if (drvord < 0) { @@ -140,10 +139,7 @@ static int smc_qdrive ( free (element_info); return (c); } - useSpectraLib=0; - smcLibraryType = getconfent_fromfile(PATH_CONF,"SMC","LIBRARY_TYPE",0); - if (NULL != smcLibraryType && - 0 == strcasecmp(smcLibraryType,"SPECTRA")) { + if (is_library_spectra_like(robot_info)) { useSpectraLib = 1; } if (isJsonEnabled) { diff --git a/mediachanger/castorrmc/rmc/spectra_like_libs.c b/mediachanger/castorrmc/rmc/spectra_like_libs.c new file mode 100644 index 0000000000000000000000000000000000000000..04d5ddefc3fd59e2f896f98ccd943543c44f063a --- /dev/null +++ b/mediachanger/castorrmc/rmc/spectra_like_libs.c @@ -0,0 +1,72 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 1998-2021 CERN + * @license 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 <string.h> +#include <ctype.h> +#include "spectra_like_libs.h" + +#define N_LIBS (sizeof(spectra_like_libs) / sizeof(spectra_like_libs[0])) + +struct vendor_product_id_pair { + char vendor_id[9]; + char product_id[17]; +}; + +static struct vendor_product_id_pair const spectra_like_libs[] = { + /* To match all products of a specific vendor, set the product_id as empty string */ + {"SPECTRA", "" }, /*Match all SPECTRA libraries */ + {"IBM" , "3573-TL"} /*Match IBM libraries, model 3573-TL*/ +}; + +void trim_trailing_spaces(char * str) { + int pos; + pos = strlen(str) - 1; + for (; pos >= 0 && isspace(str[pos]); pos--) { + str[pos] = '\0'; + } +} + +int is_library_spectra_like(const struct robot_info *const robot_info) { + int isSpectraLike; + char vendorId[9]; + char productId[17]; + unsigned int i; + + memcpy (vendorId, robot_info->inquiry, 8); + memcpy (productId, robot_info->inquiry + 8, 16); + vendorId[8] = '\0'; + productId[16] = '\0'; + + /* Trim any whitespaces in excess */ + trim_trailing_spaces(vendorId); + trim_trailing_spaces(productId); + + /* find if the vendor (and product) are in the list 'spectra_like_libs' */ + isSpectraLike = 0; + for (i=0; i < N_LIBS && !isSpectraLike; i++) { + if (strcasecmp(vendorId, spectra_like_libs[i].vendor_id) == 0) { + if ( + spectra_like_libs[i].product_id[0] == '\0' + || strcasecmp(productId, spectra_like_libs[i].product_id) == 0 + ) { + isSpectraLike = 1; + } + } + } + + return isSpectraLike; +}