Check and grow the GPT structure to the end of the volume

In the baremetal case this isn't required because it is done by
ironic-python-agent when writing the image to the volume[1].

But when using the image directly (such as in a nova VM) the GPT
structure needs to be extended first. This change does that, along
with the detection for whether extending is required, using the same
approach as [1].

[1] https://github.com/openstack/ironic-lib/blob/master/ironic_lib/disk_utils.py#L670-L674

Co-Authored-By: rminishev@itkey.com
Co-Authored-By: sbaker@redhat.com

Change-Id: I3240eb0ef4dbbb41557985f0129ae4998a846417
This commit is contained in:
Steve Baker 2022-12-22 17:15:55 +13:00
parent 1bb559b684
commit 9fa139511e
2 changed files with 34 additions and 0 deletions

View File

@ -269,6 +269,17 @@ def find_disk(opts, devices):
return device return device
def grow_gpt(disk_name):
device = '/dev/%s' % disk_name
output = execute(['sgdisk', '-v', device])
search_str = "it doesn't reside\nat the end of the disk"
if search_str in output:
LOG.info('Fixing GPT structure, moving to end of device %s', device)
execute(['sgdisk', '-e', device])
execute(['partprobe'])
def find_space(disk_name): def find_space(disk_name):
LOG.info('Finding spare space to grow into') LOG.info('Finding spare space to grow into')
dev_path = '/dev/%s' % disk_name dev_path = '/dev/%s' % disk_name
@ -490,6 +501,8 @@ def main(argv):
disk = find_disk(opts, devices) disk = find_disk(opts, devices)
disk_name = disk['KNAME'] disk_name = disk['KNAME']
grow_gpt(disk_name)
sector_bytes = find_sector_size(disk_name) sector_bytes = find_sector_size(disk_name)
sector_start, sector_end, size_sectors = find_space(disk_name) sector_start, sector_end, size_sectors = find_space(disk_name)

View File

@ -110,6 +110,13 @@ DEVICES = [{
SECTOR_START = 79267840 SECTOR_START = 79267840
SECTOR_END = 488265727 SECTOR_END = 488265727
SGDISK_LARGEST = "%s\n%s\n" % (SECTOR_START, SECTOR_END) SGDISK_LARGEST = "%s\n%s\n" % (SECTOR_START, SECTOR_END)
SGDISK_V = """
Problem: The secondary header's self-pointer indicates that it doesn't reside
at the end of the disk. If you've added a disk to a RAID array, use the 'e'
option on the experts' menu to adjust the secondary header's and partition
table's locations.
Identified 1 problems!"""
# output of vgs --noheadings --options vg_name # output of vgs --noheadings --options vg_name
VGS = " vg\n" VGS = " vg\n"
@ -465,6 +472,9 @@ class TestGrowvols(base.BaseTestCase):
# noop, only discover block device info # noop, only discover block device info
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
SGDISK_V,
'',
'',
SGDISK_LARGEST, SGDISK_LARGEST,
VGS, VGS,
LVS, LVS,
@ -473,6 +483,9 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.assert_has_calls([ mock_execute.assert_has_calls([
mock.call(['lsblk', '-Po', mock.call(['lsblk', '-Po',
'kname,pkname,name,label,type,fstype,mountpoint']), 'kname,pkname,name,label,type,fstype,mountpoint']),
mock.call(['sgdisk', '-v', '/dev/sda']),
mock.call(['sgdisk', '-e', '/dev/sda']),
mock.call(['partprobe']),
mock.call(['sgdisk', '--first-aligned-in-largest', mock.call(['sgdisk', '--first-aligned-in-largest',
'--end-of-largest', '/dev/sda']), '--end-of-largest', '/dev/sda']),
mock.call(['vgs', '--noheadings', '--options', 'vg_name']), mock.call(['vgs', '--noheadings', '--options', 'vg_name']),
@ -484,6 +497,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.reset_mock() mock_execute.reset_mock()
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
'',
SGDISK_LARGEST, SGDISK_LARGEST,
VGS, VGS,
LVS, LVS,
@ -493,6 +507,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.assert_has_calls([ mock_execute.assert_has_calls([
mock.call(['lsblk', '-Po', mock.call(['lsblk', '-Po',
'kname,pkname,name,label,type,fstype,mountpoint']), 'kname,pkname,name,label,type,fstype,mountpoint']),
mock.call(['sgdisk', '-v', '/dev/sda']),
mock.call(['sgdisk', '--first-aligned-in-largest', mock.call(['sgdisk', '--first-aligned-in-largest',
'--end-of-largest', '/dev/sda']), '--end-of-largest', '/dev/sda']),
mock.call(['vgs', '--noheadings', '--options', 'vg_name']), mock.call(['vgs', '--noheadings', '--options', 'vg_name']),
@ -512,6 +527,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.reset_mock() mock_execute.reset_mock()
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
'',
SGDISK_LARGEST, SGDISK_LARGEST,
VGS, VGS,
LVS, LVS,
@ -522,6 +538,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.assert_has_calls([ mock_execute.assert_has_calls([
mock.call(['lsblk', '-Po', mock.call(['lsblk', '-Po',
'kname,pkname,name,label,type,fstype,mountpoint']), 'kname,pkname,name,label,type,fstype,mountpoint']),
mock.call(['sgdisk', '-v', '/dev/sda']),
mock.call(['sgdisk', '--first-aligned-in-largest', mock.call(['sgdisk', '--first-aligned-in-largest',
'--end-of-largest', '/dev/sda']), '--end-of-largest', '/dev/sda']),
mock.call(['vgs', '--noheadings', '--options', 'vg_name']), mock.call(['vgs', '--noheadings', '--options', 'vg_name']),
@ -549,6 +566,7 @@ class TestGrowvols(base.BaseTestCase):
sgdisk_largest = "%s\n%s\n" % (sector_start, sector_end) sgdisk_largest = "%s\n%s\n" % (sector_start, sector_end)
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
'',
sgdisk_largest, sgdisk_largest,
VGS, VGS,
LVS, LVS,
@ -561,6 +579,7 @@ class TestGrowvols(base.BaseTestCase):
# no space to grow, success # no space to grow, success
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
'',
sgdisk_largest, sgdisk_largest,
VGS, VGS,
LVS, LVS,
@ -579,6 +598,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.reset_mock() mock_execute.reset_mock()
mock_execute.side_effect = [ mock_execute.side_effect = [
LSBLK, LSBLK,
'',
SGDISK_LARGEST, SGDISK_LARGEST,
VGS, VGS,
LVS_THIN, LVS_THIN,
@ -589,6 +609,7 @@ class TestGrowvols(base.BaseTestCase):
mock_execute.assert_has_calls([ mock_execute.assert_has_calls([
mock.call(['lsblk', '-Po', mock.call(['lsblk', '-Po',
'kname,pkname,name,label,type,fstype,mountpoint']), 'kname,pkname,name,label,type,fstype,mountpoint']),
mock.call(['sgdisk', '-v', '/dev/sda']),
mock.call(['sgdisk', '--first-aligned-in-largest', mock.call(['sgdisk', '--first-aligned-in-largest',
'--end-of-largest', '/dev/sda']), '--end-of-largest', '/dev/sda']),
mock.call(['vgs', '--noheadings', '--options', 'vg_name']), mock.call(['vgs', '--noheadings', '--options', 'vg_name']),