Skip to content

Commit c3662fa

Browse files
committed
Use MNT_DETACH for lazy unmount in cleanup and delete processes to prevent "device or resource busy" errors
1 parent bedeb49 commit c3662fa

2 files changed

Lines changed: 6 additions & 2 deletions

File tree

internal/guest/vminit/process/init.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,10 @@ func (p *Init) delete(ctx context.Context) error {
336336
}
337337
_ = p.io.Close()
338338
}
339-
if err2 := mount.UnmountRecursive(p.Rootfs, 0); err2 != nil {
339+
// Use MNT_DETACH for lazy unmount - this succeeds even if processes still hold
340+
// references to the filesystem. The actual unmount happens when all references
341+
// are released. This prevents "device or resource busy" errors during shutdown.
342+
if err2 := mount.UnmountRecursive(p.Rootfs, unix.MNT_DETACH); err2 != nil {
340343
log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")
341344
if err == nil {
342345
err = fmt.Errorf("failed rootfs umount: %w", err2)

internal/guest/vminit/system/cleanup.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ func cleanupBundles(ctx context.Context) {
6363

6464
for _, mountPath := range mounts {
6565
log.G(ctx).WithField("path", mountPath).Debug("unmounting")
66-
if err := mount.UnmountAll(mountPath, 0); err != nil {
66+
// Use MNT_DETACH for lazy unmount - succeeds even with open file handles
67+
if err := mount.UnmountAll(mountPath, unix.MNT_DETACH); err != nil {
6768
log.G(ctx).WithError(err).WithField("path", mountPath).Warn("failed to unmount")
6869
}
6970
}

0 commit comments

Comments
 (0)