]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: algorithms.cc,v 1.11 1998/11/14 07:20:06 jgg Exp $
4 /* ######################################################################
6 Algorithms - A set of misc algorithms
8 The pkgProblemResolver class has become insanely complex and
9 very sophisticated, it handles every test case I have thrown at it
10 to my satisfaction. Understanding exactly why all the steps the class
11 does are required is difficult and changing though not very risky
12 may result in other cases not working.
14 ##################################################################### */
16 // Include Files /*{{{*/
18 #pragma implementation "apt-pkg/algorithms.h"
20 #include <apt-pkg/algorithms.h>
21 #include <apt-pkg/error.h>
22 #include <apt-pkg/configuration.h>
26 pkgProblemResolver
*pkgProblemResolver::This
= 0;
28 // Simulate::Simulate - Constructor /*{{{*/
29 // ---------------------------------------------------------------------
31 pkgSimulate::pkgSimulate(pkgDepCache
&Cache
) : pkgPackageManager(Cache
),
34 Flags
= new unsigned char[Cache
.HeaderP
->PackageCount
];
35 memset(Flags
,0,sizeof(*Flags
)*Cache
.HeaderP
->PackageCount
);
38 // Simulate::Install - Simulate unpacking of a package /*{{{*/
39 // ---------------------------------------------------------------------
41 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
44 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
47 clog
<< "Inst " << Pkg
.Name();
48 Sim
.MarkInstall(Pkg
,false);
50 // Look for broken conflicts+predepends.
51 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
53 if (Sim
[I
].InstallVer
== 0)
56 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
57 if (D
->Type
== pkgCache::Dep::Conflicts
|| D
->Type
== pkgCache::Dep::PreDepends
)
59 if ((Sim
[D
] & pkgDepCache::DepInstall
) == 0)
61 clog
<< " [" << I
.Name() << " on " << D
.TargetPkg().Name() << ']';
62 if (D
->Type
== pkgCache::Dep::Conflicts
)
63 _error
->Error("Fatal, conflicts violated %s",I
.Name());
68 if (Sim
.BrokenCount() != 0)
75 // Simulate::Configure - Simulate configuration of a Package /*{{{*/
76 // ---------------------------------------------------------------------
77 /* This is not an acurate simulation of relatity, we should really not
78 install the package.. For some investigations it may be necessary
80 bool pkgSimulate::Configure(PkgIterator iPkg
)
83 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
86 // Sim.MarkInstall(Pkg,false);
87 if (Sim
[Pkg
].InstBroken() == true)
89 clog
<< "Conf " << Pkg
.Name() << " broken" << endl
;
93 // Print out each package and the failed dependencies
94 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
96 if (Sim
.IsImportantDep(D
) == false ||
97 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
100 if (D
->Type
== pkgCache::Dep::Conflicts
)
101 clog
<< " Conflicts:" << D
.TargetPkg().Name();
103 clog
<< " Depends:" << D
.TargetPkg().Name();
107 _error
->Error("Conf Broken %s",Pkg
.Name());
110 clog
<< "Conf " << Pkg
.Name();
112 if (Sim
.BrokenCount() != 0)
120 // Simulate::Remove - Simulate the removal of a package /*{{{*/
121 // ---------------------------------------------------------------------
123 bool pkgSimulate::Remove(PkgIterator iPkg
)
125 // Adapt the iterator
126 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
130 clog
<< "Remv " << Pkg
.Name();
132 if (Sim
.BrokenCount() != 0)
140 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
141 // ---------------------------------------------------------------------
143 void pkgSimulate::ShortBreaks()
146 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
148 if (Sim
[I
].InstBroken() == true)
150 if (Flags
[I
->ID
] == 0)
151 clog
<< I
.Name() << ' ';
153 clog << I.Name() << "! ";*/
159 // ApplyStatus - Adjust for non-ok packages /*{{{*/
160 // ---------------------------------------------------------------------
161 /* We attempt to change the state of the all packages that have failed
162 installation toward their real state. The ordering code will perform
163 the necessary calculations to deal with the problems. */
164 bool pkgApplyStatus(pkgDepCache
&Cache
)
166 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
168 switch (I
->CurrentState
)
170 // This means installation failed somehow
171 case pkgCache::State::UnPacked
:
172 case pkgCache::State::HalfConfigured
:
176 // This means removal failed
177 case pkgCache::State::HalfInstalled
:
182 if (I
->InstState
!= pkgCache::State::Ok
)
183 return _error
->Error("The package %s is not ok and I "
184 "don't know how to fix it!",I
.Name());
190 // FixBroken - Fix broken packages /*{{{*/
191 // ---------------------------------------------------------------------
192 /* This autoinstalls every broken package and then runs the problem resolver
194 bool pkgFixBroken(pkgDepCache
&Cache
)
196 // Auto upgrade all broken packages
197 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
198 if (Cache
[I
].NowBroken() == true)
199 Cache
.MarkInstall(I
,true);
201 /* Fix packages that are in a NeedArchive state but don't have a
202 downloadable install version */
203 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
205 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
206 Cache
[I
].Delete() == true)
209 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
212 Cache
.MarkInstall(I
,true);
215 pkgProblemResolver
Fix(Cache
);
216 return Fix
.Resolve(true);
219 // DistUpgrade - Distribution upgrade /*{{{*/
220 // ---------------------------------------------------------------------
221 /* This autoinstalls every package and then force installs every
222 pre-existing package. This creates the initial set of conditions which
223 most likely contain problems because too many things were installed.
225 The problem resolver is used to resolve the problems.
227 bool pkgDistUpgrade(pkgDepCache
&Cache
)
229 /* Auto upgrade all installed packages, this provides the basis
230 for the installation */
231 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
232 if (I
->CurrentVer
!= 0)
233 Cache
.MarkInstall(I
,true);
235 /* Now, auto upgrade all essential packages - this ensures that
236 the essential packages are present and working */
237 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
238 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
239 Cache
.MarkInstall(I
,true);
241 /* We do it again over all previously installed packages to force
242 conflict resolution on them all. */
243 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
244 if (I
->CurrentVer
!= 0)
245 Cache
.MarkInstall(I
,false);
247 pkgProblemResolver
Fix(Cache
);
249 // Hold back held packages.
250 if (_config
->FindB("APT::Ingore-Hold",false) == false)
252 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
254 if (I
->SelectedState
== pkgCache::State::Hold
)
262 return Fix
.Resolve();
265 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
266 // ---------------------------------------------------------------------
267 /* Right now the system must be consistent before this can be called.
268 It also will not change packages marked for install, it only tries
269 to install packages not marked for install */
270 bool pkgAllUpgrade(pkgDepCache
&Cache
)
272 pkgProblemResolver
Fix(Cache
);
274 if (Cache
.BrokenCount() != 0)
277 // Upgrade all installed packages
278 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
280 if (Cache
[I
].Install() == true)
283 if (_config
->FindB("APT::Ingore-Hold",false) == false)
284 if (I
->SelectedState
== pkgCache::State::Hold
)
287 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
288 Cache
.MarkInstall(I
,false);
291 return Fix
.ResolveByKeep();
294 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
295 // ---------------------------------------------------------------------
296 /* This simply goes over the entire set of packages and tries to keep
297 each package marked for upgrade. If a conflict is generated then
298 the package is restored. */
299 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
301 if (Cache
.BrokenCount() != 0)
304 // We loop indefinately to get the minimal set size.
309 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
312 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
315 // Keep it and see if that is OK
317 if (Cache
.BrokenCount() != 0)
318 Cache
.MarkInstall(I
,false);
323 while (Change
== true);
325 if (Cache
.BrokenCount() != 0)
326 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
332 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
333 // ---------------------------------------------------------------------
335 pkgProblemResolver::pkgProblemResolver(pkgDepCache
&Cache
) : Cache(Cache
)
338 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
339 Scores
= new signed short[Size
];
340 Flags
= new unsigned char[Size
];
341 memset(Flags
,0,sizeof(*Flags
)*Size
);
343 // Set debug to true to see its decision logic
344 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
347 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
348 // ---------------------------------------------------------------------
350 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
352 Package
const **A
= (Package
const **)a
;
353 Package
const **B
= (Package
const **)b
;
354 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
356 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
361 // ProblemResolver::MakeScores - Make the score table /*{{{*/
362 // ---------------------------------------------------------------------
364 void pkgProblemResolver::MakeScores()
366 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
367 memset(Scores
,0,sizeof(*Scores
)*Size
);
369 // Generate the base scores for a package based on its properties
370 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
372 if (Cache
[I
].InstallVer
== 0)
375 signed short &Score
= Scores
[I
->ID
];
377 /* This is arbitary, it should be high enough to elevate an
378 essantial package above most other packages but low enough
379 to allow an obsolete essential packages to be removed by
380 a conflicts on a powerfull normal package (ie libc6) */
381 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
384 // We transform the priority
385 // Important Required Standard Optional Extra
386 signed short PrioMap
[] = {0,3,2,1,-1,-2};
387 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
388 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
390 /* This helps to fix oddball problems with conflicting packages
391 on the same level. We enhance the score of installed packages */
392 if (I
->CurrentVer
!= 0)
396 // Now that we have the base scores we go and propogate dependencies
397 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
399 if (Cache
[I
].InstallVer
== 0)
402 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
404 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
405 Scores
[D
.TargetPkg()->ID
]++;
409 // Copy the scores to advoid additive looping
410 signed short *OldScores
= new signed short[Size
];
411 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
413 /* Now we cause 1 level of dependency inheritance, that is we add the
414 score of the packages that depend on the target Package. This
415 fortifies high scoring packages */
416 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
418 if (Cache
[I
].InstallVer
== 0)
421 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
423 // Only do it for the install version
424 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
425 (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
))
428 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
432 /* Now we propogate along provides. This makes the packages that
433 provide important packages extremely important */
434 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
436 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
438 // Only do it once per package
439 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
441 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
445 /* Protected things are pushed really high up. This number should put them
446 ahead of everything */
447 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
448 if ((Flags
[I
->ID
] & Protected
) != 0)
449 Scores
[I
->ID
] += 10000;
454 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
455 // ---------------------------------------------------------------------
456 /* This goes through and tries to reinstall packages to make this package
458 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
460 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
463 Flags
[Pkg
->ID
] &= ~Upgradable
;
465 bool WasKept
= Cache
[Pkg
].Keep();
466 Cache
.MarkInstall(Pkg
,false);
468 // This must be a virtual package or something like that.
469 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
472 // Isolate the problem dependency
474 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
476 // Compute a single dependency element (glob or)
477 pkgCache::DepIterator Start
= D
;
478 pkgCache::DepIterator End
= D
;
479 unsigned char State
= 0;
480 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
483 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
488 // We only worry about critical deps.
489 if (End
.IsCritical() != true)
493 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
496 // Hm, the group is broken.. I have no idea how to handle this
499 clog
<< "Note, a broken or group was found in " << Pkg
.Name() << "." << endl
;
504 // Do not change protected packages
505 PkgIterator P
= Start
.SmartTargetPkg();
506 if ((Flags
[P
->ID
] & Protected
) == Protected
)
509 clog
<< " Reinet Failed because of protected " << P
.Name() << endl
;
514 // Upgrade the package if the candidate version will fix the problem.
515 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
517 if (DoUpgrade(P
) == false)
520 clog
<< " Reinst Failed because of " << P
.Name() << endl
;
527 /* We let the algorithm deal with conflicts on its next iteration,
528 it is much smarter than us */
529 if (End
->Type
== pkgCache::Dep::Conflicts
)
533 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
;
539 // Undo our operations - it might be smart to undo everything this did..
545 Cache
.MarkDelete(Pkg
);
550 clog
<< " Re-Instated " << Pkg
.Name() << endl
;
554 // ProblemResolver::Resolve - Run the resolution pass /*{{{*/
555 // ---------------------------------------------------------------------
556 /* This routines works by calculating a score for each package. The score
557 is derived by considering the package's priority and all reverse
558 dependents giving an integer that reflects the amount of breakage that
559 adjusting the package will inflict.
561 It goes from highest score to lowest and corrects all of the breaks by
562 keeping or removing the dependant packages. If that fails then it removes
563 the package itself and goes on. The routine should be able to intelligently
564 go from any broken state to a fixed state.
566 The BrokenFix flag enables a mode where the algorithm tries to
567 upgrade packages to advoid problems. */
568 bool pkgProblemResolver::Resolve(bool BrokenFix
)
570 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
572 // Record which packages are marked for install
577 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
579 if (Cache
[I
].Install() == true)
580 Flags
[I
->ID
] |= PreInstalled
;
583 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
585 Cache
.MarkInstall(I
,false);
586 if (Cache
[I
].Install() == true)
590 Flags
[I
->ID
] &= ~PreInstalled
;
592 Flags
[I
->ID
] |= Upgradable
;
595 while (Again
== true);
598 clog
<< "Starting" << endl
;
602 /* We have to order the packages so that the broken fixing pass
603 operates from highest score to lowest. This prevents problems when
604 high score packages cause the removal of lower score packages that
605 would cause the removal of even lower score packages. */
606 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
607 pkgCache::Package
**PEnd
= PList
;
608 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
611 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
613 /* for (pkgCache::Package **K = PList; K != PEnd; K++)
614 if (Scores[(*K)->ID] != 0)
616 pkgCache::PkgIterator Pkg(Cache,*K);
617 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
618 ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
619 Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
623 clog
<< "Starting 2" << endl
;
625 /* Now consider all broken packages. For each broken package we either
626 remove the package or fix it's problem. We do this once, it should
627 not be possible for a loop to form (that is a < b < c and fixing b by
628 changing a breaks c) */
630 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
633 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
635 pkgCache::PkgIterator
I(Cache
,*K
);
637 /* We attempt to install this and see if any breaks result,
638 this takes care of some strange cases */
639 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
640 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
641 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
642 (Flags
[I
->ID
] & Protected
) == 0 &&
643 (Flags
[I
->ID
] & ReInstateTried
) == 0)
646 clog
<< " Try to Re-Instate " << I
.Name() << endl
;
647 unsigned long OldBreaks
= Cache
.BrokenCount();
648 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
649 Flags
[I
->ID
] &= ReInstateTried
;
651 Cache
.MarkInstall(I
,false);
652 if (Cache
[I
].InstBroken() == true ||
653 OldBreaks
< Cache
.BrokenCount())
662 clog
<< "Re-Instated " << I
.Name() << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
665 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
668 // Isolate the problem dependency
669 PackageKill KillList
[100];
670 PackageKill
*LEnd
= KillList
;
671 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
673 // Compute a single dependency element (glob or)
674 pkgCache::DepIterator Start
;
675 pkgCache::DepIterator End
;
678 // We only worry about critical deps.
679 if (End
.IsCritical() != true)
683 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
686 // Hm, the group is broken.. I have no idea how to handle this
689 clog
<< "Note, a broken or group was found in " << I
.Name() << "." << endl
;
695 clog
<< "Package " << I
.Name() << " has broken dep on " << End
.TargetPkg().Name() << endl
;
697 /* Look across the version list. If there are no possible
698 targets then we keep the package and bail. This is necessary
699 if a package has a dep on another package that cant be found */
700 pkgCache::Version
**VList
= End
.AllTargets();
701 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
702 End
->Type
!= pkgCache::Dep::Conflicts
&&
703 Cache
[I
].NowBroken() == false)
711 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
713 pkgCache::VerIterator
Ver(Cache
,*V
);
714 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
717 clog
<< " Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<
718 " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
;
719 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
720 ((Cache
[End
] & pkgDepCache::DepGNow
) == 0 &&
721 End
->Type
!= pkgCache::Dep::Conflicts
))
723 if ((Flags
[I
->ID
] & Protected
) == Protected
)
726 // See if a keep will do
728 if (Cache
[I
].InstBroken() == false)
731 clog
<< " Holding Back " << I
.Name() << " rather than change " << End
.TargetPkg().Name() << endl
;
735 if (BrokenFix
== false || DoUpgrade(I
) == false)
738 clog
<< " Removing " << I
.Name() << " rather than change " << End
.TargetPkg().Name() << endl
;
741 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
751 // Skip this if it is protected
752 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
759 if (End
->Type
!= pkgCache::Dep::Conflicts
)
764 // Hm, nothing can possibly satisify this dep. Nuke it.
765 if (VList
[0] == 0 && End
->Type
!= pkgCache::Dep::Conflicts
&&
766 (Flags
[I
->ID
] & Protected
) != Protected
)
769 if (Cache
[I
].InstBroken() == false)
772 clog
<< " Holding Back " << I
.Name() << " because I can't find " << End
.TargetPkg().Name() << endl
;
777 clog
<< " Removing " << I
.Name() << " because I can't find " << End
.TargetPkg().Name() << endl
;
790 // Apply the kill list now
791 if (Cache
[I
].InstallVer
!= 0)
792 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
795 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
797 if (J
->Dep
->Type
== pkgCache::Dep::Conflicts
)
800 clog
<< " Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
;
801 Cache
.MarkDelete(J
->Pkg
);
807 clog
<< " Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
;
808 Cache
.MarkKeep(J
->Pkg
);
812 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
818 clog
<< "Done" << endl
;
823 if (Cache
.BrokenCount() != 0)
824 return _error
->Error("Internal error, pkgProblemResolver::Resolve generated breaks.");
829 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
830 // ---------------------------------------------------------------------
831 /* This is the work horse of the soft upgrade routine. It is very gental
832 in that it does not install or remove any packages. It is assumed that the
833 system was non-broken previously. */
834 bool pkgProblemResolver::ResolveByKeep()
836 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
839 clog
<< "Entering ResolveByKeep" << endl
;
843 /* We have to order the packages so that the broken fixing pass
844 operates from highest score to lowest. This prevents problems when
845 high score packages cause the removal of lower score packages that
846 would cause the removal of even lower score packages. */
847 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
848 pkgCache::Package
**PEnd
= PList
;
849 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
852 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
854 // Consider each broken package
855 pkgCache::Package
**LastStop
= 0;
856 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
858 pkgCache::PkgIterator
I(Cache
,*K
);
860 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
863 /* Keep the package. If this works then great, otherwise we have
864 to be significantly more agressive and manipulate its dependencies */
865 if ((Flags
[I
->ID
] & Protected
) == 0)
868 clog
<< "Keeping package " << I
.Name() << endl
;
870 if (Cache
[I
].InstBroken() == false)
877 // Isolate the problem dependencies
878 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
880 // Compute a single dependency element (glob or)
881 pkgCache::DepIterator Start
= D
;
882 pkgCache::DepIterator End
= D
;
883 unsigned char State
= 0;
884 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
887 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
892 // We only worry about critical deps.
893 if (End
.IsCritical() != true)
897 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
900 // Hm, the group is broken.. I have no idea how to handle this
903 clog
<< "Note, a broken or group was found in " << I
.Name() << "." << endl
;
904 if ((Flags
[I
->ID
] & Protected
) == 0)
910 clog
<< "Package " << I
.Name() << " has broken dep on " << End
.TargetPkg().Name() << endl
;
912 // Look at all the possible provides on this package
913 pkgCache::Version
**VList
= End
.AllTargets();
914 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
916 pkgCache::VerIterator
Ver(Cache
,*V
);
917 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
919 // It is not keepable
920 if (Cache
[Pkg
].InstallVer
== 0 ||
921 Pkg
->CurrentVer
== 0)
924 if ((Flags
[I
->ID
] & Protected
) == 0)
927 clog
<< " Keeping Package " << Pkg
.Name() << " due to dep" << endl
;
931 if (Cache
[I
].InstBroken() == false)
935 if (Cache
[I
].InstBroken() == false)
939 if (Cache
[I
].InstBroken() == true)
944 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name());
952 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
953 // ---------------------------------------------------------------------
954 /* This is used to make sure protected packages are installed */
955 void pkgProblemResolver::InstallProtect()
957 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
959 if ((Flags
[I
->ID
] & Protected
) == Protected
)
961 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
964 Cache
.MarkInstall(I
,false);