SG_RBUF(8)

๐Ÿ’พ sg_rbuf โ€” the SCSI READ BUFFER speed-test bestie

Alright bestie, welcome to sg_rbuf from the sg3_utils squad โœจ this is the sg3_utils man page for SG_RBUF(8) and it's about to be your new fave for timing SCSI transfers, no cap.

โœจ SYNOPSIS โœจ

sg_rbuf [--buffer=EACH] [--dio] [--help] [--mmap] [--quick]
[--size=OVERALL] [--verbose] [--version] DEVICE

sg_rbuf [-b=EACH_KIB] [-d] [-m] [-q] [-s=OVERALL_MIB] [-t] [-v] [-V]
DEVICE

Two whole syntaxes, two whole vibes ๐Ÿ’… the first one is the preferred one and we're explaining that one first, the other one lives further down in its own section.


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

Okay so here's the whole thing: this command reads data using the SCSI READ BUFFER command and then literally just discards it ๐Ÿ—‘๏ธ. The tea is that the data being read typically comes from a disk's memory cache, and it's assumed the sourcing is fast (though the SCSI standards do not guarantee that, so don't come for me), which means it's faster than reading data from the media itself. Basically this command was designed for timing transfer speeds across a SCSI transport. It's giving speedrun energy ๐Ÿ”ฅ.

Now, if you want to fetch the data with a SCSI READ BUFFER command and optionally decode it, that's a whole different girl โ€” see the sg_read_buffer utility. There's also an sg_write_buffer utility, which is useful for downloading firmware amongst other things ๐Ÿ‘‘

This utility supports two command line syntaxes: the preferred one is shown first in the synopsis and explained in this section, and a later section on the old command line syntax outlines the second group of options.

Heads up bestie ๐Ÿซถ this is a Linux only utility and it only works when DEVICE is an sg device (e.g. "/dev/sg1"). The sg_read_buffer utility has similar functionality and is ported to other OSes, and within Linux it can use bsg and normal block device names (e.g. "/dev/sdc").

๐ŸŒธ OPTIONS ๐ŸŒธ

