Skip to content

fix: gracefully handle out of disk space failures (#3425)#3908

Open
iho wants to merge 1 commit into
mimblewimble:stagingfrom
iho:feat/graceful-disk-full
Open

fix: gracefully handle out of disk space failures (#3425)#3908
iho wants to merge 1 commit into
mimblewimble:stagingfrom
iho:feat/graceful-disk-full

Conversation

@iho

@iho iho commented Jul 10, 2026

Copy link
Copy Markdown

Summary

Addresses #3425: out-of-disk-space during chain writes could leave the node in a state where restart failed with failed to find head hash and operators resorted to grin --clean.

Changes

  1. Detect disk full (store::is_out_of_disk_space / map_io_err) for ErrorKind::StorageFull and Unix ENOSPC.
  2. Durable temp writes (save_via_temp_file): fsync temp file (existing), fsync parent dir after rename, remove temp on failure so the original file is preserved.
  3. Safer AppendOnlyFile::flush: do not clear the rewind backup / buffer until write+sync succeed; log a clear error if the write fails.
  4. Safer extension commit order: sync PMMR backends before committing the child DB batch. If sync fails, discard the extension and return error so the head tip cannot point at incomplete on-disk MMR data.
  5. Explicit errors: store::Error::DiskFull and chain::Error::DiskFull with guidance to free space and avoid wiping chain data unless recovery fails.

Related: #3352 (fsync/leaf_set durability notes), unmerged #3266 (checkpoint idea — not implemented here).

Testing

  • cargo test -p grin_store (includes new disk_full tests)
  • cargo test -p grin_chain --lib
  • cargo test -p grin_chain --test mine_simple_chain

Compatibility

  • Not consensus breaking
  • Behavior change: on disk-full during block accept, the block is rejected/discarded rather than partially committed

Closes #3425

When disk fills during chain writes, avoid committing a DB tip that
points at incomplete MMR state, and surface a clear DiskFull error
instead of opaque I/O failures.

- Detect ENOSPC / StorageFull via is_out_of_disk_space helpers
- Harden save_via_temp_file: fsync parent dir, clean up temp on error,
  leave original file intact if the write fails
- AppendOnlyFile::flush keeps buffer/rewind backup until write+sync
  succeed so discard() can roll back after a failed flush
- Sync PMMR backends before committing the DB batch on extension
  commit; discard extension if sync fails
- Add store::Error::DiskFull and chain::Error::DiskFull with
  operator-facing guidance (free space, avoid --clean unless needed)

Tests: store disk_full suite + existing store/chain regression tests.
Comment thread store/src/lmdb.rs
// heed/lmdb may surface ENOSPC as a map full / I/O error string.
let lower = msg.to_lowercase();
if lower.contains("map full")
|| lower.contains("mdb_map_full")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

map full means it should be resized, not necessary it can be full disk reason, need to check disk space on specific error instead of parsing its messages

Comment thread store/src/lib.rs
return true;
}
let msg = err.to_string().to_lowercase();
msg.contains("no space left") || msg.contains("disk full") || msg.contains("not enough space")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can no handle all possible messages here, so need to check disc space exactly to decide if it was a reason

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