diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/algorithms.cc | 202 | ||||
-rw-r--r-- | apt-pkg/algorithms.h | 4 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.h | 2 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 79 | ||||
-rw-r--r-- | apt-pkg/depcache.h | 9 | ||||
-rw-r--r-- | apt-pkg/makefile | 2 | ||||
-rw-r--r-- | apt-pkg/packagemanager.cc | 13 | ||||
-rw-r--r-- | apt-pkg/packagemanager.h | 37 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 2 |
9 files changed, 330 insertions, 20 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 479927d65..c679e76f6 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,7 +20,10 @@ #include <apt-pkg/algorithms.h> #include <apt-pkg/error.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/pkgsystem.h> +#include <apt-pkg/version.h> #include <apt-pkg/sptr.h> + #include <apti18n.h> @@ -1061,6 +1064,20 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) return _error->Error(_("Unable to correct problems, you have held broken packages.")); } + // set the auto-flags (mvo: I'm not sure if we _really_ need this, but + // I didn't managed + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) { + if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) { + if(_config->FindI("Debug::pkgAutoRemove",false)) { + std::clog << "Resolve installed new pkg: " << I.Name() + << " (now marking it as auto)" << std::endl; + } + Cache[I].Flags |= pkgCache::Flag::Auto; + } + } + + return true; } /*}}}*/ @@ -1232,3 +1249,188 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) qsort(List,Count,sizeof(*List),PrioComp); } /*}}}*/ + + +// mark a single package in Mark-and-Sweep +void pkgMarkPackage(pkgDepCache &Cache, + const pkgCache::PkgIterator &pkg, + const pkgCache::VerIterator &ver, + bool follow_recommends, + bool follow_suggests) +{ + pkgDepCache::StateCache &state=Cache[pkg]; + pkgCache::VerIterator candver=state.CandidateVerIter(Cache); + pkgCache::VerIterator instver=state.InstVerIter(Cache); + +#if 0 + // If a package was garbage-collected but is now being marked, we + // should re-select it + // For cases when a pkg is set to upgrade and this trigger the + // removal of a no-longer used dependency. if the pkg is set to + // keep again later it will result in broken deps + if(state.Delete() && state.RemoveReason=pkgDepCache::Unused) + { + if(ver==candver) + mark_install(pkg, false, false, NULL); + else if(ver==pkg.CurrentVer()) + MarkKeep(pkg); + + instver=state.InstVerIter(*this); + } +#endif + + // Ignore versions other than the InstVer, and ignore packages + // that are already going to be removed or just left uninstalled. + if(!(ver==instver && !instver.end())) + return; + + // if we are marked already we are done + if(state.Marked) + return; + + //std::cout << "Setting Marked for: " << pkg.Name() << std::endl; + state.Marked=true; + + if(!ver.end()) + { + for(pkgCache::DepIterator d=ver.DependsList(); !d.end(); ++d) + { + if(d->Type==pkgCache::Dep::Depends || + d->Type==pkgCache::Dep::PreDepends || + (follow_recommends && + d->Type==pkgCache::Dep::Recommends) || + (follow_suggests && + d->Type==pkgCache::Dep::Suggests)) + { + // Try all versions of this package. + for(pkgCache::VerIterator V=d.TargetPkg().VersionList(); + !V.end(); ++V) + { + if(_system->VS->CheckDep(V.VerStr(),d->CompareOp, d.TargetVer())) + { + pkgMarkPackage(Cache, V.ParentPkg(), V, + follow_recommends, follow_suggests); + } + } + // Now try virtual packages + for(pkgCache::PrvIterator prv=d.TargetPkg().ProvidesList(); + !prv.end(); ++prv) + { + if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, + d.TargetVer())) + { + pkgMarkPackage(Cache, prv.OwnerPkg(), prv.OwnerVer(), + follow_recommends, follow_suggests); + } + } + } + } + } +} + + +bool pkgMarkUsed(pkgDepCache &Cache) +{ + bool follow_recommends; + bool follow_suggests; + + // init the states + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) + { + Cache[p].Marked=false; + Cache[p].Garbage=false; + } + + // init vars + follow_recommends=_config->FindB("APT::AutoRemove::RecommendsImportant",false); + follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportend", false); + + + // do the mark part + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) + { + if(!(Cache[p].Flags & pkgCache::Flag::Auto) || + (p->Flags & pkgCache::Flag::Essential)) + { + if(Cache[p].Keep() && !p.CurrentVer().end()) + pkgMarkPackage(Cache, p, p.CurrentVer(), + follow_recommends, follow_suggests); + else if(Cache[p].Install()) + pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache), + follow_recommends, follow_suggests); + } + } + + + // do the sweep + for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p) + { + pkgDepCache::StateCache &state=Cache[p]; + + if(!state.Marked) + { + // mark installed but not yet marked stuff as garbage + if(p->CurrentVer != 0) { + state.Garbage=true; + std::cout << "Garbage: " << p.Name() << std::endl; + } + +#if 0 // mvo: the below bits still needs to be ported + + // Be sure not to re-delete already deleted packages. + if(delete_unused && (!p.CurrentVer().end() || state.Install()) && + !state.Delete()) + { + bool do_delete=true; + + // If the package is being upgraded, check if we're + // losing a versioned dep. If the dependency matches + // the previous version and not the new version, keep + // the package back instead of removing it. + if(!p.CurrentVer().end() && state.Install()) + { + const char *vs=p.CurrentVer().VerStr(); + + // Check direct revdeps only. THIS ASSUMES NO + // VERSIONED PROVIDES, but Debian probably won't + // have them for ages if ever. + for(pkgCache::DepIterator revdep=p.RevDependsList(); + !revdep.end(); ++revdep) + { + pkgCache::PkgIterator depender=revdep.ParentPkg(); + // Find which version of the depending package + // will be installed. + pkgCache::VerIterator instver=(*this)[depender].InstVerIter(*this); + + // Only pay attention to strong positive + // dependencies whose parents will be installed. + if(revdep.ParentVer()==instver && + (revdep->Type==pkgCache::Dep::Depends || + revdep->Type==pkgCache::Dep::PreDepends || + (revdep->Type==pkgCache::Dep::Recommends && + follow_recommends))) + { + // If the previous version matched, cancel the + // deletion. (note that I assume that the new + // version does NOT match; otherwise it would + // not be unused!) + if(_system->VS->CheckDep(vs, + revdep->CompareOp, + revdep.TargetVer())) + { + mark_keep(p, false, false, undo); + do_delete=false; + break; + } + } + } + } + + if(do_delete) + mark_delete(p, false, true, undo); + } +#endif + } + } + return true; +} diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 174a7f58d..210127ab9 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -132,5 +132,9 @@ bool pkgAllUpgrade(pkgDepCache &Cache); bool pkgMinimizeUpgrade(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); + +// mark all reachable packages, everything that is not reach can +// be removed +bool pkgMarkUsed(pkgDepCache &Cache); #endif diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b59b9dc93..8bfdff5eb 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -40,7 +40,7 @@ class pkgDPkgPM : public pkgPackageManager bool RunScripts(const char *Cnf); bool RunScriptsWithPkgs(const char *Cnf); bool SendV2Pkgs(FILE *F); - + // The Actuall installation implementation virtual bool Install(PkgIterator Pkg,string File); virtual bool Configure(PkgIterator Pkg); diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index dd1c794c9..05512e179 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -16,7 +16,13 @@ #include <apt-pkg/error.h> #include <apt-pkg/sptr.h> #include <apt-pkg/algorithms.h> - + +#include <apt-pkg/fileutl.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/tagfile.h> + +#include <iostream> +#include <sstream> #include <apti18n.h> /*}}}*/ @@ -72,7 +78,7 @@ bool pkgDepCache::Init(OpProgress *Prog) // Find the proper cache slot StateCache &State = PkgState[I->ID]; State.iFlags = 0; - + // Figure out the install version State.CandidateVer = GetCandidateVer(I); State.InstallVer = I.CurrentVer(); @@ -99,6 +105,70 @@ bool pkgDepCache::Init(OpProgress *Prog) } /*}}}*/ +bool pkgDepCache::readStateFile(OpProgress *Prog) +{ + FileFd state_file; + string state = _config->FindDir("Dir::State") + "pkgstates"; + if(FileExists(state)) { + state_file.Open(state, FileFd::ReadOnly); + int file_size = state_file.Size(); + Prog->OverallProgress(0, file_size, 1, + _("Reading state information")); + + pkgTagFile tagfile(&state_file); + pkgTagSection section; + int amt=0; + while(tagfile.Step(section)) { + string pkgname = section.FindS("Package"); + pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname); + // Silently ignore unknown packages and packages with no actual + // version. + if(!pkg.end() && !pkg.VersionList().end()) { + short reason = section.FindI("Install-Reason", 0); + if(reason > 0) + PkgState[pkg->ID].Flags |= pkgCache::Flag::Auto; + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::cout << "Install-Reason for: " << pkgname + << " is " << reason << std::endl; + amt+=section.size(); + Prog->OverallProgress(amt, file_size, 1, + _("Reading state information")); + } + Prog->OverallProgress(file_size, file_size, 1, + _("Reading state information")); + } + } + + return true; +} + +bool pkgDepCache::writeStateFile(OpProgress *prog) +{ + FileFd StateFile; + string state = _config->FindDir("Dir::State") + "pkgstates"; + + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "pkgDepCache::writeStateFile()" << std::endl; + + if(!StateFile.Open(state, FileFd::WriteEmpty)) + return _error->Error(_("Failed to write StateFile %s"), + state.c_str()); + + std::ostringstream ostr; + for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end();pkg++) { + + if(PkgState[pkg->ID].Flags & pkgCache::Flag::Auto) { + if(_config->FindB("Debug::pkgAutoRemove",false)) + std::clog << "AutoInstal: " << pkg.Name() << std::endl; + ostr.str(string("")); + ostr << "Package: " << pkg.Name() + << "\nInstall-Reason: 1\n\n"; + StateFile.Write(ostr.str().c_str(), ostr.str().size()); + } + } + return true; +} + // DepCache::CheckDep - Checks a single dependency /*{{{*/ // --------------------------------------------------------------------- /* This first checks the dependency against the main target package and @@ -450,6 +520,8 @@ void pkgDepCache::Update(OpProgress *Prog) AddStates(I); } + readStateFile(Prog); + if (Prog != 0) Prog->Progress(Done); } @@ -585,7 +657,8 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge) else P.Mode = ModeDelete; P.InstallVer = 0; - P.Flags &= Flag::Auto; + // This was not inverted before, but I think it should be + P.Flags &= ~Flag::Auto; AddStates(Pkg); Update(Pkg); diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 6d51920e9..619daf8f6 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -63,6 +63,7 @@ class pkgDepCache : protected pkgCache::Namespace enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; + struct StateCache { // Epoch stripped text versions of the two version fields @@ -79,6 +80,10 @@ class pkgDepCache : protected pkgCache::Namespace unsigned short Flags; unsigned short iFlags; // Internal flags + // mark and sweep flags + bool Marked; + bool Garbage; + // Various tree indicators signed char Status; // -1,0,1,2 unsigned char Mode; // ModeList @@ -192,6 +197,10 @@ class pkgDepCache : protected pkgCache::Namespace // This is for debuging void Update(OpProgress *Prog = 0); + + // read persistent states + bool readStateFile(OpProgress *prog); + bool writeStateFile(OpProgress *prog); // Size queries inline double UsrSize() {return iUsrSize;}; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 5f48f0f52..8de7d945e 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -13,7 +13,7 @@ include ../buildlib/defaults.mak # methods/makefile - FIXME LIBRARY=apt-pkg LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER) -MAJOR=3.9 +MAJOR=3.10 MINOR=0 SLIBS=$(PTHREADLIB) $(INTLLIBS) APT_DOMAIN:=libapt-pkg$(MAJOR) diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a08ccd602..71a0dd034 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -627,16 +627,3 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Completed; } /*}}}*/ -// PM::DoInstall - Does the installation /*{{{*/ -// --------------------------------------------------------------------- -/* This uses the filenames in FileNames and the information in the - DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall() -{ - OrderResult Res = OrderInstall(); - if (Res != Failed) - if (Go() == false) - return Failed; - return Res; -} - /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 43f2c4ace..f95b2ab56 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -28,7 +28,9 @@ #endif #include <string> +#include <iostream> #include <apt-pkg/pkgcache.h> +#include <apt-pkg/depcache.h> using std::string; @@ -70,13 +72,44 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; virtual bool Go(int statusFd=-1) {return true;}; virtual void Reset() {}; - + + // the result of the operation + OrderResult Res; + public: // Main action members bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, pkgRecords *Recs); - OrderResult DoInstall(); + + // Do the installation + OrderResult DoInstall() { + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(); + } + + // stuff that needs to be done before the fork() of a library that + // uses apt + OrderResult DoInstallPreFork() { + Res = OrderInstall(); + return Res; + }; + + // stuff that needs to be done after the fork + OrderResult DoInstallPostFork(int statusFd=-1) { + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + // if all was fine update the state file + if(Res == Completed) { + Cache.writeStateFile(NULL); + } + return Res; + }; + bool FixMissing(); pkgPackageManager(pkgDepCache *Cache); diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 2340f97fd..04904057f 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -26,6 +26,8 @@ #include <apt-pkg/sptr.h> #include <apt-pkg/pkgsystem.h> +#include <apt-pkg/tagfile.h> + #include <apti18n.h> #include <vector> |