Merge "Grow thin pool metadata by 1GiB"

This commit is contained in:
Zuul 2022-12-21 04:20:44 +00:00 committed by Gerrit Code Review
commit 9d0ba50494
2 changed files with 44 additions and 21 deletions

View File

@ -36,12 +36,22 @@ UNITS = ['%']
UNITS.extend(UNIT_BYTES.keys()) UNITS.extend(UNIT_BYTES.keys())
AMOUNT_UNIT_RE = re.compile('^([0-9]+)(%s)$' % '|'.join(UNITS)) AMOUNT_UNIT_RE = re.compile('^([0-9]+)(%s)$' % '|'.join(UNITS))
UNIT_BYTES_FORMAT = {
'B': 1,
'KiB': 1024,
'MiB': 1048576,
'GiB': 1073741824
}
# Only create growth partition if there is at least 1GiB available # Only create growth partition if there is at least 1GiB available
MIN_DISK_SPACE_BYTES = UNIT_BYTES['GiB'] MIN_DISK_SPACE_BYTES = UNIT_BYTES['GiB']
# Default LVM physical extent size is 4MiB # Default LVM physical extent size is 4MiB
PHYSICAL_EXTENT_BYTES = 4 * UNIT_BYTES['MiB'] PHYSICAL_EXTENT_BYTES = 4 * UNIT_BYTES['MiB']
# Grow the thin pool metadata size to 1GiB
POOL_METADATA_SIZE = UNIT_BYTES['GiB']
class Command(object): class Command(object):
""" An object to represent a command to run with associated comment """ """ An object to represent a command to run with associated comment """
@ -172,13 +182,13 @@ def printable_cmd(cmd):
def convert_bytes(num): def convert_bytes(num):
"""Format a bytes amount with units MB, GB etc""" """Format a bytes amount with units GiB, MiB etc"""
step_unit = 1000.0 for x in ['GiB', 'MiB', 'KiB', 'B']:
unit = UNIT_BYTES_FORMAT[x]
for x in ['B', 'KB', 'MB', 'GB', 'TB']: unit_num = num // unit
if num < step_unit: if unit_num > 0:
return "%d%s" % (num, x) break
num /= step_unit return "%d%s" % (unit_num, x)
def execute(cmd): def execute(cmd):
@ -499,9 +509,14 @@ def main(argv):
group = find_group(opts) group = find_group(opts)
partnum = find_next_partnum(devices, disk_name) partnum = find_next_partnum(devices, disk_name)
devname = find_next_device_name(devices, disk_name, partnum) devname = find_next_device_name(devices, disk_name, partnum)
thin_pool = find_thin_pool(devices, group)
if thin_pool:
# total size available, reduced by POOL_METADATA_SIZE
# rounded down to whole extent
size_bytes -= POOL_METADATA_SIZE
size_bytes -= size_bytes % PHYSICAL_EXTENT_BYTES
dev_path = '/dev/%s' % devname dev_path = '/dev/%s' % devname
grow_vols = find_grow_vols(opts, devices, group, size_bytes) grow_vols = find_grow_vols(opts, devices, group, size_bytes)
thin_pool = find_thin_pool(devices, group)
commands = [] commands = []
@ -528,14 +543,20 @@ def main(argv):
], 'Add physical volume %s to group %s' % (devname, group))) ], 'Add physical volume %s to group %s' % (devname, group)))
if thin_pool: if thin_pool:
# total size available, rounded down to whole extents
pool_size = size_bytes - size_bytes % PHYSICAL_EXTENT_BYTES
commands.append(Command([ commands.append(Command([
'lvextend', 'lvextend',
'-L+%sB' % pool_size, '--poolmetadatasize',
'+%sB' % POOL_METADATA_SIZE,
thin_pool, thin_pool,
dev_path dev_path
], 'Add %s to thin pool %s' % (convert_bytes(pool_size), ], 'Add %s to thin pool metadata %s' % (
convert_bytes(POOL_METADATA_SIZE), thin_pool)))
commands.append(Command([
'lvextend',
'-L+%sB' % size_bytes,
thin_pool,
dev_path
], 'Add %s to thin pool %s' % (convert_bytes(size_bytes),
thin_pool))) thin_pool)))
for volume_path, size_bytes in grow_vols.items(): for volume_path, size_bytes in grow_vols.items():

View File

@ -147,10 +147,10 @@ class TestGrowvols(base.BaseTestCase):
def test_convert_bytes(self): def test_convert_bytes(self):
self.assertEqual('100B', growvols.convert_bytes(100)) self.assertEqual('100B', growvols.convert_bytes(100))
self.assertEqual('1KB', growvols.convert_bytes(1000)) self.assertEqual('1000B', growvols.convert_bytes(1000))
self.assertEqual('2MB', growvols.convert_bytes(2000000)) self.assertEqual('1MiB', growvols.convert_bytes(2000000))
self.assertEqual('3GB', growvols.convert_bytes(3000000000)) self.assertEqual('2GiB', growvols.convert_bytes(3000000000))
self.assertEqual('4TB', growvols.convert_bytes(4000000000000)) self.assertEqual('3725GiB', growvols.convert_bytes(4000000000000))
@mock.patch('subprocess.Popen') @mock.patch('subprocess.Popen')
def test_execute(self, mock_popen): def test_execute(self, mock_popen):
@ -582,7 +582,7 @@ class TestGrowvols(base.BaseTestCase):
SGDISK_LARGEST, SGDISK_LARGEST,
VGS, VGS,
LVS_THIN, LVS_THIN,
'', '', '', '', '', '', '', '', '', '', '' '', '', '', '', '', '', '', '', '', '', '', ''
] ]
growvols.main(['growvols', '--yes', '--group', 'vg', growvols.main(['growvols', '--yes', '--group', 'vg',
'/home=20%', 'fs_var=40%']) '/home=20%', 'fs_var=40%'])
@ -599,13 +599,15 @@ class TestGrowvols(base.BaseTestCase):
mock.call(['partprobe']), mock.call(['partprobe']),
mock.call(['pvcreate', '/dev/sda5']), mock.call(['pvcreate', '/dev/sda5']),
mock.call(['vgextend', 'vg', '/dev/sda5']), mock.call(['vgextend', 'vg', '/dev/sda5']),
mock.call(['lvextend', '-L+209404821504B', mock.call(['lvextend', '--poolmetadatasize', '+1073741824B',
'/dev/mapper/vg-lv_thinpool', '/dev/sda5']), '/dev/mapper/vg-lv_thinpool', '/dev/sda5']),
mock.call(['lvextend', '--size', '+41880125440B', mock.call(['lvextend', '-L+208331079680B',
'/dev/mapper/vg-lv_thinpool', '/dev/sda5']),
mock.call(['lvextend', '--size', '+41666215936B',
'/dev/mapper/vg-lv_home']), '/dev/mapper/vg-lv_home']),
mock.call(['lvextend', '--size', '+83760250880B', mock.call(['lvextend', '--size', '+83332431872B',
'/dev/mapper/vg-lv_var']), '/dev/mapper/vg-lv_var']),
mock.call(['lvextend', '--size', '+83764445184B', mock.call(['lvextend', '--size', '+83332431872B',
'/dev/mapper/vg-lv_root']), '/dev/mapper/vg-lv_root']),
mock.call(['xfs_growfs', '/dev/mapper/vg-lv_home']), mock.call(['xfs_growfs', '/dev/mapper/vg-lv_home']),
mock.call(['xfs_growfs', '/dev/mapper/vg-lv_var']), mock.call(['xfs_growfs', '/dev/mapper/vg-lv_var']),