Skip to content

fix(bpf): cleanup lpm map when no paths are configured - #1326

Open
Molter73 wants to merge 1 commit into
mainfrom
mauro/fix/cleanup-lpm
Open

fix(bpf): cleanup lpm map when no paths are configured#1326
Molter73 wants to merge 1 commit into
mainfrom
mauro/fix/cleanup-lpm

Conversation

@Molter73

@Molter73 Molter73 commented Jul 30, 2026

Copy link
Copy Markdown
Member

Description

This was causing a bug where the map was not being cleaned up, potentially leading to it being completely full and crashing fact.

Fixes #1322

Checklist

  • Patch has a change log entry OR does not need one.
  • Investigated and inspected CI test results
  • Updated documentation accordingly

Automated testing

  • Added unit tests
  • Added integration tests
  • Added regression tests

If any of these don't apply, please comment below.

Testing Performed

Working on a separate PR that runs all tests on a single fact instance, fact was crashing with a full LPM map and this patch fixes that.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed path-based filtering to correctly remove obsolete path prefixes and prevent stale LPM entries.
    • Ensured all path filter rules are fully cleared when the configured path set becomes empty.
    • Improved incremental updates so added/removed prefixes remain consistent with the active configuration.
    • Strengthened handling of invalid path glob patterns so failures surface as errors instead of being ignored.

@Molter73
Molter73 requested a review from a team as a code owner July 30, 2026 13:16
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 51 lines in your changes missing coverage. Please review.
✅ Project coverage is 34.78%. Comparing base (6ba96be) to head (ed3aee8).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
fact/src/bpf/mod.rs 0.00% 45 Missing ⚠️
fact-ebpf/src/lib.rs 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1326      +/-   ##
==========================================
- Coverage   35.42%   34.78%   -0.64%     
==========================================
  Files          22       22              
  Lines        3241     3300      +59     
  Branches     3241     3300      +59     
==========================================
  Hits         1148     1148              
- Misses       2088     2147      +59     
  Partials        5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Bpf now retains the path_prefix LPM trie and updates it incrementally when paths are reloaded, including explicit cleanup when the configured path set is empty.

Changes

Path prefix reload management

Layer / File(s) Summary
Retain path prefix LPM map
fact/src/bpf/mod.rs, fact-ebpf/src/lib.rs
Bpf extracts and validates the path_prefix LPM trie during initialization, while path_prefix_t gains conversion from LPM trie keys.
Reload and clean path prefixes
fact/src/bpf/mod.rs
load_paths inserts current prefixes into the retained trie and removes stale prefixes, including cleanup when no paths are configured.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: stringy

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses #1322 by removing obsolete prefixes from the kernel-side LPM map and cleaning it when paths are empty.
Out of Scope Changes check ✅ Passed The added conversion in fact-ebpf and the Bpf refactor support the LPM cleanup work and do not look unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly matches the main change: cleaning up the BPF LPM map when no paths are configured.
Description check ✅ Passed The PR description covers the bug, linked issue, checklist, and testing notes, with only minor items left unchecked.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mauro/fix/cleanup-lpm

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
fact/src/bpf/mod.rs (2)

135-206: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add unit tests for the new reload/cleanup logic.

Per the PR objectives, Codecov flagged 0% patch coverage on these changed lines. cleanup_lpm_map, take_path_prefix, and the reload path in load_paths implement the core fix for issue #1322 and would benefit from tests covering: empty-path cleanup, partial-set reload (removed prefixes actually removed), and insert/remove failure handling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fact/src/bpf/mod.rs` around lines 135 - 206, Add unit tests covering the
reload and cleanup behavior in cleanup_lpm_map and load_paths: verify empty
configuration detaches programs, clears prefixes, and resets the globset; verify
partial reload removes prefixes absent from the new configuration; and exercise
both insertion and removal failure handling. Also cover take_path_prefix for
successful extraction and invalid or missing map cases, using test fixtures or
mocks consistent with the existing BPF test infrastructure.

135-146: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

take_path_prefix panics instead of returning a Result, unlike its siblings.

take_inode_map, take_metrics, and take_ringbuffer all return anyhow::Result<T> and use bail! when a map is missing/mistyped. take_path_prefix instead uses unreachable!(), which will abort the process on any mismatch between the compiled BPF object and this code. Given this PR's stated goal is to reduce fact crashes, panicking here (rather than propagating a Result up through Bpf::new) is an inconsistent and avoidable crash path.

