diff --git a/libcontainer/cgroups/devices/systemd.go b/libcontainer/cgroups/devices/systemd.go index 19f643ec9b3..6594d9c05a9 100644 --- a/libcontainer/cgroups/devices/systemd.go +++ b/libcontainer/cgroups/devices/systemd.go @@ -128,14 +128,16 @@ func systemdProperties(r *configs.Resources) ([]systemdDbus.Property, error) { case devices.CharDevice: entry.Path = fmt.Sprintf("/dev/char/%d:%d", rule.Major, rule.Minor) } + // systemd will issue a warning if the path we give here doesn't exist. + // Since all of this logic is best-effort anyway (we manually set these + // rules separately to systemd) we can safely skip entries that don't + // have a corresponding path. + if _, err := os.Stat(entry.Path); err != nil { + logrus.Debugf("skipping device %s for systemd: %s", entry.Path, err) + continue + } } - // systemd will issue a warning if the path we give here doesn't exist. - // Since all of this logic is best-effort anyway (we manually set these - // rules separately to systemd) we can safely skip entries that don't - // have a corresponding path. - if _, err := os.Stat(entry.Path); err == nil { - deviceAllowList = append(deviceAllowList, entry) - } + deviceAllowList = append(deviceAllowList, entry) } properties = append(properties, newProp("DeviceAllow", deviceAllowList)) diff --git a/tests/integration/dev.bats b/tests/integration/dev.bats index 95675fd301f..6d972335095 100644 --- a/tests/integration/dev.bats +++ b/tests/integration/dev.bats @@ -128,3 +128,19 @@ function teardown() { runc exec test_allow_block sh -c 'fdisk -l '"$device"'' [ "$status" -eq 0 ] } + +# https://github.com/opencontainers/runc/issues/3551 +@test "runc exec vs systemctl daemon-reload" { + requires systemd root + + runc run -d --console-socket "$CONSOLE_SOCKET" test_exec + [ "$status" -eq 0 ] + + runc exec -t test_exec sh -c "ls -l /proc/self/fd/0; echo 123" + [ "$status" -eq 0 ] + + systemctl daemon-reload + + runc exec -t test_exec sh -c "ls -l /proc/self/fd/0; echo 123" + [ "$status" -eq 0 ] +}