X Tutup
Skip to content

Commit 9bc8d63

Browse files
committed
cri/server: use containerd/oci instead of libcontainer/devices
Looks like we had our own copy of the "getDevices" code already, so use that code (which also matches the code that's used to _generate_ the spec, so a better match). Moving the code to a separate file, I also noticed that the _unix and _linux code was _exactly_ the same (baring some `//nolint:` comments), so also removing the duplicated code. With this patch applied, we removed the dependency on the libcontainer/devices package (leaving only libcontainer/user). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent ceb0875 commit 9bc8d63

File tree

9 files changed

+142
-528
lines changed

9 files changed

+142
-528
lines changed

oci/spec_opts_linux.go

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,24 @@ package oci
2020

2121
import (
2222
"context"
23-
"io/ioutil"
24-
"os"
25-
"path/filepath"
2623

2724
"github.com/containerd/containerd/containers"
2825
"github.com/containerd/containerd/pkg/cap"
2926
specs "github.com/opencontainers/runtime-spec/specs-go"
30-
"github.com/pkg/errors"
31-
"golang.org/x/sys/unix"
3227
)
3328

3429
// WithHostDevices adds all the hosts device nodes to the container's spec
3530
func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
3631
setLinux(s)
3732

38-
devs, err := getDevices("/dev", "")
33+
devs, err := HostDevices()
3934
if err != nil {
4035
return err
4136
}
4237
s.Linux.Devices = append(s.Linux.Devices, devs...)
4338
return nil
4439
}
4540

46-
var errNotADevice = errors.New("not a device node")
47-
4841
// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
4942
// If devicePath is a dir it traverses the dir to add all devices in that dir.
5043
// If devicePath is not a dir, it attempts to add the single device.
@@ -69,108 +62,6 @@ func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
6962
}
7063
}
7164

72-
func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) {
73-
stat, err := os.Stat(path)
74-
if err != nil {
75-
return nil, errors.Wrap(err, "error stating device path")
76-
}
77-
78-
if !stat.IsDir() {
79-
dev, err := deviceFromPath(path)
80-
if err != nil {
81-
return nil, err
82-
}
83-
if containerPath != "" {
84-
dev.Path = containerPath
85-
}
86-
return []specs.LinuxDevice{*dev}, nil
87-
}
88-
89-
files, err := ioutil.ReadDir(path)
90-
if err != nil {
91-
return nil, err
92-
}
93-
var out []specs.LinuxDevice
94-
for _, f := range files {
95-
switch {
96-
case f.IsDir():
97-
switch f.Name() {
98-
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
99-
// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
100-
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
101-
continue
102-
default:
103-
var cp string
104-
if containerPath != "" {
105-
cp = filepath.Join(containerPath, filepath.Base(f.Name()))
106-
}
107-
sub, err := getDevices(filepath.Join(path, f.Name()), cp)
108-
if err != nil {
109-
return nil, err
110-
}
111-
112-
out = append(out, sub...)
113-
continue
114-
}
115-
case f.Name() == "console":
116-
continue
117-
}
118-
device, err := deviceFromPath(filepath.Join(path, f.Name()))
119-
if err != nil {
120-
if err == errNotADevice {
121-
continue
122-
}
123-
if os.IsNotExist(err) {
124-
continue
125-
}
126-
return nil, err
127-
}
128-
if containerPath != "" {
129-
device.Path = filepath.Join(containerPath, filepath.Base(f.Name()))
130-
}
131-
out = append(out, *device)
132-
}
133-
return out, nil
134-
}
135-
136-
func deviceFromPath(path string) (*specs.LinuxDevice, error) {
137-
var stat unix.Stat_t
138-
if err := unix.Lstat(path, &stat); err != nil {
139-
return nil, err
140-
}
141-
142-
var (
143-
// The type is 32bit on mips.
144-
devNumber = uint64(stat.Rdev) // nolint: unconvert
145-
major = unix.Major(devNumber)
146-
minor = unix.Minor(devNumber)
147-
)
148-
if major == 0 {
149-
return nil, errNotADevice
150-
}
151-
152-
var (
153-
devType string
154-
mode = stat.Mode
155-
)
156-
switch {
157-
case mode&unix.S_IFBLK == unix.S_IFBLK:
158-
devType = "b"
159-
case mode&unix.S_IFCHR == unix.S_IFCHR:
160-
devType = "c"
161-
}
162-
fm := os.FileMode(mode &^ unix.S_IFMT)
163-
return &specs.LinuxDevice{
164-
Type: devType,
165-
Path: path,
166-
Major: int64(major),
167-
Minor: int64(minor),
168-
FileMode: &fm,
169-
UID: &stat.Uid,
170-
GID: &stat.Gid,
171-
}, nil
172-
}
173-
17465
// WithMemorySwap sets the container's swap in bytes
17566
func WithMemorySwap(swap int64) SpecOpts {
17667
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {

oci/spec_opts_unix.go

Lines changed: 2 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,25 @@ package oci
2020

2121
import (
2222
"context"
23-
"io/ioutil"
24-
"os"
25-
"path/filepath"
2623

2724
"github.com/containerd/containerd/containers"
28-
specs "github.com/opencontainers/runtime-spec/specs-go"
29-
"github.com/pkg/errors"
30-
"golang.org/x/sys/unix"
3125
)
3226

3327
// WithHostDevices adds all the hosts device nodes to the container's spec
3428
func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
3529
setLinux(s)
3630

37-
devs, err := getDevices("/dev", "")
31+
devs, err := HostDevices()
3832
if err != nil {
3933
return err
4034
}
4135
s.Linux.Devices = append(s.Linux.Devices, devs...)
4236
return nil
4337
}
4438

45-
var errNotADevice = errors.New("not a device node")
46-
4739
// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device.
4840
// If devicePath is a dir it traverses the dir to add all devices in that dir.
49-
// If devicePath is not a dir, it attempts to add the signle device.
41+
// If devicePath is not a dir, it attempts to add the single device.
5042
func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
5143
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
5244
devs, err := getDevices(devicePath, containerPath)
@@ -58,107 +50,6 @@ func WithDevices(devicePath, containerPath, permissions string) SpecOpts {
5850
}
5951
}
6052