Arguments to long options are mandatory for short options as well. Yes, all of them. Iconic behavior, honestly.

  • -b, --buffer=EACH โ€” where EACH is the number of bytes to be transferred by each READ BUFFER command. The default is the actual available buffer size returned by the READ BUFFER (descriptor) command. And the maximum is the same as the default, hence this argument can only ever be used to reduce the size of each transfer to less than the device's actual available buffer size. So it's a shrinking-only situation ๐Ÿ’€
  • -d, --dio โ€” use direct IO if available. This option is only available if the DEVICE is a sg driver device node (e.g. /dev/sg1). In this case the sg driver will attempt to configure the DMA from the SCSI adapter to transfer directly into user memory, which eliminates the copy via kernel buffers ๐Ÿš€. If it's not available then this will be reported and indirect IO will be done instead. Flexible queen.
  • -h, --help โ€” print usage message then exit. The classic.
  • -m, --mmap โ€” use memory mapped IO if available. Also only available if the DEVICE is a sg driver device node (e.g. /dev/sg1). In this case the sg driver will attempt to configure the DMA from the SCSI adapter to transfer directly into user memory, which eliminates the copy via kernel buffers. Same slay, different flag โœจ
  • -O, --old โ€” switch to older style options. Please use as first option ๐Ÿ™ (they're serious about the "first option" thing).
  • -q, --quick โ€” only transfer the data into kernel buffers (typically by DMA from the SCSI adapter card) and do not move it into the user space. Only available if the DEVICE is a sg driver device node (e.g. /dev/sg1). This is the shortcut that makes your throughput go brrr ๐Ÿ”ฅ
  • -s, --size=OVERALL โ€” where OVERALL is the size of total transfer in bytes. The default is 200 MiB (200*1024*1024 bytes). The actual number of bytes transferred may be slightly less than requested since all transfers are the same size (and an integer division is involved rounding towards zero). Math is mathing, don't @ me ๐Ÿงฎ
  • -t, --time โ€” times the bulk data transfer component of this command. The elapsed time is printed out plus a MB/sec calculation. In this case "MB" is 1,000,000 bytes. The gettimeofday() system call is used internally for the time calculation โฑ๏ธ
  • -v, --verbose โ€” increase level of verbosity. Can be used multiple times. Spam it, live your truth ๐Ÿ—ฃ๏ธ
  • -V, --version โ€” print out version string then exit.

๐Ÿ’œ NOTES ๐Ÿ’œ

This command is typically used on modern SCSI disks which have a RAM cache in their drive electronics. If no IO to the magnetic media, or slower devices like flash RAM, is involved, then the disk may be able to source data fast enough to saturate the bandwidth of the SCSI transport ๐Ÿš„. And then the bottleneck may be the DMA element in the HBA, the Linux drivers, or the host machine's hardware (e.g. speed of RAM). It's giving "it's not me, it's the hardware" energy ๐Ÿ˜ญ.

Various numeric arguments (e.g. OVERALL) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page for that lore ๐Ÿ“–.


โญ EXAMPLES โญ

On the test system /dev/sg0 corresponds to a fast disk on a U2W SCSI bus (max 80 MB/sec). The disk specifications state that its cache is 4 MB.

$ time ./sg_rbuf /dev/sg0
READ BUFFER reports: buffer capacity=3434944,
  offset boundary=6
Read 200 MiB (actual 199 MiB, 209531584 bytes),
  buffer size=3354 KiB
real 0m5.072s, user 0m0.000s, sys 0m2.280s

So that is approximately 40 MB/sec at 40 % utilization. Now with the addition of the "-q" option this throughput improves and the utilization drops to 0%. Look at her go ๐Ÿ‘‘

$ time ./sg_rbuf -q /dev/sg0
READ BUFFER reports: buffer capacity=3434944,
  offset boundary=6
Read 200 MiB (actual 199 MiB, 209531584 bytes),
  buffer size=3354 KiB
real 0m2.784s, user 0m0.000s, sys 0m0.000s

๐ŸŽ€ EXIT STATUS ๐ŸŽ€

The exit status of sg_rbuf is 0 when it is successful ๐ŸŽ‰. Otherwise, see the sg3_utils(8) man page.


๐ŸŒˆ OLDER COMMAND LINE OPTIONS ๐ŸŒˆ

The options in this section were the only ones available prior to sg3_utils version 1.23. Since then this utility defaults to the newer command line options, which can be overridden by using --old (or -O) as the first option. See the ENVIRONMENT VARIABLES section for another way to force the use of these older command line options. Retro era unlocked ๐Ÿ•ฐ๏ธ

  • -b=EACH_KIB โ€” where EACH_KIB is the number of Kilobytes (i.e. 1024 byte units) to be transferred by each READ BUFFER command. Similar to the --buffer=EACH option in the main description but the units are different.
  • -d โ€” use direct IO if available. Equivalent to the --dio option in the main description.
  • -m โ€” use memory mapped IO if available. Equivalent to the --mmap option in the main description.
  • -N, --new โ€” switch to the newer style options.
  • -q โ€” only transfer the data into kernel buffers (typically by DMA from the SCSI adapter card) and do not move it into the user space. Equivalent to the --quick option in the main description.
  • -s=OVERALL_MIB โ€” where OVERALL_MIB is the size of total transfer in Megabytes (1048576 bytes). Similar to the --size=OVERALL option in the main description but the units are different.
  • -t โ€” times the bulk data transfer component of this command. Equivalent to the --time option in the main description.
  • -v โ€” increase level of verbosity. Can be used multiple times.
  • -V โ€” print out version string then exit.

๐Ÿงš ENVIRONMENT VARIABLES ๐Ÿงš

Since sg3_utils version 1.23 the environment variable SG3_UTILS_OLD_OPTS can be given. When it is present this utility will expect the older command line options. So the presence of this environment variable is equivalent to using --old (or -O) as the first command line option. Set it and get the vintage experience ๐Ÿ’…


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Written by Douglas Gilbert. Absolute legend behavior.

๐Ÿ› REPORTING BUGS ๐Ÿ›

Report bugs to <dgilbert at interlog dot com>. Be nice about it, okay? ๐Ÿซถ

Copyright ยฉ 2000-2017 Douglas Gilbert

This software is distributed under the GPL version 2. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Fr fr read that disclaimer: NO warranty, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. So don't come crying if it does a thing ๐Ÿ™ˆ

๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

sg_read_buffer, sg_write_buffer, sg_test_rwbuf (all in sg3_utils)


Okay that's the whole page bestie, you're officially an sg_rbuf expert ๐ŸŽ“โœจ

This lil rewrite was served fresh from sg3_utils-1.43, dated October 2017 โ€” catch you in the next SG_RBUF(8) ๐Ÿ’œ

๐Ÿ“ฆ where this page comes from