From 885cf3ab41f2b95849a21c58a84c02d91093742e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 15:51:12 +0000 Subject: [PATCH] fix(hydrate): gate posix_fadvise to Linux/Android, not cfg(unix) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `release.rs` gated three sites `#[cfg(unix)]` and called `libc::posix_fadvise` / `libc::POSIX_FADV_DONTNEED` inside them. `posix_fadvise` is a Linux/Android extension, not POSIX-universal — Apple's libc does not declare it — so the crate failed to compile on macOS with `error[E0425]: cannot find function 'posix_fadvise' in crate 'libc'`. `cfg(unix)` reads as "has fadvise"; it isn't. The three sites are now gated `#[cfg(any(target_os = "linux", target_os = "android"))]`, with the existing fallback arm widened to cover macOS/BSD, and a doc comment recording the rule: widen this gate only to targets whose libc actually declares the call. Verification: - cfg selection proved two-sidedly on the pinned 1.98.1 toolchain with a `#![no_std]` rustc probe — `x86_64-apple-darwin` excludes the Linux arm, `x86_64-unknown-linux-gnu` selects it. The failure is target-OS-driven, not arch-driven. - 39/39 crate tests green on Linux (incl. the 3 in `release.rs`); `cargo fmt --check` and `clippy -p lance-graph-hydrate --all-targets -- -D warnings` clean. - Not compiled for darwin end-to-end here: `ring` needs a C toolchain this sandbox lacks. The macOS half rests on the cfg proof plus CI. Board: files `ISS-NO-NON-LINUX-TARGET`. Neither existing issue covers this one — `ISS-NO-AARCH64-RUNNER` is about target arch, and `ISS-EXCLUDED-CRATES-UNBUILT` is about the member list, while `lance-graph-hydrate` is a member that CI compiles on every PR. The accurate statement is the union: CI builds exactly one (target_os, target_arch, crate-list) tuple, and this week's three defects each fall on a different one of those axes. Found by q2's newly-ungated macos-latest job — a downstream consumer's CI doing this repo's job, for the third time in one week. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01AGVLyRZNEKKBSfBDJfbY3V --- .claude/board/ISSUES.md | 44 +++++++++++++++++++++++ crates/lance-graph-hydrate/src/release.rs | 21 +++++++---- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/.claude/board/ISSUES.md b/.claude/board/ISSUES.md index 8b3980721..d8064ac5c 100644 --- a/.claude/board/ISSUES.md +++ b/.claude/board/ISSUES.md @@ -1,3 +1,47 @@ +## ISS-NO-NON-LINUX-TARGET (2026-09-06) — OPEN + +**Neither filed issue covers the defect that opened this one, and the difference +is the generalization.** `crates/lance-graph-hydrate/src/release.rs` gated three +sites `#[cfg(unix)]` and called `libc::posix_fadvise` / `libc::POSIX_FADV_DONTNEED` +inside them. `posix_fadvise` is **Linux/Android, not POSIX-universal** — Apple's +libc does not declare it — so the crate fails to compile on macOS with +`error[E0425]: cannot find function 'posix_fadvise' in crate 'libc'`. `cfg(unix)` +reads as "has fadvise" and is not. + +Why the two existing issues miss it: + +- `ISS-NO-AARCH64-RUNNER` is about target **arch**. This is target **OS**: the cfg + selection was proved two-sidedly on the pinned 1.98.1 toolchain with a `#![no_std]` + rustc probe — `x86_64-apple-darwin` excludes the Linux arm, `x86_64-unknown-linux-gnu` + selects it. An x86 macOS runner would have caught this; an aarch64 *Linux* one + would not. +- `ISS-EXCLUDED-CRATES-UNBUILT` is about the **member list**. `lance-graph-hydrate` + is a workspace member, compiled and linted by CI on every PR. The crate list was + never the gap here. + +**The accurate statement is the union, not either half:** CI compiles exactly ONE +`(target_os, target_arch, crate-list)` tuple — `(linux, x86_64, members)`. Every +`cfg` block outside it is text the parser skips. The three defects found this week +each fall in a different one of those three axes, which is why fixing one axis would +not have caught the other two. + +**Found the same way as the other two:** by q2's newly-ungated `macos-latest` job — +a downstream consumer's CI doing this repo's job, for the third time in one week. +Nothing in this repo's own CI was capable of seeing it. + +**Fixed here** (the point repair): the three sites are gated +`#[cfg(any(target_os = "linux", target_os = "android"))]` with a fallback arm for +macOS/BSD, and the doc comment records the rule — *widen this gate only to targets +whose libc actually declares the call*. 39/39 crate tests green on Linux. + +**Not fixed here:** the axis. A `runs-on: macos-latest` job, or a cheap +`cargo check --target x86_64-apple-darwin` on the existing x86 runners, is a CI +policy change and an operator call. Note the cheap form needs +`rustup target add --toolchain 1.98.1 ` — installing a target for the +DEFAULT toolchain while the repo pins 1.98.1 produces a `can't find crate for 'core'` +that reads like a broken probe rather than a missing std; that cost a turn this +session. + ## ISS-NO-AARCH64-RUNNER (2026-09-06) — OPEN **Every `#[cfg(target_arch = "aarch64")]` block in this repo is unverified, because diff --git a/crates/lance-graph-hydrate/src/release.rs b/crates/lance-graph-hydrate/src/release.rs index 1c3dbd33f..acbf78552 100644 --- a/crates/lance-graph-hydrate/src/release.rs +++ b/crates/lance-graph-hydrate/src/release.rs @@ -22,7 +22,7 @@ use std::path::{Path, PathBuf}; /// in the page cache. A no-op hint — `POSIX_FADV_DONTNEED` can only be /// declined, never fail unsafely, so the return value is intentionally not /// surfaced. -#[cfg(unix)] +#[cfg(any(target_os = "linux", target_os = "android"))] fn advise_dontneed_file(f: &fs::File) { use std::os::unix::io::AsRawFd; let fd = f.as_raw_fd(); @@ -36,9 +36,9 @@ fn advise_dontneed_file(f: &fs::File) { } } -/// unix: open the file and advise DONTNEED; only counts on successful open -/// (matches the prior behavior this council hardened). -#[cfg(unix)] +/// linux/android: open the file and advise DONTNEED; only counts on successful +/// open (matches the prior behavior this council hardened). +#[cfg(any(target_os = "linux", target_os = "android"))] fn release_one_file(path: &Path) -> bool { if let Ok(f) = fs::File::open(path) { advise_dontneed_file(&f); @@ -48,10 +48,19 @@ fn release_one_file(path: &Path) -> bool { } } -/// non-unix: there is no portable fadvise equivalent, so opening the file +/// Everywhere else: there is no `posix_fadvise` equivalent, so opening the file /// would be pure syscall cost for zero benefit — a council-found waste /// (2026-08-17). Count the entry without opening it. -#[cfg(not(unix))] +/// +/// **This arm covers macOS and the other BSDs, not just non-unix.** The gate +/// was `cfg(unix)` until 2026-09-06, which reads as "has fadvise" but is not: +/// `posix_fadvise` is a Linux (and Android) interface that Apple's libc does +/// not provide, so `libc` does not declare it for `*-apple-*` and the crate +/// failed to compile there with `E0425: cannot find function posix_fadvise`. +/// Nothing caught it because every lance-graph CI runner is `ubuntu-*`; it +/// surfaced only through a downstream consumer's macOS job. Widen this gate +/// only to targets whose libc actually declares the call. +#[cfg(not(any(target_os = "linux", target_os = "android")))] fn release_one_file(_path: &Path) -> bool { true }