instead of 'du' we use File::Find to avoid different results on different filesystems, see https://bugs.debian.org/650077 for a discussion

This commit is contained in:
Johannes 'josch' Schauer 2020-06-23 22:45:17 +02:00
parent 655857e525
commit 4d041140d5
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1

View file

@ -32,6 +32,7 @@ use File::Copy;
use File::Path qw(make_path remove_tree); use File::Path qw(make_path remove_tree);
use File::Temp qw(tempfile tempdir); use File::Temp qw(tempfile tempdir);
use File::Basename; use File::Basename;
use File::Find;
use Cwd qw(abs_path); use Cwd qw(abs_path);
require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes) require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
use Fcntl qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD); use Fcntl qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD);
@ -2882,24 +2883,36 @@ sub guess_sources_format {
sub approx_disk_usage { sub approx_disk_usage {
my $directory = shift; my $directory = shift;
info "approximating disk usage..."; info "approximating disk usage...";
# to return the same number of blocks irrespective of the chosen mode # the "du" utility reports different results depending on the underlying
# we exclude /dev from being counted # filesystem, see https://bugs.debian.org/650077 for a discussion
open my $fh, '-|', 'du', '--block-size', '1024', #
"--exclude=$directory/dev", '--summarize', '--one-file-system', # we use code similar to the one used by dpkg-gencontrol instead
$directory // error "failed to fork(): $!"; #
chomp( # Regular files are measured in number of 1024 byte blocks. All other
my $du = do { local $/; <$fh> } # entries are assumed to take one block of space.
); #
close $fh; # We ignore /dev because depending on the mode, the directory might be
if (($? != 0) or (!$du)) { # populated or not and we want consistent disk usage results independent
error "du failed: $?"; # of the mode.
} my $installed_size = 0;
if ($du =~ /^(\d+)\t/) { my $scan_installed_size = sub {
return int($1 * 1.1); if ($File::Find::name eq "$directory/dev") {
# add all entries of @devfiles once
$installed_size += scalar @devfiles;
} elsif ($File::Find::name =~ /^$directory\/dev\//) {
# ignore everything below /dev
} elsif (-f $File::Find::name) {
# add file size in 1024 byte blocks, rounded up
$installed_size += int(((-s $File::Find::name) + 1024) / 1024);
} else { } else {
error "unexpected du output: $du"; # all other entries are assumed to only take up one block
$installed_size += 1;
} }
return; };
find($scan_installed_size, $directory);
# because the above is only a heuristic we add 10% extra for good measure
return int($installed_size * 1.1);
} }
sub main() { sub main() {