Skip to content

Commit 86bee9e

Browse files
author
Fabiano Rosas
committed
migration: Add more error handling to analyze-migration.py
The analyze-migration script was seen failing in s390x in misterious ways. It seems we're reaching the VMSDFieldStruct constructor without any fields, which would indicate an empty .subsection entry, a VMSTATE_STRUCT with no fields or a vmsd with no fields. We don't have any of those, at least not without the unmigratable flag set, so this should never happen. Add some debug statements so that we can see what's going on the next time the issue happens. Reviewed-by: Peter Xu <[email protected]> Message-Id: <[email protected]> Signed-off-by: Fabiano Rosas <[email protected]>
1 parent 8597af7 commit 86bee9e

File tree

1 file changed

+44
-29
lines changed

1 file changed

+44
-29
lines changed

scripts/analyze-migration.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@ def __init__(self, desc, file):
429429
super(VMSDFieldStruct, self).__init__(desc, file)
430430
self.data = collections.OrderedDict()
431431

432+
if 'fields' not in self.desc['struct']:
433+
raise Exception("No fields in struct. VMSD:\n%s" % self.desc)
434+
432435
# When we see compressed array elements, unfold them here
433436
new_fields = []
434437
for field in self.desc['struct']['fields']:
@@ -477,6 +480,10 @@ def read(self):
477480
raise Exception("Subsection %s not found at offset %x" % ( subsection['vmsd_name'], self.file.tell()))
478481
name = self.file.readstr()
479482
version_id = self.file.read32()
483+
484+
if not subsection:
485+
raise Exception("Empty description for subsection: %s" % name)
486+
480487
self.data[name] = VMSDSection(self.file, version_id, subsection, (name, 0))
481488
self.data[name].read()
482489

@@ -574,10 +581,13 @@ def __init__(self, filename):
574581
}
575582
self.filename = filename
576583
self.vmsd_desc = None
584+
self.vmsd_json = ""
577585

578-
def read(self, desc_only = False, dump_memory = False, write_memory = False):
586+
def read(self, desc_only = False, dump_memory = False,
587+
write_memory = False):
579588
# Read in the whole file
580589
file = MigrationFile(self.filename)
590+
self.vmsd_json = file.read_migration_debug_json()
581591

582592
# File magic
583593
data = file.read32()
@@ -635,9 +645,11 @@ def read(self, desc_only = False, dump_memory = False, write_memory = False):
635645
file.close()
636646

637647
def load_vmsd_json(self, file):
638-
vmsd_json = file.read_migration_debug_json()
639-
self.vmsd_desc = json.loads(vmsd_json, object_pairs_hook=collections.OrderedDict)
648+
self.vmsd_desc = json.loads(self.vmsd_json,
649+
object_pairs_hook=collections.OrderedDict)
640650
for device in self.vmsd_desc['devices']:
651+
if 'fields' not in device:
652+
raise Exception("vmstate for device %s has no fields" % device['name'])
641653
key = (device['name'], device['instance_id'])
642654
value = ( VMSDSection, device )
643655
self.section_classes[key] = value
@@ -666,31 +678,34 @@ def default(self, o):
666678

667679
jsonenc = JSONEncoder(indent=4, separators=(',', ': '))
668680

669-
if args.extract:
670-
dump = MigrationDump(args.file)
681+
if not any([args.extract, args.dump == "state", args.dump == "desc"]):
682+
raise Exception("Please specify either -x, -d state or -d desc")
671683

672-
dump.read(desc_only = True)
673-
print("desc.json")
674-
f = open("desc.json", "w")
675-
f.truncate()
676-
f.write(jsonenc.encode(dump.vmsd_desc))
677-
f.close()
678-
679-
dump.read(write_memory = True)
680-
dict = dump.getDict()
681-
print("state.json")
682-
f = open("state.json", "w")
683-
f.truncate()
684-
f.write(jsonenc.encode(dict))
685-
f.close()
686-
elif args.dump == "state":
687-
dump = MigrationDump(args.file)
688-
dump.read(dump_memory = args.memory)
689-
dict = dump.getDict()
690-
print(jsonenc.encode(dict))
691-
elif args.dump == "desc":
684+
try:
692685
dump = MigrationDump(args.file)
693-
dump.read(desc_only = True)
694-
print(jsonenc.encode(dump.vmsd_desc))
695-
else:
696-
raise Exception("Please specify either -x, -d state or -d desc")
686+
687+
if args.extract:
688+
dump.read(desc_only = True)
689+
690+
print("desc.json")
691+
f = open("desc.json", "w")
692+
f.truncate()
693+
f.write(jsonenc.encode(dump.vmsd_desc))
694+
f.close()
695+
696+
dump.read(write_memory = True)
697+
dict = dump.getDict()
698+
print("state.json")
699+
f = open("state.json", "w")
700+
f.truncate()
701+
f.write(jsonenc.encode(dict))
702+
f.close()
703+
elif args.dump == "state":
704+
dump.read(dump_memory = args.memory)
705+
dict = dump.getDict()
706+
print(jsonenc.encode(dict))
707+
elif args.dump == "desc":
708+
dump.read(desc_only = True)
709+
print(jsonenc.encode(dump.vmsd_desc))
710+
except Exception:
711+
raise Exception("Full JSON dump:\n%s", dump.vmsd_json)

0 commit comments

Comments
 (0)