]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: algorithms.cc,v 1.44 2002/11/28 18:49:16 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>
23 #include <apt-pkg/version.h>
24 #include <apt-pkg/sptr.h>
28 #include <sys/types.h>
33 pkgProblemResolver
*pkgProblemResolver::This
= 0;
35 // Simulate::Simulate - Constructor /*{{{*/
36 // ---------------------------------------------------------------------
37 /* The legacy translations here of input Pkg iterators is obsolete,
38 this is not necessary since the pkgCaches are fully shared now. */
39 pkgSimulate::pkgSimulate(pkgDepCache
*Cache
) : pkgPackageManager(Cache
),
41 Sim(&Cache
->GetCache(),&iPolicy
)
44 Flags
= new unsigned char[Cache
->Head().PackageCount
];
45 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
47 // Fake a filename so as not to activate the media swapping
48 string Jnk
= "SIMULATE";
49 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
53 // Simulate::Describe - Describe a package /*{{{*/
54 // ---------------------------------------------------------------------
55 /* Parameter Current == true displays the current package version,
56 Parameter Candidate == true displays the candidate package version */
57 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Current
,bool Candidate
)
65 Ver
= Pkg
.CurrentVer();
66 if (Ver
.end() == false)
67 out
<< " [" << Ver
.VerStr() << ']';
70 if (Candidate
== true)
72 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
73 if (Ver
.end() == true)
76 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
80 // Simulate::Install - Simulate unpacking of a package /*{{{*/
81 // ---------------------------------------------------------------------
83 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
86 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
90 Describe(Pkg
,cout
,true,true);
91 Sim
.MarkInstall(Pkg
,false);
93 // Look for broken conflicts+predepends.
94 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
96 if (Sim
[I
].InstallVer
== 0)
99 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
104 if (Start
->Type
== pkgCache::Dep::Conflicts
||
105 Start
->Type
== pkgCache::Dep::Obsoletes
||
106 End
->Type
== pkgCache::Dep::PreDepends
)
108 if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0)
110 cout
<< " [" << I
.Name() << " on " << Start
.TargetPkg().Name() << ']';
111 if (Start
->Type
== pkgCache::Dep::Conflicts
)
112 _error
->Error("Fatal, conflicts violated %s",I
.Name());
118 if (Sim
.BrokenCount() != 0)
125 // Simulate::Configure - Simulate configuration of a Package /*{{{*/
126 // ---------------------------------------------------------------------
127 /* This is not an acurate simulation of relatity, we should really not
128 install the package.. For some investigations it may be necessary
130 bool pkgSimulate::Configure(PkgIterator iPkg
)
132 // Adapt the iterator
133 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
136 // Sim.MarkInstall(Pkg,false);
137 if (Sim
[Pkg
].InstBroken() == true)
139 cout
<< "Conf " << Pkg
.Name() << " broken" << endl
;
143 // Print out each package and the failed dependencies
144 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
146 if (Sim
.IsImportantDep(D
) == false ||
147 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
150 if (D
->Type
== pkgCache::Dep::Obsoletes
)
151 cout
<< " Obsoletes:" << D
.TargetPkg().Name();
152 else if (D
->Type
== pkgCache::Dep::Conflicts
)
153 cout
<< " Conflicts:" << D
.TargetPkg().Name();
155 cout
<< " Depends:" << D
.TargetPkg().Name();
159 _error
->Error("Conf Broken %s",Pkg
.Name());
164 Describe(Pkg
,cout
,false,true);
167 if (Sim
.BrokenCount() != 0)
175 // Simulate::Remove - Simulate the removal of a package /*{{{*/
176 // ---------------------------------------------------------------------
178 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
180 // Adapt the iterator
181 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
189 Describe(Pkg
,cout
,true,false);
191 if (Sim
.BrokenCount() != 0)
199 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
200 // ---------------------------------------------------------------------
202 void pkgSimulate::ShortBreaks()
205 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
207 if (Sim
[I
].InstBroken() == true)
209 if (Flags
[I
->ID
] == 0)
210 cout
<< I
.Name() << ' ';
212 cout << I.Name() << "! ";*/
218 // ApplyStatus - Adjust for non-ok packages /*{{{*/
219 // ---------------------------------------------------------------------
220 /* We attempt to change the state of the all packages that have failed
221 installation toward their real state. The ordering code will perform
222 the necessary calculations to deal with the problems. */
223 bool pkgApplyStatus(pkgDepCache
&Cache
)
225 pkgDepCache::ActionGroup
group(Cache
);
227 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
229 if (I
->VersionList
== 0)
232 // Only choice for a ReInstReq package is to reinstall
233 if (I
->InstState
== pkgCache::State::ReInstReq
||
234 I
->InstState
== pkgCache::State::HoldReInstReq
)
236 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
237 Cache
.MarkKeep(I
, false, false);
240 // Is this right? Will dpkg choke on an upgrade?
241 if (Cache
[I
].CandidateVer
!= 0 &&
242 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
243 Cache
.MarkInstall(I
, false, 0, false);
245 return _error
->Error(_("The package %s needs to be reinstalled, "
246 "but I can't find an archive for it."),I
.Name());
252 switch (I
->CurrentState
)
254 /* This means installation failed somehow - it does not need to be
255 re-unpacked (probably) */
256 case pkgCache::State::UnPacked
:
257 case pkgCache::State::HalfConfigured
:
258 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
259 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
260 Cache
.MarkKeep(I
, false, false);
263 if (Cache
[I
].CandidateVer
!= 0 &&
264 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
265 Cache
.MarkInstall(I
, true, 0, false);
271 // This means removal failed
272 case pkgCache::State::HalfInstalled
:
277 if (I
->InstState
!= pkgCache::State::Ok
)
278 return _error
->Error("The package %s is not ok and I "
279 "don't know how to fix it!",I
.Name());
285 // FixBroken - Fix broken packages /*{{{*/
286 // ---------------------------------------------------------------------
287 /* This autoinstalls every broken package and then runs the problem resolver
289 bool pkgFixBroken(pkgDepCache
&Cache
)
291 pkgDepCache::ActionGroup
group(Cache
);
293 // Auto upgrade all broken packages
294 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
295 if (Cache
[I
].NowBroken() == true)
296 Cache
.MarkInstall(I
, true, 0, false);
298 /* Fix packages that are in a NeedArchive state but don't have a
299 downloadable install version */
300 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
302 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
303 Cache
[I
].Delete() == true)
306 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
309 Cache
.MarkInstall(I
, true, 0, false);
312 pkgProblemResolver
Fix(&Cache
);
313 return Fix
.Resolve(true);
316 // DistUpgrade - Distribution upgrade /*{{{*/
317 // ---------------------------------------------------------------------
318 /* This autoinstalls every package and then force installs every
319 pre-existing package. This creates the initial set of conditions which
320 most likely contain problems because too many things were installed.
322 The problem resolver is used to resolve the problems.
324 bool pkgDistUpgrade(pkgDepCache
&Cache
)
326 pkgDepCache::ActionGroup
group(Cache
);
328 /* Auto upgrade all installed packages, this provides the basis
329 for the installation */
330 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
331 if (I
->CurrentVer
!= 0)
332 Cache
.MarkInstall(I
, true, 0, false);
334 /* Now, auto upgrade all essential packages - this ensures that
335 the essential packages are present and working */
336 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
337 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
338 Cache
.MarkInstall(I
, true, 0, false);
340 /* We do it again over all previously installed packages to force
341 conflict resolution on them all. */
342 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
343 if (I
->CurrentVer
!= 0)
344 Cache
.MarkInstall(I
, false, 0, false);
346 pkgProblemResolver
Fix(&Cache
);
348 // Hold back held packages.
349 if (_config
->FindB("APT::Ignore-Hold",false) == false)
351 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
353 if (I
->SelectedState
== pkgCache::State::Hold
)
356 Cache
.MarkKeep(I
, false, false);
361 return Fix
.Resolve();
364 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
365 // ---------------------------------------------------------------------
366 /* Right now the system must be consistent before this can be called.
367 It also will not change packages marked for install, it only tries
368 to install packages not marked for install */
369 bool pkgAllUpgrade(pkgDepCache
&Cache
)
371 pkgDepCache::ActionGroup
group(Cache
);
373 pkgProblemResolver
Fix(&Cache
);
375 if (Cache
.BrokenCount() != 0)
378 // Upgrade all installed packages
379 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
381 if (Cache
[I
].Install() == true)
384 if (_config
->FindB("APT::Ignore-Hold",false) == false)
385 if (I
->SelectedState
== pkgCache::State::Hold
)
388 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
389 Cache
.MarkInstall(I
, false, 0, false);
392 return Fix
.ResolveByKeep();
395 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
396 // ---------------------------------------------------------------------
397 /* This simply goes over the entire set of packages and tries to keep
398 each package marked for upgrade. If a conflict is generated then
399 the package is restored. */
400 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
402 pkgDepCache::ActionGroup
group(Cache
);
404 if (Cache
.BrokenCount() != 0)
407 // We loop for 10 tries to get the minimal set size.
409 unsigned int Count
= 0;
413 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
416 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
419 // Keep it and see if that is OK
420 Cache
.MarkKeep(I
, false, false);
421 if (Cache
.BrokenCount() != 0)
422 Cache
.MarkInstall(I
, false, 0, false);
425 // If keep didnt actually do anything then there was no change..
426 if (Cache
[I
].Upgrade() == false)
432 while (Change
== true && Count
< 10);
434 if (Cache
.BrokenCount() != 0)
435 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
441 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
442 // ---------------------------------------------------------------------
444 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : Cache(*pCache
)
447 unsigned long Size
= Cache
.Head().PackageCount
;
448 Scores
= new signed short[Size
];
449 Flags
= new unsigned char[Size
];
450 memset(Flags
,0,sizeof(*Flags
)*Size
);
452 // Set debug to true to see its decision logic
453 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
456 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
457 // ---------------------------------------------------------------------
459 pkgProblemResolver::~pkgProblemResolver()
465 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
466 // ---------------------------------------------------------------------
468 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
470 Package
const **A
= (Package
const **)a
;
471 Package
const **B
= (Package
const **)b
;
472 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
474 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
479 // ProblemResolver::MakeScores - Make the score table /*{{{*/
480 // ---------------------------------------------------------------------
482 void pkgProblemResolver::MakeScores()
484 unsigned long Size
= Cache
.Head().PackageCount
;
485 memset(Scores
,0,sizeof(*Scores
)*Size
);
487 // Generate the base scores for a package based on its properties
488 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
490 if (Cache
[I
].InstallVer
== 0)
493 signed short &Score
= Scores
[I
->ID
];
495 /* This is arbitary, it should be high enough to elevate an
496 essantial package above most other packages but low enough
497 to allow an obsolete essential packages to be removed by
498 a conflicts on a powerfull normal package (ie libc6) */
499 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
502 // We transform the priority
503 // Important Required Standard Optional Extra
504 signed short PrioMap
[] = {0,3,2,1,-1,-2};
505 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
506 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
508 /* This helps to fix oddball problems with conflicting packages
509 on the same level. We enhance the score of installed packages */
510 if (I
->CurrentVer
!= 0)
514 // Now that we have the base scores we go and propogate dependencies
515 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
517 if (Cache
[I
].InstallVer
== 0)
520 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
522 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
523 Scores
[D
.TargetPkg()->ID
]++;
527 // Copy the scores to advoid additive looping
528 SPtrArray
<signed short> OldScores
= new signed short[Size
];
529 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
531 /* Now we cause 1 level of dependency inheritance, that is we add the
532 score of the packages that depend on the target Package. This
533 fortifies high scoring packages */
534 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
536 if (Cache
[I
].InstallVer
== 0)
539 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
541 // Only do it for the install version
542 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
543 (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
))
546 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
550 /* Now we propogate along provides. This makes the packages that
551 provide important packages extremely important */
552 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
554 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
556 // Only do it once per package
557 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
559 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
563 /* Protected things are pushed really high up. This number should put them
564 ahead of everything */
565 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
567 if ((Flags
[I
->ID
] & Protected
) != 0)
568 Scores
[I
->ID
] += 10000;
569 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
570 Scores
[I
->ID
] += 5000;
574 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
575 // ---------------------------------------------------------------------
576 /* This goes through and tries to reinstall packages to make this package
578 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
580 pkgDepCache::ActionGroup
group(Cache
);
582 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
584 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
587 Flags
[Pkg
->ID
] &= ~Upgradable
;
589 bool WasKept
= Cache
[Pkg
].Keep();
590 Cache
.MarkInstall(Pkg
, false, 0, false);
592 // This must be a virtual package or something like that.
593 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
596 // Isolate the problem dependency
598 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
600 // Compute a single dependency element (glob or)
601 pkgCache::DepIterator Start
= D
;
602 pkgCache::DepIterator End
= D
;
603 unsigned char State
= 0;
604 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
607 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
613 // We only worry about critical deps.
614 if (End
.IsCritical() != true)
617 // Iterate over all the members in the or group
621 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
624 // Do not change protected packages
625 PkgIterator P
= Start
.SmartTargetPkg();
626 if ((Flags
[P
->ID
] & Protected
) == Protected
)
629 clog
<< " Reinst Failed because of protected " << P
.Name() << endl
;
634 // Upgrade the package if the candidate version will fix the problem.
635 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
637 if (DoUpgrade(P
) == false)
640 clog
<< " Reinst Failed because of " << P
.Name() << endl
;
651 /* We let the algorithm deal with conflicts on its next iteration,
652 it is much smarter than us */
653 if (Start
->Type
== pkgCache::Dep::Conflicts
||
654 Start
->Type
== pkgCache::Dep::Obsoletes
)
658 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
;
671 // Undo our operations - it might be smart to undo everything this did..
675 Cache
.MarkKeep(Pkg
, false, false);
677 Cache
.MarkDelete(Pkg
);
682 clog
<< " Re-Instated " << Pkg
.Name() << endl
;
686 // ProblemResolver::Resolve - Run the resolution pass /*{{{*/
687 // ---------------------------------------------------------------------
688 /* This routines works by calculating a score for each package. The score
689 is derived by considering the package's priority and all reverse
690 dependents giving an integer that reflects the amount of breakage that
691 adjusting the package will inflict.
693 It goes from highest score to lowest and corrects all of the breaks by
694 keeping or removing the dependant packages. If that fails then it removes
695 the package itself and goes on. The routine should be able to intelligently
696 go from any broken state to a fixed state.
698 The BrokenFix flag enables a mode where the algorithm tries to
699 upgrade packages to advoid problems. */
700 bool pkgProblemResolver::Resolve(bool BrokenFix
)
702 pkgDepCache::ActionGroup
group(Cache
);
704 unsigned long Size
= Cache
.Head().PackageCount
;
706 // Record which packages are marked for install
711 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
713 if (Cache
[I
].Install() == true)
714 Flags
[I
->ID
] |= PreInstalled
;
717 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
719 Cache
.MarkInstall(I
, false, 0, false);
720 if (Cache
[I
].Install() == true)
724 Flags
[I
->ID
] &= ~PreInstalled
;
726 Flags
[I
->ID
] |= Upgradable
;
729 while (Again
== true);
732 clog
<< "Starting" << endl
;
736 /* We have to order the packages so that the broken fixing pass
737 operates from highest score to lowest. This prevents problems when
738 high score packages cause the removal of lower score packages that
739 would cause the removal of even lower score packages. */
740 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
741 pkgCache::Package
**PEnd
= PList
;
742 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
745 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
747 /* for (pkgCache::Package **K = PList; K != PEnd; K++)
748 if (Scores[(*K)->ID] != 0)
750 pkgCache::PkgIterator Pkg(Cache,*K);
751 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
752 ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
753 Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
757 clog
<< "Starting 2" << endl
;
759 /* Now consider all broken packages. For each broken package we either
760 remove the package or fix it's problem. We do this once, it should
761 not be possible for a loop to form (that is a < b < c and fixing b by
762 changing a breaks c) */
764 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
767 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
769 pkgCache::PkgIterator
I(Cache
,*K
);
771 /* We attempt to install this and see if any breaks result,
772 this takes care of some strange cases */
773 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
774 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
775 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
776 (Flags
[I
->ID
] & Protected
) == 0 &&
777 (Flags
[I
->ID
] & ReInstateTried
) == 0)
780 clog
<< " Try to Re-Instate " << I
.Name() << endl
;
781 unsigned long OldBreaks
= Cache
.BrokenCount();
782 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
783 Flags
[I
->ID
] &= ReInstateTried
;
785 Cache
.MarkInstall(I
, false, 0, false);
786 if (Cache
[I
].InstBroken() == true ||
787 OldBreaks
< Cache
.BrokenCount())
792 Cache
.MarkKeep(I
, false, false);
796 clog
<< "Re-Instated " << I
.Name() << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
799 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
803 cout
<< "Investigating " << I
.Name() << endl
;
805 // Isolate the problem dependency
806 PackageKill KillList
[100];
807 PackageKill
*LEnd
= KillList
;
809 pkgCache::DepIterator Start
;
810 pkgCache::DepIterator End
;
811 PackageKill
*OldEnd
= LEnd
;
813 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
814 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
815 D
.end() == false || InOr
== true;)
817 // Compute a single dependency element (glob or)
823 if (OldEnd
== LEnd
&& OrOp
== OrRemove
)
825 if ((Flags
[I
->ID
] & Protected
) != Protected
)
828 clog
<< " Or group remove for " << I
.Name() << endl
;
833 if (OldEnd
== LEnd
&& OrOp
== OrKeep
)
836 clog
<< " Or group keep for " << I
.Name() << endl
;
837 Cache
.MarkKeep(I
, false, false);
842 /* We do an extra loop (as above) to finalize the or group
847 if (Start
.end() == true)
850 // We only worry about critical deps.
851 if (End
.IsCritical() != true)
861 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
868 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
870 /* Look across the version list. If there are no possible
871 targets then we keep the package and bail. This is necessary
872 if a package has a dep on another package that cant be found */
873 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
874 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
875 Start
->Type
!= pkgCache::Dep::Conflicts
&&
876 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
877 Cache
[I
].NowBroken() == false)
881 /* No keep choice because the keep being OK could be the
882 result of another element in the OR group! */
887 Cache
.MarkKeep(I
, false, false);
892 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
894 pkgCache::VerIterator
Ver(Cache
,*V
);
895 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
898 clog
<< " Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<
899 " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
;
901 /* Try to fix the package under consideration rather than
902 fiddle with the VList package */
903 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
904 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
905 End
->Type
!= pkgCache::Dep::Conflicts
&&
906 End
->Type
!= pkgCache::Dep::Obsoletes
))
908 // Try a little harder to fix protected packages..
909 if ((Flags
[I
->ID
] & Protected
) == Protected
)
911 if (DoUpgrade(Pkg
) == true)
913 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
914 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
921 /* See if a keep will do, unless the package is protected,
922 then installing it will be necessary */
923 bool Installed
= Cache
[I
].Install();
924 Cache
.MarkKeep(I
, false, false);
925 if (Cache
[I
].InstBroken() == false)
927 // Unwind operation will be keep now
928 if (OrOp
== OrRemove
)
932 if (InOr
== true && Installed
== true)
933 Cache
.MarkInstall(I
, false, 0, false);
936 clog
<< " Holding Back " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
940 if (BrokenFix
== false || DoUpgrade(I
) == false)
942 // Consider other options
946 clog
<< " Removing " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
950 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
951 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
963 /* This is a conflicts, and the version we are looking
964 at is not the currently selected version of the
965 package, which means it is not necessary to
967 if (Cache
[Pkg
].InstallVer
!= Ver
&&
968 (Start
->Type
== pkgCache::Dep::Conflicts
||
969 Start
->Type
== pkgCache::Dep::Obsoletes
))
972 // Skip adding to the kill list if it is protected
973 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
977 clog
<< " Added " << Pkg
.Name() << " to the remove list" << endl
;
983 if (Start
->Type
!= pkgCache::Dep::Conflicts
&&
984 Start
->Type
!= pkgCache::Dep::Obsoletes
)
989 // Hm, nothing can possibly satisify this dep. Nuke it.
991 Start
->Type
!= pkgCache::Dep::Conflicts
&&
992 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
993 (Flags
[I
->ID
] & Protected
) != Protected
)
995 bool Installed
= Cache
[I
].Install();
997 if (Cache
[I
].InstBroken() == false)
999 // Unwind operation will be keep now
1000 if (OrOp
== OrRemove
)
1004 if (InOr
== true && Installed
== true)
1005 Cache
.MarkInstall(I
, false, 0, false);
1008 clog
<< " Holding Back " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1013 clog
<< " Removing " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1015 Cache
.MarkDelete(I
);
1030 // Apply the kill list now
1031 if (Cache
[I
].InstallVer
!= 0)
1033 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1036 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1038 if (J
->Dep
->Type
== pkgCache::Dep::Conflicts
||
1039 J
->Dep
->Type
== pkgCache::Dep::Obsoletes
)
1042 clog
<< " Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
;
1043 Cache
.MarkDelete(J
->Pkg
);
1049 clog
<< " Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
;
1050 Cache
.MarkKeep(J
->Pkg
, false, false);
1055 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1056 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1064 clog
<< "Done" << endl
;
1066 if (Cache
.BrokenCount() != 0)
1068 // See if this is the result of a hold
1069 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1070 for (;I
.end() != true; I
++)
1072 if (Cache
[I
].InstBroken() == false)
1074 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1075 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1077 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1080 // set the auto-flags (mvo: I'm not sure if we _really_ need this, but
1082 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1083 for (;I
.end() != true; I
++) {
1084 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1085 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1086 std::clog
<< "Resolve installed new pkg: " << I
.Name()
1087 << " (now marking it as auto)" << std::endl
;
1089 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1097 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1098 // ---------------------------------------------------------------------
1099 /* This is the work horse of the soft upgrade routine. It is very gental
1100 in that it does not install or remove any packages. It is assumed that the
1101 system was non-broken previously. */
1102 bool pkgProblemResolver::ResolveByKeep()
1104 pkgDepCache::ActionGroup
group(Cache
);
1106 unsigned long Size
= Cache
.Head().PackageCount
;
1109 clog
<< "Entering ResolveByKeep" << endl
;
1113 /* We have to order the packages so that the broken fixing pass
1114 operates from highest score to lowest. This prevents problems when
1115 high score packages cause the removal of lower score packages that
1116 would cause the removal of even lower score packages. */
1117 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1118 pkgCache::Package
**PEnd
= PList
;
1119 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1122 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1124 // Consider each broken package
1125 pkgCache::Package
**LastStop
= 0;
1126 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1128 pkgCache::PkgIterator
I(Cache
,*K
);
1130 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
1133 /* Keep the package. If this works then great, otherwise we have
1134 to be significantly more agressive and manipulate its dependencies */
1135 if ((Flags
[I
->ID
] & Protected
) == 0)
1138 clog
<< "Keeping package " << I
.Name() << endl
;
1139 Cache
.MarkKeep(I
, false, false);
1140 if (Cache
[I
].InstBroken() == false)
1147 // Isolate the problem dependencies
1148 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1152 D
.GlobOr(Start
,End
);
1154 // We only worry about critical deps.
1155 if (End
.IsCritical() != true)
1159 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1162 /* Hm, the group is broken.. I suppose the best thing to do is to
1163 is to try every combination of keep/not-keep for the set, but thats
1164 slow, and this never happens, just be conservative and assume the
1165 list of ors is in preference and keep till it starts to work. */
1169 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
1171 // Look at all the possible provides on this package
1172 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1173 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1175 pkgCache::VerIterator
Ver(Cache
,*V
);
1176 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1178 // It is not keepable
1179 if (Cache
[Pkg
].InstallVer
== 0 ||
1180 Pkg
->CurrentVer
== 0)
1183 if ((Flags
[I
->ID
] & Protected
) == 0)
1186 clog
<< " Keeping Package " << Pkg
.Name() << " due to dep" << endl
;
1187 Cache
.MarkKeep(Pkg
, false, false);
1190 if (Cache
[I
].InstBroken() == false)
1194 if (Cache
[I
].InstBroken() == false)
1202 if (Cache
[I
].InstBroken() == false)
1206 if (Cache
[I
].InstBroken() == true)
1211 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name());
1219 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1220 // ---------------------------------------------------------------------
1221 /* This is used to make sure protected packages are installed */
1222 void pkgProblemResolver::InstallProtect()
1224 pkgDepCache::ActionGroup
group(Cache
);
1226 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1228 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1230 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1231 Cache
.MarkDelete(I
);
1233 Cache
.MarkInstall(I
, false, 0, false);
1239 // PrioSortList - Sort a list of versions by priority /*{{{*/
1240 // ---------------------------------------------------------------------
1241 /* This is ment to be used in conjunction with AllTargets to get a list
1242 of versions ordered by preference. */
1243 static pkgCache
*PrioCache
;
1244 static int PrioComp(const void *A
,const void *B
)
1246 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1247 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1249 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1250 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1252 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1253 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1256 if (L
->Priority
!= R
->Priority
)
1257 return R
->Priority
- L
->Priority
;
1258 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1260 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1262 unsigned long Count
= 0;
1264 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1266 qsort(List
,Count
,sizeof(*List
),PrioComp
);