Ejemplo n.º 1
0
def _check_env():
    global ssh, scp, sshpass  # pylint: disable=global-statement
    if not ssh:
        ssh = which("ssh")
        scp = which("scp")
        sshpass = which("sshpass")
    if not (ssh and scp):
        raise HostError("OpenSSH must be installed on the host.")
Ejemplo n.º 2
0
def _check_env():
    global ssh, scp, sshpass  # pylint: disable=global-statement
    if not ssh:
        ssh = which('ssh')
        scp = which('scp')
        sshpass = which('sshpass')
    if not (ssh and scp):
        raise HostError('OpenSSH must be installed on the host.')
Ejemplo n.º 3
0
    def __init__(
        self,
        target,
        events=None,
        buffer_size=None,
        buffer_size_step=1000,
        buffer_size_file='/sys/kernel/debug/tracing/buffer_size_kb',
        marker_file='/sys/kernel/debug/tracing/trace_marker',
        automark=True,
        autoreport=True,
        autoview=False,
        no_install=False,
    ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.buffer_size_file = buffer_size_file
        self.marker_file = marker_file
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.target_output_file = os.path.join(self.target.working_directory,
                                               OUTPUT_TRACE_FILE)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = _build_trace_events(self.events)
        self._reset_needed = True

        self.host_binary = which('trace-cmd')
        self.kernelshark = which('kernelshark')

        if not self.target.is_rooted:
            raise TargetError(
                'trace-cmd instrument cannot be used on an unrooted device.')
        if self.autoreport and self.host_binary is None:
            raise HostError(
                'trace-cmd binary must be installed on the host if autoreport=True.'
            )
        if self.autoview and self.kernelshark is None:
            raise HostError(
                'kernelshark binary must be installed on the host if autoview=True.'
            )
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi,
                                     'trace-cmd')
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed('trace-cmd'):
                raise TargetError(
                    'No trace-cmd found on device and no_install=True is specified.'
                )
            self.target_binary = 'trace-cmd'
Ejemplo n.º 4
0
    def __init__(self, target, resistor_values,
                 labels=None,
                 device_entry='/dev/ttyACM0',
                 ):
        super(EnergyProbeInstrument, self).__init__(target)
        self.resistor_values = resistor_values
        if labels is not None:
            self.labels = labels
        else:
            self.labels = ['PORT_{}'.format(i)
                           for i in xrange(len(resistor_values))]
        self.device_entry = device_entry
        self.caiman = which('caiman')
        if self.caiman is None:
            raise HostError('caiman must be installed on the host '
                            '(see https://github.com/ARM-software/caiman)')
        if pandas is None:
            self.logger.info("pandas package will significantly speed up this instrument")
            self.logger.info("to install it try: pip install pandas")
        self.attributes_per_sample = 3
        self.bytes_per_sample = self.attributes_per_sample * 4
        self.attributes = ['power', 'voltage', 'current']
        self.command = None
        self.raw_output_directory = None
        self.process = None

        for label in self.labels:
            for kind in self.attributes:
                self.add_channel(label, kind)
Ejemplo n.º 5
0
    def __init__(self, target, resistor_values,
                 labels=None,
                 device_entry='/dev/ttyACM0',
                 ):
        super(EnergyProbeInstrument, self).__init__(target)
        self.resistor_values = resistor_values
        if labels is not None:
            self.labels = labels
        else:
            self.labels = ['PORT_{}'.format(i)
                           for i in xrange(len(resistor_values))]
        self.device_entry = device_entry
        self.caiman = which('caiman')
        if self.caiman is None:
            raise HostError('caiman must be installed on the host '
                            '(see https://github.com/ARM-software/caiman)')
        self.attributes_per_sample = 3
        self.bytes_per_sample = self.attributes_per_sample * 4
        self.attributes = ['power', 'voltage', 'current']
        self.command = None
        self.raw_output_directory = None
        self.process = None
        self.sample_rate_hz = 10000 # Determined empirically
        self.raw_data_file = None

        for label in self.labels:
            for kind in self.attributes:
                self.add_channel(label, kind)
Ejemplo n.º 6
0
class MonsoonBackend(EnergyInstrumentBackend):

    name = 'monsoon'
    description = """
    Monsoon Solutions power monitor

    To use this instrument, you need to install the monsoon.py script available
    from the Android Open Source Project. As of May 2017 this is under the CTS
    repository:

        https://android.googlesource.com/platform/cts/+/master/tools/utils/monsoon.py

    Collects power measurements only, from a selection of two channels, the USB
    passthrough channel and the main output channel.

    """

    parameters = [
        Parameter('monsoon_bin',
                  default=which('monsoon.py'),
                  description="""
                  Path to monsoon.py executable. If not provided,
                  ``PATH`` is searched.
                  """),
        Parameter('tty_device',
                  default='/dev/ttyACM0',
                  description="""
                  TTY device to use to communicate with the Power
                  Monitor. If not provided, /dev/ttyACM0 is used.
                  """)
    ]

    instrument = MonsoonInstrument
