OXYGENHUB

Re-read a pinned file from the disk before calling its hash wrong ab3204b9974b

A mismatch drops the file's cached pages (posix_fadvise DONTNEED) and
hashes it again; when the disk's copy is right, a warning says the
cached copy was bad. earth-1 failed every job on the rust image for
three hours through one bad cached page while the file was intact.

closes #22
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-02 20:23 UTC
Signature
✔ signed by Andy McCall
Hash
ab3204b9974bba7d93682a006d2d88fc713dd77052440e87687c16a344ae264c
Depends on
e0918b887850
Depended on by
nothing yet
In bookmarks
main newer-pipeline push-uses-login
In tags
v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.5.0 v0.5.1 v0.5.2 v0.5.3
Edits
5 atoms, 0 tree operations, 1 file

Browse the tree at this change

modified crates/flow/src/home.rs +31 −1
…
97 unchanged lines
98 98
        if self.verified.lock().unwrap().get(path) == Some(&stamp) {
99 99
            return Ok(path.to_path_buf());
100 100
        }
101 -
        let got = hash_file(path)?;
101 +
        let mut got = hash_file(path)?;
102 102
        if got != blake3_hex {
103 +
            // The read may have come from bad cached pages rather than the
104 +
            // disk (oxygenflow#22: a RAM fault on Earth failed every job for
105 +
            // hours while the file was intact): drop the file's pages and
106 +
            // read it again from the disk before giving up.
107 +
            drop_cached(path);
108 +
            let again = hash_file(path)?;
109 +
            if again == blake3_hex {
110 +
                eprintln!(
111 +
                    "warning: {} hashed {got} from the page cache but {again} from the disk: the cached copy was bad (check this machine's memory)",
112 +
                    path.display()
113 +
                );
114 +
            }
115 +
            got = again;
116 +
        }
117 +
        if got != blake3_hex {
103 118
            bail!("{} has BLAKE3 {got}, but {blake3_hex} is pinned", path.display());
104 119
        }
105 120
        self.verified.lock().unwrap().insert(path.to_path_buf(), stamp);
106 121
        Ok(path.to_path_buf())
122 +
    }
123 +
}
124 +
125 +
/// Ask the kernel to forget a file's cached pages, so the next read comes
126 +
/// from the disk. Best effort: dirty pages and other platforms stay.
127 +
fn drop_cached(path: &Path) {
128 +
    #[cfg(target_os = "linux")]
129 +
    if let Ok(f) = std::fs::File::open(path) {
130 +
        use std::os::fd::AsRawFd;
131 +
        // SAFETY: a valid descriptor; the advice only affects caching.
132 +
        unsafe {
133 +
            libc::posix_fadvise(f.as_raw_fd(), 0, 0, libc::POSIX_FADV_DONTNEED);
134 +
        }
107 135
    }
136 +
    #[cfg(not(target_os = "linux"))]
137 +
    let _ = path;
108 138
}
109 139
110 140
pub fn hash_file(path: &Path) -> Result<String> {
…
4 unchanged lines