Esempio n. 1
0
    def set_governor_tunables(self, cpu, governor=None, **kwargs):
        """
        Set tunables for the specified governor. Tunables should be specified as
        keyword arguments. Which tunables and values are valid depends on the
        governor.

        :param cpu: The cpu for which the governor will be set. This must be the
                    full cpu name as it appears in sysfs, e.g. ``cpu0``.
        :param governor: The name of the governor. Must be all lower case.

        The rest should be keyword parameters mapping tunable name onto the value to
        be set for it.

        :raises: TargetError if governor specified is not a valid governor name, or if
                 a tunable specified is not valid for the governor, or if could not set
                 tunable.

        """
        if isinstance(cpu, int):
            cpu = 'cpu{}'.format(cpu)
        if governor is None:
            governor = self.get_governor(cpu)
        valid_tunables = self.list_governor_tunables(cpu)
        for tunable, value in kwargs.iteritems():
            if tunable in valid_tunables:
                try:
                    path = '/sys/devices/system/cpu/{}/cpufreq/{}/{}'.format(
                        cpu, governor, tunable)
                    self.target.write_value(path, value)
                except TargetError:  # May be an older kernel
                    path = '/sys/devices/system/cpu/cpufreq/{}/{}'.format(
                        governor, tunable)
                    self.target.write_value(path, value)
            else:
                message = 'Unexpected tunable {} for governor {} on {}.\n'.format(
                    tunable, governor, cpu)
                message += 'Available tunables are: {}'.format(valid_tunables)
                raise TargetError(message)
Esempio n. 2
0
    def __init__(self, target):
        super(CgroupsModule, self).__init__(target)

        self.logger = logging.getLogger('CGroups')

        # Set Devlib's CGroups mount point
        self.cgroup_root = target.path.join(target.working_directory,
                                            'cgroups')

        # Get the list of the available controllers
        subsys = self.list_subsystems()
        if len(subsys) == 0:
            self.logger.warning('No CGroups controller available')
            return

        # Map hierarchy IDs into a list of controllers
        hierarchy = {}
        for ss in subsys:
            try:
                hierarchy[ss.hierarchy].append(ss.name)
            except KeyError:
                hierarchy[ss.hierarchy] = [ss.name]
        self.logger.debug('Available hierarchies: %s', hierarchy)

        # Initialize controllers
        self.logger.info('Available controllers:')
        self.controllers = {}
        for ss in subsys:
            hid = ss.hierarchy
            controller = Controller(ss.name, hid, hierarchy[hid])
            try:
                controller.mount(self.target, self.cgroup_root)
            except TargetError:
                message = 'Failed to mount "{}" controller'
                raise TargetError(message.format(controller.kind))
            self.logger.info('  %-12s : %s', controller.kind,
                             controller.mount_point)
            self.controllers[ss.name] = controller
Esempio n. 3
0
 def execute(self,
             command,
             timeout=None,
             check_exit_code=True,
             as_root=False,
             strip_colors=True):
     with self.lock:
         output = self._execute_and_wait_for_prompt(command, timeout,
                                                    as_root, strip_colors)
         if check_exit_code:
             exit_code_text = self._execute_and_wait_for_prompt(
                 'echo $?', strip_colors=strip_colors, log=False)
             try:
                 exit_code = int(exit_code_text.split()[0])
                 if exit_code:
                     message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
                     raise TargetError(
                         message.format(exit_code, command, output))
             except (ValueError, IndexError):
                 logger.warning(
                     'Could not get exit code for "{}",\ngot: "{}"'.format(
                         command, exit_code_text))
         return output
Esempio n. 4
0
 def __call__(self, image_bundle=None, images=None, bootargs=None):
     self.target.hard_reset()
     with open_serial_connection(port=self.target.platform.serial_port,
                                 baudrate=self.target.platform.baudrate,
                                 timeout=self.timeout,
                                 init_dtr=0) as tty:
         i = tty.expect(
             [self.mcc_prompt, AUTOSTART_MESSAGE, OLD_AUTOSTART_MESSAGE])
         if i:
             tty.sendline('')
         wait_for_vemsd(self.vemsd_mount, tty, self.mcc_prompt,
                        self.short_delay)
     try:
         if image_bundle:
             self._deploy_image_bundle(image_bundle)
         if images:
             self._overlay_images(images)
         os.system('sync')
     except (IOError, OSError) as e:
         msg = 'Could not deploy images to {}; got: {}'
         raise TargetError(msg.format(self.vemsd_mount, e))
     self.target.boot()
     self.target.connect(timeout=30)
Esempio n. 5
0
File: ssh.py Progetto: nuxeh/devlib
 def background(self,
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                as_root=False):
     try:
         port_string = '-p {}'.format(self.port) if self.port else ''
         keyfile_string = '-i {}'.format(
             self.keyfile) if self.keyfile else ''
         if as_root:
             command = "sudo -- sh -c '{}'".format(command)
         command = '{} {} {} {}@{} {}'.format(ssh, keyfile_string,
                                              port_string, self.username,
                                              self.host, command)
         logger.debug(command)
         if self.password:
             command = _give_password(self.password, command)
         return subprocess.Popen(command,
                                 stdout=stdout,
                                 stderr=stderr,
                                 shell=True)
     except EOF:
         raise TargetError('Connection lost.')
Esempio n. 6
0
    def __init__(self, target):
        super(CgroupsModule, self).__init__(target)

        self.logger = logging.getLogger('CGroups')

        # Initialize controllers mount point
        mounted = self.target.list_file_systems()
        if self.cgroup_root not in [e.mount_point for e in mounted]:
            self.target.execute('mount -t tmpfs {} {}'\
                    .format('cgroup_root',
                            self.cgroup_root),
                            as_root=True)
        else:
            self.logger.debug('cgroup_root already mounted at %s',
                              self.cgroup_root)

        # Load list of available controllers
        controllers = []
        subsys = self.list_subsystems()
        for (n, h, c, e) in subsys:
            controllers.append(n)
        self.logger.debug('Available controllers: %s', controllers)

        # Initialize controllers
        self.controllers = {}
        for idx in controllers:
            controller = Controller(idx)
            self.logger.debug('Init %s controller...', controller.kind)
            if not controller.probe(self.target):
                continue
            try:
                controller.mount(self.target, self.cgroup_root)
            except TargetError:
                message = 'cgroups {} controller is not supported by the target'
                raise TargetError(message.format(controller.kind))
            self.logger.debug('Controller %s enabled', controller.kind)
            self.controllers[idx] = controller
Esempio n. 7
0
    def kick_off(self, command, as_root=False):
        """
        Like execute but closes adb session and returns immediately, leaving the command running on the
        device (this is different from execute(background=True) which keeps adb connection open and returns
        a subprocess object).

        .. note:: This relies on busybox's nohup applet and so won't work on unrooted devices.

        """
        if not self.is_rooted:
            raise TargetError(
                'kick_off uses busybox\'s nohup applet and so can only be run a rooted device.'
            )
        try:
            command = 'cd {} && {} nohup {}'.format(self.working_directory,
                                                    self.bin('busybox'),
                                                    command)
            output = self.execute(command, timeout=1, as_root=as_root)
        except TimeoutError:
            pass
        else:
            raise ValueError(
                'Background command exited before timeout; got "{}"'.format(
                    output))
