Control SCSI Background Operations Safely with sg_bg_ctl

sg_bg_ctl asks a supported SCSI disk to start or stop its own background housekeeping, like garbage collection. Get the device wrong and you throttle the wrong unit's performance instead, so allow about fifteen minutes, plus time to identify the correct one. The examples use sg_bg_ctl from package sg3-utils 1.46-3ubuntu4; the installed executable reports utility version 1.11 20191220.

This is a device-control command, not a generic Linux disk-tuning switch. It sends a SCSI BACKGROUND CONTROL command to whichever device you name, so a wrong path can affect the wrong storage unit. Check the path twice before using --ctl=1 or --ctl=2.

1. Confirm the installed command

Start with read-only checks. The version output identifies the executable; the package query identifies the distribution package that supplied it:

$ command -v sg_bg_ctl
/usr/bin/sg_bg_ctl
$ sg_bg_ctl --version
version: 1.11 20191220
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4

The local manual page carries a sg3_utils-1.43 header dated May 2016, so keep the executable and documentation versions distinct when comparing another host. The option meanings used here appear in both the installed manual and the installed command.

Checkpoint: if command -v finds no executable, stop and install or repair sg3-utils through your normal package process. Do not substitute a similarly named vendor utility.

2. Choose and inspect the device

Set a placeholder to the exact SCSI generic or block device you intend to address, replacing it with a path from your own host, such as /dev/sg3 or one documented by your storage team:

$ DEVICE='/dev/sgX'
$ test -e "$DEVICE" && printf 'device exists: %s\n' "$DEVICE"
device exists: /dev/sgX

/dev/sgX is deliberately a placeholder, not a path to copy unchanged. Find the real mapping with your usual SCSI inventory tools and confirm the vendor, model and serial identity before proceeding. Reading inquiry data is normally unprivileged; use sudo only if the device permissions actually require it.

Background control targets resource or thin-provisioned logical units, commonly solid-state disks. Support is signalled by the BOCS bit in the Block Device Characteristics VPD page, so ask sg_vpd for it:

$ sg_vpd --page=0xb1 "$DEVICE"

Output depends on the device and its SCSI translation layer. Look for the decoded BOCS indication. If the page cannot be read, or BOCS isn't set, treat that as a reason not to send the background-control command at all; it is not evidence that adding sudo will make the feature appear.

3. Understand the safe default

Run the command with no control option when you just want the default field value:

$ sg_bg_ctl "$DEVICE"
$ printf 'exit status: %s\n' "$?"
exit status: 0

The default --ctl=0 leaves host-initiated advanced background operations unchanged. A successful status means the device accepted the SCSI command, nothing more; it does not mean a background operation started. Useful as a parsing and access check, but not a support probe on its own.

Checkpoint: confirm the printed device variable is the intended unit and the status is zero. If the command reports a SCSI error, preserve the error text and stop. Do not retry against a different disk just because the first one rejected the command.

4. Start operations with a bounded time

Starting operations can compete with application I/O and degrade performance, so do this only in a maintenance window or another period where that's acceptable. --ctl=1 starts host-initiated advanced background operations; pair it with --time for a maximum duration:

$ sudo sg_bg_ctl --ctl=1 --time=50 "$DEVICE"
$ printf 'exit status: %s\n' "$?"
exit status: 0

--time=50 means 50 units of 100 milliseconds, or 5 seconds. Valid values run 0 through 255, with 0 as the default meaning no maximum time limit. The time field is ignored unless --ctl=1 is selected, so adding it to a stop command imposes no limit on anything.

Use sudo only when the device node requires elevated access. This is not a service manager and does not touch persistent Linux configuration. Success can produce no visible output at all, so read the exit status immediately after the command, as shown above.

5. Stop a host-initiated operation

Use --ctl=2 to ask the device to stop host-initiated advanced background operations:

$ sudo sg_bg_ctl --ctl=2 "$DEVICE"
$ printf 'exit status: %s\n' "$?"
exit status: 0

This is an operational control, not an undo for unrelated firmware work. A successful command means the SCSI request succeeded; the device's own status and timing decide when its work actually stops. If an application is already seeing latency, monitor it and follow the device vendor's recovery procedure rather than repeatedly sending commands.

There is no persistent change to undo in these examples. Need the device to resume host-initiated operations later? Send --ctl=1 again, preferably with a time limit and an agreed maintenance window.

6. Inspect status and diagnose failures

The installed manual points to the Background Operations Control mode page and the Background Operation log page as where to inspect configuration and status. Use sdparm for the mode page if installed, and sg_logs for the log page:

$ sdparm --page=0x0a,0x06 "$DEVICE"
$ sg_logs --page=0x15,0x02 "$DEVICE"

Exact decoding varies by device and utility version. The first command shows the BO_MODE field; the second asks for the background-operation log subpage and may show the device's BO_STATUS. Both read device data. Do not add a write or save option while diagnosing an unexpected mode, and do not modify BO_MODE unless the device documentation and change procedure explicitly call for it.

If sg_bg_ctl returns non-zero, record the complete diagnostic and status. Common causes include an unsupported command, a device path that is not a SCSI pass-through endpoint, insufficient access to the device node, or a device that simply does not advertise background-control support. Test access with a read-only inquiry or VPD command first. A failed start is not proof it's safe to keep retrying during production I/O.

--verbose adds debug output for a vendor or maintainer who needs more detail:

$ sudo sg_bg_ctl --verbose --ctl=1 --time=10 "$DEVICE"

Verbose output is diagnostic and can vary by transport and utility build. Do not parse it as a stable interface; use the process exit status and the device's log page for automation instead.

Done means