diff options
author | Julian Andres Klode <jak@debian.org> | 2024-04-13 20:27:48 +0200 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2024-04-13 20:27:48 +0200 |
commit | f7e5ed3c8dffcdfc2c55c63f2e3cbcb390bbf013 (patch) | |
tree | 0b610e56522989082301b14b0cef9a3109aa8d94 | |
parent | cf71004551eca23f6d73648bc19f65e8b2a08ce9 (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.cc | 56 | ||||
-rw-r--r-- | apt-pkg/depcache.h | 4 | ||||
-rw-r--r-- | apt-pkg/init.cc | 2 | ||||
-rw-r--r-- | apt-private/private-install.cc | 23 | ||||
-rw-r--r-- | doc/examples/configure-index | 3 |
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 |