コード例 #1
0
def run_command(command, ignore_output=False):
    """Runs a command via subprocess communication.

    Args:
        command: The command.
        ignore_output: (OPTIONAL) Whether to ignore the output. Defaults to
            False.

    Returns:
        A tuple containing (the output, the return code).
    """
    printf('Running command {}'.format(command),
           print_type=PrintType.DEBUG_LOG)

    try:
        args = shlex.split(command)
        p = subprocess.Popen(args,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             preexec_fn=os.setsid)

        ProcessManager.add_process(command, p)

        if ignore_output:
            return None, _wait_for_process(command, p)

        return _communicate_to_process(command, p)
    except (ValueError, subprocess.CalledProcessError,
            FileNotFoundError) as err:
        printf('Command {} erred:\n{}'.format(command, err),
               print_type=PrintType.ERROR_LOG)
        return None, None
    finally:
        ProcessManager.clear_process(command)
コード例 #2
0
ファイル: workloads.py プロジェクト: UOFL-CSL/iobs
    def process_with_repetitions(self, output_configuration, file, device,
                                 scheduler, job_type, repetitions,
                                 template_setting_permutation,
                                 environment_setting_permutation,
                                 enable_blktrace):
        """Process the workload for the template permutation and repetitions.

        Args:
            output_configuration: The OutputConfiguration.
            file: The input file.
            device: The device to execute on.
            scheduler: The schedulers to execute with.
            job_type: The job type.
            repetitions: The number of repetitions.
            template_setting_permutation: The template setting permutation.
            environment_setting_permutation: The environment setting permutation.
            enable_blktrace: Whether blktrace is enabled.
        """
        for rep in range(repetitions):
            printf(
                'Executing file {} with device {}, scheduler {}, repetition '
                '{} of {}'.format(file, device, scheduler, rep + 1,
                                  repetitions),
                print_type=PrintType.INFO_LOG)

            output = self._try_process(job_type, file, device, scheduler,
                                       enable_blktrace)
            output_configuration.process(output, self._name, device, scheduler,
                                         template_setting_permutation,
                                         environment_setting_permutation,
                                         enable_blktrace)
コード例 #3
0
def run_command_nowait(command):
    """Runs a command via subprocess communication, and does not communicate
       with it for completion. It instead returns the process so the caller
       can handle it.

    Args:
        command: The command.

    Returns:
        The Process, or None if erred.
    """
    printf('Running command {}'.format(command),
           print_type=PrintType.DEBUG_LOG)

    try:
        args = shlex.split(command)
        p = subprocess.Popen(args,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             preexec_fn=os.setsid)

        ProcessManager.add_process(command, p)
        return p

    except (ValueError, subprocess.CalledProcessError,
            FileNotFoundError) as err:
        printf('Command {} erred:\n{}'.format(command, err),
               print_type=PrintType.ERROR_LOG)
        ProcessManager.clear_process(command)
        return None
コード例 #4
0
ファイル: __main__.py プロジェクト: UOFL-CSL/iobs
def main():
    try:
        return dispatch(sys.argv[1:])
    except IOBSBaseException as err:
        printf('Program encountered critical error\n{}'.format(err),
               print_type=PrintType.ERROR | PrintType.ERROR_LOG)
        return '{}: {}'.format(err.__class__.__name__, err.args[0])
コード例 #5
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def restore_system_environment(self):
        """Restores system environment.

        NOTE: This should be called after `save_environment` has been called.
        """
        printf('Restoring system information...',
               print_type=PrintType.DEBUG_LOG)

        se = self._system_environment
        change_randomize_va_space(se['randomize_va_space'])
コード例 #6
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def validate(self):
        """Validates the configuration."""
        printf('Validating input file {}'.format(self._input_file),
               print_type=PrintType.DEBUG_LOG)

        self._environment_configuration.validate()
        self._global_configuration.validate()
        self._output_configuration.validate()
        self._template_configuration.validate()

        for wc in self._workload_configurations:
            wc.validate()
