Read SCSI Mode Pages Safely with sg_modes

Firmware on a disk or tape drive changes, and sg_modes reads its SCSI mode pages to show you exactly what shifted, entirely read-only. This guide uses sg_modes from sg3-utils 1.46-3ubuntu4, whose installed command reports version 1.72 from the 2020 upstream release. You will finish with a repeatable way to inspect the mode pages exposed by a disk, tape drive, enclosure or other SCSI device.

1. Confirm the installed interface

Check the binary, package and version before copying examples. These are ordinary read-only commands:

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

The preferred interface uses long options, such as --page=10. Short options are available, but the command also has an older option syntax selected with --old. Keep the newer form in scripts unless you are maintaining an existing older invocation.

Checkpoint: If sg_modes --version does not run, stop and repair the package or PATH before troubleshooting a SCSI device.

2. List page names without touching a device

Start with the built-in list. With no device, sg_modes assumes a disk-like peripheral type and prints common page and subpage names:

$ sg_modes --list
    Assume peripheral device type: disk
Page[,subpage]   Name
=====================
 0x00            Unit Attention condition [vendor specific format]
 0x01            Read-Write error recovery
 0x02            Disconnect-Reconnect
 0x08            Caching

Do not confuse a page number with a Linux device name. Page 0x08 means a SCSI mode page; it does not identify a disk or partition.

3. Read the device's current pages

Set a real device path in a shell variable so a pasted command has one obvious value to review:

$ DEVICE=/dev/sg3
$ test -r "$DEVICE" && echo "readable: $DEVICE"
readable: /dev/sg3
$ sg_modes --all "$DEVICE"

--all requests all mode pages reported by the device, but not subpages. Omit --page and skip --list, and the command behaves as though --all was selected. It decodes known page and subpage numbers into text, then shows the page contents in hexadecimal. Block descriptors are normally included when the device returns them.

For one page, make the scope explicit. The page code may be decimal, hexadecimal with a 0x prefix, or an acronym from the list:

$ sg_modes --page=8 "$DEVICE"
$ sg_modes --page=co "$DEVICE"
$ sg_modes --page=10,1 "$DEVICE"

The first two examples select the caching or control page as named by the installed utility. The third selects page 10, subpage 1. A device may reject a page that it does not implement, so a failed request is not evidence that sg_modes itself is broken.

Checkpoint: Save the normal decoded output before experimenting with formatting. It is the easiest record to compare after a firmware change or a storage-path investigation.

4. Choose the page control deliberately

Each page can have up to four views:

$ sg_modes --page=8 --control=0 "$DEVICE"
$ sg_modes --page=8 --control=1 "$DEVICE"
$ sg_modes --page=8 --control=2 "$DEVICE"
$ sg_modes --page=8 --control=3 "$DEVICE"

These commands still only issue MODE SENSE requests. The changeable view tells you which fields could be changed by a separate MODE SELECT operation; it is not a request to change them. Saved values are what the device says it will reinstate after a power cycle or reset. Devices vary, and some do not provide every useful view.

Do not infer a safe setting from a hex byte alone. Page layout depends on the SCSI command set and device. Use sdparm when you need decoded fields or an intentional mode-page change, and treat that as a separate, change-sensitive task.

5. Handle MODE SENSE 6 and 10 differences

sg_modes sends the 10-byte MODE SENSE command by default. Older SCSI devices, including some SCSI-2 tape drives, may support only the 6-byte command. If the normal request fails with an illegal command operation code, retry with --six:

$ sg_modes --all --six "$DEVICE"
$ printf 'exit status: %s\n' "$?"
exit status: 0

The actual output and status depend on the device. --flexible helps with bridges or drivers that translate between 6-byte and 10-byte commands without correcting the response length:

$ sg_modes --all --flexible "$DEVICE"

Use --six when the device requires it, not as a general quality improvement. The 6-byte form has a smaller maximum allocation length, 252 bytes by default, whereas the 10-byte form defaults to 4096 bytes. Set an explicit limit with --maxlen, but it must fit the selected command form.

6. Make output suitable for comparison or capture

$ sg_modes --page=8 --dbout "$DEVICE"
$ sg_modes --page=8 --dbd "$DEVICE"

If an older device reports an illegal request after --dbd, retry without it. Do not repeatedly add options to a failing command without recording which change fixed the response.

For machine capture, --hex once prints the response in hexadecimal. Twice also prints page numbers and control values in hex. Three times emits the full MODE SENSE response in hex without decoding, which can be redirected and later decoded by sdparm --inhex=:

$ sg_modes --page=8 --hex --hex --hex "$DEVICE" > mode-page-08.hex
$ test -s mode-page-08.hex && echo 'capture written'
capture written

The filename is new in this example, so the command does not alter the device. Check the file before sharing it: raw or low-level captures can reveal device identifiers and storage details.

7. Diagnose failures without escalating blindly

An invalid path or a non-SCSI file produces an operating-system or INQUIRY error. For example, /dev/null is not a valid test device:

$ sg_modes --all /dev/null
inquiry: pass-through os error: Inappropriate ioctl for device
/dev/null doesn't respond to a SCSI INQUIRY
sg_modes failed: Inappropriate ioctl for device

Use the path reported by your storage configuration, then check it without changing anything:

$ ls -l "$DEVICE"
$ test -e "$DEVICE" && echo 'device path exists'
$ sg_modes --help | sed -n '1,24p'

A permission error may justify sudo sg_modes ..., but root cannot make an absent SCSI endpoint appear. A transport, enclosure or device firmware problem may need investigation at a lower layer. Keep --readwrite out of read-only inspection: it changes how the device is opened, and this utility does not need it to read mode pages.

Safety boundary: sg_modes does not provide a mode-page editing facility. Do not treat its changeable or saved output as a write command, and do not pipe binary output into an unreviewed tool. There is nothing to undo in the read-only examples above. If you deliberately open a device read-write for a separately justified test, close the command and return to the default read-only invocation afterwards.

Done means