[PATCH] Enforce limits on partition start/end sectors.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All bootable requests should lie completely below 2TB.

Also honor disklabel-specific maximum sector when growing partitions.

Related: rhbz#604059
---
 storage/partitioning.py |   73 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/storage/partitioning.py b/storage/partitioning.py
index 519350b..ba61227 100644
--- a/storage/partitioning.py
+++ b/storage/partitioning.py
@@ -644,6 +644,14 @@ def getBestFreeSpaceRegion(disk, part_type, req_size,
             log.debug("free range start sector beyond max for new partitions")
             continue
 
+        if boot:
+            free_start_mb = sectorsToSize(free_geom.start,
+                                          disk.device.sectorSize)
+            req_end_mb = free_start_mb + req_size
+            if req_end_mb > 2*1024*1024:
+                log.debug("free range position would place boot req above 2TB")
+                continue
+
         log.debug("current free range is %d-%d (%dMB)" % (free_geom.start,
                                                           free_geom.end,
                                                           free_geom.getSize()))
@@ -1250,6 +1258,11 @@ class Chunk(object):
 
                 requests -- list of Request instances allocated from this chunk
 
+
+            Note: We will limit partition growth based on disklabel
+            limitations for partition end sector, so a 10TB disk with an
+            msdos disklabel will be treated like a 2TB disk.
+
         """
         self.geometry = geometry            # parted.Geometry
         self.pool = self.geometry.length    # free sector count
@@ -1278,6 +1291,25 @@ class Chunk(object):
     def addRequest(self, req):
         """ Add a Request to this chunk. """
         log.debug("adding request %d to chunk %s" % (req.partition.id, self))
+        if not self.requests:
+            # when adding the first request to the chunk, adjust the pool
+            # size to reflect any disklabel-specific limits on end sector
+            max_sector = req.partition.partedPartition.disk.maxPartitionStartSector
+            chunk_end = min(max_sector, self.geometry.end)
+            if chunk_end <= self.geometry.start:
+                # this should clearly never be possible, but if the chunk's
+                # start sector is beyond the maximum allowed end sector, we
+                # cannot continue
+                log.error("chunk start sector is beyond disklabel maximum")
+                raise PartitioningError("partitions allocated outside "
+                                        "disklabel limits")
+
+            new_pool = chunk_end - self.geometry.start + 1
+            if new_pool != self.pool:
+                log.debug("adjusting pool to %d based on disklabel limits"
+                            % new_pool)
+                self.pool = new_pool
+
         self.requests.append(req)
         self.pool -= req.base
 
@@ -1315,16 +1347,49 @@ class Chunk(object):
 
     def trimOverGrownRequest(self, req, base=None):
         """ Enforce max growth and return extra sectors to the pool. """
-        if req.max_growth and req.growth >= req.max_growth:
-            if req.growth > req.max_growth:
+        req_end = req.partition.partedPartition.geometry.end
+        req_start = req.partition.partedPartition.geometry.start
+
+        # Establish the current total number of sectors of growth for requests
+        # that lie before this one within this chunk. We add the total count
+        # to this request's end sector to obtain the end sector for this
+        # request, including growth of earlier requests but not including
+        # growth of this request. Maximum growth values are obtained using
+        # this end sector and various values for maximum end sector.
+        growth = 0
+        for request in self.requests:
+            if request.partition.partedPartition.geometry.start < req_start:
+                growth += request.growth
+        req_end += growth
+
+        # obtain the set of possible maximum sectors-of-growth values for this
+        # request and use the smallest
+        limits = []
+
+        # disklabel-specific maximum sector
+        max_sector = req.partition.partedPartition.disk.maxPartitionStartSector
+        limits.append(max_sector - req_end)
+
+        # 2TB limit on bootable partitions, regardless of disklabel
+        if req.partition.req_bootable:
+            limits.append(sizeToSectors(2*1024*1024, self.sectorSize) - req_end)
+
+        # request-specific maximum (see Request.__init__, above, for details)
+        if req.max_growth:
+            limits.append(req.max_growth)
+
+        max_growth = min(limits)
+
+        if max_growth and req.growth >= max_growth:
+            if req.growth > max_growth:
                 # we've grown beyond the maximum. put some back.
-                extra = req.growth - req.max_growth
+                extra = req.growth - max_growth
                 log.debug("taking back %d (%dMB) from %d (%s)" %
                             (extra,
                              sectorsToSize(extra, self.sectorSize),
                              req.partition.id, req.partition.name))
                 self.pool += extra
-                req.growth = req.max_growth
+                req.growth = max_growth
 
             # We're done growing this partition, so it no longer
             # factors into the growable base used to determine
-- 
1.7.1.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux