Skip to content

fix: stop masking fsync failures in the image store - #447

Merged
kacy merged 1 commit into
mainfrom
hardening/error-handling-sweep
Jun 23, 2026
Merged

fix: stop masking fsync failures in the image store#447
kacy merged 1 commit into
mainfrom
hardening/error-handling-sweep

Conversation

@kacy

@kacy kacy commented Jun 23, 2026

Copy link
Copy Markdown
Owner

summary

third of the four-PR hardening pass — the targeted error-handling sweep.
the audit found ~264 catch {} and ~165 catch unreachable, but the
large majority are legitimately benign (idempotent migrations,
best-effort temp cleanup, writes to disconnected peers, sleeps that only
fail on cancellation). this PR fixes the ones that actually mask a
real fault
: silently-swallowed fsync failures in the image store.

what's in here

four sync() catch {}catch |err| log.warn(...) in the blob/layer
write path:

  • image/layer/create.zig — layer tar fsync
  • image/registry/blob_transfer.zig — downloaded blob fsync
  • image/store/blob_runtime.zig — blob copy + blob store fsync (×2)

a swallowed fsync means a durability failure (disk full, IO error) goes
unnoticed until a later read finds a corrupt/missing layer. content
addressing still guards correctness on read; this adds the early signal
at write time.

deliberately not touched (and why)

  • idempotent schema migrations (addColumnIfMissing ... catch {}) —
    "column already exists" is the expected benign case
  • best-effort temp-file cleanup on error paths — leaving a temp file
    is harmless
  • best-effort client writes in reverse_proxy — the peer is often
    already gone; logging every disconnect would be noise
  • sleep(...) catch unreachable — fails only on cancellation, not
    reachable from external input

a blanket sweep of all 264 sites would be high-churn and risky for no
real safety gain; this stays surgical.

verification

  • YOQ_SKIP_SLOW_TESTS=1 zig build test — 2235 passed, 0 failed
  • tools/panic_audit.sh clean; zig fmt --check clean

four sync() catch {} sites in the image/blob write path swallowed fsync
errors — a durability failure (disk full, IO error) would go unnoticed
until a later read found a corrupt or missing layer. convert each to
catch |err| log.warn(...) so the failure is observable. content
addressing still guards correctness; this adds the early signal.

deliberately left untouched: idempotent schema migrations, best-effort
temp-file cleanup on error paths, best-effort client writes to a
possibly-gone peer, and sleep catch unreachable (not reachable on
external input). those aren't masking real faults — churning them adds
risk without value.
@kacy
kacy merged commit 8fca978 into main Jun 23, 2026
2 checks passed
@kacy
kacy deleted the hardening/error-handling-sweep branch June 23, 2026 01:52
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.

1 participant