#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
#
# top-like utility for displaying kvm statistics
#
# Copyright 2006-2008 Qumranet Technologies
# Copyright 2008-2011 Red Hat, Inc.
#
# Authors:
#  Avi Kivity <avi@redhat.com>
#
"""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 argparse
import ctypes
import fcntl
import resource
import struct
import re
import subprocess
import signal
from collections import defaultdict, namedtuple
from functools import reduce
from datetime import datetime

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,
}

signal_received = False

ENCODING = locale.getpreferredencoding(False)
TRACE_FILTER = re.compile(r'^[^\(]*$')


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

    def tracepoint_is_child(self, field):
        if (TRACE_FILTER.match(field)):
            return None
        return field.split('(', 1)[0]


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

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


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_reason_field = 'exit_nr'
        self.exit_reasons = {}

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


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

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        return None


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

    def debugfs_is_child(self, field):
        """ Returns name of parent if 'field' is a child, None otherwise """
        if field.startswith('instruction_'):
            return 'exit_instruction'


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


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."""
    def __init__(self, pid):
        self.child_events = False
        self.pid = pid

    @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)
        super(TracepointProvider, self).__init__(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_reason_field and ARCH.exit_reasons:
            filters['kvm_exit'] = (ARCH.exit_reason_field, ARCH.exit_reasons)
        return filters

    def _get_available_fields(self):
        """Returns a list of available events 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)]
        # add parents for child fields - otherwise we won't see any output!
        for field in self._fields:
            parent = ARCH.tracepoint_is_child(field)
            if (parent and parent not in self._fields):
                self.fields.append(parent)

    @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 not in self._fields:
                    continue
                parent = ARCH.tracepoint_is_child(name)
                if parent:
                    name += ' ' + parent
                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 = []
        super(DebugfsProvider, self).__init__(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

        """
        exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns', 'halt_wait_ns']
        fields = [field for field in self.walkdir(PATH_DEBUGFS_KVM)[2]
                  if field not in exempt_list]

        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)]
        # add parents for child fields - otherwise we won't see any output!
        for field in self._fields:
            parent = ARCH.debugfs_is_child(field)
            if (parent and parent not in self._fields):
                self.fields.append(parent)

    @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 = list(filter(lambda x: "{}-".format(pid) in x, vms))

        else:
            self.paths = []
            self.do_read = True

    def _verify_paths(self):
        """Remove invalid paths"""
        for path in self.paths:
            if not os.path.exists(os.path.join(PATH_DEBUGFS_KVM, path)):
                self.paths.remove(path)
                continue

    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
        self._verify_paths()

        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
                parent = ARCH.debugfs_is_child(field)
                if parent:
                    field = field + ' ' + parent
                else:
                    if by_guest:
                        field = key.split('-')[0]    # set 'field' to 'pid'
                increment = value - self._baseline.get(key, 0)
                if field in results:
                    results[field] += 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)


EventStat = namedtuple('EventStat', ['value', 'delta'])


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 = {}
        self._child_events = False

    def _get_providers(self, options):
        """Returns a list of data providers depending on the passed options."""
        providers = []

        if options.debugfs:
            providers.append(DebugfsProvider(options.pid, options.fields,
                                             options.debugfs_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

    @property
    def child_events(self):
        return self._child_events

    @child_events.setter
    def child_events(self, val):
        self._child_events = val
        for provider in self.providers:
            provider.child_events = val

    def get(self, by_guest=0):
        """Returns a dict with field -> (value, delta to last value) of all
        provider data.
        Key formats:
          * plain: 'key' is event name
          * child-parent: 'key' is in format '<child> <parent>'
          * pid: 'key' is the pid of the guest, and the record contains the
               aggregated event data
        These formats are generated by the providers, and handled in class TUI.
        """
        for provider in self.providers:
            new = provider.read(by_guest=by_guest)
            for key in new:
                oldval = self.values.get(key, EventStat(0, 0)).value
                newval = new.get(key, 0)
                newdelta = newval - oldval
                self.values[key] = EventStat(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
SORT_DEFAULT = 0
MIN_DELAY = 0.1
MAX_DELAY = 25.5


class Tui(object):
    """Instruments curses to draw a nice text ui."""
    def __init__(self, stats, opts):
        self.stats = stats
        self.screen = None
        self._delay_initial = 0.25
        self._delay_regular = opts.set_delay
        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_pid(self, pid):
        """Propagates pid selection to stats object."""
        self.screen.addstr(4, 1, 'Updating pid filter...')
        self.screen.refresh()
        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)
        self._gname = gname
        if gname:
            gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
                                   if len(gname) > MAX_GUEST_NAME_LEN
                                   else gname))
        if pid > 0:
            self._headline = 'kvm statistics - pid {0} {1}'.format(pid, gname)
        else:
            self._headline = 'kvm statistics - summary'
        self.screen.addstr(0, 0, self._headline, curses.A_BOLD)
        if self.stats.fields_filter:
            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):
        def insert_child(sorted_items, child, values, parent):
            num = len(sorted_items)
            for i in range(0, num):
                # only add child if parent is present
                if parent.startswith(sorted_items[i][0]):
                    sorted_items.insert(i + 1, ('  ' + child, values))

        def get_sorted_events(self, stats):
            """ separate parent and child events """
            if self._sorting == SORT_DEFAULT:
                def sortkey(pair):
                    # sort by (delta value, overall value)
                    v = pair[1]
                    return (v.delta, v.value)
            else:
                def sortkey(pair):
                    # sort by overall value
                    v = pair[1]
                    return v.value

            childs = []
            sorted_items = []
            # we can't rule out child events to appear prior to parents even
            # when sorted - separate out all children first, and add in later
            for key, values in sorted(stats.items(), key=sortkey,
                                      reverse=True):
                if values == (0, 0):
                    continue
                if key.find(' ') != -1:
                    if not self.stats.child_events:
                        continue
                    childs.insert(0, (key, values))
                else:
                    sorted_items.append((key, values))
            if self.stats.child_events:
                for key, values in childs:
                    (child, parent) = key.split(' ')
                    insert_child(sorted_items, child, values, parent)

            return sorted_items

        if not self._is_running_guest(self.stats.pid_filter):
            if self._gname:
                try:  # ...to identify the guest by name in case it's back
                    pids = self.get_pid_from_gname(self._gname)
                    if len(pids) == 1:
                        self._refresh_header(pids[0])
                        self._update_pid(pids[0])
                        return
                except:
                    pass
            self._display_guest_dead()
            # leave final data on screen
            return
        row = 3
        self.screen.move(row, 0)
        self.screen.clrtobot()
        stats = self.stats.get(self._display_guests)
        total = 0.
        ctotal = 0.
        for key, values in stats.items():
            if self._display_guests:
                if self.get_gname_from_pid(key):
                    total += values.value
                continue
            if not key.find(' ') != -1:
                total += values.value
            else:
                ctotal += values.value
        if total == 0.:
            # we don't have any fields, or all non-child events are filtered
            total = ctotal

        # print events
        tavg = 0
        tcur = 0
        guest_removed = False
        for key, values in get_sorted_events(self, stats):
            if row >= self.screen.getmaxyx()[0] - 1 or values == (0, 0):
                break
            if self._display_guests:
                key = self.get_gname_from_pid(key)
                if not key:
                    continue
            cur = int(round(values.delta / sleeptime)) if values.delta else 0
            if cur < 0:
                guest_removed = True
                continue
            if key[0] != ' ':
                if values.delta:
                    tcur += values.delta
                ptotal = values.value
                ltotal = total
            else:
                ltotal = ptotal
            self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' % (key,
                               values.value,
                               values.value * 100 / float(ltotal), cur))
            row += 1
        if row == 3:
            if guest_removed:
                self.screen.addstr(4, 1, 'Guest removed, updating...')
            else:
                self.screen.addstr(4, 1, 'No matching events reported yet')
        if row > 4:
            tavg = int(round(tcur / sleeptime)) if tcur > 0 else ''
            self.screen.addstr(row, 1, '%-40s %10d        %8s' %
                               ('Total', total, tavg), curses.A_BOLD)
        self.screen.refresh()

    def _display_guest_dead(self):
        marker = '   Guest is DEAD   '
        y = min(len(self._headline), 80 - len(marker))
        self.screen.addstr(0, y, marker, curses.A_BLINK | curses.A_STANDOUT)

    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/PID',
               '   h     display interactive commands reference',
               '   o     toggle sorting order (Total vs CurAvg/s)',
               '   p     filter by guest name/PID',
               '   q     quit',
               '   r     reset stats',
               '   s     set delay between refreshs (value range: '
               '%s-%s secs)' % (MIN_DELAY, MAX_DELAY),
               '   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.

        """
        msg = ''
        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(5, 0, msg)
            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 = ''
                self._refresh_header()
                return
            try:
                re.compile(regex)
                self.stats.fields_filter = regex
                self._refresh_header()
                return
            except re.error:
                msg = '"' + regex + '": Not a valid regular expression'
                continue

    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 %.1fs).'
                               % 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)
                    err = is_delay_valid(delay)
                    if err is not None:
                        msg = err
                        continue
                else:
                    delay = DELAY_DEFAULT
                self._delay_regular = delay
                break

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

    def _is_running_guest(self, pid):
        """Check if pid is still a running process."""
        if not pid:
            return True
        return os.path.isdir(os.path.join('/proc/', str(pid)))

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

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

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               'Show statistics for specific guest or 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()
            curses.curs_set(1)
            self.screen.addstr(3, 0, "Guest or pid [ENTER exits]: ")
            guest = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            pid = 0
            if not guest or guest == '0':
                break
            if guest.isdigit():
                if not self._is_running_guest(guest):
                    msg = '"' + guest + '": Not a running process'
                    continue
                pid = int(guest)
                break
            pids = []
            try:
                pids = self.get_pid_from_gname(guest)
            except:
                msg = '"' + guest + '": Internal error while searching, ' \
                      'use pid filter instead'
                continue
            if len(pids) == 0:
                msg = '"' + guest + '": Not an active guest'
                continue
            if len(pids) > 1:
                msg = '"' + guest + '": Multiple matches found, use pid ' \
                      'filter instead'
                continue
            pid = pids[0]
            break
        curses.curs_set(0)
        self._refresh_header(pid)
        self._update_pid(pid)

    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 = ''
                    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' or char == 'p':
                    self._show_vm_selection_by_guest()
                    sleeptime = self._delay_initial
                if char == 'h':
                    self._show_help_interactive()
                if char == 'o':
                    self._sorting = not self._sorting
                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.stats.child_events = not self.stats.child_events
            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, values in sorted(s.items()):
            print('%-42s%10d%10d' % (key.split(' ')[0], values.value,
                  values.delta))
    except KeyboardInterrupt:
        pass


class StdFormat(object):
    def __init__(self, keys):
        self._banner = ''
        for key in keys:
            self._banner += key.split(' ')[0] + ' '

    def get_banner(self):
        return self._banner

    def get_statline(self, keys, s):
        res = ''
        for key in keys:
            res += ' %9d' % s[key].delta
        return res


class CSVFormat(object):
    def __init__(self, keys):
        self._banner = 'timestamp'
        self._banner += reduce(lambda res, key: "{},{!s}".format(res,
                               key.split(' ')[0]), keys, '')

    def get_banner(self):
        return self._banner

    def get_statline(self, keys, s):
        return reduce(lambda res, key: "{},{!s}".format(res, s[key].delta),
                      keys, '')


def log(stats, opts, frmt, keys):
    """Prints statistics as reiterating key block, multiple value blocks."""
    global signal_received
    line = 0
    banner_repeat = 20
    f = None

    def do_banner(opts):
        nonlocal f
        if opts.log_to_file:
            if not f:
                try:
                     f = open(opts.log_to_file, 'a')
                except (IOError, OSError):
                    sys.exit("Error: Could not open file: %s" %
                             opts.log_to_file)
                if isinstance(frmt, CSVFormat) and f.tell() != 0:
                    return
        print(frmt.get_banner(), file=f or sys.stdout)

    def do_statline(opts, values):
        statline = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + \
                   frmt.get_statline(keys, values)
        print(statline, file=f or sys.stdout)

    do_banner(opts)
    banner_printed = True
    while True:
        try:
            time.sleep(opts.set_delay)
            if signal_received:
                banner_printed = True
                line = 0
                f.close()
                do_banner(opts)
                signal_received = False
            if (line % banner_repeat == 0 and not banner_printed and
                not (opts.log_to_file and isinstance(frmt, CSVFormat))):
                do_banner(opts)
                banner_printed = True
            values = stats.get()
            if (not opts.skip_zero_records or
                any(values[k].delta != 0 for k in keys)):
                do_statline(opts, values)
                line += 1
                banner_printed = False
        except KeyboardInterrupt:
            break

    if opts.log_to_file:
        f.close()


def handle_signal(sig, frame):
    global signal_received

    signal_received = True

    return


def is_delay_valid(delay):
    """Verify delay is in valid value range."""
    msg = None
    if delay < MIN_DELAY:
        msg = '"' + str(delay) + '": Delay must be >=%s' % MIN_DELAY
    if delay > MAX_DELAY:
        msg = '"' + str(delay) + '": Delay must be <=%s' % MAX_DELAY
    return msg


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 (value range: 0.1-25.5 secs)
   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 Guest_to_pid(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            try:
                pids = Tui.get_pid_from_gname(values)
            except:
                sys.exit('Error while searching for guest "{}". Use "-p" to '
                         'specify a pid instead?'.format(values))
            if len(pids) == 0:
                sys.exit('Error: No guest by the name "{}" found'
                         .format(values))
            if len(pids) > 1:
                sys.exit('Error: Multiple processes found (pids: {}). Use "-p"'
                         ' to specify the desired pid'.format(" ".join(pids)))
            namespace.pid = pids[0]

    argparser = argparse.ArgumentParser(description=description_text,
                                        formatter_class=argparse
                                        .RawTextHelpFormatter)
    argparser.add_argument('-1', '--once', '--batch',
                           action='store_true',
                           default=False,
                           help='run in batch mode for one second',
                           )
    argparser.add_argument('-c', '--csv',
                           action='store_true',
                           default=False,
                           help='log in csv format - requires option -l/-L',
                           )
    argparser.add_argument('-d', '--debugfs',
                           action='store_true',
                           default=False,
                           help='retrieve statistics from debugfs',
                           )
    argparser.add_argument('-f', '--fields',
                           default='',
                           help='''fields to display (regex)
"-f help" for a list of available events''',
                           )
    argparser.add_argument('-g', '--guest',
                           type=str,
                           help='restrict statistics to guest by name',
                           action=Guest_to_pid,
                           )
    argparser.add_argument('-i', '--debugfs-include-past',
                           action='store_true',
                           default=False,
                           help='include all available data on past events for'
                                ' debugfs',
                           )
    argparser.add_argument('-l', '--log',
                           action='store_true',
                           default=False,
                           help='run in logging mode (like vmstat)',
                           )
    argparser.add_argument('-L', '--log-to-file',
                           type=str,
                           metavar='FILE',
                           help="like '--log', but logging to a file"
                           )
    argparser.add_argument('-p', '--pid',
                           type=int,
                           default=0,
                           help='restrict statistics to pid',
                           )
    argparser.add_argument('-s', '--set-delay',
                           type=float,
                           default=DELAY_DEFAULT,
                           metavar='DELAY',
                           help='set delay between refreshs (value range: '
                                '%s-%s secs)' % (MIN_DELAY, MAX_DELAY),
                           )
    argparser.add_argument('-t', '--tracepoints',
                           action='store_true',
                           default=False,
                           help='retrieve statistics from tracepoints',
                           )
    argparser.add_argument('-z', '--skip-zero-records',
                           action='store_true',
                           default=False,
                           help='omit records with all zeros in logging mode',
                           )
    options = argparser.parse_args()
    if options.csv and not (options.log or options.log_to_file):
        sys.exit('Error: Option -c/--csv requires -l/--log')
    if options.skip_zero_records and not (options.log or options.log_to_file):
        sys.exit('Error: Option -z/--skip-zero-records requires -l/-L')
    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(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 assign_globals():
    global PATH_DEBUGFS_KVM
    global PATH_DEBUGFS_TRACING

    debugfs = ''
    for line in open('/proc/mounts'):
        if line.split(' ')[0] == 'debugfs':
            debugfs = line.split(' ')[1]
            break
    if debugfs == '':
        sys.stderr.write("Please make sure that CONFIG_DEBUG_FS is enabled in "
                         "your kernel, mounted and\nreadable by the current "
                         "user:\n"
                         "('mount -t debugfs debugfs /sys/kernel/debug')\n")
        sys.exit(1)

    PATH_DEBUGFS_KVM = os.path.join(debugfs, 'kvm')
    PATH_DEBUGFS_TRACING = os.path.join(debugfs, 'tracing')

    if not os.path.exists(PATH_DEBUGFS_KVM):
        sys.stderr.write("Please make sure that CONFIG_KVM is enabled in "
                         "your kernel and that the modules are loaded.\n")
        sys.exit(1)


def main():
    assign_globals()
    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.')

    err = is_delay_valid(options.set_delay)
    if err is not None:
        sys.exit('Error: ' + err)

    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 or options.log_to_file:
        if options.log_to_file:
            signal.signal(signal.SIGHUP, handle_signal)
        keys = sorted(stats.get().keys())
        if options.csv:
            frmt = CSVFormat(keys)
        else:
            frmt = StdFormat(keys)
        log(stats, options, frmt, keys)
    elif not options.once:
        with Tui(stats, options) as tui:
            tui.show_stats()
    else:
        batch(stats)


if __name__ == "__main__":
    main()
