#!/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

        """
        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)]
        # 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()
