mirror of
https://github.com/opencontainers/runc.git
synced 2025-12-24 11:50:58 +08:00
runc exec: reject paused container unless --ignore-paused
Currently, if a container is paused (i.e. its cgroup is frozen), runc exec just hangs, and it is not obvious why. Refuse to exec in a paused container. Add a test case. In case runc exec in a paused container is a legit use case, add --ignore-paused option to override the check. Document it, add a test case. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -173,6 +173,7 @@ _runc_exec() {
|
||||
--apparmor
|
||||
--cap, -c
|
||||
--preserve-fds
|
||||
--ignore-paused
|
||||
"
|
||||
|
||||
local all_options="$options_with_args $boolean_options"
|
||||
|
||||
9
exec.go
9
exec.go
@@ -91,6 +91,10 @@ following will output a list of processes running in the container:
|
||||
Name: "cgroup",
|
||||
Usage: "run the process in an (existing) sub-cgroup(s). Format is [<controller>:]<cgroup>.",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ignore-paused",
|
||||
Usage: "allow exec in a paused container",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
if err := checkArgs(context, 1, minArgs); err != nil {
|
||||
@@ -145,7 +149,10 @@ func execProcess(context *cli.Context) (int, error) {
|
||||
return -1, err
|
||||
}
|
||||
if status == libcontainer.Stopped {
|
||||
return -1, errors.New("cannot exec a container that has stopped")
|
||||
return -1, errors.New("cannot exec in a stopped container")
|
||||
}
|
||||
if status == libcontainer.Paused && !context.Bool("ignore-paused") {
|
||||
return -1, errors.New("cannot exec in a paused container (use --ignore-paused to override)")
|
||||
}
|
||||
path := context.String("process")
|
||||
if path == "" && len(context.Args()) == 1 {
|
||||
|
||||
@@ -59,6 +59,11 @@ multiple times.
|
||||
: Pass _N_ additional file descriptors to the container (**stdio** +
|
||||
**$LISTEN_FDS** + _N_ in total). Default is **0**.
|
||||
|
||||
**--ignore-paused**
|
||||
: Allow exec in a paused container. By default, if a container is paused,
|
||||
**runc exec** errors out; this option can be used to override it.
|
||||
A paused container needs to be resumed for the exec to complete.
|
||||
|
||||
**--cgroup** _path_ | _controller_[,_controller_...]:_path_
|
||||
: Execute a process in a sub-cgroup. If the specified cgroup does not exist, an
|
||||
error is returned. Default is empty path, which means to use container's top
|
||||
|
||||
@@ -303,3 +303,47 @@ function setup() {
|
||||
# check that the cgroups v2 path is the same for both processes
|
||||
[[ "$run_cgroup" == "$exec_cgroup" ]]
|
||||
}
|
||||
|
||||
@test "runc exec should refuse a paused container" {
|
||||
if [[ "$ROOTLESS" -ne 0 ]]; then
|
||||
requires rootless_cgroup
|
||||
fi
|
||||
requires cgroups_freezer
|
||||
|
||||
set_cgroups_path
|
||||
|
||||
runc run -d --console-socket "$CONSOLE_SOCKET" ct1
|
||||
[ "$status" -eq 0 ]
|
||||
runc pause ct1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Exec should not timeout or succeed.
|
||||
runc exec ct1 echo ok
|
||||
[ "$status" -eq 255 ]
|
||||
[[ "$output" == *"cannot exec in a paused container"* ]]
|
||||
}
|
||||
|
||||
@test "runc exec --ignore-paused" {
|
||||
if [[ "$ROOTLESS" -ne 0 ]]; then
|
||||
requires rootless_cgroup
|
||||
fi
|
||||
requires cgroups_freezer
|
||||
|
||||
set_cgroups_path
|
||||
|
||||
runc run -d --console-socket "$CONSOLE_SOCKET" ct1
|
||||
[ "$status" -eq 0 ]
|
||||
runc pause ct1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Resume the container a bit later.
|
||||
(
|
||||
sleep 2
|
||||
runc resume ct1
|
||||
) &
|
||||
|
||||
# Exec should not timeout or succeed.
|
||||
runc exec --ignore-paused ct1 echo ok
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" = "ok" ]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user