diff --git a/fuel_agent/drivers/nailgun.py b/fuel_agent/drivers/nailgun.py index e66e4d7a..7db8b7d6 100644 --- a/fuel_agent/drivers/nailgun.py +++ b/fuel_agent/drivers/nailgun.py @@ -183,8 +183,29 @@ class Nailgun(object): fs_label=self._getlabel(volume.get('disk_label'))) if volume['type'] == 'pv': + lvm_meta_size = volume.get('lvm_meta_size', 64) + # The reason for that is to make sure that + # there will be enough space for creating logical volumes. + # Default lvm extension size is 4M. Nailgun volume + # manager does not care of it and if physical volume size + # is 4M * N + 3M and lvm metadata size is 4M * L then only + # 4M * (N-L) + 3M of space will be available for + # creating logical extensions. So only 4M * (N-L) of space + # will be available for logical volumes, while nailgun + # volume manager might reguire 4M * (N-L) + 3M + # logical volume. Besides, parted aligns partitions + # according to its own algorithm and actual partition might + # be a bit smaller than integer number of mebibytes. + if lvm_meta_size < 10: + raise errors.WrongPartitionSchemeError( + 'Error while creating physical volume: ' + 'lvm metadata size is too small') + metadatasize = int(math.floor((lvm_meta_size - 8) / 2)) + metadatacopies = 2 partition_scheme.vg_attach_by_name( - pvname=prt.name, vgname=volume['vg']) + pvname=prt.name, vgname=volume['vg'], + metadatasize=metadatasize, + metadatacopies=metadatacopies) if volume['type'] == 'raid': if 'mount' in volume and volume['mount'] != 'none': diff --git a/fuel_agent/manager.py b/fuel_agent/manager.py index 19a69ec5..95acdd28 100644 --- a/fuel_agent/manager.py +++ b/fuel_agent/manager.py @@ -122,7 +122,8 @@ class Manager(object): # creating physical volumes for pv in self.partition_scheme.pvs: - lu.pvcreate(pv.name) + lu.pvcreate(pv.name, metadatasize=pv.metadatasize, + metadatacopies=pv.metadatacopies) # creating volume groups for vg in self.partition_scheme.vgs: diff --git a/fuel_agent/objects/partition.py b/fuel_agent/objects/partition.py index e28bd509..c1132364 100644 --- a/fuel_agent/objects/partition.py +++ b/fuel_agent/objects/partition.py @@ -120,8 +120,10 @@ class Partition(object): class Pv(object): - def __init__(self, name): + def __init__(self, name, metadatasize=16, metadatacopies=2): self.name = name + self.metadatasize = metadatasize + self.metadatacopies = metadatacopies class Vg(object): @@ -194,8 +196,8 @@ class PartitionScheme(object): self.parteds.append(parted) return parted - def add_pv(self, name): - pv = Pv(name=name) + def add_pv(self, **kwargs): + pv = Pv(**kwargs) self.pvs.append(pv) return pv @@ -269,9 +271,12 @@ class PartitionScheme(object): if found: return found[0] - def vg_attach_by_name(self, pvname, vgname): + def vg_attach_by_name(self, pvname, vgname, + metadatasize=16, metadatacopies=2): vg = self.vg_by_name(vgname) or self.add_vg(name=vgname) - pv = self.pv_by_name(pvname) or self.add_pv(name=pvname) + pv = self.pv_by_name(pvname) or self.add_pv( + name=pvname, metadatasize=metadatasize, + metadatacopies=metadatacopies) vg.add_pv(pv.name) def fs_by_mount(self, mount): diff --git a/fuel_agent/tests/test_manager.py b/fuel_agent/tests/test_manager.py index 0b5986ac..2cf798f6 100644 --- a/fuel_agent/tests/test_manager.py +++ b/fuel_agent/tests/test_manager.py @@ -107,10 +107,11 @@ class TestManager(test_base.BaseTestCase): '/dev/sdc3')] self.assertEqual(mock_mu_m_expected_calls, mock_mu_m.call_args_list) - mock_lu_p_expected_calls = [mock.call('/dev/sda5'), - mock.call('/dev/sda6'), - mock.call('/dev/sdb4'), - mock.call('/dev/sdc4')] + mock_lu_p_expected_calls = [ + mock.call('/dev/sda5', metadatasize=28, metadatacopies=2), + mock.call('/dev/sda6', metadatasize=28, metadatacopies=2), + mock.call('/dev/sdb4', metadatasize=28, metadatacopies=2), + mock.call('/dev/sdc4', metadatasize=28, metadatacopies=2)] self.assertEqual(mock_lu_p_expected_calls, mock_lu_p.call_args_list) mock_lu_v_expected_calls = [mock.call('os', '/dev/sda5'),