Skip to content

docs(spec): design for factory-reset wipe modes 2, 3, 4 - #23

Open
JanZachmann wants to merge 1 commit into
omnect:mainfrom
JanZachmann:feat/factory-reset-wipe-modes
Open

docs(spec): design for factory-reset wipe modes 2, 3, 4#23
JanZachmann wants to merge 1 commit into
omnect:mainfrom
JanZachmann:feat/factory-reset-wipe-modes

Conversation

@JanZachmann

@JanZachmann JanZachmann commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Design spec for the remaining factory-reset wipe modes: 2 (random overwrite), 3 (block discard), 4 (custom wipe hook). The wipe runs between backup and reformat; a wipe failure is a warning and the reset always continues. The implementation follows in a separate PR once this spec is approved.

Deliberate changes vs the legacy script (details in section 1.1 of the spec):

  • Mode 2 overwrites the whole device natively in Rust instead of dd with a 2048-byte skip — partitions are found by number, not label, so the skip is not needed.
  • Mode 3 uses one BLKDISCARD ioctl instead of mount + rm -rf + fstrim. This discards all blocks (including fs-journal remnants) and fixes the legacy bug where a failed mount counted as a successful wipe.
  • Mode 4 keeps the exact legacy contract: /opt/factory_reset/custom-wipe, no arguments, partitions unmounted.

The ODS result contract does not change: no new fields or status codes, the wipe-failure note travels in the existing free-text context field (ods PR omnect/omnect-device-service#207 already parses the schema).

Reason

Mode 1 is implemented; modes 2–4 are the missing part of the factory-reset port from the legacy initramfs scripts. The spec fixes the behaviour differences and the error-handling rules before implementation starts.

Signed-off-by: Jan Zachmann <jan.zachmann@conplement.de>
Comment on lines +13 to +16
| 2 | overwrite `etc` and `data` with random data (slow, better privacy) | native Rust write loop over the whole device |
| 3 | discard all blocks of `etc` and `data` (fast, needs hardware discard support) | `BLKDISCARD` ioctl |
| 4 | custom wipe hook | run `/opt/factory_reset/custom-wipe` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while being the right mode for plain hard disks (magnetic aka spinning rust), mode 2 is actually the worst solution on any kind of flash that implements wear leveling or any kind of other indirection to manage free/unallocated blocks:

  • all blocks available to the partition suffer one more wear
  • any currently unused blocks of the internal block management keep their old values which can potentially resurface sporadically sometimes in the future

on the other hand, method 3 is only supported by flash type disks (if at all) and in varying flavors.

I know this is not new in the course of this init re-implementation, but imho it should be addressed, either right here or as follow-up.
at least our Readme.md should be updated to contain some guide which method is suitable for which kind of disk storage (if changing the modes to operate kind of intelligently is considered too much effort)

Comment on lines +28 to +35
- **Mode 3:** legacy did mount → `rm -rf *` → `fstrim` → unmount, which trims
only the blocks freed by `rm` and leaves fs-journal remnants. New: one
`BLKDISCARD` ioctl discards every block of the partition. This also fixes a
legacy bug where a failed mount silently counted as a successful wipe.
On hardware without discard support the ioctl fails cleanly → warning
(legacy `fstrim` had the same hardware requirement). Discard remains a hint
on some disks — the "no total privacy guarantee" note in the meta-omnect
README stays true.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as there are levels to the blkdiscard game we might want to consider them in future:

  • mode standard discard (standard without additional options)
  • mode zero out (option -z)
  • mode secure (option -s) which is a standard discard plus discard of block management internal copies/old data freed up by device internal garbage collection

again, this is something beyond the legacy implementation and might need some more refinement (do we want explicit choice of mode or just implement some reasonable fallback strategy between modes) ; therefore this is probably rather subject to a follow-up than part of this PR.

Comment on lines +131 to +132
- custom wipe with temp scripts: exit 0 → Ok; exit 1 → Err; missing file →
Err.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not test-only but also affecting tests ...

I think we need to refine the custom script behavior a bit further:

  • exit code 0 is self-explaining
  • a custom script might want to signal different errors to the user, via ...
    • its exit status (an integer value) and/or
    • its output (stdout and/or stderr)

Comment on lines +143 to +145
- omnect-os CI covers only mode 1 today; nothing breaks. Optional follow-up
on the `feature_rust_init` branch: add mode-2 and mode-3 test runs (mode 4
needs a customer bbappend, not generically testable).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I don't think a bbappend is mandatory here, a test script could just as well be simply injected.
  2. a crafted test script could always simulate a real customer script that takes advantage of the possibilities to signal the outcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants