From: Eric Bollengier Date: Mon, 1 Mar 2021 17:58:39 +0000 (+0100) Subject: Handle lin_tape end of device with new 'Use Lintape=yes' Device directive X-Git-Tag: Release-11.3.2~629 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd3c6c51ba2b9800c9b69169b40fa5471e91707e;p=thirdparty%2Fbacula.git Handle lin_tape end of device with new 'Use Lintape=yes' Device directive Use MTIOCGET = No Use lintape = Yes --- diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 39e9c4ad0..67dd77111 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -149,6 +149,7 @@ typedef struct { #define CAP_BLOCKCHECKSUM (1<<23) /* Create/test block checksum */ #define CAP_LSEEK (1<<24) /* Has lseek function defined i.e. basically File storage */ #define CAP_SYNCONCLOSE (1<<25) /* Need to call fsync() when releasing/closing the device */ +#define CAP_LINTAPE (1<<26) /* If has the Lintape interface */ /* Test state */ #define dev_state(dev, st_state) ((dev)->state & (st_state)) diff --git a/bacula/src/stored/lintape.h b/bacula/src/stored/lintape.h new file mode 100644 index 000000000..d50465d3c --- /dev/null +++ b/bacula/src/stored/lintape.h @@ -0,0 +1,63 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2020 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ + +#ifndef LIN_TAPE_H +#define LIN_TAPE_H + +#include "bacula.h" + +/* Interface to request information to a tape drive + * Technical information found on IBM web site + * https://www.ibm.com/support/knowledgecenter/STAKKZ/dd_pr_kc/con_a89p4_lnx_sioc_reqsense.html + * TODO: May not work SPARC CPU + */ + +#if defined(HAVE_LINUX_OS) + +#ifndef SIOC_REQSENSE +# define SIOC_REQSENSE _IOR('C', 0x02, lintape_request_sense) +#endif + +struct lintape_request_sense { + uint8_t valid :1, /* sense data is valid */ + err_code :7; /* error code */ + uint8_t segnum; /* segment number */ + uint32_t fm :1, /* filemark detected */ + eom :1, /* end of medium */ + ili :1, /* incorrect length indicator */ + resvd1 :1, /* reserved */ + key :4; /* sense key */ + int32_t info; /* information bytes */ + uint8_t addlen; /* additional sense length */ + uint32_t cmdinfo; /* command specific information */ + uint8_t asc; /* additional sense code */ + uint8_t ascq; /* additional sense code qualifier */ + uint8_t fru; /* field replaceable unit code */ + uint32_t sksv :1, /* sense key specific valid */ + cd :1, /* control/data */ + resvd2 :2, /* reserved */ + bpv :1, /* bit pointer valid */ + sim :3; /* system information message */ + uint8_t field[2]; /* field pointer */ + uint8_t vendor[109]; /* vendor specific (padded to 127) */ +}; + +#endif // HAVE_LINUX_OS + +#endif // LIN_TAPE_H diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 6065c82ec..8b2b5842e 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -153,6 +153,7 @@ static RES_ITEM dev_items[] = { {"RequiresMount", store_bit, ITEM(res_dev.cap_bits), CAP_REQMOUNT, ITEM_DEFAULT, 0}, {"OfflineOnUnmount", store_bit, ITEM(res_dev.cap_bits), CAP_OFFLINEUNMOUNT, ITEM_DEFAULT, 0}, {"BlockChecksum", store_bit, ITEM(res_dev.cap_bits), CAP_BLOCKCHECKSUM, ITEM_DEFAULT, 1}, + {"UseLintape", store_bit, ITEM(res_dev.cap_bits), CAP_LINTAPE, ITEM_DEFAULT, 0}, {"Enabled", store_bool, ITEM(res_dev.enabled), 0, ITEM_DEFAULT, 1}, {"AutoSelect", store_bool, ITEM(res_dev.autoselect), 0, ITEM_DEFAULT, 1}, {"ReadOnly", store_bool, ITEM(res_dev.read_only), 0, ITEM_DEFAULT, 0}, diff --git a/bacula/src/stored/tape_dev.c b/bacula/src/stored/tape_dev.c index 7b323cc1a..e71af8b8c 100644 --- a/bacula/src/stored/tape_dev.c +++ b/bacula/src/stored/tape_dev.c @@ -57,6 +57,7 @@ #include "bacula.h" #include "stored.h" +#include "lintape.h" #ifndef O_NONBLOCK #define O_NONBLOCK 0 @@ -623,6 +624,9 @@ bool tape_dev::fsf(int num) */ } else if (at_eof() && errno == ENOSPC) { stat = 0; + /* With IBM Lintape, we need to check the Error sense of the device */ + } else if (at_eof() && errno == EIO && check_lintape_eod()) { + stat = 0; } else { berrno be; set_eot(); @@ -1127,3 +1131,84 @@ void tape_dev::term(DCR *dcr) delete_alerts(); DEVICE::term(dcr); } + +/* Official documentation + * https://www.ibm.com/support/pages/node/652827 + * + * TS3310 TApe Library SCSI Reference, look for "REQUEST SENSE" + * https://www.ibm.com/support/pages/system/files/support/ssg/ssgdocs.nsf/0/b321b010cdcf56e58525773b0070c925/$FILE/GA32-0476-01.pdf + */ +bool tape_dev::check_lintape_eod() +{ +#ifdef HAVE_LINUX_OS + if (has_cap(CAP_LINTAPE)) { + int rc; + char buf[128]; + lintape_request_sense sense; + memset(&sense, 0, sizeof(sense)); + + rc = d_ioctl(m_fd, SIOC_REQSENSE, (char*)&sense); + if (rc != 0) { + Dmsg0(150, "Unable to perform SIOC_REQSENSE\n"); + return false; + } + + if (chk_dbglvl(150)) { + d_msg(__FILE__, __LINE__, 150, + "Information Field Valid Bit-------%d\n" + "Error Code------------------------0x%02x\n" + "Segment Number--------------------0x%02x\n" + "filemark Detected Bit-------------%d\n" + "End Of Medium Bit-----------------%d\n" + "Illegal Length Indicator Bit------%d\n" + "Sense Key-------------------------0x%02x\n" + " Information Bytes---------------0x%02x 0x%02x 0x%02x 0x%02x\n" + "Additional Sense Length-----------0x%02x\n" + "Command Specific Information------0x%02x 0x%02x 0x%02x 0x%02x\n" + "Additional Sense Code-------------0x%02x\n" + "Additional Sense Code Qualifier---0x%02x\n" + "Field Replaceable Unit Code-------0x%02x\n" + "Sense Key Specific Valid Bit------%d\n" + " Command Data Block Bit----------%d\n" + " Bit Pointer Valid Bit-----------%d\n" + " System Information Message----0x%02x\n" + " Field Pointer-------------------0x%02x%02x\n" + "Vendor----------------------------%s\n", + (int)sense.valid, + (int)sense.err_code, + (int)sense.segnum, + (int)sense.fm, + (int)sense.eom, + (int)sense.ili, + (int)sense.key, + sense.valid?(int)(sense.info >> 24) :0, + sense.valid?(int)(sense.info >> 16) :0, + sense.valid?(int)(sense.info >> 8) :0, + sense.valid?(int)(sense.info & 0xFF):0, + (int)sense.addlen, + (int)(sense.cmdinfo >> 24), (int)(sense.cmdinfo >> 16), + (int)(sense.cmdinfo >> 8), (int)(sense.cmdinfo & 0xFF), + (int)sense.asc, + (int)sense.ascq, + (int)sense.fru, + (int)sense.sksv, + sense.sksv?(int)sense.cd :0, + sense.sksv?(int)sense.bpv :0, + (sense.sksv && sense.bpv)?(int)sense.sim :0, + sense.sksv?(int)sense.field[0] :0, + sense.sksv?(int)sense.field[1] :0, + smartdump((char*)sense.vendor, sizeof(sense.vendor), + buf, sizeof(buf), NULL)); + } + if (sense.err_code) { + /* The following values are reported to be correct by Mariusz Czulada + * on the bacula-devel list in 2007 + */ + return sense.key == 0x08 && + sense.asc == 0x00 && + sense.ascq == 0x05; + } + } +#endif + return false; +} diff --git a/bacula/src/stored/tape_dev.h b/bacula/src/stored/tape_dev.h index 0a81dfc49..d5c930f35 100644 --- a/bacula/src/stored/tape_dev.h +++ b/bacula/src/stored/tape_dev.h @@ -69,7 +69,7 @@ public: void show_tape_alerts(DCR *dcr, alert_list_type type, alert_list_which which, alert_cb alert_callback); int delete_alerts(); - + bool check_lintape_eod(); alist *alert_list; };