Home / Alt manpages / sg_read_long(8)

  • sg_read_long(8)
  • Admin command
  • linux

Read a SCSI Long Block Safely with sg_read_long

You will finish with a repeatable way to send a SCSI READ LONG command to one device, inspect the returned block and ECC data, and save the result as binary when that is more useful than a terminal dump. The installed command here is sg_read_long version 1.27 (20180627), from package sg3-utils 1.46-3ubuntu4.

Allow about fifteen minutes. You need a Linux shell, the sg3-utils package and the correct SCSI generic device path. This is a low-level diagnostic read, but it still touches real storage hardware. It does not repair a block, remap a defect or write data. Do not guess the device path, and do not paste a production path into a script until you have checked it.

1. Check the installed command

Start with the read-only help and version checks. These do not need elevated privileges and do not access a disk:

$ sg_read_long --version
sg_read_long: version: 1.27 20180627
$ sg_read_long --help
Usage: sg_read_long [--16] [--correct] [--help] [--lba=LBA] [--out=OF]
                    [--pblock] [--readonly] [--verbose] [--version]
                    [--xfer_len=BTL] DEVICE

The version output is useful when comparing a result with another host. The local manpage is labelled sg3_utils 1.42, while the installed Debian package and executable report newer package metadata and an older-looking utility version string. Record both when you hand the result to somebody else.

Checkpoint

Confirm the command is the one from your PATH:

$ command -v sg_read_long
/usr/bin/sg_read_long
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4

2. Identify the exact device

Use the SCSI generic device that represents the target. A path such as /dev/sg3 is only an example, not a safe universal default. On a host with several disks, confirm the mapping with your normal inventory tooling before continuing. If you are unsure whether a path is a disk, enclosure, tape drive or another SCSI target, stop and ask the system owner.

Keep the device in a shell variable so the command is easy to review:

DEVICE='/dev/sgX'
printf 'target: %s\n' "$DEVICE"
test -e "$DEVICE"

Replace /dev/sgX with the verified path. The final command's positional DEVICE argument is mandatory. A failed test means the path does not exist; it is not a reason to try a nearby number.

Access to a SCSI generic device is commonly restricted. If the normal command reports a permissions error, retry only the already-reviewed command with the least privilege your device policy permits, usually through an approved administrative shell or group. Do not broadly change device permissions just to make this one read work.

3. Read the default logical block

The default operation sends READ LONG(10) for logical block address zero, with a 520-byte transfer length. The output is a human-readable hexadecimal and ASCII view on standard output:

$ sg_read_long --lba=0 --xfer_len=520 "$DEVICE"
Read long starting at lba=0, with 520 bytes (10 bytes command)
00000000  ... hexadecimal bytes and an ASCII column ...
... device-specific output ...

The exact heading and bytes depend on the target, so treat the sample as shape rather than a literal transcript. A successful command exits with status zero. Check it immediately:

$ status=$?
$ printf 'sg_read_long exit status: %s\n' "$status"
sg_read_long exit status: 0

Do not infer that the returned bytes are ordinary user data. A long block normally contains the logical block, often 512 bytes, followed by ECC information and possibly other proprietary data. The logical data can also be encoded or encrypted. The ECC layout is device-specific, so this utility is useful for capture and comparison, not for decoding every vendor format.

4. Correct the transfer length after a mismatch

The default is 520 bytes, but a device's long-block size may differ. If the transfer length is wrong, sg_read_long can report the appropriate length on standard error. Read that diagnostic and retry with the value it gives you:

$ sg_read_long --lba=0 --xfer_len=520 "$DEVICE" > /tmp/sg-read-long.txt
sg_read_long: ... device reports a different long block length ...
$ sg_read_long --lba=0 --xfer_len=REPORTED_LENGTH "$DEVICE"
... hexadecimal and ASCII output ...

REPORTED_LENGTH is a placeholder. Replace it with the decimal value printed by your device, and keep the output file in /tmp only if its contents are not sensitive. Remove that temporary capture when it is no longer needed. If the command keeps failing, preserve the complete error text and check the device documentation instead of repeatedly guessing lengths.

5. Select the address and command width

Use --lba for a different logical block. Decimal is the default; a value beginning with 0x or ending in h is hexadecimal:

$ sg_read_long --lba=12345 --xfer_len=LONG_LENGTH "$DEVICE"
$ sg_read_long --lba=0x3039 --xfer_len=LONG_LENGTH "$DEVICE"
$ sg_read_long --lba=3039h --xfer_len=LONG_LENGTH "$DEVICE"

These three examples name the same address. The numeric parser also accepts documented multiplicative suffixes such as 2k, but a plain decimal or hexadecimal address is easier to audit in an incident record.

READ LONG(10) has a 32-bit LBA field. If the address is larger than that, add --16 to select READ LONG(16), whose LBA field is 64 bits:

$ sg_read_long --16 --lba=0x100000000 --xfer_len=LONG_LENGTH "$DEVICE"

The --16 option changes the SCSI command format. It does not make an older target support an operation that the target rejects.

6. Save binary output when another tool needs it

Use --out=FILE to write the returned bytes in binary instead of rendering ASCII hex. This changes where the capture is written, not what the device reads:

$ sg_read_long --lba=0 --xfer_len=LONG_LENGTH \
    --out=/tmp/sg-read-long.bin "$DEVICE"
$ file /tmp/sg-read-long.bin
/tmp/sg-read-long.bin: data

Informational and error messages go to standard error when binary output is selected. Never redirect this mode to a terminal. --out=- sends binary output to standard output, which is suitable for a deliberately constructed pipeline but easy to corrupt by mixing diagnostic text into it.

The capture may contain storage contents and proprietary ECC information. Treat it as sensitive operational data, restrict access, and delete it after the approved analysis. This guide does not provide a recovery command because the read itself does not alter the device; recovery means removing only the capture file you created:

$ rm -- /tmp/sg-read-long.bin

7. Understand the two important flags

--correct sets the command's CORRCT bit. The device corrects the data with ECC before transferring it back. Without that flag, the default leaves correction clear. Compare corrected and uncorrected reads only when your device documentation says that comparison is meaningful.

--pblock sets PBLOCK and asks for the physical block containing the requested logical address, including its ECC data. It is not a way to discover an arbitrary physical disk location, and it does not bypass the target's translation or protection rules.

--readonly opens the device read-only instead of the default read-write open. That sounds safer, but the local manpage warns that the Linux sg driver needs read-write access for READ LONG, while other access methods may accept read-only access. Try it only when your access method requires it:

$ sg_read_long --readonly --lba=0 --xfer_len=LONG_LENGTH "$DEVICE"
... success, or an access-method error ...

An error here does not mean the media read would have written data. It means the selected open mode is incompatible with the path used by this driver or target.

8. Handle failures without hiding the cause

Capture both output streams when diagnosing a failure, and preserve the exit status:

$ sg_read_long --lba=0 --xfer_len=LONG_LENGTH "$DEVICE" \
    >/tmp/sg-read-long.stdout 2>/tmp/sg-read-long.stderr
$ status=$?
$ printf 'exit status: %s\n' "$status"
exit status: NON_ZERO_STATUS
$ sed -n '1,40p' /tmp/sg-read-long.stderr

Replace NON_ZERO_STATUS with the value printed by your shell; it is intentionally not a fabricated device result. Check, in order, that the path names the intended target, the device accepts READ LONG, the LBA is valid, the transfer length matches the target, and your access permissions are sufficient. Do not treat a non-zero status as proof that a block is defective. The command can fail before it reads media.

If the device reports a defective block after its contents have been retrieved, the manpage points to sg_reassign as a separate maintenance operation. Do not run it as an automatic follow-up: remapping changes device state and needs a documented maintenance decision, backups and vendor guidance.

Done means

  • You verified the installed sg_read_long and sg3-utils versions.
  • You confirmed the exact SCSI generic device instead of guessing a path.
  • You used the device's reported long-block size, or recorded why the default was appropriate.
  • You chose READ LONG(10) or READ LONG(16) to match the LBA range.
  • You checked the exit status and kept diagnostic output separate from binary data.
  • You treated captures as sensitive and removed temporary files when the analysis ended.