Esempio n. 8
0
def ssh_get_shell(host,
                  username,
                  password=None,
                  keyfile=None,
                  port=None,
                  timeout=10,
                  telnet=False):
    _check_env()
    if telnet:
        if keyfile:
            raise ValueError(
                'keyfile may not be used with a telnet connection.')
        conn = TelnetConnection()
    else:  # ssh
        conn = pxssh.pxssh()
    try:
        if keyfile:
            conn.login(host,
                       username,
                       ssh_key=keyfile,
                       port=port,
                       login_timeout=timeout)
        else:
            conn.login(host,
                       username,
                       password,
                       port=port,
                       login_timeout=timeout)
    except EOF:
        raise TargetError(
            'Could not connect to {}; is the host name correct?'.format(host))
    conn.setwinsize(500, 200)
    conn.sendline('')
    conn.prompt()
    conn.setecho(False)
    return conn
Esempio n. 9
0
    def __init__(self, target):
        if not hasattr(target, 'hwmon'):
            raise TargetError('Target does not support HWMON')
        super(HwmonInstrument, self).__init__(target)

        self.logger.debug('Discovering available HWMON sensors...')
        for ts in self.target.hwmon.sensors:
            try:
                ts.get_file('input')
                measure = self.measure_map.get(ts.kind)[0]
                if measure:
                    self.logger.debug('\tAdding sensor {}'.format(ts.name))
                    self.add_channel(_guess_site(ts),
                                     measure,
                                     name=ts.name,
                                     sensor=ts)
                else:
                    self.logger.debug(
                        '\tSkipping sensor {} (unknown kind "{}")'.format(
                            ts.name, ts.kind))
            except ValueError:
                message = 'Skipping sensor {} because it does not have an input file'
                self.logger.debug(message.format(ts.name))
                continue
Esempio n. 10
0
 def _check_ready(self):
     """
     Check if the gem5 platform is ready
     """
     if not self.ready:
         raise TargetError('Gem5 is not ready to interact yet')
Esempio n. 11
0
 def _gem5_util(self, command):
     """ Execute a gem5 utility command using the m5 binary on the device """
     if self.m5_path is None:
         raise TargetError('Path to m5 binary on simulated system  is not set!')
     self._gem5_shell('{} {}'.format(self.m5_path, command))
Esempio n. 12
0
    def _gem5_shell(self, command, as_root=False, timeout=None, check_exit_code=True, sync=True):  # pylint: disable=R0912
        """
        Execute a command in the gem5 shell

        This wraps the telnet connection to gem5 and processes the raw output.

        This method waits for the shell to return, and then will try and
        separate the output from the command from the command itself. If this
        fails, warn, but continue with the potentially wrong output.

        The exit code is also checked by default, and non-zero exit codes will
        raise a TargetError.
        """
        if sync:
            self._sync_gem5_shell()

        gem5_logger.debug("gem5_shell command: {}".format(command))

        if as_root:
            command = 'echo "{}" | su'.format(escape_double_quotes(command))

        # Send the actual command
        self.conn.send("{}\n".format(command))

        # Wait for the response. We just sit here and wait for the prompt to
        # appear, as gem5 might take a long time to provide the output. This
        # avoids timeout issues.
        command_index = -1
        while command_index == -1:
            if self.conn.prompt():
                output = re.sub(r' \r([^\n])', r'\1', self.conn.before)
                output = re.sub(r'[\b]', r'', output)
                # Deal with line wrapping
                output = re.sub(r'[\r].+?<', r'', output)
                command_index = output.find(command)

                # If we have -1, then we cannot match the command, but the
                # prompt has returned. Hence, we have a bit of an issue. We
                # warn, and return the whole output.
                if command_index == -1:
                    gem5_logger.warn("gem5_shell: Unable to match command in "
                                     "command output. Expect parsing errors!")
                    command_index = 0

        output = output[command_index + len(command):].strip()

        # If the gem5 system echoes the executed command, we need to remove that too!
        if self.strip_echoed_commands:
            command_index = output.find(command)
            if command_index != -1:
                output = output[command_index + len(command):].strip()

        gem5_logger.debug("gem5_shell output: {}".format(output))

        # We get a second prompt. Hence, we need to eat one to make sure that we
        # stay in sync. If we do not do this, we risk getting out of sync for
        # slower simulations.
        self.conn.expect([self.conn.UNIQUE_PROMPT, self.conn.PROMPT], timeout=self.default_timeout)

        if check_exit_code:
            exit_code_text = self._gem5_shell('echo $?', as_root=as_root,
                                             timeout=timeout, check_exit_code=False,
                                             sync=False)
            try:
                exit_code = int(exit_code_text.split()[0])
                if exit_code:
                    message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
                    raise TargetError(message.format(exit_code, command, output))
            except (ValueError, IndexError):
                gem5_logger.warning('Could not get exit code for "{}",\ngot: "{}"'.format(command, exit_code_text))

        return output
Esempio n. 13
0
    def connect_gem5(self, port, gem5_simulation, gem5_interact_dir,
                      gem5_out_dir):
        """
        Connect to the telnet port of the gem5 simulation.

        We connect, and wait for the prompt to be found. We do not use a timeout
        for this, and wait for the prompt in a while loop as the gem5 simulation
        can take many hours to reach a prompt when booting the system. We also
        inject some newlines periodically to try and force gem5 to show a
        prompt. Once the prompt has been found, we replace it with a unique
        prompt to ensure that we are able to match it properly. We also disable
        the echo as this simplifies parsing the output when executing commands
        on the device.
        """
        host = socket.gethostname()
        gem5_logger.info("Connecting to the gem5 simulation on port {}".format(port))

        # Check if there is no on-going connection yet
        lock_file_name = '{}{}_{}.LOCK'.format(self.lock_directory, host, port)
        if os.path.isfile(lock_file_name):
            # There is already a connection to this gem5 simulation
            raise TargetError('There is already a connection to the gem5 '
                              'simulation using port {} on {}!'
                              .format(port, host))

        # Connect to the gem5 telnet port. Use a short timeout here.
        attempts = 0
        while attempts < 10:
            attempts += 1
            try:
                self.conn = TelnetPxssh(original_prompt=None)
                self.conn.login(host, self.username, port=port,
                                login_timeout=10, auto_prompt_reset=False)
                break
            except pxssh.ExceptionPxssh:
                pass
            except EOF as err:
                self._gem5_EOF_handler(gem5_simulation, gem5_out_dir, err)
        else:
            gem5_simulation.kill()
            raise TargetError("Failed to connect to the gem5 telnet session.")

        gem5_logger.info("Connected! Waiting for prompt...")

        # Create the lock file
        self.lock_file_name = lock_file_name
        open(self.lock_file_name, 'w').close() # Similar to touch
        gem5_logger.info("Created lock file {} to prevent reconnecting to "
                         "same simulation".format(self.lock_file_name))

        # We need to find the prompt. It might be different if we are resuming
        # from a checkpoint. Therefore, we test multiple options here.
        prompt_found = False
        while not prompt_found:
            try:
                self._login_to_device()
            except TIMEOUT:
                pass
            except EOF as err:
                self._gem5_EOF_handler(gem5_simulation, gem5_out_dir, err)

            try:
                # Try and force a prompt to be shown
                self.conn.send('\n')
                self.conn.expect([r'# ', r'\$ ', self.conn.UNIQUE_PROMPT, r'\[PEXPECT\][\\\$\#]+ '], timeout=60)
                prompt_found = True
            except TIMEOUT:
                pass
            except EOF as err:
                self._gem5_EOF_handler(gem5_simulation, gem5_out_dir, err)

        gem5_logger.info("Successfully logged in")
        gem5_logger.info("Setting unique prompt...")

        self.conn.set_unique_prompt()
        self.conn.prompt()
        gem5_logger.info("Prompt found and replaced with a unique string")

        # We check that the prompt is what we think it should be. If not, we
        # need to update the regex we use to match.
        self._find_prompt()

        self.conn.setecho(False)
        self._sync_gem5_shell()

        # Fully connected to gem5 simulation
        self.gem5_interact_dir = gem5_interact_dir
        self.gem5_out_dir = gem5_out_dir
        self.gem5simulation = gem5_simulation

        # Ready for interaction now
        self.ready = True
Esempio n. 14
0
            attempts += 1
            try:
                self.conn = TelnetPxssh(original_prompt=None)
                self.conn.login(host,
                                self.username,
                                port=port,
                                login_timeout=10,
                                auto_prompt_reset=False)
                break
            except pxssh.ExceptionPxssh:
                pass
            except EOF, err:
                self._gem5_EOF_handler(gem5_simulation, gem5_out_dir, err)
        else:
            gem5_simulation.kill()
            raise TargetError("Failed to connect to the gem5 telnet session.")

        gem5_logger.info("Connected! Waiting for prompt...")

        # Create the lock file
        self.lock_file_name = lock_file_name
        open(self.lock_file_name, 'w').close()  # Similar to touch
        gem5_logger.info("Created lock file {} to prevent reconnecting to "
                         "same simulation".format(self.lock_file_name))

        # We need to find the prompt. It might be different if we are resuming
        # from a checkpoint. Therefore, we test multiple options here.
        prompt_found = False
        while not prompt_found:
            try:
                self._login_to_device()
Esempio n. 15
0
 def install_apk(self, filepath, timeout=None):  # pylint: disable=W0221
     ext = os.path.splitext(filepath)[1].lower()
     if ext == '.apk':
         return adb_command(self.adb_name, "install '{}'".format(filepath), timeout=timeout)
     else:
         raise TargetError('Can\'t install {}: unsupported format.'.format(filepath))
Esempio n. 16
0
def _overwritten_reboot(self):
    raise TargetError('Rebooting is not allowed on gem5 platforms!')
Esempio n. 17
0
 def check_target(self):
     if not self.target.has('cpuidle'):
         raise TargetError('Target does not appear to support cpuidle')
Esempio n. 18
0
 def check_target(self):
     if not self.target.has('hotplug'):
         raise TargetError('Target does not appear to support hotplug')
Esempio n. 19
0
 def roi_start(self, label):
     if label not in self.rois:
         raise KeyError('Incorrect ROI label: {}'.format(label))
     if not self.rois[label].start():
         raise TargetError('ROI {} was already running'.format(label))
Esempio n. 20
0
def adb_shell(device,
              command,
              timeout=None,
              check_exit_code=False,
              as_root=False,
              adb_server=None):  # NOQA
    _check_env()
    if as_root:
        command = 'echo \'{}\' | su'.format(escape_single_quotes(command))
    device_part = []
    if adb_server:
        device_part = ['-H', adb_server]
    device_part += ['-s', device] if device else []

    # On older combinations of ADB/Android versions, the adb host command always
    # exits with 0 if it was able to run the command on the target, even if the
    # command failed (https://code.google.com/p/android/issues/detail?id=3254).
    # Homogenise this behaviour by running the command then echoing the exit
    # code.
    adb_shell_command = '({}); echo \"\n$?\"'.format(command)
    actual_command = ['adb'] + device_part + ['shell', adb_shell_command]
    logger.debug('adb {} shell {}'.format(' '.join(device_part), command))
    try:
        raw_output, error = check_output(actual_command, timeout, shell=False)
    except subprocess.CalledProcessError as e:
        raise TargetError(str(e))

    if raw_output:
        try:
            output, exit_code, _ = raw_output.replace('\r\n', '\n').replace(
                '\r', '\n').rsplit('\n', 2)
        except ValueError:
            exit_code, _ = raw_output.replace('\r\n', '\n').replace(
                '\r', '\n').rsplit('\n', 1)
            output = ''
    else:  # raw_output is empty
        exit_code = '969696'  # just because
        output = ''

    if check_exit_code:
        exit_code = exit_code.strip()
        re_search = AM_START_ERROR.findall('{}\n{}'.format(output, error))
        if exit_code.isdigit():
            if int(exit_code):
                message = ('Got exit code {}\nfrom target command: {}\n'
                           'STDOUT: {}\nSTDERR: {}')
                raise TargetError(
                    message.format(exit_code, command, output, error))
            elif re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
        else:  # not all digits
            if re_search:
                message = 'Could not start activity; got the following:\n{}'
                raise TargetError(message.format(re_search[0]))
            else:
                message = 'adb has returned early; did not get an exit code. '\
                          'Was kill-server invoked?\nOUTPUT:\n-----\n{}\n'\
                          '-----\nERROR:\n-----\n{}\n-----'
                raise TargetError(message.format(raw_output, error))

    return output
