Merge pull request #55 from sboeuf/scsi_support

virtcontainers: kata_agent: Add virtio-scsi support
This commit is contained in:
Eric Ernst 2018-03-15 13:41:32 -07:00 committed by GitHub
commit de8506d8e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 36 deletions

View File

@ -49,7 +49,10 @@ var (
type9pFs = "9p" type9pFs = "9p"
devPath = "/dev" devPath = "/dev"
vsockSocketScheme = "vsock" vsockSocketScheme = "vsock"
kata9pDevType = "9p"
kataBlkDevType = "blk" kataBlkDevType = "blk"
kataSCSIDevType = "scsi"
sharedDir9pOptions = []string{"trans=virtio,version=9p2000.L", "nodev"}
) )
// KataAgentConfig is a structure storing information needed // KataAgentConfig is a structure storing information needed
@ -471,10 +474,11 @@ func (k *kataAgent) startPod(pod Pod) error {
// (resolv.conf, etc...) and potentially all container // (resolv.conf, etc...) and potentially all container
// rootfs will reside. // rootfs will reside.
sharedVolume := &grpc.Storage{ sharedVolume := &grpc.Storage{
Driver: kata9pDevType,
Source: mountGuest9pTag, Source: mountGuest9pTag,
MountPoint: kataGuestSharedDir, MountPoint: kataGuestSharedDir,
Fstype: type9pFs, Fstype: type9pFs,
Options: []string{"trans=virtio", "nodev"}, Options: sharedDir9pOptions,
} }
req := &grpc.CreateSandboxRequest{ req := &grpc.CreateSandboxRequest{
@ -577,6 +581,31 @@ func constraintGRPCSpec(grpcSpec *grpc.Spec) {
} }
} }
func (k *kataAgent) appendDevices(deviceList []*grpc.Device, devices []Device) []*grpc.Device {
for _, device := range devices {
d, ok := device.(*BlockDevice)
if !ok {
continue
}
kataDevice := &grpc.Device{
ContainerPath: d.DeviceInfo.ContainerPath,
}
if d.SCSIAddr == "" {
kataDevice.Type = kataBlkDevType
kataDevice.VmPath = d.VirtPath
} else {
kataDevice.Type = kataSCSIDevType
kataDevice.Id = d.SCSIAddr
}
deviceList = append(deviceList, kataDevice)
}
return deviceList
}
func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) { func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) {
ociSpecJSON, ok := c.config.Annotations[vcAnnotations.ConfigJSONKey] ociSpecJSON, ok := c.config.Annotations[vcAnnotations.ConfigJSONKey]
if !ok { if !ok {
@ -599,27 +628,30 @@ func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) {
if c.state.Fstype != "" { if c.state.Fstype != "" {
// This is a block based device rootfs. // This is a block based device rootfs.
// driveName is the predicted virtio-block guest name (the vd* in /dev/vd*).
driveName, err := getVirtDriveName(c.state.BlockIndex)
if err != nil {
return nil, err
}
virtPath := filepath.Join(devPath, driveName)
// Create a new device with empty ContainerPath so that we get // Pass a drive name only in case of virtio-blk driver.
// the device being waited for by the agent inside the VM, // If virtio-scsi driver, the agent will be able to find the
// without trying to match and update it into the OCI spec list // device based on the provided address.
// of actual devices. The device corresponding to the rootfs is if pod.config.HypervisorConfig.BlockDeviceDriver == VirtioBlock {
// a very specific case. // driveName is the predicted virtio-block guest name (the vd* in /dev/vd*).
rootfsDevice := &grpc.Device{ driveName, err := getVirtDriveName(c.state.BlockIndex)
Type: kataBlkDevType, if err != nil {
VmPath: virtPath, return nil, err
ContainerPath: "", }
virtPath := filepath.Join(devPath, driveName)
rootfs.Driver = kataBlkDevType
rootfs.Source = virtPath
} else {
scsiAddr, err := getSCSIAddress(c.state.BlockIndex)
if err != nil {
return nil, err
}
rootfs.Driver = kataSCSIDevType
rootfs.Source = scsiAddr
} }
ctrDevices = append(ctrDevices, rootfsDevice)
rootfs.Source = virtPath
rootfs.MountPoint = rootPathParent rootfs.MountPoint = rootPathParent
rootfs.Fstype = c.state.Fstype rootfs.Fstype = c.state.Fstype
@ -678,22 +710,8 @@ func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) {
// irrelevant information to the agent. // irrelevant information to the agent.
constraintGRPCSpec(grpcSpec) constraintGRPCSpec(grpcSpec)
// Append container mounts for block devices passed with --device. // Append container devices for block devices passed with --device.
for _, device := range c.devices { ctrDevices = k.appendDevices(ctrDevices, c.devices)
d, ok := device.(*BlockDevice)
if !ok {
continue
}
kataDevice := &grpc.Device{
Type: kataBlkDevType,
VmPath: d.VirtPath,
ContainerPath: d.DeviceInfo.ContainerPath,
}
ctrDevices = append(ctrDevices, kataDevice)
}
req := &grpc.CreateContainerRequest{ req := &grpc.CreateContainerRequest{
ContainerId: c.id, ContainerId: c.id,

View File

@ -33,7 +33,11 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
) )
var testKataProxyURLTempl = "unix://%s/kata-proxy-test.sock" var (
testKataProxyURLTempl = "unix://%s/kata-proxy-test.sock"
testBlockDeviceVirtPath = "testBlockDeviceVirtPath"
testBlockDeviceCtrPath = "testBlockDeviceCtrPath"
)
func proxyHandlerDiscard(c net.Conn) { func proxyHandlerDiscard(c net.Conn) {
buf := make([]byte, 1024) buf := make([]byte, 1024)
@ -336,3 +340,42 @@ func TestGenerateInterfacesAndRoutes(t *testing.T) {
"Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes) "Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes)
} }
func TestAppendDevicesEmptyContainerDeviceList(t *testing.T) {
k := kataAgent{}
devList := []*pb.Device{}
expected := []*pb.Device{}
ctrDevices := []Device{}
updatedDevList := k.appendDevices(devList, ctrDevices)
assert.True(t, reflect.DeepEqual(updatedDevList, expected),
"Device lists didn't match: got %+v, expecting %+v",
updatedDevList, expected)
}
func TestAppendDevices(t *testing.T) {
k := kataAgent{}
devList := []*pb.Device{}
expected := []*pb.Device{
{
Type: kataBlkDevType,
VmPath: testBlockDeviceVirtPath,
ContainerPath: testBlockDeviceCtrPath,
},
}
ctrDevices := []Device{
&BlockDevice{
VirtPath: testBlockDeviceVirtPath,
DeviceInfo: DeviceInfo{
ContainerPath: testBlockDeviceCtrPath,
},
},
}
updatedDevList := k.appendDevices(devList, ctrDevices)
assert.True(t, reflect.DeepEqual(updatedDevList, expected),
"Device lists didn't match: got %+v, expecting %+v",
updatedDevList, expected)
}