Safely Exercise a SCSI Disk Cache with sg_seek
You will finish with a checked sg_seek command for sending a SCSI SEEK or PRE-FETCH request to a device, plus a shell pattern that handles its unusual success statuses. Allow about fifteen minutes, including the time to identify the correct device. This guide assumes the sg3-utils package is installed. The examples here use package version 1.46-3ubuntu4; the installed utility reports 1.08 20200115, while its local manual page is labelled sg3_utils 1.43.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a storage-device command, not a file-cache command. It sends a SCSI command through the device interface. It normally does not write user data, but a request can consume device cache and I/O time, and a wrong device can affect a live workload. Plan the target before running anything that sends a command.
1. Confirm the installed interface
Start with the binary and its built-in help. This changes no device state:
$ command -v sg_seek
/usr/bin/sg_seek
$ sg_seek --version
version: 1.08 20200115
$ sg_seek --help
Usage: sg_seek [--10] [--count=NC] [--grpnum=GN] [--help] [--immed]
[--lba=LBA] [--num-blocks=NUM] [--pre-fetch] [--readonly]
[--skip=SB] [--time] [--verbose] [--version]
[--wrap-offset=WO] DEVICE
The final argument is mandatory. The default command is one SEEK(10) request at LBA 0. Adding --pre-fetch selects PRE-FETCH(16), unless --10 is also present, in which case it selects PRE-FETCH(10).
Checkpoint
Confirm the package and binary before copying a command into an operational script:
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
2. Identify the target without sending a command
Use the device path already documented for your host. A SCSI generic path such as /dev/sg3 is a pass-through endpoint; a disk path such as /dev/sdb may also be accepted when the kernel exposes the required interface. Do not guess from the number alone. Check the mapping with your normal inventory tools, for example:
$ ls -l /dev/disk/by-id/ | grep -E 'scsi|wwn'
$ readlink -f /dev/disk/by-id/scsi-REPLACE_WITH_THE_REAL_ID
Replace the example identifier with an entry that you have positively matched to the intended disk or enclosure. This inspection is unprivileged. Opening a device may require elevated access, but sudo does not make an uncertain device choice safe.
Warning
Stop here if you cannot prove which device you are holding. SEEK and PRE-FETCH are advisory cache or positioning operations, but they can still disturb latency on a production device. Do not test against a mounted or busy disk during a sensitive workload without an agreed maintenance window.
3. Test argument handling with no SCSI command
Set --count=0 while preparing a script. The manual says this checks options and opens the device, but sends no commands. It is useful for finding a typo before selecting a real operation:
$ sg_seek --count=0 --readonly /dev/sg3
$ printf '%s\n' "$?"
0
--readonly asks the operating system to open the device read-only where supported. It is a sensible defensive option, but it is not a guarantee that the pass-through operation is logically read-only. The manual warns that operating systems may require a read-write device open because they cannot reliably classify every pass-through command. Treat this test as syntax and access validation, not as a safety certification.
4. Send one PRE-FETCH request
PRE-FETCH is the modern operation in this tool. It asks the device to bring blocks beginning at an LBA into its cache. Choose the block range deliberately. The following sends one PRE-FETCH(16) request for 128 blocks beginning at LBA 1048576:
$ sg_seek --pre-fetch --lba=1048576 --num-blocks=128 --readonly /dev/sg3
$ status=$?
$ printf 'sg_seek exit status: %s\n' "$status"
sg_seek exit status: 0
That output is an example of the successful GOOD result. A device can instead return CONDITION MET, which sg_seek reports with exit status 25. The latter is also a successful result according to the manual: it means the requested blocks fit, or appear likely to fit, in the cache. Do not write a script that treats every non-zero status as failure.
Capture the status immediately, before running another command. For a script, distinguish the two documented successful results from an actual error:
sg_seek --pre-fetch --lba=1048576 --num-blocks=128 --readonly /dev/sg3
status=$?
case "$status" in
0) printf '%s\n' 'PRE-FETCH completed with GOOD' ;;
25) printf '%s\n' 'PRE-FETCH completed with CONDITION MET' ;;
*) printf 'PRE-FETCH failed with status %s\n' "$status" >&2
exit "$status" ;;
esac
5. Choose repetition only when measuring a real workload
--count=NC repeats the selected command. Between commands, --skip=SB advances the LBA by that many blocks; its default is 1. Use --skip=0 to repeat the same LBA. --wrap-offset=WO can reset the next LBA back to the starting value after the configured offset is exceeded. These options make sense for a controlled experiment, not as a casual way to warm an unknown disk.
For example, this runs five PRE-FETCH(10) commands, records elapsed time, and moves forward by 32 blocks each time:
$ sg_seek --10 --pre-fetch --count=5 --lba=1048576 \
--num-blocks=128 --skip=32 --time --readonly /dev/sg3
Command count=5, number of condition_mets=..., number of goods=...
The exact counters and timing depend on the device. With more than one command, the last command determines the process exit status. The summary is printed when --count or --verbose is used, so retain it with the rest of the test record.
6. Diagnose a failed request
An error such as Inappropriate ioctl for device usually means the chosen path does not provide the SCSI pass-through interface expected by the command. For example, this harmless probe opens /dev/null but cannot send a SCSI request:
$ sg_seek --pre-fetch --count=1 --readonly /dev/null
sg_seek: failedInappropriate ioctl for device
number of errors=1
first error: Inappropriate ioctl for device
$ printf '%s\n' "$?"
75
Do not solve that by adding more flags. Recheck the device mapping, permissions, and whether the path is a SCSI-capable block or generic device. If the device is correct but access is denied, ask an administrator to grant the narrowest required access or run the command with the host's approved privilege mechanism. Elevated privileges are not normally required for displaying help, checking the version, or validating options with a permitted device.
If PRE-FETCH returns a real error, reduce the test to one command and a small explicit range, then consult the device logs and the storage owner. Remove the experimental command from an automated job by deleting or disabling that job in its own change-control process; sg_seek does not create a persistent configuration that needs an undo command. Keep the original device and workload settings recorded so a test can be reproduced or stopped cleanly.
Done means
- The installed
sg_seekversion and package version are recorded. - The target device is positively identified, not guessed from a path.
--count=0passed before any SCSI command was sent.- The selected SEEK or PRE-FETCH variant, LBA and block count are explicit.
- A script accepts both exit status 0 and exit status 25 as successful PRE-FETCH results.
- Repeated tests have a maintenance window, a recorded range, and an owner for the resulting I/O load.