From a3f7ec94f228796f5f182ee75acf79852c3ff805 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 31 Aug 2021 05:29:55 +0000 Subject: [PATCH] add support for obtaining sense status and source slot of a media this fixes a bug in bacula where the catalog was not properly kept up-to-date if a tape was in a drive becuse its source slot was unknown based on code from FreeBSD; ok krw@ picker 0: sense: <0x00/0x00> voltag: <:0> avoltag: <:0> source: <> slot 0: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 1: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 2: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 3: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 4: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 5: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 6: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 7: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 8: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 9: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 10: sense: <0x00/0x00> voltag: <:0> avoltag: <:0> source: slot 11: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 12: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 13: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 14: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 15: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 16: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 17: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 18: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 19: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 20: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 21: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 22: sense: <0x00/0x00> voltag: avoltag: <:0> source: slot 23: sense: <0x00/0x00> voltag: avoltag: <:0> source: drive 0: sense: <0x00/0x00> voltag: avoltag: <:0> source: --- bin/chio/chio.c | 40 +++++++++++++++++++++++++++++++++++++--- sys/scsi/ch.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- sys/sys/chio.h | 7 ++++++- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/bin/chio/chio.c b/bin/chio/chio.c index bec50cb4683..8ec01b1b724 100644 --- a/bin/chio/chio.c +++ b/bin/chio/chio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chio.c,v 1.27 2021/06/26 15:42:58 deraadt Exp $ */ +/* $OpenBSD: chio.c,v 1.28 2021/08/31 05:29:55 robert Exp $ */ /* $NetBSD: chio.c,v 1.1.1.1 1996/04/03 00:34:38 thorpej Exp $ */ /* @@ -59,6 +59,7 @@ static int parse_element_type(char *); static int parse_element_unit(char *); static int parse_special(char *); static int is_special(char *); +static const char * element_type_name(int et); static char *bits_to_string(int, const char *); static void find_voltag(char *, int *, int *); static void check_source_drive(int); @@ -104,6 +105,8 @@ static int changer_fd; static char *changer_name; static int avoltag; static int pvoltag; +static int sense; +static int source; int main(int argc, char *argv[]) @@ -486,8 +489,14 @@ do_status(char *cname, int argc, char *argv[]) optreset = 1; optind = 1; - while ((c = getopt(argc, argv, "vVa")) != -1) { + while ((c = getopt(argc, argv, "SsvVa")) != -1) { switch (c) { + case 's': + sense = 1; + break; + case 'S': + source = 1; + break; case 'v': pvoltag = 1; break; @@ -495,7 +504,7 @@ do_status(char *cname, int argc, char *argv[]) avoltag = 1; break; case 'a': - pvoltag = avoltag = 1; + pvoltag = avoltag = source = sense = 1; break; default: goto usage; @@ -589,6 +598,10 @@ do_status(char *cname, int argc, char *argv[]) &(cmd.cesr_data[i]); printf("%s %d: %s", description, i, bits_to_string(ces->ces_flags, CESTATUS_BITS)); + if (sense) + printf(" sense: <0x%02x/0x%02x>", + ces->ces_sensecode, + ces->ces_sensequal); if (pvoltag) printf(" voltag: <%s:%d>", ces->ces_pvoltag.cv_volid, @@ -597,6 +610,15 @@ do_status(char *cname, int argc, char *argv[]) printf(" avoltag: <%s:%d>", ces->ces_avoltag.cv_volid, ces->ces_avoltag.cv_serial); + if (source) { + if (ces->ces_flags & CESTATUS_ACCESS) + printf(" source: <%s %d>", + element_type_name( + ces->ces_source_type), + ces->ces_source_addr); + else + printf(" source: <>"); + } printf("\n"); } @@ -765,6 +787,18 @@ parse_element_type(char *cp) errx(1, "invalid element type `%s'", cp); } +static const char * +element_type_name(int et) +{ + int i; + + for (i = 0; elements[i].et_name != NULL; i++) + if (elements[i].et_type == et) + return elements[i].et_name; + + return "unknown"; +} + static int parse_element_unit(char *cp) { diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c index 672bd9560b2..7672970b5c8 100644 --- a/sys/scsi/ch.c +++ b/sys/scsi/ch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ch.c,v 1.68 2021/03/12 10:22:46 jsg Exp $ */ +/* $OpenBSD: ch.c,v 1.69 2021/08/31 05:29:55 robert Exp $ */ /* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */ /* @@ -514,11 +514,53 @@ copy_voltag(struct changer_voltag *uvoltag, struct volume_tag *voltag) * changer_element_status structure. */ static void -copy_element_status(int flags, struct read_element_status_descriptor *desc, +copy_element_status(struct ch_softc *sc, int flags, + struct read_element_status_descriptor *desc, struct changer_element_status *ces) { + u_int16_t eaddr = _2btol(desc->eaddr); + u_int16_t et; + + for (et = CHET_MT; et <= CHET_DT; et++) { + if ((sc->sc_firsts[et] <= eaddr) + && ((sc->sc_firsts[et] + sc->sc_counts[et]) + > eaddr)) { + ces->ces_addr = eaddr - sc->sc_firsts[et]; + ces->ces_type = et; + break; + } + } + ces->ces_flags = desc->flags1; + ces->ces_sensecode = desc->sense_code; + ces->ces_sensequal = desc->sense_qual; + + if (desc->flags2 & READ_ELEMENT_STATUS_INVERT) + ces->ces_flags |= READ_ELEMENT_STATUS_EXCEPT; + + if (desc->flags2 & READ_ELEMENT_STATUS_SVALID) { + eaddr = _2btol(desc->ssea); + + /* convert source address to logical format */ + for (et = CHET_MT; et <= CHET_DT; et++) { + if ((sc->sc_firsts[et] <= eaddr) + && ((sc->sc_firsts[et] + sc->sc_counts[et]) + > eaddr)) { + ces->ces_source_addr = + eaddr - sc->sc_firsts[et]; + ces->ces_source_type = et; + ces->ces_flags |= READ_ELEMENT_STATUS_ACCESS; + break; + } + } + + if (!(ces->ces_flags & READ_ELEMENT_STATUS_ACCESS)) + printf("ch: warning: could not map element source " + "address %ud to a valid element type\n", + eaddr); + } + if (ISSET(flags, READ_ELEMENT_STATUS_PVOLTAG)) copy_voltag(&ces->ces_pvoltag, &desc->pvoltag); if (ISSET(flags, READ_ELEMENT_STATUS_AVOLTAG)) @@ -604,7 +646,7 @@ ch_usergetelemstatus(struct ch_softc *sc, desc = (caddr_t)(pg_hdr + 1); for (i = 0; i < avail; ++i) { struct changer_element_status *ces = &(user_data[i]); - copy_element_status(pg_hdr->flags, + copy_element_status(sc, pg_hdr->flags, (struct read_element_status_descriptor *)desc, ces); desc += desclen; } diff --git a/sys/sys/chio.h b/sys/sys/chio.h index 88afaa92e7a..a6cb8b11047 100644 --- a/sys/sys/chio.h +++ b/sys/sys/chio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: chio.h,v 1.7 2006/05/31 03:01:44 beck Exp $ */ +/* $OpenBSD: chio.h,v 1.8 2021/08/31 05:29:55 robert Exp $ */ /* $NetBSD: chio.h,v 1.8 1996/04/03 00:25:21 thorpej Exp $ */ /* @@ -127,6 +127,11 @@ struct changer_voltag { struct changer_element_status { int ces_type; /* element type */ u_int8_t ces_flags; /* flags */ + u_int16_t ces_addr; /* logical element address */ + u_int8_t ces_sensecode; /* additional sense code for element */ + u_int8_t ces_sensequal; /* additional sense code qualifier */ + u_int8_t ces_source_type; /* element type of source address */ + u_int16_t ces_source_addr; /* source address of medium */ struct changer_voltag ces_pvoltag; /* primary voltag */ struct changer_voltag ces_avoltag; /* alternate voltag */ }; -- 2.20.1