diff --git a/oci/utils_unix.go b/oci/utils_unix.go index f358a2089..874cc941a 100644 --- a/oci/utils_unix.go +++ b/oci/utils_unix.go @@ -91,6 +91,9 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { } return nil, err } + if device.Type == fifoDevice { + continue + } if containerPath != "" { device.Path = filepath.Join(containerPath, filepath.Base(f.Name())) } @@ -99,6 +102,14 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { return out, nil } +// TODO consider adding these consts to the OCI runtime-spec. +const ( + wildcardDevice = "a" //nolint // currently unused, but should be included when upstreaming to OCI runtime-spec. + blockDevice = "b" + charDevice = "c" // or "u" + fifoDevice = "p" +) + func deviceFromPath(path string) (*specs.LinuxDevice, error) { var stat unix.Stat_t if err := unix.Lstat(path, &stat); err != nil { @@ -110,19 +121,21 @@ func deviceFromPath(path string) (*specs.LinuxDevice, error) { major = unix.Major(devNumber) minor = unix.Minor(devNumber) ) - if major == 0 { - return nil, errNotADevice - } var ( devType string mode = stat.Mode ) - switch { - case mode&unix.S_IFBLK == unix.S_IFBLK: - devType = "b" - case mode&unix.S_IFCHR == unix.S_IFCHR: - devType = "c" + + switch mode & unix.S_IFMT { + case unix.S_IFBLK: + devType = blockDevice + case unix.S_IFCHR: + devType = charDevice + case unix.S_IFIFO: + devType = fifoDevice + default: + return nil, errNotADevice } fm := os.FileMode(mode &^ unix.S_IFMT) return &specs.LinuxDevice{ diff --git a/oci/utils_unix_test.go b/oci/utils_unix_test.go new file mode 100644 index 000000000..7ec324562 --- /dev/null +++ b/oci/utils_unix_test.go @@ -0,0 +1,44 @@ +//go:build !windows && !darwin +// +build !windows,!darwin + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package oci + +import "testing" + +func TestHostDevicesAllValid(t *testing.T) { + devices, err := HostDevices() + if err != nil { + t.Fatalf("failed to get host devices: %v", err) + } + + for _, device := range devices { + // Devices can't have major number 0. + if device.Major == 0 { + t.Errorf("device entry %+v has zero major number", device) + } + switch device.Type { + case blockDevice, charDevice: + case fifoDevice: + t.Logf("fifo devices shouldn't show up from HostDevices") + fallthrough + default: + t.Errorf("device entry %+v has unexpected type %v", device, device.Type) + } + } +}