mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-01 17:06:28 +00:00
Merge branch 'master' into static-checks
This commit is contained in:
23
qemu/qemu.go
23
qemu/qemu.go
@@ -82,6 +82,9 @@ const (
|
|||||||
|
|
||||||
// VirtioSerialPort is the serial port device driver.
|
// VirtioSerialPort is the serial port device driver.
|
||||||
VirtioSerialPort DeviceDriver = "virtserialport"
|
VirtioSerialPort DeviceDriver = "virtserialport"
|
||||||
|
|
||||||
|
// VHostVSockPCI is the vhost vsock pci driver.
|
||||||
|
VHostVSockPCI DeviceDriver = "vhost-vsock-pci"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectType is a string representing a qemu object type.
|
// ObjectType is a string representing a qemu object type.
|
||||||
@@ -962,6 +965,12 @@ type VSOCKDevice struct {
|
|||||||
ID string
|
ID string
|
||||||
|
|
||||||
ContextID uint32
|
ContextID uint32
|
||||||
|
|
||||||
|
// VHostFD vhost file descriptor that holds the ContextID
|
||||||
|
VHostFD *os.File
|
||||||
|
|
||||||
|
// DisableModern prevents qemu from relying on fast MMIO.
|
||||||
|
DisableModern bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -988,12 +997,22 @@ func (vsock VSOCKDevice) Valid() bool {
|
|||||||
|
|
||||||
// QemuParams returns the qemu parameters built out of the VSOCK device.
|
// QemuParams returns the qemu parameters built out of the VSOCK device.
|
||||||
func (vsock VSOCKDevice) QemuParams(config *Config) []string {
|
func (vsock VSOCKDevice) QemuParams(config *Config) []string {
|
||||||
|
var deviceParams []string
|
||||||
var qemuParams []string
|
var qemuParams []string
|
||||||
|
|
||||||
deviceParam := fmt.Sprintf("%s,id=%s,%s=%d", VhostVSOCKPCI, vsock.ID, VSOCKGuestCID, vsock.ContextID)
|
deviceParams = append(deviceParams, fmt.Sprintf("%s", VhostVSOCKPCI))
|
||||||
|
if vsock.DisableModern {
|
||||||
|
deviceParams = append(deviceParams, ",disable-modern=true")
|
||||||
|
}
|
||||||
|
if vsock.VHostFD != nil {
|
||||||
|
qemuFDs := config.appendFDs([]*os.File{vsock.VHostFD})
|
||||||
|
deviceParams = append(deviceParams, fmt.Sprintf(",vhostfd=%d", qemuFDs[0]))
|
||||||
|
}
|
||||||
|
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", vsock.ID))
|
||||||
|
deviceParams = append(deviceParams, fmt.Sprintf(",%s=%d", VSOCKGuestCID, vsock.ContextID))
|
||||||
|
|
||||||
qemuParams = append(qemuParams, "-device")
|
qemuParams = append(qemuParams, "-device")
|
||||||
qemuParams = append(qemuParams, deviceParam)
|
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
|
||||||
|
|
||||||
return qemuParams
|
return qemuParams
|
||||||
}
|
}
|
||||||
|
@@ -329,12 +329,14 @@ func TestAppendDeviceVFIO(t *testing.T) {
|
|||||||
testAppend(vfioDevice, deviceVFIOString, t)
|
testAppend(vfioDevice, deviceVFIOString, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceVSOCKString = "-device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=4"
|
var deviceVSOCKString = "-device vhost-vsock-pci,disable-modern=true,id=vhost-vsock-pci0,guest-cid=4"
|
||||||
|
|
||||||
func TestAppendVSOCK(t *testing.T) {
|
func TestAppendVSOCK(t *testing.T) {
|
||||||
vsockDevice := VSOCKDevice{
|
vsockDevice := VSOCKDevice{
|
||||||
ID: "vhost-vsock-pci0",
|
ID: "vhost-vsock-pci0",
|
||||||
ContextID: 4,
|
ContextID: 4,
|
||||||
|
VHostFD: nil,
|
||||||
|
DisableModern: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
testAppend(vsockDevice, deviceVSOCKString, t)
|
testAppend(vsockDevice, deviceVSOCKString, t)
|
||||||
@@ -344,6 +346,8 @@ func TestVSOCKValid(t *testing.T) {
|
|||||||
vsockDevice := VSOCKDevice{
|
vsockDevice := VSOCKDevice{
|
||||||
ID: "vhost-vsock-pci0",
|
ID: "vhost-vsock-pci0",
|
||||||
ContextID: MinimalGuestCID - 1,
|
ContextID: MinimalGuestCID - 1,
|
||||||
|
VHostFD: nil,
|
||||||
|
DisableModern: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if vsockDevice.Valid() {
|
if vsockDevice.Valid() {
|
||||||
|
55
qemu/qmp.go
55
qemu/qmp.go
@@ -728,6 +728,51 @@ func (q *QMP) ExecuteBlockdevDel(ctx context.Context, blockdevID string) error {
|
|||||||
return q.executeCommand(ctx, "x-blockdev-del", args, nil)
|
return q.executeCommand(ctx, "x-blockdev-del", args, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteNetdevAdd adds a Net device to a QEMU instance
|
||||||
|
// using the netdev_add command. netdevID is the id of the device to add.
|
||||||
|
// Must be valid QMP identifier.
|
||||||
|
func (q *QMP) ExecuteNetdevAdd(ctx context.Context, netdevType, netdevID, ifname, downscript, script string, queues int) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"type": netdevType,
|
||||||
|
"id": netdevID,
|
||||||
|
"ifname": ifname,
|
||||||
|
"downscript": downscript,
|
||||||
|
"script": script,
|
||||||
|
}
|
||||||
|
if queues > 1 {
|
||||||
|
args["queues"] = queues
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.executeCommand(ctx, "netdev_add", args, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecuteNetdevDel deletes a Net device from a QEMU instance
|
||||||
|
// using the netdev_del command. netdevID is the id of the device to delete.
|
||||||
|
func (q *QMP) ExecuteNetdevDel(ctx context.Context, netdevID string) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"id": netdevID,
|
||||||
|
}
|
||||||
|
return q.executeCommand(ctx, "netdev_del", args, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecuteNetPCIDeviceAdd adds a Net PCI device to a QEMU instance
|
||||||
|
// using the device_add command. devID is the id of the device to add.
|
||||||
|
// Must be valid QMP identifier. netdevID is the id of nic added by previous netdev_add.
|
||||||
|
func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus string) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"id": devID,
|
||||||
|
"driver": VirtioNetPCI,
|
||||||
|
"netdev": netdevID,
|
||||||
|
"mac": macAddr,
|
||||||
|
"addr": addr,
|
||||||
|
}
|
||||||
|
|
||||||
|
if bus != "" {
|
||||||
|
args["bus"] = bus
|
||||||
|
}
|
||||||
|
return q.executeCommand(ctx, "device_add", args, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// ExecuteDeviceDel deletes guest portion of a QEMU device by sending a
|
// ExecuteDeviceDel deletes guest portion of a QEMU device by sending a
|
||||||
// device_del command. devId is the identifier of the device to delete.
|
// device_del command. devId is the identifier of the device to delete.
|
||||||
// Typically it would match the devID parameter passed to an earlier call
|
// Typically it would match the devID parameter passed to an earlier call
|
||||||
@@ -882,3 +927,13 @@ func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecutePCIVSockAdd adds a vhost-vsock-pci bus
|
||||||
|
func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID string) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"driver": VHostVSockPCI,
|
||||||
|
"id": id,
|
||||||
|
"guest-cid": guestCID,
|
||||||
|
}
|
||||||
|
return q.executeCommand(ctx, "device_add", args, nil)
|
||||||
|
}
|
||||||
|
@@ -364,6 +364,66 @@ func TestQMPBlockdevAdd(t *testing.T) {
|
|||||||
<-disconnectedCh
|
<-disconnectedCh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks that the netdev_add command is correctly sent.
|
||||||
|
//
|
||||||
|
// We start a QMPLoop, send the netdev_add command and stop the loop.
|
||||||
|
//
|
||||||
|
// The netdev_add command should be correctly sent and the QMP loop should
|
||||||
|
// exit gracefully.
|
||||||
|
func TestQMPNetdevAdd(t *testing.T) {
|
||||||
|
connectedCh := make(chan *QMPVersion)
|
||||||
|
disconnectedCh := make(chan struct{})
|
||||||
|
buf := newQMPTestCommandBuffer(t)
|
||||||
|
buf.AddCommand("netdev_add", nil, "return", nil)
|
||||||
|
cfg := QMPConfig{Logger: qmpTestLogger{}}
|
||||||
|
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
|
||||||
|
q.version = checkVersion(t, connectedCh)
|
||||||
|
err := q.ExecuteNetdevAdd(context.Background(), "tap", "br0", "tap0", "no", "no", 8)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error %v", err)
|
||||||
|
}
|
||||||
|
q.Shutdown()
|
||||||
|
<-disconnectedCh
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks that the netdev_del command is correctly sent.
|
||||||
|
//
|
||||||
|
// We start a QMPLoop, send the netdev_del command and stop the loop.
|
||||||
|
//
|
||||||
|
// The netdev_del command should be correctly sent and the QMP loop should
|
||||||
|
// exit gracefully.
|
||||||
|
func TestQMPNetdevDel(t *testing.T) {
|
||||||
|
connectedCh := make(chan *QMPVersion)
|
||||||
|
disconnectedCh := make(chan struct{})
|
||||||
|
buf := newQMPTestCommandBuffer(t)
|
||||||
|
buf.AddCommand("netdev_del", nil, "return", nil)
|
||||||
|
cfg := QMPConfig{Logger: qmpTestLogger{}}
|
||||||
|
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
|
||||||
|
q.version = checkVersion(t, connectedCh)
|
||||||
|
err := q.ExecuteNetdevDel(context.Background(), "br0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error %v", err)
|
||||||
|
}
|
||||||
|
q.Shutdown()
|
||||||
|
<-disconnectedCh
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQMPNetPCIDeviceAdd(t *testing.T) {
|
||||||
|
connectedCh := make(chan *QMPVersion)
|
||||||
|
disconnectedCh := make(chan struct{})
|
||||||
|
buf := newQMPTestCommandBuffer(t)
|
||||||
|
buf.AddCommand("device_add", nil, "return", nil)
|
||||||
|
cfg := QMPConfig{Logger: qmpTestLogger{}}
|
||||||
|
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
|
||||||
|
checkVersion(t, connectedCh)
|
||||||
|
err := q.ExecuteNetPCIDeviceAdd(context.Background(), "br0", "virtio-0", "02:42:ac:11:00:02", "0x7", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error %v", err)
|
||||||
|
}
|
||||||
|
q.Shutdown()
|
||||||
|
<-disconnectedCh
|
||||||
|
}
|
||||||
|
|
||||||
// Checks that the device_add command is correctly sent.
|
// Checks that the device_add command is correctly sent.
|
||||||
//
|
//
|
||||||
// We start a QMPLoop, send the device_add command and stop the loop.
|
// We start a QMPLoop, send the device_add command and stop the loop.
|
||||||
@@ -945,3 +1005,20 @@ func TestExecHotplugMemory(t *testing.T) {
|
|||||||
q.Shutdown()
|
q.Shutdown()
|
||||||
<-disconnectedCh
|
<-disconnectedCh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks vsock-pci hotplug
|
||||||
|
func TestExecutePCIVSockAdd(t *testing.T) {
|
||||||
|
connectedCh := make(chan *QMPVersion)
|
||||||
|
disconnectedCh := make(chan struct{})
|
||||||
|
buf := newQMPTestCommandBuffer(t)
|
||||||
|
buf.AddCommand("device_add", nil, "return", nil)
|
||||||
|
cfg := QMPConfig{Logger: qmpTestLogger{}}
|
||||||
|
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
|
||||||
|
checkVersion(t, connectedCh)
|
||||||
|
err := q.ExecutePCIVSockAdd(context.Background(), "vsock-pci0", "3")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error %v", err)
|
||||||
|
}
|
||||||
|
q.Shutdown()
|
||||||
|
<-disconnectedCh
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user