61-
func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) {
62-
stat, err := os.Stat(path)
63-
if err != nil {
64-
return nil, errors.Wrap(err, "error stating device path")
65-
}
66-
67-
if !stat.IsDir() {
68-
dev, err := deviceFromPath(path)
69-
if err != nil {
70-
return nil, err
71-
}
72-
if containerPath != "" {
73-
dev.Path = containerPath
74-
}
75-
return []specs.LinuxDevice{*dev}, nil
76-
}
77-
78-
files, err := ioutil.ReadDir(path)
79-
if err != nil {
80-
return nil, err
81-
}
82-
var out []specs.LinuxDevice
83-
for _, f := range files {
84-
switch {
85-
case f.IsDir():
86-
switch f.Name() {
87-
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
88-
// ".udev" added to address https://github.com/opencontainers/runc/issues/2093
89-
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev":
90-
continue
91-
default:
92-
var cp string
93-
if containerPath != "" {
94-
cp = filepath.Join(containerPath, filepath.Base(f.Name()))
95-
}
96-
sub, err := getDevices(filepath.Join(path, f.Name()), cp)
97-
if err != nil {
98-
return nil, err
99-
}
100-
101-
out = append(out, sub...)
102-
continue
103-
}
104-
case f.Name() == "console":
105-
continue
106-
}
107-
device, err := deviceFromPath(filepath.Join(path, f.Name()))
108-
if err != nil {
109-
if err == errNotADevice {
110-
continue
111-
}
112-
if os.IsNotExist(err) {
113-
continue
114-
}
115-
return nil, err
116-
}
117-
if containerPath != "" {
118-
device.Path = filepath.Join(containerPath, filepath.Base(f.Name()))
119-
}
120-
out = append(out, *device)
121-
}
122-
return out, nil
123-
}
124-
125-
func deviceFromPath(path string) (*specs.LinuxDevice, error) {
126-
var stat unix.Stat_t
127-
if err := unix.Lstat(path, &stat); err != nil {
128-
return nil, err
129-
}
130-
131-
var (
132-
devNumber = uint64(stat.Rdev)
133-
major = unix.Major(devNumber)
134-
minor = unix.Minor(devNumber)
135-
)
136-
if major == 0 {
137-
return nil, errNotADevice
138-
}
139-
140-
var (
141-
devType string
142-
mode = stat.Mode
143-
)
144-
switch {
145-
case mode&unix.S_IFBLK == unix.S_IFBLK:
146-
devType = "b"
147-
case mode&unix.S_IFCHR == unix.S_IFCHR:
148-
devType = "c"
149-
}
150-
fm := os.FileMode(mode &^ unix.S_IFMT)
151-
return &specs.LinuxDevice{
152-
Type: devType,
153-
Path: path,
154-
Major: int64(major),
155-
Minor: int64(minor),
156-
FileMode: &fm,
157-
UID: &stat.Uid,
158-
GID: &stat.Gid,
159-
}, nil
160-
}
161-
16253
// WithCPUCFS sets the container's Completely fair scheduling (CFS) quota and period
16354
func WithCPUCFS(quota int64, period uint64) SpecOpts {
16455
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error {

0 commit comments

Comments
 (0)
X Tutup