Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f2f0677
fix(tunnel): keep tunnel captures out of git
tolgaergin Oct 11, 2026
c650ea4
fix(tunnel): run no repository code, and say only what git confirms a…
tolgaergin Oct 11, 2026
37556b8
test(tunnel): check linked sidecars and leftover capture file modes d…
tolgaergin Oct 11, 2026
2edf4d1
fix(tunnel): keep the untrack advice as short as the list it follows
tolgaergin Oct 11, 2026
d7e983a
fix(tunnel): restrict capture files through their handle, and read .l…
tolgaergin Oct 11, 2026
92efd3a
fix(tunnel): keep captures from other users and planted files, and as…
tolgaergin Oct 12, 2026
fd2f611
fix(tunnel): review captures without replacing, and refuse planted sc…
tolgaergin Oct 12, 2026
53d7428
fix(tunnel): let captures open past a reader where modes don't hold, …
tolgaergin Oct 12, 2026
9327450
fix(tunnel): keep quoted schema text, count ownership-ignoring volume…
tolgaergin Oct 12, 2026
9fdfbcf
fix(tunnel): read schema SQL as SQLite tokenizes it, check the replac…
tolgaergin Oct 12, 2026
947c211
fix(tunnel): name the room a full disk lacks on the check's first rea…
tolgaergin Oct 13, 2026
73c7436
fix(tunnel): keep another connection's WAL files, name the room taken…
tolgaergin Oct 13, 2026
7d079d7
fix(tunnel): name the files that move with the capture database, coun…
tolgaergin Oct 13, 2026
4017a80
test(tunnel): expect the database advice that names its sidecars in t…
tolgaergin Oct 13, 2026
c223c06
fix(tunnel): open another user's captures as that user under root, an…
tolgaergin Oct 13, 2026
1ce07b4
Merge remote-tracking branch 'origin/main' into fix/tunnel-capture-gi…
tolgaergin Oct 13, 2026
95c5dba
fix(tunnel): keep captures only where no one else can change the path…
tolgaergin Oct 13, 2026
6d43cbf
Merge branch 'main' into fix/tunnel-capture-gitignore
tolgaergin Oct 13, 2026
1198e7c
test(common): check APFS's reserve where it holds on every release
tolgaergin Oct 13, 2026
8ecd4a5
Merge main into fix/tunnel-capture-gitignore
tolgaergin Oct 14, 2026
7c15b9f
Merge remote-tracking branch 'origin/main' into fix/tunnel-capture-gi…
tolgaergin Oct 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/lpm-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ wiremock = "0.6"
assert_cmd = "2"
insta = { version = "1", features = ["json"] }
lpm-vault = { workspace = true, features = ["acceptance-test-hooks"] }
# Damages a test project's capture database to exercise disk failures.
rusqlite = { version = "0.40", features = ["bundled"] }

# Phase 46 P4 Chunk 2: generate synthetic x509 certs with URI SANs in
# unit tests so the SAN-extractor is exercised against deterministic
Expand Down
33 changes: 2 additions & 31 deletions crates/lpm-cli/src/commands/cache_prune.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ fn run_all_virtual_stores_locked(
) -> Result<PruneSummary, LpmError> {
let free_before = flags
.apply
.then(|| filesystem_available_bytes(v3_store.paths().root()))
.then(|| lpm_common::filesystem_available_bytes(v3_store.paths().root()))
.flatten();
let stores = [v2_store, v3_store];
let directories = [
Expand Down Expand Up @@ -353,7 +353,7 @@ fn run_all_virtual_stores_locked(
}
let mut summary = merge_prune_summaries(v2, v3);
summary.observed_physical_bytes_freed = free_before.and_then(|before| {
filesystem_available_bytes(v3_store.paths().root())?.checked_sub(before)
lpm_common::filesystem_available_bytes(v3_store.paths().root())?.checked_sub(before)
});
Ok(summary)
}
Expand Down Expand Up @@ -1498,35 +1498,6 @@ fn dir_size(dir: &Path) -> std::io::Result<u64> {
Ok(total)
}

#[cfg(unix)]
fn filesystem_available_bytes(path: &Path) -> Option<u64> {
use std::ffi::CString;
use std::os::unix::ffi::OsStrExt;

let mut probe = path.to_path_buf();
while !probe.try_exists().ok()? {
if !probe.pop() {
return None;
}
}
let path = CString::new(probe.as_os_str().as_bytes()).ok()?;
let mut stats = std::mem::MaybeUninit::<libc::statvfs>::uninit();
// SAFETY: `path` is NUL-terminated and `stats` points to writable,
// properly aligned storage that is read only after a successful call.
if unsafe { libc::statvfs(path.as_ptr(), stats.as_mut_ptr()) } != 0 {
return None;
}
// SAFETY: `statvfs` returned success and initialized the output structure.
let stats = unsafe { stats.assume_init() };
let bytes = u128::from(stats.f_bavail).checked_mul(u128::from(stats.f_frsize))?;
u64::try_from(bytes).ok()
}

#[cfg(not(unix))]
fn filesystem_available_bytes(_path: &Path) -> Option<u64> {
None
}

/// LRU + crash-recovery orphan detection for the compat-island cache at
/// `~/.lpm/store/v2/compat/`.
///
Expand Down
Loading
Loading