virtcontainers: Add Bridge to the types package

Bridge is representing a PCI/E bridge, so we're moving the bridge*.go
to types/pci*.go.

Fixes: #1119

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-01-16 15:45:08 +01:00
parent b25f43e865
commit 2e1ddbc725
8 changed files with 59 additions and 55 deletions

View File

@ -47,7 +47,7 @@ type CPUDevice struct {
// QemuState keeps Qemu's state // QemuState keeps Qemu's state
type QemuState struct { type QemuState struct {
Bridges []Bridge Bridges []types.PCIBridge
// HotpluggedCPUs is the list of CPUs that were hot-added // HotpluggedCPUs is the list of CPUs that were hot-added
HotpluggedVCPUs []CPUDevice HotpluggedVCPUs []CPUDevice
HotpluggedMemory int HotpluggedMemory int
@ -722,25 +722,25 @@ func (q *qemu) qmpShutdown() {
} }
} }
func (q *qemu) addDeviceToBridge(ID string) (string, Bridge, error) { func (q *qemu) addDeviceToBridge(ID string) (string, types.PCIBridge, error) {
var err error var err error
var addr uint32 var addr uint32
// looking for an empty address in the bridges // looking for an empty address in the bridges
for _, b := range q.state.Bridges { for _, b := range q.state.Bridges {
addr, err = b.addDevice(ID) addr, err = b.AddDevice(ID)
if err == nil { if err == nil {
return fmt.Sprintf("%02x", addr), b, nil return fmt.Sprintf("%02x", addr), b, nil
} }
} }
return "", Bridge{}, err return "", types.PCIBridge{}, err
} }
func (q *qemu) removeDeviceFromBridge(ID string) error { func (q *qemu) removeDeviceFromBridge(ID string) error {
var err error var err error
for _, b := range q.state.Bridges { for _, b := range q.state.Bridges {
err = b.removeDevice(ID) err = b.RemoveDevice(ID)
if err == nil { if err == nil {
// device was removed correctly // device was removed correctly
return nil return nil
@ -1377,7 +1377,7 @@ func (q *qemu) resizeMemory(reqMemMB uint32, memoryBlockSizeMB uint32) (uint32,
} }
// genericAppendBridges appends to devices the given bridges // genericAppendBridges appends to devices the given bridges
func genericAppendBridges(devices []govmmQemu.Device, bridges []Bridge, machineType string) []govmmQemu.Device { func genericAppendBridges(devices []govmmQemu.Device, bridges []types.PCIBridge, machineType string) []govmmQemu.Device {
bus := defaultPCBridgeBus bus := defaultPCBridgeBus
switch machineType { switch machineType {
case QemuQ35, QemuVirt: case QemuQ35, QemuVirt:
@ -1386,7 +1386,7 @@ func genericAppendBridges(devices []govmmQemu.Device, bridges []Bridge, machineT
for idx, b := range bridges { for idx, b := range bridges {
t := govmmQemu.PCIBridge t := govmmQemu.PCIBridge
if b.Type == pcieBridge { if b.Type == types.PCIE {
t = govmmQemu.PCIEBridge t = govmmQemu.PCIEBridge
} }
@ -1408,9 +1408,9 @@ func genericAppendBridges(devices []govmmQemu.Device, bridges []Bridge, machineT
return devices return devices
} }
func genericBridges(number uint32, machineType string) []Bridge { func genericBridges(number uint32, machineType string) []types.PCIBridge {
var bridges []Bridge var bridges []types.PCIBridge
var bt bridgeType var bt types.PCIType
switch machineType { switch machineType {
case QemuQ35: case QemuQ35:
@ -1418,19 +1418,19 @@ func genericBridges(number uint32, machineType string) []Bridge {
// qemu-2.10 will introduce pcie bridges // qemu-2.10 will introduce pcie bridges
fallthrough fallthrough
case QemuPC: case QemuPC:
bt = pciBridge bt = types.PCI
case QemuVirt: case QemuVirt:
bt = pcieBridge bt = types.PCIE
case QemuPseries: case QemuPseries:
bt = pciBridge bt = types.PCI
case QemuCCWVirtio: case QemuCCWVirtio:
bt = pciBridge bt = types.PCI
default: default:
return nil return nil
} }
for i := uint32(0); i < number; i++ { for i := uint32(0); i < number; i++ {
bridges = append(bridges, Bridge{ bridges = append(bridges, types.PCIBridge{
Type: bt, Type: bt,
ID: fmt.Sprintf("%s-bridge-%d", bt, i), ID: fmt.Sprintf("%s-bridge-%d", bt, i),
Address: make(map[uint32]string), Address: make(map[uint32]string),

View File

@ -117,7 +117,7 @@ func (q *qemuAmd64) capabilities() types.Capabilities {
return caps return caps
} }
func (q *qemuAmd64) bridges(number uint32) []Bridge { func (q *qemuAmd64) bridges(number uint32) []types.PCIBridge {
return genericBridges(number, q.machineType) return genericBridges(number, q.machineType)
} }
@ -160,6 +160,6 @@ func (q *qemuAmd64) appendImage(devices []govmmQemu.Device, path string) ([]govm
} }
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device { func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device, bridges []types.PCIBridge) []govmmQemu.Device {
return genericAppendBridges(devices, bridges, q.machineType) return genericAppendBridges(devices, bridges, q.machineType)
} }

View File

@ -12,6 +12,7 @@ import (
"testing" "testing"
govmmQemu "github.com/intel/govmm/qemu" govmmQemu "github.com/intel/govmm/qemu"
"github.com/kata-containers/runtime/virtcontainers/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -43,8 +44,8 @@ func TestQemuAmd64Bridges(t *testing.T) {
assert.Len(bridges, len) assert.Len(bridges, len)
for i, b := range bridges { for i, b := range bridges {
id := fmt.Sprintf("%s-bridge-%d", pciBridge, i) id := fmt.Sprintf("%s-bridge-%d", types.PCI, i)
assert.Equal(pciBridge, b.Type) assert.Equal(types.PCI, b.Type)
assert.Equal(id, b.ID) assert.Equal(id, b.ID)
assert.NotNil(b.Address) assert.NotNil(b.Address)
} }
@ -54,8 +55,8 @@ func TestQemuAmd64Bridges(t *testing.T) {
assert.Len(bridges, len) assert.Len(bridges, len)
for i, b := range bridges { for i, b := range bridges {
id := fmt.Sprintf("%s-bridge-%d", pciBridge, i) id := fmt.Sprintf("%s-bridge-%d", types.PCI, i)
assert.Equal(pciBridge, b.Type) assert.Equal(types.PCI, b.Type)
assert.Equal(id, b.ID) assert.Equal(id, b.ID)
assert.NotNil(b.Address) assert.NotNil(b.Address)
} }

View File

@ -48,7 +48,7 @@ type qemuArch interface {
capabilities() types.Capabilities capabilities() types.Capabilities
// bridges returns the number bridges for the machine type // bridges returns the number bridges for the machine type
bridges(number uint32) []Bridge bridges(number uint32) []types.PCIBridge
// cpuTopology returns the CPU topology for the given amount of vcpus // cpuTopology returns the CPU topology for the given amount of vcpus
cpuTopology(vcpus, maxvcpus uint32) govmmQemu.SMP cpuTopology(vcpus, maxvcpus uint32) govmmQemu.SMP
@ -69,7 +69,7 @@ type qemuArch interface {
appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread) appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread)
// appendBridges appends bridges to devices // appendBridges appends bridges to devices
appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device appendBridges(devices []govmmQemu.Device, bridges []types.PCIBridge) []govmmQemu.Device
// append9PVolume appends a 9P volume to devices // append9PVolume appends a 9P volume to devices
append9PVolume(devices []govmmQemu.Device, volume types.Volume) []govmmQemu.Device append9PVolume(devices []govmmQemu.Device, volume types.Volume) []govmmQemu.Device
@ -235,13 +235,13 @@ func (q *qemuArchBase) capabilities() types.Capabilities {
return caps return caps
} }
func (q *qemuArchBase) bridges(number uint32) []Bridge { func (q *qemuArchBase) bridges(number uint32) []types.PCIBridge {
var bridges []Bridge var bridges []types.PCIBridge
for i := uint32(0); i < number; i++ { for i := uint32(0); i < number; i++ {
bridges = append(bridges, Bridge{ bridges = append(bridges, types.PCIBridge{
Type: pciBridge, Type: types.PCI,
ID: fmt.Sprintf("%s-bridge-%d", pciBridge, i), ID: fmt.Sprintf("%s-bridge-%d", types.PCI, i),
Address: make(map[uint32]string), Address: make(map[uint32]string),
}) })
} }
@ -346,10 +346,10 @@ func (q *qemuArchBase) appendSCSIController(devices []govmmQemu.Device, enableIO
} }
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuArchBase) appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device { func (q *qemuArchBase) appendBridges(devices []govmmQemu.Device, bridges []types.PCIBridge) []govmmQemu.Device {
for idx, b := range bridges { for idx, b := range bridges {
t := govmmQemu.PCIBridge t := govmmQemu.PCIBridge
if b.Type == pcieBridge { if b.Type == types.PCIE {
t = govmmQemu.PCIEBridge t = govmmQemu.PCIEBridge
} }

View File

@ -150,8 +150,8 @@ func TestQemuArchBaseBridges(t *testing.T) {
assert.Len(bridges, len) assert.Len(bridges, len)
for i, b := range bridges { for i, b := range bridges {
id := fmt.Sprintf("%s-bridge-%d", pciBridge, i) id := fmt.Sprintf("%s-bridge-%d", types.PCI, i)
assert.Equal(pciBridge, b.Type) assert.Equal(types.PCI, b.Type)
assert.Equal(id, b.ID) assert.Equal(id, b.ID)
assert.NotNil(b.Address) assert.NotNil(b.Address)
} }

View File

@ -104,7 +104,7 @@ func (q *qemuPPC64le) capabilities() types.Capabilities {
return caps return caps
} }
func (q *qemuPPC64le) bridges(number uint32) []Bridge { func (q *qemuPPC64le) bridges(number uint32) []types.PCIBridge {
return genericBridges(number, q.machineType) return genericBridges(number, q.machineType)
} }
@ -151,6 +151,6 @@ func (q *qemuPPC64le) appendImage(devices []govmmQemu.Device, path string) ([]go
} }
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device { func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device, bridges []types.PCIBridge) []govmmQemu.Device {
return genericAppendBridges(devices, bridges, q.machineType) return genericAppendBridges(devices, bridges, q.machineType)
} }

View File

@ -3,37 +3,41 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
package virtcontainers package types
import "fmt" import "fmt"
type bridgeType string // PCIType represents a type of PCI bus and bridge.
type PCIType string
const ( const (
pciBridge bridgeType = "pci" // PCI represents a PCI bus and bridge
pcieBridge bridgeType = "pcie" PCI PCIType = "pci"
// PCIE represents a PCIe bus and bridge
PCIE PCIType = "pcie"
) )
const pciBridgeMaxCapacity = 30 const pciBridgeMaxCapacity = 30
// Bridge is a bridge where devices can be hot plugged // PCIBridge is a PCI or PCIe bridge where devices can be hot plugged
type Bridge struct { type PCIBridge struct {
// Address contains information about devices plugged and its address in the bridge // Address contains information about devices plugged and its address in the bridge
Address map[uint32]string Address map[uint32]string
// Type is the type of the bridge (pci, pcie, etc) // Type is the PCI type of the bridge (pci, pcie, etc)
Type bridgeType Type PCIType
//ID is used to identify the bridge in the hypervisor // ID is used to identify the bridge in the hypervisor
ID string ID string
// Addr is the PCI/e slot of the bridge // Addr is the PCI/e slot of the bridge
Addr int Addr int
} }
// addDevice on success adds the device ID to the bridge and return the address // AddDevice on success adds the device ID to the PCI bridge and returns
// where the device was added, otherwise an error is returned // the address where the device was added.
func (b *Bridge) addDevice(ID string) (uint32, error) { func (b *PCIBridge) AddDevice(ID string) (uint32, error) {
var addr uint32 var addr uint32
// looking for the first available address // looking for the first available address
@ -53,9 +57,8 @@ func (b *Bridge) addDevice(ID string) (uint32, error) {
return addr, nil return addr, nil
} }
// removeDevice on success removes the device ID from the bridge and return nil, // RemoveDevice removes the device ID from the PCI bridge.
// otherwise an error is returned func (b *PCIBridge) RemoveDevice(ID string) error {
func (b *Bridge) removeDevice(ID string) error {
// check if the device was hot plugged in the bridge // check if the device was hot plugged in the bridge
for addr, devID := range b.Address { for addr, devID := range b.Address {
if devID == ID { if devID == ID {

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
package virtcontainers package types
import ( import (
"fmt" "fmt"
@ -16,22 +16,22 @@ func TestAddRemoveDevice(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
// create a bridge // create a bridge
bridges := []*Bridge{{make(map[uint32]string), pciBridge, "rgb123", 5}} bridges := []*PCIBridge{{make(map[uint32]string), PCI, "rgb123", 5}}
// add device // add device
devID := "abc123" devID := "abc123"
b := bridges[0] b := bridges[0]
addr, err := b.addDevice(devID) addr, err := b.AddDevice(devID)
assert.NoError(err) assert.NoError(err)
if addr < 1 { if addr < 1 {
assert.Fail("address cannot be less than 1") assert.Fail("address cannot be less than 1")
} }
// remove device // remove device
err = b.removeDevice("") err = b.RemoveDevice("")
assert.Error(err) assert.Error(err)
err = b.removeDevice(devID) err = b.RemoveDevice(devID)
assert.NoError(err) assert.NoError(err)
// add device when the bridge is full // add device when the bridge is full
@ -39,7 +39,7 @@ func TestAddRemoveDevice(t *testing.T) {
for i := uint32(1); i <= pciBridgeMaxCapacity; i++ { for i := uint32(1); i <= pciBridgeMaxCapacity; i++ {
bridges[0].Address[i] = fmt.Sprintf("%d", i) bridges[0].Address[i] = fmt.Sprintf("%d", i)
} }
addr, err = b.addDevice(devID) addr, err = b.AddDevice(devID)
assert.Error(err) assert.Error(err)
if addr != 0 { if addr != 0 {
assert.Fail("address should be 0") assert.Fail("address should be 0")