Skip to content

Commit

Permalink
runc run: refuse a frozen cgroup
Browse files Browse the repository at this point in the history
Sometimes a container cgroup already exists but is frozen.
When this happens, runc init hangs, and it's not clear what is going on.

Refuse to run in a frozen cgroup; add a test case.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
kolyshkin committed Aug 19, 2021
1 parent 839a605 commit e3d0a62
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
11 changes: 11 additions & 0 deletions libcontainer/factory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package libcontainer

import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -182,6 +183,16 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
}
}

// Check that cgroup is not frozen. Do it even if Exists() above returned
// false, since in cgroup v1 it only checks "devices" controller.
st, err := cm.GetFreezerState()
if err != nil {
return nil, fmt.Errorf("unable to get cgroup freezer state: %w", err)
}
if st == configs.Frozen {
return nil, errors.New("container's cgroup unexpectedly frozen")
}

if err := os.MkdirAll(containerRoot, 0o711); err != nil {
return nil, err
}
Expand Down
41 changes: 41 additions & 0 deletions tests/integration/cgroups.bats
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,44 @@ function setup() {
[ "$status" -ne 0 ]
[[ "$output" == *"container's cgroup is not empty"* ]]
}

@test "runc run/create should refule pre-existing frozen cgroup" {
requires cgroups_freezer
if [[ "$ROOTLESS" -ne 0 ]]; then
requires rootless_cgroup
fi

set_cgroups_path

case $CGROUP_UNIFIED in
no)
FREEZER_DIR="${CGROUP_FREEZER_BASE_PATH}/${REL_CGROUPS_PATH}"
FREEZER="${FREEZER_DIR}/freezer.state"
STATE="FROZEN"
;;
yes)
FREEZER_DIR="${CGROUP_PATH}"
FREEZER="${FREEZER_DIR}/cgroup.freeze"
STATE="1"
;;
esac

# Create and freeze the cgroup.
mkdir "$FREEZER_DIR"
echo "$STATE" >"$FREEZER"

# Start a container.
runc run -d --console-socket "$CONSOLE_SOCKET" ct1
[ "$status" -eq 1 ]
# A warning should be printed.
[[ "$output" == *"container's cgroup unexpectedly frozen"* ]]

# Same check for runc create.
runc create --console-socket "$CONSOLE_SOCKET" ct2
[ "$status" -eq 1 ]
# A warning should be printed.
[[ "$output" == *"container's cgroup unexpectedly frozen"* ]]

# Cleanup.
rmdir "$FREEZER_DIR"
}

0 comments on commit e3d0a62

Please sign in to comment.