Skip to content

ROX-33036: add mount-related operations - #1059

Merged
Molter73 merged 4 commits into
mainfrom
mauro/ROX-33036/track-mount
Jul 30, 2026
Merged

ROX-33036: add mount-related operations#1059
Molter73 merged 4 commits into
mainfrom
mauro/ROX-33036/track-mount

Conversation

@Molter73

@Molter73 Molter73 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Description

This was originally going to be about adding just lsm/sb_mount, however while adding this hook it became pretty clear we needed lsm/sb_umount and lsm/move_mount for a comprehensive implementation and it really didn't add too much code, so they are all added in.

These operations are not currently intended to be forwarded via gRPC, they only trigger inode tracking related behavior (scans on new/moved mounts, inode map cleanups on moved/unmounted directories).

The move mount operation shares quite a bit of similarities with rename, so there is a bit of refactoring mixed in so they can be reused while keeping the code clean.

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

Added integration tests.

Summary by CodeRabbit

  • New Features
    • Added monitoring and event support for mount, unmount, and move-mount activity.
    • Automatically re-scans the host filesystem on mount-related changes.
    • Added new metrics for mount, unmount, and move-mount activity.
    • Added inode-path introspection updates for more accurate mount tracking.
  • Bug Fixes
    • Updated rename event output to correctly report old vs. new details.
    • When all endpoints are disabled, /metrics now returns HTTP 503.
  • Tests
    • Added root-only mount tracking coverage across mount → unmount transitions.
  • Documentation
    • Updated the changelog with the new mount-related operations.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Mount, unmount, and move-mount hooks now emit events with dedicated metrics. Rust event handling, host scanning, integration-test container setup, and mount tracking tests support these operations.

Changes

Mount event tracking

Layer / File(s) Summary
Kernel mount hooks and event contracts
fact-ebpf/src/bpf/*, fact-ebpf/src/lib.rs, fact/src/metrics/kernel_metrics.rs
Adds mount-related event types, path handling, LSM probes, submission helpers, and per-hook metrics.
Rust event model and serialization
fact/src/event/mod.rs
Adds mount, unmount, and move-mount variants; updates accessors, conversions, serialization, and rename representation.
Host scanner mount handling
fact/src/host_scanner.rs
Triggers a full host scan for mount-related events and skips normal event processing.
Mount integration validation
tests/conftest.py, tests/test_mount.py, tests/test_config_hotreload.py, CHANGELOG.md
Adds mount tracking coverage, container settings, introspection configuration, a hot-reload assertion update, and a changelog entry.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant KernelHooks
  participant RingBuffer
  participant FileData
  participant HostScanner
  KernelHooks->>RingBuffer: submit mount-related event
  RingBuffer->>FileData: construct Mount, Umount, or MoveMount
  FileData->>HostScanner: classify mount-related event
  HostScanner->>HostScanner: perform full host scan
Loading

Possibly related PRs

Suggested reviewers: joukovirtanen, stringy

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.31% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding mount-related operations.
Description check ✅ Passed The description follows the template and covers the change summary, checklist, automated testing, and testing performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mauro/ROX-33036/track-mount

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

@codecov-commenter

codecov-commenter commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.04%. Comparing base (ec9af6d) to head (b68ecb5).

Files with missing lines Patch % Lines
fact/src/event/mod.rs 0.00% 53 Missing ⚠️
fact/src/host_scanner.rs 0.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1059      +/-   ##
==========================================
- Coverage   35.48%   35.04%   -0.45%     
==========================================
  Files          22       22              
  Lines        3235     3276      +41     
  Branches     3235     3276      +41     
==========================================
  Hits         1148     1148              
- Misses       2082     2123      +41     
  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.

@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 3cc1980 to b15f103 Compare July 20, 2026 09:12
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from b15f103 to 0eb199b Compare July 27, 2026 14:50
@Molter73
Molter73 changed the base branch from main to mauro/feat/inodes-introspection July 27, 2026 14:50
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 0eb199b to 5e41f99 Compare July 28, 2026 09:37
@Molter73

Copy link
Copy Markdown
Member Author

/retest

@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from a0d0d78 to edc7efa Compare July 28, 2026 16:11

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
fact/src/event/mod.rs (1)

657-687: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

PartialEq for FileData missing arms for Mount, Umount, MoveMount.

Every other variant (including all pre-existing ones) has an explicit equality arm, but the three new mount variants fall through to _ => false. This means two identical Mount/Umount/MoveMount events will never compare equal.

🐛 Proposed fix
             (FileData::AclSet(this), FileData::AclSet(other)) => {
                 this.inner == other.inner
                     && this.acl_type == other.acl_type
                     && this.entries == other.entries
             }
+            (FileData::Mount(this), FileData::Mount(other)) => this == other,
+            (FileData::Umount(this), FileData::Umount(other)) => this == other,
+            (
+                FileData::MoveMount { to: l_to, from: l_from },
+                FileData::MoveMount { to: r_to, from: r_from },
+            ) => l_to == r_to && l_from == r_from,
             _ => false,
🤖 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/event/mod.rs` around lines 657 - 687, Add explicit equality arms to
PartialEq::eq for FileData covering Mount, Umount, and MoveMount, comparing each
variant’s corresponding fields consistently with the other variant arms. Keep
the fallback _ => false for differing variants.
🧹 Nitpick comments (3)
fact/src/host_scanner.rs (1)

429-439: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Mount events trigger a synchronous full scan per event, with no coalescing for bursts.

handle_mount_event calls self.scan() directly and inline in the select! branch, blocking the task for the scan's duration and running once per mount-related event with no debouncing. The existing scan_trigger/Notify mechanism used for periodic and paths.changed() scans already coalesces repeated triggers (multiple notify_one() calls before consumption collapse to a single pending scan), but that path isn't reused here. Under a burst of mount/unmount activity this could serialize many redundant full scans and delay processing of other events in the loop (e.g. introspection queries).

Also applies to: 493-497

🤖 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/host_scanner.rs` around lines 429 - 439, Update handle_mount_event
to signal the existing scan_trigger/Notify mechanism instead of calling
self.scan() synchronously. Route mount events through the same coalesced scan
path used by periodic and paths.changed() triggers, preserving a single pending
scan during event bursts and keeping the select loop responsive.
fact/src/event/mod.rs (1)

437-535: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider adding Rust-side test coverage for the new Mount/Umount/MoveMount variants.

Codecov flags 130 uncovered lines in this file for this PR, and the PartialEq gap above went unnoticed likely due to this. EventTestData (used by the #[cfg(all(test, feature = "bpf-test"))] constructor) doesn't have variants for the new mount events either.

🤖 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/event/mod.rs` around lines 437 - 535, Add Rust-side tests covering
FileData::Mount, FileData::Umount, and FileData::MoveMount, including their
constructed fields and equality behavior. Extend EventTestData and its bpf-test
constructor with corresponding mount-event variants so these cases can be
exercised through the existing test path, and ensure the tests cover both source
and destination data for MoveMount.
tests/test_mount.py (1)

44-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Subprocess calls don't check exit status.

mount/umount failures (e.g. wrong tmpfs support, misconfigured environment) will pass silently, and the test would then just fail (or worse, pass) based on stale inode state rather than surfacing the real cause.

♻️ Proposed fix
-    subprocess.run(
-        ['mount', '-t', 'tmpfs', '-o', 'size=10M', 'tmpfs', monitored_dir]
-    )
+    subprocess.run(
+        ['mount', '-t', 'tmpfs', '-o', 'size=10M', 'tmpfs', monitored_dir],
+        check=True,
+    )
     assert_tracked_path(monitored_dir)

-    subprocess.run(['umount', monitored_dir])
+    subprocess.run(['umount', monitored_dir], check=True)
🤖 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 `@tests/test_mount.py` around lines 44 - 50, Update the subprocess.run calls in
the mount/umount test to enforce successful exit status, so mount or unmount
failures raise immediately instead of allowing assertions to use stale inode
state. Preserve the existing command arguments and tracking assertions.
🤖 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 `@CHANGELOG.md`:
- Line 9: Update the ROX-33036 changelog entry to hyphenate “mount-related” in
the description of the operations.

In `@fact-ebpf/src/bpf/main.c`:
- Around line 557-603: Update trace_move_mount so events are emitted for every
monitored classification except MONITORED_NOT, matching the sb_mount/sb_umount
handling and allowing parent/path-monitored moves to reach rescan. In the same
function, derive args.parent_inode from to’s actual parent inode rather than
reusing to->dentry->d_inode, and pass that value to is_monitored.

---

Outside diff comments:
In `@fact/src/event/mod.rs`:
- Around line 657-687: Add explicit equality arms to PartialEq::eq for FileData
covering Mount, Umount, and MoveMount, comparing each variant’s corresponding
fields consistently with the other variant arms. Keep the fallback _ => false
for differing variants.

---

Nitpick comments:
In `@fact/src/event/mod.rs`:
- Around line 437-535: Add Rust-side tests covering FileData::Mount,
FileData::Umount, and FileData::MoveMount, including their constructed fields
and equality behavior. Extend EventTestData and its bpf-test constructor with
corresponding mount-event variants so these cases can be exercised through the
existing test path, and ensure the tests cover both source and destination data
for MoveMount.

In `@fact/src/host_scanner.rs`:
- Around line 429-439: Update handle_mount_event to signal the existing
scan_trigger/Notify mechanism instead of calling self.scan() synchronously.
Route mount events through the same coalesced scan path used by periodic and
paths.changed() triggers, preserving a single pending scan during event bursts
and keeping the select loop responsive.

In `@tests/test_mount.py`:
- Around line 44-50: Update the subprocess.run calls in the mount/umount test to
enforce successful exit status, so mount or unmount failures raise immediately
instead of allowing assertions to use stale inode state. Preserve the existing
command arguments and tracking assertions.
🪄 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: 05fc42f0-315c-46df-9f9b-5b00f13b4fd4

📥 Commits

Reviewing files that changed from the base of the PR and between 91987cb and 4a5ee00.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • fact-ebpf/src/bpf/bound_path.h
  • fact-ebpf/src/bpf/events.h
  • fact-ebpf/src/bpf/main.c
  • fact-ebpf/src/bpf/types.h
  • fact-ebpf/src/lib.rs
  • fact/src/event/mod.rs
  • fact/src/host_scanner.rs
  • fact/src/metrics/kernel_metrics.rs
  • tests/conftest.py
  • tests/test_config_hotreload.py
  • tests/test_mount.py

Comment thread CHANGELOG.md Outdated
Comment thread fact-ebpf/src/bpf/main.c
@Molter73 Molter73 changed the title ROX-33036: add mount related operations ROX-33036: add mount-related operations Jul 29, 2026
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 4a5ee00 to 72aa4a2 Compare July 29, 2026 08:33

@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: 2

🤖 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 `@tests/test_mount.py`:
- Line 17: Update the requests.get call for FACT_INTROSPECTION_INODES in the
test to include a finite timeout, using the project’s established timeout
convention if available, so the test fails promptly when the local service is
unavailable or unresponsive.
- Around line 25-35: Update the retry loop around get_inodes so it refreshes res
by calling get_inodes() at the start of each attempt, rather than reusing the
initial snapshot. Preserve the existing assertion, KeyError logging, and retry
delay behavior.
🪄 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: 37bf14d9-5342-4cbd-b40a-6d0974b27ddf

📥 Commits

Reviewing files that changed from the base of the PR and between 4a5ee00 and 72aa4a2.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • fact-ebpf/src/bpf/bound_path.h
  • fact-ebpf/src/bpf/events.h
  • fact-ebpf/src/bpf/main.c
  • fact-ebpf/src/bpf/types.h
  • fact-ebpf/src/lib.rs
  • fact/src/event/mod.rs
  • fact/src/host_scanner.rs
  • fact/src/metrics/kernel_metrics.rs
  • tests/conftest.py
  • tests/test_config_hotreload.py
  • tests/test_mount.py
🚧 Files skipped from review as they are similar to previous changes (9)
  • CHANGELOG.md
  • fact/src/metrics/kernel_metrics.rs
  • fact-ebpf/src/bpf/bound_path.h
  • fact-ebpf/src/bpf/events.h
  • fact/src/host_scanner.rs
  • fact-ebpf/src/bpf/types.h
  • fact-ebpf/src/bpf/main.c
  • tests/test_config_hotreload.py
  • fact/src/event/mod.rs

Comment thread tests/test_mount.py Outdated
Comment thread tests/test_mount.py Outdated
Molter73 added a commit that referenced this pull request Jul 29, 2026
This is a small refactor done ahead of #1059, cleaning up
getters in the `FileData` type by using better pattern matching. The
`Rename` variant is also streamlined by using a struct variant instead
of a tuple holding `RenameFileData`.
Molter73 added a commit that referenced this pull request Jul 29, 2026
This is a small refactor done ahead of #1059, cleaning up
getters in the `FileData` type by using better pattern matching. The
`Rename` variant is also streamlined by using a struct variant instead
of a tuple holding `RenameFileData`.
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 72aa4a2 to 3d17ab3 Compare July 29, 2026 09:25
@Molter73
Molter73 changed the base branch from mauro/feat/inodes-introspection to mauro/refactor/cleanup-file-data-accesors July 29, 2026 09:28
@Molter73
Molter73 marked this pull request as ready for review July 29, 2026 10:33
@Molter73
Molter73 requested a review from a team as a code owner July 29, 2026 10:33
@Molter73
Molter73 force-pushed the mauro/refactor/cleanup-file-data-accesors branch from 631caae to ca94fc3 Compare July 30, 2026 08:22
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 5f72749 to 8240b89 Compare July 30, 2026 08:22
@Molter73
Molter73 disabled auto-merge July 30, 2026 13:21
Molter73 added a commit that referenced this pull request Jul 30, 2026
This is a small refactor done ahead of #1059, cleaning up
getters in the `FileData` type by using better pattern matching. The
`Rename` variant is also streamlined by using a struct variant instead
of a tuple holding `RenameFileData`.
Base automatically changed from mauro/refactor/cleanup-file-data-accesors to main July 30, 2026 13:23
Molter73 added 4 commits July 30, 2026 15:24
This was originally going to be about adding just `lsm/sb_mount`,
however while adding this hook it became pretty clear we needed
`lsm/sb_umount` and `lsm/move_mount` for a comprehensive implementation
and it really didn't add too much code, so they are all added in.

These operations are not currently intended to be forwarded via gRPC,
they only trigger inode tracking related behavior (scans on new/moved
mounts, inode map cleanups on moved/unmounted directories).

The move mount operation shares quite a bit of similarities with rename,
so there is a bit of refactoring mixed in so they can be reused while
keeping the code clean.

TODO: add integration tests.
Add a basic test for checking mount operations are properly tracked.
This test works by checking the monitored directory is tracked using the
inodes introspection endpoint, then a tmpfs is mounted on top of this
directory and we validate we see the new inode, then we unmount and
check the introspection endpoint one last time.
@Molter73
Molter73 force-pushed the mauro/ROX-33036/track-mount branch from 8240b89 to b68ecb5 Compare July 30, 2026 13:24
@Molter73
Molter73 enabled auto-merge (squash) July 30, 2026 13:24

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
fact/src/event/mod.rs (1)

657-687: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

PartialEq for FileData is missing arms for Mount, Umount, and MoveMount.

All other variants (including the newly reshaped Rename { new, old }) have explicit same-variant match arms, but Mount, Umount, and MoveMount fall through to the _ => false catch-all. Two identical Mount/Umount/MoveMount values will therefore never compare equal — unlike every pre-existing variant.

🐛 Proposed fix
             (FileData::SetXattr(this), FileData::SetXattr(other)) => this == other,
             (FileData::RemoveXattr(this), FileData::RemoveXattr(other)) => this == other,
             (FileData::AclSet(this), FileData::AclSet(other)) => {
                 this.inner == other.inner
                     && this.acl_type == other.acl_type
                     && this.entries == other.entries
             }
+            (FileData::Mount(this), FileData::Mount(other)) => this == other,
+            (FileData::Umount(this), FileData::Umount(other)) => this == other,
+            (
+                FileData::MoveMount {
+                    to: l_to,
+                    from: l_from,
+                },
+                FileData::MoveMount {
+                    to: r_to,
+                    from: r_from,
+                },
+            ) => l_to == r_to && l_from == r_from,
             _ => false,
         }
🤖 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/event/mod.rs` around lines 657 - 687, Update the PartialEq
implementation for FileData by adding same-variant comparison arms for Mount,
Umount, and MoveMount, comparing each variant’s payload with == like the
existing variants. Leave the catch-all false behavior for differing variants
unchanged.
fact/src/host_scanner.rs (1)

538-546: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Disable the introspection arm once the channel closes. recv() returning None leaves this branch permanently ready, so the scanner can spin here and miss shutdown. Store the receiver as Option<...> and drop the arm after closure, or break the loop when introspection is gone.

🤖 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/host_scanner.rs` around lines 538 - 546, Update the introspection
receive arm in the scanner loop to handle channel closure permanently: when
self.introspection.recv() returns None, disable or remove the receiver (or exit
the loop) instead of continuing. Preserve request handling and response
serialization for open channels while ensuring the closed channel cannot remain
continuously ready and prevent shutdown.
🧹 Nitpick comments (1)
tests/test_mount.py (1)

44-57: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add integration coverage for move-mount.

This test validates mount and unmount only, while the PR also adds lsm/move_mount. Add a move-mount scenario, or verify that equivalent coverage exists elsewhere, so regressions in that hook are detected.

🤖 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 `@tests/test_mount.py` around lines 44 - 57, Add move-mount integration
coverage to test_mount, using the existing mounted monitored_dir and cleanup
flow to invoke the move-mount operation and assert_tracked_path before and after
it. If equivalent coverage already exists elsewhere, verify it exercises
lsm/move_mount and retain this test’s existing mount/unmount assertions.
🤖 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/host_scanner.rs`:
- Around line 434-437: Update handle_mount_event so a failed self.scan() is
retained as pending work or retried before the mount event is considered
handled, including the corresponding failure path around the other mount-event
handling block. Preserve the existing warning log while ensuring scan_interval =
0 still guarantees a later rescan after a transient failure.
- Around line 429-438: Update the scan flow used by handle_mount_event() to
reconcile tracked paths whose st_dev:st_ino identity changed after a mount or
unmount. Before or during rescanning, remove stale inode records and kernel-map
entries for affected paths (including moved or unmounted subtrees), then
register the current identities so later inode events cannot resolve to old
paths.

---

Outside diff comments:
In `@fact/src/event/mod.rs`:
- Around line 657-687: Update the PartialEq implementation for FileData by
adding same-variant comparison arms for Mount, Umount, and MoveMount, comparing
each variant’s payload with == like the existing variants. Leave the catch-all
false behavior for differing variants unchanged.

In `@fact/src/host_scanner.rs`:
- Around line 538-546: Update the introspection receive arm in the scanner loop
to handle channel closure permanently: when self.introspection.recv() returns
None, disable or remove the receiver (or exit the loop) instead of continuing.
Preserve request handling and response serialization for open channels while
ensuring the closed channel cannot remain continuously ready and prevent
shutdown.

---

Nitpick comments:
In `@tests/test_mount.py`:
- Around line 44-57: Add move-mount integration coverage to test_mount, using
the existing mounted monitored_dir and cleanup flow to invoke the move-mount
operation and assert_tracked_path before and after it. If equivalent coverage
already exists elsewhere, verify it exercises lsm/move_mount and retain this
test’s existing mount/unmount assertions.
🪄 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: 5febde9e-5e12-4628-aafd-b8c4e73cea3f

📥 Commits

Reviewing files that changed from the base of the PR and between 72aa4a2 and b68ecb5.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • fact-ebpf/src/bpf/bound_path.h
  • fact-ebpf/src/bpf/events.h
  • fact-ebpf/src/bpf/main.c
  • fact-ebpf/src/bpf/types.h
  • fact-ebpf/src/lib.rs
  • fact/src/event/mod.rs
  • fact/src/host_scanner.rs
  • fact/src/metrics/kernel_metrics.rs
  • tests/conftest.py
  • tests/test_config_hotreload.py
  • tests/test_mount.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Comment thread fact/src/host_scanner.rs
Comment on lines +429 to +438
/// Handle a mount being modified in a monitored directory.
///
/// This should really do a partial scan of the directory where the
/// mount is being changed, but we don't have an easy way to do that
/// at the moment, so we trigger a full scan instead.
fn handle_mount_event(&self) {
if let Err(e) = self.scan() {
warn!("Host scan failed: {e:?}");
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Reconcile inode identity during mount scans.

handle_mount_event() relies on scan(), but scan() retains entries when their paths still exist. Mounting or unmounting changes st_dev:st_ino while the path remains present, so the new inode is added without removing the old inode/kernel-map entry. This leaves stale /inodes records and can associate later inode events with the wrong path. Compare each tracked path’s current inode identity or purge the affected subtree before rescanning.

The PR objective explicitly requires inode-map cleanup for moved or unmounted directories.

🤖 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/host_scanner.rs` around lines 429 - 438, Update the scan flow used
by handle_mount_event() to reconcile tracked paths whose st_dev:st_ino identity
changed after a mount or unmount. Before or during rescanning, remove stale
inode records and kernel-map entries for affected paths (including moved or
unmounted subtrees), then register the current identities so later inode events
cannot resolve to old paths.

Comment thread fact/src/host_scanner.rs
Comment on lines +434 to +437
fn handle_mount_event(&self) {
if let Err(e) = self.scan() {
warn!("Host scan failed: {e:?}");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Retry or preserve failed mount scans.

handle_mount_event() only logs scan errors, and the caller then discards the mount event. With scan_interval = 0, there is no guaranteed periodic retry, so one transient scan failure can leave inode tracking stale indefinitely. Keep a pending rescan or retry before treating the event as handled.

The integration fixture explicitly uses a zero scan interval.

Also applies to: 493-496

🤖 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/host_scanner.rs` around lines 434 - 437, Update handle_mount_event
so a failed self.scan() is retained as pending work or retried before the mount
event is considered handled, including the corresponding failure path around the
other mount-event handling block. Preserve the existing warning log while
ensuring scan_interval = 0 still guarantees a later rescan after a transient
failure.

@Molter73
Molter73 merged commit 0129f0f into main Jul 30, 2026
61 of 65 checks passed
@Molter73
Molter73 deleted the mauro/ROX-33036/track-mount branch July 30, 2026 14:24
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.

3 participants