SG_DECODE_SENSE(8)

πŸ’… SG_DECODE_SENSE(8) β€” or, how to read SCSI sense data without crying

okay so bestie, welcome to sg_decode_sense, a little icon from the sg3_utils lineup ✨ It decodes SCSI sense data and related stuff. Here's the whole vibe, no gatekeeping.

🌸 SYNOPSIS

sg_decode_sense [--binary=BFN] [--cdb] [--err=ES] [--file=HFN] [--help]
[--hex] [--inhex=HFN] [--ignore-first] [--json[=JO]] [--js-file=JFN]
[--nodecode] [--nospace] [--status=SS] [--verbose] [--version]
[--write=WFN] [H1 H2 H3 ...]

πŸ¦‹ DESCRIPTION

So this utility takes SCSI sense data β€” either in binary or as a sequence of ASCII hex bytes β€” and decodes it for you. The main character reference for the decoding is SPC-5 ANSI INCITS 502-2020 plus the most recent draft SPC-6 revision 6, which you can find at https://www.t10.org and other spots around the internet. iykyk πŸ’…

SCSI sense data shows up in kernel log files all the time, usually because something went wrong, or sometimes just as an informative lil warning πŸ₯Ί It's often printed as a sequence of hex bytes starting with 70, 71, 72, 73, f0 or f1. Sense data can technically be up to 252 bytes long, but honestly it's usually way shorter than that β€” 18 bytes is super common and is normally the older "fixed" format sense data.

You can hand the sense data over on the command line or in a file. On the command line it should be a sequence of hex bytes separated by spaces. Or you can give a file whose contents are binary or ASCII hex bytes. That hex form can have several lines, each with zero, one or more ASCII hex bytes separated by space (or comma, or tab). The hash symbol # may appear, and it plus the rest of that line is ignored β€” so cute for comments πŸŽ€

Now, plot twist β€” if you give the --cdb option, the hex args aren't viewed as sense data anymore, they're viewed as a SCSI command descriptor block (CDB). In that case the command name gets printed. That name is based on the first hex byte you gave (known as the opcode) and optionally on another field called the "service action" ✨

Another alternate action: --err=ES. Here ES is assumed to be an "exit status" value between 0 and 255 from one of the utilities in this package, and a descriptive string gets printed. Other options are ignored apart from --verbose.

And when --nodecode is given, this utility can just be your lil converter β€” binary file to hex or vice versa. The data doesn't even need to be SCSI sense data or CDBs. it's giving swiss army knife πŸ”₯


✨ OPTIONS ✨

Heads up: arguments to long options are mandatory for short options as well.

  • -b, --binary=BFN β€” the data is read in binary from a file called BFN. Can't be given with --file=HFN or --inhex=HFN because those straight up contradict it πŸ™ˆ The data is assumed to be sense data unless --nodecode is given.
  • -c, --cdb β€” treat the given string of hex arguments as bytes in a SCSI CDB and decode the command name.
  • -e, --err=ES β€” ES should be an "exit status" value between 0 and 255, available from the shell (i.e. the utility's execution context) after the utility finishes. By default an indicative error message is printed to stdout; but if --verbose is given once (or an odd number of times) then the message goes to stderr instead. If --verbose is given two or more times, a longer form of the message is output. In all cases the message is less than 128 characters long with one trailing line feed. All other command line options and arguments are ignored. periodt πŸ’…
  • -f, --file=HFN β€” the sense data is read in ASCII hex from a file called HFN. The sense data should appear as a sequence of bytes separated by space, comma, tab, hyphen or newline. Everything from and including a hash symbol to the end of that line is ignored. If --nospace is set, then no separator is required between the ASCII hex digits in HFN, with bytes decoded from pairs of ASCII hex digits.
  • -h, --help β€” output the usage message then exit. classic 🫢
  • -H, --hex β€” this one is used once in conjunction with --write=WFN to change the output written to WFN into lines of ASCII hex bytes suitable for a C language compiler. Each line holds up to 16 bytes (e.g. a line starting with 0x3b,0x07,0x00,0xff). In other cases (i.e. when --write=WFN isn't given, or this option is given more than once) the output is as described in the sg3_utils(8) manpage. The combo of --inhex=HFN with this option used three times is lowkey useful for converting hex bytes (e.g. hyphen separated) into a more regular form. The short option form is more convenient for invoking it three times (e.g. -HHH). obsessed 😍
  • -i, --inhex=HFN β€” same action as --file=HFN. This option was added for compatibility with other utilities in this package that have an --inhex= option.
  • -I, --ignore-first β€” so many programs that output hex bytes (e.g. hexdump -C) put a running count (or index) in the first column of each line. This option ignores the first hex value on each line. It has no effect if --binary=BFN or --nospace are given. Blank lines, and any character from and after # on a line, are ignored. Useful with the --file=HFN and --nodecode options.
  • -j[=JO], --json[=JO] β€” output is in JSON format instead of plain text form. Note that arguments to the short and long form are themselves optional, and if present they start with = β€” and no whitespace is permitted around that =. See the sg3_utils_json manpage, or use ? for JO to get a summary. ✨
  • -J, --js-file=JFN β€” output is in JSON format and it's sent to a file named JFN. If that file exists then it is truncated. By default the JSON output is sent to stdout. When this option is given, --json[=JO] is implied and need not be given. The --json[=JO] option may still be needed to set the JO parameter to non-default values.
  • -N, --nodecode β€” do not decode the given data as sense or a cdb. Useful when arbitrary data is given (e.g. when converting hex to binary or vice versa). main character energy for a converter tbh πŸ‘‘
  • -n, --nospace β€” expect ASCII hex to be a string of hex digits with no spaces between them. Bytes are decoded by taking two hex digits at a time, so an even number of digits is expected. The string of hex digits may be on the command line (replacing H1 H2 H3) or spread across multiple lines of the HFN given to --file=. On the command line, spaces (or other whitespace characters) between sequences of hex digits are ignored; the maximum command line hex string is 1023 characters long.
  • -s, --status=SS β€” where SS is a SCSI status byte value, given in hexadecimal. The SCSI status byte is related to, but distinct from, sense data. not them being siblings πŸ’€
  • -v, --verbose β€” increase the degree of verbosity (debug messages).
  • -V, --version β€” output version string then exit.
  • -w, --write=WFN β€” writes the sense data out to a file called WFN. If necessary WFN is created. If WFN exists then it is truncated prior to writing the sense data to it. If the --hex option is also given then ASCII hex is written to WFN (see the --hex option description); otherwise binary is written to WFN. This option is a convenience and may be helpful in converting the ASCII hex representation of sense data (or literally anything else) into the equivalent binary or a compilable ASCII hex form πŸŽ€

🧚 NOTES

Unlike most utilities in this package, this utility does not access a SCSI device (logical unit). It accesses a library associated with this package β€” and amongst other things, that library decodes SCSI sense data.

The sg_raw utility takes an ASCII hex sequence representing a SCSI CDB. When sg_raw is given the -vvv option, it will attempt to decode the CDB name.

Using the option combination --inhex=HFN --nodecode --write=WFN may be used to convert hexadecimal (as produced by this and other utilities in this package) to binary, where the output file is WFN.

Unlike many other utilities there is no --raw option πŸ™ˆ However binary data can be input using the --binary=BFN option, while binary data can be output using the --write=WFN option (in the absence of the --hex option).


πŸ”₯ EXAMPLES

Sense data is often printed out in kernel logs, and sometimes on the command line when verbose or debug flags are given. It'll be at least 8 bytes long, often 18 bytes long, but may be longer. A sense data string might look like this:

f0 00 03 00 00 12 34 0a  00 00 00 00 11 00 00 00
00 00

Cut and paste it after the sg_decode_sense command:

sg_decode_sense f0 00 03 00 00 12 34 0a 00 00 00 00 11 00 00 00 00 00

and for this sense data the output should look like this:

Fixed format, current;  Sense key: Medium Error
Additional sense: Unrecovered read error
 Info fld=0x1234 [4660]

For a medium error, the Info field is the logical block address (LBA) of the lowest numbered block that the associated SCSI command was not able to read (verify or write). slay 🫢

To convert arbitrary binary data to hex, suitable to be parsed by other sg3_utils utilities, use the --nodecode option:

sg_decode_sense -N -i vpd_zbdc.hex -w vpd_zbdc.bin

The -HHH will output hex to the console (stdout) in a form suitable for other utilities in this package to parse as input. And sg_decode_sense can also be used to convert from arbitrary hex to binary with:

sg_decode_sense -N -b vpd_zbdc.raw -HHH

Note that tools like hexdump and od place a counter (i.e. an index starting at 0) at the beginning of each line, which is a whole pain when parsing hex 😭 The -HHH option(s) does not output that leading counter on each line.


⭐ EXIT STATUS

The exit status of sg_decode_sense is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

πŸ‘‘ AUTHORS

Written by Douglas Gilbert.

πŸ’€ REPORTING BUGS

Report bugs to <dgilbert at interlog dot com>.

Copyright Β© 2010-2022 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

πŸ“ SEE ALSO

sg_requests, sg_raw(sg3_utils)


okay that's the whole page bestie, go decode something iconic πŸ’œ

this lil rewrite is brought to you by sg3_utils-1.48, dated May 2023 β€” the original page was SG_DECODE_SENSE(8), and now it's yours πŸŽ€βœ¨
πŸ“¦ where this page comes from