mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-24 10:41:43 +00:00
pkg/cgroups: implement functions to get information from a host device
Add functions to convert a host device to a cgroup device or linux device, the first one is used to update the device cgroup and the second one to update the resources in the OCI spec. Signed-off-by: Julio Montes <julio.montes@intel.com> Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
parent
387d3d34dc
commit
045c7ae9a3
@ -7,8 +7,13 @@ package cgroups
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// prepend a kata specific string to oci cgroup path to
|
// prepend a kata specific string to oci cgroup path to
|
||||||
@ -63,3 +68,53 @@ func IsSystemdCgroup(cgroupPath string) bool {
|
|||||||
// it's a correct systemd cgroup path.
|
// it's a correct systemd cgroup path.
|
||||||
return found != nil && cgroupPath[found[0]:found[1]] == cgroupPath
|
return found != nil && cgroupPath[found[0]:found[1]] == cgroupPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeviceToCgroupDevice(device string) (*configs.Device, error) {
|
||||||
|
var st unix.Stat_t
|
||||||
|
linuxDevice := configs.Device{
|
||||||
|
Allow: true,
|
||||||
|
Permissions: "rwm",
|
||||||
|
Path: device,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := unix.Stat(device, &st); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
devType := st.Mode & unix.S_IFMT
|
||||||
|
|
||||||
|
switch devType {
|
||||||
|
case unix.S_IFCHR:
|
||||||
|
linuxDevice.Type = 'c'
|
||||||
|
case unix.S_IFBLK:
|
||||||
|
linuxDevice.Type = 'b'
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported device type: %v", devType)
|
||||||
|
}
|
||||||
|
|
||||||
|
major := int64(unix.Major(st.Rdev))
|
||||||
|
minor := int64(unix.Minor(st.Rdev))
|
||||||
|
linuxDevice.Major = major
|
||||||
|
linuxDevice.Minor = minor
|
||||||
|
|
||||||
|
linuxDevice.Gid = st.Gid
|
||||||
|
linuxDevice.Uid = st.Uid
|
||||||
|
linuxDevice.FileMode = os.FileMode(st.Mode)
|
||||||
|
|
||||||
|
return &linuxDevice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeviceToLinuxDevice(device string) (specs.LinuxDeviceCgroup, error) {
|
||||||
|
dev, err := DeviceToCgroupDevice(device)
|
||||||
|
if err != nil {
|
||||||
|
return specs.LinuxDeviceCgroup{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return specs.LinuxDeviceCgroup{
|
||||||
|
Allow: dev.Allow,
|
||||||
|
Type: string(dev.Type),
|
||||||
|
Major: &dev.Major,
|
||||||
|
Minor: &dev.Minor,
|
||||||
|
Access: dev.Permissions,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
package cgroups
|
package cgroups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -102,3 +104,60 @@ func TestValidCgroupPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeviceToCgroupDevice(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
f, err := ioutil.TempFile("", "device")
|
||||||
|
assert.NoError(err)
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
// fail: regular file to device
|
||||||
|
dev, err := DeviceToCgroupDevice(f.Name())
|
||||||
|
assert.Error(err)
|
||||||
|
assert.Nil(dev)
|
||||||
|
|
||||||
|
// fail: no such file
|
||||||
|
os.Remove(f.Name())
|
||||||
|
dev, err = DeviceToCgroupDevice(f.Name())
|
||||||
|
assert.Error(err)
|
||||||
|
assert.Nil(dev)
|
||||||
|
|
||||||
|
devPath := "/dev/null"
|
||||||
|
if _, err := os.Stat(devPath); os.IsNotExist(err) {
|
||||||
|
t.Skipf("no such device: %v", devPath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dev, err = DeviceToCgroupDevice(devPath)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(dev)
|
||||||
|
assert.Equal(dev.Type, 'c')
|
||||||
|
assert.Equal(dev.Path, devPath)
|
||||||
|
assert.NotZero(dev.Major)
|
||||||
|
assert.NotZero(dev.Minor)
|
||||||
|
assert.NotEmpty(dev.Permissions)
|
||||||
|
assert.NotZero(dev.FileMode)
|
||||||
|
assert.Zero(dev.Uid)
|
||||||
|
assert.Zero(dev.Gid)
|
||||||
|
assert.True(dev.Allow)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeviceToLinuxDevice(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
devPath := "/dev/null"
|
||||||
|
if _, err := os.Stat(devPath); os.IsNotExist(err) {
|
||||||
|
t.Skipf("no such device: %v", devPath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dev, err := DeviceToLinuxDevice(devPath)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(dev)
|
||||||
|
assert.Equal(dev.Type, "c")
|
||||||
|
assert.NotNil(dev.Major)
|
||||||
|
assert.NotZero(*dev.Major)
|
||||||
|
assert.NotNil(dev.Minor)
|
||||||
|
assert.NotZero(*dev.Minor)
|
||||||
|
assert.NotEmpty(dev.Access)
|
||||||
|
assert.True(dev.Allow)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user