summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2024-04-13 20:27:48 +0200
committerJulian Andres Klode <jak@debian.org>2024-04-13 20:27:48 +0200
commitf7e5ed3c8dffcdfc2c55c63f2e3cbcb390bbf013 (patch)
tree0b610e56522989082301b14b0cef9a3109aa8d94
parentcf71004551eca23f6d73648bc19f65e8b2a08ce9 (diff)
Show space estimate for /boot, if separate; or estimate initrd for /usr
Calculate an estimate of 110% of the biggest initrd + system.map as the additional space a kernel needs in /boot. If /boot is a different file system than /usr, print the size of the kernels + the additional space they will need separately; otherwise include it in our /usr figure.
-rw-r--r--apt-pkg/depcache.cc56
-rw-r--r--apt-pkg/depcache.h4
-rw-r--r--apt-pkg/init.cc2
-rw-r--r--apt-private/private-install.cc23
-rw-r--r--doc/examples/configure-index3
5 files changed, 86 insertions, 2 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index e3e8d627c..76a5c09ba 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -42,6 +42,7 @@
#include <unordered_map>
#include <utility>
#include <vector>
+#include <dirent.h>
#include <sys/stat.h>
@@ -2613,3 +2614,58 @@ bool pkgDepCache::PhasingApplied(pkgCache::PkgIterator Pkg) const
return true;
}
/*}}}*/
+
+// DepCache::BootSize /*{{{*/
+double pkgDepCache::BootSize(bool initrdOnly)
+{
+ double BootSize = 0;
+ int BootCount = 0;
+ auto VirtualKernelPkg = FindPkg("$kernel", "any");
+ if (VirtualKernelPkg.end())
+ return 0;
+
+ for (pkgCache::PrvIterator Prv = VirtualKernelPkg.ProvidesList(); Prv.end() == false; ++Prv)
+ {
+ auto Pkg = Prv.OwnerPkg();
+ if ((*this)[Pkg].NewInstall())
+ BootSize += (*this)[Pkg].InstallVer->InstalledSize, BootCount++;
+ }
+ if (BootCount == 0)
+ return 0;
+ if (initrdOnly)
+ BootSize = 0;
+
+ DIR *boot = opendir(_config->FindDir("Dir::Boot").c_str());
+ struct dirent *ent;
+ if (boot)
+ {
+ double initrdSize = 0;
+ double mapSize = 0;
+ while ((ent = readdir(boot)))
+ {
+ enum
+ {
+ INITRD,
+ MAP
+ } type;
+ if (APT::String::Startswith(ent->d_name, "initrd.img-"))
+ type = INITRD;
+ else if (APT::String::Startswith(ent->d_name, "System.map-"))
+ type = MAP;
+ else
+ continue;
+
+ auto path = _config->FindDir("Dir::Boot") + ent->d_name;
+
+ if (struct stat st; stat(path.c_str(), &st) == 0)
+ {
+ double &targetSize = type == INITRD ? initrdSize : mapSize;
+ targetSize = std::max(targetSize, double(st.st_size));
+ }
+ }
+ closedir(boot);
+ return initrdSize ? BootSize + BootCount * (initrdSize + mapSize) * 1.1 : 0;
+ }
+ return 0;
+}
+ /*}}}*/
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 5dd022b56..23047b97a 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -490,7 +490,9 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace
virtual ~pkgDepCache();
bool CheckConsistency(char const *const msgtag = "");
-
+#ifdef APT_COMPILING_APT
+ double BootSize(bool initrdOnly);
+#endif
protected:
// methods call by IsInstallOk
bool IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index 75935404f..487f94f20 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -147,6 +147,8 @@ bool pkgInitConfig(Configuration &Cnf)
// Configuration
Cnf.CndSet("Dir::Etc", &CONF_DIR[1]);
+ Cnf.CndSet("Dir::Boot", "boot");
+ Cnf.CndSet("Dir::Usr", "usr");
Cnf.CndSet("Dir::Etc::sourcelist","sources.list");
Cnf.CndSet("Dir::Etc::sourceparts","sources.list.d");
Cnf.CndSet("Dir::Etc::main","apt.conf");
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index 13c90c6fc..c67b71cb3 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -28,6 +28,7 @@
#include <map>
#include <set>
#include <vector>
+#include <langinfo.h>
#include <sys/statvfs.h>
#include <apt-private/acqprogress.h>
@@ -343,13 +344,33 @@ bool InstallPackages(CacheFile &Cache, APT::PackageVector &HeldBackPackages, boo
else
{
struct statvfs st;
- if (statvfs("/usr", &st) == 0)
+ if (statvfs(_config->FindDir("Dir::Usr").c_str(), &st) == 0)
{
+ struct statvfs st_boot;
+ double BootSize = 0;
+ double InitrdSize = 0;
+ if (statvfs(_config->FindDir("Dir::Boot").c_str(), &st_boot) == 0 && st_boot.f_fsid != st.f_fsid)
+ BootSize = Cache->BootSize(false);
+ else
+ InitrdSize = Cache->BootSize(true); /* initrd only, adding to /usr space */
+
ioprintf(c1out, " ");
// TRANSLATOR: The required space between number and unit is already included
// in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
ioprintf(c1out, _("Space needed: %sB / approx. %sB available\n"),
SizeToStr(Cache->UsrSize() + InitrdSize).c_str(), SizeToStr((st.f_bsize * st.f_bavail)).c_str());
+
+ if (BootSize != 0)
+ {
+ bool Unicode = strcmp(nl_langinfo(CODESET), "UTF-8") == 0;
+ ioprintf(c1out, Unicode ? " └─ " : " - ");
+ // TRANSLATOR: The required space between number and unit is already included
+ // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB -
+ // The first %s is the location of the boot directory (determined from Dir::Boot),
+ // and it tells the space being needed there.
+ ioprintf(c1out, _("in %s: approx. %sB / %sB available\n"),
+ _config->FindFile("Dir::Boot").c_str(), SizeToStr(BootSize).c_str(), SizeToStr((st_boot.f_bsize * st_boot.f_bavail)).c_str());
+ }
}
else
{
diff --git a/doc/examples/configure-index b/doc/examples/configure-index
index cc9a2e765..72e907507 100644
--- a/doc/examples/configure-index
+++ b/doc/examples/configure-index
@@ -487,6 +487,9 @@ Dir "<DIR>"
{
MountPath "/media/apt"; // Media AutoDetect mount path
};
+
+ Boot "<DIR>";
+ Usr "<DIR>";
};
// Things that effect the APT dselect method