Switch from optimal alignment to minimum

fuel-agent always uses optimal alignment for partitions and
thoroughly relies on parted to perform that aligning. (-a optimal)

The issue is that under certain circumstances due to that alignment,
the end of particular partition could cross 1M boundary. And due to
actual partition' bounderies being rounded up, fuel-agent mistakenly
assumes that partition couldn't fit within provided boundaries and
raises errors.WrongPartitionSchemeError.

However, some h/w data storages are well known for reporting
relatively huge optimal IO sizes (16M or even bigger), so the 1M room
can't be enough. Thus, optimal aligning is not an option. Therefore,
parted has been switched to the minimum alignment.

The min value is the minimum aligment needed to align the partition
properly to physical blocks, which avoids performance degradation.

Change-Id: I83116ccc9236053a93664c1cf40a3ef0c1a189b7
Closes-Bug: #1543233
This commit is contained in:
Alexander Gordeev 2016-02-10 19:07:48 +03:00
parent d1fc735650
commit 4c74eaa187
5 changed files with 25 additions and 23 deletions

View File

@ -89,8 +89,8 @@ class Parted(base.Serializable):
if not self.partitions:
return 1
if self.partitions[-1] == self.extended:
return self.partitions[-1].begin
return self.partitions[-1].end
return self.partitions[-1].begin + 1
return self.partitions[-1].end + 1
def next_name(self):
if self.next_type() == 'extended':

View File

@ -448,18 +448,19 @@ class TestManager(unittest2.TestCase):
mock_pu_mp_expected_calls = [
mock.call('/dev/sda', 1, 25, 'primary'),
mock.call('/dev/sda', 25, 225, 'primary'),
mock.call('/dev/sda', 225, 425, 'primary'),
mock.call('/dev/sda', 425, 625, 'primary'),
mock.call('/dev/sda', 625, 20063, 'primary'),
mock.call('/dev/sda', 20063, 65660, 'primary'),
mock.call('/dev/sda', 65660, 65680, 'primary'),
mock.call('/dev/sda', 26, 226, 'primary'),
mock.call('/dev/sda', 227, 427, 'primary'),
mock.call('/dev/sda', 428, 628, 'primary'),
mock.call('/dev/sda', 629, 20067, 'primary'),
mock.call('/dev/sda', 20068, 65665, 'primary'),
mock.call('/dev/sda', 65666, 65686, 'primary'),
mock.call('/dev/sdb', 1, 25, 'primary'),
mock.call('/dev/sdb', 25, 225, 'primary'),
mock.call('/dev/sdb', 225, 65196, 'primary'),
mock.call('/dev/sdb', 26, 226, 'primary'),
mock.call('/dev/sdb', 227, 65198, 'primary'),
mock.call('/dev/sdc', 1, 25, 'primary'),
mock.call('/dev/sdc', 25, 225, 'primary'),
mock.call('/dev/sdc', 225, 65196, 'primary')]
mock.call('/dev/sdc', 26, 226, 'primary'),
mock.call('/dev/sdc', 227, 65198, 'primary')]
self.assertEqual(mock_pu_mp_expected_calls, mock_pu_mp.call_args_list)
mock_pu_spf_expected_calls = [mock.call('/dev/sda', 1, 'bios_grub'),
@ -1099,6 +1100,7 @@ class TestManagerMultipathPartition(unittest2.TestCase):
test_nailgun.MPATH_DISK_KS_SPACES
self.mgr = manager.Manager(data)
@mock.patch.object(mu, 'mdclean_all')
@mock.patch.object(manager.utils, 'refresh_multipath')
@mock.patch.object(hu, 'is_multipath_device')
@mock.patch.object(manager.os.path, 'exists')
@ -1109,7 +1111,7 @@ class TestManagerMultipathPartition(unittest2.TestCase):
@mock.patch.object(hu, 'list_block_devices')
def test_do_partitioning_mp(self, mock_hu_lbd, mock_fu_mf, mock_exec,
mock_unbl, mock_bl, mock_os_path, mock_mp,
mock_refresh_multipath):
mock_refresh_multipath, mock_md_clean):
mock_os_path.return_value = True
mock_hu_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_MPATH
self.mgr._make_partitions = mock.MagicMock()
@ -1170,10 +1172,10 @@ class TestManagerMultipathPartition(unittest2.TestCase):
self.assertEqual(mock_make_partition.mock_calls, [
mock.call('/dev/mapper/12312', 1, 25, 'primary'),
mock.call('/dev/mapper/12312', 25, 225, 'primary'),
mock.call('/dev/mapper/12312', 225, 425, 'primary'),
mock.call('/dev/mapper/12312', 425, 625, 'primary'),
mock.call('/dev/mapper/12312', 625, 645, 'primary'),
mock.call('/dev/mapper/12312', 26, 226, 'primary'),
mock.call('/dev/mapper/12312', 227, 427, 'primary'),
mock.call('/dev/mapper/12312', 428, 628, 'primary'),
mock.call('/dev/mapper/12312', 629, 649, 'primary'),
mock.call('/dev/sdc', 1, 201, 'primary')])
self.assertEqual(mock_set_partition_flag.mock_calls, [

View File

@ -286,15 +286,15 @@ class TestParted(unittest2.TestCase):
def test_next_begin_last_extended_partition(self):
self.prtd.partitions.append(
objects.Partition('name', 'count', 'device', 'begin', 'end',
objects.Partition('name', 'count', 'device', 1, 100,
'extended'))
self.assertEqual('begin', self.prtd.next_begin())
self.assertEqual(2, self.prtd.next_begin())
def test_next_begin_no_last_extended_partition(self):
self.prtd.partitions.append(
objects.Partition('name', 'count', 'device', 'begin', 'end',
objects.Partition('name', 'count', 'device', 1, 100,
'primary'))
self.assertEqual('end', self.prtd.next_begin())
self.assertEqual(101, self.prtd.next_begin())
def test_next_count_no_logical(self):
self.assertEqual(1, self.prtd.next_count('primary'))

View File

@ -127,7 +127,7 @@ class TestPartitionUtils(unittest2.TestCase):
}
pu.make_partition('/dev/fake', 100, 200, 'primary')
mock_exec_expected_calls = [
mock.call('parted', '-a', 'optimal', '-s', '/dev/fake', 'unit',
mock.call('parted', '-a', 'minimal', '-s', '/dev/fake', 'unit',
'MiB', 'mkpart', 'primary', '100', '200',
check_exit_code=[0, 1])]
mock_udev.assert_called_once_with()

View File

@ -156,7 +156,7 @@ def make_partition(dev, begin, end, ptype):
utils.udevadm_settle()
out, err = utils.execute(
'parted', '-a', 'optimal', '-s', dev, 'unit', 'MiB',
'parted', '-a', 'minimal', '-s', dev, 'unit', 'MiB',
'mkpart', ptype, str(begin), str(end), check_exit_code=[0, 1])
LOG.debug('Parted output: \n%s' % out)
reread_partitions(dev, out=out)