♻️ Suggested refactor for consistency
-    fn take_path_prefix(
-        obj: &mut Ebpf,
-    ) -> LpmTrie<MapData, [c_char; LPM_SIZE_MAX as usize], c_char> {
-        let Some(paths_lpm_prefix) = obj.take_map("path_prefix") else {
-            unreachable!("path_prefix map not found");
-        };
-
-        match paths_lpm_prefix.try_into() {
-            Ok(map) => map,
-            Err(_) => unreachable!("path_prefix map is not LpmTrie"),
-        }
-    }
+    fn take_path_prefix(
+        obj: &mut Ebpf,
+    ) -> anyhow::Result<LpmTrie<MapData, [c_char; LPM_SIZE_MAX as usize], c_char>> {
+        let Some(paths_lpm_prefix) = obj.take_map("path_prefix") else {
+            bail!("path_prefix map not found");
+        };
+        Ok(paths_lpm_prefix.try_into()?)
+    }

and adjust the call site (let paths_lpm_map = Bpf::take_path_prefix(&mut obj)?;).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fact/src/bpf/mod.rs` around lines 135 - 146, Update take_path_prefix to
return anyhow::Result<LpmTrie<...>> like take_inode_map, take_metrics, and
take_ringbuffer; replace both unreachable! paths with bail! errors. Propagate
the result through Bpf::new by calling Bpf::take_path_prefix with ?, preserving
successful map extraction while avoiding panics for missing or mistyped maps.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@fact/src/bpf/mod.rs`:
- Around line 156-162: The cleanup_lpm_map method must retain any path prefix
whose paths_lpm_map.remove operation fails, so it can be retried later. Update
the surrounding self.paths update logic to preserve failed removals instead of
unconditionally replacing tracking with new_paths, while continuing to remove
successfully deleted prefixes.
- Around line 177-203: Make prefix reload in the paths update flow keep
self.paths consistent with paths_lpm_map when any iteration or globset build
fails. Update the logic around the new_paths construction, paths_lpm_map.insert,
and final self.paths assignment to either record each successfully inserted
prefix incrementally or remove all prefixes inserted during the failed reload
before returning the error; preserve successful reload behavior and ensure
cleanup_lpm_map cannot miss partially inserted entries.
- Around line 187-191: Update the glob construction in the builder loop to
propagate the contextualized invalid-pattern error with the function’s existing
anyhow result flow instead of calling unwrap. Preserve the current “invalid
glob” context and let the surrounding fallible operations continue using ?.

---

Nitpick comments:
In `@fact/src/bpf/mod.rs`:
- Around line 135-206: Add unit tests covering the reload and cleanup behavior
in cleanup_lpm_map and load_paths: verify empty configuration detaches programs,
clears prefixes, and resets the globset; verify partial reload removes prefixes
absent from the new configuration; and exercise both insertion and removal
failure handling. Also cover take_path_prefix for successful extraction and
invalid or missing map cases, using test fixtures or mocks consistent with the
existing BPF test infrastructure.
- Around line 135-146: Update take_path_prefix to return
anyhow::Result<LpmTrie<...>> like take_inode_map, take_metrics, and
take_ringbuffer; replace both unreachable! paths with bail! errors. Propagate
the result through Bpf::new by calling Bpf::take_path_prefix with ?, preserving
successful map extraction while avoiding panics for missing or mistyped maps.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Enterprise

Run ID: 2b139f62-14b0-400c-87bd-9fb8ab688c1a

📥 Commits

Reviewing files that changed from the base of the PR and between 6ba96be and 7534e09.

📒 Files selected for processing (1)
  • fact/src/bpf/mod.rs

Comment thread fact/src/bpf/mod.rs Outdated
Comment thread fact/src/bpf/mod.rs Outdated
Comment thread fact/src/bpf/mod.rs
@Molter73
Molter73 force-pushed the mauro/fix/cleanup-lpm branch from 7534e09 to ee2012c Compare July 30, 2026 15:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@fact/src/bpf/mod.rs`:
- Around line 132-144: Update take_path_prefix to return
anyhow::Result<LpmTrie<MapData, [c_char; LPM_SIZE_MAX as usize], c_char>>,
replacing both unreachable! paths with descriptive bail! errors for a missing or
mismatched path_prefix map. Update its call site to propagate the Result using
the surrounding error-handling convention, matching take_inode_map,
take_metrics, and take_ringbuffer.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Enterprise

Run ID: 07f131ad-7416-421b-99da-565a1032af27

📥 Commits

Reviewing files that changed from the base of the PR and between 7534e09 and ee2012c.

📒 Files selected for processing (2)
  • fact-ebpf/src/lib.rs
  • fact/src/bpf/mod.rs

Comment thread fact/src/bpf/mod.rs
@Molter73
Molter73 force-pushed the mauro/fix/cleanup-lpm branch from ee2012c to 0ae62ac Compare July 30, 2026 15:16
This was causing a bug where the map was not being cleaned up,
potentially leading to it being completely full and crashing fact.
@Molter73
Molter73 force-pushed the mauro/fix/cleanup-lpm branch from 0ae62ac to ed3aee8 Compare July 30, 2026 15:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
fact/src/bpf/mod.rs (1)

153-180: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider adding test coverage for the new cleanup/reload logic.

The PR's Codecov report flagged 0% patch coverage across the changed lines in this file, including cleanup_lpm_map and the reworked load_paths. Since this is the exact logic that fixes the LPM-map-fills-up crash (issue #1322), a regression here would silently reintroduce the original bug. A unit/integration test exercising a reload cycle (insert prefixes → reload with a subset → assert stale prefixes are removed from the trie, plus the empty-config wipe case) would meaningfully de-risk this path.

Also applies to: 189-211

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fact/src/bpf/mod.rs` around lines 153 - 180, Add test coverage for the reload
behavior implemented by cleanup_lpm_map and load_paths: insert multiple
prefixes, reload with a subset, and assert removed prefixes no longer exist in
the LPM trie; also verify that reloading with an empty configuration clears the
map. Use the existing test setup and public behavior rather than changing
production logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@fact/src/bpf/mod.rs`:
- Around line 153-180: Add test coverage for the reload behavior implemented by
cleanup_lpm_map and load_paths: insert multiple prefixes, reload with a subset,
and assert removed prefixes no longer exist in the LPM trie; also verify that
reloading with an empty configuration clears the map. Use the existing test
setup and public behavior rather than changing production logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Enterprise

Run ID: f0abe901-71c7-49c8-aa4f-e37adb780e5a

📥 Commits

Reviewing files that changed from the base of the PR and between ee2012c and 0ae62ac.

📒 Files selected for processing (2)
  • fact-ebpf/src/lib.rs
  • fact/src/bpf/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • fact-ebpf/src/lib.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
fact/src/bpf/mod.rs (1)

177-211: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add regression coverage for incremental and empty-path cleanup.

Codecov reports no coverage for the reload logic. Add tests that preload prefixes, reload with a changed set, then reload with an empty set; assert stale trie keys are removed while retained/new keys remain.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fact/src/bpf/mod.rs` around lines 177 - 211, The load_paths reload behavior
in load_paths lacks regression coverage for incremental updates and empty-path
cleanup. Add tests that preload prefixes, reload with a changed configuration,
and verify stale LPM trie keys are removed while retained and new keys remain;
then reload with an empty configuration and verify all keys are cleaned up and
programs are detached. Use the existing paths_lpm_map and paths_config test
setup and target load_paths directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@fact/src/bpf/mod.rs`:
- Around line 177-211: The load_paths reload behavior in load_paths lacks
regression coverage for incremental updates and empty-path cleanup. Add tests
that preload prefixes, reload with a changed configuration, and verify stale LPM
trie keys are removed while retained and new keys remain; then reload with an
empty configuration and verify all keys are cleaned up and programs are
detached. Use the existing paths_lpm_map and paths_config test setup and target
load_paths directly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Enterprise

Run ID: 108ee8ab-384d-4ae3-8e4a-794a3a9cbefe

📥 Commits

Reviewing files that changed from the base of the PR and between 0ae62ac and ed3aee8.

📒 Files selected for processing (2)
  • fact-ebpf/src/lib.rs
  • fact/src/bpf/mod.rs

@Molter73
Molter73 enabled auto-merge (squash) July 30, 2026 15:48
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.

fact does not cleanup the LPM prefix map in kernel side

2 participants