mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-02-21 22:44:27 +01:00
Currently, the block driver option is specifed by hard coding, maybe it is better to use const string variables instead of hard coded strings. Another modification is to remove duplicate consts for virtio driver in manager.go. Fixes: #3321 Signed-off-by: Jason Zhang <zhanghj.lc@inspur.com>
266 lines
7.2 KiB
Go
266 lines
7.2 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
// Copyright (c) 2018 Huawei Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package manager
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
|
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
|
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const fileMode0640 = os.FileMode(0640)
|
|
|
|
// dirMode is the permission bits used for creating a directory
|
|
const dirMode = os.FileMode(0750) | os.ModeDir
|
|
|
|
func TestNewDevice(t *testing.T) {
|
|
dm := &deviceManager{
|
|
blockDriver: config.VirtioBlock,
|
|
devices: make(map[string]api.Device),
|
|
}
|
|
savedSysDevPrefix := config.SysDevPrefix
|
|
|
|
major := int64(252)
|
|
minor := int64(3)
|
|
|
|
tmpDir, err := os.MkdirTemp("", "")
|
|
assert.Nil(t, err)
|
|
|
|
config.SysDevPrefix = tmpDir
|
|
defer func() {
|
|
os.RemoveAll(tmpDir)
|
|
config.SysDevPrefix = savedSysDevPrefix
|
|
}()
|
|
|
|
path := "/dev/vfio/2"
|
|
deviceInfo := config.DeviceInfo{
|
|
ContainerPath: "",
|
|
Major: major,
|
|
Minor: minor,
|
|
UID: 2,
|
|
GID: 2,
|
|
DevType: "c",
|
|
}
|
|
|
|
_, err = dm.NewDevice(deviceInfo)
|
|
assert.NotNil(t, err)
|
|
|
|
format := strconv.FormatInt(major, 10) + ":" + strconv.FormatInt(minor, 10)
|
|
ueventPathPrefix := filepath.Join(config.SysDevPrefix, "char", format)
|
|
ueventPath := filepath.Join(ueventPathPrefix, "uevent")
|
|
|
|
// Return true for non-existent /sys/dev path.
|
|
deviceInfo.ContainerPath = path
|
|
_, err = dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
|
|
err = os.MkdirAll(ueventPathPrefix, dirMode)
|
|
assert.Nil(t, err)
|
|
|
|
// Should return error for bad data in uevent file
|
|
content := []byte("nonkeyvaluedata")
|
|
err = os.WriteFile(ueventPath, content, fileMode0640)
|
|
assert.Nil(t, err)
|
|
|
|
_, err = dm.NewDevice(deviceInfo)
|
|
assert.NotNil(t, err)
|
|
|
|
content = []byte("MAJOR=252\nMINOR=3\nDEVNAME=vfio/2")
|
|
err = os.WriteFile(ueventPath, content, fileMode0640)
|
|
assert.Nil(t, err)
|
|
|
|
device, err := dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
|
|
vfioDev, ok := device.(*drivers.VFIODevice)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, vfioDev.DeviceInfo.HostPath, path)
|
|
assert.Equal(t, vfioDev.DeviceInfo.ContainerPath, path)
|
|
assert.Equal(t, vfioDev.DeviceInfo.DevType, "c")
|
|
assert.Equal(t, vfioDev.DeviceInfo.Major, major)
|
|
assert.Equal(t, vfioDev.DeviceInfo.Minor, minor)
|
|
assert.Equal(t, vfioDev.DeviceInfo.UID, uint32(2))
|
|
assert.Equal(t, vfioDev.DeviceInfo.GID, uint32(2))
|
|
}
|
|
|
|
func TestAttachVFIODevice(t *testing.T) {
|
|
dm := &deviceManager{
|
|
blockDriver: config.VirtioBlock,
|
|
devices: make(map[string]api.Device),
|
|
}
|
|
tmpDir, err := os.MkdirTemp("", "")
|
|
assert.Nil(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
testFDIOGroup := "2"
|
|
testDeviceBDFPath := "0000:00:1c.0"
|
|
|
|
devicesDir := filepath.Join(tmpDir, testFDIOGroup, "devices")
|
|
err = os.MkdirAll(devicesDir, dirMode)
|
|
assert.Nil(t, err)
|
|
|
|
deviceBDFDir := filepath.Join(devicesDir, testDeviceBDFPath)
|
|
err = os.MkdirAll(deviceBDFDir, dirMode)
|
|
assert.Nil(t, err)
|
|
|
|
deviceClassFile := filepath.Join(deviceBDFDir, "class")
|
|
_, err = os.Create(deviceClassFile)
|
|
assert.Nil(t, err)
|
|
|
|
deviceConfigFile := filepath.Join(deviceBDFDir, "config")
|
|
_, err = os.Create(deviceConfigFile)
|
|
assert.Nil(t, err)
|
|
|
|
savedIOMMUPath := config.SysIOMMUPath
|
|
config.SysIOMMUPath = tmpDir
|
|
|
|
savedSysBusPciDevicesPath := config.SysBusPciDevicesPath
|
|
config.SysBusPciDevicesPath = devicesDir
|
|
|
|
defer func() {
|
|
config.SysIOMMUPath = savedIOMMUPath
|
|
config.SysBusPciDevicesPath = savedSysBusPciDevicesPath
|
|
}()
|
|
|
|
path := filepath.Join(vfioPath, testFDIOGroup)
|
|
deviceInfo := config.DeviceInfo{
|
|
HostPath: path,
|
|
ContainerPath: path,
|
|
DevType: "c",
|
|
}
|
|
|
|
device, err := dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
_, ok := device.(*drivers.VFIODevice)
|
|
assert.True(t, ok)
|
|
|
|
devReceiver := &api.MockDeviceReceiver{}
|
|
err = device.Attach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
|
|
err = device.Detach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
}
|
|
|
|
func TestAttachGenericDevice(t *testing.T) {
|
|
dm := &deviceManager{
|
|
blockDriver: config.VirtioBlock,
|
|
devices: make(map[string]api.Device),
|
|
}
|
|
path := "/dev/tty2"
|
|
deviceInfo := config.DeviceInfo{
|
|
HostPath: path,
|
|
ContainerPath: path,
|
|
DevType: "c",
|
|
}
|
|
|
|
device, err := dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
_, ok := device.(*drivers.GenericDevice)
|
|
assert.True(t, ok)
|
|
|
|
devReceiver := &api.MockDeviceReceiver{}
|
|
err = device.Attach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
|
|
err = device.Detach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
}
|
|
|
|
func TestAttachBlockDevice(t *testing.T) {
|
|
dm := &deviceManager{
|
|
blockDriver: config.VirtioBlock,
|
|
devices: make(map[string]api.Device),
|
|
}
|
|
path := "/dev/hda"
|
|
deviceInfo := config.DeviceInfo{
|
|
HostPath: path,
|
|
ContainerPath: path,
|
|
DevType: "b",
|
|
}
|
|
|
|
devReceiver := &api.MockDeviceReceiver{}
|
|
device, err := dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
_, ok := device.(*drivers.BlockDevice)
|
|
assert.True(t, ok)
|
|
|
|
err = device.Attach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
|
|
err = device.Detach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
|
|
// test virtio SCSI driver
|
|
dm.blockDriver = config.VirtioSCSI
|
|
device, err = dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
err = device.Attach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
|
|
err = device.Detach(context.Background(), devReceiver)
|
|
assert.Nil(t, err)
|
|
}
|
|
|
|
func TestAttachDetachDevice(t *testing.T) {
|
|
dm := NewDeviceManager(config.VirtioSCSI, false, "", nil)
|
|
|
|
path := "/dev/hda"
|
|
deviceInfo := config.DeviceInfo{
|
|
HostPath: path,
|
|
ContainerPath: path,
|
|
DevType: "b",
|
|
}
|
|
|
|
devReceiver := &api.MockDeviceReceiver{}
|
|
device, err := dm.NewDevice(deviceInfo)
|
|
assert.Nil(t, err)
|
|
|
|
// attach non-exist device
|
|
err = dm.AttachDevice(context.Background(), "non-exist", devReceiver)
|
|
assert.NotNil(t, err)
|
|
|
|
// attach device
|
|
err = dm.AttachDevice(context.Background(), device.DeviceID(), devReceiver)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, device.GetAttachCount(), uint(1), "attach device count should be 1")
|
|
// attach device again(twice)
|
|
err = dm.AttachDevice(context.Background(), device.DeviceID(), devReceiver)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, device.GetAttachCount(), uint(2), "attach device count should be 2")
|
|
|
|
attached := dm.IsDeviceAttached(device.DeviceID())
|
|
assert.True(t, attached)
|
|
|
|
// detach device
|
|
err = dm.DetachDevice(context.Background(), device.DeviceID(), devReceiver)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, device.GetAttachCount(), uint(1), "attach device count should be 1")
|
|
// detach device again(twice)
|
|
err = dm.DetachDevice(context.Background(), device.DeviceID(), devReceiver)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, device.GetAttachCount(), uint(0), "attach device count should be 0")
|
|
// detach device again should report error
|
|
err = dm.DetachDevice(context.Background(), device.DeviceID(), devReceiver)
|
|
assert.NotNil(t, err)
|
|
assert.Equal(t, err, ErrDeviceNotAttached, "")
|
|
assert.Equal(t, device.GetAttachCount(), uint(0), "attach device count should be 0")
|
|
|
|
attached = dm.IsDeviceAttached(device.DeviceID())
|
|
assert.False(t, attached)
|
|
|
|
err = dm.RemoveDevice(device.DeviceID())
|
|
assert.Nil(t, err)
|
|
}
|