Skip to content

internal/server/instance/drivers: Unmount residual Unix devices during cleanup - #3979

Merged
stgraber merged 1 commit into
lxc:mainfrom
fivetime:upstream/unix-mount-cleanup-20260911
Sep 14, 2026
Merged

stgraber merged 1 commit into
lxc:mainfrom
fivetime:upstream/unix-mount-cleanup-20260911

Conversation

@fivetime

@fivetime fivetime commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Failed restore cleanup can reach removeUnixDevices with device bind mounts still present. Removing their mountpoints returns EBUSY, leaving the entries behind.

Unmount them normally before removing the entries. Ignore only the expected not-mounted/already-gone errors; collect other unmount/removal errors and return them after attempting the remaining devices. An unmount failure keeps its mountpoint intact. This uses no lazy detach.

A separate private mount-namespace check exercised failed-restore cleanup, repeated cleanup, a real EPERM failure after dropping CAP_SYS_ADMIN, and a real EBUSY failure while the current directory held the bind mount busy. The busy mount and its contents remained accessible; cleanup succeeded after releasing the reference. The previous MNT_DETACH implementation failed this check by returning success for the busy mount.

Validation: the separate runtime check with the race detector, go test -v ./..., and make static-analysis. The added test file was removed from this PR following review. The runtime check injects cleanup state directly and does not claim a full CRIU migration test.

@fivetime
fivetime requested a review from stgraber as a code owner September 11, 2026 09:23
"github.com/lxc/incus/v7/shared/logger"
)

func TestRemoveUnixDevicesAfterFailedRestore(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

drop the test

err := os.Remove(devicePath)
if err != nil {
d.logger.Error("Failed removing unix device", logger.Ctx{"err": err, "path": devicePath})
err := unix.Unmount(devicePath, unix.MNT_DETACH)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should never use detach as that can then hide a mounted filesystem leading to data corruption or system crashes when we then go to the storage layer to delete it.

โ€ฆg cleanup

Signed-off-by: Simon Zhou <jp.zdm2008@gmail.com>
@fivetime
fivetime force-pushed the upstream/unix-mount-cleanup-20260911 branch from 56f03b9 to f3cff86 Compare September 14, 2026 01:57
@fivetime

Copy link
Copy Markdown
Contributor Author

Changed to a normal unmount (flags 0), retaining the mountpoint and returning the error on EBUSY or EPERM. Dropped the added test from this PR.

Verified both failures in a private mount namespace, including that cleanup succeeds after releasing the busy reference. The previous lazy-detach version incorrectly returned success for that busy mount. The full unit suite and static analysis pass.

@stgraber
stgraber merged commit dfd7cb9 into lxc:main Sep 14, 2026
90 of 92 checks passed
@fivetime
fivetime deleted the upstream/unix-mount-cleanup-20260911 branch September 17, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants