Skip to content

o/snapshotstate, o/s/backend: saving snapshot excludes all mount points#17182

Open
Mohit-Chachada wants to merge 4 commits into
canonical:masterfrom
Mohit-Chachada:snapshot-excludes-all-mounts
Open

o/snapshotstate, o/s/backend: saving snapshot excludes all mount points#17182
Mohit-Chachada wants to merge 4 commits into
canonical:masterfrom
Mohit-Chachada:snapshot-excludes-all-mounts

Conversation

@Mohit-Chachada

@Mohit-Chachada Mohit-Chachada commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Follows #17119

Extends the previously added exclusion of snapctl mounts to now exclude all mount points under snap data dirs while saving a snapshot.

  • data dirs of all users set in the "snapshot-setup" are checked, in addition to the root user and global data dirs. If no users are set, all users' data dirs are checked
  • all mount paths are mapped to the snapshot's Exclude pattern and appended to SnapshotOptions's dynamic Exclude list

Review hint: due to spread test renaming, the overall diff shows the old file as deleted and new one as added. For reviewing just the diff of the spread test, look at commit a933b67

SNAPDENG-37006

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR broadens snapshot creation behavior in overlord/snapshotstate so that any active mount points under a snap’s data directories (global and per-user) are automatically added to the snapshot’s dynamic exclude list, preventing mounted-in data from being captured.

Changes:

  • Replace the mount-control/systemd-based mount discovery with /proc/self/mountinfo parsing and map mounts under $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA, $SNAP_USER_COMMON into snapshot excludes.
  • Add backend helper to map absolute snap data directories to the corresponding $SNAP_* variables, including user directories (selected users or all users).
  • Update unit tests accordingly and replace the old spread test with a new one that covers both snapctl mounts and user-created mounts (where applicable).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/main/snapshot-excludes-mounts/task.yaml New spread test validating that mount points under snap data dirs are excluded from snapshots (including user dirs for snap save).
tests/main/snapshot-excludes-mount-control-mounts/task.yaml Removed older spread test limited to mount-control mounts; superseded by the new broader test.
overlord/snapshotstate/snapshotmgr.go Implement mount exclusion via osutil.LoadMountInfo() and generalized mapping to $SNAP_* excludes for global + user dirs.
overlord/snapshotstate/snapshotmgr_test.go Update tests to use mocked mountinfo and validate mapping/exclusion behavior across global + user dirs and error paths.
overlord/snapshotstate/export_test.go Export updated mapping helper and add a mock hook for backend dir→var mapping.
overlord/snapshotstate/backend/mountunit.go Removed systemd mount-unit helper (no longer needed).
overlord/snapshotstate/backend/mountunit_test.go Removed tests for the deleted systemd mount-unit helper.
overlord/snapshotstate/backend/backend.go Add MapSnapDataDirToSnapVar helper used by snapshotstate to build exclude patterns.
overlord/snapshotstate/backend/backend_test.go Add coverage for MapSnapDataDirToSnapVar behavior (all users, selected users, and error handling).

Comment thread tests/main/snapshot-excludes-mounts/task.yaml
Comment thread tests/main/snapshot-excludes-mounts/task.yaml
@Mohit-Chachada Mohit-Chachada force-pushed the snapshot-excludes-all-mounts branch from 4531d32 to a933b67 Compare June 10, 2026 09:12
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

Mon Jun 15 15:00:44 UTC 2026
The following results are from: https://github.com/canonical/snapd/actions/runs/27549569605

Failures:

Preparing:

  • openstack:arch-linux-64:tests/main/postrm-purge
  • openstack:ubuntu-core-20-64:tests/main/auto-refresh-gating-from-snap

