diff options
author | David Kalnischkies <david@kalnischkies.de> | 2014-10-15 04:18:07 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2014-10-15 04:18:07 +0200 |
commit | 9c81f8de38df940559d13a3ea9591d63cbe970bb (patch) | |
tree | be24247ffdc8c1589484a3b60da477d9f3ea1b36 /apt-private/private-download.cc | |
parent | 990dd78ab46607ad06d81b36e303156040a236e2 (diff) |
check for available space, excluding root reserved blocks
We are checking the space requirements for ages, but the check uses the
free blocks count, which includes the blocks reserved for usage by root.
Now that we use an unprivileged user it has no access to these blocks
anymore – and more importantly these blocks are a reserve, they
shouldn't be used by apt without special encouragement by the user as it
would be bad to have dpkg run out of diskspace and maintainerscripts
like man-db skip certain actions if not enough space is available
freely.
Diffstat (limited to 'apt-private/private-download.cc')
-rw-r--r-- | apt-private/private-download.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/apt-private/private-download.cc b/apt-private/private-download.cc index 3ded9e0b9..8cabf14b5 100644 --- a/apt-private/private-download.cc +++ b/apt-private/private-download.cc @@ -19,6 +19,9 @@ #include <sys/types.h> #include <pwd.h> #include <fcntl.h> +#include <sys/vfs.h> +#include <sys/statvfs.h> +#include <errno.h> #include <apti18n.h> /*}}}*/ @@ -146,3 +149,39 @@ bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failu return true; } /*}}}*/ +bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes)/*{{{*/ +{ + uint32_t const RAMFS_MAGIC = 0x858458f6; + /* Check for enough free space, but only if we are actually going to + download */ + if (_config->FindB("APT::Get::Print-URIs", false) == true || + _config->FindB("APT::Get::Download", true) == false) + return true; + + struct statvfs Buf; + if (statvfs(Dir.c_str(),&Buf) != 0) { + if (errno == EOVERFLOW) + return _error->WarningE("statvfs",_("Couldn't determine free space in %s"), + Dir.c_str()); + else + return _error->Errno("statvfs",_("Couldn't determine free space in %s"), + Dir.c_str()); + } + else + { + unsigned long long const FreeBlocks = _config->Find("APT::Sandbox::User").empty() ? Buf.f_bfree : Buf.f_bavail; + if (FreeBlocks < (FetchBytes / Buf.f_bsize)) + { + struct statfs Stat; + if (statfs(Dir.c_str(),&Stat) != 0 +#if HAVE_STRUCT_STATFS_F_TYPE + || Stat.f_type != RAMFS_MAGIC +#endif + ) + return _error->Error(_("You don't have enough free space in %s."), + Dir.c_str()); + } + } + return true; +} + /*}}}*/ |