]> git.saurik.com Git - apt.git/commitdiff
check for available space, excluding root reserved blocks
authorDavid Kalnischkies <david@kalnischkies.de>
Wed, 15 Oct 2014 02:18:07 +0000 (04:18 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 15 Oct 2014 02:18:07 +0000 (04:18 +0200)
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.

apt-private/private-download.cc
apt-private/private-download.h
apt-private/private-install.cc
apt-private/private-install.h
cmdline/apt-get.cc

index 3ded9e0b9b20e64e6286e00d97071aa00510147d..8cabf14b5fb6e8e6338ff9f90d3ef6fc92c2a58c 100644 (file)
@@ -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;
+}
+                                                                       /*}}}*/
index 809650a97c19595f3096013f17e9d3af88ec354a..0a0ac6b95f7c151e36658de8e70e414355b416f8 100644 (file)
@@ -18,4 +18,6 @@ APT_PUBLIC bool AuthPrompt(std::string const &UntrustedList, bool const PromptUs
 
 APT_PUBLIC bool AcquireRun(pkgAcquire &Fetcher, int const PulseInterval, bool * const Failure, bool * const TransientNetworkFailure);
 
+APT_PUBLIC bool CheckFreeSpaceBeforeDownload(std::string const &Dir, unsigned long long FetchBytes);
+
 #endif
index c06caeedd7207e483ade21455c0862640a2fa070..2a4c3eea560c96664f36f318e0f84b3bdd688dfa 100644 (file)
 #include <apt-pkg/upgrade.h>
 #include <apt-pkg/install-progress.h>
 
-#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
 #include <algorithm>
 #include <iostream>
 #include <set>
@@ -177,33 +174,9 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety)
    if (_error->PendingError() == true)
       return false;
 
-   /* Check for enough free space, but only if we are actually going to
-      download */
-   if (_config->FindB("APT::Get::Print-URIs") == false &&
-       _config->FindB("APT::Get::Download",true) == true)
-   {
-      struct statvfs Buf;
-      std::string OutputDir = _config->FindDir("Dir::Cache::Archives");
-      if (statvfs(OutputDir.c_str(),&Buf) != 0) {
-        if (errno == EOVERFLOW)
-           return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
-                                OutputDir.c_str());
-        else
-           return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
-                                OutputDir.c_str());
-      } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
-      {
-         struct statfs Stat;
-         if (statfs(OutputDir.c_str(),&Stat) != 0
-#if HAVE_STRUCT_STATFS_F_TYPE
-             || unsigned(Stat.f_type) != RAMFS_MAGIC
-#endif
-             )
-            return _error->Error(_("You don't have enough free space in %s."),
-                OutputDir.c_str());
-      }
-   }
-   
+   if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false)
+      return false;
+
    // Fail safe check
    if (_config->FindI("quiet",0) >= 2 ||
        _config->FindB("APT::Get::Assume-Yes",false) == true)
index 8daa4a7769e2e0c9939bf1476cfdcdd06cff1e1b..62276fbff0bb94204a0373bbe1d0261ee1ba0569 100644 (file)
@@ -16,8 +16,6 @@ class CacheFile;
 class CommandLine;
 class pkgProblemResolver;
 
-#define RAMFS_MAGIC     0x858458f6
-
 APT_PUBLIC bool DoInstall(CommandLine &Cmd);
 
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
index 8c0c50f8312fe86cd534802d0d5ffed4ba738b3a..e176a3350c23cf3632e775cd17617cff406d4e9b 100644 (file)
@@ -78,8 +78,6 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <algorithm>
@@ -866,29 +864,9 @@ static bool DoSource(CommandLine &CmdL)
    unsigned long long FetchPBytes = Fetcher.PartialPresent();
    unsigned long long DebBytes = Fetcher.TotalNeeded();
 
-   // Check for enough free space
-   struct statvfs Buf;
-   string OutputDir = ".";
-   if (statvfs(OutputDir.c_str(),&Buf) != 0) {
-      if (errno == EOVERFLOW)
-        return _error->WarningE("statvfs",_("Couldn't determine free space in %s"),
-                               OutputDir.c_str());
-      else
-        return _error->Errno("statvfs",_("Couldn't determine free space in %s"),
-                               OutputDir.c_str());
-   } else if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
-     {
-       struct statfs Stat;
-       if (statfs(OutputDir.c_str(),&Stat) != 0
-#if HAVE_STRUCT_STATFS_F_TYPE
-           || unsigned(Stat.f_type) != RAMFS_MAGIC
-#endif
-           )  {
-          return _error->Error(_("You don't have enough free space in %s"),
-              OutputDir.c_str());
-       }
-     }
-   
+   if (CheckFreeSpaceBeforeDownload(".", (FetchBytes - FetchPBytes)) == false)
+      return false;
+
    // Number of bytes
    if (DebBytes != FetchBytes)
       //TRANSLATOR: The required space between number and unit is already included