diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2023-10-17 10:06:20 -0400 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2023-10-17 10:06:21 -0400 |
commit | ec6f9f135d5e5596ab0258da2ddd048f1fd8c359 (patch) | |
tree | d6805bf8f756fcad1dc248dd49c1303cb9b35a5a /scripts | |
parent | 0193b3bc05fe45860849b11958431e53feec7516 (diff) | |
parent | 967e3889874b1116090a60c0cb43157130bdbd16 (diff) |
Merge tag 'migration-20231017-pull-request' of https://gitlab.com/juan.quintela/qemu into staging
Migration Pull request (20231017)
Hi
Same that yesterday one, except:
- rebased to latest (clean rebase)
- fixed 64 bits read on big endian host
CI: https://gitlab.com/juan.quintela/qemu/-/pipelines/1039214198
Please, apply.
# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmUuReUACgkQ9IfvGFhy
# 1yO+FQ/+Nx2botbrUVJb3vLeG6f+x5xeWJjB0boOqhk7227cKmAA33Oqwx5l4UtL
# oLOHA6P4ThqacpaluGOMMp44BSr/jOMDC/HUDVJtSplTD+droPiklIIGUfYScLbA
# oYx6lXfSB2jMpSuSU19STbjwBRvd4bjJix3zDGwEIgXYqYt0tY0FY/nnGTmImnM1
# KDjRerf1lg4Rt0vvwg7I0onIDvh3CKX26Sj5a3wSRaLoocUe3jpsuBNH7MMqroHs
# WpocBIsLiBAf/CbeLZsQlhbVeOi1R+kSAR5hDPvvJCPWHIrd2wf8+3NXjcFepb7d
# M4wE2jLjCvHhzwYwSc0ir4n74jwD22IirEPQs8ONHrjLCb5VoBKYV5bqsFUHF55N
# SbFvcZIzJFiOm2anEWiiqiNTLtYAdQCKtUvbyJ7Mq4ck6icIInLdX9zrm4voofYJ
# 02lX/IIGlT3C3dGSz09LBoJ6E82zmQWNHmov8A90+3RYvMF9uSpxi0z40lhj6jWC
# 6Q2AHxrJJ040ZboeOfJQG78BtvZ/9PQ2ORhJ3ceRDND4kSTDtfe/TSNAZ3thM33y
# Sv99o+F/HaqrKnxK8eTJrvIEWxojDu3lnqJERWAm2AOxTnQ+6mgGtsCfLEdrv5D1
# xVsY2QczB1quRjaU2ml/7Cxe4Q1urTtfl82IEXGded6UL+cmF/I=
# =br93
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 17 Oct 2023 04:29:25 EDT
# gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full]
# gpg: aka "Juan Quintela <quintela@trasno.org>" [full]
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723
* tag 'migration-20231017-pull-request' of https://gitlab.com/juan.quintela/qemu: (38 commits)
migration/multifd: Clarify Error usage in multifd_channel_connect
migration/multifd: Unify multifd_send_thread error paths
migration/multifd: Remove direct "socket" references
migration/ram: Merge save_zero_page functions
migration/ram: Move xbzrle zero page handling into save_zero_page
migration/ram: Stop passing QEMUFile around in save_zero_page
migration/ram: Remove RAMState from xbzrle_cache_zero_page
migration/ram: Refactor precopy ram loading code
multifd: reset next_packet_len after sending pages
multifd: fix counters in multifd_send_thread
migration: check for rate_limit_max for RATE_LIMIT_DISABLED
migration: Improve json and formatting
migration/rdma: Remove all "ret" variables that are used only once
migration/rdma: Declare for index variables local
migration/rdma: Use i as for index instead of idx
migration/rdma: Check sooner if we are in postcopy for save_page()
migration/rdma: Remove qemu_ prefix from exported functions
migration/rdma: Move rdma constants from qemu-file.h to rdma.h
qemu-file: Remove QEMUFileHooks
migration/rdma: Create rdma_control_save_page()
...
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/analyze-migration.py | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py index 082424558b..de506cb8bf 100755 --- a/scripts/analyze-migration.py +++ b/scripts/analyze-migration.py @@ -38,13 +38,13 @@ class MigrationFile(object): self.file = open(self.filename, "rb") def read64(self): - return int.from_bytes(self.file.read(8), byteorder='big', signed=True) + return int.from_bytes(self.file.read(8), byteorder='big', signed=False) def read32(self): - return int.from_bytes(self.file.read(4), byteorder='big', signed=True) + return int.from_bytes(self.file.read(4), byteorder='big', signed=False) def read16(self): - return int.from_bytes(self.file.read(2), byteorder='big', signed=True) + return int.from_bytes(self.file.read(2), byteorder='big', signed=False) def read8(self): return int.from_bytes(self.file.read(1), byteorder='big', signed=True) @@ -123,6 +123,7 @@ class RamSection(object): self.TARGET_PAGE_SIZE = ramargs['page_size'] self.dump_memory = ramargs['dump_memory'] self.write_memory = ramargs['write_memory'] + self.ignore_shared = ramargs['ignore_shared'] self.sizeinfo = collections.OrderedDict() self.data = collections.OrderedDict() self.data['section sizes'] = self.sizeinfo @@ -169,6 +170,8 @@ class RamSection(object): f.truncate(0) f.truncate(len) self.files[self.name] = f + if self.ignore_shared: + mr_addr = self.file.read64() flags &= ~self.RAM_SAVE_FLAG_MEM_SIZE if flags & self.RAM_SAVE_FLAG_COMPRESS: @@ -261,12 +264,41 @@ class HTABSection(object): class ConfigurationSection(object): - def __init__(self, file): + def __init__(self, file, desc): self.file = file + self.desc = desc + self.caps = [] + + def parse_capabilities(self, vmsd_caps): + if not vmsd_caps: + return + + ncaps = vmsd_caps.data['caps_count'].data + self.caps = vmsd_caps.data['capabilities'] + + if type(self.caps) != list: + self.caps = [self.caps] + + if len(self.caps) != ncaps: + raise Exception("Number of capabilities doesn't match " + "caps_count field") + + def has_capability(self, cap): + return any([str(c) == cap for c in self.caps]) def read(self): - name_len = self.file.read32() - name = self.file.readstr(len = name_len) + if self.desc: + version_id = self.desc['version'] + section = VMSDSection(self.file, version_id, self.desc, + 'configuration') + section.read() + self.parse_capabilities( + section.data.get("configuration/capabilities")) + else: + # backward compatibility for older streams that don't have + # the configuration section in the json + name_len = self.file.read32() + name = self.file.readstr(len = name_len) class VMSDFieldGeneric(object): def __init__(self, desc, file): @@ -288,6 +320,23 @@ class VMSDFieldGeneric(object): self.data = self.file.readvar(size) return self.data +class VMSDFieldCap(object): + def __init__(self, desc, file): + self.file = file + self.desc = desc + self.data = "" + + def __repr__(self): + return self.data + + def __str__(self): + return self.data + + def read(self): + len = self.file.read8() + self.data = self.file.readstr(len) + + class VMSDFieldInt(VMSDFieldGeneric): def __init__(self, desc, file): super(VMSDFieldInt, self).__init__(desc, file) @@ -462,6 +511,7 @@ vmsd_field_readers = { "unused_buffer" : VMSDFieldGeneric, "bitmap" : VMSDFieldGeneric, "struct" : VMSDFieldStruct, + "capability": VMSDFieldCap, "unknown" : VMSDFieldGeneric, } @@ -525,6 +575,7 @@ class MigrationDump(object): ramargs['page_size'] = self.vmsd_desc['page_size'] ramargs['dump_memory'] = dump_memory ramargs['write_memory'] = write_memory + ramargs['ignore_shared'] = False self.section_classes[('ram',0)][1] = ramargs while True: @@ -532,8 +583,10 @@ class MigrationDump(object): if section_type == self.QEMU_VM_EOF: break elif section_type == self.QEMU_VM_CONFIGURATION: - section = ConfigurationSection(file) + config_desc = self.vmsd_desc.get('configuration') + section = ConfigurationSection(file, config_desc) section.read() + ramargs['ignore_shared'] = section.has_capability('x-ignore-shared') elif section_type == self.QEMU_VM_SECTION_START or section_type == self.QEMU_VM_SECTION_FULL: section_id = file.read32() name = file.readstr() |