diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index be12106fd..6a8f593d6 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -49,7 +49,10 @@ var ( type9pFs = "9p" devPath = "/dev" vsockSocketScheme = "vsock" + kata9pDevType = "9p" kataBlkDevType = "blk" + kataSCSIDevType = "scsi" + sharedDir9pOptions = []string{"trans=virtio,version=9p2000.L", "nodev"} ) // 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 // rootfs will reside. sharedVolume := &grpc.Storage{ + Driver: kata9pDevType, Source: mountGuest9pTag, MountPoint: kataGuestSharedDir, Fstype: type9pFs, - Options: []string{"trans=virtio", "nodev"}, + Options: sharedDir9pOptions, } 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) { ociSpecJSON, ok := c.config.Annotations[vcAnnotations.ConfigJSONKey] if !ok { @@ -599,27 +628,30 @@ func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) { if c.state.Fstype != "" { // 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 - // the device being waited for by the agent inside the VM, - // without trying to match and update it into the OCI spec list - // of actual devices. The device corresponding to the rootfs is - // a very specific case. - rootfsDevice := &grpc.Device{ - Type: kataBlkDevType, - VmPath: virtPath, - ContainerPath: "", + // Pass a drive name only in case of virtio-blk driver. + // If virtio-scsi driver, the agent will be able to find the + // device based on the provided address. + if pod.config.HypervisorConfig.BlockDeviceDriver == VirtioBlock { + // 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) + + 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.Fstype = c.state.Fstype @@ -678,22 +710,8 @@ func (k *kataAgent) createContainer(pod *Pod, c *Container) (*Process, error) { // irrelevant information to the agent. constraintGRPCSpec(grpcSpec) - // Append container mounts for block devices passed with --device. - for _, device := range 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) - } + // Append container devices for block devices passed with --device. + ctrDevices = k.appendDevices(ctrDevices, c.devices) req := &grpc.CreateContainerRequest{ ContainerId: c.id, diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index 8440636e1..da2e83824 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -33,7 +33,11 @@ import ( "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) { buf := make([]byte, 1024) @@ -336,3 +340,42 @@ func TestGenerateInterfacesAndRoutes(t *testing.T) { "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) +}