[f23-branch 1/1] Improve install space required estimation (#1224048)

jkonecny12 installerbot-noreply at redhat.com
Fri Oct 23 14:12:31 UTC 2015


From: Jiri Konecny <jkonecny at redhat.com>

The problem was that 35% add is not enough on the smaller installations.
That result in crash on RPM transaction check. RPM required more space
than we have.
This problem was consulted with RPM team and this is result.
The RPM rounding size of files to fragment size for better estimation
also they are required package header size * 4 for RPM DB.

We don't have header size or file size in the installation so I'm trying
to simulate worst case scenario for file rounding and using 2KiB for
every file to get something like RPM DB space required.
Also 10% is add to all this as a safeguard.

Seems as stable assumption right now.
+
Improved logging for packaging.

Resolves: rhbz#1224048
---
 pyanaconda/packaging/dnfpayload.py | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/pyanaconda/packaging/dnfpayload.py b/pyanaconda/packaging/dnfpayload.py
index 70b120d..8092752 100644
--- a/pyanaconda/packaging/dnfpayload.py
+++ b/pyanaconda/packaging/dnfpayload.py
@@ -115,8 +115,8 @@ def reasonable_mpoint(mpoint):
                    # for root we need to take in count both download and install size
                    if ((key != root_mpoint and val > requested)
                    or val > requested_root) and reasonable_mpoint(key)}
-    log.debug('Estimated size: download %s & install %s - df: %s', requested,
-              (requested_root - requested), df)
+    log.debug('Estimated size: download %s & install %s', requested,
+              (requested_root - requested))
     log.info('Sufficient mountpoints found: %s', sufficients)
 
     if not len(sufficients):
@@ -555,11 +555,14 @@ def spaceRequired(self):
             if key.startswith('/') and ((root_mpoint + new_key) not in valid_points):
                 valid_points[root_mpoint + new_key] = val.format.freeSpaceEstimate(val.size)
 
-        m_points = _pick_mpoint(valid_points, download_size, size)
-        if not m_points or m_points == root_mpoint:
+        m_point = _pick_mpoint(valid_points, download_size, size)
+        if not m_point or m_point == root_mpoint:
             # download and install to the same mount point
             size = size + download_size
-        log.debug("Instalation space required %s for mpoints %s", size, m_points)
+            log.debug("Install + download space required %s", size)
+        else:
+            log.debug("Download space required %s for mpoint %s (non-chroot)", download_size, m_point)
+            log.debug("Installation space required %s", size)
         return size
 
     def _spaceRequired(self):
@@ -567,11 +570,23 @@ def _spaceRequired(self):
         if transaction is None:
             return Size("3000 MB")
 
-        size = sum(tsi.installed.installsize for tsi in transaction)
-        # add 35% to account for the fact that the above method is laughably
-        # inaccurate:
-        size *= 1.35
-        return Size(size)
+        size = 0
+        files_nm = 0
+        for tsi in transaction:
+            # space taken by all files installed by the packages
+            size += tsi.installed.installsize
+            # number of files installed on the system
+            files_nm += len(tsi.installed.files)
+        # add required space which depends on block size and rpm database taken space estimation
+        # 6144 = 4K(max default fragment size) + 2K(rpm db could be taken for a header file)
+        bonus_size = files_nm * 6144
+        size = size + bonus_size
+        # add another 10% as safeguard
+        total_space = Size(size) * 1.1
+        log.debug("Size %s files %s", Size(size), files_nm)
+        log.debug("Bonus size %s B", bonus_size)
+        log.debug("Complete size required %s", total_space)
+        return total_space
 
     def _isGroupVisible(self, grpid):
         grp = self._base.comps.group_by_pattern(grpid)
@@ -688,7 +703,7 @@ def install(self):
                 _failure_limbo()
 
         pkgs_to_download = self._base.transaction.install_set
-        log.info('Downloading packages.')
+        log.info('Downloading packages to %s.', self._download_location)
         progressQ.send_message(_('Downloading packages'))
         progress = DownloadProgress()
         try:


-- 
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/e1c50ac9ae5a38bb63c918994ba7503e6dd07b50


More information about the anaconda-patches mailing list