tests/migration/guestperf: Add file, fixed-ram and direct-io support

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 <farosas@suse.de>
This commit is contained in:
Fabiano Rosas
2023-03-29 11:17:37 -03:00
parent 6179e52fed
commit 38e85e9320
3 changed files with 65 additions and 6 deletions

View File

@@ -35,10 +35,11 @@ from qemu.machine import QEMUMachine
class Engine(object): class Engine(object):
def __init__(self, binary, dst_host, kernel, initrd, transport="tcp", 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._binary = binary # Path to QEMU binary
self._dst_host = dst_host # Hostname of target host 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._kernel = kernel # Path to kernel image
self._initrd = initrd # Path to stress initrd self._initrd = initrd # Path to stress initrd
self._transport = transport # 'unix' or 'tcp' or 'rdma' self._transport = transport # 'unix' or 'tcp' or 'rdma'
@@ -203,6 +204,23 @@ class Engine(object):
resp = dst.command("migrate-set-parameters", resp = dst.command("migrate-set-parameters",
multifd_channels=scenario._multifd_channels) 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) resp = src.command("migrate", uri=connect_uri)
post_copy = False post_copy = False
@@ -233,6 +251,12 @@ class Engine(object):
progress_history.append(progress) progress_history.append(progress)
if progress._status == "completed": if progress._status == "completed":
print("Completed")
if connect_uri[0:5] == "file:":
if self._verbose:
print("Migrating incoming")
dst.command("migrate-incoming", uri=connect_uri)
if self._verbose: if self._verbose:
print("Sleeping %d seconds for final guest workload run" % self._sleep) print("Sleeping %d seconds for final guest workload run" % self._sleep)
sleep_secs = self._sleep sleep_secs = self._sleep
@@ -357,7 +381,11 @@ class Engine(object):
if self._dst_host != "localhost": if self._dst_host != "localhost":
tunnelled = True tunnelled = True
argv = self._get_common_args(hardware, tunnelled) 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 @staticmethod
def _get_common_wrapper(cpu_bind, mem_bind): def _get_common_wrapper(cpu_bind, mem_bind):
@@ -417,6 +445,10 @@ class Engine(object):
os.remove(monaddr) os.remove(monaddr)
except: except:
pass 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": if self._dst_host != "localhost":
dstmonaddr = ("localhost", 9001) dstmonaddr = ("localhost", 9001)
@@ -453,6 +485,9 @@ class Engine(object):
if self._dst_host == "localhost" and os.path.exists(dstmonaddr): if self._dst_host == "localhost" and os.path.exists(dstmonaddr):
os.remove(dstmonaddr) os.remove(dstmonaddr)
if uri[0:5] == "file:" and os.path.exists(uri[5:]):
os.remove(uri[5:])
if self._verbose: if self._verbose:
print("Finished migration") print("Finished migration")

View File

@@ -30,7 +30,8 @@ class Scenario(object):
auto_converge=False, auto_converge_step=10, auto_converge=False, auto_converge_step=10,
compression_mt=False, compression_mt_threads=1, compression_mt=False, compression_mt_threads=1,
compression_xbzrle=False, compression_xbzrle_cache=10, 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 self._name = name
@@ -60,6 +61,11 @@ class Scenario(object):
self._multifd = multifd self._multifd = multifd
self._multifd_channels = multifd_channels self._multifd_channels = multifd_channels
self._fixed_ram = fixed_ram
self._direct_io = direct_io
def serialize(self): def serialize(self):
return { return {
"name": self._name, "name": self._name,
@@ -79,6 +85,8 @@ class Scenario(object):
"compression_xbzrle_cache": self._compression_xbzrle_cache, "compression_xbzrle_cache": self._compression_xbzrle_cache,
"multifd": self._multifd, "multifd": self._multifd,
"multifd_channels": self._multifd_channels, "multifd_channels": self._multifd_channels,
"fixed_ram": self._fixed_ram,
"direct_io": self._direct_io,
} }
@classmethod @classmethod
@@ -100,4 +108,6 @@ class Scenario(object):
data["compression_xbzrle"], data["compression_xbzrle"],
data["compression_xbzrle_cache"], data["compression_xbzrle_cache"],
data["multifd"], data["multifd"],
data["multifd_channels"]) data["multifd_channels"],
data["fixed_ram"],
data["direct_io"])

View File

@@ -48,6 +48,7 @@ class BaseShell(object):
parser.add_argument("--kernel", dest="kernel", default="/boot/vmlinuz-%s" % platform.release()) 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("--initrd", dest="initrd", default="tests/migration/initrd-stress.img")
parser.add_argument("--transport", dest="transport", default="unix") parser.add_argument("--transport", dest="transport", default="unix")
parser.add_argument("--dst-file", dest="dst_file")
# Hardware args # Hardware args
@@ -71,7 +72,8 @@ class BaseShell(object):
transport=args.transport, transport=args.transport,
sleep=args.sleep, sleep=args.sleep,
debug=args.debug, debug=args.debug,
verbose=args.verbose) verbose=args.verbose,
dst_file=args.dst_file)
def get_hardware(self, args): def get_hardware(self, args):
def split_map(value): def split_map(value):
@@ -127,6 +129,13 @@ class Shell(BaseShell):
parser.add_argument("--multifd-channels", dest="multifd_channels", parser.add_argument("--multifd-channels", dest="multifd_channels",
default=2, type=int) 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): def get_scenario(self, args):
return Scenario(name="perfreport", return Scenario(name="perfreport",
downtime=args.downtime, downtime=args.downtime,
@@ -150,7 +159,12 @@ class Shell(BaseShell):
compression_xbzrle_cache=args.compression_xbzrle_cache, compression_xbzrle_cache=args.compression_xbzrle_cache,
multifd=args.multifd, 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): def run(self, argv):
args = self._parser.parse_args(argv) args = self._parser.parse_args(argv)