#!/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,
    'INIT_SIGNAL':          3,
    'SIPI_SIGNAL':          4,
    'INTERRUPT_WINDOW':     7,
    'NMI_WINDOW':           8,
    'TASK_SWITCH':          9,
    'CPUID':                10,
    'HLT':                  12,
    'INVD':                 13,
    '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,
    'MSR_LOAD_FAIL':        34,
    'MWAIT_INSTRUCTION':    36,
    'MONITOR_TRAP_FLAG':    37,
    'MONITOR_INSTRUCTION':  39,
    'PAUSE_INSTRUCTION':    40,
    'MCE_DURING_VMENTRY':   41,
    'TPR_BELOW_THRESHOLD':  43,
    'APIC_ACCESS':          44,
    'EOI_INDUCED':          45,
    'GDTR_IDTR':            46,
    'LDTR_TR':              47,
    'EPT_VIOLATION':        48,
    'EPT_MISCONFIG':        49,
    'INVEPT':               50,
    'RDTSCP':               51,
    'PREEMPTION_TIMER':     52,
    'INVVPID':              53,
    'WBINVD':               54,
    'XSETBV':               55,
    'APIC_WRITE':           56,
    'RDRAND':               57,
    'INVPCID':              58,
    'VMFUNC':               59,
    'ENCLS':                60,
    'RDSEED':               61,
    'PML_FULL':             62,
    'XSAVES':               63,
    'XRSTORS':              64,
    'UMWAIT':               67,
    'TPAUSE':               68,
    'BUS_LOCK':             74,
    'NOTIFY':               75,
}

SVM_EXIT_REASONS = {
    'READ_CR0':       0x000,
    'READ_CR2':       0x002,
    'READ_CR3':       0x003,
    'READ_CR4':       0x004,
    'READ_CR8':       0x008,
    'WRITE_CR0':      0x010,
    'WRITE_CR2':      0x012,
    '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,
    'LAST_EXCP':      0x05f,
    '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,
    'RDPRU':          0x08e,
    'EFER_WRITE_TRAP':           0x08f,
    'CR0_WRITE_TRAP':            0x090,
    'CR1_WRITE_TRAP':            0x091,
    'CR2_WRITE_TRAP':            0x092,
    'CR3_WRITE_TRAP':            0x093,
    'CR4_WRITE_TRAP':            0x094,
    'CR5_WRITE_TRAP':            0x095,
    'CR6_WRITE_TRAP':            0x096,
    'CR7_WRITE_TRAP':            0x097,
    'CR8_WRITE_TRAP':            0x098,
    'CR9_WRITE_TRAP':            0x099,
    'CR10_WRITE_TRAP':           0x09a,
    'CR11_WRITE_TRAP':           0x09b,
    'CR12_WRITE_TRAP':           0x09c,
    'CR13_WRITE_TRAP':           0x09d,
    'CR14_WRITE_TRAP':           0x09e,
    'CR15_WRITE_TRAP':           0x09f,
    'INVPCID':        0x0a2,
    'NPF':            0x400,
    'AVIC_INCOMPLETE_IPI':       0x401,
    'AVIC_UNACCELERATED_ACCESS': 0x402,
    'VMGEXIT':        0x403,
}

# EC definition of HSR (from arch/arm64/include/asm/esr.h)
AARCH64_EXIT_REASONS = {
    'UNKNOWN':      0x00,
    'WFx':          0x01,
    'CP15_32':      0x03,
    'CP15_64':      0x04,
    'CP14_MR':      0x05,
    'CP14_LS':      0x06,
    'FP_ASIMD':     0x07,
    'CP10_ID':      0x08,
    'PAC':          0x09,
    'CP14_64':      0x0C,
    'BTI':          0x0D,
    'ILL':          0x0E,
    'SVC32':        0x11,
    'HVC32':        0x12,
    'SMC32':        0x13,
    'SVC64':        0x15,
    'HVC64':        0x16,
    'SMC64':        0x17,
    'SYS64':        0x18,
    'SVE':          0x19,
    'ERET':         0x1A,
    'FPAC':         0x1C,
    'SME':          0x1D,
    'IMP_DEF':      0x1F,
    'IABT_LOW':     0x20,
    'IABT_CUR':     0x21,
    'PC_ALIGN':     0x22,
    'DABT_LOW':     0x24,
    'DABT_CUR':     0x25,
    'SP_ALIGN':     0x26,
    'FP_EXC32':     0x28,
    'FP_EXC64':     0x2C,
    'SERROR':       0x2F,
    'BREAKPT_LOW':  0x30,
    'BREAKPT_CUR':  0x31,
    'SOFTSTP_LOW':  0x32,
    'SOFTSTP_CUR':  0x33,
    'WATCHPT_LOW':  0x34,
    'WATCHPT_CUR':  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,
    'S390_STSI':        25,
    'IOAPIC_EOI':       26,
    'HYPERV':           27,
    'ARM_NISV':         28,
    'X86_RDMSR':        29,
    'X86_WRMSR':        30,
    'DIRTY_RING_FULL':  31,
    'AP_RESET_HOLD':    32,
    'X86_BUS_LOCK':     33,
    'XEN':              34,
    'RISCV_SBI':        35,
    'RISCV_CSR':        36,
    'NOTIFY':           37,
}

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(map(str, 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(' ')[2] == '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()
