diff --git a/libcontainer/cgroups/devices/systemd.go b/libcontainer/cgroups/devices/systemd.go index b78d90eaf..70768f9db 100644 --- a/libcontainer/cgroups/devices/systemd.go +++ b/libcontainer/cgroups/devices/systemd.go @@ -2,9 +2,9 @@ package devices import ( "bufio" - "errors" "fmt" "os" + "strconv" "strings" systemdDbus "github.com/coreos/go-systemd/v22/dbus" @@ -181,6 +181,7 @@ func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) { if err != nil { return "", err } + ruleMajorStr := strconv.FormatInt(ruleMajor, 10) + " " scanner := bufio.NewScanner(fh) var currentType devices.Type @@ -205,20 +206,9 @@ func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) { continue } - // Parse out the (major, name). - var ( - currMajor int64 - currName string - ) - if n, err := fmt.Sscanf(line, "%d %s", &currMajor, &currName); err != nil || n != 2 { - if err == nil { - err = errors.New("wrong number of fields") - } - return "", fmt.Errorf("scan /proc/devices line %q: %w", line, err) - } - - if currMajor == ruleMajor { - return prefix + currName, nil + group := strings.TrimPrefix(line, ruleMajorStr) + if len(group) < len(line) { // got it + return prefix + group, nil } } if err := scanner.Err(); err != nil { diff --git a/libcontainer/cgroups/devices/systemd_test.go b/libcontainer/cgroups/devices/systemd_test.go index 050fdd2d2..b6e81dcd8 100644 --- a/libcontainer/cgroups/devices/systemd_test.go +++ b/libcontainer/cgroups/devices/systemd_test.go @@ -2,6 +2,7 @@ package devices import ( "bytes" + "fmt" "os" "os/exec" "strings" @@ -240,6 +241,32 @@ func TestSkipDevicesFalse(t *testing.T) { }) } +func testFindDeviceGroup() error { + const ( + major = 136 + group = "char-pts" + ) + res, err := findDeviceGroup(devices.CharDevice, major) + if res != group || err != nil { + return fmt.Errorf("expected %v, nil, got %v, %w", group, res, err) + } + return nil +} + +func TestFindDeviceGroup(t *testing.T) { + if err := testFindDeviceGroup(); err != nil { + t.Fatal(err) + } +} + +func BenchmarkFindDeviceGroup(b *testing.B) { + for i := 0; i < b.N; i++ { + if err := testFindDeviceGroup(); err != nil { + b.Fatal(err) + } + } +} + func newManager(t *testing.T, config *configs.Cgroup) (m cgroups.Manager) { t.Helper() var err error