Measure SCSI Transport Throughput Safely with sg_rbuf
You will finish with a repeatable READ BUFFER throughput test for a Linux SCSI generic device, plus enough evidence to tell a transport limit from a slow disk or an unsuitable test target. The examples use the installed sg3-utils package, version 1.46-3ubuntu4. Its binary reports version 5.08 20200501; the local manpage is from sg3_utils 1.43, so the installed help output is the final word for options on this host.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes if the device path is already known. You need a shell, the sg3-utils package, and an accessible SCSI generic device such as /dev/sg1. The test reads and discards data. It does not write blocks or firmware, but it does create sustained device and bus traffic, so do not run it against a busy production device without an agreed test window.
1. Confirm the installed command
Start with read-only checks. These commands do not need elevated privileges:
$ command -v sg_rbuf
/usr/bin/sg_rbuf
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
$ sg_rbuf --version
Version string: 5.08 20200501
Checkpoint: read the local option summary before copying an example. The preferred syntax uses long options, and the device argument is mandatory:
$ sg_rbuf --help
Usage: sg_rbuf [--buffer=EACH] [--dio] [--echo] [--help] [--mmap]
[--quick] [--size=OVERALL] [--time] [--verbose] [--version]
SG_DEVICE
The installed binary exposes --echo, which is not present in the older local manpage. This guide stays with the options documented by the manpage and verified by the command. If you need echo-buffer mode, inspect the installed help and device documentation first rather than assuming that data mode and echo mode measure the same path.
2. Identify an sg device
sg_rbuf is Linux-only and requires a SCSI generic device node. It does not accept an ordinary block path such as /dev/sdc in place of /dev/sg1:
$ ls -l /dev/sg*
crw-rw---- 1 root disk 21, 1 ... /dev/sg1
$ test -r /dev/sg1 && echo readable
readable
Replace /dev/sg1 with the actual target on your host. Do not infer the mapping from a stale note or guess a number. Use the SCSI generic devices exposed by the running system and confirm the target with your normal inventory tools. If the node is not readable, ask for the least privilege needed to access it. Running the whole shell as root is not a substitute for selecting the right device.
Checkpoint: stop here if you cannot identify the target. A wrong SCSI generic path can benchmark a different disk, a tape device or another transport entirely.
3. Run a baseline transfer
The default total transfer is 200 MiB. The command asks the device for its READ BUFFER capacity, chooses a buffer size up to that capacity, repeatedly reads from buffer mode 0, and discards the returned data:
$ sg_rbuf --time /dev/sg1
READ BUFFER reports: buffer capacity=...,
offset boundary=...
Read 200 MiB (actual ... MiB, ... bytes),
buffer size=... KiB
Time ... seconds, ... MB/sec
Exact numbers and timing vary by device. The output should include the reported capacity, the requested and actual transfer, and the buffer size. With --time, the program times the bulk transfer and reports MB as 1,000,000 bytes. The manpage's example shows that the actual total can be slightly lower than requested because the command uses equal-sized transfers and integer division.
A zero exit status means the utility completed successfully. Capture it immediately if a script or test harness needs the result:
$ status=$?
$ printf 'sg_rbuf exit status: %s\n' "$status"
sg_rbuf exit status: 0
Do not treat a plausible speed as proof that the disk media is fast. READ BUFFER normally sources data from device memory, so this is primarily a SCSI transport, adapter, driver and host-memory test. It is not a normal filesystem read benchmark.
4. Compare user-space and quick transfers
Run the baseline more than once if you need a stable comparison, then try --quick:
$ sg_rbuf --quick --time /dev/sg1
READ BUFFER reports: buffer capacity=...
Read 200 MiB (actual ... MiB, ... bytes),
buffer size=... KiB
Time ... seconds, ... MB/sec
--quick asks the SCSI generic driver to transfer into kernel buffers without moving the data into user space. It is only available with an sg device. A higher result can show that copying into user memory was part of the baseline cost; it does not mean that an application will receive data at the quick-mode rate.
Try direct or memory-mapped I/O only as controlled comparisons:
$ sg_rbuf --dio --time /dev/sg1
$ sg_rbuf --mmap --time /dev/sg1
--dio requests direct I/O and --mmap requests memory-mapped I/O. The driver may report that the requested method is unavailable and fall back to indirect I/O. Record that message with the timing. These options do not improve a measurement merely because they are present, and --quick takes precedence over direct I/O in the installed help.
5. Control test size and each transfer
Use --size when 200 MiB is too much for a quick smoke test or too little for a comparison:
$ sg_rbuf --size=64M --time /dev/sg1
Read 64 MiB (actual ... MiB, ... bytes),
buffer size=... KiB
The preferred syntax takes the overall size in bytes and accepts numeric suffixes supported by sg3_utils. The default is 200 MiB, where MiB means 1024 squared bytes. Do not confuse that with the MB/sec unit printed by the timer.
--buffer reduces the bytes transferred by each READ BUFFER command. It cannot increase the device's reported capacity:
$ sg_rbuf --buffer=65536 --size=64M --time /dev/sg1
Use a smaller per-command buffer when comparing command overhead or when an adapter behaves poorly with larger requests. Otherwise, leave it at the reported default. If you use the older interface with --old, the units change: -b is in KiB and -s is in MiB. Do not mix those old-style units into the preferred syntax.
6. Diagnose failures without changing the device
For a failure, first rerun with one or more --verbose options and keep the complete output:
$ sg_rbuf --verbose --time /dev/sg1
$ printf 'exit status: %s\n' "$?"
exit status: 1
Non-zero status means the test did not complete successfully. Check the path, permissions and device type before trying another option. A missing or inaccessible sg node is different from a SCSI CHECK CONDITION returned by the target. If the device is shared with a service, stop and use that service's maintenance procedure instead of repeatedly probing it.
There is nothing persistent to undo after a completed read test: the utility discards the data it retrieves. If the test is still running and it is safe to stop it, press Ctrl-C. Treat the resulting measurement as incomplete. Do not use sg_rbuf for firmware downloads; the manpage identifies sg_write_buffer as the separate utility for writing buffer data.
Done means
- You confirmed the installed package and binary version.
- You selected the correct Linux SCSI generic device and checked access.
- You recorded a timed baseline and, where useful, a
--quickcomparison. - You understand that READ BUFFER measures a transport and cache path, not ordinary media or filesystem performance.
- You kept the test size, units, fallback messages and exit status with the result.
- You did not write data, alter firmware, change configuration or leave a service disrupted.