コード例 #7
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def process(self):
        """Processes the configuration."""
        printf('Processing input file {}'.format(self._input_file),
               print_type=PrintType.DEBUG_LOG)

        if self._workload_type == 'filebench':
            change_randomize_va_space(0)

        for wc in self._workload_configurations:
            wc.process(self._job_type, self._output_configuration,
                       self._global_configuration,
                       self._template_configuration,
                       self._environment_configuration)
コード例 #8
0
def parse_section(config_parser, section, config):
    """Parses a section of a config file.

    Args:
        config_parser: The config parser.
        section: The section name.
        config: The Configuration object.
    """
    printf('Parsing section {}'.format(section),
           print_type=PrintType.DEBUG_LOG)

    for key, value in config_parser[section].items():
        config.add_setting(key, value)
コード例 #9
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def save_system_environment(self):
        """Saves system environment information so it can be restored.

        NOTE: This should be called after `validate` has bee called.
        """
        printf('Saving system information...', print_type=PrintType.DEBUG_LOG)

        self._system_environment = {
            'randomize_va_space': get_randomize_va_space()
        }

        printf('Saving system environment: {}'.format(
            self._system_environment),
               print_type=PrintType.DEBUG_LOG)
コード例 #10
0
def is_block_device(device):
    """Returns whether the given device is a valid block device.

    Args:
        device: The device.

    Returns:
        True if is a valid block device, else False.
    """
    printf('Checking if device {} is a valid block device'.format(device),
           print_type=PrintType.DEBUG_LOG)

    try:
        if stat.S_ISBLK(os.stat(device).st_mode):
            printf('Device {} is a valid block device'.format(device),
                   print_type=PrintType.DEBUG_LOG)
            return True

        printf('Device {} is not a valid block device'.format(device),
               print_type=PrintType.ERROR_LOG)
        return False
    except (FileNotFoundError, TypeError):
        printf('Device {} is not a valid block device'.format(device),
               print_type=PrintType.ERROR_LOG)
        return False
コード例 #11
0
ファイル: __main__.py プロジェクト: UOFL-CSL/iobs
def sig_handler(signal, frame):
    """Signal handler for termination signals sent to main process.

    Args:
        signal: The signal.
        frame: The frame.
    """
    printf('Program encountered termination signal, aborting...',
           print_type=PrintType.ERROR | PrintType.ERROR_LOG)

    ProcessManager.kill_processes()
    ProcessManager.clear_processes()

    colorama.deinit()

    sys.exit(1)
コード例 #12
0
def get_randomize_va_space():
    """Returns the current randomize_va_space for the system.

    Returns:
        The current randomize_va_space setting.
    """
    printf('Retrieving randomize_va_space for system',
           print_type=PrintType.DEBUG_LOG)

    out, rc = run_command('cat /proc/sys/kernel/randomize_va_space')

    if rc != 0:
        printf('Unable to find randomize_va_space for system',
               print_type=PrintType.ERROR_LOG)
        return []

    return int(out)
コード例 #13
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def save_device_environments(self):
        """Saves device environment information so it can be restored.

        NOTE: This should be called after `validate` has bee called.
        """
        printf('Saving device information...', print_type=PrintType.DEBUG_LOG)

        for device in self._global_configuration.devices:
            self._device_environments[device] = {
                'nomerges': get_device_nomerges(device),
                'scheduler': get_device_scheduler(device)
            }

            de = self._device_environments[device]

            printf('Saving device {} environment: {}'.format(device, de),
                   print_type=PrintType.DEBUG_LOG)
コード例 #14
0
def _wait_for_process(command, p):
    """Waits for a process to complete.

    Args:
        command: The command.
        p: The process.

    Returns:
        The return code.
    """
    rc = p.wait()

    if rc != 0:
        printf('Command {} [{}] erred with return code {}'.format(
            command, p.pid, rc),
               print_type=PrintType.ERROR_LOG)
    return rc
コード例 #15
0
def terminate_process(process):
    """Terminates a process.

    Args:
        process: The process.

    Returns:
        A tuple of the output and return code.
    """
    process.terminate()
    out, err = process.communicate()
    rc = process.returncode

    if err:
        printf('Process [{}] erred with return code {}:\n{}'.format(
            process.pid, rc, err.decode('utf-8')),
               print_type=PrintType.ERROR_LOG)

    return out.decode('utf-8'), rc
コード例 #16
0
def _communicate_to_process(command, p):
    """Communicates to a process.

    Args:
        command: The command.
        p: The process.

    Returns:
        A tuple of the output and return code.
    """
    out, err = p.communicate()
    rc = p.returncode

    if err:
        printf('Command {} [{}] erred with return code {}:\n{}'.format(
            command, p.pid, rc, err.decode('utf-8')),
               print_type=PrintType.ERROR_LOG)

    return out.decode('utf-8'), rc
コード例 #17
0
def check_command(command):
    """Returns whether the given command exists on the system.

    Args:
        command: The command.

    Returns:
        True if exists, else False.
    """
    printf('Checking if command {} exists'.format(command),
           print_type=PrintType.DEBUG_LOG)

    if run_system_command('command -v {}'.format(command)) == 0:
        return True

    printf('Command {} does not exist'.format(command),
           print_type=PrintType.ERROR_LOG)

    return False
コード例 #18
0
ファイル: base.py プロジェクト: UOFL-CSL/iobs
    def restore_device_environments(self):
        """Restores device environments.

        NOTE: This should be called after `save_device_environments` has been
        called.
        """
        printf('Restoring device information...',
               print_type=PrintType.DEBUG_LOG)

        for device in self._global_configuration.devices:
            if device not in self._device_environments:
                continue

            de = self._device_environments[device]

            printf('Restoring device {} environment: {}'.format(device, de),
                   print_type=PrintType.DEBUG_LOG)

            change_nomerges(device, de['nomerges'])
            change_scheduler(device, de['scheduler'])
コード例 #19
0
def clear_caches(device):
    """Clears various data caches. Should be run before each benchmark.

    Args:
        device: The device.
    """
    printf('Clearing caches for device {}'.format(device),
           print_type=PrintType.DEBUG_LOG)

    # Writes any data buffered in memory out to disk
    run_system_command('sync')

    # Drops clean caches
    run_system_command('echo 3 > /proc/sys/vm/drop_caches')

    # Calls block device ioctls to flush buffers
    run_system_command('blockdev --flushbufs {}'.format(device))

    # Flushes the on-drive write cache buffer
    run_system_command('hdparm -F {}'.format(device))
コード例 #20
0
def validate(args):
    """Validates workloads.

    Args:
        args: The parsed command-line arguments.

    Returns:
        0 if successful.

    Raises:
        IOBSBaseException: If error occurs and `continue_on_failure` not set.
    """
    validate_os()
    validate_privileges()

    printf('Beginning program validation...',
           print_type=PrintType.NORMAL | PrintType.INFO_LOG)

    for i, input_file in enumerate(args.inputs):
        printf('Validating input file {} ({} of {})'
               .format(input_file, i + 1, len(args.inputs)))

        configuration = parse_config_file(input_file)
        configuration.validate()

    printf('Finishing program validation...',
           print_type=PrintType.NORMAL | PrintType.INFO_LOG)

    return 0
コード例 #21
0
ファイル: workloads.py プロジェクト: UOFL-CSL/iobs
    def _try_process(self, job_type, file, device, scheduler, enable_blktrace):
        """Attempts to process a job with retrying if failure.

        Args:
            job_type: The job type.
            file: The input file.
            device: The device to execute on.
            scheduler: The scheduler to execute with.
            enable_blktrace: Whether blktrace is enabled.

        Returns:
            The output of processing the job.

        Raises:
            RetryCountExceededError: If job fails and retry counts are exceeded.
        """
        retry_count = SettingsManager.get('retry_count')

        for retry in range(retry_count):
            if retry != 0:
                printf('Retrying job...', print_type=PrintType.DEBUG_LOG)

            job = job_type(file, device, scheduler)

            try:
                ret = job.process(enable_blktrace)

                if SettingsManager.get('cleanup_files'):
                    device_name = match_regex(device, 'device_name')
                    files = get_formatter('cleanup_blktrace').format(
                        device_name)
                    cleanup_files(files)

                return ret
            except (JobExecutionError, OutputParsingError) as err:
                printf('Unable to run job \n{}'.format(err),
                       print_type=PrintType.ERROR_LOG)

        raise RetryCountExceededError(
            'Unable to run job, exceeded retry counts')
コード例 #22
0
ファイル: workloads.py プロジェクト: UOFL-CSL/iobs
    def process(self, job_type, output_configuration, global_configuration,
                template_configuration, environment_configuration):
        """Process the workload.

        Args:
            job_type: The Job.
            output_configuration: The OutputConfiguration.
            template_configuration: The TemplateConfiguration.
            global_configuration: The GlobalConfiguration.
            environment_configuration: The EnvironmentConfiguration.
        """
        printf('Processing workload {}'.format(self._name),
               print_type=PrintType.INFO_LOG)

        devices = global_configuration.devices
        schedulers = global_configuration.schedulers
        repetitions = global_configuration.repetitions
        enable_blktrace = global_configuration.enable_blktrace

        for device, scheduler in itertools.product(devices, schedulers):
            for file, tsp in template_configuration.get_file_permutations(
                    self.file, device, scheduler):
                printf('Using template permutation {}'.format(tsp),
                       print_type=PrintType.INFO_LOG)

                for esp in environment_configuration.get_environment_permutations(
                        device):
                    printf('Using environment permutation {}'.format(esp),
                           print_type=PrintType.INFO_LOG)

                    self.process_with_repetitions(output_configuration, file,
                                                  device, scheduler, job_type,
                                                  repetitions, tsp, esp,
                                                  enable_blktrace)
コード例 #23
0
def is_rotational_device(device):
    """Returns whether the given device is a rotational device.

    Args:
        device: The device.

    Returns:
        True if is a rotational device, else False.
    """
    printf('Checking whether device {} is a rotational device'.format(device),
           print_type=PrintType.DEBUG_LOG)

    device_name = match_regex(device, 'device_name')

    if not device_name:
        return False

    out, rc = run_command(
        'cat /sys/block/{}/queue/rotational'.format(device_name))

    if rc != 0:
        return False

    if int(out) == 1:
        printf('Device {} is a rotational device'.format(device),
               print_type=PrintType.DEBUG_LOG)
    else:
        printf('Device {} is not a rotational device'.format(device),
               print_type=PrintType.DEBUG_LOG)

    return int(out) == 1
コード例 #24
0
def get_schedulers_for_device(device):
    """Returns a list of available schedulers for a given device.

    Args:
        device: The device.

    Returns:
        A list of schedulers.
    """
    printf('Retrieving schedulers for device {}'.format(device),
           print_type=PrintType.DEBUG_LOG)

    device_name = match_regex(device, 'device_name')

    out, rc = run_command(
        'cat /sys/block/{}/queue/scheduler'.format(device_name))

    if rc != 0:
        printf('Unable to find schedulers for device',
               print_type=PrintType.ERROR_LOG)
        return []

    ret = out.strip().replace('[', '').replace(']', '')

    printf('Found the following schedulers for device {}: '
           '{}'.format(device, ret),
           print_type=PrintType.DEBUG_LOG)

    return ret.split()