Ejemplo n.º 7
0
    def __init__(
        self,
        target,
        resistor_values,
        labels=None,
        device_entry='/dev/ttyACM0',
    ):
        super(EnergyProbeInstrument, self).__init__(target)
        self.resistor_values = resistor_values
        if labels is not None:
            self.labels = labels
        else:
            self.labels = [
                'PORT_{}'.format(i) for i in xrange(len(resistor_values))
            ]
        self.device_entry = device_entry
        self.caiman = which('caiman')
        if self.caiman is None:
            raise HostError('caiman must be installed on the host '
                            '(see https://github.com/ARM-software/caiman)')
        if pandas is None:
            self.logger.info(
                "pandas package will significantly speed up this instrument")
            self.logger.info("to install it try: pip install pandas")
        self.attributes_per_sample = 3
        self.bytes_per_sample = self.attributes_per_sample * 4
        self.attributes = ['power', 'voltage', 'current']
        self.command = None
        self.raw_output_directory = None
        self.process = None

        for label in self.labels:
            for kind in self.attributes:
                self.add_channel(label, kind)
Ejemplo n.º 8
0
    def __init__(self, system, simulator, **kwargs):
            simulator_args = copy.copy(simulator.get('args', []))
            system_platform = system['platform']

            # Get gem5 binary arguments
            simulator_args.append('--listener-mode=on')

            simulator_args.append(system_platform['description'])
            simulator_args.extend(system_platform.get('args', []))

            simulator_args += ['--kernel {}'.format(system['kernel']),
                     '--dtb {}'.format(system['dtb']),
                     '--disk-image {}'.format(system['disk'])]

            # Quote/escape arguments and build the command line
            gem5_args = ' '.join(shlex.quote(a) for a in simulator_args)

            diod_path = which('diod')
            if diod_path is None:
                raise RuntimeError('Failed to find "diod" on your host machine, check your installation or your PATH variable')

            # Setup virtio
            # Brackets are there to let the output dir be created automatically
            virtio_args = '--which-diod={} --workload-automation-vio={{}}'.format(diod_path)

            super().__init__(
                gem5_args=gem5_args,
                gem5_bin=simulator['bin'],
                virtio_args=virtio_args,
                **kwargs
            )
Ejemplo n.º 9
0
    def __init__(
        self,
        target,
        resistor_values,
        labels=None,
        device_entry='/dev/ttyACM0',
    ):
        super(EnergyProbeInstrument, self).__init__(target)
        self.resistor_values = resistor_values
        if labels is not None:
            self.labels = labels
        else:
            self.labels = [
                'PORT_{}'.format(i) for i in range(len(resistor_values))
            ]
        self.device_entry = device_entry
        self.caiman = which('caiman')
        if self.caiman is None:
            raise HostError('caiman must be installed on the host '
                            '(see https://github.com/ARM-software/caiman)')
        self.attributes_per_sample = 3
        self.bytes_per_sample = self.attributes_per_sample * 4
        self.attributes = ['power', 'voltage', 'current']
        self.command = None
        self.raw_output_directory = None
        self.process = None
        self.sample_rate_hz = 10000  # Determined empirically
        self.raw_data_file = None

        for label in self.labels:
            for kind in self.attributes:
                self.add_channel(label, kind)
Ejemplo n.º 10
0
    def __init__(
        self,
        target,
        events=None,
        buffer_size=None,
        buffer_size_step=1000,
        buffer_size_file="/sys/kernel/debug/tracing/buffer_size_kb",
        marker_file="/sys/kernel/debug/tracing/trace_marker",
        automark=True,
        autoreport=True,
        autoview=False,
        no_install=False,
    ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.buffer_size_file = buffer_size_file
        self.marker_file = marker_file
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.target_output_file = os.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = _build_trace_events(self.events)
        self._reset_needed = True

        self.host_binary = which("trace-cmd")
        self.kernelshark = which("kernelshark")

        if not self.target.is_rooted:
            raise TargetError("trace-cmd instrument cannot be used on an unrooted device.")
        if self.autoreport and self.host_binary is None:
            raise HostError("trace-cmd binary must be installed on the host if autoreport=True.")
        if self.autoview and self.kernelshark is None:
            raise HostError("kernelshark binary must be installed on the host if autoview=True.")
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, "trace-cmd")
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed("trace-cmd"):
                raise TargetError("No trace-cmd found on device and no_install=True is specified.")
            self.target_binary = "trace-cmd"
Ejemplo n.º 11
0
def _initialize_without_android_home(env):
    if which('adb'):
        env.adb = 'adb'
    else:
        raise HostError('ANDROID_HOME is not set and adb is not in PATH. '
                        'Have you installed Android SDK?')
    logger.debug('Discovering ANDROID_HOME from adb path.')
    env.platform_tools = os.path.dirname(env.adb)
    env.android_home = os.path.dirname(env.platform_tools)
    _init_common(env)
    return env
Ejemplo n.º 12
0
def _initialize_without_android_home(env):
    if which('adb'):
        env.adb = 'adb'
    else:
        raise HostError('ANDROID_HOME is not set and adb is not in PATH. '
                        'Have you installed Android SDK?')
    logger.debug('Discovering ANDROID_HOME from adb path.')
    env.platform_tools = os.path.dirname(env.adb)
    env.android_home = os.path.dirname(env.platform_tools)
    _init_common(env)
    return env
Ejemplo n.º 13
0
def _discover_aapt(env):
    if env.build_tools:
        aapt_path = ''
        aapt2_path = ''
        versions = os.listdir(env.build_tools)
        for version in reversed(sorted(versions)):
            if not os.path.isfile(aapt2_path):
                aapt2_path = os.path.join(env.build_tools, version, 'aapt2')
            if not os.path.isfile(aapt_path):
                aapt_path = os.path.join(env.build_tools, version, 'aapt')
                aapt_version = 1
            # Use latest available version for aapt/appt2 but ensure at least one is valid.
            if os.path.isfile(aapt2_path) or os.path.isfile(aapt_path):
                break

        # Use aapt2 only if present and we have a suitable version
        if aapt2_path and _check_supported_aapt2(aapt2_path):
            aapt_path = aapt2_path
            aapt_version = 2

        # Use the aapt version discoverted from build tools.
        if aapt_path:
            logger.debug('Using {} for version {}'.format(aapt_path, version))
            env.aapt = aapt_path
            env.aapt_version = aapt_version
            return

    # Try detecting aapt2 and aapt from PATH
    if not env.aapt:
        aapt2_path = which('aapt2')
        if _check_supported_aapt2(aapt2_path):
            env.aapt = aapt2_path
            env.aapt_version = 2
        else:
            env.aapt = which('aapt')
            env.aapt_version = 1

    if not env.aapt:
        raise HostError(
            'aapt/aapt2 not found. Please make sure it is avaliable in PATH'
            ' or at least one Android platform is installed')
Ejemplo n.º 14
0
    def _init_target_gem5(self):
        system = self.conf['gem5']['system']
        simulator = self.conf['gem5']['simulator']

        # Get gem5 binary arguments
        args = simulator.get('args', [])
        args.append('--listener-mode=on')

        # Get platform description
        args.append(system['platform']['description'])

        # Get platform arguments
        args += system['platform'].get('args', [])
        args += [
            '--kernel {}'.format(system['kernel']),
            '--dtb {}'.format(system['dtb']),
            '--disk-image {}'.format(system['disk'])
        ]

        # Gather all arguments
        args = ' '.join(args)

        diod_path = which('diod')
        if diod_path is None:
            raise RuntimeError('Failed to find "diod" on your host machine, '
                               'check your installation or your PATH variable')

        # Setup virtio
        # Brackets are there to let the output dir be created automatically
        virtio_args = '--which-diod={} --workload-automation-vio={{}}'.format(
            diod_path)

        # Change conf['board'] to include platform information
        suffix = os.path.splitext(
            os.path.basename(system['platform']['description']))[0]
        self.conf['board'] = self.conf['board'].lower() + suffix

        board = self._load_board(self.conf['board'])

        # Merge all arguments
        platform = devlib.platform.gem5.Gem5SimulationPlatform(
            name='gem5',
            gem5_bin=simulator['bin'],
            gem5_args=args,
            gem5_virtio=virtio_args,
            host_output_dir=self.res_dir,
            core_names=board['cores'] if board else None,
            core_clusters=self._get_clusters(board['cores'])
            if board else None,
            big_core=board.get('big_core', None) if board else None,
        )

        return platform
def _initialize_without_android_home(env):
    adb_full_path = which('adb')
    if adb_full_path:
        env.adb = 'adb'
    else:
        raise HostError('ANDROID_HOME is not set and adb is not in PATH. '
                        'Have you installed Android SDK?')
    logger.debug('Discovering ANDROID_HOME from adb path.')
    env.platform_tools = os.path.dirname(adb_full_path)
    env.android_home = os.path.dirname(env.platform_tools)
    try:
        _init_common(env)
    except:
        env.aapt = which('aapt')
        if env.aapt:
            logger.info('Using aapt: ' + env.aapt)
        else:
            raise RuntimeError('aapt not found, try setting ANDROID_HOME to \
                                Android SDK or run LISA from android environment'
                               )
    return env
