Skip to content

Commit 642fac6

Browse files
committed
runc run: refuse a frozen cgroup
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>
1 parent 941533c commit 642fac6

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

libcontainer/factory_linux.go

+10
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
182182
}
183183
}
184184

185+
// Check that cgroup is not frozen. Do not use Exists() here
186+
// since in cgroup v1 it only checks "devices" controller.
187+
st, err := cm.GetFreezerState()
188+
if err != nil {
189+
return nil, fmt.Errorf("unable to get cgroup freezer state: %w", err)
190+
}
191+
if st == configs.Frozen {
192+
return nil, errors.New("container's cgroup unexpectedly frozen")
193+
}
194+
185195
if err := os.MkdirAll(containerRoot, 0o711); err != nil {
186196
return nil, err
187197
}

tests/integration/cgroups.bats

+41
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,44 @@ function setup() {
368368
[ "$status" -ne 0 ]
369369
[[ "$output" == *"container's cgroup is not empty"* ]]
370370
}
371+
372+
@test "runc run/create should refuse pre-existing frozen cgroup" {
373+
requires cgroups_freezer
374+
if [[ "$ROOTLESS" -ne 0 ]]; then
375+
requires rootless_cgroup
376+
fi
377+
378+
set_cgroups_path
379+
380+
case $CGROUP_UNIFIED in
381+
no)
382+
FREEZER_DIR="${CGROUP_FREEZER_BASE_PATH}/${REL_CGROUPS_PATH}"
383+
FREEZER="${FREEZER_DIR}/freezer.state"
384+
STATE="FROZEN"
385+
;;
386+
yes)
387+
FREEZER_DIR="${CGROUP_PATH}"
388+
FREEZER="${FREEZER_DIR}/cgroup.freeze"
389+
STATE="1"
390+
;;
391+
esac
392+
393+
# Create and freeze the cgroup.
394+
mkdir -p "$FREEZER_DIR"
395+
echo "$STATE" >"$FREEZER"
396+
397+
# Start a container.
398+
runc run -d --console-socket "$CONSOLE_SOCKET" ct1
399+
[ "$status" -eq 1 ]
400+
# A warning should be printed.
401+
[[ "$output" == *"container's cgroup unexpectedly frozen"* ]]
402+
403+
# Same check for runc create.
404+
runc create --console-socket "$CONSOLE_SOCKET" ct2
405+
[ "$status" -eq 1 ]
406+
# A warning should be printed.
407+
[[ "$output" == *"container's cgroup unexpectedly frozen"* ]]
408+
409+
# Cleanup.
410+
rmdir "$FREEZER_DIR"
411+
}

0 commit comments

Comments
 (0)