Commit 9666a511 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

Leave 2048 sectors space at the end when shrinking

Most partition manipulation programs leave 2048 sector empty space
after the last partition.
parent 564a18ce
......@@ -320,6 +320,8 @@ class DiskDevice(object):
self.out.output("Shrinking image (this may take a while)...", False)
sector_size = self.g.blockdev_getss(self.guestfs_device)
last_part = None
fstype = None
while True:
......@@ -336,7 +338,10 @@ class DiskDevice(object):
part_del(last_part['part_num'])
continue
self.meta['SIZE'] = last_part['part_end'] + 1
# Most disk manipulation programs leave 2048 sectors after the last
# partition
new_size = last_part['part_end'] + 1 + 2048 * sector_size
self.meta['SIZE'] = min(self.meta['SIZE'], new_size)
break
if not re.match("ext[234]", fstype):
......@@ -353,7 +358,6 @@ class DiskDevice(object):
block_cnt = int(
filter(lambda x: x[0] == 'Block count', out)[0][1])
sector_size = self.g.blockdev_getss(self.guestfs_device)
start = last_part['part_start'] / sector_size
end = start + (block_size * block_cnt) / sector_size - 1
......@@ -398,13 +402,18 @@ class DiskDevice(object):
part_set_id(last_part['part_num'], last_part['id'])
new_size = (end + 1) * sector_size
self.out.success("new size is %dMB" % ((new_size + MB - 1) // MB))
assert (new_size <= self.meta['SIZE'])
if self.meta['PARTITION_TABLE'] == 'gpt':
ptable = GPTPartitionTable(self.real_device)
self.meta['SIZE'] = ptable.shrink(new_size)
self.meta['SIZE'] = ptable.shrink(new_size, self.meta['SIZE'])
else:
self.meta['SIZE'] = new_size
self.meta['SIZE'] = min(new_size + 2048 * sector_size,
self.meta['SIZE'])
self.out.success("new size is %dMB" %
((self.meta['SIZE'] + MB - 1) // MB))
return self.meta['SIZE']
......
......@@ -255,18 +255,24 @@ class GPTPartitionTable(object):
"""Returns the payload size of GPT partitioned device."""
return (self.primary.backup_lba + 1) * BLOCKSIZE
def shrink(self, size):
def shrink(self, size, old_size):
"""Move the secondary GPT Header entries to the address specified by
size parameter.
"""
if size == self.size():
return size
assert size < self.size()
# Most partition manipulation programs leave 2048 sector after the last
# partition
aligned = size + 2048 * BLOCKSIZE
# new_size is at least: size + Partition Entries + Secondary GPT Header
new_size = aligned if aligned <= old_size else \
size + len(self.part_entries) + BLOCKSIZE
assert new_size <= old_size, "The secodary GPT fits in the device"
if new_size == self.size():
return new_size
# new_size = size + Partition Entries + Secondary GPT Header
new_size = size + len(self.part_entries) + BLOCKSIZE
new_size = ((new_size + 4095) // 4096) * 4096 # align to 4K
lba_count = new_size // BLOCKSIZE
# Correct MBR
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment