Home / Alt manpages / sg_get_lba_status(8)

  • sg_get_lba_status(8)
  • Admin command
  • linux

Check Thin-Provisioned LBA Ranges with sg_get_lba_status

A thin-provisioned volume can claim space it never actually allocated, and sg_get_lba_status shows you which blocks are real. It decodes a SCSI device's logical block provisioning status, optionally narrowed to a starting LBA or report type, and stays read-only when opened with --readonly. Allow about 10 minutes if you already know the device path; the slower part is identifying the correct SCSI device and interpreting storage-specific results.

Before you start

You need the sg3-utils package and a device that accepts GET LBA STATUS. The installed program on this system is sg3-utils 1.46-3ubuntu4 and reports version 1.21 (20190913). The command sends either the 16-byte or 32-byte SCSI command variant. A device that supports logical block provisioning should support the 16-byte command, but support still depends on the device and its SCSI implementation.

Set the placeholder below to the SCSI device you intend to inspect. Do not guess if several disks, paths or enclosures are present. Confirm the path with your normal inventory process first. The examples use /dev/sgX only as a visible placeholder, not as a path to copy unchanged.

1. Confirm the installed command

Run this as your ordinary user. It does not contact a device.

sg_get_lba_status --version
sg_get_lba_status --help

Expected version output on the system described here is:

version: 1.21 20190913

The help text also confirms that the default command is GET LBA STATUS(16), and that the default maximum response length is 24 bytes. Those details matter when comparing output from different hosts or package versions.

2. Run a safe baseline query

Use --readonly explicitly. Without it, the program opens the device read-write by default, even though this particular SCSI command asks for status rather than changing provisioning.

sudo sg_get_lba_status --readonly /dev/sgX

sudo is needed only when your account cannot open the device. The command should print a header followed by one LBA status descriptor per line. The descriptor LBA is hexadecimal, the block count is decimal, and provisioning and additional status values are decimal. A successful exit has status 0.

Checkpoint

Stop here if the command reports an unavailable device, an unsupported SCSI command or a permissions error. Check the path, device health and access rights before adding options. Do not treat a failed query as proof that every block is mapped.

3. Reduce the output to descriptor lines

For scripts or a long response, use one --brief. Each returned line has the starting LBA and block count in hexadecimal, followed by provisioning status and additional status in decimal.

sudo sg_get_lba_status --readonly --brief /dev/sgX

The provisioning status values currently used by the utility are 0 for mapped or unknown, 1 for unmapped, 2 for anchored, 3 for mapped and 4 for unknown. The command can represent values through 15, so keep the numeric value when recording results rather than assuming that every future device uses only those five meanings.

To ask for the status covering a particular starting LBA, add --lba:

sudo sg_get_lba_status --readonly --lba=0x100000 --brief /dev/sgX

The device chooses how many following blocks to describe. The option sets the starting LBA; it does not request exactly one block.

4. Ask for a particular provisioning class

Report type 1 requests LBAs with a non-zero provisioning status. Report types 2, 3 and 4 request mapped, de-allocated and anchored LBAs respectively. Report type 16 requests LBAs that may return an unrecovered error.

sudo sg_get_lba_status --readonly --32 --report-type=1 --brief /dev/sgX

The 32-byte command variant is useful when you need the options that are specific to it. --element-id selects a non-zero physical element identifier, and --scan-len limits the number of contiguous logical blocks scanned. A scan length of 0 means no limit. For example:

sudo sg_get_lba_status --readonly --32 --report-type=1 --scan-len=1048576 --brief /dev/sgX

The response includes an RTP indication showing whether the device acted on the report type. Read that indication rather than assuming a filter was honoured. The report type field was added in SBC-4 revision 12, so older or less capable devices may not apply it.

5. Use the compact status check

Two brief options change the output from descriptor lines to the provisioning status for the requested LBA, or LBA 0 when --lba is absent:

sudo sg_get_lba_status --readonly --brief --brief --lba=0x100000 /dev/sgX

The utility checks that the requested LBA falls within the first returned descriptor's range. If it does not, warnings go to standard error. Preserve both standard output and standard error in automated checks so that a numeric answer is not mistaken for a valid range match.

Handling response size and diagnostics

The default allocation length is 24 bytes, enough for the response header and one 16-byte descriptor. To receive more descriptors, use a value that is 8 plus a multiple of 16, such as 40 or 56:

sudo sg_get_lba_status --readonly --maxlen=56 --brief /dev/sgX

The device may still return fewer descriptors. A larger allocation length does not force it to scan or report a particular range.

For troubleshooting, --hex prints the response as ASCII hexadecimal, while --verbose adds debugging output on standard error:

sudo sg_get_lba_status --readonly --hex --verbose /dev/sgX

Do not use --raw in a terminal. It writes binary response data to standard output. If you redirect it to a file, treat that file as sensitive device metadata and remove it using your normal retention policy when it is no longer needed. This query does not provide an undo operation because it does not change the device.

Decode a saved response without touching a device

If you have a response captured as ASCII hexadecimal, --inhex decodes the file instead of sending the command to the device. When --inhex is present, any DEVICE argument is ignored. This makes it the safest way to reproduce a parsing issue on a test machine.

sg_get_lba_status --inhex=/path/to/response.hex --brief

With --raw as well, the input file is treated as binary rather than ASCII hexadecimal. Keep the two cases distinct, and do not feed an arbitrary file to the parser as if it were a captured response.

Common traps

  • Wrong command variant: --16 is the default. If both --16 and --32 are supplied, the 16-byte variant wins. Use one explicitly when documenting a test.
  • Assuming a filter worked: report type support is device-dependent. Check the response's RTP indication and compare with an unfiltered query.
  • Reading units incorrectly: descriptor LBAs and block counts change representation in brief mode. The first two fields are hexadecimal; the two status fields are decimal.
  • Confusing status with reclamation: this utility reports provisioning status. It does not de-allocate blocks. Do not substitute it for a command intended to change provisioning.
  • Comparing old captures blindly: SBC-3 revision 25 changed the response Parameter Data Length calculation from byte offset 8 to byte offset 4. Version, device firmware and the command variant all belong in a useful capture record.

Done means

  • Versions confirmed. You checked the installed sg3-utils and sg_get_lba_status versions.
  • Baseline query run. You queried the intended device with --readonly and recorded the exit status.
  • Output type known. You know whether the output is a full decode, brief descriptors or a single-LBA status.
  • Filters checked. If you used report type, element ID or scan length, you checked the device response rather than assuming the option was honoured.
  • Captures kept separate. You kept any hexadecimal or binary capture separate from the live device and used the correct input mode when replaying it.