Example #1
0
def setup_blkio_cgroup(srcpath, dstpath, bps_limit, execute=utils.execute):
    if not bps_limit:
        return None

    try:
        srcdev = utils.get_blkdev_major_minor(srcpath)
    except exception.Error as e:
        msg = (
            _('Failed to get device number for read throttling: %(error)s') % {
                'error': e
            })
        LOG.error(msg)
        srcdev = None

    try:
        dstdev = utils.get_blkdev_major_minor(dstpath)
    except exception.Error as e:
        msg = (
            _('Failed to get device number for write throttling: %(error)s') %
            {
                'error': e
            })
        LOG.error(msg)
        dstdev = None

    if not srcdev and not dstdev:
        return None

    group_name = CONF.volume_copy_blkio_cgroup_name
    try:
        execute('cgcreate', '-g', 'blkio:%s' % group_name, run_as_root=True)
    except processutils.ProcessExecutionError:
        LOG.warn(_('Failed to create blkio cgroup'))
        return None

    try:
        if srcdev:
            execute('cgset',
                    '-r',
                    'blkio.throttle.read_bps_device=%s %d' %
                    (srcdev, bps_limit),
                    group_name,
                    run_as_root=True)
        if dstdev:
            execute('cgset',
                    '-r',
                    'blkio.throttle.write_bps_device=%s %d' %
                    (dstdev, bps_limit),
                    group_name,
                    run_as_root=True)
    except processutils.ProcessExecutionError:
        msg = (_('Failed to setup blkio cgroup to throttle the devices: '
                 '\'%(src)s\',\'%(dst)s\'') % {
                     'src': srcdev,
                     'dst': dstdev
                 })
        LOG.warn(msg)
        return None

    return ['cgexec', '-g', 'blkio:%s' % group_name]
Example #2
0
def setup_blkio_cgroup(srcpath, dstpath, bps_limit, execute=utils.execute):
    if not bps_limit:
        LOG.debug('Not using bps rate limiting on volume copy')
        return None

    try:
        srcdev = utils.get_blkdev_major_minor(srcpath)
    except exception.Error as e:
        msg = (_('Failed to get device number for read throttling: %(error)s')
               % {'error': e})
        LOG.error(msg)
        srcdev = None

    try:
        dstdev = utils.get_blkdev_major_minor(dstpath)
    except exception.Error as e:
        msg = (_('Failed to get device number for write throttling: %(error)s')
               % {'error': e})
        LOG.error(msg)
        dstdev = None

    if not srcdev and not dstdev:
        return None

    group_name = CONF.volume_copy_blkio_cgroup_name
    LOG.debug('Setting rate limit to %s bps for blkio '
              'group: %s' % (bps_limit, group_name))
    try:
        execute('cgcreate', '-g', 'blkio:%s' % group_name, run_as_root=True)
    except processutils.ProcessExecutionError:
        LOG.warn(_('Failed to create blkio cgroup'))
        return None

    try:
        if srcdev:
            execute('cgset', '-r', 'blkio.throttle.read_bps_device=%s %d'
                    % (srcdev, bps_limit), group_name, run_as_root=True)
        if dstdev:
            execute('cgset', '-r', 'blkio.throttle.write_bps_device=%s %d'
                    % (dstdev, bps_limit), group_name, run_as_root=True)
    except processutils.ProcessExecutionError:
        msg = (_('Failed to setup blkio cgroup to throttle the devices: '
                 '\'%(src)s\',\'%(dst)s\'')
               % {'src': srcdev, 'dst': dstdev})
        LOG.warn(msg)
        return None

    return ['cgexec', '-g', 'blkio:%s' % group_name]
Example #3
0
 def _get_device_number(self, path):
     try:
         return utils.get_blkdev_major_minor(path)
     except exception.Error as e:
         LOG.error(
             _LE('Failed to get device number for throttling: '
                 '%(error)s'), {'error': e})
Example #4
0
 def test_get_blkdev_is_chr(self, mock_isblk, mock_ischr, mock_stat):
     path = '/some/path'
     output = utils.get_blkdev_major_minor(path, lookup_for_file=False)
     mock_stat.assert_called_once_with(path)
     mock_isblk.assert_called_once_with(mock_stat.return_value.st_mode)
     mock_ischr.assert_called_once_with(mock_stat.return_value.st_mode)
     self.assertIs(None, output)
 def test_get_blkdev_is_chr(self, mock_isblk, mock_ischr, mock_stat):
     path = '/some/path'
     output = utils.get_blkdev_major_minor(path, lookup_for_file=False)
     mock_stat.assert_called_once_with(path)
     mock_isblk.assert_called_once_with(mock_stat.return_value.st_mode)
     mock_ischr.assert_called_once_with(mock_stat.return_value.st_mode)
     self.assertIs(None, output)
Example #6
0
    def test_get_blkdev_major_minor(self, mock_stat):
        class stat_result:
            st_mode = 0o60660
            st_rdev = os.makedev(253, 7)

        test_device = '/dev/made_up_blkdev'
        mock_stat.return_value = stat_result
        dev = utils.get_blkdev_major_minor(test_device)
        self.assertEqual('253:7', dev)
        mock_stat.assert_called_once_with(test_device)
Example #7
0
    def test_get_blkdev_major_minor(self, mock_stat):

        class stat_result:
            st_mode = 0o60660
            st_rdev = os.makedev(253, 7)

        test_device = '/dev/made_up_blkdev'
        mock_stat.return_value = stat_result
        dev = utils.get_blkdev_major_minor(test_device)
        self.assertEqual('253:7', dev)
        mock_stat.aseert_called_once_with(test_device)
Example #8
0
    def _test_get_blkdev_major_minor_file(self, test_partition, mock_exec,
                                          mock_stat):
        mock_exec.return_value = (
            'Filesystem Size Used Avail Use%% Mounted on\n'
            '%s 4096 2048 2048 50%% /tmp\n' % test_partition, None)

        test_file = '/tmp/file'
        test_disk = '/dev/made_up_disk'

        class stat_result_file:
            st_mode = 0o660

        class stat_result_partition:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 65)

        class stat_result_disk:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 64)

        def fake_stat(path):
            try:
                return {
                    test_file: stat_result_file,
                    test_partition: stat_result_partition,
                    test_disk: stat_result_disk
                }[path]
            except KeyError:
                raise OSError

        mock_stat.side_effect = fake_stat

        dev = utils.get_blkdev_major_minor(test_file)
        mock_stat.assert_any_call(test_file)
        mock_exec.assert_called_once_with('df', test_file)
        if test_partition.startswith('/'):
            mock_stat.assert_any_call(test_partition)
            mock_stat.assert_any_call(test_disk)
        return dev
Example #9
0
    def test_get_blkdev_major_minor_file(self, mock_exec, mock_stat):

        mock_exec.return_value = (
            'Filesystem Size Used Avail Use% Mounted on\n'
            '/dev/made_up_disk1 4096 2048 2048 50% /tmp\n', None)

        test_file = '/tmp/file'
        test_partition = '/dev/made_up_disk1'
        test_disk = '/dev/made_up_disk'

        class stat_result_file:
            st_mode = 0o660

        class stat_result_partition:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 65)

        class stat_result_disk:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 64)

        def fake_stat(path):
            try:
                return {
                    test_file: stat_result_file,
                    test_partition: stat_result_partition,
                    test_disk: stat_result_disk
                }[path]
            except KeyError:
                raise OSError

        mock_stat.side_effect = fake_stat

        dev = utils.get_blkdev_major_minor(test_file)
        self.assertEqual('8:64', dev)
        mock_exec.aseert_called_once_with(test_file)
        mock_stat.aseert_called_once_with(test_file)
        mock_stat.aseert_called_once_with(test_partition)
        mock_stat.aseert_called_once_with(test_disk)
Example #10
0
    def test_get_blkdev_major_minor_file(self, mock_exec, mock_stat):

        mock_exec.return_value = (
            'Filesystem Size Used Avail Use% Mounted on\n'
            '/dev/made_up_disk1 4096 2048 2048 50% /tmp\n', None)

        test_file = '/tmp/file'
        test_partition = '/dev/made_up_disk1'
        test_disk = '/dev/made_up_disk'

        class stat_result_file:
            st_mode = 0o660

        class stat_result_partition:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 65)

        class stat_result_disk:
            st_mode = 0o60660
            st_rdev = os.makedev(8, 64)

        def fake_stat(path):
            try:
                return {test_file: stat_result_file,
                        test_partition: stat_result_partition,
                        test_disk: stat_result_disk}[path]
            except KeyError:
                raise OSError

        mock_stat.side_effect = fake_stat

        dev = utils.get_blkdev_major_minor(test_file)
        self.assertEqual('8:64', dev)
        mock_exec.aseert_called_once_with(test_file)
        mock_stat.aseert_called_once_with(test_file)
        mock_stat.aseert_called_once_with(test_partition)
        mock_stat.aseert_called_once_with(test_disk)
Example #11
0
    def _test_get_blkdev_major_minor_file(self, test_partition,
                                          mock_exec, mock_stat):
        mock_exec.return_value = (
            'Filesystem Size Used Avail Use%% Mounted on\n'
            '%s 4096 2048 2048 50%% /tmp\n' % test_partition, None)

        test_file = '/tmp/file'
        test_disk = '/dev/made_up_disk'

        class stat_result_file(object):
            st_mode = 0o660

        class stat_result_partition(object):
            st_mode = 0o60660
            st_rdev = os.makedev(8, 65)

        class stat_result_disk(object):
            st_mode = 0o60660
            st_rdev = os.makedev(8, 64)

        def fake_stat(path):
            try:
                return {test_file: stat_result_file,
                        test_partition: stat_result_partition,
                        test_disk: stat_result_disk}[path]
            except KeyError:
                raise OSError

        mock_stat.side_effect = fake_stat

        dev = utils.get_blkdev_major_minor(test_file)
        mock_stat.assert_any_call(test_file)
        mock_exec.assert_called_once_with('df', test_file)
        if test_partition.startswith('/'):
            mock_stat.assert_any_call(test_partition)
            mock_stat.assert_any_call(test_disk)
        return dev
Example #12
0
 def _get_device_number(self, path):
     try:
         return utils.get_blkdev_major_minor(path)
     except exception.Error as e:
         LOG.error(_LE('Failed to get device number for throttling: '
                       '%(error)s'), {'error': e})