[PATCH] Delete dependency packages more thoroughly when removing a package.
Hello All,
My name is Ulrik Sjolin and I have been assigned to solve an issue with apt-get at $DAYJOB. The bug we encounter is related to the fact that we have an or-package pretty high up in our dependency tree. This leads to the problem where apt adds a bunch of packages that it later on decides should be removed. In the removal process apt-get does not remove the all packages it added in the first pass (looks a bit like bug 122304) . This forces us to use the auto-remove functionality. Unfortunately that switch does not work for us since this will remove packages that we want.
So I have created a patch that I would appreciate if you would review/approve/merge ;-) I am sure that this is not the most efficient way of writing this code, I am new to the apt code base so advice and or suggestions on how to improve the patch is greatly appreciated. I have run our test cases on the patch and it seems to work....
Best Regards,
Ulrik Sjolin
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 34da745..3d6d5f5 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -715,6 +715,42 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
Cache.MarkKeep(Pkg, false, false);
else
Cache.MarkDelete(Pkg);
+
+ // Loop over all the packages and look for further packages to remove.
+ // The specific case that we need to handle here is the one where a package
+ // that is removed has a target package that has no other parent package.
+ for(PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
+ {
+ for (pkgCache::DepIterator D = P.RevDependsList(); D.end() == false; D++)
+ {
+ if (D.ParentPkg()->ID == Pkg->ID)
+ {
+ int count = 0;
+ for(DepIterator childDeps = D.TargetPkg().RevDependsList(); childDeps.end() == false; childDeps++) {
+ if ((Flags[childDeps.ParentPkg()->ID] & PreInstalled) == PreInstalled) {
+ count++;
+ }
+ }
+
+ // If the child package only had the parent that we are going to remove and
+ // the child package was not marked as protected we should get rid of the
+ // child package.
+ if(count == 1 && ((Flags[D.TargetPkg()->ID] & Protected) != Protected))
+ {
+ if (Debug == true)
+ clog << " Killed sibling: " << D.TargetPkg() << endl;
+ if(WasKept == true)
+ Cache.MarkKeep(D.TargetPkg(), false, false);
+ else
+ Cache.MarkDelete(D.TargetPkg());
+ }
+ }
+ }
+ }
+
+ if (Debug == true)
+ clog << " Killed " << Pkg << endl;
+
return false;
}
Reply to: