Skip to content

Commit

Permalink
Make sure autopart requests fit in somewhere
Browse files Browse the repository at this point in the history
When doing LVM/BTRFS autopart we implicitly schedule one partition on each disk
as a device for LVM/BTRFS. Those implicitly scheduled partitions are requested
to be at least 500 MiB big and grow if possible. That's fine and works well
until we have many small disks (e.g. DASDs) and need to fit another partition
(for e.g. swap) that is in combination with the 500MiB implicit partition bigger
than any disk we have.

Thus we need to make sure all our partition requests fit somewhere with the
implicitly scheduled partitions by making the latter ones smaller or by removing
them if needed.

Related: rhbz#1202877
(cherry picked from commit a6d17f9)

Conflicts:
	blivet/devices.py
	blivet/partitioning.py
  • Loading branch information
vpodzime committed Jun 3, 2015
1 parent 71344c6 commit 023164e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
5 changes: 4 additions & 1 deletion blivet/devices/partition.py
Expand Up @@ -736,7 +736,10 @@ def _setSize(self, newsize):
raise ValueError("new size must of type Size")

if not self.exists:
raise errors.DeviceError("device does not exist", self.name)
# device does not exist (a partition request), just set basic values
self._size = newsize
self.req_size = newsize
self.req_base_size = newsize

if newsize > self.disk.size:
raise ValueError("partition size would exceed disk size")
Expand Down
29 changes: 25 additions & 4 deletions blivet/partitioning.py
Expand Up @@ -115,7 +115,7 @@ def _scheduleImplicitPartitions(storage, disks, min_luks_entropy=0):

return devs

def _schedulePartitions(storage, disks, min_luks_entropy=0, requests=None):
def _schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0, requests=None):
""" Schedule creation of autopart/reqpart partitions.
This only schedules the requests for actual partitions.
Expand Down Expand Up @@ -242,8 +242,29 @@ def _schedulePartitions(storage, disks, min_luks_entropy=0, requests=None):
parents=dev)
storage.createDevice(luks_dev)

# make sure preexisting broken lvm/raid configs get out of the way
return
if storage.autoPartType in (AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP,
AUTOPART_TYPE_BTRFS):
# doing LVM/BTRFS -- make sure the newly created partition fits in some
# free space together with one of the implicitly requested partitions
smallest_implicit = sorted(implicit_devices, key=lambda d: d.size)[0]
if (request.size + smallest_implicit.size) > all_free[0]:
# not enough space to allocate the smallest implicit partition
# and the request, make the implicit partition smaller with
# fixed size in order to make space for the request
new_size = all_free[0] - request.size

# subtract the size from the biggest free region and reorder the
# list
all_free[0] -= request.size
all_free.sort(reverse=True)

if new_size > Size(0):
smallest_implicit.size = new_size
else:
implicit_devices.remove(smallest_implicit)
storage.destroyDevice(smallest_implicit)

return implicit_devices

def _scheduleVolumes(storage, devs):
""" Schedule creation of autopart lvm/btrfs volumes.
Expand Down Expand Up @@ -419,7 +440,7 @@ def doAutoPartition(storage, data, min_luks_entropy=0):
raise NotEnoughFreeSpaceError(_("Not enough free space on disks for "
"automatic partitioning"))

_schedulePartitions(storage, disks, min_luks_entropy=min_luks_entropy)
devs = _schedulePartitions(storage, disks, devs, min_luks_entropy=min_luks_entropy)

# run the autopart function to allocate and grow partitions
doPartitioning(storage)
Expand Down

0 comments on commit 023164e

Please sign in to comment.