Executing:

  • openstack:arch-linux-64:tests/completion/indirect:plain
  • openstack:arch-linux-64:tests/main/desktop-file-ids
  • openstack:debian-12-64:tests/main/interface-allow-auto-connection:unset
  • openstack:debian-12-64:tests/main/cgroup-devices-v2
  • openstack:ubuntu-core-20-64:tests/core/snapd-failover
  • openstack:ubuntu-core-24-64:tests/main/dbus-activation-session
  • openstack:ubuntu-20.04-64:tests/main/degraded
  • openstack:ubuntu-24.04-64:tests/main/apparmor-prompting-smoke:home_deny_timespan

Restoring:

  • openstack:arch-linux-64:tests/main/snaps-state
  • openstack:arch-linux-64:tests/completion/indirect:plain
  • openstack:arch-linux-64:tests/completion/
  • openstack:arch-linux-64:
  • openstack:arch-linux-64:tests/main/
  • openstack:arch-linux-64:
  • openstack:arch-linux-64:tests/main/postrm-purge
  • openstack:arch-linux-64:tests/main/
  • openstack:arch-linux-64:
  • openstack:debian-12-64:tests/main/interface-allow-auto-connection:unset
  • openstack:debian-12-64:tests/main/
  • openstack:debian-12-64:

Skipped tests from snapd-testing-skip

If you wish to have any of the below tests run in your PR, in your PR description, add 'unskip:' followed by a copy-and-pasted list (without variants) of the below tests you wish to run (unskip plus test list must be valid yaml)

  • openstack:ubuntu-24.04-64:tests/main/i18n
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-flag-restart
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:audio_record_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:audio_record_timespan_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:audio_record_timespan_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_fd_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_path_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_write_same_path_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_conflict
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_defaults
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_safer
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:read_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:read_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:special_characters
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:timespan_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:timespan_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_allow_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_deny_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-prompt-restoration
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-snapd-startup
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-support
  • openstack:ubuntu-26.04-64:tests/main/i18n
  • openstack:ubuntu-26.04-64:tests/main/interfaces-requests-activates-handlers

@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.87234% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 79.19%. Comparing base (01b3b10) to head (edd726e).
⚠️ Report is 15 commits behind head on master.

Files with missing lines Patch % Lines
overlord/snapshotstate/snapshotmgr.go 96.96% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #17182      +/-   ##
==========================================
+ Coverage   79.18%   79.19%   +0.01%     
==========================================
  Files        1374     1376       +2     
  Lines      193037   193329     +292     
  Branches     2466     2466              
==========================================
+ Hits       152855   153111     +256     
- Misses      30994    31028      +34     
- Partials     9188     9190       +2     
Flag Coverage Δ
unittests 79.19% <97.87%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@Mohit-Chachada Mohit-Chachada added this to the 2.77 milestone Jun 10, 2026
Comment thread overlord/snapshotstate/export_test.go Outdated
Comment on lines +221 to +225
old := backendMapSnapDataDirToSnapVar
backendMapSnapDataDirToSnapVar = f
return func() {
backendMapSnapDataDirToSnapVar = old
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
old := backendMapSnapDataDirToSnapVar
backendMapSnapDataDirToSnapVar = f
return func() {
backendMapSnapDataDirToSnapVar = old
}
return testutil.Backup(&backendMapSnapDataDirToSnapVar, f)

@Mohit-Chachada Mohit-Chachada Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, i think you were referring to testutil.Mock.
While at it, I updated all mocks in this file to use testutil.Mock in edd726e

Comment on lines +294 to +296
for i, e := range entries {
mountPts[i] = e.MountDir
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could we exclude mount points that do not have the prefixes we care about?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

that's actually done in mapMountPointsInDataDirsToExcludes in a single loop.
I wanted to avoid doing very similar prefix matching for [ filtering ] and then for [ snap variable replacement ], so instead it is combined in a single loop.

Had also added Paths outside the snap's data directories are skipped because they are not included in the snapshot. to the method doc.

@Mohit-Chachada Mohit-Chachada requested a review from bboozzoo June 15, 2026 13:34
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