#!/usr/bin/python
#
# top-like utility for displaying kvm statistics
#
# Copyright 2006-2008 Qumranet Technologies
# Copyright 2008-2011 Red Hat, Inc.
#
# Authors:
#  Avi Kivity <avi@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.  See
# the COPYING file in the top-level directory.
"""The kvm_stat module outputs statistics about running KVM VMs

Three different ways of output formatting are available:
- as a top-like text ui
- in a key -> value format
- in an all keys, all values format

The data is sampled from the KVM's debugfs entries and its perf events.
"""
from __future__ import print_function

import curses
import sys
import locale
import os
import time
import optparse
import ctypes
import fcntl
import resource
import struct
import re
import subprocess
from collections import defaultdict

VMX_EXIT_REASONS = {
    'EXCEPTION_NMI':        0,
    'EXTERNAL_INTERRUPT':   1,
    'TRIPLE_FAULT':         2,
    'PENDING_INTERRUPT':    7,
    'NMI_WINDOW':           8,
    'TASK_SWITCH':          9,
    'CPUID':                10,
    'HLT':                  12,
    'INVLPG':               14,
    'RDPMC':                15,
    'RDTSC':                16,
    'VMCALL':               18,
    'VMCLEAR':              19,
    'VMLAUNCH':             20,
    'VMPTRLD':              21,
    'VMPTRST':              22,
    'VMREAD':               23,
    'VMRESUME':             24,
    'VMWRITE':              25,
    'VMOFF':                26,
    'VMON':                 27,
    'CR_ACCESS':            28,
    'DR_ACCESS':            29,
    'IO_INSTRUCTION':       30,
    'MSR_READ':             31,
    'MSR_WRITE':            32,
    'INVALID_STATE':        33,
    'MWAIT_INSTRUCTION':    36,
    'MONITOR_INSTRUCTION':  39,
    'PAUSE_INSTRUCTION':    40,
    'MCE_DURING_VMENTRY':   41,
    'TPR_BELOW_THRESHOLD':  43,
    'APIC_ACCESS':          44,
    'EPT_VIOLATION':        48,
    'EPT_MISCONFIG':        49,
    'WBINVD':               54,
    'XSETBV':               55,
    'APIC_WRITE':           56,
    'INVPCID':              58,
}

SVM_EXIT_REASONS = {
    'READ_CR0':       0x000,
    'READ_CR3':       0x003,
    'READ_CR4':       0x004,
    'READ_CR8':       0x008,
    'WRITE_CR0':      0x010,
    'WRITE_CR3':      0x013,
    'WRITE_CR4':      0x014,
    'WRITE_CR8':      0x018,
    'READ_DR0':       0x020,
    'READ_DR1':       0x021,
    'READ_DR2':       0x022,
    'READ_DR3':       0x023,
    'READ_DR4':       0x024,
    'READ_DR5':       0x025,
    'READ_DR6':       0x026,
    'READ_DR7':       0x027,
    'WRITE_DR0':      0x030,
    'WRITE_DR1':      0x031,
    'WRITE_DR2':      0x032,
    'WRITE_DR3':      0x033,
    'WRITE_DR4':      0x034,
    'WRITE_DR5':      0x035,
    'WRITE_DR6':      0x036,
    'WRITE_DR7':      0x037,
    'EXCP_BASE':      0x040,
    'INTR':           0x060,
    'NMI':            0x061,
    'SMI':            0x062,
    'INIT':           0x063,
    'VINTR':          0x064,
    'CR0_SEL_WRITE':  0x065,
    'IDTR_READ':      0x066,
    'GDTR_READ':      0x067,
    'LDTR_READ':      0x068,
    'TR_READ':        0x069,
    'IDTR_WRITE':     0x06a,
    'GDTR_WRITE':     0x06b,
    'LDTR_WRITE':     0x06c,
    'TR_WRITE':       0x06d,
    'RDTSC':          0x06e,
    'RDPMC':          0x06f,
    'PUSHF':          0x070,
    'POPF':           0x071,
    'CPUID':          0x072,
    'RSM':            0x073,
    'IRET':           0x074,
    'SWINT':          0x075,
    'INVD':           0x076,
    'PAUSE':          0x077,
    'HLT':            0x078,
    'INVLPG':         0x079,
    'INVLPGA':        0x07a,
    'IOIO':           0x07b,
    'MSR':            0x07c,
    'TASK_SWITCH':    0x07d,
    'FERR_FREEZE':    0x07e,
    'SHUTDOWN':       0x07f,
    'VMRUN':          0x080,
    'VMMCALL':        0x081,
    'VMLOAD':         0x082,
    'VMSAVE':         0x083,
    'STGI':           0x084,
    'CLGI':           0x085,
    'SKINIT':         0x086,
    'RDTSCP':         0x087,
    'ICEBP':          0x088,
    'WBINVD':         0x089,
    'MONITOR':        0x08a,
    'MWAIT':          0x08b,
    'MWAIT_COND':     0x08c,
    'XSETBV':         0x08d,
    'NPF':            0x400,
}

# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
AARCH64_EXIT_REASONS = {
    'UNKNOWN':      0x00,
    'WFI':          0x01,
    'CP15_32':      0x03,
    'CP15_64':      0x04,
    'CP14_MR':      0x05,
    'CP14_LS':      0x06,
    'FP_ASIMD':     0x07,
    'CP10_ID':      0x08,
    'CP14_64':      0x0C,
    'ILL_ISS':      0x0E,
    'SVC32':        0x11,
    'HVC32':        0x12,
    'SMC32':        0x13,
    'SVC64':        0x15,
    'HVC64':        0x16,
    'SMC64':        0x17,
    'SYS64':        0x18,
    'IABT':         0x20,
    'IABT_HYP':     0x21,
    'PC_ALIGN':     0x22,
    'DABT':         0x24,
    'DABT_HYP':     0x25,
    'SP_ALIGN':     0x26,
    'FP_EXC32':     0x28,
    'FP_EXC64':     0x2C,
    'SERROR':       0x2F,
    'BREAKPT':      0x30,
    'BREAKPT_HYP':  0x31,
    'SOFTSTP':      0x32,
    'SOFTSTP_HYP':  0x33,
    'WATCHPT':      0x34,
    'WATCHPT_HYP':  0x35,
    'BKPT32':       0x38,
    'VECTOR32':     0x3A,
    'BRK64':        0x3C,
}

# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
USERSPACE_EXIT_REASONS = {
    'UNKNOWN':          0,
    'EXCEPTION':        1,
    'IO':               2,
    'HYPERCALL':        3,
    'DEBUG':            4,
    'HLT':              5,
    'MMIO':             6,
    'IRQ_WINDOW_OPEN':  7,
    'SHUTDOWN':         8,
    'FAIL_ENTRY':       9,
    'INTR':             10,
    'SET_TPR':          11,
    'TPR_ACCESS':       12,
    'S390_SIEIC':       13,
    'S390_RESET':       14,
    'DCR':              15,
    'NMI':              16,
    'INTERNAL_ERROR':   17,
    'OSI':              18,
    'PAPR_HCALL':       19,
    'S390_UCONTROL':    20,
    'WATCHDOG':         21,
    'S390_TSCH':        22,
    'EPR':              23,
    'SYSTEM_EVENT':     24,
}

IOCTL_NUMBERS = {
    'SET_FILTER':  0x40082406,
    'ENABLE':      0x00002400,
    'DISABLE':     0x00002401,
    'RESET':       0x00002403,
}

ENCODING = locale.getpreferredencoding(False)


class Arch(object):
    """Encapsulates global architecture specific data.

    Contains the performance event open syscall and ioctl numbers, as
    well as the VM exit reasons for the architecture it runs on.

    """
    @staticmethod
    def get_arch():
        machine = os.uname()[4]

        if machine.startswith('ppc'):
            return ArchPPC()
        elif machine.startswith('aarch64'):
            return ArchA64()
        elif machine.startswith('s390'):
            return ArchS390()
        else:
            # X86_64
            for line in open('/proc/cpuinfo'):
                if not line.startswith('flags'):
                    continue

                flags = line.split()
                if 'vmx' in flags:
                    return ArchX86(VMX_EXIT_REASONS)
                if 'svm' in flags:
                    return ArchX86(SVM_EXIT_REASONS)
                return


class ArchX86(Arch):
    def __init__(self, exit_reasons):
        self.sc_perf_evt_open = 298
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = exit_reasons


