]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: algorithms.cc,v 1.42 2002/11/09 23:10:32 doogie 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>
23 #include <apt-pkg/sptr.h>
30 pkgProblemResolver
*pkgProblemResolver::This
= 0;
32 // Simulate::Simulate - Constructor /*{{{*/
33 // ---------------------------------------------------------------------
34 /* The legacy translations here of input Pkg iterators is obsolete,
35 this is not necessary since the pkgCaches are fully shared now. */
36 pkgSimulate::pkgSimulate(pkgDepCache
*Cache
) : pkgPackageManager(Cache
),
38 Sim(&Cache
->GetCache(),&iPolicy
)
41 Flags
= new unsigned char[Cache
->Head().PackageCount
];
42 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
44 // Fake a filename so as not to activate the media swapping
45 string Jnk
= "SIMULATE";
46 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
50 // Simulate::Describe - Describe a package /*{{{*/
51 // ---------------------------------------------------------------------
52 /* Parameter Now == true gives both current and available varsion,
53 Parameter Now == false gives only the available package version */
54 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Now
)
62 Ver
= Pkg
.CurrentVer();
63 if (Ver
.end() == false)
64 out
<< " [" << Ver
.VerStr() << ']';
67 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
68 if (Ver
.end() == true)
71 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
74 // Simulate::Install - Simulate unpacking of a package /*{{{*/
75 // ---------------------------------------------------------------------
77 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
80 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
84 Describe(Pkg
,cout
,true);
85 Sim
.MarkInstall(Pkg
,false);
87 // Look for broken conflicts+predepends.
88 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
90 if (Sim
[I
].InstallVer
== 0)
93 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
98 if (Start
->Type
== pkgCache::Dep::Conflicts
||
99 Start
->Type
== pkgCache::Dep::Obsoletes
||
100 End
->Type
== pkgCache::Dep::PreDepends
)
102 if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0)
104 cout
<< " [" << I
.Name() << " on " << Start
.TargetPkg().Name() << ']';
105 if (Start
->Type
== pkgCache::Dep::Conflicts
)
106 _error
->Error("Fatal, conflicts violated %s",I
.Name());
112 if (Sim
.BrokenCount() != 0)
119 // Simulate::Configure - Simulate configuration of a Package /*{{{*/
120 // ---------------------------------------------------------------------
121 /* This is not an acurate simulation of relatity, we should really not
122 install the package.. For some investigations it may be necessary
124 bool pkgSimulate::Configure(PkgIterator iPkg
)
126 // Adapt the iterator
127 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
130 // Sim.MarkInstall(Pkg,false);
131 if (Sim
[Pkg
].InstBroken() == true)
133 cout
<< "Conf " << Pkg
.Name() << " broken" << endl
;
137 // Print out each package and the failed dependencies
138 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
140 if (Sim
.IsImportantDep(D
) == false ||
141 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
144 if (D
->Type
== pkgCache::Dep::Obsoletes
)
145 cout
<< " Obsoletes:" << D
.TargetPkg().Name();
146 else if (D
->Type
== pkgCache::Dep::Conflicts
)
147 cout
<< " Conflicts:" << D
.TargetPkg().Name();
149 cout
<< " Depends:" << D
.TargetPkg().Name();
153 _error
->Error("Conf Broken %s",Pkg
.Name());
158 Describe(Pkg
,cout
,false);
161 if (Sim
.BrokenCount() != 0)
169 // Simulate::Remove - Simulate the removal of a package /*{{{*/
170 // ---------------------------------------------------------------------
172 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
174 // Adapt the iterator
175 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
183 Describe(Pkg
,cout
,false);
185 if (Sim
.BrokenCount() != 0)
193 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
194 // ---------------------------------------------------------------------
196 void pkgSimulate::ShortBreaks()
199 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
201 if (Sim
[I
].InstBroken() == true)
203 if (Flags
[I
->ID
] == 0)
204 cout
<< I
.Name() << ' ';
206 cout << I.Name() << "! ";*/
212 // ApplyStatus - Adjust for non-ok packages /*{{{*/
213 // ---------------------------------------------------------------------
214 /* We attempt to change the state of the all packages that have failed
215 installation toward their real state. The ordering code will perform
216 the necessary calculations to deal with the problems. */
217 bool pkgApplyStatus(pkgDepCache
&Cache
)
219 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
221 if (I
->VersionList
== 0)
224 // Only choice for a ReInstReq package is to reinstall
225 if (I
->InstState
== pkgCache::State::ReInstReq
||
226 I
->InstState
== pkgCache::State::HoldReInstReq
)
228 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
232 // Is this right? Will dpkg choke on an upgrade?
233 if (Cache
[I
].CandidateVer
!= 0 &&
234 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
235 Cache
.MarkInstall(I
);
237 return _error
->Error(_("The package %s needs to be reinstalled, "
238 "but I can't find an archive for it."),I
.Name());
244 switch (I
->CurrentState
)
246 /* This means installation failed somehow - it does not need to be
247 re-unpacked (probably) */
248 case pkgCache::State::UnPacked
:
249 case pkgCache::State::HalfConfigured
:
250 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
251 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
255 if (Cache
[I
].CandidateVer
!= 0 &&
256 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
257 Cache
.MarkInstall(I
);
263 // This means removal failed
264 case pkgCache::State::HalfInstalled
:
269 if (I
->InstState
!= pkgCache::State::Ok
)
270 return _error
->Error("The package %s is not ok and I "
271 "don't know how to fix it!",I
.Name());
277 // FixBroken - Fix broken packages /*{{{*/
278 // ---------------------------------------------------------------------
279 /* This autoinstalls every broken package and then runs the problem resolver
281 bool pkgFixBroken(pkgDepCache
&Cache
)
283 // Auto upgrade all broken packages
284 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
285 if (Cache
[I
].NowBroken() == true)
286 Cache
.MarkInstall(I
,true);
288 /* Fix packages that are in a NeedArchive state but don't have a
289 downloadable install version */
290 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
292 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
293 Cache
[I
].Delete() == true)
296 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
299 Cache
.MarkInstall(I
,true);
302 pkgProblemResolver
Fix(&Cache
);
303 return Fix
.Resolve(true);
306 // DistUpgrade - Distribution upgrade /*{{{*/
307 // ---------------------------------------------------------------------
308 /* This autoinstalls every package and then force installs every
309 pre-existing package. This creates the initial set of conditions which
310 most likely contain problems because too many things were installed.
312 The problem resolver is used to resolve the problems.
314 bool pkgDistUpgrade(pkgDepCache
&Cache
)
316 /* Auto upgrade all installed packages, this provides the basis
317 for the installation */
318 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
319 if (I
->CurrentVer
!= 0)
320 Cache
.MarkInstall(I
,true);
322 /* Now, auto upgrade all essential packages - this ensures that
323 the essential packages are present and working */
324 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
325 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
326 Cache
.MarkInstall(I
,true);
328 /* We do it again over all previously installed packages to force
329 conflict resolution on them all. */
330 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
331 if (I
->CurrentVer
!= 0)
332 Cache
.MarkInstall(I
,false);
334 pkgProblemResolver
Fix(&Cache
);
336 // Hold back held packages.
337 if (_config
->FindB("APT::Ignore-Hold",false) == false)
339 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
341 if (I
->SelectedState
== pkgCache::State::Hold
)
349 return Fix
.Resolve();
352 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
353 // ---------------------------------------------------------------------
354 /* Right now the system must be consistent before this can be called.
355 It also will not change packages marked for install, it only tries
356 to install packages not marked for install */
357 bool pkgAllUpgrade(pkgDepCache
&Cache
)
359 pkgProblemResolver
Fix(&Cache
);
361 if (Cache
.BrokenCount() != 0)
364 // Upgrade all installed packages
365 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
367 if (Cache
[I
].Install() == true)
370 if (_config
->FindB("APT::Ignore-Hold",false) == false)
371 if (I
->SelectedState
== pkgCache::State::Hold
)
374 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
375 Cache
.MarkInstall(I
,false);
378 return Fix
.ResolveByKeep();
381 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
382 // ---------------------------------------------------------------------
383 /* This simply goes over the entire set of packages and tries to keep
384 each package marked for upgrade. If a conflict is generated then
385 the package is restored. */
386 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
388 if (Cache
.BrokenCount() != 0)
391 // We loop for 10 tries to get the minimal set size.
393 unsigned int Count
= 0;
397 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
400 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
403 // Keep it and see if that is OK
405 if (Cache
.BrokenCount() != 0)
406 Cache
.MarkInstall(I
,false);
409 // If keep didnt actually do anything then there was no change..
410 if (Cache
[I
].Upgrade() == false)
416 while (Change
== true && Count
< 10);
418 if (Cache
.BrokenCount() != 0)
419 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
425 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
426 // ---------------------------------------------------------------------
428 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : Cache(*pCache
)
431 unsigned long Size
= Cache
.Head().PackageCount
;
432 Scores
= new signed short[Size
];
433 Flags
= new unsigned char[Size
];
434 memset(Flags
,0,sizeof(*Flags
)*Size
);
436 // Set debug to true to see its decision logic
437 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
440 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
441 // ---------------------------------------------------------------------
443 pkgProblemResolver::~pkgProblemResolver()
449 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
450 // ---------------------------------------------------------------------
452 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
454 Package
const **A
= (Package
const **)a
;
455 Package
const **B
= (Package
const **)b
;
456 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
458 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
463 // ProblemResolver::MakeScores - Make the score table /*{{{*/
464 // ---------------------------------------------------------------------
466 void pkgProblemResolver::MakeScores()
468 unsigned long Size
= Cache
.Head().PackageCount
;
469 memset(Scores
,0,sizeof(*Scores
)*Size
);
471 // Generate the base scores for a package based on its properties
472 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
474 if (Cache
[I
].InstallVer
== 0)
477 signed short &Score
= Scores
[I
->ID
];
479 /* This is arbitary, it should be high enough to elevate an
480 essantial package above most other packages but low enough
481 to allow an obsolete essential packages to be removed by
482 a conflicts on a powerfull normal package (ie libc6) */
483 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
486 // We transform the priority
487 // Important Required Standard Optional Extra
488 signed short PrioMap
[] = {0,3,2,1,-1,-2};
489 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
490 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
492 /* This helps to fix oddball problems with conflicting packages
493 on the same level. We enhance the score of installed packages */
494 if (I
->CurrentVer
!= 0)
498 // Now that we have the base scores we go and propogate dependencies
499 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
501 if (Cache
[I
].InstallVer
== 0)
504 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
506 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
507 Scores
[D
.TargetPkg()->ID
]++;
511 // Copy the scores to advoid additive looping
512 SPtrArray
<signed short> OldScores
= new signed short[Size
];
513 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
515 /* Now we cause 1 level of dependency inheritance, that is we add the
516 score of the packages that depend on the target Package. This
517 fortifies high scoring packages */
518 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
520 if (Cache
[I
].InstallVer
== 0)
523 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
525 // Only do it for the install version
526 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
527 (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
))
530 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
534 /* Now we propogate along provides. This makes the packages that
535 provide important packages extremely important */
536 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
538 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
540 // Only do it once per package
541 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
543 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
547 /* Protected things are pushed really high up. This number should put them
548 ahead of everything */
549 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
551 if ((Flags
[I
->ID
] & Protected
) != 0)
552 Scores
[I
->ID
] += 10000;
553 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
554 Scores
[I
->ID
] += 5000;
558 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
559 // ---------------------------------------------------------------------
560 /* This goes through and tries to reinstall packages to make this package
562 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
564 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
566 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
569 Flags
[Pkg
->ID
] &= ~Upgradable
;
571 bool WasKept
= Cache
[Pkg
].Keep();
572 Cache
.MarkInstall(Pkg
,false);
574 // This must be a virtual package or something like that.
575 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
578 // Isolate the problem dependency
580 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
582 // Compute a single dependency element (glob or)
583 pkgCache::DepIterator Start
= D
;
584 pkgCache::DepIterator End
= D
;
585 unsigned char State
= 0;
586 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
589 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
595 // We only worry about critical deps.
596 if (End
.IsCritical() != true)
599 // Iterate over all the members in the or group
603 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
606 // Do not change protected packages
607 PkgIterator P
= Start
.SmartTargetPkg();
608 if ((Flags
[P
->ID
] & Protected
) == Protected
)
611 clog
<< " Reinst Failed because of protected " << P
.Name() << endl
;
616 // Upgrade the package if the candidate version will fix the problem.
617 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
619 if (DoUpgrade(P
) == false)
622 clog
<< " Reinst Failed because of " << P
.Name() << endl
;
633 /* We let the algorithm deal with conflicts on its next iteration,
634 it is much smarter than us */
635 if (Start
->Type
== pkgCache::Dep::Conflicts
||
636 Start
->Type
== pkgCache::Dep::Obsoletes
)
640 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
;
653 // Undo our operations - it might be smart to undo everything this did..
659 Cache
.MarkDelete(Pkg
);
664 clog
<< " Re-Instated " << Pkg
.Name() << endl
;
668 // ProblemResolver::Resolve - Run the resolution pass /*{{{*/
669 // ---------------------------------------------------------------------
670 /* This routines works by calculating a score for each package. The score
671 is derived by considering the package's priority and all reverse
672 dependents giving an integer that reflects the amount of breakage that
673 adjusting the package will inflict.
675 It goes from highest score to lowest and corrects all of the breaks by
676 keeping or removing the dependant packages. If that fails then it removes
677 the package itself and goes on. The routine should be able to intelligently
678 go from any broken state to a fixed state.
680 The BrokenFix flag enables a mode where the algorithm tries to
681 upgrade packages to advoid problems. */
682 bool pkgProblemResolver::Resolve(bool BrokenFix
)
684 unsigned long Size
= Cache
.Head().PackageCount
;
686 // Record which packages are marked for install
691 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
693 if (Cache
[I
].Install() == true)
694 Flags
[I
->ID
] |= PreInstalled
;
697 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
699 Cache
.MarkInstall(I
,false);
700 if (Cache
[I
].Install() == true)
704 Flags
[I
->ID
] &= ~PreInstalled
;
706 Flags
[I
->ID
] |= Upgradable
;
709 while (Again
== true);
712 clog
<< "Starting" << endl
;
716 /* We have to order the packages so that the broken fixing pass
717 operates from highest score to lowest. This prevents problems when
718 high score packages cause the removal of lower score packages that
719 would cause the removal of even lower score packages. */
720 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
721 pkgCache::Package
**PEnd
= PList
;
722 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
725 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
727 /* for (pkgCache::Package **K = PList; K != PEnd; K++)
728 if (Scores[(*K)->ID] != 0)
730 pkgCache::PkgIterator Pkg(Cache,*K);
731 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
732 ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
733 Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
737 clog
<< "Starting 2" << endl
;
739 /* Now consider all broken packages. For each broken package we either
740 remove the package or fix it's problem. We do this once, it should
741 not be possible for a loop to form (that is a < b < c and fixing b by
742 changing a breaks c) */
744 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
747 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
749 pkgCache::PkgIterator
I(Cache
,*K
);
751 /* We attempt to install this and see if any breaks result,
752 this takes care of some strange cases */
753 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
754 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
755 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
756 (Flags
[I
->ID
] & Protected
) == 0 &&
757 (Flags
[I
->ID
] & ReInstateTried
) == 0)
760 clog
<< " Try to Re-Instate " << I
.Name() << endl
;
761 unsigned long OldBreaks
= Cache
.BrokenCount();
762 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
763 Flags
[I
->ID
] &= ReInstateTried
;
765 Cache
.MarkInstall(I
,false);
766 if (Cache
[I
].InstBroken() == true ||
767 OldBreaks
< Cache
.BrokenCount())
776 clog
<< "Re-Instated " << I
.Name() << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
779 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
783 cout
<< "Investigating " << I
.Name() << endl
;
785 // Isolate the problem dependency
786 PackageKill KillList
[100];
787 PackageKill
*LEnd
= KillList
;
789 pkgCache::DepIterator Start
;
790 pkgCache::DepIterator End
;
791 PackageKill
*OldEnd
= LEnd
;
793 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
794 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
795 D
.end() == false || InOr
== true;)
797 // Compute a single dependency element (glob or)
803 if (OldEnd
== LEnd
&& OrOp
== OrRemove
)
805 if ((Flags
[I
->ID
] & Protected
) != Protected
)
808 clog
<< " Or group remove for " << I
.Name() << endl
;
813 if (OldEnd
== LEnd
&& OrOp
== OrKeep
)
816 clog
<< " Or group keep for " << I
.Name() << endl
;
822 /* We do an extra loop (as above) to finalize the or group
827 if (Start
.end() == true)
830 // We only worry about critical deps.
831 if (End
.IsCritical() != true)
841 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
848 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
850 /* Look across the version list. If there are no possible
851 targets then we keep the package and bail. This is necessary
852 if a package has a dep on another package that cant be found */
853 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
854 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
855 Start
->Type
!= pkgCache::Dep::Conflicts
&&
856 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
857 Cache
[I
].NowBroken() == false)
861 /* No keep choice because the keep being OK could be the
862 result of another element in the OR group! */
872 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
874 pkgCache::VerIterator
Ver(Cache
,*V
);
875 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
878 clog
<< " Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<
879 " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
;
881 /* Try to fix the package under consideration rather than
882 fiddle with the VList package */
883 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
884 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
885 End
->Type
!= pkgCache::Dep::Conflicts
&&
886 End
->Type
!= pkgCache::Dep::Obsoletes
))
888 // Try a little harder to fix protected packages..
889 if ((Flags
[I
->ID
] & Protected
) == Protected
)
891 if (DoUpgrade(Pkg
) == true)
893 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
894 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
901 /* See if a keep will do, unless the package is protected,
902 then installing it will be necessary */
903 bool Installed
= Cache
[I
].Install();
905 if (Cache
[I
].InstBroken() == false)
907 // Unwind operation will be keep now
908 if (OrOp
== OrRemove
)
912 if (InOr
== true && Installed
== true)
913 Cache
.MarkInstall(I
,false);
916 clog
<< " Holding Back " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
920 if (BrokenFix
== false || DoUpgrade(I
) == false)
922 // Consider other options
926 clog
<< " Removing " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
930 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
931 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
943 /* This is a conflicts, and the version we are looking
944 at is not the currently selected version of the
945 package, which means it is not necessary to
947 if (Cache
[Pkg
].InstallVer
!= Ver
&&
948 (Start
->Type
== pkgCache::Dep::Conflicts
||
949 Start
->Type
== pkgCache::Dep::Obsoletes
))
952 // Skip adding to the kill list if it is protected
953 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
957 clog
<< " Added " << Pkg
.Name() << " to the remove list" << endl
;
963 if (Start
->Type
!= pkgCache::Dep::Conflicts
&&
964 Start
->Type
!= pkgCache::Dep::Obsoletes
)
969 // Hm, nothing can possibly satisify this dep. Nuke it.
971 Start
->Type
!= pkgCache::Dep::Conflicts
&&
972 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
973 (Flags
[I
->ID
] & Protected
) != Protected
)
975 bool Installed
= Cache
[I
].Install();
977 if (Cache
[I
].InstBroken() == false)
979 // Unwind operation will be keep now
980 if (OrOp
== OrRemove
)
984 if (InOr
== true && Installed
== true)
985 Cache
.MarkInstall(I
,false);
988 clog
<< " Holding Back " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
993 clog
<< " Removing " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1010 // Apply the kill list now
1011 if (Cache
[I
].InstallVer
!= 0)
1013 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1016 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1018 if (J
->Dep
->Type
== pkgCache::Dep::Conflicts
||
1019 J
->Dep
->Type
== pkgCache::Dep::Obsoletes
)
1022 clog
<< " Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
;
1023 Cache
.MarkDelete(J
->Pkg
);
1029 clog
<< " Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
;
1030 Cache
.MarkKeep(J
->Pkg
);
1035 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1036 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1044 clog
<< "Done" << endl
;
1046 if (Cache
.BrokenCount() != 0)
1048 // See if this is the result of a hold
1049 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1050 for (;I
.end() != true; I
++)
1052 if (Cache
[I
].InstBroken() == false)
1054 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1055 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1057 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1063 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1064 // ---------------------------------------------------------------------
1065 /* This is the work horse of the soft upgrade routine. It is very gental
1066 in that it does not install or remove any packages. It is assumed that the
1067 system was non-broken previously. */
1068 bool pkgProblemResolver::ResolveByKeep()
1070 unsigned long Size
= Cache
.Head().PackageCount
;
1073 clog
<< "Entering ResolveByKeep" << endl
;
1077 /* We have to order the packages so that the broken fixing pass
1078 operates from highest score to lowest. This prevents problems when
1079 high score packages cause the removal of lower score packages that
1080 would cause the removal of even lower score packages. */
1081 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1082 pkgCache::Package
**PEnd
= PList
;
1083 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1086 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1088 // Consider each broken package
1089 pkgCache::Package
**LastStop
= 0;
1090 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1092 pkgCache::PkgIterator
I(Cache
,*K
);
1094 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
1097 /* Keep the package. If this works then great, otherwise we have
1098 to be significantly more agressive and manipulate its dependencies */
1099 if ((Flags
[I
->ID
] & Protected
) == 0)
1102 clog
<< "Keeping package " << I
.Name() << endl
;
1104 if (Cache
[I
].InstBroken() == false)
1111 // Isolate the problem dependencies
1112 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1116 D
.GlobOr(Start
,End
);
1118 // We only worry about critical deps.
1119 if (End
.IsCritical() != true)
1123 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1126 /* Hm, the group is broken.. I suppose the best thing to do is to
1127 is to try every combination of keep/not-keep for the set, but thats
1128 slow, and this never happens, just be conservative and assume the
1129 list of ors is in preference and keep till it starts to work. */
1133 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
1135 // Look at all the possible provides on this package
1136 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1137 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1139 pkgCache::VerIterator
Ver(Cache
,*V
);
1140 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1142 // It is not keepable
1143 if (Cache
[Pkg
].InstallVer
== 0 ||
1144 Pkg
->CurrentVer
== 0)
1147 if ((Flags
[I
->ID
] & Protected
) == 0)
1150 clog
<< " Keeping Package " << Pkg
.Name() << " due to dep" << endl
;
1151 Cache
.MarkKeep(Pkg
);
1154 if (Cache
[I
].InstBroken() == false)
1158 if (Cache
[I
].InstBroken() == false)
1166 if (Cache
[I
].InstBroken() == false)
1170 if (Cache
[I
].InstBroken() == true)
1175 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name());
1183 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1184 // ---------------------------------------------------------------------
1185 /* This is used to make sure protected packages are installed */
1186 void pkgProblemResolver::InstallProtect()
1188 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1190 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1192 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1193 Cache
.MarkDelete(I
);
1195 Cache
.MarkInstall(I
,false);
1201 // PrioSortList - Sort a list of versions by priority /*{{{*/
1202 // ---------------------------------------------------------------------
1203 /* This is ment to be used in conjunction with AllTargets to get a list
1204 of versions ordered by preference. */
1205 static pkgCache
*PrioCache
;
1206 static int PrioComp(const void *A
,const void *B
)
1208 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1209 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1211 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1212 (L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1214 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1215 (L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1218 if (L
->Priority
!= R
->Priority
)
1219 return L
->Priority
- R
->Priority
;
1220 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1222 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1224 unsigned long Count
= 0;
1226 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1228 qsort(List
,Count
,sizeof(*List
),PrioComp
);