advanced30 min studyLesson 180 in Engineering

Crash experiments that test a stated recovery invariant

Design disposable, reproducible persistence experiments with explicit fault models, acknowledgment logs, allowed states, and minimized failing traces.

On this page

What you’ll understand

  • Define allowed recovered states relative to durable acknowledgments.
  • Distinguish process termination, guest failure, and power-loss fault coverage.
  • Construct a reproducible crash matrix and minimize a failing operation trace without destroying evidence.

A persistence protocol is a claim about what remains true after interruption. Running the happy path and finding a readable file does not test that claim. A useful experiment specifies the invariant, interrupts particular dependencies under a defined fault model, and classifies the recovered state against what was actually acknowledged. Perform destructive crash work only on disposable test storage with a preserved initial image and a separate evidence channel; the method is about controlled learning, not surprising production systems.

Define the oracle before choosing a crash button

Start with an application invariant, such as a public manifest naming a generation whose payload digest matches. Then define the acknowledgment promise: after durable success, recovery must expose that generation or a later valid committed generation according to the protocol. Before acknowledgment, an old or new complete generation may be allowed, while a manifest paired with partial payload is forbidden. This allowed-state set is the oracle. A filesystem that mounts cleanly can still fail it; a leftover temporary file may be harmless if the protocol explicitly permits and safely cleans it.

Keep the acknowledgment record outside the failure domain being tested, or use a harness whose observation semantics are explicit. Otherwise the test can lose the evidence telling it which operations were promised durable. Record operation identifiers, generation numbers, byte counts, synchronization results, and crash cut points. A wall-clock timestamp alone does not reconstruct persistence order or prove a syscall completed before the failure. Treat failed or interrupted operations as uncertain according to their contract rather than automatically classifying them as absent.

ack⁡(g)⟹R∈Aafter(g),¬ack⁡(g)⟹R∈Abefore(g)\operatorname{ack}(g)\Longrightarrow R\in\mathcal{A}_{\rm after}(g),\qquad \neg\operatorname{ack}(g)\Longrightarrow R\in\mathcal{A}_{\rm before}(g)
R is the recovered application state and the two A sets are protocol-defined allowed states after or before durable acknowledgment of generation g. The second implication assumes this is the current attempted generation and a known previous valid state; absence of acknowledgment is not proof the operation had no effect.↔ Scroll wide equations horizontally.

Fault models have different failure domains

Killing only an application leaves the kernel, page cache, and device running; pending writeback can continue. It tests application recovery from process interruption but is not a power-loss test. Crashing a virtual machine can discard guest memory while host caching remains, depending on the virtual-disk setup. A physical power interruption has different behavior again, including device caches and power-loss protection. State precisely which buffers and components survive each experiment. Do not label every abrupt stop as a disk crash and then generalize its passing result to stronger faults.

A controlled block-device or virtual-storage fault-injection harness can explore selected reorderings, lost writes, and errors, but its model is also a specification with limits. Identify whether it represents flush and FUA correctly, whether sectors can tear, and which completed writes are eligible to disappear. Filesystem version, mount settings, kernel, virtual-disk cache configuration, device firmware, and initial layout belong with the result. Original crash-consistency research shows why application protocols need testing across persistence behaviors rather than assuming one filesystem's incidental ordering is portable.

Ncases=NcutsNconfigurationsNrepetitionsN_{\rm cases}=N_{\rm cuts}N_{\rm configurations}N_{\rm repetitions}
This Cartesian-product count assumes every chosen cut is exercised under every configuration and repetition. It counts executions, not semantic coverage; repeated identical schedules can leave important permitted persistence orderings unexplored.↔ Scroll wide equations horizontally.

Minimize failures and separate coverage from confidence

On each run, restore the known starting image, execute one recorded operation trace, interrupt at the selected point, recover through the documented filesystem procedure, and inspect the application oracle before making repairs. Preserve the failed image, trace, configuration, and checksums. Reduce a failing sequence by removing unrelated operations while retaining the failure and prerequisite state. A small counterexample that names the broken ordering is more useful than a large collection of unexplained corrupt images. Rerun the proposed fix against the original failure and neighboring cuts.

The probability lab illustrates repeated independent detection opportunities, not exhaustive correctness. Let p be a hypothetical probability that one trial exposes a particular bug, and n the number of independent trials up to the lab's thirty-trial limit. Increase n and predict more probability of at least one detection; the zero-success bar gives the complement. Real cut points are often correlated and p is unknown, so a hundred clean runs cannot be converted into proof by inventing independence. The lab runs no filesystem and injects no crash; use it to explain why both systematic cases and repeated trials matter.

Build and interpret a crash matrix

A disposable harness tests eight cut points around a publication protocol, three documented filesystem configurations, and five repetitions per pair. It finds an acknowledged generation with a mismatching payload after one recovery.

  1. The planned matrix has 8 × 3 × 5 = 120 executions. Preserve the exact cut, configuration, operation trace, acknowledgment evidence, and recovered image for the failing case.

  2. The post-acknowledgment oracle rejects the mismatching payload even if the filesystem mounted normally. Check whether the protocol, storage stack, or fault model violated a required assumption before assigning a cause.

  3. After fixing the identified defect, rerun the minimized reproducer and the full 120-case matrix. Passing those cases is evidence for their defined coverage, not a proof against every possible ordering or physical fault.

The result

One well-observed forbidden state can refute a durability claim. Many passing executions strengthen bounded evidence only when their configurations and fault coverage are explicit.

Explore the model

Interactive lab

Interactive lab · probability

Repeated trials are not exhaustive exploration

Set hypothetical independent bug-exposure probability p and trial count n between one and thirty in the binomial model. Predict that the zero-success bar is (1−p)^n. Real crash schedules may be correlated and p unknown; this is not a filesystem crash tester or a correctness certificate.

Repeated trials are not exhaustive explorationThese are exact binomial probabilities for independent trials with one fixed success probability. Playback tours the distribution; it does not resample outcomes. Current readings: Mean · np: 5; Variance · np(1−p): 2.5; Total probability: 1. All parameters are adjustable with the labeled controls below.03581000.070.150.220.3Successes kP(X = k)k = 0 · P = 9.77e-4
Exact probabilityHighlighted outcomeMean np
Mean · np
5
Variance · np(1−p)
2.5
Total probability
1
t = 0 s

These are exact binomial probabilities for independent trials with one fixed success probability. Playback tours the distribution; it does not resample outcomes. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forUse repetitions to supplement a systematic fault matrix, while treating unknown exposure probabilities and shared schedules honestly.

Check your understanding

A test kills only the writer process after write returns, waits, and then finds the complete file. What does that observation establish?

Try it yourself

A protocol has six selected crash cuts and two storage configurations. Four repetitions of each pair pass. State the execution count and write one defensible claim and one unsupported claim about the result.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Count the matrix, then keep its defined fault model separate from universal correctness.

Compare with the solution

The matrix contains 6 × 2 × 4 = 48 executions. A defensible claim is that all 48 recorded runs satisfied the stated recovery oracle under the two documented configurations and selected fault model. An unsupported claim is that no crash can ever lose acknowledged data on any filesystem or device. New orderings, configurations, and stronger failure domains remain outside that evidence.

Take it with you

  • A crash test needs a post-recovery application oracle tied to observed acknowledgments.
  • Process death, guest failure, and physical power loss preserve different buffers and components.
  • Preserved counterexamples and explicit fault coverage provide stronger evidence than an unexplained count of passing runs.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.