class ArchPPC(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 319
        self.ioctl_numbers = IOCTL_NUMBERS
        self.ioctl_numbers['ENABLE'] = 0x20002400
        self.ioctl_numbers['DISABLE'] = 0x20002401
        self.ioctl_numbers['RESET'] = 0x20002403

        # PPC comes in 32 and 64 bit and some generated ioctl
        # numbers depend on the wordsize.
        char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
        self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
        self.exit_reasons = {}


class ArchA64(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 241
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = AARCH64_EXIT_REASONS


class ArchS390(Arch):
    def __init__(self):
        self.sc_perf_evt_open = 331
        self.ioctl_numbers = IOCTL_NUMBERS
        self.exit_reasons = None

ARCH = Arch.get_arch()


class perf_event_attr(ctypes.Structure):
    """Struct that holds the necessary data to set up a trace event.

    For an extensive explanation see perf_event_open(2) and
    include/uapi/linux/perf_event.h, struct perf_event_attr

    All fields that are not initialized in the constructor are 0.

    """
    _fields_ = [('type', ctypes.c_uint32),
                ('size', ctypes.c_uint32),
                ('config', ctypes.c_uint64),
                ('sample_freq', ctypes.c_uint64),
                ('sample_type', ctypes.c_uint64),
                ('read_format', ctypes.c_uint64),
                ('flags', ctypes.c_uint64),
                ('wakeup_events', ctypes.c_uint32),
                ('bp_type', ctypes.c_uint32),
                ('bp_addr', ctypes.c_uint64),
                ('bp_len', ctypes.c_uint64),
                ]

    def __init__(self):
        super(self.__class__, self).__init__()
        self.type = PERF_TYPE_TRACEPOINT
        self.size = ctypes.sizeof(self)
        self.read_format = PERF_FORMAT_GROUP


PERF_TYPE_TRACEPOINT = 2
PERF_FORMAT_GROUP = 1 << 3

PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'


class Group(object):
    """Represents a perf event group."""

    def __init__(self):
        self.events = []

    def add_event(self, event):
        self.events.append(event)

    def read(self):
        """Returns a dict with 'event name: value' for all events in the
        group.

        Values are read by reading from the file descriptor of the
        event that is the group leader. See perf_event_open(2) for
        details.

        Read format for the used event configuration is:
        struct read_format {
            u64 nr; /* The number of events */
            struct {
                u64 value; /* The value of the event */
            } values[nr];
        };

        """
        length = 8 * (1 + len(self.events))
        read_format = 'xxxxxxxx' + 'Q' * len(self.events)
        return dict(zip([event.name for event in self.events],
                        struct.unpack(read_format,
                                      os.read(self.events[0].fd, length))))


class Event(object):
    """Represents a performance event and manages its life cycle."""
    def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
                 trace_filter, trace_set='kvm'):
        self.libc = ctypes.CDLL('libc.so.6', use_errno=True)
        self.syscall = self.libc.syscall
        self.name = name
        self.fd = None
        self.setup_event(group, trace_cpu, trace_pid, trace_point,
                         trace_filter, trace_set)

    def __del__(self):
        """Closes the event's file descriptor.

        As no python file object was created for the file descriptor,
        python will not reference count the descriptor and will not
        close it itself automatically, so we do it.

        """
        if self.fd:
            os.close(self.fd)

    def perf_event_open(self, attr, pid, cpu, group_fd, flags):
        """Wrapper for the sys_perf_evt_open() syscall.

        Used to set up performance events, returns a file descriptor or -1
        on error.

        Attributes are:
        - syscall number
        - struct perf_event_attr *
        - pid or -1 to monitor all pids
        - cpu number or -1 to monitor all cpus
        - The file descriptor of the group leader or -1 to create a group.
        - flags

        """
        return self.syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
                            ctypes.c_int(pid), ctypes.c_int(cpu),
                            ctypes.c_int(group_fd), ctypes.c_long(flags))

    def setup_event_attribute(self, trace_set, trace_point):
        """Returns an initialized ctype perf_event_attr struct."""

        id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
                               trace_point, 'id')

        event_attr = perf_event_attr()
        event_attr.config = int(open(id_path).read())
        return event_attr

    def setup_event(self, group, trace_cpu, trace_pid, trace_point,
                    trace_filter, trace_set):
        """Sets up the perf event in Linux.

        Issues the syscall to register the event in the kernel and
        then sets the optional filter.

        """

        event_attr = self.setup_event_attribute(trace_set, trace_point)

        # First event will be group leader.
        group_leader = -1

        # All others have to pass the leader's descriptor instead.
        if group.events:
            group_leader = group.events[0].fd

        fd = self.perf_event_open(event_attr, trace_pid,
                                  trace_cpu, group_leader, 0)
        if fd == -1:
            err = ctypes.get_errno()
            raise OSError(err, os.strerror(err),
                          'while calling sys_perf_event_open().')

        if trace_filter:
            fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
                        trace_filter)

        self.fd = fd

    def enable(self):
        """Enables the trace event in the kernel.

        Enabling the group leader makes reading counters from it and the
        events under it possible.

        """
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)

    def disable(self):
        """Disables the trace event in the kernel.

        Disabling the group leader makes reading all counters under it
        impossible.

        """
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)

    def reset(self):
        """Resets the count of the trace event in the kernel."""
        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)


class Provider(object):
    """Encapsulates functionalities used by all providers."""
    @staticmethod
    def is_field_wanted(fields_filter, field):
        """Indicate whether field is valid according to fields_filter."""
        if not fields_filter:
            return True
        return re.match(fields_filter, field) is not None

    @staticmethod
    def walkdir(path):
        """Returns os.walk() data for specified directory.

        As it is only a wrapper it returns the same 3-tuple of (dirpath,
        dirnames, filenames).
        """
        return next(os.walk(path))


class TracepointProvider(Provider):
    """Data provider for the stats class.

    Manages the events/groups from which it acquires its data.

    """
    def __init__(self, pid, fields_filter):
        self.group_leaders = []
        self.filters = self.get_filters()
        self.update_fields(fields_filter)
        self.pid = pid

    @staticmethod
    def get_filters():
        """Returns a dict of trace events, their filter ids and
        the values that can be filtered.

        Trace events can be filtered for special values by setting a
        filter string via an ioctl. The string normally has the format
        identifier==value. For each filter a new event will be created, to
        be able to distinguish the events.

        """
        filters = {}
        filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
        if ARCH.exit_reasons:
            filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
        return filters

    def get_available_fields(self):
        """Returns a list of available event's of format 'event name(filter
        name)'.

        All available events have directories under
        /sys/kernel/debug/tracing/events/ which export information
        about the specific event. Therefore, listing the dirs gives us
        a list of all available events.

        Some events like the vm exit reasons can be filtered for
        specific values. To take account for that, the routine below
        creates special fields with the following format:
        event name(filter name)

        """
        path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
        fields = self.walkdir(path)[1]
        extra = []
        for field in fields:
            if field in self.filters:
                filter_name_, filter_dicts = self.filters[field]
                for name in filter_dicts:
                    extra.append(field + '(' + name + ')')
        fields += extra
        return fields

    def update_fields(self, fields_filter):
        """Refresh fields, applying fields_filter"""
        self.fields = [field for field in self.get_available_fields()
                       if self.is_field_wanted(fields_filter, field)]

    @staticmethod
    def get_online_cpus():
        """Returns a list of cpu id integers."""
        def parse_int_list(list_string):
            """Returns an int list from a string of comma separated integers and
            integer ranges."""
            integers = []
            members = list_string.split(',')

            for member in members:
                if '-' not in member:
                    integers.append(int(member))
                else:
                    int_range = member.split('-')
                    integers.extend(range(int(int_range[0]),
                                          int(int_range[1]) + 1))

            return integers

        with open('/sys/devices/system/cpu/online') as cpu_list:
            cpu_string = cpu_list.readline()
            return parse_int_list(cpu_string)

    def setup_traces(self):
        """Creates all event and group objects needed to be able to retrieve
        data."""
        fields = self.get_available_fields()
        if self._pid > 0:
            # Fetch list of all threads of the monitored pid, as qemu
            # starts a thread for each vcpu.
            path = os.path.join('/proc', str(self._pid), 'task')
            groupids = self.walkdir(path)[1]
        else:
            groupids = self.get_online_cpus()

        # The constant is needed as a buffer for python libs, std
        # streams and other files that the script opens.
        newlim = len(groupids) * len(fields) + 50
        try:
            softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)

            if hardlim < newlim:
                # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
            else:
                # Raising the soft limit is sufficient.
                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))

        except ValueError:
            sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))

        for groupid in groupids:
            group = Group()
            for name in fields:
                tracepoint = name
                tracefilter = None
                match = re.match(r'(.*)\((.*)\)', name)
                if match:
                    tracepoint, sub = match.groups()
                    tracefilter = ('%s==%d\0' %
                                   (self.filters[tracepoint][0],
                                    self.filters[tracepoint][1][sub]))

                # From perf_event_open(2):
                # pid > 0 and cpu == -1
                # This measures the specified process/thread on any CPU.
                #
                # pid == -1 and cpu >= 0
                # This measures all processes/threads on the specified CPU.
                trace_cpu = groupid if self._pid == 0 else -1
                trace_pid = int(groupid) if self._pid != 0 else -1

                group.add_event(Event(name=name,
                                      group=group,
                                      trace_cpu=trace_cpu,
                                      trace_pid=trace_pid,
                                      trace_point=tracepoint,
                                      trace_filter=tracefilter))

            self.group_leaders.append(group)

    @property
    def fields(self):
        return self._fields

    @fields.setter
    def fields(self, fields):
        """Enables/disables the (un)wanted events"""
        self._fields = fields
        for group in self.group_leaders:
            for index, event in enumerate(group.events):
                if event.name in fields:
                    event.reset()
                    event.enable()
                else:
                    # Do not disable the group leader.
                    # It would disable all of its events.
                    if index != 0:
                        event.disable()

    @property
    def pid(self):
        return self._pid

    @pid.setter
    def pid(self, pid):
        """Changes the monitored pid by setting new traces."""
        self._pid = pid
        # The garbage collector will get rid of all Event/Group
        # objects and open files after removing the references.
        self.group_leaders = []
        self.setup_traces()
        self.fields = self._fields

    def read(self, by_guest=0):
        """Returns 'event name: current value' for all enabled events."""
        ret = defaultdict(int)
        for group in self.group_leaders:
            for name, val in group.read().items():
                if name in self._fields:
                    ret[name] += val
        return ret

    def reset(self):
        """Reset all field counters"""
        for group in self.group_leaders:
            for event in group.events:
                event.reset()


class DebugfsProvider(Provider):
    """Provides data from the files that KVM creates in the kvm debugfs
    folder."""
    def __init__(self, pid, fields_filter, include_past):
        self.update_fields(fields_filter)
        self._baseline = {}
        self.do_read = True
        self.paths = []
        self.pid = pid
        if include_past:
            self.restore()

    def get_available_fields(self):
        """"Returns a list of available fields.

        The fields are all available KVM debugfs files

        """
        return self.walkdir(PATH_DEBUGFS_KVM)[2]

    def update_fields(self, fields_filter):
        """Refresh fields, applying fields_filter"""
        self._fields = [field for field in self.get_available_fields()
                        if self.is_field_wanted(fields_filter, field)]

    @property
    def fields(self):
        return self._fields

    @fields.setter
    def fields(self, fields):
        self._fields = fields
        self.reset()

    @property
    def pid(self):
        return self._pid

    @pid.setter
    def pid(self, pid):
        self._pid = pid
        if pid != 0:
            vms = self.walkdir(PATH_DEBUGFS_KVM)[1]
            if len(vms) == 0:
                self.do_read = False

            self.paths = filter(lambda x: "{}-".format(pid) in x, vms)

        else:
            self.paths = []
            self.do_read = True
        self.reset()

    def read(self, reset=0, by_guest=0):
        """Returns a dict with format:'file name / field -> current value'.

        Parameter 'reset':
          0   plain read
          1   reset field counts to 0
          2   restore the original field counts

        """
        results = {}

        # If no debugfs filtering support is available, then don't read.
        if not self.do_read:
            return results

        paths = self.paths
        if self._pid == 0:
            paths = []
            for entry in os.walk(PATH_DEBUGFS_KVM):
                for dir in entry[1]:
                    paths.append(dir)
        for path in paths:
            for field in self._fields:
                value = self.read_field(field, path)
                key = path + field
                if reset == 1:
                    self._baseline[key] = value
                if reset == 2:
                    self._baseline[key] = 0
                if self._baseline.get(key, -1) == -1:
                    self._baseline[key] = value
                increment = (results.get(field, 0) + value -
                             self._baseline.get(key, 0))
                if by_guest:
                    pid = key.split('-')[0]
                    if pid in results:
                        results[pid] += increment
                    else:
                        results[pid] = increment
                else:
                    results[field] = increment

        return results

    def read_field(self, field, path):
        """Returns the value of a single field from a specific VM."""
        try:
            return int(open(os.path.join(PATH_DEBUGFS_KVM,
                                         path,
                                         field))
                       .read())
        except IOError:
            return 0

    def reset(self):
        """Reset field counters"""
        self._baseline = {}
        self.read(1)

    def restore(self):
        """Reset field counters"""
        self._baseline = {}
        self.read(2)


