]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
b21fcbb2f9b4e9a8d51553b5877bd3b45cc90054
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 /*{{{*/
17 #include <apt-pkg/algorithms.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/configuration.h>
20 #include <apt-pkg/version.h>
21 #include <apt-pkg/sptr.h>
25 #include <sys/types.h>
32 pkgProblemResolver
*pkgProblemResolver::This
= 0;
34 // Simulate::Simulate - Constructor /*{{{*/
35 // ---------------------------------------------------------------------
36 /* The legacy translations here of input Pkg iterators is obsolete,
37 this is not necessary since the pkgCaches are fully shared now. */
38 pkgSimulate::pkgSimulate(pkgDepCache
*Cache
) : pkgPackageManager(Cache
),
40 Sim(&Cache
->GetCache(),&iPolicy
)
43 Flags
= new unsigned char[Cache
->Head().PackageCount
];
44 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
46 // Fake a filename so as not to activate the media swapping
47 string Jnk
= "SIMULATE";
48 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
52 // Simulate::Describe - Describe a package /*{{{*/
53 // ---------------------------------------------------------------------
54 /* Parameter Current == true displays the current package version,
55 Parameter Candidate == true displays the candidate package version */
56 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Current
,bool Candidate
)
64 Ver
= Pkg
.CurrentVer();
65 if (Ver
.end() == false)
66 out
<< " [" << Ver
.VerStr() << ']';
69 if (Candidate
== true)
71 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
72 if (Ver
.end() == true)
75 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
79 // Simulate::Install - Simulate unpacking of a package /*{{{*/
80 // ---------------------------------------------------------------------
82 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
85 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
89 Describe(Pkg
,cout
,true,true);
90 Sim
.MarkInstall(Pkg
,false);
92 // Look for broken conflicts+predepends.
93 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
95 if (Sim
[I
].InstallVer
== 0)
98 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
103 if (Start
->Type
== pkgCache::Dep::Conflicts
||
104 Start
->Type
== pkgCache::Dep::DpkgBreaks
||
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();
154 else if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
155 cout
<< " Breaks:" << D
.TargetPkg().Name();
157 cout
<< " Depends:" << D
.TargetPkg().Name();
161 _error
->Error("Conf Broken %s",Pkg
.Name());
166 Describe(Pkg
,cout
,false,true);
169 if (Sim
.BrokenCount() != 0)
177 // Simulate::Remove - Simulate the removal of a package /*{{{*/
178 // ---------------------------------------------------------------------
180 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
182 // Adapt the iterator
183 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
191 Describe(Pkg
,cout
,true,false);
193 if (Sim
.BrokenCount() != 0)
201 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
202 // ---------------------------------------------------------------------
204 void pkgSimulate::ShortBreaks()
207 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
209 if (Sim
[I
].InstBroken() == true)
211 if (Flags
[I
->ID
] == 0)
212 cout
<< I
.Name() << ' ';
214 cout << I.Name() << "! ";*/
220 // ApplyStatus - Adjust for non-ok packages /*{{{*/
221 // ---------------------------------------------------------------------
222 /* We attempt to change the state of the all packages that have failed
223 installation toward their real state. The ordering code will perform
224 the necessary calculations to deal with the problems. */
225 bool pkgApplyStatus(pkgDepCache
&Cache
)
227 pkgDepCache::ActionGroup
group(Cache
);
229 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
231 if (I
->VersionList
== 0)
234 // Only choice for a ReInstReq package is to reinstall
235 if (I
->InstState
== pkgCache::State::ReInstReq
||
236 I
->InstState
== pkgCache::State::HoldReInstReq
)
238 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
239 Cache
.MarkKeep(I
, false, false);
242 // Is this right? Will dpkg choke on an upgrade?
243 if (Cache
[I
].CandidateVer
!= 0 &&
244 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
245 Cache
.MarkInstall(I
, false, 0, false);
247 return _error
->Error(_("The package %s needs to be reinstalled, "
248 "but I can't find an archive for it."),I
.Name());
254 switch (I
->CurrentState
)
256 /* This means installation failed somehow - it does not need to be
257 re-unpacked (probably) */
258 case pkgCache::State::UnPacked
:
259 case pkgCache::State::HalfConfigured
:
260 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
261 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
262 Cache
.MarkKeep(I
, false, false);
265 if (Cache
[I
].CandidateVer
!= 0 &&
266 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
267 Cache
.MarkInstall(I
, true, 0, false);
273 // This means removal failed
274 case pkgCache::State::HalfInstalled
:
279 if (I
->InstState
!= pkgCache::State::Ok
)
280 return _error
->Error("The package %s is not ok and I "
281 "don't know how to fix it!",I
.Name());
287 // FixBroken - Fix broken packages /*{{{*/
288 // ---------------------------------------------------------------------
289 /* This autoinstalls every broken package and then runs the problem resolver
291 bool pkgFixBroken(pkgDepCache
&Cache
)
293 pkgDepCache::ActionGroup
group(Cache
);
295 // Auto upgrade all broken packages
296 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
297 if (Cache
[I
].NowBroken() == true)
298 Cache
.MarkInstall(I
, true, 0, false);
300 /* Fix packages that are in a NeedArchive state but don't have a
301 downloadable install version */
302 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
304 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
305 Cache
[I
].Delete() == true)
308 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
311 Cache
.MarkInstall(I
, true, 0, false);
314 pkgProblemResolver
Fix(&Cache
);
315 return Fix
.Resolve(true);
318 // DistUpgrade - Distribution upgrade /*{{{*/
319 // ---------------------------------------------------------------------
320 /* This autoinstalls every package and then force installs every
321 pre-existing package. This creates the initial set of conditions which
322 most likely contain problems because too many things were installed.
324 The problem resolver is used to resolve the problems.
326 bool pkgDistUpgrade(pkgDepCache
&Cache
)
328 pkgDepCache::ActionGroup
group(Cache
);
330 /* Auto upgrade all installed packages, this provides the basis
331 for the installation */
332 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
333 if (I
->CurrentVer
!= 0)
334 Cache
.MarkInstall(I
, true, 0, false);
336 /* Now, auto upgrade all essential packages - this ensures that
337 the essential packages are present and working */
338 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
339 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
340 Cache
.MarkInstall(I
, true, 0, false);
342 /* We do it again over all previously installed packages to force
343 conflict resolution on them all. */
344 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
345 if (I
->CurrentVer
!= 0)
346 Cache
.MarkInstall(I
, false, 0, false);
348 pkgProblemResolver
Fix(&Cache
);
350 // Hold back held packages.
351 if (_config
->FindB("APT::Ignore-Hold",false) == false)
353 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
355 if (I
->SelectedState
== pkgCache::State::Hold
)
358 Cache
.MarkKeep(I
, false, false);
363 return Fix
.Resolve();
366 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
367 // ---------------------------------------------------------------------
368 /* Right now the system must be consistent before this can be called.
369 It also will not change packages marked for install, it only tries
370 to install packages not marked for install */
371 bool pkgAllUpgrade(pkgDepCache
&Cache
)
373 pkgDepCache::ActionGroup
group(Cache
);
375 pkgProblemResolver
Fix(&Cache
);
377 if (Cache
.BrokenCount() != 0)
380 // Upgrade all installed packages
381 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
383 if (Cache
[I
].Install() == true)
386 if (_config
->FindB("APT::Ignore-Hold",false) == false)
387 if (I
->SelectedState
== pkgCache::State::Hold
)
390 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
391 Cache
.MarkInstall(I
, false, 0, false);
394 return Fix
.ResolveByKeep();
397 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
398 // ---------------------------------------------------------------------
399 /* This simply goes over the entire set of packages and tries to keep
400 each package marked for upgrade. If a conflict is generated then
401 the package is restored. */
402 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
404 pkgDepCache::ActionGroup
group(Cache
);
406 if (Cache
.BrokenCount() != 0)
409 // We loop for 10 tries to get the minimal set size.
411 unsigned int Count
= 0;
415 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
418 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
421 // Keep it and see if that is OK
422 Cache
.MarkKeep(I
, false, false);
423 if (Cache
.BrokenCount() != 0)
424 Cache
.MarkInstall(I
, false, 0, false);
427 // If keep didnt actually do anything then there was no change..
428 if (Cache
[I
].Upgrade() == false)
434 while (Change
== true && Count
< 10);
436 if (Cache
.BrokenCount() != 0)
437 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
443 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
444 // ---------------------------------------------------------------------
446 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : Cache(*pCache
)
449 unsigned long Size
= Cache
.Head().PackageCount
;
450 Scores
= new signed short[Size
];
451 Flags
= new unsigned char[Size
];
452 memset(Flags
,0,sizeof(*Flags
)*Size
);
454 // Set debug to true to see its decision logic
455 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
458 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
459 // ---------------------------------------------------------------------
461 pkgProblemResolver::~pkgProblemResolver()
467 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
468 // ---------------------------------------------------------------------
470 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
472 Package
const **A
= (Package
const **)a
;
473 Package
const **B
= (Package
const **)b
;
474 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
476 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
481 // ProblemResolver::MakeScores - Make the score table /*{{{*/
482 // ---------------------------------------------------------------------
484 void pkgProblemResolver::MakeScores()
486 unsigned long Size
= Cache
.Head().PackageCount
;
487 memset(Scores
,0,sizeof(*Scores
)*Size
);
489 // Generate the base scores for a package based on its properties
490 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
492 if (Cache
[I
].InstallVer
== 0)
495 signed short &Score
= Scores
[I
->ID
];
497 /* This is arbitary, it should be high enough to elevate an
498 essantial package above most other packages but low enough
499 to allow an obsolete essential packages to be removed by
500 a conflicts on a powerfull normal package (ie libc6) */
501 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
504 // We transform the priority
505 // Important Required Standard Optional Extra
506 signed short PrioMap
[] = {0,3,2,1,-1,-2};
507 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
508 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
510 /* This helps to fix oddball problems with conflicting packages
511 on the same level. We enhance the score of installed packages
512 if those are not obsolete
514 if (I
->CurrentVer
!= 0 && Cache
[I
].CandidateVer
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable())
518 // Now that we have the base scores we go and propogate dependencies
519 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
521 if (Cache
[I
].InstallVer
== 0)
524 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
526 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
527 Scores
[D
.TargetPkg()->ID
]++;
531 // Copy the scores to advoid additive looping
532 SPtrArray
<signed short> OldScores
= new signed short[Size
];
533 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
535 /* Now we cause 1 level of dependency inheritance, that is we add the
536 score of the packages that depend on the target Package. This
537 fortifies high scoring packages */
538 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
540 if (Cache
[I
].InstallVer
== 0)
543 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
545 // Only do it for the install version
546 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
547 (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
))
550 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
554 /* Now we propogate along provides. This makes the packages that
555 provide important packages extremely important */
556 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
558 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
560 // Only do it once per package
561 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
563 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
567 /* Protected things are pushed really high up. This number should put them
568 ahead of everything */
569 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
571 if ((Flags
[I
->ID
] & Protected
) != 0)
572 Scores
[I
->ID
] += 10000;
573 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
574 Scores
[I
->ID
] += 5000;
578 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
579 // ---------------------------------------------------------------------
580 /* This goes through and tries to reinstall packages to make this package
582 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
584 pkgDepCache::ActionGroup
group(Cache
);
586 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
588 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
591 Flags
[Pkg
->ID
] &= ~Upgradable
;
593 bool WasKept
= Cache
[Pkg
].Keep();
594 Cache
.MarkInstall(Pkg
, false, 0, false);
596 // This must be a virtual package or something like that.
597 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
600 // Isolate the problem dependency
602 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
604 // Compute a single dependency element (glob or)
605 pkgCache::DepIterator Start
= D
;
606 pkgCache::DepIterator End
= D
;
607 unsigned char State
= 0;
608 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
611 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
617 // We only worry about critical deps.
618 if (End
.IsCritical() != true)
621 // Iterate over all the members in the or group
625 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
628 // Do not change protected packages
629 PkgIterator P
= Start
.SmartTargetPkg();
630 if ((Flags
[P
->ID
] & Protected
) == Protected
)
633 clog
<< " Reinst Failed because of protected " << P
.Name() << endl
;
638 // Upgrade the package if the candidate version will fix the problem.
639 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
641 if (DoUpgrade(P
) == false)
644 clog
<< " Reinst Failed because of " << P
.Name() << endl
;
655 /* We let the algorithm deal with conflicts on its next iteration,
656 it is much smarter than us */
657 if (Start
->Type
== pkgCache::Dep::Conflicts
||
658 Start
->Type
== pkgCache::Dep::DpkgBreaks
||
659 Start
->Type
== pkgCache::Dep::Obsoletes
)
663 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
;
676 // Undo our operations - it might be smart to undo everything this did..
680 Cache
.MarkKeep(Pkg
, false, false);
682 Cache
.MarkDelete(Pkg
);
687 clog
<< " Re-Instated " << Pkg
.Name() << endl
;
691 // ProblemResolver::Resolve - Run the resolution pass /*{{{*/
692 // ---------------------------------------------------------------------
693 /* This routines works by calculating a score for each package. The score
694 is derived by considering the package's priority and all reverse
695 dependents giving an integer that reflects the amount of breakage that
696 adjusting the package will inflict.
698 It goes from highest score to lowest and corrects all of the breaks by
699 keeping or removing the dependant packages. If that fails then it removes
700 the package itself and goes on. The routine should be able to intelligently
701 go from any broken state to a fixed state.
703 The BrokenFix flag enables a mode where the algorithm tries to
704 upgrade packages to advoid problems. */
705 bool pkgProblemResolver::Resolve(bool BrokenFix
)
707 pkgDepCache::ActionGroup
group(Cache
);
709 unsigned long Size
= Cache
.Head().PackageCount
;
711 // Record which packages are marked for install
716 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
718 if (Cache
[I
].Install() == true)
719 Flags
[I
->ID
] |= PreInstalled
;
722 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
724 Cache
.MarkInstall(I
, false, 0, false);
725 if (Cache
[I
].Install() == true)
729 Flags
[I
->ID
] &= ~PreInstalled
;
731 Flags
[I
->ID
] |= Upgradable
;
734 while (Again
== true);
737 clog
<< "Starting" << endl
;
741 /* We have to order the packages so that the broken fixing pass
742 operates from highest score to lowest. This prevents problems when
743 high score packages cause the removal of lower score packages that
744 would cause the removal of even lower score packages. */
745 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
746 pkgCache::Package
**PEnd
= PList
;
747 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
750 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
752 /* for (pkgCache::Package **K = PList; K != PEnd; K++)
753 if (Scores[(*K)->ID] != 0)
755 pkgCache::PkgIterator Pkg(Cache,*K);
756 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
757 ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
758 Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
762 clog
<< "Starting 2" << endl
;
764 /* Now consider all broken packages. For each broken package we either
765 remove the package or fix it's problem. We do this once, it should
766 not be possible for a loop to form (that is a < b < c and fixing b by
767 changing a breaks c) */
769 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
772 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
774 pkgCache::PkgIterator
I(Cache
,*K
);
776 /* We attempt to install this and see if any breaks result,
777 this takes care of some strange cases */
778 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
779 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
780 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
781 (Flags
[I
->ID
] & Protected
) == 0 &&
782 (Flags
[I
->ID
] & ReInstateTried
) == 0)
785 clog
<< " Try to Re-Instate " << I
.Name() << endl
;
786 unsigned long OldBreaks
= Cache
.BrokenCount();
787 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
788 Flags
[I
->ID
] &= ReInstateTried
;
790 Cache
.MarkInstall(I
, false, 0, false);
791 if (Cache
[I
].InstBroken() == true ||
792 OldBreaks
< Cache
.BrokenCount())
797 Cache
.MarkKeep(I
, false, false);
801 clog
<< "Re-Instated " << I
.Name() << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
804 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
808 clog
<< "Investigating " << I
.Name() << endl
;
810 // Isolate the problem dependency
811 PackageKill KillList
[100];
812 PackageKill
*LEnd
= KillList
;
814 pkgCache::DepIterator Start
;
815 pkgCache::DepIterator End
;
816 PackageKill
*OldEnd
= LEnd
;
818 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
819 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
820 D
.end() == false || InOr
== true;)
822 // Compute a single dependency element (glob or)
828 if (OldEnd
== LEnd
&& OrOp
== OrRemove
)
830 if ((Flags
[I
->ID
] & Protected
) != Protected
)
833 clog
<< " Or group remove for " << I
.Name() << endl
;
838 if (OldEnd
== LEnd
&& OrOp
== OrKeep
)
841 clog
<< " Or group keep for " << I
.Name() << endl
;
842 Cache
.MarkKeep(I
, false, false);
847 /* We do an extra loop (as above) to finalize the or group
852 if (Start
.end() == true)
855 // We only worry about critical deps.
856 if (End
.IsCritical() != true)
865 // We only worry about critical deps.
866 if (Start
.IsCritical() != true)
871 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
878 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
880 /* Look across the version list. If there are no possible
881 targets then we keep the package and bail. This is necessary
882 if a package has a dep on another package that cant be found */
883 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
884 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
885 Start
->Type
!= pkgCache::Dep::Conflicts
&&
886 Start
->Type
!= pkgCache::Dep::DpkgBreaks
&&
887 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
888 Cache
[I
].NowBroken() == false)
892 /* No keep choice because the keep being OK could be the
893 result of another element in the OR group! */
898 Cache
.MarkKeep(I
, false, false);
903 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
905 pkgCache::VerIterator
Ver(Cache
,*V
);
906 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
909 clog
<< " Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<
910 " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
;
912 /* Try to fix the package under consideration rather than
913 fiddle with the VList package */
914 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
915 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
916 End
->Type
!= pkgCache::Dep::Conflicts
&&
917 End
->Type
!= pkgCache::Dep::DpkgBreaks
&&
918 End
->Type
!= pkgCache::Dep::Obsoletes
))
920 // Try a little harder to fix protected packages..
921 if ((Flags
[I
->ID
] & Protected
) == Protected
)
923 if (DoUpgrade(Pkg
) == true)
925 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
926 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
933 /* See if a keep will do, unless the package is protected,
934 then installing it will be necessary */
935 bool Installed
= Cache
[I
].Install();
936 Cache
.MarkKeep(I
, false, false);
937 if (Cache
[I
].InstBroken() == false)
939 // Unwind operation will be keep now
940 if (OrOp
== OrRemove
)
944 if (InOr
== true && Installed
== true)
945 Cache
.MarkInstall(I
, false, 0, false);
948 clog
<< " Holding Back " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
952 if (BrokenFix
== false || DoUpgrade(I
) == false)
954 // Consider other options
958 clog
<< " Removing " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
962 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
963 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
975 /* This is a conflicts, and the version we are looking
976 at is not the currently selected version of the
977 package, which means it is not necessary to
979 if (Cache
[Pkg
].InstallVer
!= Ver
&&
980 (Start
->Type
== pkgCache::Dep::Conflicts
||
981 Start
->Type
== pkgCache::Dep::Obsoletes
))
984 if (Start
->Type
== pkgCache::Dep::DpkgBreaks
)
986 /* Would it help if we upgraded? */
987 if (Cache
[End
] & pkgDepCache::DepGCVer
) {
989 clog
<< " Upgrading " << Pkg
.Name() << " due to Breaks field in " << I
.Name() << endl
;
990 Cache
.MarkInstall(Pkg
, false, 0, false);
994 clog
<< " Will not break " << Pkg
.Name() << " as stated in Breaks field in " << I
.Name() <<endl
;
995 Cache
.MarkKeep(I
, false, false);
999 // Skip adding to the kill list if it is protected
1000 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
1004 clog
<< " Added " << Pkg
.Name() << " to the remove list" << endl
;
1010 if (Start
->Type
!= pkgCache::Dep::Conflicts
&&
1011 Start
->Type
!= pkgCache::Dep::Obsoletes
)
1016 // Hm, nothing can possibly satisify this dep. Nuke it.
1017 if (VList
[0] == 0 &&
1018 Start
->Type
!= pkgCache::Dep::Conflicts
&&
1019 Start
->Type
!= pkgCache::Dep::DpkgBreaks
&&
1020 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
1021 (Flags
[I
->ID
] & Protected
) != Protected
)
1023 bool Installed
= Cache
[I
].Install();
1025 if (Cache
[I
].InstBroken() == false)
1027 // Unwind operation will be keep now
1028 if (OrOp
== OrRemove
)
1032 if (InOr
== true && Installed
== true)
1033 Cache
.MarkInstall(I
, false, 0, false);
1036 clog
<< " Holding Back " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1041 clog
<< " Removing " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1043 Cache
.MarkDelete(I
);
1058 // Apply the kill list now
1059 if (Cache
[I
].InstallVer
!= 0)
1061 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1064 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1066 if (J
->Dep
->Type
== pkgCache::Dep::Conflicts
||
1067 J
->Dep
->Type
== pkgCache::Dep::Obsoletes
)
1070 clog
<< " Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
;
1071 Cache
.MarkDelete(J
->Pkg
);
1077 clog
<< " Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
;
1078 Cache
.MarkKeep(J
->Pkg
, false, false);
1083 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1084 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1092 clog
<< "Done" << endl
;
1094 if (Cache
.BrokenCount() != 0)
1096 // See if this is the result of a hold
1097 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1098 for (;I
.end() != true; I
++)
1100 if (Cache
[I
].InstBroken() == false)
1102 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1103 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1105 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1108 // set the auto-flags (mvo: I'm not sure if we _really_ need this, but
1110 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1111 for (;I
.end() != true; I
++) {
1112 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1113 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1114 std::clog
<< "Resolve installed new pkg: " << I
.Name()
1115 << " (now marking it as auto)" << std::endl
;
1117 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1125 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1126 // ---------------------------------------------------------------------
1127 /* This is the work horse of the soft upgrade routine. It is very gental
1128 in that it does not install or remove any packages. It is assumed that the
1129 system was non-broken previously. */
1130 bool pkgProblemResolver::ResolveByKeep()
1132 pkgDepCache::ActionGroup
group(Cache
);
1134 unsigned long Size
= Cache
.Head().PackageCount
;
1137 clog
<< "Entering ResolveByKeep" << endl
;
1141 /* We have to order the packages so that the broken fixing pass
1142 operates from highest score to lowest. This prevents problems when
1143 high score packages cause the removal of lower score packages that
1144 would cause the removal of even lower score packages. */
1145 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1146 pkgCache::Package
**PEnd
= PList
;
1147 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1150 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1152 // Consider each broken package
1153 pkgCache::Package
**LastStop
= 0;
1154 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1156 pkgCache::PkgIterator
I(Cache
,*K
);
1158 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
1161 /* Keep the package. If this works then great, otherwise we have
1162 to be significantly more agressive and manipulate its dependencies */
1163 if ((Flags
[I
->ID
] & Protected
) == 0)
1166 clog
<< "Keeping package " << I
.Name() << endl
;
1167 Cache
.MarkKeep(I
, false, false);
1168 if (Cache
[I
].InstBroken() == false)
1175 // Isolate the problem dependencies
1176 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1180 D
.GlobOr(Start
,End
);
1182 // We only worry about critical deps.
1183 if (End
.IsCritical() != true)
1187 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1190 /* Hm, the group is broken.. I suppose the best thing to do is to
1191 is to try every combination of keep/not-keep for the set, but thats
1192 slow, and this never happens, just be conservative and assume the
1193 list of ors is in preference and keep till it starts to work. */
1197 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
1199 // Look at all the possible provides on this package
1200 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1201 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1203 pkgCache::VerIterator
Ver(Cache
,*V
);
1204 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1206 // It is not keepable
1207 if (Cache
[Pkg
].InstallVer
== 0 ||
1208 Pkg
->CurrentVer
== 0)
1211 if ((Flags
[I
->ID
] & Protected
) == 0)
1214 clog
<< " Keeping Package " << Pkg
.Name() << " due to dep" << endl
;
1215 Cache
.MarkKeep(Pkg
, false, false);
1218 if (Cache
[I
].InstBroken() == false)
1222 if (Cache
[I
].InstBroken() == false)
1230 if (Cache
[I
].InstBroken() == false)
1234 if (Cache
[I
].InstBroken() == true)
1239 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name());
1247 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1248 // ---------------------------------------------------------------------
1249 /* This is used to make sure protected packages are installed */
1250 void pkgProblemResolver::InstallProtect()
1252 pkgDepCache::ActionGroup
group(Cache
);
1254 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1256 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1258 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1259 Cache
.MarkDelete(I
);
1262 // preserver the information if the package was auto
1263 // or manual installed
1264 bool autoInst
= (Cache
[I
].Flags
& pkgCache::Flag::Auto
);
1265 Cache
.MarkInstall(I
, false, 0, !autoInst
);
1272 // PrioSortList - Sort a list of versions by priority /*{{{*/
1273 // ---------------------------------------------------------------------
1274 /* This is ment to be used in conjunction with AllTargets to get a list
1275 of versions ordered by preference. */
1276 static pkgCache
*PrioCache
;
1277 static int PrioComp(const void *A
,const void *B
)
1279 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1280 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1282 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1283 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1285 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1286 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1289 if (L
->Priority
!= R
->Priority
)
1290 return R
->Priority
- L
->Priority
;
1291 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1293 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1295 unsigned long Count
= 0;
1297 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1299 qsort(List
,Count
,sizeof(*List
),PrioComp
);