Skip to content

Commit

Permalink
linux: cgroups: cleanup unused mount if move failed
Browse files Browse the repository at this point in the history
When running a container with /sys/fs/cgroup already mounted
(e.g. --volume=/sys:/sys) and another shared volume somewhere
(e.g. --volume=/mnt:/mnt:shared), the move mount fails with EINVAL:
```
mount("/run/crun/6d75ef05e540486f21ef54743f8af97f4dff0d0d7c54d9b7852cd5302e884db8/tmpmount", "/proc/self/fd/8", NULL, MS_MOVE, NULL) = -1 EINVAL (Invalid argument)
```

This leaves tmpmount as a mountpoint behind, which then fails to
cleanup:
```
openat(AT_FDCWD, "/run/crun", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 3
openat(3, "0d1342f7a7375593813287c743170bb71f30f9a64fa8bc141d3cf9b8e9aa5a89", O_RDONLY|O_DIRECTORY) = 4
unlinkat(4, "tmpmount", 0) = -1 EISDIR (Is a directory)
unlinkat(4, "tmpmount", AT_REMOVEDIR) = -1 EBUSY (Device or resource busy)
close(4)                   = 0
unlinkat(3, "0d1342f7a7375593813287c743170bb71f30f9a64fa8bc141d3cf9b8e9aa5a89", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)
```

This in turn ultimately fails libcrun_container_delete_status() and
friends, leading to the non-execution of post hooks in this reproducer:

```
$ mkdir hooks.d
$ cat > hooks.d/hook.json <<'EOF'
{
  "version": "1.0.0",
  "when": {"always": true},
  "hook": {
    "path": "/bin/sh",
    "args": ["/bin/sh", "-c", "date >> /tmp/hookme"]
  },
  "stages": ["poststop"]
}
EOF
$ podman --runtime=path/crun run  \
    --net=none --name test -d --replace --hooks-dir=$PWD/hooks.d \
    --volume=/sys:/sys --volume=/mnt:/mnt:shared \
    docker.io/alpine true
```

(the hook is eventually run on podman rm, but not by crun immediately on
container stop)

Just cleaning up the mount point makes the problem go away.

Fixes: 523eed3 ("linux: add new fallback when mount fails with EBUSY")
Signed-off-by: Dominique Martinet <[email protected]>
  • Loading branch information
martinetd committed Apr 27, 2024
1 parent 6df8cef commit 0f9984a
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,9 +1353,12 @@ do_mount_cgroup_v2 (libcrun_container_t *container, int targetfd, const char *ta
if (LIKELY (ret == 0))
return 0;

/* Best-effort cleanup of now-unused temporary mount */
umount2 (tmp_mount_dir, MNT_DETACH);
crun_error_release (err);
}
}
rmdir (tmp_mount_dir);
}

ret = do_mount (container, "tmpfs", targetfd, target, "tmpfs", MS_PRIVATE, "nr_blocks=1,nr_inodes=1", LABEL_NONE, err);
Expand Down

0 comments on commit 0f9984a

Please sign in to comment.