Add support to the new migration features: - 'file' transport; - 'fixed-ram' stream format capability; - 'direct-io' parameter;
Usage: $ ./guestperf.py --binary <path/to/qemu> --initrd <path/to/initrd-stress.img> \ --transport file --dst-file migfile --multifd --fixed-ram \ --multifd-channels 4 --output fixed-ram.json --verbose Signed-off-by: Fabiano Rosas <faro...@suse.de> --- tests/migration/guestperf/engine.py | 38 +++++++++++++++++++++++++-- tests/migration/guestperf/scenario.py | 14 ++++++++-- tests/migration/guestperf/shell.py | 18 +++++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py index e69d16a62c..a465336184 100644 --- a/tests/migration/guestperf/engine.py +++ b/tests/migration/guestperf/engine.py @@ -35,10 +35,11 @@ class Engine(object): def __init__(self, binary, dst_host, kernel, initrd, transport="tcp", - sleep=15, verbose=False, debug=False): + sleep=15, verbose=False, debug=False, dst_file="/tmp/migfile"): self._binary = binary # Path to QEMU binary self._dst_host = dst_host # Hostname of target host + self._dst_file = dst_file # Path to file (for file transport) self._kernel = kernel # Path to kernel image self._initrd = initrd # Path to stress initrd self._transport = transport # 'unix' or 'tcp' or 'rdma' @@ -203,6 +204,23 @@ def _migrate(self, hardware, scenario, src, dst, connect_uri): resp = dst.command("migrate-set-parameters", multifd_channels=scenario._multifd_channels) + if scenario._fixed_ram: + resp = src.command("migrate-set-capabilities", + capabilities = [ + { "capability": "fixed-ram", + "state": True } + ]) + resp = dst.command("migrate-set-capabilities", + capabilities = [ + { "capability": "fixed-ram", + "state": True } + ]) + + if scenario._direct_io: + resp = src.command("migrate-set-parameters", + direct_io=scenario._direct_io) + + resp = src.command("migrate", uri=connect_uri) post_copy = False @@ -233,6 +251,11 @@ def _migrate(self, hardware, scenario, src, dst, connect_uri): progress_history.append(progress) if progress._status == "completed": + if connect_uri[0:5] == "file:": + if self._verbose: + print("Migrating incoming") + dst.command("migrate-incoming", uri=connect_uri) + if self._verbose: print("Sleeping %d seconds for final guest workload run" % self._sleep) sleep_secs = self._sleep @@ -357,7 +380,11 @@ def _get_dst_args(self, hardware, uri): if self._dst_host != "localhost": tunnelled = True argv = self._get_common_args(hardware, tunnelled) - return argv + ["-incoming", uri] + + incoming = ["-incoming", uri] + if uri[0:5] == "file:": + incoming = ["-incoming", "defer"] + return argv + incoming @staticmethod def _get_common_wrapper(cpu_bind, mem_bind): @@ -417,6 +444,10 @@ def run(self, hardware, scenario, result_dir=os.getcwd()): os.remove(monaddr) except: pass + elif self._transport == "file": + if self._dst_host != "localhost": + raise Exception("Use unix migration transport for non-local host") + uri = "file:%s" % self._dst_file if self._dst_host != "localhost": dstmonaddr = ("localhost", 9001) @@ -453,6 +484,9 @@ def run(self, hardware, scenario, result_dir=os.getcwd()): if self._dst_host == "localhost" and os.path.exists(dstmonaddr): os.remove(dstmonaddr) + if uri[0:5] == "file:" and os.path.exists(uri[5:]): + os.remove(uri[5:]) + if self._verbose: print("Finished migration") diff --git a/tests/migration/guestperf/scenario.py b/tests/migration/guestperf/scenario.py index de70d9b2f5..29b6af41ac 100644 --- a/tests/migration/guestperf/scenario.py +++ b/tests/migration/guestperf/scenario.py @@ -30,7 +30,8 @@ def __init__(self, name, auto_converge=False, auto_converge_step=10, compression_mt=False, compression_mt_threads=1, compression_xbzrle=False, compression_xbzrle_cache=10, - multifd=False, multifd_channels=2): + multifd=False, multifd_channels=2, + fixed_ram=False, direct_io=False): self._name = name @@ -60,6 +61,11 @@ def __init__(self, name, self._multifd = multifd self._multifd_channels = multifd_channels + self._fixed_ram = fixed_ram + + self._direct_io = direct_io + + def serialize(self): return { "name": self._name, @@ -79,6 +85,8 @@ def serialize(self): "compression_xbzrle_cache": self._compression_xbzrle_cache, "multifd": self._multifd, "multifd_channels": self._multifd_channels, + "fixed_ram": self._fixed_ram, + "direct_io": self._direct_io, } @classmethod @@ -100,4 +108,6 @@ def deserialize(cls, data): data["compression_xbzrle"], data["compression_xbzrle_cache"], data["multifd"], - data["multifd_channels"]) + data["multifd_channels"], + data["fixed_ram"], + data["direct_io"]) diff --git a/tests/migration/guestperf/shell.py b/tests/migration/guestperf/shell.py index 8a809e3dda..0cb402adce 100644 --- a/tests/migration/guestperf/shell.py +++ b/tests/migration/guestperf/shell.py @@ -48,6 +48,7 @@ def __init__(self): parser.add_argument("--kernel", dest="kernel", default="/boot/vmlinuz-%s" % platform.release()) parser.add_argument("--initrd", dest="initrd", default="tests/migration/initrd-stress.img") parser.add_argument("--transport", dest="transport", default="unix") + parser.add_argument("--dst-file", dest="dst_file") # Hardware args @@ -71,7 +72,8 @@ def get_engine(self, args): transport=args.transport, sleep=args.sleep, debug=args.debug, - verbose=args.verbose) + verbose=args.verbose, + dst_file=args.dst_file) def get_hardware(self, args): def split_map(value): @@ -127,6 +129,13 @@ def __init__(self): parser.add_argument("--multifd-channels", dest="multifd_channels", default=2, type=int) + parser.add_argument("--fixed-ram", dest="fixed_ram", default=False, + action="store_true") + + parser.add_argument("--direct-io", dest="direct_io", default=False, + action="store_true") + + def get_scenario(self, args): return Scenario(name="perfreport", downtime=args.downtime, @@ -150,7 +159,12 @@ def get_scenario(self, args): compression_xbzrle_cache=args.compression_xbzrle_cache, multifd=args.multifd, - multifd_channels=args.multifd_channels) + multifd_channels=args.multifd_channels, + + fixed_ram=args.fixed_ram, + + direct_io=args.direct_io) + def run(self, argv): args = self._parser.parse_args(argv) -- 2.35.3