braid remove
Remove a live disk from the pool. Data migrates off the disk before it is detached. Going from two disks to one, the pool first converts off RAID1 while the disk is still in it, so the disk can hold the only copy of some data until the removal finishes (step 5).
When to use it
- Shrinking the pool (retiring a drive you no longer need)
- Removing a drive that is still online and healthy. On a 2-disk pool, braid refuses a drive that shows btrfs errors or a bad SMART verdict (see Safety checks below)
If the disk is already dead or missing, use braid replace to rebuild data onto a new disk, or braid remove-missing to forget the entry without rebuilding.
Basic example
sudo braid remove toshiba3
Common variations
Preview what would happen:
sudo braid remove toshiba3 --dry-run
Skip the confirmation prompt:
sudo braid remove toshiba3 --yes
Important flags
| Flag | Purpose |
|---|---|
--dry-run | Show what would happen without executing |
--yes | Skip interactive confirmation |
--progress auto|always|never | Control progress display (default: auto) |
What happens under the hood
- Probes the pool to verify the disk is a live member
- Checks that the remaining disks have room for the data being migrated (see the space rule under Safety checks below). When one disk would remain, it also checks the departing disk’s btrfs error counters and SMART health (see the health rule under Safety checks below)
- Shows a confirmation prompt with the disk’s name and devid, its model/size/serial (best-effort from the live backing device via lsblk – omitted if unavailable), and the resulting disk count (e.g.
Pool: 3 disks -> 2 disks). When one disk would remain, the prompt also carries aWARNING:line that the pool loses RAID1 redundancy. This interactive prompt, warning included, is skipped by--yesand not shown in--dry-run; dry-run shows the redundancy loss as the balance step of step 5 instead (see ADR 022). - After confirmation (or straight away with
--yes), plans again against the live pool: steps 1-2 and the pool’s safety checks below. If a check now refuses, or the new plan differs from the confirmed one, braid stops before writing anything. This runs before any--enqueuewait (see below), so it does not cover changes while the removal is queued behind another exclusive operation, or while it runs. - If removing the second-to-last disk (going from 2 to 1): first balances the pool off RAID1, then removes the device. Data converts to single, and metadata and system convert to DUP (two copies on the one disk), which
braid statusthen shows. See btrfs balance profiles for why metadata keeps two copies. The disk being removed is still in the pool during this balance, so btrfs can put some converted data on it alone. That data has one copy, on the departing disk, until step 6 finishes. This is why braid refuses an unhealthy disk here (see ADR 012). - Runs
btrfs device removeto migrate all data off the disk (this is the long-running step) - Closes the LUKS mapper on the removed disk
- Updates pool.json to remove the member’s UUID entry
The step-7 mapper close is best-effort. Because btrfs has already committed the device removal, braid never fails the remove on the close: a failed close prints a [warn] disk <name>: lock failed row, and a close-time ownership probe that cannot prove the mapper is the expected disk – inactive, a probe failure, or a foreign LUKS UUID – skips the close with a Warning: line. A clean exit therefore does not guarantee the mapper is closed. The probe reads the LUKS UUID the kernel recorded when the mapper was opened, not the disk’s header, so the mapper still closes when the removed disk is already gone.
A sleep inhibitor is held during data migration and cleanup.
If a btrfs exclusive operation (a running balance, device add/remove/replace, resize, or swap activate) is already in flight on the pool, braid does not fail – its btrfs commands queue behind the in-flight operation (via --enqueue) and the kernel runs them when the pool is free. A paused balance is the exception and is refused (see Safety checks below).
Safety checks / refusal cases
- Refuses if the pool is not mounted
- Refuses if the named disk is hot-unplugged: its LUKS mapper is open but
cryptsetup statusreportsdevice: (null), and btrfs has not promoted it to MISSING. Re-plugging alone never reopens the mapper, so braid gives the reopen route:braid lockthenbraid unlockif the disk is back, orbraid lockthenbraid unlock --allow-degradedif it is gone, then re-runbraid remove. If the disk is hot-unplugged after the journal is written, the route reopens withbraid recoverinstead. See Hot-unplug while pool is mounted. - Refuses if the named disk is otherwise not a live member of the pool. If missing devices are detected, it suggests
braid replace --old <missing-name> --new <new-name>=/dev/disk/by-id/<...>, and alsobraid remove-missingwhenever the pool has a present disk to keep (on a 2-disk pool, remove-missing collapses the pool onto that disk) - Refuses to remove the last disk from the pool
- Refuses if there are missing devices in the pool (resolve those first)
- Refuses if the remaining disks lack space for the removed disk’s data
(ENOSPC pre-flight). When one disk would remain, braid also refuses
whenever it cannot verify the survivor’s space. When two or more would
remain and braid cannot run
btrfs device usageor read its output, it prints a[warn]row and goes ahead, because btrfs then stops cleanly on ENOSPC. A nonzero exit from btrfs refuses on both paths. The error names the reason. See ADR 012 for the policy. - When one disk would remain, refuses if the departing disk has any nonzero
btrfs device statscounter, if braid cannot read those counters, or if SMART on its live backing device readsfailingorwarning(the verdictbraid statusshows). The counters are the raw totals, so an acked alert still refuses. If SMART reports nothing, as on virtio disks and many USB bridges, braid prints a[warn]row and goes ahead. The refusal names two safe routes:braid replaceonto a new disk, or, with no spare,braid lock, disconnect the disk,braid unlock --allow-degraded, thenbraid remove-missingto collapse the pool onto the other disk without writing to this one. - Refuses if the pool changed between planning and the journal write (for example, survivor space was used up, a balance was paused, or a disk dropped out while the prompt waited). Nothing was written, so re-run the command.
- Refuses if a pending operation journal (
pending-op.json) exists – runbraid recoverto reconcile. - Refuses if another braid operation is in progress (pool lock
/run/braid-pool.lockis held) – retry once it finishes. - Refuses if a btrfs balance is paused on the pool – resume or cancel it first. A paused balance holds the exclusive-operation lock indefinitely, so braid cannot wait it out.
- Refuses if the pool is mounted read-only. If an operator or a tool remounted it,
mount -o remount,rw <mount-point>fixes that; if btrfs forced it read-only after an error, only a fresh mount does (braid lock, thenbraid unlock). See Pool is mounted read-only. - Refuses when UPS support is enabled and
braid ups statuscannot verify a trustedOL(utility-power) state.
Related commands
- braid status – see which disks are in the pool and their devids
- braid remove-missing – forget a dead/missing device entry
- braid replace – replace a disk (live or dead) with a new one
- braid add – add a disk to the pool