Blame SOURCES/BZ-1645173-clean-all-disk-usage-fixes.patch

6e3a62
diff -up yum-3.4.3/cli.py.orig yum-3.4.3/cli.py
6e3a62
--- yum-3.4.3/cli.py.orig	2019-03-27 16:55:58.034750506 +0100
6e3a62
+++ yum-3.4.3/cli.py	2019-03-27 16:57:54.515257711 +0100
6e3a62
@@ -1740,6 +1740,7 @@ class YumBaseCli(yum.YumBase, output.Yum
6e3a62
             paths = glob.glob(cacheglob + '/*')
6e3a62
             table = ([], [], [], [])  # (enabled, disabled, untracked, other)
6e3a62
             repos = self.repos.repos
6e3a62
+            empty = True
6e3a62
             for path in paths:
6e3a62
                 base = os.path.basename(path)
6e3a62
                 if os.path.isdir(path):
6e3a62
@@ -1750,18 +1751,29 @@ class YumBaseCli(yum.YumBase, output.Yum
6e3a62
                         col = 0
6e3a62
                     else:
6e3a62
                         col = 1
6e3a62
-                    # Recursively gather all files in this repodir
6e3a62
-                    files = yum.misc.getFileList(path, '', [])
6e3a62
                 else:
6e3a62
                     # Ordinary file (such as timedhosts)
6e3a62
                     col = 3
6e3a62
-                    files = [path]
6e3a62
-                usage = sum(map(os.path.getsize, files))
6e3a62
-                if usage > 0:
6e3a62
-                    table[col].append((usage, path))
6e3a62
+                usage = yum.misc.disk_usage(path)
6e3a62
+                if not usage:
6e3a62
+                    continue
6e3a62
+                table[col].append((usage, path))
6e3a62
+                # Detect any uncleaned data.
6e3a62
+                #
6e3a62
+                # We never remove directories or any unrecognized repodata
6e3a62
+                # files, so there always will be a few kilobytes left behind.
6e3a62
+                # To avoid a constant false alarm, let's ignore such files if
6e3a62
+                # they are really tiny (such as "productid").  The easiest way
6e3a62
+                # is to look at "usage" as it covers both directories and
6e3a62
+                # files.  Given that a typical cleaned repodir (4K) consists of
6e3a62
+                # the gen/ (4K) and packages/ (4K) subdirs and possibly the
6e3a62
+                # productid file (8K), let's "round" it up to 64K and use that
6e3a62
+                # as our threshold.
6e3a62
+                if col < 3 and usage > 64*1024:
6e3a62
+                    empty = False
6e3a62
 
6e3a62
             # Print the table (verbose mode only)
6e3a62
-            lines = [_('Disk usage of %s after cleanup:') % cacheglob]
6e3a62
+            lines = [_('Disk usage under %s after cleanup:') % cacheglob]
6e3a62
             headers = ('enabled repos', 'disabled repos', 'untracked repos',
6e3a62
                        'other data')
6e3a62
             totals = [0, 0, 0, 0]
6e3a62
@@ -1783,12 +1795,11 @@ class YumBaseCli(yum.YumBase, output.Yum
6e3a62
             msg = '\n'.join(lines)
6e3a62
             self.verbose_logger.log(yum.logginglevels.DEBUG_3, msg)
6e3a62
 
6e3a62
-            # Print a short hint for leftover repos specifically (non-verbose
6e3a62
-            # mode only)
6e3a62
-            total = sum(totals[:3])
6e3a62
-            if self.conf.debuglevel == 6 or not total:
6e3a62
+            # Print a short hint if leftover repos are found (non-verbose mode
6e3a62
+            # only).
6e3a62
+            if empty or self.conf.debuglevel == 6:
6e3a62
                 return code, []
6e3a62
-            total = self.format_number(total)
6e3a62
+            total = self.format_number(sum(totals[:3]))
6e3a62
             if total[-1] == ' ':
6e3a62
                 total = total[:-1] + 'bytes'
6e3a62
             msg = (_('Other repos take up %s of disk space '
6e3a62
diff -up yum-3.4.3/docs/yum.8.orig yum-3.4.3/docs/yum.8
6e3a62
--- yum-3.4.3/docs/yum.8.orig	2019-03-27 16:55:58.034750506 +0100
6e3a62
+++ yum-3.4.3/docs/yum.8	2019-03-27 16:57:54.515257711 +0100
6e3a62
@@ -1032,35 +1032,13 @@ Or:          \fByum list available 'foo*
6e3a62
 .SH "CLEAN OPTIONS"
6e3a62
 The following are the ways which you can invoke \fByum\fP in clean mode.
6e3a62
 
6e3a62
-Note that these commands only operate on files in currently enabled
6e3a62
-repositories.
6e3a62
-If you use substitution variables (such as $releasever) in your \fBcachedir\fP
6e3a62
-configuration, the operation is further restricted to the current values of
6e3a62
-those variables.
6e3a62
-
6e3a62
-For fine-grained control over what is being cleaned, you can use
6e3a62
-\fB\-\-enablerepo\fP, \fB\-\-disablerepo\fP and \fB\-\-releasever\fP as
6e3a62
-desired.
6e3a62
-Note, however, that you cannot use \fB\-\-releasever='*'\fP to do the cleaning
6e3a62
-for all values previously used.
6e3a62
-Also note that untracked (no longer configured) repositories will not be
6e3a62
-automatically cleaned.
6e3a62
-
6e3a62
-To purge the entire cache in one go, the easiest way is to delete the files
6e3a62
-manually.
6e3a62
-Depending on your \fBcachedir\fP configuration, this usually means treating any
6e3a62
-variables as shell wildcards and recursively removing matching directories.
6e3a62
-For example, if your \fBcachedir\fP is /var/cache/yum/$basearch/$releasever,
6e3a62
-then the whole /var/cache/yum directory has to be removed.
6e3a62
-If you do this, \fByum\fP will rebuild the cache as required the next time it
6e3a62
-is run (this may take a while).
6e3a62
-
6e3a62
-As a convenience, when you run \fByum clean all\fP, a recursive lookup will be
6e3a62
-done to detect any repositories not cleaned due to the above restrictions.
6e3a62
-If some are found, a message will be printed stating how much disk space they
6e3a62
-occupy and thus how much you can reclaim by cleaning them.
6e3a62
-If you also supply \fB\-\-verbose\fP, a more detailed breakdown will be
6e3a62
-printed.
6e3a62
+Note that these commands only operate on the currently enabled repositories
6e3a62
+within the current \fBcachedir\fR (that is, with any substitution variables
6e3a62
+such as $releasever expanded to their runtime values).
6e3a62
+To clean specific repositories, use \fB\-\-enablerepo\fP, \fB\-\-disablerepo\fP
6e3a62
+or \fB\-\-releasever\fP accordingly.
6e3a62
+Note, however, that untracked (no longer configured) repositories cannot be
6e3a62
+cleaned this way; they have to be removed manually.
6e3a62
 
6e3a62
 .IP "\fByum clean expire-cache\fP"
6e3a62
 Eliminate the local data saying when the metadata and mirrorlists were downloaded for each repo. This means yum will revalidate the cache for each repo. next time it is used. However if the cache is still valid, nothing significant was deleted.
6e3a62
@@ -1090,6 +1068,13 @@ Tell any enabled plugins to eliminate th
6e3a62
 
6e3a62
 .IP "\fByum clean all\fP"
6e3a62
 Does all of the above.
6e3a62
+As a convenience, if this command does not result in a completely empty cache
6e3a62
+due to the restrictions outlined at the beginning of this section, a message
6e3a62
+will be printed, saying how much disk space can be reclaimed by cleaning the
6e3a62
+remaining repos manually.
6e3a62
+For this purpose, a repo is considered clean when its disk usage doesn't exceed
6e3a62
+64KB (that is to account for directory entries and tiny metadata files such as
6e3a62
+"productid" that are never cleaned).
6e3a62
 
6e3a62
 .SH "EXAMPLES"
6e3a62
 .PP
6e3a62
diff -up yum-3.4.3/yum/misc.py.orig yum-3.4.3/yum/misc.py
6e3a62
--- yum-3.4.3/yum/misc.py.orig	2019-03-27 16:55:58.010750196 +0100
6e3a62
+++ yum-3.4.3/yum/misc.py	2019-03-27 16:57:54.515257711 +0100
6e3a62
@@ -1252,3 +1252,15 @@ def validate_repoid(repoid):
6e3a62
             return char
6e3a62
     else:
6e3a62
         return None
6e3a62
+
6e3a62
+def disk_usage(path):
6e3a62
+    """Return disk usage of the given filename, recursively for dirs."""
6e3a62
+    def usage(path):
6e3a62
+        return os.stat(path).st_blocks * 512
6e3a62
+    total = usage(path)
6e3a62
+    if not os.path.isdir(path):
6e3a62
+        return total
6e3a62
+    for root, dirs, files in os.walk(path):
6e3a62
+        paths = (os.path.join(root, entry) for entry in dirs + files)
6e3a62
+        total += sum(usage(path) for path in paths)
6e3a62
+    return total