summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2010-02-10 17:42:39 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2010-02-10 17:42:39 +0100
commit8b32e9209ecfab776f064e3c4ccab249307ae49d (patch)
treedf0a6a283bff447e55a9345425eba17c1e90bb5c
parent857e9c13d8d9808fcd1ac8ff3469f6c0b90b7fea (diff)
Pre-MultiArch a package which depends on a package with architecture "all"
can be sure that a package comeing in as a dependency of this package will be of the same architecture as itself (or all). We don't want to break this, so internal an arch all package is represented as many arch depending packages. The only problem we have now is that we only know that a arch all package is installed or not - we don't know for which architecture it was installed: So we will look at all these broken arch all pseudo packages and "remove" them.
-rw-r--r--apt-pkg/depcache.cc93
-rw-r--r--apt-pkg/depcache.h12
-rw-r--r--apt-pkg/pkgcachegen.cc16
3 files changed, 110 insertions, 11 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 228750b74..b04181d76 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -17,6 +17,7 @@
#include <apt-pkg/fileutl.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/tagfile.h>
@@ -596,6 +597,57 @@ void pkgDepCache::UpdateVerState(PkgIterator Pkg)
}
}
/*}}}*/
+// DepCache::RemovePseudoInstalledPkg - MultiArch helper for Update() /*{{{*/
+// ---------------------------------------------------------------------
+/* We "install" arch all packages for all archs if it is installed. Many
+ of these will be broken. This method will look at these broken Pkg and
+ "remove" it. */
+bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) {
+ if (unlikely(Pkg->CurrentVer == 0))
+ return false;
+
+ VerIterator V = Pkg.CurrentVer();
+ if (V->MultiArch != Version::All)
+ return false;
+
+ unsigned char const DepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy);
+ if ((DepState & DepInstMin) == DepInstMin)
+ return false;
+
+ // Dependencies for this arch all are not statisfied
+ // so we installed it only for our convenience: get right of it now.
+ RemoveSizes(Pkg);
+ RemoveStates(Pkg);
+
+ Pkg->CurrentVer = 0;
+ PkgState[Pkg->ID].InstallVer = 0;
+
+ AddStates(Pkg);
+ Update(Pkg);
+ AddSizes(Pkg);
+
+ // After the remove previously satisfied pseudo pkg could be now
+ // no longer satisfied, so we need to recheck the reverse dependencies
+ for (DepIterator d = Pkg.RevDependsList(); d.end() != true; ++d)
+ {
+ PkgIterator const P = d.ParentPkg();
+ if (P->CurrentVer != 0)
+ recheck.insert(P.Index());
+ }
+
+ if (V.end() != true)
+ for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++)
+ for (DepIterator d = Prv.ParentPkg().RevDependsList();
+ d.end() != true; ++d)
+ {
+ PkgIterator const P = d.ParentPkg();
+ if (P->CurrentVer != 0)
+ recheck.insert(P.Index());
+ }
+
+ return true;
+}
+ /*}}}*/
// DepCache::Update - Figure out all the state information /*{{{*/
// ---------------------------------------------------------------------
/* This will figure out the state of all the packages and all the
@@ -609,9 +661,13 @@ void pkgDepCache::Update(OpProgress *Prog)
iKeepCount = 0;
iBrokenCount = 0;
iBadCount = 0;
-
+
+ std::set<unsigned long> recheck;
+
// Perform the depends pass
int Done = 0;
+ bool const checkMultiArch = APT::Configuration::getArchitectures().size() > 1;
+ unsigned long killed = 0;
for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
{
if (Prog != 0 && Done%20 == 0)
@@ -619,7 +675,7 @@ void pkgDepCache::Update(OpProgress *Prog)
for (VerIterator V = I.VersionList(); V.end() != true; V++)
{
unsigned char Group = 0;
-
+
for (DepIterator D = V.DependsList(); D.end() != true; D++)
{
// Build the dependency state.
@@ -637,16 +693,43 @@ void pkgDepCache::Update(OpProgress *Prog)
D->Type == Dep::DpkgBreaks ||
D->Type == Dep::Obsoletes)
State = ~State;
- }
+ }
}
- // Compute the pacakge dependency state and size additions
+ // Compute the package dependency state and size additions
AddSizes(I);
UpdateVerState(I);
AddStates(I);
+
+ if (checkMultiArch != true || I->CurrentVer == 0)
+ continue;
+
+ VerIterator const V = I.CurrentVer();
+ if (V->MultiArch != Version::All)
+ continue;
+
+ recheck.insert(I.Index());
+ --Done; // no progress if we need to recheck the package
}
- if (Prog != 0)
+ if (checkMultiArch == true) {
+ /* FIXME: recheck breaks proper progress reporting as we don't know
+ how many packages we need to recheck. To lower the effect
+ a bit we increase with a kill, but we should do something more clever… */
+ for(std::set<unsigned long>::const_iterator p = recheck.begin();
+ p != recheck.end(); ++p) {
+ if (Prog != 0 && Done%20 == 0)
+ Prog->Progress(Done);
+ PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p);
+ if (RemovePseudoInstalledPkg(P, recheck) == true) {
+ ++killed;
+ ++Done;
+ }
+ recheck.erase(p);
+ }
+ }
+
+ if (Prog != 0)
Prog->Progress(Done);
readStateFile(Prog);
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 0306861a1..63cd954ad 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -46,6 +46,7 @@
#include <vector>
#include <memory>
+#include <set>
class pkgDepCache : protected pkgCache::Namespace
{
@@ -442,9 +443,6 @@ class pkgDepCache : protected pkgCache::Namespace
virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false,
unsigned long Depth = 0, bool FromUser = true);
- // This is for debuging
- void Update(OpProgress *Prog = 0);
-
// read persistent states
bool readStateFile(OpProgress *prog);
bool writeStateFile(OpProgress *prog, bool InstalledOnly=false);
@@ -460,9 +458,15 @@ class pkgDepCache : protected pkgCache::Namespace
inline unsigned long BadCount() {return iBadCount;};
bool Init(OpProgress *Prog);
-
+ // Generate all state information
+ void Update(OpProgress *Prog = 0);
+
pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
virtual ~pkgDepCache();
+
+ private:
+ // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages
+ bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck);
};
#endif
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 2a4a30349..a4ca9dfe4 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -108,13 +108,24 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
unsigned int Counter = 0;
while (List.Step() == true)
{
- // Get a pointer to the package structure
string const PackageName = List.Package();
if (PackageName.empty() == true)
return false;
+ /* As we handle Arch all packages as architecture bounded
+ we add all information to every (simulated) arch package */
+ std::vector<string> genArch;
+ if (List.ArchitectureAll() == true)
+ genArch = APT::Configuration::getArchitectures();
+ else
+ genArch.push_back(List.Architecture());
+
+ for (std::vector<string>::const_iterator arch = genArch.begin();
+ arch != genArch.end(); ++arch)
+ {
+ // Get a pointer to the package structure
pkgCache::PkgIterator Pkg;
- if (NewPackage(Pkg, PackageName, List.Architecture()) == false)
+ if (NewPackage(Pkg, PackageName, *arch) == false)
return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str());
Counter++;
if (Counter % 100 == 0 && Progress != 0)
@@ -257,6 +268,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str());
+ }
}
FoundFileDeps |= List.HasFileDeps();