Flush a SCSI Device Cache Safely with sg_sync
You will send a SCSI Synchronise CACHE command to a chosen block device, confirm that it completed, and understand when a partial range or asynchronous request is appropriate. Allow about fifteen minutes, plus however long the device takes to finish writing cached blocks. The examples use sg_sync from the installed sg3-utils package.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a device-level operation. It is not a filesystem sync, it does not flush every device in the machine, and it does not make a backup. Identify the target carefully before using an elevated command. A cache flush is normally non-destructive, but it can create a burst of I/O and can wait for a slow or failing device.
1. Check the installed command
Start with read-only checks. On this machine the package is sg3-utils version 1.46-3ubuntu4. The installed executable reports its own version as 1.25 20191220, while the local manual page is from the sg3_utils 1.43 documentation set. Keep those details together when comparing output with another host: the package and manual may have been built from different upstream revisions.
$ command -v sg_sync
/usr/bin/sg_sync
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
$ sg_sync --version
version: 1.25 20191220
Check the option shape without naming a device:
$ sg_sync --help
Usage: sg_sync [--16] [--count=COUNT] [--group=GN] [--help] [--immed]
[--lba=LBA] [--sync-nv] [--timeout=SECS] [--verbose]
[--version] DEVICE
The command needs a device argument for an actual operation. --help and --version exit without sending SCSI I/O.
2. Identify the exact SCSI device
Use a stable path if your system provides one, and check its model and mount points before proceeding. This inspection is ordinary and does not need sudo:
$ lsblk -o NAME,TYPE,MODEL,SERIAL,MOUNTPOINTS /dev/sdX
NAME TYPE MODEL SERIAL MOUNTPOINTS
sdX disk Example-SCSI-Disk 123456789ABC /data
Replace /dev/sdX with the device you have positively identified. On a system with udev links, a path such as /dev/disk/by-id/scsi-EXAMPLE is less vulnerable to device names changing after a reboot. Do not guess from the last letter of a device name, and do not use a partition path when you intend to address the whole disk.
Checkpoint: record the exact path and confirm that any application using it can tolerate a short period of increased write latency. If the device is carrying production traffic, schedule the flush with the same care as other storage maintenance. Nothing in sg_sync pauses or coordinates your applications.
3. Flush the whole cached range
With no range options, sg_sync uses Synchronise CACHE(10). Its default logical block address is zero and its default count is zero. Together, those defaults mean that all blocks held in the device cache are synchronised with the medium.
The operation generally needs access to the SCSI device, so use sudo only when the current account cannot open it:
$ sudo sg_sync /dev/disk/by-id/scsi-EXAMPLE
$ status=$?
$ printf 'sg_sync exit status: %s\n' "$status"
sg_sync exit status: 0
A successful run normally produces no progress text. Exit status 0 is the verification supplied by the command: the device accepted and completed the requested operation. The cache flush does not change files or filesystem metadata, so there is no undo command. If the command returns a non-zero status, do not treat silence or a partial wait as success; keep the status and investigate the device error first.
4. Flush a specific block range when you have a reason
Use --lba for the first logical block and a non-zero --count for the number of blocks. The range is inclusive at the start and covers LBA through LBA + COUNT - 1:
$ sudo sg_sync --lba=1048576 --count=4096 /dev/disk/by-id/scsi-EXAMPLE
$ printf 'sg_sync exit status: %s\n' "$?"
sg_sync exit status: 0
Do not use a partial range merely to make the command look quicker. It only covers the blocks named by the request, and the device's cache and command support determine what can be synchronised. If --lba is greater than zero while --count remains zero, the command covers that LBA through the device's highest block address. With both values at zero, it covers the whole cache.
Large numeric arguments may use the formats documented by sg3_utils(8), including hexadecimal and multiplicative suffixes. Decimal values are easier to audit in a maintenance record, so use them unless the device documentation gives you a better reason.
5. Choose the command variant deliberately
--16 selects Synchronise CACHE(16) instead of the default 10-byte command. It allows a 64-bit LBA and a 32-bit count, whereas the 10-byte form has smaller fields. Use it when the address or count requires it, or when the target's documentation specifically requires the 16-byte form:
$ sudo sg_sync --16 --lba=4294967296 --count=4096 /dev/disk/by-id/scsi-EXAMPLE
$ printf 'sg_sync exit status: %s\n' "$?"
sg_sync exit status: 0
The exact device capability still matters. A command that is valid for the SCSI standard can be rejected by a particular target, bridge or enclosure. If you do not need the larger fields, leave out --16.
--immed sets the command's IMMED bit. It asks the device to return GOOD status without waiting for the cache to be written to the medium. That is useful when the device supports asynchronous completion, but status zero then confirms acceptance rather than the end of the physical write. Leave it out when the next step requires a completed flush.
--timeout=SECS is only active with --16; the documented default is 60 seconds. A timeout can lead the operating system to try to cancel the command, which the manual says is best avoided. Do not increase or decrease it casually. If the device is slow, first establish whether the operation is expected and whether the workload can be drained safely.
6. Handle the options that are easy to misread
--group=GN accepts a group number from 0 through 63. Groups are a device data-segregation feature and the local manual describes them as something that can probably be ignored for the time being. Keep the default group 0 unless the target documentation and your storage design specify another value.
--sync-nv requests synchronisation from volatile cache to a distinct non-volatile cache rather than to the medium. The option is marked obsolete in SBC-3 revision 35d, and it has no useful general-purpose default. Do not add it because the device has a battery-backed or non-volatile cache; decide from the target's SCSI documentation what guarantee you need.
Use --verbose when a command fails and you need more diagnostic output:
$ sudo sg_sync --verbose /dev/disk/by-id/scsi-EXAMPLE
$ printf 'sg_sync exit status: %s\n' "$?"
sg_sync exit status: 0
Verbose output is diagnostic, not proof of a stronger flush. Save it with the exit status if you need to report a target, transport or permission problem.
7. Diagnose a failed flush without making the problem worse
If you see a permission error, check the device ownership and retry with the minimum elevation required by your policy:
$ ls -l /dev/disk/by-id/scsi-EXAMPLE
$ sudo sg_sync --verbose /dev/disk/by-id/scsi-EXAMPLE
$ printf 'sg_sync exit status: %s\n' "$?"
A non-zero result can also mean that the path is not a SCSI block device, a SCSI-to-USB or storage bridge rejected the command, the target returned a SCSI sense error, or the operation exceeded the allowed time. Check the device and kernel logs using your normal read-only diagnostics before repeating the command. Do not substitute /dev/null, a filesystem path or a partition just to make the syntax run.
If the flush is slow, do not repeatedly issue new flushes while the first one may still be active. Stop the workload if your change procedure allows it, capture the command status and logs, and follow the device vendor's recovery procedure. If --immed was used, allow for the device's asynchronous work before treating a later power-off or removal as safe.
Done means
- You checked the installed package and command version, and selected one exact SCSI block device.
- You used the default whole-cache flush unless a documented LBA range was genuinely required.
- You recorded exit status
0after the operation, without confusing it with--immedacceptance. - You selected Synchronise CACHE(16), a timeout, group or non-volatile-cache mode only for a stated device-specific reason.
- You kept the storage workload and any service impact under control, and investigated non-zero status before retrying.