Ejemplo n.º 16
0
    def __init__(self, target, monsoon_bin=None, tty_device=None):
        super(MonsoonInstrument, self).__init__(target)
        self.monsoon_bin = monsoon_bin or which('monsoon.py')
        if not self.monsoon_bin:
            raise HostError(INSTALL_INSTRUCTIONS)

        self.tty_device = tty_device

        self.process = None
        self.output = None

        self.sample_rate_hz = 500
        self.add_channel('output', 'power')
        self.add_channel('USB', 'power')
Ejemplo n.º 17
0
    def __init__(self, target, monsoon_bin=None, tty_device=None):
        super(MonsoonInstrument, self).__init__(target)
        self.monsoon_bin = monsoon_bin or which('monsoon.py')
        if not self.monsoon_bin:
            raise HostError(INSTALL_INSTRUCTIONS)

        self.tty_device = tty_device

        self.process = None
        self.output = None

        self.sample_rate_hz = 500
        self.add_channel('output', 'power')
        self.add_channel('USB', 'power')
Ejemplo n.º 18
0
Archivo: env.py Proyecto: credp/lisa
    def _init_target_gem5(self):
        system = self.conf['gem5']['system']
        simulator = self.conf['gem5']['simulator']

        # Get gem5 binary arguments
        args = simulator.get('args', [])
        args.append('--listener-mode=on')

        # Get platform description
        args.append(system['platform']['description'])

        # Get platform arguments
        args += system['platform'].get('args', [])
        args += ['--kernel {}'.format(system['kernel']),
                 '--dtb {}'.format(system['dtb']),
                 '--disk-image {}'.format(system['disk'])]

        # Gather all arguments
        args = ' '.join(args)

        diod_path = which('diod')
        if diod_path is None:
            raise RuntimeError('Failed to find "diod" on your host machine, '
                               'check your installation or your PATH variable')

        # Setup virtio
        # Brackets are there to let the output dir be created automatically
        virtio_args = '--which-diod={} --workload-automation-vio={{}}'.format(diod_path)

        # Change conf['board'] to include platform information
        suffix = os.path.splitext(os.path.basename(
            system['platform']['description']))[0]
        self.conf['board'] = self.conf['board'].lower() + suffix

        board = self._load_board(self.conf['board'])

        # Merge all arguments
        platform = devlib.platform.gem5.Gem5SimulationPlatform(
            name = 'gem5',
            gem5_bin = simulator['bin'],
            gem5_args = args,
            gem5_virtio = virtio_args,
            host_output_dir = self.res_dir,
            core_names = board['cores'] if board else None,
            core_clusters = self._get_clusters(board['cores']) if board else None,
            big_core = board.get('big_core', None) if board else None,
        )

        return platform
Ejemplo n.º 19
0
    def __init__(self, target, config_file='./config-aep', keep_raw=False):
        super(ArmEnergyProbeInstrument, self).__init__(target)
        self.arm_probe = which('arm-probe')
        if self.arm_probe is None:
            raise HostError('arm-probe must be installed on the host')
        #todo detect is config file exist
        self.attributes = ['power', 'voltage', 'current']
        self.sample_rate_hz = 10000
        self.config_file = config_file
        self.keep_raw = keep_raw

        self.parser = AepParser()
        #TODO make it generic
        topo = self.parser.topology_from_config(self.config_file)
        for item in topo:
            if item == 'time':
                self.add_channel('timestamp', 'time')
            else:
                self.add_channel(item, 'power')
Ejemplo n.º 20
0
    def __init__(self, target,
                 iio_capture=which('iio-capture'),
                 host='baylibre-acme.local',
                 iio_device='iio:device0',
                 buffer_size=256):
        super(AcmeCapeInstrument, self).__init__(target)
        self.iio_capture = iio_capture
        self.host = host
        self.iio_device = iio_device
        self.buffer_size = buffer_size
        self.sample_rate_hz = 100
        if self.iio_capture is None:
            raise HostError('Missing iio-capture binary')
        self.command = None
        self.process = None

        self.add_channel('shunt', 'voltage')
        self.add_channel('bus', 'voltage')
        self.add_channel('device', 'power')
        self.add_channel('device', 'current')
        self.add_channel('timestamp', 'time_ms')
Ejemplo n.º 21
0
    def __init__(self, target,
                 iio_capture=which('iio-capture'),
                 host='baylibre-acme.local',
                 iio_device='iio:device0',
                 buffer_size=256):
        super(AcmeCapeInstrument, self).__init__(target)
        self.iio_capture = iio_capture
        self.host = host
        self.iio_device = iio_device
        self.buffer_size = buffer_size
        self.sample_rate_hz = 100
        if self.iio_capture is None:
            raise HostError('Missing iio-capture binary')
        self.command = None
        self.process = None

        self.add_channel('shunt', 'voltage')
        self.add_channel('bus', 'voltage')
        self.add_channel('device', 'power')
        self.add_channel('device', 'current')
        self.add_channel('timestamp', 'time_ms')
Ejemplo n.º 22
0
    def __init__(
        self,
        target,
        events=None,
        functions=None,
        buffer_size=None,
        buffer_size_step=1000,
        tracing_path='/sys/kernel/debug/tracing',
        automark=True,
        autoreport=True,
        autoview=False,
        no_install=False,
    ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.functions = functions
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.tracing_path = tracing_path
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.target_output_file = os.path.join(self.target.working_directory,
                                               OUTPUT_TRACE_FILE)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = _build_trace_events(self.events)
        self.function_string = _build_trace_functions(self.functions)
        self._reset_needed = True

        # Setup tracing paths
        self.available_functions_file = self.target.path.join(
            self.tracing_path, 'available_filter_functions')
        self.buffer_size_file = self.target.path.join(self.tracing_path,
                                                      'buffer_size_kb')
        self.current_tracer_file = self.target.path.join(
            self.tracing_path, 'current_tracer')
        self.function_profile_file = self.target.path.join(
            self.tracing_path, 'function_profile_enabled')
        self.marker_file = self.target.path.join(self.tracing_path,
                                                 'trace_marker')
        self.ftrace_filter_file = self.target.path.join(
            self.tracing_path, 'set_ftrace_filter')

        self.host_binary = which('trace-cmd')
        self.kernelshark = which('kernelshark')

        if not self.target.is_rooted:
            raise TargetError(
                'trace-cmd instrument cannot be used on an unrooted device.')
        if self.autoreport and self.host_binary is None:
            raise HostError(
                'trace-cmd binary must be installed on the host if autoreport=True.'
            )
        if self.autoview and self.kernelshark is None:
            raise HostError(
                'kernelshark binary must be installed on the host if autoview=True.'
            )
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi,
                                     'trace-cmd')
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed('trace-cmd'):
                raise TargetError(
                    'No trace-cmd found on device and no_install=True is specified.'
                )
            self.target_binary = 'trace-cmd'

        # Check for function tracing support
        if self.functions:
            if not self.target.file_exists(self.function_profile_file):
                raise TargetError('Function profiling not supported. '\
                        'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
            # Validate required functions to be traced
            available_functions = self.target.execute('cat {}'.format(
                self.available_functions_file)).splitlines()
            for function in self.functions:
                if function not in available_functions:
                    raise TargetError(
                        'Function [{}] not available for filtering'.format(
                            function))
Ejemplo n.º 23
0
    def __init__(
        self,
        target,
        events=None,
        functions=None,
        buffer_size=None,
        buffer_size_step=1000,
        tracing_path="/sys/kernel/debug/tracing",
        automark=True,
        autoreport=True,
        autoview=False,
        no_install=False,
    ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.functions = functions
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.tracing_path = tracing_path
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.target_output_file = os.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = _build_trace_events(self.events)
        self.function_string = _build_trace_functions(self.functions)
        self._reset_needed = True

        # Setup tracing paths
        self.available_functions_file = self.target.path.join(self.tracing_path, "available_filter_functions")
        self.buffer_size_file = self.target.path.join(self.tracing_path, "buffer_size_kb")
        self.current_tracer_file = self.target.path.join(self.tracing_path, "current_tracer")
        self.function_profile_file = self.target.path.join(self.tracing_path, "function_profile_enabled")
        self.marker_file = self.target.path.join(self.tracing_path, "trace_marker")
        self.ftrace_filter_file = self.target.path.join(self.tracing_path, "set_ftrace_filter")

        self.host_binary = which("trace-cmd")
        self.kernelshark = which("kernelshark")

        if not self.target.is_rooted:
            raise TargetError("trace-cmd instrument cannot be used on an unrooted device.")
        if self.autoreport and self.host_binary is None:
            raise HostError("trace-cmd binary must be installed on the host if autoreport=True.")
        if self.autoview and self.kernelshark is None:
            raise HostError("kernelshark binary must be installed on the host if autoview=True.")
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, "trace-cmd")
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed("trace-cmd"):
                raise TargetError("No trace-cmd found on device and no_install=True is specified.")
            self.target_binary = "trace-cmd"

        # Check for function tracing support
        if self.functions:
            if not self.target.file_exists(self.function_profile_file):
                raise TargetError(
                    "Function profiling not supported. "
                    "A kernel build with CONFIG_FUNCTION_PROFILER enable is required"
                )
            # Validate required functions to be traced
            available_functions = self.target.execute("cat {}".format(self.available_functions_file)).splitlines()
            for function in self.functions:
                if function not in available_functions:
                    raise TargetError("Function [{}] not available for filtering".format(function))
    def __init__(
        self,
        target,
        events=None,
        functions=None,
        buffer_size=None,
        buffer_size_step=1000,
        tracing_path='/sys/kernel/debug/tracing',
        automark=True,
        autoreport=True,
        autoview=False,
        no_install=False,
        strict=False,
        report_on_target=False,
    ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.functions = functions
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.tracing_path = tracing_path
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.report_on_target = report_on_target
        self.target_output_file = target.path.join(
            self.target.working_directory, OUTPUT_TRACE_FILE)
        text_file_name = target.path.splitext(OUTPUT_TRACE_FILE)[0] + '.txt'
        self.target_text_file = target.path.join(self.target.working_directory,
                                                 text_file_name)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = None
        self.function_string = None
        self._reset_needed = True

        # Setup tracing paths
        self.available_events_file = self.target.path.join(
            self.tracing_path, 'available_events')
        self.available_functions_file = self.target.path.join(
            self.tracing_path, 'available_filter_functions')
        self.buffer_size_file = self.target.path.join(self.tracing_path,
                                                      'buffer_size_kb')
        self.current_tracer_file = self.target.path.join(
            self.tracing_path, 'current_tracer')
        self.function_profile_file = self.target.path.join(
            self.tracing_path, 'function_profile_enabled')
        self.marker_file = self.target.path.join(self.tracing_path,
                                                 'trace_marker')
        self.ftrace_filter_file = self.target.path.join(
            self.tracing_path, 'set_ftrace_filter')

        self.host_binary = which('trace-cmd')
        self.kernelshark = which('kernelshark')

        if not self.target.is_rooted:
            raise TargetError(
                'trace-cmd instrument cannot be used on an unrooted device.')
        if self.autoreport and not self.report_on_target and self.host_binary is None:
            raise HostError(
                'trace-cmd binary must be installed on the host if autoreport=True.'
            )
        if self.autoview and self.kernelshark is None:
            raise HostError(
                'kernelshark binary must be installed on the host if autoview=True.'
            )
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi,
                                     'trace-cmd')
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed('trace-cmd'):
                raise TargetError(
                    'No trace-cmd found on device and no_install=True is specified.'
                )
            self.target_binary = 'trace-cmd'

        # Validate required events to be traced
        available_events = self.target.execute('cat {}'.format(
            self.available_events_file),
                                               as_root=True).splitlines()
        selected_events = []
        for event in self.events:
            # Convert globs supported by FTrace into valid regexp globs
            _event = event
            if event[0] != '*':
                _event = '*' + event
            event_re = re.compile(_event.replace('*', '.*'))
            # Select events matching the required ones
            if len(filter(event_re.match, available_events)) == 0:
                message = 'Event [{}] not available for tracing'.format(event)
                if strict:
                    raise TargetError(message)
                self.target.logger.warning(message)
            else:
                selected_events.append(event)
        # If function profiling is enabled we always need at least one event.
        # Thus, if not other events have been specified, try to add at least
        # a tracepoint which is always available and possibly triggered few
        # times.
        if self.functions and len(selected_events) == 0:
            selected_events = ['sched_wakeup_new']
        self.event_string = _build_trace_events(selected_events)

        # Check for function tracing support
        if self.functions:
            if not self.target.file_exists(self.function_profile_file):
                raise TargetError('Function profiling not supported. '\
                        'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
            # Validate required functions to be traced
            available_functions = self.target.execute(
                'cat {}'.format(self.available_functions_file),
                as_root=True).splitlines()
            selected_functions = []
            for function in self.functions:
                if function not in available_functions:
                    message = 'Function [{}] not available for profiling'.format(
                        function)
                    if strict:
                        raise TargetError(message)
                    self.target.logger.warning(message)
                else:
                    selected_functions.append(function)
            self.function_string = _build_trace_functions(selected_functions)
Ejemplo n.º 25
0
    def __init__(self, target,
                 events=None,
                 functions=None,
                 tracer=None,
                 trace_children_functions=False,
                 buffer_size=None,
                 buffer_size_step=1000,
                 tracing_path='/sys/kernel/debug/tracing',
                 automark=True,
                 autoreport=True,
                 autoview=False,
                 no_install=False,
                 strict=False,
                 report_on_target=False,
                 trace_clock='local',
                 saved_cmdlines_nr=4096,
                 ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.functions = functions
        self.tracer = tracer
        self.trace_children_functions = trace_children_functions
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.tracing_path = tracing_path
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.strict = strict
        self.report_on_target = report_on_target
        self.target_output_file = target.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
        text_file_name = target.path.splitext(OUTPUT_TRACE_FILE)[0] + '.txt'
        self.target_text_file = target.path.join(self.target.working_directory, text_file_name)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = None
        self.function_string = None
        self.trace_clock = trace_clock
        self.saved_cmdlines_nr = saved_cmdlines_nr
        self._reset_needed = True

        # pylint: disable=bad-whitespace
        # Setup tracing paths
        self.available_events_file    = self.target.path.join(self.tracing_path, 'available_events')
        self.available_functions_file = self.target.path.join(self.tracing_path, 'available_filter_functions')
        self.buffer_size_file         = self.target.path.join(self.tracing_path, 'buffer_size_kb')
        self.current_tracer_file      = self.target.path.join(self.tracing_path, 'current_tracer')
        self.function_profile_file    = self.target.path.join(self.tracing_path, 'function_profile_enabled')
        self.marker_file              = self.target.path.join(self.tracing_path, 'trace_marker')
        self.ftrace_filter_file       = self.target.path.join(self.tracing_path, 'set_ftrace_filter')
        self.trace_clock_file         = self.target.path.join(self.tracing_path, 'trace_clock')
        self.save_cmdlines_size_file  = self.target.path.join(self.tracing_path, 'saved_cmdlines_size')
        self.available_tracers_file  = self.target.path.join(self.tracing_path, 'available_tracers')

        self.host_binary = which('trace-cmd')
        self.kernelshark = which('kernelshark')

        if not self.target.is_rooted:
            raise TargetStableError('trace-cmd instrument cannot be used on an unrooted device.')
        if self.autoreport and not self.report_on_target and self.host_binary is None:
            raise HostError('trace-cmd binary must be installed on the host if autoreport=True.')
        if self.autoview and self.kernelshark is None:
            raise HostError('kernelshark binary must be installed on the host if autoview=True.')
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, 'trace-cmd')
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed('trace-cmd'):
                raise TargetStableError('No trace-cmd found on device and no_install=True is specified.')
            self.target_binary = 'trace-cmd'

        # Validate required events to be traced
        def event_to_regex(event):
            if not event.startswith('*'):
                event = '*' + event

            return re.compile(event.replace('*', '.*'))

        def event_is_in_list(event, events):
            return any(
                event_to_regex(event).match(_event)
                for _event in events
            )

        unavailable_events = [
            event
            for event in self.events
            if not event_is_in_list(event, self.available_events)
        ]
        if unavailable_events:
            message = 'Events not available for tracing: {}'.format(
                ', '.join(unavailable_events)
            )
            if self.strict:
                raise TargetStableError(message)
            else:
                self.target.logger.warning(message)

        selected_events = sorted(set(self.events) - set(unavailable_events))

        if self.tracer and self.tracer not in self.available_tracers:
            raise TargetStableError('Unsupported tracer "{}". Available tracers: {}'.format(
                self.tracer, ', '.join(self.available_tracers)))

        # Check for function tracing support
        if self.functions:
            if not self.target.file_exists(self.function_profile_file):
                raise TargetStableError('Function profiling not supported. '\
                        'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
            # Validate required functions to be traced
            available_functions = self.target.execute(
                    'cat {}'.format(self.available_functions_file),
                    as_root=True).splitlines()
            selected_functions = []
            for function in self.functions:
                if function not in available_functions:
                    message = 'Function [{}] not available for profiling'.format(function)
                    if self.strict:
                        raise TargetStableError(message)
                    self.target.logger.warning(message)
                else:
                    selected_functions.append(function)

            if self.tracer is None:
                self.function_string = _build_trace_functions(selected_functions)
                # If function profiling is enabled we always need at least one event.
                # Thus, if not other events have been specified, try to add at least
                # a tracepoint which is always available and possibly triggered few
                # times.
                if not selected_events:
                    selected_events = ['sched_wakeup_new']
            elif self.tracer == 'function_graph':
                self.function_string = _build_graph_functions(selected_functions, trace_children_functions)

        self.event_string = _build_trace_events(selected_events)
Ejemplo n.º 26
0
    def __init__(self, target,
                 events=None,
                 functions=None,
                 buffer_size=None,
                 buffer_size_step=1000,
                 tracing_path='/sys/kernel/debug/tracing',
                 automark=True,
                 autoreport=True,
                 autoview=False,
                 no_install=False,
                 strict=False,
                 ):
        super(FtraceCollector, self).__init__(target)
        self.events = events if events is not None else DEFAULT_EVENTS
        self.functions = functions
        self.buffer_size = buffer_size
        self.buffer_size_step = buffer_size_step
        self.tracing_path = tracing_path
        self.automark = automark
        self.autoreport = autoreport
        self.autoview = autoview
        self.target_output_file = os.path.join(self.target.working_directory, OUTPUT_TRACE_FILE)
        self.target_binary = None
        self.host_binary = None
        self.start_time = None
        self.stop_time = None
        self.event_string = None
        self.function_string = None
        self._reset_needed = True

        # Setup tracing paths
        self.available_events_file    = self.target.path.join(self.tracing_path, 'available_events')
        self.available_functions_file = self.target.path.join(self.tracing_path, 'available_filter_functions')
        self.buffer_size_file         = self.target.path.join(self.tracing_path, 'buffer_size_kb')
        self.current_tracer_file      = self.target.path.join(self.tracing_path, 'current_tracer')
        self.function_profile_file    = self.target.path.join(self.tracing_path, 'function_profile_enabled')
        self.marker_file              = self.target.path.join(self.tracing_path, 'trace_marker')
        self.ftrace_filter_file       = self.target.path.join(self.tracing_path, 'set_ftrace_filter')

        self.host_binary = which('trace-cmd')
        self.kernelshark = which('kernelshark')

        if not self.target.is_rooted:
            raise TargetError('trace-cmd instrument cannot be used on an unrooted device.')
        if self.autoreport and self.host_binary is None:
            raise HostError('trace-cmd binary must be installed on the host if autoreport=True.')
        if self.autoview and self.kernelshark is None:
            raise HostError('kernelshark binary must be installed on the host if autoview=True.')
        if not no_install:
            host_file = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi, 'trace-cmd')
            self.target_binary = self.target.install(host_file)
        else:
            if not self.target.is_installed('trace-cmd'):
                raise TargetError('No trace-cmd found on device and no_install=True is specified.')
            self.target_binary = 'trace-cmd'

        # Validate required events to be traced
        available_events = self.target.execute(
                'cat {}'.format(self.available_events_file)).splitlines()
        selected_events = []
        for event in self.events:
            # Convert globs supported by FTrace into valid regexp globs
            _event = event
            if event[0] != '*':
                _event = '*' + event
            event_re = re.compile(_event.replace('*', '.*'))
            # Select events matching the required ones
            if len(filter(event_re.match, available_events)) == 0:
                message = 'Event [{}] not available for tracing'.format(event)
                if strict:
                    raise TargetError(message)
                self.target.logger.warning(message)
            else:
                selected_events.append(event)
        # If function profiling is enabled we always need at least one event.
        # Thus, if not other events have been specified, try to add at least
        # a tracepoint which is always available and possibly triggered few
        # times.
        if self.functions and len(selected_events) == 0:
            selected_events = ['sched_wakeup_new']
        self.event_string = _build_trace_events(selected_events)

        # Check for function tracing support
        if self.functions:
            if not self.target.file_exists(self.function_profile_file):
                raise TargetError('Function profiling not supported. '\
                        'A kernel build with CONFIG_FUNCTION_PROFILER enable is required')
            # Validate required functions to be traced
            available_functions = self.target.execute(
                    'cat {}'.format(self.available_functions_file)).splitlines()
            selected_functions = []
            for function in self.functions:
                if function not in available_functions:
                    message = 'Function [{}] not available for profiling'.format(function)
                    if strict:
                        raise TargetError(message)
                    self.target.logger.warning(message)
                else:
                    selected_functions.append(function)
            self.function_string = _build_trace_functions(selected_functions)
Ejemplo n.º 27
0
class AcmeCapeBackend(EnergyInstrumentBackend):

    name = 'acme_cape'
    description = """
    BayLibre ACME cape

    This backend relies on iio-capture utility:

        https://github.com/BayLibre/iio-capture

    For more information about ACME cape please see:

        https://baylibre.com/acme/

    """

    parameters = [
        Parameter('iio-capture',
                  default=which('iio-capture'),
                  description="""
                  Path to the iio-capture binary will be taken from the
                  environment, if not specfied.
                  """),
        Parameter('host',
                  default='baylibre-acme.local',
                  description="""
                  Host name (or IP address) of the ACME cape board.
                  """),
        Parameter('iio-devices',
                  default='iio:device0',
                  kind=list_or_string,
                  description="""
                  """),
        Parameter('buffer-size',
                  kind=int,
                  default=256,
                  description="""
                  Size of the capture buffer (in KB).
                  """),
    ]

    # pylint: disable=arguments-differ
    def get_instruments(self, target, metadir, iio_capture, host, iio_devices,
                        buffer_size):

        #
        # Devlib's ACME instrument uses iio-capture under the hood, which can
        # only capture data from one IIO device at a time. Devlib's instrument
        # API expects to produce a single CSV file for the Instrument, with a
        # single axis of sample timestamps. These two things cannot be correctly
        # reconciled without changing the devlib Instrument API - get_data would
        # need to be able to return two distinct sets of data.
        #
        # Instead, where required WA will instantiate the ACME instrument
        # multiple times (once for each IIO device), producing two separate CSV
        # files. Aggregated energy info _can_ be meaningfully combined from
        # multiple IIO devices, so we will later sum the derived stats across
        # each of the channels reported by the instruments.
        #

        ret = {}
        for iio_device in iio_devices:
            ret[iio_device] = AcmeCapeInstrument(target,
                                                 iio_capture=iio_capture,
                                                 host=host,
                                                 iio_device=iio_device,
                                                 buffer_size=buffer_size)
        return ret