コード例 #25
0
def get_device_scheduler(device):
    """Returns the current scheduler for the device.

    Args:
        device: The device.

    Returns:
        The current scheduler.
    """
    printf('Retrieving schedulers for device {}'.format(device),
           print_type=PrintType.DEBUG_LOG)

    device_name = match_regex(device, 'device_name')

    out, rc = run_command(
        'cat /sys/block/{}/queue/scheduler'.format(device_name))

    if rc != 0:
        printf('Unable to find schedulers for device',
               print_type=PrintType.ERROR_LOG)
        return []

    l, r = out.index('['), out.index(']')
    ret = out[l + 1:r]

    printf('Found the current scheduler for device {}: '
           '{}'.format(device, ret),
           print_type=PrintType.DEBUG_LOG)

    return ret
コード例 #26
0
def get_device_major_minor(device):
    """Returns a string of the major, minor of a given device.

    Args:
        device: The device.

    Returns:
        A string of major,minor.
    """
    printf('Retrieving major,minor for device {}'.format(device),
           print_type=PrintType.DEBUG_LOG)

    out, _ = run_command('stat -c \'%%t,%%T\' {}'.format(device))

    if not out:
        printf(
            'Unable to retrieve major,minor information for device {}'.format(
                device),
            print_Type=PrintType.ERROR_LOG)
        return None

    out = out.strip()
    printf('major,minor for device {} is {}'.format(device, out),
           print_Type=PrintType.DEBUG_LOG)

    return out
コード例 #27
0
def change_scheduler(device, scheduler):
    """Changes the I/O scheduler for the given device.

    Args:
        device: The device.
        scheduler: The I/O scheduler.

    Returns:
        True if successful, else False.
    """
    printf('Changing scheduler for device {} to {}'.format(device, scheduler),
           print_type=PrintType.DEBUG_LOG)

    command = 'bash -c "echo {} > /sys/block/{}/queue/scheduler"' \
              .format(scheduler, match_regex(device, 'device_name'))

    _, rc = run_command(command)

    if rc != 0:
        raise SchedulerChangeError(
            'Unable to change scheduler to {} for device {}'.format(
                scheduler, device))
コード例 #28
0
def change_nomerges(device, nomerges):
    """Changes the nomerges setting for the given device.

    Args:
        device: The device.
        nomerges: The nomerges setting.

    Returns:
        True if successful, else False.
    """
    printf('Changing nomerges for device {} to {}'.format(device, nomerges),
           print_type=PrintType.DEBUG_LOG)

    command = 'bash -c "echo {} > /sys/block/{}/queue/nomerges"' \
              .format(nomerges, match_regex(device, 'device_name'))

    _, rc = run_command(command)

    if rc != 0:
        raise DeviceSettingChangeError(
            'Unable to change nomerges to {} for device {}'.format(
                nomerges, device))
コード例 #29
0
def change_randomize_va_space(randomize_va_space):
    """Changes the randomize_va_space setting for the given device.

    Args:
        randomize_va_space: The randomize_va_space setting.

    Returns:
        True if successful, else False.
    """
    printf('Changing randomize_va_space for system to {}'.format(
        randomize_va_space),
           print_type=PrintType.DEBUG_LOG)

    command = 'bash -c "echo {} > /proc/sys/kernel/randomize_va_space"' \
              .format(randomize_va_space)

    _, rc = run_command(command)

    if rc != 0:
        raise SystemSettingChangeError(
            'Unable to change randomize_va_space to {} for system'.format(
                randomize_va_space))
コード例 #30
0
def run_system_command(command, silence=True):
    """Runs a system command.

    Args:
        command: The command.
        silence: (OPTIONAL) Whether to silence the console output. Defaults to
            True.

    Returns:
        The return code.
    """
    if silence:
        command = '{} >/dev/null 2>&1'.format(command)

    printf('Running command {}'.format(command),
           print_type=PrintType.DEBUG_LOG)

    try:
        return os.system(command)
    except Exception as err:
        printf('Error occurred running command {}\n{}'.format(command, err),
               print_type=PrintType.ERROR_LOG)
        return -1