06 - atomic update
This commit is contained in:
1 parent
6d63457737
commit
2bdacaf37a
21 files changed
+1302
-365
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# Interrupted A/B installation model
|
||||
|
||||
This C++17 example follows [chapter 06](../../../docs/06-atomic-updates.md), [ADR-018](../../../adr/ADR-018-prepare-and-verify-before-activation.md), and [ADR-019](../../../adr/ADR-019-recover-interrupted-updates-from-durable-state.md). It models preparation and activation of B while confirmed system A remains available. It does not access devices or install files.
|
||||
|
||||
Build and run from the repository root with CMake 3.20 or later and a C++17 compiler. No third-party libraries are required.
|
||||
|
||||
```sh
|
||||
cmake -S examples/simulations/interrupted-installation -B /tmp/ota-installation-build -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake --build /tmp/ota-installation-build
|
||||
/tmp/ota-installation-build/installation-simulate all
|
||||
ctest --test-dir /tmp/ota-installation-build --output-on-failure
|
||||
```
|
||||
|
||||
With no argument, the runner also runs all scenarios. `--help` prints usage. Unknown arguments return a nonzero exit status.
|
||||
|
||||
## Reset Points
|
||||
|
||||
Each run starts from fresh storage. It performs the first N steps, destroys the installer, and creates another installer using the same simulated storage.
|
||||
|
||||
| Steps completed before reset | Last operation | Recovery action |
|
||||
|---|---|---|
|
||||
| 0 | None | Keep A; start preparation. |
|
||||
| 1 | Save release and target intent | Keep A; restart preparation. |
|
||||
| 2 | Write part of B | Keep A; restart preparation. |
|
||||
| 3 | Complete writing B | Verify again; save prepared state; wait for activation policy. |
|
||||
| 4 | Verify B | Repeat verification; save prepared state; wait for activation policy. |
|
||||
| 5 | Save prepared state | Verify again; wait for activation policy. |
|
||||
| 6 | Save trial request | Preserve trial and attempts; repair old progress. |
|
||||
| 7 | Save trial-requested progress | Preserve trial and attempts. |
|
||||
|
||||
The runner also supplies three possible results of an interrupted boot-record write: retain the old record, retain the new record, or find no valid record. The last case requires separate recovery. These are assumed outcomes, not a redundant-record algorithm.
|
||||
|
||||
## Storage and Ownership
|
||||
|
||||
`Storage` represents persistent bytes and records in memory. Each modeled storage operation is already complete and durable when it returns. `Installer` holds a temporary verification result. Recreating it clears that result, so a new activation requires fresh verification.
|
||||
|
||||
Boot state owns selection and the trial limit. OTA progress can be old. When a trial request already exists, recovery repairs progress without rewriting B or renewing attempts. Recovery with A selected checks both the release identity and installed contents before accepting B as prepared.
|
||||
|
||||
Only one installer is active. A is initially confirmed; there is no earlier pending trial. B is writable only while boot state selects A. A remains unchanged. `recover()` does not activate B automatically; the caller still owns activation policy.
|
||||
|
||||
## Checks and Limits
|
||||
|
||||
[tests.cpp](tests.cpp) checks all reset points and their continuation, activation guards, loss of temporary verification, damaged contents, wrong release identity, all supplied boot-write outcomes, and repeated recovery without renewing attempts. Checks remain active in Release builds.
|
||||
|
||||
The model compares strings with fixed expected bytes. It has no signatures, real files, flushing, redundant records, or interruption inside a write. It does not model storage wear, concurrent installers, data migration, running processes, or later releases. Direct changes to `Storage` in tests represent faults between installer instances.
|
||||
|
||||
The boot record is simplified to A selected, B trial, or invalid. Attempts are recorded but not consumed here. The printed boot choice is the next lifecycle destination, not a real bootloader decision. Confirmation, attempt exhaustion, and recovery health checks remain in the separate [A/B trial boot example](../ab-trial-boot/readme.md); the programs are not integrated.
|
||||
|
||||
Real storage needs a defined durability contract and failure-injection tests on the target platform. This model checks ordering and recovery decisions only.
|
||||
|
||||
## Sources and Diagrams
|
||||
|
||||
- [simulation.hpp](simulation.hpp) and [simulation.cpp](simulation.cpp): storage, installer, and recovery rules.
|
||||
- [main.cpp](main.cpp): scenario output.
|
||||
- [CMakeLists.txt](CMakeLists.txt): build and CTest integration.
|
||||
- [Preparation and activation sequence](../../../diagrams/plantuml/ab-installation-sequence.puml).
|
||||
- [Installation recovery states](../../../diagrams/plantuml/ab-installation-recovery.puml).
|
||||
|
||||
Format C++ sources with the repository's root `.clang-format`.
|
||||
Reference in new issue
Block a user