#!/usr/bin/env python3
#
# Compares vmstate information stored in JSON format, obtained from
# the -dump-vmstate QEMU command.
#
# Copyright 2014 Amit Shah <amit.shah@redhat.com>
# Copyright 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.

import argparse
import json
import sys

# Count the number of errors found
taint = 0

def bump_taint():
    global taint

    # Ensure we don't wrap around or reset to 0 -- the shell only has
    # an 8-bit return value.
    if taint < 255:
        taint = taint + 1


def check_fields_match(name, s_field, d_field):
    if s_field == d_field:
        return True

    # Some fields changed names between qemu versions.  This list
    # is used to allow such changes in each section / description.
    changed_names = {
        'apic': ['timer', 'timer_expiry'],
        'e1000': ['dev', 'parent_obj'],
        'ehci': ['dev', 'pcidev'],
        'I440FX': ['dev', 'parent_obj'],
        'ich9_ahci': ['card', 'parent_obj'],
        'ich9-ahci': ['ahci', 'ich9_ahci'],
        'ioh3420': ['PCIDevice', 'PCIEDevice'],
        'ioh-3240-express-root-port': ['port.br.dev',
                                       'parent_obj.parent_obj.parent_obj',
                                       'port.br.dev.exp.aer_log',
                                'parent_obj.parent_obj.parent_obj.exp.aer_log'],
        'cirrus_vga': ['hw_cursor_x', 'vga.hw_cursor_x',
                       'hw_cursor_y', 'vga.hw_cursor_y'],
        'lsiscsi': ['dev', 'parent_obj'],
        'mch': ['d', 'parent_obj'],
        'pci_bridge': ['bridge.dev', 'parent_obj', 'bridge.dev.shpc', 'shpc'],
        'pcnet': ['pci_dev', 'parent_obj'],
        'PIIX3': ['pci_irq_levels', 'pci_irq_levels_vmstate'],
        'piix4_pm': ['dev', 'parent_obj', 'pci0_status',
                     'acpi_pci_hotplug.acpi_pcihp_pci_status[0x0]',
                     'pm1a.sts', 'ar.pm1.evt.sts', 'pm1a.en', 'ar.pm1.evt.en',
                     'pm1_cnt.cnt', 'ar.pm1.cnt.cnt',
                     'tmr.timer', 'ar.tmr.timer',
                     'tmr.overflow_time', 'ar.tmr.overflow_time',
                     'gpe', 'ar.gpe'],
        'rtl8139': ['dev', 'parent_obj'],
        'qxl': ['num_surfaces', 'ssd.num_surfaces'],
        'usb-ccid': ['abProtocolDataStructure', 'abProtocolDataStructure.data'],
        'usb-host': ['dev', 'parent_obj'],
        'usb-mouse': ['usb-ptr-queue', 'HIDPointerEventQueue'],
        'usb-tablet': ['usb-ptr-queue', 'HIDPointerEventQueue'],
        'vmware_vga': ['card', 'parent_obj'],
        'vmware_vga_internal': ['depth', 'new_depth'],
        'xhci': ['pci_dev', 'parent_obj'],
        'x3130-upstream': ['PCIDevice', 'PCIEDevice'],
        'xio3130-express-downstream-port': ['port.br.dev',
                                            'parent_obj.parent_obj.parent_obj',
                                            'port.br.dev.exp.aer_log',
                                'parent_obj.parent_obj.parent_obj.exp.aer_log'],
        'xio3130-downstream': ['PCIDevice', 'PCIEDevice'],
        'xio3130-express-upstream-port': ['br.dev', 'parent_obj.parent_obj',
                                          'br.dev.exp.aer_log',
                                          'parent_obj.parent_obj.exp.aer_log'],
        'spapr_pci': ['dma_liobn[0]', 'mig_liobn',
                      'mem_win_addr', 'mig_mem_win_addr',
                      'mem_win_size', 'mig_mem_win_size',
                      'io_win_addr', 'mig_io_win_addr',
                      'io_win_size', 'mig_io_win_size'],
    }

    if not name in changed_names:
        return False

    if s_field in changed_names[name] and d_field in changed_names[name]:
        return True

    return False

def get_changed_sec_name(sec):
    # Section names can change -- see commit 292b1634 for an example.
    changes = {
        "ICH9 LPC": "ICH9-LPC",
        "e1000-82540em": "e1000",
    }

    for item in changes:
        if item == sec:
            return changes[item]
        if changes[item] == sec:
            return item
    return ""

def exists_in_substruct(fields, item):
    # Some QEMU versions moved a few fields inside a substruct.  This
    # kept the on-wire format the same.  This function checks if
    # something got shifted inside a substruct.  For example, the
    # change in commit 1f42d22233b4f3d1a2933ff30e8d6a6d9ee2d08f

    if not "Description" in fields:
        return False

    if not "Fields" in fields["Description"]:
        return False

    substruct_fields = fields["Description"]["Fields"]

    if substruct_fields == []:
        return False

    return check_fields_match(fields["Description"]["name"],
                              substruct_fields[0]["field"], item)


def check_fields(src_fields, dest_fields, desc, sec):
    # This function checks for all the fields in a section.  If some
    # fields got embedded into a substruct, this function will also
    # attempt to check inside the substruct.

    d_iter = iter(dest_fields)
    s_iter = iter(src_fields)

    # Using these lists as stacks to store previous value of s_iter
    # and d_iter, so that when time comes to exit out of a substruct,
    # we can go back one level up and continue from where we left off.

    s_iter_list = []
    d_iter_list = []

    advance_src = True
    advance_dest = True
    unused_count = 0

    while True:
        if advance_src:
            try:
                s_item = next(s_iter)
            except StopIteration:
                if s_iter_list == []:
                    break

                s_iter = s_iter_list.pop()
                continue
        else:
            if unused_count == 0:
                # We want to avoid advancing just once -- when entering a
                # dest substruct, or when exiting one.
                advance_src = True

        if advance_dest:
            try:
                d_item = next(d_iter)
            except StopIteration:
                if d_iter_list == []:
                    # We were not in a substruct
                    print("Section \"" + sec + "\",", end=' ')
                    print("Description " + "\"" + desc + "\":", end=' ')
                    print("expected field \"" + s_item["field"] + "\",", end=' ')
                    print("while dest has no further fields")
                    bump_taint()
                    break

                d_iter = d_iter_list.pop()
                advance_src = False
                continue
        else:
            if unused_count == 0:
                advance_dest = True

        if unused_count != 0:
            if advance_dest == False:
                unused_count = unused_count - s_item["size"]
                if unused_count == 0:
                    advance_dest = True
                    continue
                if unused_count < 0:
                    print("Section \"" + sec + "\",", end=' ')
                    print("Description \"" + desc + "\":", end=' ')
                    print("unused size mismatch near \"", end=' ')
                    print(s_item["field"] + "\"")
                    bump_taint()
                    break
                continue

            if advance_src == False:
                unused_count = unused_count - d_item["size"]
                if unused_count == 0:
                    advance_src = True
                    continue
                if unused_count < 0:
                    print("Section \"" + sec + "\",", end=' ')
                    print("Description \"" + desc + "\":", end=' ')
                    print("unused size mismatch near \"", end=' ')
                    print(d_item["field"] + "\"")
                    bump_taint()
                    break
                continue

        if not check_fields_match(desc, s_item["field"], d_item["field"]):
            # Some fields were put in substructs, keeping the
            # on-wire format the same, but breaking static tools
            # like this one.

            # First, check if dest has a new substruct.
            if exists_in_substruct(d_item, s_item["field"]):
                # listiterators don't have a prev() function, so we
                # have to store our current location, descend into the
                # substruct, and ensure we come out as if nothing
                # happened when the substruct is over.
                #
                # Essentially we're opening the substructs that got
                # added which didn't change the wire format.
                d_iter_list.append(d_iter)
                substruct_fields = d_item["Description"]["Fields"]
                d_iter = iter(substruct_fields)
                advance_src = False
                continue

            # Next, check if src has substruct that dest removed
            # (can happen in backward migration: 2.0 -> 1.5)
            if exists_in_substruct(s_item, d_item["field"]):
                s_iter_list.append(s_iter)
                substruct_fields = s_item["Description"]["Fields"]
                s_iter = iter(substruct_fields)
                advance_dest = False
                continue

            if s_item["field"] == "unused" or d_item["field"] == "unused":
                if s_item["size"] == d_item["size"]:
                    continue

                if d_item["field"] == "unused":
                    advance_dest = False
                    unused_count = d_item["size"] - s_item["size"]
                    continue

                if s_item["field"] == "unused":
                    advance_src = False
                    unused_count = s_item["size"] - d_item["size"]
                    continue

            print("Section \"" + sec + "\",", end=' ')
            print("Description \"" + desc + "\":", end=' ')
            print("expected field \"" + s_item["field"] + "\",", end=' ')
            print("got \"" + d_item["field"] + "\"; skipping rest")
            bump_taint()
            break

        check_version(s_item, d_item, sec, desc)

        if not "Description" in s_item:
            # Check size of this field only if it's not a VMSTRUCT entry
            check_size(s_item, d_item, sec, desc, s_item["field"])

        check_description_in_list(s_item, d_item, sec, desc)


