From f6511471d4001000c58e6edb349a6fb20e1a8760 Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Fri, 16 Nov 2018 11:07:20 +0800 Subject: [PATCH] block: Add cache-related options for block devices Add block_device_cache_set, block_device_cache_direct and block_device_cache_noflush. They are cache-related options for block devices that are described in https://github.com/qemu/qemu/blob/master/qapi/block-core.json. block_device_cache_direct denotes whether use of O_DIRECT (bypass the host page cache) is enabled. block_device_cache_noflush denotes whether flush requests for the device are ignored. The json said they are supported since 2.9. So add block_device_cache_set to control the cache options set to block devices or not. It will help to support the old version qemu. Fixes: #956 Signed-off-by: Hui Zhu --- pkg/katautils/config-settings.go | 3 + pkg/katautils/config.go | 159 ++++++++++++++++--------------- virtcontainers/hypervisor.go | 11 +++ virtcontainers/qemu.go | 7 +- 4 files changed, 104 insertions(+), 76 deletions(-) diff --git a/pkg/katautils/config-settings.go b/pkg/katautils/config-settings.go index cc81166639..8dcf6ac370 100644 --- a/pkg/katautils/config-settings.go +++ b/pkg/katautils/config-settings.go @@ -28,6 +28,9 @@ const defaultBridgesCount uint32 = 1 const defaultInterNetworkingModel = "macvtap" const defaultDisableBlockDeviceUse bool = false const defaultBlockDeviceDriver = "virtio-scsi" +const defaultBlockDeviceCacheSet bool = false +const defaultBlockDeviceCacheDirect bool = false +const defaultBlockDeviceCacheNoflush bool = false const defaultEnableIOThreads bool = false const defaultEnableMemPrealloc bool = false const defaultEnableHugePages bool = false diff --git a/pkg/katautils/config.go b/pkg/katautils/config.go index b1703bbe83..d9e7b796c3 100644 --- a/pkg/katautils/config.go +++ b/pkg/katautils/config.go @@ -79,33 +79,36 @@ type factory struct { } type hypervisor struct { - Path string `toml:"path"` - Kernel string `toml:"kernel"` - Initrd string `toml:"initrd"` - Image string `toml:"image"` - Firmware string `toml:"firmware"` - MachineAccelerators string `toml:"machine_accelerators"` - KernelParams string `toml:"kernel_params"` - MachineType string `toml:"machine_type"` - BlockDeviceDriver string `toml:"block_device_driver"` - EntropySource string `toml:"entropy_source"` - NumVCPUs int32 `toml:"default_vcpus"` - DefaultMaxVCPUs uint32 `toml:"default_maxvcpus"` - MemorySize uint32 `toml:"default_memory"` - MemSlots uint32 `toml:"memory_slots"` - DefaultBridges uint32 `toml:"default_bridges"` - Msize9p uint32 `toml:"msize_9p"` - DisableBlockDeviceUse bool `toml:"disable_block_device_use"` - MemPrealloc bool `toml:"enable_mem_prealloc"` - HugePages bool `toml:"enable_hugepages"` - Swap bool `toml:"enable_swap"` - Debug bool `toml:"enable_debug"` - DisableNestingChecks bool `toml:"disable_nesting_checks"` - EnableIOThreads bool `toml:"enable_iothreads"` - UseVSock bool `toml:"use_vsock"` - HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"` - DisableVhostNet bool `toml:"disable_vhost_net"` - GuestHookPath string `toml:"guest_hook_path"` + Path string `toml:"path"` + Kernel string `toml:"kernel"` + Initrd string `toml:"initrd"` + Image string `toml:"image"` + Firmware string `toml:"firmware"` + MachineAccelerators string `toml:"machine_accelerators"` + KernelParams string `toml:"kernel_params"` + MachineType string `toml:"machine_type"` + BlockDeviceDriver string `toml:"block_device_driver"` + EntropySource string `toml:"entropy_source"` + BlockDeviceCacheSet bool `toml:"block_device_cache_set"` + BlockDeviceCacheDirect bool `toml:"block_device_cache_direct"` + BlockDeviceCacheNoflush bool `toml:"block_device_cache_noflush"` + NumVCPUs int32 `toml:"default_vcpus"` + DefaultMaxVCPUs uint32 `toml:"default_maxvcpus"` + MemorySize uint32 `toml:"default_memory"` + MemSlots uint32 `toml:"memory_slots"` + DefaultBridges uint32 `toml:"default_bridges"` + Msize9p uint32 `toml:"msize_9p"` + DisableBlockDeviceUse bool `toml:"disable_block_device_use"` + MemPrealloc bool `toml:"enable_mem_prealloc"` + HugePages bool `toml:"enable_hugepages"` + Swap bool `toml:"enable_swap"` + Debug bool `toml:"enable_debug"` + DisableNestingChecks bool `toml:"disable_nesting_checks"` + EnableIOThreads bool `toml:"enable_iothreads"` + UseVSock bool `toml:"use_vsock"` + HotplugVFIOOnRootBus bool `toml:"hotplug_vfio_on_root_bus"` + DisableVhostNet bool `toml:"disable_vhost_net"` + GuestHookPath string `toml:"guest_hook_path"` } type proxy struct { @@ -416,33 +419,36 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { } return vc.HypervisorConfig{ - HypervisorPath: hypervisor, - KernelPath: kernel, - InitrdPath: initrd, - ImagePath: image, - FirmwarePath: firmware, - MachineAccelerators: machineAccelerators, - KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)), - HypervisorMachineType: machineType, - NumVCPUs: h.defaultVCPUs(), - DefaultMaxVCPUs: h.defaultMaxVCPUs(), - MemorySize: h.defaultMemSz(), - MemSlots: h.defaultMemSlots(), - EntropySource: h.GetEntropySource(), - DefaultBridges: h.defaultBridges(), - DisableBlockDeviceUse: h.DisableBlockDeviceUse, - MemPrealloc: h.MemPrealloc, - HugePages: h.HugePages, - Mlock: !h.Swap, - Debug: h.Debug, - DisableNestingChecks: h.DisableNestingChecks, - BlockDeviceDriver: blockDriver, - EnableIOThreads: h.EnableIOThreads, - Msize9p: h.msize9p(), - UseVSock: useVSock, - HotplugVFIOOnRootBus: h.HotplugVFIOOnRootBus, - DisableVhostNet: h.DisableVhostNet, - GuestHookPath: h.guestHookPath(), + HypervisorPath: hypervisor, + KernelPath: kernel, + InitrdPath: initrd, + ImagePath: image, + FirmwarePath: firmware, + MachineAccelerators: machineAccelerators, + KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)), + HypervisorMachineType: machineType, + NumVCPUs: h.defaultVCPUs(), + DefaultMaxVCPUs: h.defaultMaxVCPUs(), + MemorySize: h.defaultMemSz(), + MemSlots: h.defaultMemSlots(), + EntropySource: h.GetEntropySource(), + DefaultBridges: h.defaultBridges(), + DisableBlockDeviceUse: h.DisableBlockDeviceUse, + MemPrealloc: h.MemPrealloc, + HugePages: h.HugePages, + Mlock: !h.Swap, + Debug: h.Debug, + DisableNestingChecks: h.DisableNestingChecks, + BlockDeviceDriver: blockDriver, + BlockDeviceCacheSet: h.BlockDeviceCacheSet, + BlockDeviceCacheDirect: h.BlockDeviceCacheDirect, + BlockDeviceCacheNoflush: h.BlockDeviceCacheNoflush, + EnableIOThreads: h.EnableIOThreads, + Msize9p: h.msize9p(), + UseVSock: useVSock, + HotplugVFIOOnRootBus: h.HotplugVFIOOnRootBus, + DisableVhostNet: h.DisableVhostNet, + GuestHookPath: h.guestHookPath(), }, nil } @@ -538,27 +544,30 @@ func initConfig() (config oci.RuntimeConfig, err error) { var defaultAgentConfig interface{} defaultHypervisorConfig := vc.HypervisorConfig{ - HypervisorPath: defaultHypervisorPath, - KernelPath: defaultKernelPath, - ImagePath: defaultImagePath, - InitrdPath: defaultInitrdPath, - FirmwarePath: defaultFirmwarePath, - MachineAccelerators: defaultMachineAccelerators, - HypervisorMachineType: defaultMachineType, - NumVCPUs: defaultVCPUCount, - DefaultMaxVCPUs: defaultMaxVCPUCount, - MemorySize: defaultMemSize, - DefaultBridges: defaultBridgesCount, - MemPrealloc: defaultEnableMemPrealloc, - HugePages: defaultEnableHugePages, - Mlock: !defaultEnableSwap, - Debug: defaultEnableDebug, - DisableNestingChecks: defaultDisableNestingChecks, - BlockDeviceDriver: defaultBlockDeviceDriver, - EnableIOThreads: defaultEnableIOThreads, - Msize9p: defaultMsize9p, - HotplugVFIOOnRootBus: defaultHotplugVFIOOnRootBus, - GuestHookPath: defaultGuestHookPath, + HypervisorPath: defaultHypervisorPath, + KernelPath: defaultKernelPath, + ImagePath: defaultImagePath, + InitrdPath: defaultInitrdPath, + FirmwarePath: defaultFirmwarePath, + MachineAccelerators: defaultMachineAccelerators, + HypervisorMachineType: defaultMachineType, + NumVCPUs: defaultVCPUCount, + DefaultMaxVCPUs: defaultMaxVCPUCount, + MemorySize: defaultMemSize, + DefaultBridges: defaultBridgesCount, + MemPrealloc: defaultEnableMemPrealloc, + HugePages: defaultEnableHugePages, + Mlock: !defaultEnableSwap, + Debug: defaultEnableDebug, + DisableNestingChecks: defaultDisableNestingChecks, + BlockDeviceDriver: defaultBlockDeviceDriver, + BlockDeviceCacheSet: defaultBlockDeviceCacheSet, + BlockDeviceCacheDirect: defaultBlockDeviceCacheDirect, + BlockDeviceCacheNoflush: defaultBlockDeviceCacheNoflush, + EnableIOThreads: defaultEnableIOThreads, + Msize9p: defaultMsize9p, + HotplugVFIOOnRootBus: defaultHotplugVFIOOnRootBus, + GuestHookPath: defaultGuestHookPath, } err = config.InterNetworkModel.SetModel(defaultInterNetworkingModel) diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index 33d21aa8f5..0857dad900 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -206,6 +206,17 @@ type HypervisorConfig struct { // it will be used for the sandbox's kernel path instead of KernelPath. customAssets map[assetType]*asset + // BlockDeviceCacheSet specifies cache-related options will be set to block devices or not. + BlockDeviceCacheSet bool + + // BlockDeviceCacheDirect specifies cache-related options for block devices. + // Denotes whether use of O_DIRECT (bypass the host page cache) is enabled. + BlockDeviceCacheDirect bool + + // BlockDeviceCacheNoflush specifies cache-related options for block devices. + // Denotes whether flush requests for the device are ignored. + BlockDeviceCacheNoflush bool + // DisableBlockDeviceUse disallows a block device from being used. DisableBlockDeviceUse bool diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 25b29e6ac9..61f305ee11 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -736,7 +736,12 @@ func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error devID := "virtio-" + drive.ID if op == addDevice { - if err := q.qmpMonitorCh.qmp.ExecuteBlockdevAdd(q.qmpMonitorCh.ctx, drive.File, drive.ID); err != nil { + if q.config.BlockDeviceCacheSet { + err = q.qmpMonitorCh.qmp.ExecuteBlockdevAddWithCache(q.qmpMonitorCh.ctx, drive.File, drive.ID, q.config.BlockDeviceCacheDirect, q.config.BlockDeviceCacheNoflush) + } else { + err = q.qmpMonitorCh.qmp.ExecuteBlockdevAdd(q.qmpMonitorCh.ctx, drive.File, drive.ID) + } + if err != nil { return err }