instar rebase — change an overlay's backing-file reference¶
instar rebase changes the backing-file pointer recorded in an
overlay image and, in safe mode, copies divergent clusters from
the old backing chain into the overlay so the post-rebase result
is content-equivalent to the pre-rebase result. It is the safe,
sandboxed equivalent of qemu-img rebase, with byte-equivalent
post-rebase qemu-img info --output=json output for qcow2
across every qemu-img version 6.0.0 through 10.2.0.
Both modes run the rebase.bin guest in the KVM sandbox. The
host opens the overlay as the output device (RW), the old
backing chain as input slots [0..N), and (in safe mode) the
new backing chain as input slots [N..M). The guest reads the
overlay's header, plans the metadata mutation, and applies the
patches via virtio-block.
Synopsis¶
Common options:
-f, --format <FMT> qcow2 | vmdk
Default: auto-detect from the
existing file's magic bytes
-b, --backing <BACKING> Required. New backing file path,
or empty string ("") to detach.
-F, --backing-format <FMT> qcow2 | vmdk | raw. Optional
format hint for the new backing;
the guest probes it either way.
-u, --backing-unsafe Unsafe (metadata-only) rebase.
Trusts the caller that the new
backing has the same content as
the old; no chain comparison, no
data copy.
-q, --quiet Suppress the success line.
Errors still go to stderr.
--output <FORMAT> human (default) | json
The full flag surface is reported by instar rebase --help.
Mode grammar¶
The rebase planner runs in one of two modes:
| Mode | Trigger | What it does |
|---|---|---|
Unsafe (-u) |
-u flag |
Rewrites only the backing-file pointer in the overlay's header. No chain comparison, no cluster copying. |
| Safe (default) | absence of -u |
Walks the old and new backing chains, copies clusters whose content differs into the overlay, then rewrites the backing pointer. |
Detach is encoded as -b "" — the overlay's backing pointer
is zeroed, and the overlay becomes standalone. Detach is valid
in either mode and is essentially equivalent to "rebase to no
backing"; unsafe-mode detach is instant, safe-mode detach
flattens every cluster the old chain provided.
Target formats¶
| Format | Unsafe (-u) |
Safe (default) | Notes |
|---|---|---|---|
| qcow2 | ✓ | ✓ | v2 and v3; refcount_bits=16 only |
| vmdk monolithicSparse | ✓ | reject | Safe mode is a planner gap (Future work) |
| Other formats | reject | reject | qemu-img also rejects |
For qcow2, the post-rebase qemu-img info --output=json matches
qemu-img rebase byte-for-byte across every shipped qemu-img
version (verified by the cross-version baseline matrix in
instar-testdata/expected-outputs/rebase-info-json/ and
exercised by
tests/test_rebase.py:TestRebaseBaselineMatrix). For vmdk —
which qemu-img rebase rejects with Image format driver does
not support rebase on every shipped version — the post-rebase
state is verified by tests/test_rebase.py's vmdk smoke and
the qemu-img info readback (TestRebaseSuccessPaths).
Output format¶
Human (default):
(matches qemu-img rebase byte-for-byte.) When -b "" is
supplied:
JSON (--output=json, non-detach):
{
"overlay": "/path/to/disk.qcow2",
"overlay_format": "qcow2",
"mode": "unsafe",
"clusters_copied": 0,
"bytes_copied": 0,
"new_backing": "next.qcow2"
}
Detach JSON drops new_backing and adds "detached": true.
mode is one of "unsafe" or "safe". -q suppresses both
forms on success and prints only errors.
-u (unsafe) semantics¶
Unsafe-mode rebase rewrites only the qcow2 backing_file_offset
and backing_file_size header fields (or the vmdk descriptor's
parentFileNameHint= line). No backing-chain content is read;
no overlay cluster data is touched. The caller is asserting
that the new backing is content-equivalent to the old backing,
so existing overlay clusters remain coherent against the new
chain without copying.
Use -u when:
- You renamed or moved the backing file but haven't changed its bytes.
- You're swapping in a backing image you know is bit-identical to the old one (e.g. a copy, a hardlink, a snapshot you took immediately after the original was finalised).
Avoid -u when:
- The new backing's data could legitimately differ from the old. The overlay's existing-data assumptions would be silently broken; reads through the rebased overlay would return stale or incorrect content.
-b (new backing) semantics¶
-b BACKING is required (no implicit "current parent" — that's
commit's job). Relative paths resolve against the overlay's
parent directory at parse time, matching qemu-img's convention.
The path is stored in the qcow2 header (or the vmdk descriptor)
verbatim — instar does not canonicalise to absolute paths.
Detach is signalled by -b "". The backing pointer is zeroed
and the overlay becomes standalone.
Known divergences from qemu-img rebase¶
- Long-path relocation is rejected. Long new-backing paths
that don't fit the overlay's existing header slot are
refused with
ERROR_BACKING_PATH_TOO_LONG(the planner's in-place rewrite path is bounded by the existing slot size). qemu-img silently relocates the path string to a fresh cluster and updates the header offset. Lifting the gap is a master-plan TODO; for now the picker in the differential fuzzer matches the backing-name length to the overlay's existing slot. - Safe-mode rebase for vmdk is not yet supported. instar
rejects with
ERROR_UNSUPPORTED_FORMAT. qemu-img also rejects vmdk rebase entirely (there is no upstream vmdk rebase at all). The vmdk smoke tests use unsafe mode. - Cross-cluster-size rebase is rejected. If the new
backing's qcow2 cluster size differs from the overlay's,
safe-mode rebase refuses with
ERROR_NEW_BACKING_INCOMPATIBLE. qemu-img silently succeeds but the resulting overlay has inconsistent metadata; the master plan tracks this as a future hardening item. - External-data-file qcow2 overlays are refused. Rebase
refuses any overlay with the
INCOMPAT_EXTERNAL_DATAfeature bit set; that's the qcow2 v3 external data file feature, which is incompatible with backing chains. qemu-img refuses for the same reason. - LUKS-encrypted overlays / backings are refused. Lifting the gap depends on the matching LUKS plumbing on the convert side (master-plan Future work).
--object OBJDEFand--image-optsare not implemented. Rejected at the host CLI surface; the qemu-img features they unlock require complex plumbing not in scope for v1.- Cross-version baseline matrix scope. The recorded baselines cover qcow2 only — qemu-img rebase rejects vmdk / vhd / vhdx with "Operation not supported" on every shipped version, so there is no cross-tool diff to record for those targets.
Future work¶
For the per-format rebase planners, see
src/crates/rebase/src/lib.rs
(plan_rebase_qcow2, plan_rebase_vmdk). For the divergence
whitelist applied during cross-version baseline comparison, see
tests/helpers/info_json.py.
Tracked under the PLAN-rebase-commit master plan:
- Long-path relocation in qcow2 unsafe-mode rebase (planner + guest scratch budget for the appended path cluster).
- Vmdk safe-mode rebase (planner gap; cluster comparison loop
- descriptor rewrite atomicity).
- Cross-cluster-size rebase (planner gap; would need cluster-size adapters in the safe-mode allocator).
--object/--image-optsfor LUKS-wrapped overlays (depends on convert-side LUKS plumbing).- Targeted seed corpus for
fuzz_rebase_planners. Thescripts/generate-fuzz-seeds.pyinfrastructure can walk the existing testdata. - Tighter scratch-budget bounds on the safe-mode allocator
so larger-cluster-size overlays don't surface
ERROR_SCRATCH_TOO_SMALL.
Examples¶
Unsafe rebase to a new backing in the same directory:
Safe rebase to a new backing of the same virtual size:
Detach the overlay (zero its backing pointer):
JSON output for scripting:
Auto-detect the overlay format from the file's magic bytes: