Reduced lvm metadata size to (actual size - 8M)

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.

Implements: blueprint image-based-provisioning
Change-Id: I14e5e8e37a52685a67a99fece630b368e6064c76
This commit is contained in:
Vladimir Kozhukalov 2014-10-13 14:27:15 +04:00
parent afd0bf6988
commit c473202d4d
4 changed files with 39 additions and 11 deletions

View File

@ -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':

View File

@ -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:

View File

@ -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):

View File

@ -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'),