def run_once(self):
        errors = 0
        # The minimum available space we expect on temp filesystems.
        # TempFS allows 1/2 of Total Memory for each temp fs. Our threshold
        # allows for 50% usage of space allocated before this test is run.

        threshold = utils.memtotal()/4
        tempdirs = ['/dev', '/tmp', '/dev/shm', '/var/tmp', '/run',
                    '/run/lock']

        for dir in tempdirs:
            if os.path.isdir(dir):
                # utils.freespace is in bytes, so convert to kb.
                avail = utils.freespace(dir)/1024
                if avail < threshold:
                    logging.error('Not enough available space on %s', dir)
                    logging.error('%d bytes is minimum, found %d bytes',
                                  (threshold, avail))
                    errors += 1
            else:
                logging.error('%s does not exist!' % dir)
                errors += 1

        if errors:
            raise error.TestFail('There were %d temp directory errors' % errors)
Exemple #2
0
    def execute(self, disks = None, gigabytes = None,
                chunk_mb = utils.memtotal() / 1024):
        os.chdir(self.srcdir)

        if not disks:
            disks = [self.tmpdir]
        if not gigabytes:
            free = 100       # cap it at 100GB by default
            for disk in disks:
                free = min(utils.freespace(disk) / 1024**3, free)
            gigabytes = free
            logging.info("resizing to %s GB", gigabytes)
            sys.stdout.flush()

        self.chunk_mb = chunk_mb
        self.memory_mb = utils.memtotal()/1024
        if self.memory_mb > chunk_mb:
            e_msg = "Too much RAM (%dMB) for this test to work" % self.memory_mb
            raise error.TestError(e_msg)

        chunks = (1024 * gigabytes) / chunk_mb

        for i in range(chunks):
            pids = []
            for disk in disks:
                pid = self.test_one_disk_chunk(disk, i)
                pids.append(pid)
            errors = []
            for pid in pids:
                (junk, retval) = os.waitpid(pid, 0)
                if (retval != 0):
                    errors.append(retval)
            if errors:
                raise error.TestError("Errors from children: %s" % errors)
Exemple #3
0
    def run_once(self, disks=None, gigabytes=None, chunk_mb=None):
        """
        Runs one iteration of disktest.

        @param disks: List of directories (usually mountpoints) to be passed
                to the test.
        @param gigabytes: Disk space that will be used for the test to run.
        @param chunk_mb: Size of the portion of the disk used to run the test.
                Cannot be larger than the total amount of free RAM.
        """
        os.chdir(self.srcdir)
        if chunk_mb is None:
            chunk_mb = utils.memtotal() / 1024
        if disks is None:
            disks = [self.tmpdir]
        if gigabytes is None:
            free = 100 # cap it at 100GB by default
            for disk in disks:
                free = min(utils.freespace(disk) / 1024**3, free)
            gigabytes = free
            logging.info("Resizing to %s GB", gigabytes)
            sys.stdout.flush()

        self.chunk_mb = chunk_mb
        self.memory_mb = utils.memtotal()/1024
        if self.memory_mb > chunk_mb:
            raise error.TestError("Too much RAM (%dMB) for this test to work" %
                                  self.memory_mb)

        chunks = (1024 * gigabytes) / chunk_mb

        logging.info("Total of disk chunks that will be used: %s", chunks)
        for i in range(chunks):
            pids = []
            for disk in disks:
                pid = self.test_one_disk_chunk(disk, i)
                pids.append(pid)
            errors = []
            for pid in pids:
                (junk, retval) = os.waitpid(pid, 0)
                if (retval != 0):
                    errors.append(retval)
            if errors:
                raise error.TestError("Errors from children: %s" % errors)
Exemple #4
0
    def run_once(self, args = '', stress_length=60):
        if not args:
            # We will use 2 workers of each type for each CPU detected
            threads = 2 * utils.count_cpus()

            # Sometimes the default memory used by each memory worker (256 M)
            # might make our machine go OOM and then funny things might start to
            # happen. Let's avoid that.
            mb = utils.freememtotal() + utils.read_from_meminfo('SwapFree') / 2
            memory_per_thread = (mb * 1024) / threads

            # Even though unlikely, it's good to prevent from allocating more
            # disk than this machine actually has on its autotest directory
            # (limit the amount of disk used to max of 90 % of free space)
            free_disk = utils.freespace(self.srcdir)
            file_size_per_thread = 1024 ** 2
            if (0.9 * free_disk) < file_size_per_thread * threads:
                file_size_per_thread = (0.9 * free_disk) / threads

            # Number of CPU workers spinning on sqrt()
            args = '--cpu %d ' % threads
            # Number of IO workers spinning on sync()
            args += '--io %d ' % threads
            # Number of Memory workers spinning on malloc()/free()
            args += '--vm %d ' % threads
            # Amount of memory used per each worker
            args += '--vm-bytes %d ' % memory_per_thread
            # Number of HD workers spinning on write()/ulink()
            args += '--hdd %d ' % threads
            # Size of the files created by each worker in bytes
            args += '--hdd-bytes %d ' % file_size_per_thread
            # Time for which the stress test will run
            args += '--timeout %d ' % stress_length
            # Verbose flag
            args += '--verbose'

        utils.system(self.srcdir + '/src/stress ' + args)
Exemple #5
0
    def run_once(self, args='', stress_length=60):
        if not args:
            # We will use 2 workers of each type for each CPU detected
            threads = 2 * utils.count_cpus()

            # Sometimes the default memory used by each memory worker (256 M)
            # might make our machine go OOM and then funny things might start to
            # happen. Let's avoid that.
            mb = utils.freememtotal() + utils.read_from_meminfo('SwapFree') / 2
            memory_per_thread = (mb * 1024) / threads

            # Even though unlikely, it's good to prevent from allocating more
            # disk than this machine actually has on its autotest directory
            # (limit the amount of disk used to max of 90 % of free space)
            free_disk = utils.freespace(self.srcdir)
            file_size_per_thread = 1024**2
            if (0.9 * free_disk) < file_size_per_thread * threads:
                file_size_per_thread = (0.9 * free_disk) / threads

            # Number of CPU workers spinning on sqrt()
            args = '--cpu %d ' % threads
            # Number of IO workers spinning on sync()
            args += '--io %d ' % threads
            # Number of Memory workers spinning on malloc()/free()
            args += '--vm %d ' % threads
            # Amount of memory used per each worker
            args += '--vm-bytes %d ' % memory_per_thread
            # Number of HD workers spinning on write()/ulink()
            args += '--hdd %d ' % threads
            # Size of the files created by each worker in bytes
            args += '--hdd-bytes %d ' % file_size_per_thread
            # Time for which the stress test will run
            args += '--timeout %d ' % stress_length
            # Verbose flag
            args += '--verbose'

        utils.system(self.srcdir + '/src/stress ' + args)
    def stop(self):
        # if no maximum usage rate was set, we don't need to
        # generate any warnings
        if not self.max_mb_per_hour:
            return

        final_space = utils.freespace(self.device)
        used_space = self.initial_space - final_space
        stop_time = time.time()
        total_time = stop_time - self.start_time
        # round up the time to one minute, to keep extremely short
        # tests from generating false positives due to short, badly
        # timed bursts of activity
        total_time = max(total_time, 60.0)

        # determine the usage rate
        bytes_per_sec = used_space / total_time
        mb_per_sec = bytes_per_sec / 1024**2
        mb_per_hour = mb_per_sec * 60 * 60

        if mb_per_hour > self.max_mb_per_hour:
            msg = ("disk space on %s was consumed at a rate of %.2f MB/hour")
            msg %= (self.device, mb_per_hour)
            self.func(msg)
Exemple #7
0
    def stop(self):
        # if no maximum usage rate was set, we don't need to
        # generate any warnings
        if not self.max_mb_per_hour:
            return

        final_space = utils.freespace(self.device)
        used_space = self.initial_space - final_space
        stop_time = time.time()
        total_time = stop_time - self.start_time
        # round up the time to one minute, to keep extremely short
        # tests from generating false positives due to short, badly
        # timed bursts of activity
        total_time = max(total_time, 60.0)

        # determine the usage rate
        bytes_per_sec = used_space / total_time
        mb_per_sec = bytes_per_sec / 1024**2
        mb_per_hour = mb_per_sec * 60 * 60

        if mb_per_hour > self.max_mb_per_hour:
            msg = ("disk space on %s was consumed at a rate of %.2f MB/hour")
            msg %= (self.device, mb_per_hour)
            self.func(msg)
Exemple #8
0
def backup_image(params, root_dir, action, good=True):
    """
    Backup or restore a disk image, depending on the action chosen.

    @param params: Dictionary containing the test parameters.
    @param root_dir: Base directory for relative filenames.
    @param action: Whether we want to backup or restore the image.
    @param good: If we are backing up a good image(we want to restore it) or
            a bad image (we are saving a bad image for posterior analysis).

    @note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    """
    def backup_raw_device(src, dst):
        utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))

    def backup_image_file(src, dst):
        logging.debug("Copying %s -> %s", src, dst)
        shutil.copy(src, dst)

    def get_backup_name(filename, backup_dir, good):
        if not os.path.isdir(backup_dir):
            os.makedirs(backup_dir)
        basename = os.path.basename(filename)
        if good:
            backup_filename = "%s.backup" % basename
        else:
            backup_filename = (
                "%s.bad.%s" % (basename, virt_utils.generate_random_string(4)))
        return os.path.join(backup_dir, backup_filename)

    image_filename = get_image_filename(params, root_dir)
    backup_dir = params.get("backup_dir")
    if params.get('image_raw_device') == 'yes':
        iname = "raw_device"
        iformat = params.get("image_format", "qcow2")
        ifilename = "%s.%s" % (iname, iformat)
        ifilename = virt_utils.get_path(root_dir, ifilename)
        image_filename_backup = get_backup_name(ifilename, backup_dir, good)
        backup_func = backup_raw_device
    else:
        image_filename_backup = get_backup_name(image_filename, backup_dir,
                                                good)
        backup_func = backup_image_file

    if action == 'backup':
        image_dir = os.path.dirname(image_filename)
        image_dir_disk_free = utils.freespace(image_dir)
        image_filename_size = os.path.getsize(image_filename)
        image_filename_backup_size = 0
        if os.path.isfile(image_filename_backup):
            image_filename_backup_size = os.path.getsize(image_filename_backup)
        disk_free = image_dir_disk_free + image_filename_backup_size
        minimum_disk_free = 1.2 * image_filename_size
        if disk_free < minimum_disk_free:
            image_dir_disk_free_gb = float(image_dir_disk_free) / 10**9
            minimum_disk_free_gb = float(minimum_disk_free) / 10**9
            logging.error(
                "Dir %s has %.1f GB free, less than the minimum "
                "required to store a backup, defined to be 120%% "
                "of the backup size, %.1f GB. Skipping backup...", image_dir,
                image_dir_disk_free_gb, minimum_disk_free_gb)
            return
        if good:
            # In case of qemu-img check return 1, we will make 2 backups, one
            # for investigation and other, to use as a 'pristine' image for
            # further tests
            state = 'good'
        else:
            state = 'bad'
        logging.info("Backing up %s image file %s", state, image_filename)
        src, dst = image_filename, image_filename_backup
    elif action == 'restore':
        if not os.path.isfile(image_filename_backup):
            logging.error('Image backup %s not found, skipping restore...',
                          image_filename_backup)
            return
        logging.info("Restoring image file %s from backup", image_filename)
        src, dst = image_filename_backup, image_filename

    backup_func(src, dst)
 def start(self):
     self.initial_space = utils.freespace(self.device)
     self.start_time = time.time()
Exemple #10
0
 def start(self):
     self.initial_space = utils.freespace(self.device)
     self.start_time = time.time()
Exemple #11
0
def backup_image(params, root_dir, action, good=True):
    """
    Backup or restore a disk image, depending on the action chosen.

    @param params: Dictionary containing the test parameters.
    @param root_dir: Base directory for relative filenames.
    @param action: Whether we want to backup or restore the image.
    @param good: If we are backing up a good image(we want to restore it) or
            a bad image (we are saving a bad image for posterior analysis).

    @note: params should contain:
           image_name -- the name of the image file, without extension
           image_format -- the format of the image (qcow2, raw etc)
    """
    def backup_raw_device(src, dst):
        utils.system("dd if=%s of=%s bs=4k conv=sync" % (src, dst))

    def backup_image_file(src, dst):
        logging.debug("Copying %s -> %s", src, dst)
        shutil.copy(src, dst)

    def get_backup_name(filename, backup_dir, good):
        if not os.path.isdir(backup_dir):
            os.makedirs(backup_dir)
        basename = os.path.basename(filename)
        if good:
            backup_filename = "%s.backup" % basename
        else:
            backup_filename = ("%s.bad.%s" %
                               (basename, virt_utils.generate_random_string(4)))
        return os.path.join(backup_dir, backup_filename)


    image_filename = get_image_filename(params, root_dir)
    backup_dir = params.get("backup_dir")
    if params.get('image_raw_device') == 'yes':
        iname = "raw_device"
        iformat = params.get("image_format", "qcow2")
        ifilename = "%s.%s" % (iname, iformat)
        ifilename = virt_utils.get_path(root_dir, ifilename)
        image_filename_backup = get_backup_name(ifilename, backup_dir, good)
        backup_func = backup_raw_device
    else:
        image_filename_backup = get_backup_name(image_filename, backup_dir,
                                                good)
        backup_func = backup_image_file

    if action == 'backup':
        image_dir = os.path.dirname(image_filename)
        image_dir_disk_free = utils.freespace(image_dir)
        image_filename_size = os.path.getsize(image_filename)
        image_filename_backup_size = 0
        if os.path.isfile(image_filename_backup):
            image_filename_backup_size = os.path.getsize(image_filename_backup)
        disk_free = image_dir_disk_free + image_filename_backup_size
        minimum_disk_free = 1.2 * image_filename_size
        if disk_free < minimum_disk_free:
            image_dir_disk_free_gb = float(image_dir_disk_free) / 10**9
            minimum_disk_free_gb = float(minimum_disk_free) / 10**9
            logging.error("Dir %s has %.1f GB free, less than the minimum "
                          "required to store a backup, defined to be 120%% "
                          "of the backup size, %.1f GB. Skipping backup...",
                          image_dir, image_dir_disk_free_gb,
                          minimum_disk_free_gb)
            return
        if good:
            # In case of qemu-img check return 1, we will make 2 backups, one
            # for investigation and other, to use as a 'pristine' image for
            # further tests
            state = 'good'
        else:
            state = 'bad'
        logging.info("Backing up %s image file %s", state, image_filename)
        src, dst = image_filename, image_filename_backup
    elif action == 'restore':
        if not os.path.isfile(image_filename_backup):
            logging.error('Image backup %s not found, skipping restore...',
                          image_filename_backup)
            return
        logging.info("Restoring image file %s from backup",
                     image_filename)
        src, dst = image_filename_backup, image_filename

    backup_func(src, dst)