Inspect SCSI Command Support Safely with sg_opcodes

A storage vendor's spec sheet claims support for a command, and sg_opcodes lets you ask the device itself rather than trust the marketing. You will finish with a repeatable way to list which commands it supports, inspect one operation code, and look up a command name without touching a device. The examples use sg_opcodes from sg3-utils 1.46-3ubuntu4, whose installed utility reports version 0.69 20210319.

1. Confirm the installed tool

Start with ordinary, read-only checks. They do not need elevated privileges:

$ command -v sg_opcodes
/usr/bin/sg_opcodes
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
$ sg_opcodes --version
Version string: 0.69 20210319

The preferred syntax uses long options. The manpage also documents an older option style, but the newer form makes the meaning of an option clearer. Do not mix an old-style assumption about hexadecimal values with the newer syntax: in the preferred form, opcode and service-action values are decimal unless prefixed with 0x or suffixed with h.

Checkpoint: If command -v finds nothing, install or enable the distribution package through your normal change process. Do not copy an unverified binary into /usr/local/bin just to make the example run.

2. Choose the device and list supported commands

Replace /dev/sdX with the device you have positively identified. A block device such as /dev/sda is supported by modern Linux kernels; an /dev/sgN generic device is also appropriate when you need to target the SCSI generic node explicitly.

$ DEVICE=/dev/sdX
$ sg_opcodes "$DEVICE"
VENDOR PRODUCT REVISION
... device inquiry summary ...
Opcode  Service Action  CDB Size  Command Name
... supported commands ...

The exact vendor strings and command rows depend on the target. By default the utility performs an INQUIRY first, prints a summary, then sends REPORT SUPPORTED OPERATION CODES. The returned list is sorted numerically by opcode and then service action unless you request another order.

If the device refuses the request, first check that DEVICE names the intended target and that your account can read it. Retry with sudo only when the error is a permissions error:

$ sudo sg_opcodes "$DEVICE"

This is an ordinary query, not a repair command. A SCSI target can legally reject REPORT SUPPORTED OPERATION CODES, and a rejection does not prove the device is absent or damaged.

3. Inspect one opcode in detail

Use --opcode when the full list is too noisy or when you need the device's answer for one command. The value below is an example only:

$ sg_opcodes --opcode=0x93 "$DEVICE"
Opcode=0x93
Command_name: Write same(16)
Command supported [conforming to SCSI standard]
Usage data: ...

The response is device-specific, so treat the output as evidence rather than as a promise that every command can safely be issued. An opcode may have service actions. Give one explicitly when you need to distinguish it:

$ sg_opcodes --opcode=0x9b,0xa "$DEVICE"

These values are parsed as hexadecimal because they use the 0x prefix. The opcode range is 0 through 255, and a service action can range from 0 through 65535. Use --opcode=OP without a service action for a command that has one, and the utility assumes service action zero, which is not the same request as omitting a service action for a command that has none.

4. Look up a command name without hardware

--enumerate is useful while reading a trace or a SCSI specification. It ignores DEVICE, so this is a read-only local lookup:

$ sg_opcodes --enumerate --opcode=0x9b,0xa
SCSI command:
  Read buffer(16), read data from echo buffer

Omit the values and they default to opcode zero, peripheral device type zero and no service action:

$ sg_opcodes --enumerate
SCSI command:
  Test Unit Ready

When a name depends on the peripheral device type, add --pdt. This changes the lookup context; it does not query or alter a device:

$ sg_opcodes --enumerate --pdt=0 --opcode=0x12

The utility's exit status is zero on success. An unknown or unsupported combination can produce an error, so keep the output and status together when using this in a script.

5. Query task management functions separately

Use --tmf to send REPORT SUPPORTED TASK MANAGEMENT FUNCTIONS instead of listing operation codes:

$ sg_opcodes --tmf --no-inquiry "$DEVICE"
Task Management Functions supported by device:
    Abort task
    Abort task set
    Clear ACA
    Clear task set
    Logical unit reset
    Query task

The exact functions vary by device. In this mode, options such as --opcode, --sa, --alpha and --unsorted are ignored. --no-inquiry suppresses the preliminary inquiry summary; it does not suppress the task-management report itself.

Warning: do not confuse querying supported task management functions with invoking one. sg_opcodes --tmf reports capabilities only. Issuing a task-management function through another tool can disrupt I/O, so keep that work outside this read-only check and use an approved maintenance procedure.

6. Control output for scripts and troubleshooting

Reserve --raw for a program that explicitly expects binary data. It writes the response to standard output, so piping it to a terminal can produce unreadable output. Capture it deliberately:

$ sg_opcodes --raw --no-inquiry "$DEVICE" > sg-opcodes-response.bin
$ wc -c sg-opcodes-response.bin

The file is a diagnostic artefact, not a configuration file. Remove it through your normal data-retention process when it is no longer needed. Do not feed raw output to a text parser and assume displayed bytes are a decoded command list.

7. Check the result before acting on it

For a useful record, keep the command, utility version, device path, exit status and output together:

$ sg_opcodes --compact --no-inquiry "$DEVICE" | tee sg-opcodes.txt
$ status=${PIPESTATUS[0]}
$ printf 'sg_opcodes exit status: %s\n' "$status"
$ test "$status" -eq 0

The device path can be unstable across reboots, especially when several similar disks are present. Before saving a report, confirm the target with your normal udev or storage inventory tools. Never select a disk from a copied example because its name happens to match your own.

Done means