Merge pull request #2477 from bergwolf/ro

qemu: pass rootfs image in readonly mode
This commit is contained in:
Fupan Li 2020-02-26 19:22:13 +08:00 committed by GitHub
commit 6bed2a724d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 566 additions and 362 deletions

4
Gopkg.lock generated
View File

@ -412,11 +412,11 @@
revision = "2f1d1f20f75d5404f53b9edf6b53ed5505508675"
[[projects]]
digest = "1:2ee402700d1a01bc9b09a41eea4823431685445f9aaf77fe4ba3fcea92ae952b"
digest = "1:0044fb81f517f480ca3c33675a3af6b4ada77a6faf699a302bc2388c98cacba9"
name = "github.com/intel/govmm"
packages = ["qemu"]
pruneopts = "NUT"
revision = "cab47093760f36ef5a5da880bb70c4bf128abbbf"
revision = "3700c55dd766d37e17af354fb9975dc801619d62"
[[projects]]
digest = "1:87d8533d926ef2bf1f84ef08589a753104e343e49a6e63a446eba17f59a0ce37"

View File

@ -48,7 +48,7 @@
[[constraint]]
name = "github.com/intel/govmm"
revision = "cab47093760f36ef5a5da880bb70c4bf128abbbf"
revision = "3700c55dd766d37e17af354fb9975dc801619d62"
[[constraint]]
name = "github.com/kata-containers/agent"

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
// +build !s390x
/*
// Copyright contributors to the Virtual Machine Manager for Go project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
package qemu
const (
// Virtio9P is the 9pfs device driver.
Virtio9P DeviceDriver = "virtio-9p-pci"
// VirtioSerial is the serial device driver.
VirtioSerial DeviceDriver = "virtio-serial-pci"
// VirtioNet is the virt-io pci networking device driver.
VirtioNet DeviceDriver = VirtioNetPCI
// Vfio is the vfio driver
Vfio DeviceDriver = "vfio-pci"
// VirtioScsi is the virtio-scsi device
VirtioScsi DeviceDriver = "virtio-scsi-pci"
// VHostVSock is a generic Vsock vhost device
VHostVSock DeviceDriver = "vhost-vsock-pci"
)
// isVirtioPCI is a map indicating if a DeviceDriver is considered as a
// virtio PCI device, which is helpful to determine if the option "romfile"
// applies or not to this specific device.
var isVirtioPCI = map[DeviceDriver]bool{
NVDIMM: false,
Virtio9P: true,
VirtioNetPCI: true,
VirtioSerial: true,
VirtioBlock: true,
VirtioBlockPCI: true,
Console: false,
VirtioSerialPort: false,
VHostVSock: true,
VirtioRng: true,
VirtioBalloon: true,
VhostUserSCSI: true,
VhostUserBlk: true,
Vfio: true,
VirtioScsi: true,
PCIBridgeDriver: true,
PCIePCIBridgeDriver: true,
PCIeRootPort: true,
}
// isVirtioCCW is a dummy map to return always false on no-s390x arch
var isVirtioCCW = map[DeviceDriver]bool{}
// QemuNetdevParam converts to the QEMU -netdev parameter notation
func (n NetDeviceType) QemuNetdevParam() string {
switch n {
case TAP:
return "tap"
case MACVTAP:
return "tap"
case IPVTAP:
return "tap"
case VETHTAP:
return "tap" // -netdev type=tap -device virtio-net-pci
case VFIO:
return "" // -device vfio-pci (no netdev)
case VHOSTUSER:
return "vhost-user" // -netdev type=vhost-user (no device)
default:
return ""
}
}
// QemuDeviceParam converts to the QEMU -device parameter notation
func (n NetDeviceType) QemuDeviceParam() DeviceDriver {
switch n {
case TAP:
return "virtio-net-pci"
case MACVTAP:
return "virtio-net-pci"
case IPVTAP:
return "virtio-net-pci"
case VETHTAP:
return "virtio-net-pci" // -netdev type=tap -device virtio-net-pci
case VFIO:
return "vfio-pci" // -device vfio-pci (no netdev)
case VHOSTUSER:
return "" // -netdev type=vhost-user (no device)
default:
return ""
}
}
func isDimmSupported() bool {
return true
}

View File

@ -1,140 +0,0 @@
// +build s390x
/*
// Copyright contributors to the Virtual Machine Manager for Go project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
package qemu
import "log"
// IBM Z uses CCW devices intead of PCI devices.
// See https://wiki.qemu.org/Documentation/Platforms/S390X
const (
// Virtio9P is the 9pfs device driver.
Virtio9P DeviceDriver = "virtio-9p-ccw"
// VirtioSerial is the serial device driver.
VirtioSerial DeviceDriver = "virtio-serial-ccw"
// VirtioNet is the virt-io ccw networking device driver.
VirtioNet DeviceDriver = VirtioNetCCW
// Vfio is the vfio driver
Vfio DeviceDriver = "vfio-ccw"
// VirtioScsi is the virtio-scsi device
VirtioScsi DeviceDriver = "virtio-scsi-ccw"
// VHostVSock is a generic Vsock Device
VHostVSock DeviceDriver = "vhost-vsock-ccw"
)
// isVirtioPCI is a fake map on s390x to always avoid the "romfile"
// option
var isVirtioPCI = map[DeviceDriver]bool{
NVDIMM: false,
Virtio9P: false,
VirtioNetCCW: false,
VirtioSerial: false,
VirtioBlock: false,
Console: false,
VirtioSerialPort: false,
VHostVSock: false,
VirtioRng: false,
VirtioBalloon: false,
VhostUserSCSI: false,
VhostUserBlk: false,
Vfio: false,
VirtioScsi: false,
PCIBridgeDriver: false,
PCIePCIBridgeDriver: false,
}
// isVirtioCCW returns if the device is a ccw device
var isVirtioCCW = map[DeviceDriver]bool{
NVDIMM: false,
Virtio9P: true,
VirtioNetCCW: true,
VirtioSerial: true,
VirtioBlock: true,
VirtioBlockCCW: true,
Console: false,
VirtioSerialPort: false,
VHostVSock: true,
VirtioRng: true,
VirtioBalloon: true,
VhostUserSCSI: false,
VhostUserBlk: false,
Vfio: true,
VirtioScsi: true,
PCIBridgeDriver: false,
PCIePCIBridgeDriver: false,
}
// QemuDeviceParam converts to the QEMU -device parameter notation
// This function has been reimplemented for the s390x architecture to deal
// with the VHOSTUSER case. Vhost user devices are not implemented on s390x
// architecture. For further details see issue
// https://github.com/kata-containers/runtime/issues/659
func (n NetDeviceType) QemuDeviceParam() string {
switch n {
case TAP:
return string(VirtioNet)
case MACVTAP:
return string(VirtioNet)
case IPVTAP:
return string(VirtioNet)
case VETHTAP:
return string(VirtioNet)
case VFIO:
return string(Vfio)
case VHOSTUSER:
log.Fatal("vhost-user devices are not supported on IBM Z")
return ""
default:
return ""
}
}
// QemuNetdevParam converts to the QEMU -netdev parameter notation
// This function has been reimplemented for the s390x architecture to deal
// with the VHOSTUSER case. Vhost user devices are not implemented on s390x
// architecture. For further details see issue
// https://github.com/kata-containers/runtime/issues/659
func (n NetDeviceType) QemuNetdevParam() string {
switch n {
case TAP:
return "tap"
case MACVTAP:
return "tap"
case IPVTAP:
return "tap"
case VETHTAP:
return "tap"
case VFIO:
return ""
case VHOSTUSER:
log.Fatal("vhost-user devices are not supported on IBM Z")
return ""
default:
return ""
}
}
func isDimmSupported() bool {
return false
}

View File

@ -846,7 +846,9 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b
"drive": blockdevID,
}
if isVirtioCCW[DeviceDriver(driver)] {
var transport VirtioTransport
if transport.isVirtioCCW(nil) {
args["devno"] = bus
} else if bus != "" {
args["bus"] = bus
@ -855,7 +857,7 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b
if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) {
args["share-rw"] = "on"
}
if isVirtioPCI[DeviceDriver(driver)] {
if transport.isVirtioPCI(nil) {
args["romfile"] = romfile
if disableModern {
@ -897,12 +899,7 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive
"id": devID,
"driver": driver,
"drive": blockdevID,
}
if isVirtioCCW[DeviceDriver(driver)] {
args["devno"] = bus
} else {
args["bus"] = bus
"bus": bus,
}
if scsiID >= 0 {
@ -914,13 +911,6 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive
if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) {
args["share-rw"] = "on"
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
if disableModern {
args["disable-modern"] = disableModern
}
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -1124,7 +1114,10 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver
if queues > 0 {
args["num-queues"] = strconv.Itoa(queues)
}
if isVirtioPCI[DeviceDriver(driver)] {
var transport VirtioTransport
if transport.isVirtioPCI(nil) {
args["romfile"] = romfile
if disableModern {
@ -1161,9 +1154,18 @@ func (q *QMP) ExecutePCIVhostUserDevAdd(ctx context.Context, driver, devID, char
// bdf is the PCI bus-device-function of the pci device.
// bus is optional. When hot plugging a PCIe device, the bus can be the ID of the pcie-root-port.
func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, bus, romfile string) error {
var driver string
var transport VirtioTransport
if transport.isVirtioCCW(nil) {
driver = string(VfioCCW)
} else {
driver = string(VfioPCI)
}
args := map[string]interface{}{
"id": devID,
"driver": Vfio,
"driver": driver,
"host": bdf,
"romfile": romfile,
}
@ -1181,7 +1183,7 @@ func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, bus, romfile
func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus, romfile string) error {
args := map[string]interface{}{
"id": devID,
"driver": Vfio,
"driver": VfioPCI,
"host": bdf,
"addr": addr,
"romfile": romfile,
@ -1201,7 +1203,7 @@ func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus
func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus, romfile string) error {
args := map[string]interface{}{
"id": devID,
"driver": Vfio,
"driver": VfioPCI,
"sysfsdev": sysfsdev,
"romfile": romfile,
}
@ -1265,10 +1267,6 @@ func (q *QMP) ExecuteCPUDeviceAdd(ctx context.Context, driver, cpuID, socketID,
}
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -1477,7 +1475,7 @@ func (q *QMP) ExecuteBalloon(ctx context.Context, bytes uint64) error {
// 1.0 in nested environments.
func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd, addr, bus, romfile string, disableModern bool) error {
args := map[string]interface{}{
"driver": VHostVSock,
"driver": VHostVSockPCI,
"id": id,
"guest-cid": guestCID,
"vhostfd": vhostfd,

View File

@ -153,6 +153,9 @@ type BlockDrive struct {
// ShareRW enables multiple qemu instances to share the File
ShareRW bool
// ReadOnly sets the device file readonly
ReadOnly bool
}
// VFIODeviceType indicates VFIO device type

View File

@ -343,10 +343,11 @@ func genericImage(path string) (config.BlockDrive, error) {
id := utils.MakeNameID("image", hex.EncodeToString(randBytes), maxDevIDSize)
drive := config.BlockDrive{
File: path,
Format: "raw",
ID: id,
ShareRW: true,
File: path,
Format: "raw",
ID: id,
ShareRW: true,
ReadOnly: true,
}
return drive, nil
@ -603,6 +604,7 @@ func genericBlockDevice(drive config.BlockDrive, nestedRun bool) (govmmQemu.Bloc
Interface: "none",
DisableModern: nestedRun,
ShareRW: drive.ShareRW,
ReadOnly: drive.ReadOnly,
}, nil
}
@ -622,16 +624,19 @@ func (q *qemuArchBase) appendVhostUserDevice(devices []govmmQemu.Device, attr co
case config.VhostUserNet:
qemuVhostUserDevice.TypeDevID = utils.MakeNameID("net", attr.DevID, maxDevIDSize)
qemuVhostUserDevice.Address = attr.MacAddress
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserNet
case config.VhostUserSCSI:
qemuVhostUserDevice.TypeDevID = utils.MakeNameID("scsi", attr.DevID, maxDevIDSize)
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserSCSI
case config.VhostUserBlk:
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserBlk
case config.VhostUserFS:
qemuVhostUserDevice.TypeDevID = utils.MakeNameID("fs", attr.DevID, maxDevIDSize)
qemuVhostUserDevice.Tag = attr.Tag
qemuVhostUserDevice.CacheSize = attr.CacheSize
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserFS
}
qemuVhostUserDevice.VhostUserType = govmmQemu.DeviceDriver(attr.Type)
qemuVhostUserDevice.SocketPath = attr.SocketPath
qemuVhostUserDevice.CharDevID = utils.MakeNameID("char", attr.DevID, maxDevIDSize)

View File

@ -308,6 +308,7 @@ func TestQemuArchBaseAppendImage(t *testing.T) {
Format: "raw",
Interface: "none",
ShareRW: true,
ReadOnly: true,
},
}
@ -426,7 +427,7 @@ func TestQemuArchBaseAppendVhostUserDevice(t *testing.T) {
CharDevID: fmt.Sprintf("char-%s", id),
TypeDevID: fmt.Sprintf("net-%s", id),
Address: macAddress,
VhostUserType: config.VhostUserNet,
VhostUserType: govmmQemu.VhostUserNet,
},
}