diff --git a/docs/Home.md b/docs/Home.md index f76dac4c..44e24017 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -92,6 +92,8 @@ Usage: auto_hck.rb test [test options] --fs-test-image-format Filesystem test image format (qcow2/raw). Default is qcow2. Has effect only when testing storage drivers. + --aio-native Use aio=native for virtual disks (forces cache=none, cannot combine with --aio-threads) + --aio-threads Use aio=threads for virtual disks (forces cache=none, cannot combine with --aio-native) --extensions List of extensions for run test --net-test-speed diff --git a/lib/cli.rb b/lib/cli.rb index b78b0d1d..bbb60dab 100644 --- a/lib/cli.rb +++ b/lib/cli.rb @@ -111,6 +111,19 @@ class CliTestOptions < T::Struct prop :latest_session, T::Boolean, default: false prop :category, T.nilable(String) prop :testcase, T.nilable(String) + prop :drive_aio_state, T.nilable(String) + + def aio_native=(value) + raise(AutoHCKError, '--aio-native cannot be combined with --aio-threads') if value && drive_aio_state == 'threads' + + self.drive_aio_state = 'native' if value + end + + def aio_threads=(value) + raise(AutoHCKError, '--aio-threads cannot be combined with --aio-native') if value && drive_aio_state == 'native' + + self.drive_aio_state = 'threads' if value + end def create_parser OptionParser.new do |parser| @@ -277,6 +290,14 @@ def define_options(parser) parser.on('--testcase ', String, 'Run specific functest test cases, comma-separated (used with functest engine)', &method(:testcase=)) + + parser.on('--aio-native', TrueClass, + 'Use aio=native for virtual disks (forces cache=none, cannot combine with --aio-threads)', + &method(:aio_native=)) + + parser.on('--aio-threads', TrueClass, + 'Use aio=threads for virtual disks (forces cache=none, cannot combine with --aio-native)', + &method(:aio_threads=)) end # rubocop:enable Metrics/AbcSize, Metrics/MethodLength end diff --git a/lib/setupmanagers/qemuhck/qemu_machine.rb b/lib/setupmanagers/qemuhck/qemu_machine.rb index 89baa210..aae0db9e 100644 --- a/lib/setupmanagers/qemuhck/qemu_machine.rb +++ b/lib/setupmanagers/qemuhck/qemu_machine.rb @@ -4,6 +4,7 @@ # AutoHCK module module AutoHCK # QemuMachine class + # rubocop:disable Metrics/ClassLength class QemuMachine extend T::Sig extend AutoHCK::AutoloadExtension @@ -305,10 +306,29 @@ def init_config @states_config = Json.read_json(STATES_JSON, @logger) @states_config.each { |name, state| apply_state name, state } + apply_drive_aio_state + validate_drive_aio_state apply_cpu_options_config end + def apply_drive_aio_state + case option_config('drive_aio_state') + when 'native' then @drive_cache_options << ',cache=none,aio=native' + when 'threads' then @drive_cache_options << ',cache=none,aio=threads' + end + end + + # cache=unsafe has cache.direct=off, which conflicts with the cache=none (cache.direct=on) + # forced by drive_aio_state above, so QEMU would fail to start with both applied at once. + def validate_drive_aio_state + return unless %w[native threads].include?(option_config('drive_aio_state')) + return unless option_config('drive_unsafe_cache_state') + + raise QemuHCKError, "drive_aio_state=#{option_config('drive_aio_state')} is incompatible with " \ + 'drive_unsafe_cache_state=true (both set a conflicting cache= mode)' + end + def apply_cpu_options_config extra = option_config('cpu_options') return if extra.nil? || extra.empty? @@ -794,4 +814,5 @@ def run(scope, run_opts = nil) end end end + # rubocop:enable Metrics/ClassLength end diff --git a/lib/setupmanagers/qemuhck/qemuhck.rb b/lib/setupmanagers/qemuhck/qemuhck.rb index b9f25c36..50482fb9 100644 --- a/lib/setupmanagers/qemuhck/qemuhck.rb +++ b/lib/setupmanagers/qemuhck/qemuhck.rb @@ -108,6 +108,7 @@ def client_vm_common_options 'boot_device' => test_opt.boot_device, 'fs_test_image_format' => test_opt.fs_test_image_format, 'net_test_speed' => test_opt.net_test_speed, + 'drive_aio_state' => test_opt.drive_aio_state, 'ctrl_net_device' => common.client_ctrl_net_dev }.compact end