def check_subsections(src_sub, dest_sub, desc, sec):
    for s_item in src_sub:
        found = False
        for d_item in dest_sub:
            if s_item["name"] != d_item["name"]:
                continue

            found = True
            check_descriptions(s_item, d_item, sec)

        if not found:
            print("Section \"" + sec + "\", Description \"" + desc + "\":", end=' ')
            print("Subsection \"" + s_item["name"] + "\" not found")
            bump_taint()


def check_description_in_list(s_item, d_item, sec, desc):
    if not "Description" in s_item:
        return

    if not "Description" in d_item:
        print("Section \"" + sec + "\", Description \"" + desc + "\",", end=' ')
        print("Field \"" + s_item["field"] + "\": missing description")
        bump_taint()
        return

    check_descriptions(s_item["Description"], d_item["Description"], sec)


def check_descriptions(src_desc, dest_desc, sec):
    check_version(src_desc, dest_desc, sec, src_desc["name"])

    if not check_fields_match(sec, src_desc["name"], dest_desc["name"]):
        print("Section \"" + sec + "\":", end=' ')
        print("Description \"" + src_desc["name"] + "\"", end=' ')
        print("missing, got \"" + dest_desc["name"] + "\" instead; skipping")
        bump_taint()
        return

    for f in src_desc:
        if not f in dest_desc:
            print("Section \"" + sec + "\"", end=' ')
            print("Description \"" + src_desc["name"] + "\":", end=' ')
            print("Entry \"" + f + "\" missing")
            bump_taint()
            continue

        if f == 'Fields':
            check_fields(src_desc[f], dest_desc[f], src_desc["name"], sec)

        if f == 'Subsections':
            check_subsections(src_desc[f], dest_desc[f], src_desc["name"], sec)


def check_version(s, d, sec, desc=None):
    if s["version_id"] > d["version_id"]:
        print("Section \"" + sec + "\"", end=' ')
        if desc:
            print("Description \"" + desc + "\":", end=' ')
        print("version error:", s["version_id"], ">", d["version_id"])
        bump_taint()

    if not "minimum_version_id" in d:
        return

    if s["version_id"] < d["minimum_version_id"]:
        print("Section \"" + sec + "\"", end=' ')
        if desc:
            print("Description \"" + desc + "\":", end=' ')
            print("minimum version error:", s["version_id"], "<", end=' ')
            print(d["minimum_version_id"])
            bump_taint()


def check_size(s, d, sec, desc=None, field=None):
    if s["size"] != d["size"]:
        print("Section \"" + sec + "\"", end=' ')
        if desc:
            print("Description \"" + desc + "\"", end=' ')
        if field:
            print("Field \"" + field + "\"", end=' ')
        print("size mismatch:", s["size"], ",", d["size"])
        bump_taint()


def check_machine_type(s, d):
    if s["Name"] != d["Name"]:
        print("Warning: checking incompatible machine types:", end=' ')
        print("\"" + s["Name"] + "\", \"" + d["Name"] + "\"")
    return


def main():
    help_text = "Parse JSON-formatted vmstate dumps from QEMU in files SRC and DEST.  Checks whether migration from SRC to DEST QEMU versions would break based on the VMSTATE information contained within the JSON outputs.  The JSON output is created from a QEMU invocation with the -dump-vmstate parameter and a filename argument to it.  Other parameters to QEMU do not matter, except the -M (machine type) parameter."

    parser = argparse.ArgumentParser(description=help_text)
    parser.add_argument('-s', '--src', type=argparse.FileType('r'),
                        required=True,
                        help='json dump from src qemu')
    parser.add_argument('-d', '--dest', type=argparse.FileType('r'),
                        required=True,
                        help='json dump from dest qemu')
    parser.add_argument('--reverse', required=False, default=False,
                        action='store_true',
                        help='reverse the direction')
    args = parser.parse_args()

    src_data = json.load(args.src)
    dest_data = json.load(args.dest)
    args.src.close()
    args.dest.close()

    if args.reverse:
        temp = src_data
        src_data = dest_data
        dest_data = temp

    for sec in src_data:
        dest_sec = sec
        if not dest_sec in dest_data:
            # Either the section name got changed, or the section
            # doesn't exist in dest.
            dest_sec = get_changed_sec_name(sec)
            if not dest_sec in dest_data:
                print("Section \"" + sec + "\" does not exist in dest")
                bump_taint()
                continue

        s = src_data[sec]
        d = dest_data[dest_sec]

        if sec == "vmschkmachine":
            check_machine_type(s, d)
            continue

        check_version(s, d, sec)

        for entry in s:
            if not entry in d:
                print("Section \"" + sec + "\": Entry \"" + entry + "\"", end=' ')
                print("missing")
                bump_taint()
                continue

            if entry == "Description":
                check_descriptions(s[entry], d[entry], sec)

    return taint


if __name__ == '__main__':
    sys.exit(main())
