#!/usr/bin/env python
#
# 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.

from __future__ import print_function
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()
