Skip to content

Commit e809955

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 <[email protected]>
1 parent bcbf566 commit e809955

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

libcontainer/factory_linux.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
185185
}
186186
}
187187

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

tests/integration/cgroups.bats

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,44 @@ function setup() {
368368
[ "$status" -eq 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)