Esempio n. 21
0
 def roi_end(self, label):
     if label not in self.rois:
         raise KeyError('Incorrect ROI label: {}'.format(label))
     if not self.rois[label].stop():
         raise TargetError('ROI {} was not running'.format(label))
    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)
Esempio n. 23
0
    def __init__(self,
                 platform,
                 host=None,
                 username=None,
                 password=None,
                 port=None,
                 timeout=None,
                 password_prompt=None,
                 original_prompt=None,
                 strip_echoed_commands=False,
                 ):
        if host is not None:
            host_system = socket.gethostname()
            if host_system != host:
                raise TargetError("Gem5Connection can only connect to gem5 "
                                   "simulations on your current host, which "
                                   "differs from the one given {}!"
                                   .format(host_system, host))
        if username is not None and username != 'root':
            raise ValueError('User should be root in gem5!')
        if password is not None and password != '':
            raise ValueError('No password needed in gem5!')
        self.username = '******'
        self.is_rooted = True
        self.password = None
        self.port = None
        # Flag to indicate whether commands are echoed by the simulated system
        self.strip_echoed_commands = strip_echoed_commands
        # Long timeouts to account for gem5 being slow
        # Can be overriden if the given timeout is longer
        self.default_timeout = 3600
        if timeout is not None:
            if timeout > self.default_timeout:
                logger.info('Overwriting the default timeout of gem5 ({})'
                                 ' to {}'.format(self.default_timeout, timeout))
                self.default_timeout = timeout
            else:
                logger.info('Ignoring the given timeout --> gem5 needs longer timeouts')
        self.ready_timeout = self.default_timeout * 3
        # Counterpart in gem5_interact_dir
        self.gem5_input_dir = '/mnt/host/'
        # Location of m5 binary in the gem5 simulated system
        self.m5_path = None
        # Actual telnet connection to gem5 simulation
        self.conn = None
        # Flag to indicate the gem5 device is ready to interact with the
        # outer world
        self.ready = False
        # Lock file to prevent multiple connections to same gem5 simulation
        # (gem5 does not allow this)
        self.lock_directory = '/tmp/'
        self.lock_file_name = None # Will be set once connected to gem5

        # These parameters will be set by either the method to connect to the
        # gem5 platform or directly to the gem5 simulation
        # Intermediate directory to push things to gem5 using VirtIO
        self.gem5_interact_dir = None
        # Directory to store output  from gem5 on the host
        self.gem5_out_dir = None
        # Actual gem5 simulation
        self.gem5simulation = None

        # Connect to gem5
        if platform:
            self._connect_gem5_platform(platform)

        # Wait for boot
        self._wait_for_boot()

        # Mount the virtIO to transfer files in/out gem5 system
        self._mount_virtio()
Esempio n. 24
0
 def set_governor(self, governor):
     if governor not in self.governors:
         raise TargetError('Governor {} not supported for gpu {}'.format(governor, cpu))
     self.target.write_value("/sys/kernel/gpu/gpu_governor", governor)
Esempio n. 25
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))