Merge "Add option to choose partition alignment mode"

This commit is contained in:
Jenkins 2016-05-23 14:31:17 +00:00 committed by Gerrit Code Review
commit 3392c405f5
6 changed files with 93 additions and 31 deletions

View File

@ -163,6 +163,12 @@ opts = [
'volumes. Devices in directories outside this hierarchy will be '
'ignored.'
),
cfg.StrOpt(
'partition_alignment',
default='optimal',
help='Set alignment for newly created partitions, valid alignment '
'types are: none, cylinder, minimal, optimal'
),
cfg.StrOpt(
'lvm_conf_path',
default='/etc/lvm/lvm.conf',
@ -217,7 +223,8 @@ class Manager(object):
for parted in parteds:
pu.make_label(parted.name, parted.label)
for prt in parted.partitions:
pu.make_partition(prt.device, prt.begin, prt.end, prt.type)
pu.make_partition(prt.device, prt.begin, prt.end, prt.type,
alignment=CONF.partition_alignment)
utils.udevadm_trigger_blocks()
for flag in prt.flags:
pu.set_partition_flag(prt.device, prt.count, flag)

View File

@ -89,8 +89,10 @@ 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
# NOTE(agordeev): this 1M room could be enough for minimal
# partition alignment mode for the most of cases.
return self.partitions[-1].begin + 1
return self.partitions[-1].end + 1
def next_name(self):
if self.next_type() == 'extended':

View File

@ -447,19 +447,21 @@ class TestManager(unittest2.TestCase):
self.assertEqual(mock_pu_ml_expected_calls, mock_pu_ml.call_args_list)
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/sdb', 1, 25, 'primary'),
mock.call('/dev/sdb', 25, 225, 'primary'),
mock.call('/dev/sdb', 225, 65196, '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/sda', 1, 25, 'primary', alignment='optimal'),
mock.call('/dev/sda', 26, 226, 'primary', alignment='optimal'),
mock.call('/dev/sda', 227, 427, 'primary', alignment='optimal'),
mock.call('/dev/sda', 428, 628, 'primary', alignment='optimal'),
mock.call('/dev/sda', 629, 20067, 'primary', alignment='optimal'),
mock.call('/dev/sda', 20068, 65665, 'primary',
alignment='optimal'),
mock.call('/dev/sda', 65666, 65686, 'primary',
alignment='optimal'),
mock.call('/dev/sdb', 1, 25, 'primary', alignment='optimal'),
mock.call('/dev/sdb', 26, 226, 'primary', alignment='optimal'),
mock.call('/dev/sdb', 227, 65198, 'primary', alignment='optimal'),
mock.call('/dev/sdc', 1, 25, 'primary', alignment='optimal'),
mock.call('/dev/sdc', 26, 226, 'primary', alignment='optimal'),
mock.call('/dev/sdc', 227, 65198, 'primary', alignment='optimal')]
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'),
@ -1230,6 +1232,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')
@ -1240,7 +1243,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_mdclean_all):
mock_os_path.return_value = True
mock_hu_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_MPATH
self.mgr._make_partitions = mock.MagicMock()
@ -1300,14 +1303,19 @@ class TestManagerMultipathPartition(unittest2.TestCase):
mock.call('/dev/sdc', 'gpt')])
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/sdc', 1, 25, 'primary'),
mock.call('/dev/sdc', 25, 225, 'primary'),
mock.call('/dev/sdc', 225, 425, 'primary')])
mock.call('/dev/mapper/12312', 1, 25, 'primary',
alignment='optimal'),
mock.call('/dev/mapper/12312', 26, 226, 'primary',
alignment='optimal'),
mock.call('/dev/mapper/12312', 227, 427, 'primary',
alignment='optimal'),
mock.call('/dev/mapper/12312', 428, 628, 'primary',
alignment='optimal'),
mock.call('/dev/mapper/12312', 629, 649, 'primary',
alignment='optimal'),
mock.call('/dev/sdc', 1, 25, 'primary', alignment='optimal'),
mock.call('/dev/sdc', 26, 226, 'primary', alignment='optimal'),
mock.call('/dev/sdc', 227, 427, 'primary', alignment='optimal')])
self.assertEqual(mock_set_partition_flag.mock_calls, [
mock.call('/dev/mapper/12312', 1, 'bios_grub'),

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

@ -134,6 +134,35 @@ class TestPartitionUtils(unittest2.TestCase):
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(pu, 'reread_partitions')
@mock.patch.object(pu, 'info')
@mock.patch.object(utils, 'execute')
def test_make_partition_minimal(self, mock_exec, mock_info, mock_rerd,
mock_udev):
# should run parted OS command
# in order to create new partition
mock_exec.return_value = ('out', '')
mock_info.return_value = {
'parts': [
{'begin': 0, 'end': 1000, 'fstype': 'free'},
]
}
pu.make_partition('/dev/fake', 100, 200, 'primary',
alignment='minimal')
mock_exec_expected_calls = [
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()
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
def test_make_partition_wrong_alignment(self):
self.assertRaises(errors.WrongPartitionSchemeError, pu.make_partition,
'/dev/fake', 1, 10, 'primary', 'invalid')
@mock.patch.object(utils, 'execute')
def test_make_partition_wrong_ptype(self, mock_exec):
# should check if partition type is one of

View File

@ -19,6 +19,7 @@ from fuel_agent.openstack.common import log as logging
from fuel_agent.utils import utils
LOG = logging.getLogger(__name__)
PARTITION_ALIGMENT = ('none', 'cylinder', 'minimal', 'optimal')
def parse_partition_info(output):
@ -135,12 +136,27 @@ def set_gpt_type(dev, num, type_guid):
dev, check_exit_code=[0])
def make_partition(dev, begin, end, ptype):
def make_partition(dev, begin, end, ptype, alignment='optimal'):
"""Creates a partition on the device.
:param dev: A device file, e.g. /dev/sda.
:param begin: Beginning of the partition.
:param end: Ending of the partition.
:param ptype: Partition type: primary or logical.
:param alignment: Set alignment mode for newly created partitions,
valid alignment types are: none, cylinder, minimal, optimal. For more
information about this you can find in GNU parted manual.
:returns: None
"""
LOG.debug('Trying to create a partition: dev=%s begin=%s end=%s' %
(dev, begin, end))
if ptype not in ('primary', 'logical'):
raise errors.WrongPartitionSchemeError(
'Wrong partition type: %s' % ptype)
if alignment not in PARTITION_ALIGMENT:
raise errors.WrongPartitionSchemeError(
'Wrong partition alignment requested: %s' % alignment)
# check begin >= end
if begin >= end:
@ -156,7 +172,7 @@ def make_partition(dev, begin, end, ptype):
utils.udevadm_settle()
out, err = utils.execute(
'parted', '-a', 'optimal', '-s', dev, 'unit', 'MiB',
'parted', '-a', alignment, '-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)