SG_READ(8)
π SG_READ(8) π
Okay bestie, welcome to sg_read, the manual page for SG_READ(8) from SG3_UTILS π Let's get into it β¨
β¨ NAME β¨
sg_read - read multiple blocks of data, optionally with SCSI READ commands π¦
β¨ SYNOPSIS β¨
sg_read [blk_sgio=0|1] [bpt=BPT] [bs=BS] [cdbsz=6|10|12|16] count=COUNT
[dio=0|1] [dpo=0|1] [fua=0|1] if=IFILE [mmap=0|1] [no_dxfer=0|1]
[odir=0|1] [skip=SKIP] [time=TI] [verbose=VERB] [--help] [--version]
β¨ DESCRIPTION β¨
Okay so sg_read reads data from a Linux SCSI generic (sg) device, a block device, or a normal file. Every read command goes to the same offset or logical block address (lba), which is seriously iconic for testing or timing disk caching π₯ It can also show you SCSI (or some other) transport throughput and/or SCSI command overhead. Main character energy, literally π
When COUNT is positive, up to BPT blocks get read at a time until COUNT is used up. Every read starts at the same lba, which is the beginning of the file or device unless you pass SKIP πΈ
Now the spicy part πΆοΈ COUNT can go negative when IFILE is an sg device or a block device with blk_sgio=1 set. You can also give bpt=0 instead. In those cases you get |COUNT| "zero block" SCSI READ commands. "Zero block" means "do nothing" for SCSI READ 10, 12 and 16 byte commands (but NOT the 6 byte one, so don't get it twisted π). In practice these have super low latency, which makes them a lowkey perfect way to measure SCSI command overhead β¨
π Heads up bestie: this is a very old utility. It uses 32 bit integers for disk LBAs and the count, so it can't address beyond 2 Terabytes on a disk with logical blocks that are 512 bytes long. If you need more, the alternatives are thesg_ddandddptutilities π«Ά
β¨ OPTIONS β¨
blk_sgio=0 | 1β By default this utility uses the Unixread()command whenIFILEis a block device. In lk 2.6 a lot of block devices can handle SCSI commands sent through the SG_IO ioctl, so when you set this option, the SG_IO ioctl sends SCSI READ commands toIFILEif it's a block device πbpt=BPTβBPTis the max number of blocks each read operation fetches. If the leftoverCOUNTis less thanBPT, you get fewer blocks. The defaultBPTis 128. Each read still starts at the samelba(set byskip=SKIP, or 0). If you dobpt=0, thenCOUNTis treated as the number of zero block SCSI READ commands to issue π§bs=BSβBSis the size (in bytes) of each block read. This has to match the block size of the physical device (defaults to 512) if SCSI commands are going toIFILEπcdbsz=6 | 10 | 12 | 16β the size of the SCSI READ commands sent to sg device names, or to block devices ifblk_sgio=1is given. The default is 10 byte SCSI READ cdbs πcount=COUNTβ whenCOUNTis positive, read that many blocks, usually with several read operations. WhenCOUNTis negative, you get |COUNT| SCSI READ commands asking for zero blocks to be transferred. This one is mandatory, no skipping it πdio=0 | 1β default is 0, which picks indirect IO. A value of 1 tries direct IO. If that's not available, it falls back to indirect IO and tells you about it when it's done. This option only works ifIFILEis an sg device. If you pick direct IO and/sys/module/sg/parameters/allow_diohas the value 0, you get a warning and indirect IO happens anyway β οΈdpo=0 | 1β when set, the disable page out (DPO) bit goes into SCSI READ commands. Otherwise the DPO bit is cleared, which is the default πfua=0 | 1β when set, the force unit access (FUA) bit goes into SCSI READ commands. Otherwise the FUA bit is cleared, which is the default πif=IFILEβ read from thisIFILE. This argument is mandatory. IfIFILEis a normal file, it has to be seekable (ifCOUNT>BPTorskip=SKIPis given). So no stdin, and passing-as theIFILEargument gets reported as an error π ββοΈmmap=0 | 1β default is 0, which picks indirect IO. A value of 1 does memory mapped IO. Picking bothdioandmmapis an error. This option only works ifIFILEis an sg device π¦no_dxfer=0 | 1β when set, DMA transfers from the device go into kernel buffers and stop there (no second copy into user space). The default is 0, where transfers go into user space. When neithermmapnordiois set, data gets copied through kernel buffers (a double copy). This is mainly for testing π§ͺodir=0 | 1β when set, opens anIFILEthat's a block device with the extra O_DIRECT flag. The default is 0, so block devices don't get opened O_DIRECT πskip=SKIPβ every read operation starts offset bySKIPbs-sized blocks from the start of the input file (or device) βοΈtime=TIβ whenTIis 0 (the default), no timing happens. When 1, it times the transfer and calculates throughput, starting at the first issued command and going until completion. When 2, it does the same but starts at the second issued command. When 3, it starts from the third command, and so on. It also prints an average number of commands (SCSI READs or Unixread()s) executed per second β±οΈverbose=VERBβ asVERBgoes up, so does the amount of debug output sent to stderr. The default is zero, which gives the minimum amount of debug output. A value of 1 reports extra info that isn't repetitive π£--helpβ outputs the usage message, then exits π--versionβ outputs the version string, then exits π
β¨ NOTES β¨
Some numeric arguments (like SKIP) can include multiplicative suffixes or be given in hexadecimal. Check the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page for the deets π’
Data usually gets to user space in a 2 stage process. First the SCSI adapter DMAs into kernel buffers, then the sg driver copies that data into user memory. This is called "indirect IO". There's a dio option to select "direct IO", which DMAs straight into user memory. Due to some issues, "direct IO" is disabled in the sg driver and needs a config change to turn on. This is typically done with echo 1 > /sys/module/sg/parameters/allow_dio. Another way to skip the 2 stage copy is memory mapped IO with mmap=1 π«§
β¨ SIGNALS β¨
The signal handling was borrowed from dd π SIGINT, SIGQUIT and SIGPIPE output the number of remaining blocks to be transferred, then they do their default action. SIGUSR1 outputs that same info, but the copy keeps going. All output caused by signals goes to stderr π¨
β¨ EXAMPLES β¨
Okay, let's say /dev/sg0 is a disk and we want to time the disk's cache performance π
sg_read if=/dev/sg0 bs=512 count=1MB mmap=1 time=2
This command will keep reading 128 512 byte blocks from block 0. The 128 is the default for bpt, and block 0 is picked because the skip argument wasn't given. It keeps going until 1,000,000 blocks are read. The idea behind time=2 is that the first 64 KiB read operation will involve reading the magnetic media, while the rest of the read operations will "hit" the disk's cache π§ The output of third command will look like this:
time from second command to end was 4.50 secs, 113.70 MB/sec
Average number of READ commands per second was 1735.27
1000000+0 records in, SCSI commands issued: 7813
β¨ EXIT STATUS β¨
The exit status of sg_read is 0 when it works. Otherwise, see the sg3_utils(8) man page π―
β¨ AUTHORS β¨
Written by Douglas Gilbert π«Ά
β¨ REPORTING BUGS β¨
Report bugs to <dgilbert at interlog dot com> π
β¨ COPYRIGHT β¨
Copyright Β© 2000-2019 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 π
β¨ SEE ALSO β¨
To time streaming media read or write time, see sg_dd, which is in the sg3_utils package, and ddpt, which is in a package of the same name. The lmbench package contains lmdd, which is also interesting π Also check out raw(8) and dd(1) π
Ta-da, you're officially an sg_read expert now, bestie π SG3_UTILS sg3_utils-1.45, September 2019 π Stay iconic π β¨
π¦ where this page comes from
- alpine 3.24: sg3_utils-doc 1.48-r0 Β· BSD-2-Clause AND GPL-2.0-or-later
- arch rolling: sg3_utils 1.49-1 Β· GPL-2.0-or-later AND BSD-2-Clause
- centos-stream 10: sg3_utils 1.48-11.el10 Β· GPL-2.0-or-later AND BSD-2-Clause
- debian trixie: sg3-utils 1.48-3~deb13u1
- fedora 43: sg3_utils 1.48-10.fc43 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 43: sg3_utils 1.48-6.fc43 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-10.fc44 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-8.fc44 Β· GPL-2.0-or-later AND BSD-2-Clause
- nixos 26.05: sg3_utils 1.48
- nixpkgs unstable: sg3_utils 1.49
- ubuntu questing: sg3-utils 1.48-2ubuntu1
- ubuntu resolute: sg3-utils 1.48-3ubuntu3
- ubuntu resolute: sg3-utils 1.48-3ubuntu3.2
- ubuntu stonking: sg3-utils 1.48-3ubuntu5
- π girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms