Read SCSI Disk Capacity Safely with scsi_readcap

Reach for scsi_readcap when you need a disk's exact block count and block size without touching the device itself. It is a shell wrapper around sg_readcap: normally it tries READ CAPACITY(10), and it can request READ CAPACITY(16) when you need the bigger response. Allow about ten minutes, including time to confirm the device name. You need the sg3-utils package and a readable SCSI or SCSI-emulating block device.

This guide describes the installed Ubuntu package sg3-utils 1.46-3ubuntu4. The local manual page identifies its documentation as sg3_utils-1.36, while the installed command itself reports version 4.05 from January 2020. Keep that gap in mind when comparing output with another host.

1. Check the wrapper before touching a disk

Confirm which executable will actually run and read its usage message first:

$ command -v scsi_readcap
/usr/bin/scsi_readcap
$ scsi_readcap --help
Usage: scsi_readcap [-b] [-h] [-l] [-v] <device>+
  where:
    -b, --brief          output brief capacity data
    -h, --help           print usage message
    -l, --long           send longer SCSI READ CAPACITY (16) cdb
    -v, --verbose        more verbose output

The command requires at least one device. Use a real path such as /dev/sdb, not a partition, when you want the capacity of the whole disk. Confirm the path first:

$ ls -l /dev/sdX
$ readlink -f /dev/sdX

Checkpoint: stop if the resolved path is not the disk you intend to inspect. The query is read-only, but a wrong device name can still hand you misleading capacity information as if it were correct.

2. Run the normal capacity query

Replace /dev/sdX with the confirmed device:

$ scsi_readcap /dev/sdX
sg_readcap   /dev/sdX
Read Capacity results:
  Last block address: 0x...
  Number of blocks:    ...
  Block size:          ... bytes

The exact formatting comes from the installed sg_readcap. In the default mode, the wrapper sends READ CAPACITY(10). If that response indicates at least 2**32 - 1 blocks, the script then sends READ CAPACITY(16) and prints that response instead. The output above is a shape, not a promise of particular values: the block count and size belong to your device, not this page.

Do not pipe this through something that captures only the final line and assumes it is always the first response. A large device can trigger that automatic second query without warning.

3. Request the longer READ CAPACITY(16) response

Use --long when you need the 16-byte CDB and its extra response fields:

$ scsi_readcap --long /dev/sdX
sg_readcap --16  /dev/sdX
Read Capacity results:
  ...

The wrapper translates --long to --16 for sg_readcap. This is a query, not a resize operation. It does not change a partition table, filesystem or device capacity. Some older devices do not support READ CAPACITY(16); if the underlying utility reports a SCSI or transport error, retry the default mode and inspect the device and connection rather than hammering it with repeated requests.

Use --verbose when the ordinary diagnostic is too thin:

$ scsi_readcap --long --verbose /dev/sdX

More verbosity helps for troubleshooting, but it is usually the wrong format for a monitoring script. Do not parse the human-readable default output unless you control the package version everywhere it runs.

4. Produce two values for a script

Pass --brief when a script only needs the number of blocks and the size of each block:

$ scsi_readcap --brief /dev/sdX
0x12a19eb0 0x200

The first hexadecimal value is the available block count and the second is the block size in bytes. Both carry a 0x prefix. Convert them deliberately in whatever language consumes them; do not treat the first number as a byte count, it is not one.

For multiple devices, list each path after the options:

$ scsi_readcap --brief /dev/sdX /dev/sdY
0x12a19eb0 0x200
0x746a8c00 0x1000

In brief mode, an error is represented by 0x0 0x0, and the wrapper carries on to later devices regardless. That makes the output convenient but lossy. If zero capacity is a real possibility in your environment, pair the result with a separate exit-status check or fall back to the normal output for investigation.

5. Handle permissions and failures

Run the command as your normal user first. If it cannot open the device because of permissions, rerun only that read-only query with the privilege your host requires:

$ scsi_readcap /dev/sdX
$ sudo scsi_readcap /dev/sdX

sudo does not repair a missing device, an unsupported SCSI command or a failed cable. Avoid making a permanent device-node permission change just to run this check. Ask your system administrator if a service account genuinely needs recurring access.

Capture the status immediately if a script needs to tell success from failure:

if scsi_readcap --brief /dev/sdX >capacity.txt; then
    printf '%s\n' 'capacity query succeeded'
else
    status=$?
    printf 'capacity query failed with status %s\n' "$status" >&2
    exit "$status"
fi

The manual says the wrapper returns zero on success and otherwise returns the status from the last sg_readcap invocation. With several devices, do not assume an earlier failure will still be visible if a later query succeeds. Keep the output file only if the status and values are acceptable. A failed redirection can leave an empty or partial file, so write to a temporary name and replace an existing report only after validation.

Done means