class Stats(object):
    """Manages the data providers and the data they provide.

    It is used to set filters on the provider's data and collect all
    provider data.

    """
    def __init__(self, options):
        self.providers = self.get_providers(options)
        self._pid_filter = options.pid
        self._fields_filter = options.fields
        self.values = {}

    @staticmethod
    def get_providers(options):
        """Returns a list of data providers depending on the passed options."""
        providers = []

        if options.debugfs:
            providers.append(DebugfsProvider(options.pid, options.fields,
                                             options.dbgfs_include_past))
        if options.tracepoints or not providers:
            providers.append(TracepointProvider(options.pid, options.fields))

        return providers

    def update_provider_filters(self):
        """Propagates fields filters to providers."""
        # As we reset the counters when updating the fields we can
        # also clear the cache of old values.
        self.values = {}
        for provider in self.providers:
            provider.update_fields(self._fields_filter)

    def reset(self):
        self.values = {}
        for provider in self.providers:
            provider.reset()

    @property
    def fields_filter(self):
        return self._fields_filter

    @fields_filter.setter
    def fields_filter(self, fields_filter):
        if fields_filter != self._fields_filter:
            self._fields_filter = fields_filter
            self.update_provider_filters()

    @property
    def pid_filter(self):
        return self._pid_filter

    @pid_filter.setter
    def pid_filter(self, pid):
        if pid != self._pid_filter:
            self._pid_filter = pid
            self.values = {}
            for provider in self.providers:
                provider.pid = self._pid_filter

    def get(self, by_guest=0):
        """Returns a dict with field -> (value, delta to last value) of all
        provider data."""
        for provider in self.providers:
            new = provider.read(by_guest=by_guest)
            for key in new if by_guest else provider.fields:
                oldval = self.values.get(key, (0, 0))[0]
                newval = new.get(key, 0)
                newdelta = newval - oldval
                self.values[key] = (newval, newdelta)
        return self.values

    def toggle_display_guests(self, to_pid):
        """Toggle between collection of stats by individual event and by
        guest pid

        Events reported by DebugfsProvider change when switching to/from
        reading by guest values. Hence we have to remove the excess event
        names from self.values.

        """
        if any(isinstance(ins, TracepointProvider) for ins in self.providers):
            return 1
        if to_pid:
            for provider in self.providers:
                if isinstance(provider, DebugfsProvider):
                    for key in provider.fields:
                        if key in self.values.keys():
                            del self.values[key]
        else:
            oldvals = self.values.copy()
            for key in oldvals:
                if key.isdigit():
                    del self.values[key]
        # Update oldval (see get())
        self.get(to_pid)
        return 0

DELAY_DEFAULT = 3.0
MAX_GUEST_NAME_LEN = 48
MAX_REGEX_LEN = 44
DEFAULT_REGEX = r'^[^\(]*$'
SORT_DEFAULT = 0


class Tui(object):
    """Instruments curses to draw a nice text ui."""
    def __init__(self, stats):
        self.stats = stats
        self.screen = None
        self._delay_initial = 0.25
        self._delay_regular = DELAY_DEFAULT
        self._sorting = SORT_DEFAULT
        self._display_guests = 0

    def __enter__(self):
        """Initialises curses for later use.  Based on curses.wrapper
           implementation from the Python standard library."""
        self.screen = curses.initscr()
        curses.noecho()
        curses.cbreak()

        # The try/catch works around a minor bit of
        # over-conscientiousness in the curses module, the error
        # return from C start_color() is ignorable.
        try:
            curses.start_color()
        except curses.error:
            pass

        # Hide cursor in extra statement as some monochrome terminals
        # might support hiding but not colors.
        try:
            curses.curs_set(0)
        except curses.error:
            pass

        curses.use_default_colors()
        return self

    def __exit__(self, *exception):
        """Resets the terminal to its normal state.  Based on curses.wrapper
           implementation from the Python standard library."""
        if self.screen:
            self.screen.keypad(0)
            curses.echo()
            curses.nocbreak()
            curses.endwin()

    @staticmethod
    def get_all_gnames():
        """Returns a list of (pid, gname) tuples of all running guests"""
        res = []
        try:
            child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
                                     stdout=subprocess.PIPE)
        except:
            raise Exception
        for line in child.stdout:
            line = line.decode(ENCODING).lstrip().split(' ', 1)
            # perform a sanity check before calling the more expensive
            # function to possibly extract the guest name
            if ' -name ' in line[1]:
                res.append((line[0], Tui.get_gname_from_pid(line[0])))
        child.stdout.close()

        return res

    def print_all_gnames(self, row):
        """Print a list of all running guests along with their pids."""
        self.screen.addstr(row, 2, '%8s  %-60s' %
                           ('Pid', 'Guest Name (fuzzy list, might be '
                            'inaccurate!)'),
                           curses.A_UNDERLINE)
        row += 1
        try:
            for line in self.get_all_gnames():
                self.screen.addstr(row, 2, '%8s  %-60s' % (line[0], line[1]))
                row += 1
                if row >= self.screen.getmaxyx()[0]:
                    break
        except Exception:
            self.screen.addstr(row + 1, 2, 'Not available')

    @staticmethod
    def get_pid_from_gname(gname):
        """Fuzzy function to convert guest name to QEMU process pid.

        Returns a list of potential pids, can be empty if no match found.
        Throws an exception on processing errors.

        """
        pids = []
        for line in Tui.get_all_gnames():
            if gname == line[1]:
                pids.append(int(line[0]))

        return pids

    @staticmethod
    def get_gname_from_pid(pid):
        """Returns the guest name for a QEMU process pid.

        Extracts the guest name from the QEMU comma line by processing the
        '-name' option. Will also handle names specified out of sequence.

        """
        name = ''
        try:
            line = open('/proc/{}/cmdline'
                        .format(pid), 'r').read().split('\0')
            parms = line[line.index('-name') + 1].split(',')
            while '' in parms:
                # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results
                # in # ['foo', '', 'bar'], which we revert here
                idx = parms.index('')
                parms[idx - 1] += ',' + parms[idx + 1]
                del parms[idx:idx+2]
            # the '-name' switch allows for two ways to specify the guest name,
            # where the plain name overrides the name specified via 'guest='
            for arg in parms:
                if '=' not in arg:
                    name = arg
                    break
                if arg[:6] == 'guest=':
                    name = arg[6:]
        except (ValueError, IOError, IndexError):
            pass

        return name

    def update_drilldown(self):
        """Sets or removes a filter that only allows fields without braces."""
        if not self.stats.fields_filter:
            self.stats.fields_filter = DEFAULT_REGEX

        elif self.stats.fields_filter == DEFAULT_REGEX:
            self.stats.fields_filter = None

    def update_pid(self, pid):
        """Propagates pid selection to stats object."""
        self.stats.pid_filter = pid

    def refresh_header(self, pid=None):
        """Refreshes the header."""
        if pid is None:
            pid = self.stats.pid_filter
        self.screen.erase()
        gname = self.get_gname_from_pid(pid)
        if gname:
            gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
                                   if len(gname) > MAX_GUEST_NAME_LEN
                                   else gname))
        if pid > 0:
            self.screen.addstr(0, 0, 'kvm statistics - pid {0} {1}'
                               .format(pid, gname), curses.A_BOLD)
        else:
            self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
        if self.stats.fields_filter and self.stats.fields_filter \
           != DEFAULT_REGEX:
            regex = self.stats.fields_filter
            if len(regex) > MAX_REGEX_LEN:
                regex = regex[:MAX_REGEX_LEN] + '...'
            self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
        if self._display_guests:
            col_name = 'Guest Name'
        else:
            col_name = 'Event'
        self.screen.addstr(2, 1, '%-40s %10s%7s %8s' %
                           (col_name, 'Total', '%Total', 'CurAvg/s'),
                           curses.A_STANDOUT)
        self.screen.addstr(4, 1, 'Collecting data...')
        self.screen.refresh()

    def refresh_body(self, sleeptime):
        row = 3
        self.screen.move(row, 0)
        self.screen.clrtobot()
        stats = self.stats.get(self._display_guests)

        def sortCurAvg(x):
            # sort by current events if available
            if stats[x][1]:
                return (-stats[x][1], -stats[x][0])
            else:
                return (0, -stats[x][0])

        def sortTotal(x):
            # sort by totals
            return (0, -stats[x][0])
        total = 0.
        for key in stats.keys():
            if key.find('(') is -1:
                total += stats[key][0]
        if self._sorting == SORT_DEFAULT:
            sortkey = sortCurAvg
        else:
            sortkey = sortTotal
        tavg = 0
        for key in sorted(stats.keys(), key=sortkey):
            if row >= self.screen.getmaxyx()[0] - 1:
                break
            values = stats[key]
            if not values[0] and not values[1]:
                break
            if values[0] is not None:
                cur = int(round(values[1] / sleeptime)) if values[1] else ''
                if self._display_guests:
                    key = self.get_gname_from_pid(key)
                self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' %
                                   (key, values[0], values[0] * 100 / total,
                                    cur))
                if cur is not '' and key.find('(') is -1:
                    tavg += cur
            row += 1
        if row == 3:
            self.screen.addstr(4, 1, 'No matching events reported yet')
        else:
            self.screen.addstr(row, 1, '%-40s %10d        %8s' %
                               ('Total', total, tavg if tavg else ''),
                               curses.A_BOLD)
        self.screen.refresh()

    def show_msg(self, text):
        """Display message centered text and exit on key press"""
        hint = 'Press any key to continue'
        curses.cbreak()
        self.screen.erase()
        (x, term_width) = self.screen.getmaxyx()
        row = 2
        for line in text:
            start = (term_width - len(line)) / 2
            self.screen.addstr(row, start, line)
            row += 1
        self.screen.addstr(row + 1, (term_width - len(hint)) / 2, hint,
                           curses.A_STANDOUT)
        self.screen.getkey()

    def show_help_interactive(self):
        """Display help with list of interactive commands"""
        msg = ('   b     toggle events by guests (debugfs only, honors'
               ' filters)',
               '   c     clear filter',
               '   f     filter by regular expression',
               '   g     filter by guest name',
               '   h     display interactive commands reference',
               '   o     toggle sorting order (Total vs CurAvg/s)',
               '   p     filter by PID',
               '   q     quit',
               '   r     reset stats',
               '   s     set update interval',
               '   x     toggle reporting of stats for individual child trace'
               ' events',
               'Any other key refreshes statistics immediately')
        curses.cbreak()
        self.screen.erase()
        self.screen.addstr(0, 0, "Interactive commands reference",
                           curses.A_BOLD)
        self.screen.addstr(2, 0, "Press any key to exit", curses.A_STANDOUT)
        row = 4
        for line in msg:
            self.screen.addstr(row, 0, line)
            row += 1
        self.screen.getkey()
        self.refresh_header()

    def show_filter_selection(self):
        """Draws filter selection mask.

        Asks for a valid regex and sets the fields filter accordingly.

        """
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               "Show statistics for events matching a regex.",
                               curses.A_BOLD)
            self.screen.addstr(2, 0,
                               "Current regex: {0}"
                               .format(self.stats.fields_filter))
            self.screen.addstr(3, 0, "New regex: ")
            curses.echo()
            regex = self.screen.getstr().decode(ENCODING)
            curses.noecho()
            if len(regex) == 0:
                self.stats.fields_filter = DEFAULT_REGEX
                self.refresh_header()
                return
            try:
                re.compile(regex)
                self.stats.fields_filter = regex
                self.refresh_header()
                return
            except re.error:
                continue

    def show_vm_selection_by_pid(self):
        """Draws PID selection mask.

        Asks for a pid until a valid pid or 0 has been entered.

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               'Show statistics for specific pid.',
                               curses.A_BOLD)
            self.screen.addstr(1, 0,
                               'This might limit the shown data to the trace '
                               'statistics.')
            self.screen.addstr(5, 0, msg)
            self.print_all_gnames(7)

            curses.echo()
            self.screen.addstr(3, 0, "Pid [0 or pid]: ")
            pid = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            try:
                if len(pid) > 0:
                    pid = int(pid)
                    if pid != 0 and not os.path.isdir(os.path.join('/proc/',
                                                                   str(pid))):
                        msg = '"' + str(pid) + '": Not a running process'
                        continue
                else:
                    pid = 0
                self.refresh_header(pid)
                self.update_pid(pid)
                break
            except ValueError:
                msg = '"' + str(pid) + '": Not a valid pid'

    def show_set_update_interval(self):
        """Draws update interval selection mask."""
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0, 'Set update interval (defaults to %fs).' %
                               DELAY_DEFAULT, curses.A_BOLD)
            self.screen.addstr(4, 0, msg)
            self.screen.addstr(2, 0, 'Change delay from %.1fs to ' %
                               self._delay_regular)
            curses.echo()
            val = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            try:
                if len(val) > 0:
                    delay = float(val)
                    if delay < 0.1:
                        msg = '"' + str(val) + '": Value must be >=0.1'
                        continue
                    if delay > 25.5:
                        msg = '"' + str(val) + '": Value must be <=25.5'
                        continue
                else:
                    delay = DELAY_DEFAULT
                self._delay_regular = delay
                break

            except ValueError:
                msg = '"' + str(val) + '": Invalid value'
        self.refresh_header()

    def show_vm_selection_by_guest_name(self):
        """Draws guest selection mask.

        Asks for a guest name until a valid guest name or '' is entered.

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               'Show statistics for specific guest.',
                               curses.A_BOLD)
            self.screen.addstr(1, 0,
                               'This might limit the shown data to the trace '
                               'statistics.')
            self.screen.addstr(5, 0, msg)
            self.print_all_gnames(7)
            curses.echo()
            self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
            gname = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            if not gname:
                self.refresh_header(0)
                self.update_pid(0)
                break
            else:
                pids = []
                try:
                    pids = self.get_pid_from_gname(gname)
                except:
                    msg = '"' + gname + '": Internal error while searching, ' \
                          'use pid filter instead'
                    continue
                if len(pids) == 0:
                    msg = '"' + gname + '": Not an active guest'
                    continue
                if len(pids) > 1:
                    msg = '"' + gname + '": Multiple matches found, use pid ' \
                          'filter instead'
                    continue
                self.refresh_header(pids[0])
                self.update_pid(pids[0])
                break

    def show_stats(self):
        """Refreshes the screen and processes user input."""
        sleeptime = self._delay_initial
        self.refresh_header()
        start = 0.0  # result based on init value never appears on screen
        while True:
            self.refresh_body(time.time() - start)
            curses.halfdelay(int(sleeptime * 10))
            start = time.time()
            sleeptime = self._delay_regular
            try:
                char = self.screen.getkey()
                if char == 'b':
                    self._display_guests = not self._display_guests
                    if self.stats.toggle_display_guests(self._display_guests):
                        self.show_msg(['Command not available with tracepoints'
                                       ' enabled', 'Restart with debugfs only '
                                       '(see option \'-d\') and try again!'])
                        self._display_guests = not self._display_guests
                    self.refresh_header()
                if char == 'c':
                    self.stats.fields_filter = DEFAULT_REGEX
                    self.refresh_header(0)
                    self.update_pid(0)
                if char == 'f':
                    curses.curs_set(1)
                    self.show_filter_selection()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'g':
                    curses.curs_set(1)
                    self.show_vm_selection_by_guest_name()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'h':
                    self.show_help_interactive()
                if char == 'o':
                    self._sorting = not self._sorting
                if char == 'p':
                    curses.curs_set(1)
                    self.show_vm_selection_by_pid()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'q':
                    break
                if char == 'r':
                    self.stats.reset()
                if char == 's':
                    curses.curs_set(1)
                    self.show_set_update_interval()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'x':
                    self.update_drilldown()
                    # prevents display of current values on next refresh
                    self.stats.get(self._display_guests)
            except KeyboardInterrupt:
                break
            except curses.error:
                continue


def batch(stats):
    """Prints statistics in a key, value format."""
    try:
        s = stats.get()
        time.sleep(1)
        s = stats.get()
        for key in sorted(s.keys()):
            values = s[key]
            print('%-42s%10d%10d' % (key, values[0], values[1]))
    except KeyboardInterrupt:
        pass


def log(stats):
    """Prints statistics as reiterating key block, multiple value blocks."""
    keys = sorted(stats.get().keys())

    def banner():
        for k in keys:
            print(k, end=' ')
        print()

    def statline():
        s = stats.get()
        for k in keys:
            print(' %9d' % s[k][1], end=' ')
        print()
    line = 0
    banner_repeat = 20
    while True:
        try:
            time.sleep(1)
            if line % banner_repeat == 0:
                banner()
            statline()
            line += 1
        except KeyboardInterrupt:
            break


def get_options():
    """Returns processed program arguments."""
    description_text = """
This script displays various statistics about VMs running under KVM.
The statistics are gathered from the KVM debugfs entries and / or the
currently available perf traces.

The monitoring takes additional cpu cycles and might affect the VM's
performance.

Requirements:
- Access to:
    %s
    %s/events/*
    /proc/pid/task
- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
  CAP_SYS_ADMIN and perf events are used.
- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
  the large number of files that are possibly opened.

Interactive Commands:
   b     toggle events by guests (debugfs only, honors filters)
   c     clear filter
   f     filter by regular expression
   g     filter by guest name
   h     display interactive commands reference
   o     toggle sorting order (Total vs CurAvg/s)
   p     filter by PID
   q     quit
   r     reset stats
   s     set update interval
   x     toggle reporting of stats for individual child trace events
Press any other key to refresh statistics immediately.
""" % (PATH_DEBUGFS_KVM, PATH_DEBUGFS_TRACING)

    class PlainHelpFormatter(optparse.IndentedHelpFormatter):
        def format_description(self, description):
            if description:
                return description + "\n"
            else:
                return ""

    def cb_guest_to_pid(option, opt, val, parser):
        try:
            pids = Tui.get_pid_from_gname(val)
        except:
            sys.exit('Error while searching for guest "{}". Use "-p" to '
                     'specify a pid instead?'.format(val))
        if len(pids) == 0:
            sys.exit('Error: No guest by the name "{}" found'.format(val))
        if len(pids) > 1:
            sys.exit('Error: Multiple processes found (pids: {}). Use "-p" '
                     'to specify the desired pid'.format(" ".join(pids)))
        parser.values.pid = pids[0]

    optparser = optparse.OptionParser(description=description_text,
                                      formatter=PlainHelpFormatter())
    optparser.add_option('-1', '--once', '--batch',
                         action='store_true',
                         default=False,
                         dest='once',
                         help='run in batch mode for one second',
                         )
    optparser.add_option('-i', '--debugfs-include-past',
                         action='store_true',
                         default=False,
                         dest='dbgfs_include_past',
                         help='include all available data on past events for '
                              'debugfs',
                         )
    optparser.add_option('-l', '--log',
                         action='store_true',
                         default=False,
                         dest='log',
                         help='run in logging mode (like vmstat)',
                         )
    optparser.add_option('-t', '--tracepoints',
                         action='store_true',
                         default=False,
                         dest='tracepoints',
                         help='retrieve statistics from tracepoints',
                         )
    optparser.add_option('-d', '--debugfs',
                         action='store_true',
                         default=False,
                         dest='debugfs',
                         help='retrieve statistics from debugfs',
                         )
    optparser.add_option('-f', '--fields',
                         action='store',
                         default=DEFAULT_REGEX,
                         dest='fields',
                         help='''fields to display (regex)
                                 "-f help" for a list of available events''',
                         )
    optparser.add_option('-p', '--pid',
                         action='store',
                         default=0,
                         type='int',
                         dest='pid',
                         help='restrict statistics to pid',
                         )
    optparser.add_option('-g', '--guest',
                         action='callback',
                         type='string',
                         dest='pid',
                         metavar='GUEST',
                         help='restrict statistics to guest by name',
                         callback=cb_guest_to_pid,
                         )
    options, unkn = optparser.parse_args(sys.argv)
    if len(unkn) != 1:
        sys.exit('Error: Extra argument(s): ' + ' '.join(unkn[1:]))
    try:
        # verify that we were passed a valid regex up front
        re.compile(options.fields)
    except re.error:
        sys.exit('Error: "' + options.fields + '" is not a valid regular '
                 'expression')

    return options


def check_access(options):
    """Exits if the current user can't access all needed directories."""
    if not os.path.exists('/sys/kernel/debug'):
        sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
        sys.exit(1)

    if not os.path.exists(PATH_DEBUGFS_KVM):
        sys.stderr.write("Please make sure, that debugfs is mounted and "
                         "readable by the current user:\n"
                         "('mount -t debugfs debugfs /sys/kernel/debug')\n"
                         "Also ensure, that the kvm modules are loaded.\n")
        sys.exit(1)

    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints or
                                                     not options.debugfs):
        sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
                         "when using the option -t (default).\n"
                         "If it is enabled, make {0} readable by the "
                         "current user.\n"
                         .format(PATH_DEBUGFS_TRACING))
        if options.tracepoints:
            sys.exit(1)

        sys.stderr.write("Falling back to debugfs statistics!\n")
        options.debugfs = True
        time.sleep(5)

    return options


def main():
    options = get_options()
    options = check_access(options)

    if (options.pid > 0 and
        not os.path.isdir(os.path.join('/proc/',
                                       str(options.pid)))):
        sys.stderr.write('Did you use a (unsupported) tid instead of a pid?\n')
        sys.exit('Specified pid does not exist.')

    stats = Stats(options)

    if options.fields == 'help':
        stats.fields_filter = None
        event_list = []
        for key in stats.get().keys():
            event_list.append(key.split('(', 1)[0])
        sys.stdout.write('  ' + '\n  '.join(sorted(set(event_list))) + '\n')
        sys.exit(0)

    if options.log:
        log(stats)
    elif not options.once:
        with Tui(stats) as tui:
            tui.show_stats()
    else:
        batch(stats)

if __name__ == "__main__":
    main()
