#!/usr/bin/env python3
#
# Tool to manipulate QED image files
#
# Copyright (C) 2010 IBM, Corp.
#
# Authors:
#  Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.

import sys
import struct
import random
import optparse

# This can be used as a module
__all__ = ['QED_F_NEED_CHECK', 'QED']

QED_F_NEED_CHECK = 0x02

header_fmt = '<IIIIQQQQQII'
header_size = struct.calcsize(header_fmt)
field_names = ['magic', 'cluster_size', 'table_size',
               'header_size', 'features', 'compat_features',
               'autoclear_features', 'l1_table_offset', 'image_size',
               'backing_filename_offset', 'backing_filename_size']
table_elem_fmt = '<Q'
table_elem_size = struct.calcsize(table_elem_fmt)

def err(msg):
    sys.stderr.write(msg + '\n')
    sys.exit(1)

def unpack_header(s):
    fields = struct.unpack(header_fmt, s)
    return dict((field_names[idx], val) for idx, val in enumerate(fields))

def pack_header(header):
    fields = tuple(header[x] for x in field_names)
    return struct.pack(header_fmt, *fields)

def unpack_table_elem(s):
    return struct.unpack(table_elem_fmt, s)[0]

def pack_table_elem(elem):
    return struct.pack(table_elem_fmt, elem)

class QED(object):
    def __init__(self, f):
        self.f = f

        self.f.seek(0, 2)
        self.filesize = f.tell()

        self.load_header()
        self.load_l1_table()

    def raw_pread(self, offset, size):
        self.f.seek(offset)
        return self.f.read(size)

    def raw_pwrite(self, offset, data):
        self.f.seek(offset)
        return self.f.write(data)

    def load_header(self):
        self.header = unpack_header(self.raw_pread(0, header_size))

    def store_header(self):
        self.raw_pwrite(0, pack_header(self.header))

    def read_table(self, offset):
        size = self.header['table_size'] * self.header['cluster_size']
        s = self.raw_pread(offset, size)
        table = [unpack_table_elem(s[i:i + table_elem_size]) for i in xrange(0, size, table_elem_size)]
        return table

    def load_l1_table(self):
        self.l1_table = self.read_table(self.header['l1_table_offset'])
        self.table_nelems = self.header['table_size'] * self.header['cluster_size'] // table_elem_size

    def write_table(self, offset, table):
        s = ''.join(pack_table_elem(x) for x in table)
        self.raw_pwrite(offset, s)

def random_table_item(table):
    vals = [(index, offset) for index, offset in enumerate(table) if offset != 0]
    if not vals:
        err('cannot pick random item because table is empty')
    return random.choice(vals)

def corrupt_table_duplicate(table):
    '''Corrupt a table by introducing a duplicate offset'''
    victim_idx, victim_val = random_table_item(table)
    unique_vals = set(table)
    if len(unique_vals) == 1:
        err('no duplication corruption possible in table')
    dup_val = random.choice(list(unique_vals.difference([victim_val])))
    table[victim_idx] = dup_val

def corrupt_table_invalidate(qed, table):
    '''Corrupt a table by introducing an invalid offset'''
    index, _ = random_table_item(table)
    table[index] = qed.filesize + random.randint(0, 100 * 1024 * 1024 * 1024 * 1024)

def cmd_show(qed, *args):
    '''show [header|l1|l2 <offset>]- Show header or l1/l2 tables'''
    if not args or args[0] == 'header':
        print(qed.header)
    elif args[0] == 'l1':
        print(qed.l1_table)
    elif len(args) == 2 and args[0] == 'l2':
        offset = int(args[1])
        print(qed.read_table(offset))
    else:
        err('unrecognized sub-command')

def cmd_duplicate(qed, table_level):
    '''duplicate l1|l2 - Duplicate a random table element'''
    if table_level == 'l1':
        offset = qed.header['l1_table_offset']
        table = qed.l1_table
    elif table_level == 'l2':
        _, offset = random_table_item(qed.l1_table)
        table = qed.read_table(offset)
    else:
        err('unrecognized sub-command')
    corrupt_table_duplicate(table)
    qed.write_table(offset, table)

def cmd_invalidate(qed, table_level):
    '''invalidate l1|l2 - Plant an invalid table element at random'''
    if table_level == 'l1':
        offset = qed.header['l1_table_offset']
        table = qed.l1_table
    elif table_level == 'l2':
        _, offset = random_table_item(qed.l1_table)
        table = qed.read_table(offset)
    else:
        err('unrecognized sub-command')
    corrupt_table_invalidate(qed, table)
    qed.write_table(offset, table)

def cmd_need_check(qed, *args):
    '''need-check [on|off] - Test, set, or clear the QED_F_NEED_CHECK header bit'''
    if not args:
        print(bool(qed.header['features'] & QED_F_NEED_CHECK))
        return

    if args[0] == 'on':
        qed.header['features'] |= QED_F_NEED_CHECK
    elif args[0] == 'off':
        qed.header['features'] &= ~QED_F_NEED_CHECK
    else:
        err('unrecognized sub-command')
    qed.store_header()

def cmd_zero_cluster(qed, pos, *args):
    '''zero-cluster <pos> [<n>] - Zero data clusters'''
    pos, n = int(pos), 1
    if args:
        if len(args) != 1:
            err('expected one argument')
        n = int(args[0])

    for i in xrange(n):
        l1_index = pos // qed.header['cluster_size'] // len(qed.l1_table)
        if qed.l1_table[l1_index] == 0:
            err('no l2 table allocated')

        l2_offset = qed.l1_table[l1_index]
        l2_table = qed.read_table(l2_offset)

        l2_index = (pos // qed.header['cluster_size']) % len(qed.l1_table)
        l2_table[l2_index] = 1 # zero the data cluster
        qed.write_table(l2_offset, l2_table)
        pos += qed.header['cluster_size']

def cmd_copy_metadata(qed, outfile):
    '''copy-metadata <outfile> - Copy metadata only (for scrubbing corrupted images)'''
    out = open(outfile, 'wb')

    # Match file size
    out.seek(qed.filesize - 1)
    out.write('\0')

    # Copy header clusters
    out.seek(0)
    header_size_bytes = qed.header['header_size'] * qed.header['cluster_size']
    out.write(qed.raw_pread(0, header_size_bytes))

    # Copy L1 table
    out.seek(qed.header['l1_table_offset'])
    s = ''.join(pack_table_elem(x) for x in qed.l1_table)
    out.write(s)

    # Copy L2 tables
    for l2_offset in qed.l1_table:
        if l2_offset == 0:
            continue
        l2_table = qed.read_table(l2_offset)
        out.seek(l2_offset)
        s = ''.join(pack_table_elem(x) for x in l2_table)
        out.write(s)

    out.close()

def usage():
    print('Usage: %s <file> <cmd> [<arg>, ...]' % sys.argv[0])
    print()
    print('Supported commands:')
    for cmd in sorted(x for x in globals() if x.startswith('cmd_')):
        print(globals()[cmd].__doc__)
    sys.exit(1)

def main():
    if len(sys.argv) < 3:
        usage()
    filename, cmd = sys.argv[1:3]

    cmd = 'cmd_' + cmd.replace('-', '_')
    if cmd not in globals():
        usage()

    qed = QED(open(filename, 'r+b'))
    try:
        globals()[cmd](qed, *sys.argv[3:])
    except TypeError as e:
        sys.stderr.write(globals()[cmd].__doc__ + '\n')
        sys.exit(1)

if __name__ == '__main__':
    main()
