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>
22 #include <apt-pkg/acquire-item.h>
25 #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
),
45 Flags
= new unsigned char[Cache
->Head().PackageCount
];
46 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
48 // Fake a filename so as not to activate the media swapping
49 string Jnk
= "SIMULATE";
50 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
54 // Simulate::Describe - Describe a package /*{{{*/
55 // ---------------------------------------------------------------------
56 /* Parameter Current == true displays the current package version,
57 Parameter Candidate == true displays the candidate package version */
58 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Current
,bool Candidate
)
66 Ver
= Pkg
.CurrentVer();
67 if (Ver
.end() == false)
68 out
<< " [" << Ver
.VerStr() << ']';
71 if (Candidate
== true)
73 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
74 if (Ver
.end() == true)
77 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
81 // Simulate::Install - Simulate unpacking of a package /*{{{*/
82 // ---------------------------------------------------------------------
84 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
87 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
91 Describe(Pkg
,cout
,true,true);
92 Sim
.MarkInstall(Pkg
,false);
94 // Look for broken conflicts+predepends.
95 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
97 if (Sim
[I
].InstallVer
== 0)
100 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
105 if (Start
->Type
== pkgCache::Dep::Conflicts
||
106 Start
->Type
== pkgCache::Dep::DpkgBreaks
||
107 Start
->Type
== pkgCache::Dep::Obsoletes
||
108 End
->Type
== pkgCache::Dep::PreDepends
)
110 if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0)
112 cout
<< " [" << I
.Name() << " on " << Start
.TargetPkg().Name() << ']';
113 if (Start
->Type
== pkgCache::Dep::Conflicts
)
114 _error
->Error("Fatal, conflicts violated %s",I
.Name());
120 if (Sim
.BrokenCount() != 0)
127 // Simulate::Configure - Simulate configuration of a Package /*{{{*/
128 // ---------------------------------------------------------------------
129 /* This is not an acurate simulation of relatity, we should really not
130 install the package.. For some investigations it may be necessary
132 bool pkgSimulate::Configure(PkgIterator iPkg
)
134 // Adapt the iterator
135 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
138 // Sim.MarkInstall(Pkg,false);
139 if (Sim
[Pkg
].InstBroken() == true)
141 cout
<< "Conf " << Pkg
.Name() << " broken" << endl
;
145 // Print out each package and the failed dependencies
146 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
148 if (Sim
.IsImportantDep(D
) == false ||
149 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
152 if (D
->Type
== pkgCache::Dep::Obsoletes
)
153 cout
<< " Obsoletes:" << D
.TargetPkg().Name();
154 else if (D
->Type
== pkgCache::Dep::Conflicts
)
155 cout
<< " Conflicts:" << D
.TargetPkg().Name();
156 else if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
157 cout
<< " Breaks:" << D
.TargetPkg().Name();
159 cout
<< " Depends:" << D
.TargetPkg().Name();
163 _error
->Error("Conf Broken %s",Pkg
.Name());
168 Describe(Pkg
,cout
,false,true);
171 if (Sim
.BrokenCount() != 0)
179 // Simulate::Remove - Simulate the removal of a package /*{{{*/
180 // ---------------------------------------------------------------------
182 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
184 // Adapt the iterator
185 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name());
193 Describe(Pkg
,cout
,true,false);
195 if (Sim
.BrokenCount() != 0)
203 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
204 // ---------------------------------------------------------------------
206 void pkgSimulate::ShortBreaks()
209 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
211 if (Sim
[I
].InstBroken() == true)
213 if (Flags
[I
->ID
] == 0)
214 cout
<< I
.Name() << ' ';
216 cout << I.Name() << "! ";*/
222 // ApplyStatus - Adjust for non-ok packages /*{{{*/
223 // ---------------------------------------------------------------------
224 /* We attempt to change the state of the all packages that have failed
225 installation toward their real state. The ordering code will perform
226 the necessary calculations to deal with the problems. */
227 bool pkgApplyStatus(pkgDepCache
&Cache
)
229 pkgDepCache::ActionGroup
group(Cache
);
231 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
233 if (I
->VersionList
== 0)
236 // Only choice for a ReInstReq package is to reinstall
237 if (I
->InstState
== pkgCache::State::ReInstReq
||
238 I
->InstState
== pkgCache::State::HoldReInstReq
)
240 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
241 Cache
.MarkKeep(I
, false, false);
244 // Is this right? Will dpkg choke on an upgrade?
245 if (Cache
[I
].CandidateVer
!= 0 &&
246 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
247 Cache
.MarkInstall(I
, false, 0, false);
249 return _error
->Error(_("The package %s needs to be reinstalled, "
250 "but I can't find an archive for it."),I
.Name());
256 switch (I
->CurrentState
)
258 /* This means installation failed somehow - it does not need to be
259 re-unpacked (probably) */
260 case pkgCache::State::UnPacked
:
261 case pkgCache::State::HalfConfigured
:
262 case pkgCache::State::TriggersAwaited
:
263 case pkgCache::State::TriggersPending
:
264 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
265 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
266 Cache
.MarkKeep(I
, false, false);
269 if (Cache
[I
].CandidateVer
!= 0 &&
270 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
271 Cache
.MarkInstall(I
, true, 0, false);
277 // This means removal failed
278 case pkgCache::State::HalfInstalled
:
283 if (I
->InstState
!= pkgCache::State::Ok
)
284 return _error
->Error("The package %s is not ok and I "
285 "don't know how to fix it!",I
.Name());
291 // FixBroken - Fix broken packages /*{{{*/
292 // ---------------------------------------------------------------------
293 /* This autoinstalls every broken package and then runs the problem resolver
295 bool pkgFixBroken(pkgDepCache
&Cache
)
297 pkgDepCache::ActionGroup
group(Cache
);
299 // Auto upgrade all broken packages
300 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
301 if (Cache
[I
].NowBroken() == true)
302 Cache
.MarkInstall(I
, true, 0, false);
304 /* Fix packages that are in a NeedArchive state but don't have a
305 downloadable install version */
306 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
308 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
309 Cache
[I
].Delete() == true)
312 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
315 Cache
.MarkInstall(I
, true, 0, false);
318 pkgProblemResolver
Fix(&Cache
);
319 return Fix
.Resolve(true);
322 // DistUpgrade - Distribution upgrade /*{{{*/
323 // ---------------------------------------------------------------------
324 /* This autoinstalls every package and then force installs every
325 pre-existing package. This creates the initial set of conditions which
326 most likely contain problems because too many things were installed.
328 The problem resolver is used to resolve the problems.
330 bool pkgDistUpgrade(pkgDepCache
&Cache
)
332 pkgDepCache::ActionGroup
group(Cache
);
334 /* Auto upgrade all installed packages, this provides the basis
335 for the installation */
336 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
337 if (I
->CurrentVer
!= 0)
338 Cache
.MarkInstall(I
, true, 0, false);
340 /* Now, auto upgrade all essential packages - this ensures that
341 the essential packages are present and working */
342 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
343 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
344 Cache
.MarkInstall(I
, true, 0, false);
346 /* We do it again over all previously installed packages to force
347 conflict resolution on them all. */
348 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
349 if (I
->CurrentVer
!= 0)
350 Cache
.MarkInstall(I
, false, 0, false);
352 pkgProblemResolver
Fix(&Cache
);
354 // Hold back held packages.
355 if (_config
->FindB("APT::Ignore-Hold",false) == false)
357 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
359 if (I
->SelectedState
== pkgCache::State::Hold
)
362 Cache
.MarkKeep(I
, false, false);
367 return Fix
.Resolve();
370 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
371 // ---------------------------------------------------------------------
372 /* Right now the system must be consistent before this can be called.
373 It also will not change packages marked for install, it only tries
374 to install packages not marked for install */
375 bool pkgAllUpgrade(pkgDepCache
&Cache
)
377 pkgDepCache::ActionGroup
group(Cache
);
379 pkgProblemResolver
Fix(&Cache
);
381 if (Cache
.BrokenCount() != 0)
384 // Upgrade all installed packages
385 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
387 if (Cache
[I
].Install() == true)
390 if (_config
->FindB("APT::Ignore-Hold",false) == false)
391 if (I
->SelectedState
== pkgCache::State::Hold
)
394 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
395 Cache
.MarkInstall(I
, false, 0, false);
398 return Fix
.ResolveByKeep();
401 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
402 // ---------------------------------------------------------------------
403 /* This simply goes over the entire set of packages and tries to keep
404 each package marked for upgrade. If a conflict is generated then
405 the package is restored. */
406 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
408 pkgDepCache::ActionGroup
group(Cache
);
410 if (Cache
.BrokenCount() != 0)
413 // We loop for 10 tries to get the minimal set size.
415 unsigned int Count
= 0;
419 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
422 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
425 // Keep it and see if that is OK
426 Cache
.MarkKeep(I
, false, false);
427 if (Cache
.BrokenCount() != 0)
428 Cache
.MarkInstall(I
, false, 0, false);
431 // If keep didnt actually do anything then there was no change..
432 if (Cache
[I
].Upgrade() == false)
438 while (Change
== true && Count
< 10);
440 if (Cache
.BrokenCount() != 0)
441 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
447 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
448 // ---------------------------------------------------------------------
450 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : Cache(*pCache
)
453 unsigned long Size
= Cache
.Head().PackageCount
;
454 Scores
= new signed short[Size
];
455 Flags
= new unsigned char[Size
];
456 memset(Flags
,0,sizeof(*Flags
)*Size
);
458 // Set debug to true to see its decision logic
459 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
462 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
463 // ---------------------------------------------------------------------
465 pkgProblemResolver::~pkgProblemResolver()
471 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
472 // ---------------------------------------------------------------------
474 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
476 Package
const **A
= (Package
const **)a
;
477 Package
const **B
= (Package
const **)b
;
478 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
480 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
485 // ProblemResolver::MakeScores - Make the score table /*{{{*/
486 // ---------------------------------------------------------------------
488 void pkgProblemResolver::MakeScores()
490 unsigned long Size
= Cache
.Head().PackageCount
;
491 memset(Scores
,0,sizeof(*Scores
)*Size
);
493 // Generate the base scores for a package based on its properties
494 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
496 if (Cache
[I
].InstallVer
== 0)
499 signed short &Score
= Scores
[I
->ID
];
501 /* This is arbitrary, it should be high enough to elevate an
502 essantial package above most other packages but low enough
503 to allow an obsolete essential packages to be removed by
504 a conflicts on a powerfull normal package (ie libc6) */
505 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
508 // We transform the priority
509 // Important Required Standard Optional Extra
510 signed short PrioMap
[] = {0,3,2,1,-1,-2};
511 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
512 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
514 /* This helps to fix oddball problems with conflicting packages
515 on the same level. We enhance the score of installed packages
516 if those are not obsolete
518 if (I
->CurrentVer
!= 0 && Cache
[I
].CandidateVer
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable())
522 // Now that we have the base scores we go and propogate dependencies
523 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
525 if (Cache
[I
].InstallVer
== 0)
528 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
530 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
531 Scores
[D
.TargetPkg()->ID
]++;
535 // Copy the scores to advoid additive looping
536 SPtrArray
<signed short> OldScores
= new signed short[Size
];
537 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
539 /* Now we cause 1 level of dependency inheritance, that is we add the
540 score of the packages that depend on the target Package. This
541 fortifies high scoring packages */
542 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
544 if (Cache
[I
].InstallVer
== 0)
547 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
549 // Only do it for the install version
550 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
551 (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
))
554 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
558 /* Now we propogate along provides. This makes the packages that
559 provide important packages extremely important */
560 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
562 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
564 // Only do it once per package
565 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
567 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
571 /* Protected things are pushed really high up. This number should put them
572 ahead of everything */
573 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
575 if ((Flags
[I
->ID
] & Protected
) != 0)
576 Scores
[I
->ID
] += 10000;
577 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
578 Scores
[I
->ID
] += 5000;
582 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
583 // ---------------------------------------------------------------------
584 /* This goes through and tries to reinstall packages to make this package
586 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
588 pkgDepCache::ActionGroup
group(Cache
);
590 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
592 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
595 Flags
[Pkg
->ID
] &= ~Upgradable
;
597 bool WasKept
= Cache
[Pkg
].Keep();
598 Cache
.MarkInstall(Pkg
, false, 0, false);
600 // This must be a virtual package or something like that.
601 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
604 // Isolate the problem dependency
606 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
608 // Compute a single dependency element (glob or)
609 pkgCache::DepIterator Start
= D
;
610 pkgCache::DepIterator End
= D
;
611 unsigned char State
= 0;
612 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
615 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
621 // We only worry about critical deps.
622 if (End
.IsCritical() != true)
625 // Iterate over all the members in the or group
629 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
632 // Do not change protected packages
633 PkgIterator P
= Start
.SmartTargetPkg();
634 if ((Flags
[P
->ID
] & Protected
) == Protected
)
637 clog
<< " Reinst Failed because of protected " << P
.Name() << endl
;
642 // Upgrade the package if the candidate version will fix the problem.
643 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
645 if (DoUpgrade(P
) == false)
648 clog
<< " Reinst Failed because of " << P
.Name() << endl
;
659 /* We let the algorithm deal with conflicts on its next iteration,
660 it is much smarter than us */
661 if (Start
->Type
== pkgCache::Dep::Conflicts
||
662 Start
->Type
== pkgCache::Dep::DpkgBreaks
||
663 Start
->Type
== pkgCache::Dep::Obsoletes
)
667 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
;
680 // Undo our operations - it might be smart to undo everything this did..
684 Cache
.MarkKeep(Pkg
, false, false);
686 Cache
.MarkDelete(Pkg
);
691 clog
<< " Re-Instated " << Pkg
.Name() << endl
;
695 // ProblemResolver::Resolve - Run the resolution pass /*{{{*/
696 // ---------------------------------------------------------------------
697 /* This routines works by calculating a score for each package. The score
698 is derived by considering the package's priority and all reverse
699 dependents giving an integer that reflects the amount of breakage that
700 adjusting the package will inflict.
702 It goes from highest score to lowest and corrects all of the breaks by
703 keeping or removing the dependant packages. If that fails then it removes
704 the package itself and goes on. The routine should be able to intelligently
705 go from any broken state to a fixed state.
707 The BrokenFix flag enables a mode where the algorithm tries to
708 upgrade packages to advoid problems. */
709 bool pkgProblemResolver::Resolve(bool BrokenFix
)
711 pkgDepCache::ActionGroup
group(Cache
);
713 unsigned long Size
= Cache
.Head().PackageCount
;
715 // Record which packages are marked for install
720 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
722 if (Cache
[I
].Install() == true)
723 Flags
[I
->ID
] |= PreInstalled
;
726 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
728 Cache
.MarkInstall(I
, false, 0, false);
729 if (Cache
[I
].Install() == true)
733 Flags
[I
->ID
] &= ~PreInstalled
;
735 Flags
[I
->ID
] |= Upgradable
;
738 while (Again
== true);
741 clog
<< "Starting" << endl
;
745 /* We have to order the packages so that the broken fixing pass
746 operates from highest score to lowest. This prevents problems when
747 high score packages cause the removal of lower score packages that
748 would cause the removal of even lower score packages. */
749 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
750 pkgCache::Package
**PEnd
= PList
;
751 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
754 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
756 /* for (pkgCache::Package **K = PList; K != PEnd; K++)
757 if (Scores[(*K)->ID] != 0)
759 pkgCache::PkgIterator Pkg(Cache,*K);
760 clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
761 ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
762 Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
766 clog
<< "Starting 2" << endl
;
768 /* Now consider all broken packages. For each broken package we either
769 remove the package or fix it's problem. We do this once, it should
770 not be possible for a loop to form (that is a < b < c and fixing b by
771 changing a breaks c) */
773 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
776 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
778 pkgCache::PkgIterator
I(Cache
,*K
);
780 /* We attempt to install this and see if any breaks result,
781 this takes care of some strange cases */
782 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
783 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
784 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
785 (Flags
[I
->ID
] & Protected
) == 0 &&
786 (Flags
[I
->ID
] & ReInstateTried
) == 0)
789 clog
<< " Try to Re-Instate " << I
.Name() << endl
;
790 unsigned long OldBreaks
= Cache
.BrokenCount();
791 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
792 Flags
[I
->ID
] &= ReInstateTried
;
794 Cache
.MarkInstall(I
, false, 0, false);
795 if (Cache
[I
].InstBroken() == true ||
796 OldBreaks
< Cache
.BrokenCount())
801 Cache
.MarkKeep(I
, false, false);
805 clog
<< "Re-Instated " << I
.Name() << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
808 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
812 clog
<< "Investigating " << I
.Name() << endl
;
814 // Isolate the problem dependency
815 PackageKill KillList
[100];
816 PackageKill
*LEnd
= KillList
;
818 pkgCache::DepIterator Start
;
819 pkgCache::DepIterator End
;
820 PackageKill
*OldEnd
= LEnd
;
822 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
823 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
824 D
.end() == false || InOr
== true;)
826 // Compute a single dependency element (glob or)
832 if (OldEnd
== LEnd
&& OrOp
== OrRemove
)
834 if ((Flags
[I
->ID
] & Protected
) != Protected
)
837 clog
<< " Or group remove for " << I
.Name() << endl
;
842 if (OldEnd
== LEnd
&& OrOp
== OrKeep
)
845 clog
<< " Or group keep for " << I
.Name() << endl
;
846 Cache
.MarkKeep(I
, false, false);
851 /* We do an extra loop (as above) to finalize the or group
856 if (Start
.end() == true)
859 // We only worry about critical deps.
860 if (End
.IsCritical() != true)
869 // We only worry about critical deps.
870 if (Start
.IsCritical() != true)
875 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
882 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
884 /* Look across the version list. If there are no possible
885 targets then we keep the package and bail. This is necessary
886 if a package has a dep on another package that cant be found */
887 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
888 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
889 Start
->Type
!= pkgCache::Dep::Conflicts
&&
890 Start
->Type
!= pkgCache::Dep::DpkgBreaks
&&
891 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
892 Cache
[I
].NowBroken() == false)
896 /* No keep choice because the keep being OK could be the
897 result of another element in the OR group! */
902 Cache
.MarkKeep(I
, false, false);
907 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
909 pkgCache::VerIterator
Ver(Cache
,*V
);
910 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
913 clog
<< " Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] <<
914 " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
;
916 /* Try to fix the package under consideration rather than
917 fiddle with the VList package */
918 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
919 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
920 End
->Type
!= pkgCache::Dep::Conflicts
&&
921 End
->Type
!= pkgCache::Dep::DpkgBreaks
&&
922 End
->Type
!= pkgCache::Dep::Obsoletes
))
924 // Try a little harder to fix protected packages..
925 if ((Flags
[I
->ID
] & Protected
) == Protected
)
927 if (DoUpgrade(Pkg
) == true)
929 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
930 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
937 /* See if a keep will do, unless the package is protected,
938 then installing it will be necessary */
939 bool Installed
= Cache
[I
].Install();
940 Cache
.MarkKeep(I
, false, false);
941 if (Cache
[I
].InstBroken() == false)
943 // Unwind operation will be keep now
944 if (OrOp
== OrRemove
)
948 if (InOr
== true && Installed
== true)
949 Cache
.MarkInstall(I
, false, 0, false);
952 clog
<< " Holding Back " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
956 if (BrokenFix
== false || DoUpgrade(I
) == false)
958 // Consider other options
962 clog
<< " Removing " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
;
966 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
967 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
979 /* This is a conflicts, and the version we are looking
980 at is not the currently selected version of the
981 package, which means it is not necessary to
983 if (Cache
[Pkg
].InstallVer
!= Ver
&&
984 (Start
->Type
== pkgCache::Dep::Conflicts
||
985 Start
->Type
== pkgCache::Dep::Obsoletes
))
988 if (Start
->Type
== pkgCache::Dep::DpkgBreaks
)
990 // first, try upgradring the package, if that
991 // does not help, the breaks goes onto the
993 // FIXME: use DoUpgrade(Pkg) instead?
994 if (Cache
[End
] & pkgDepCache::DepGCVer
)
997 clog
<< " Upgrading " << Pkg
.Name() << " due to Breaks field in " << I
.Name() << endl
;
998 Cache
.MarkInstall(Pkg
, false, 0, false);
1003 // Skip adding to the kill list if it is protected
1004 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
1008 clog
<< " Added " << Pkg
.Name() << " to the remove list" << endl
;
1014 if (Start
->Type
!= pkgCache::Dep::Conflicts
&&
1015 Start
->Type
!= pkgCache::Dep::Obsoletes
)
1020 // Hm, nothing can possibly satisify this dep. Nuke it.
1021 if (VList
[0] == 0 &&
1022 Start
->Type
!= pkgCache::Dep::Conflicts
&&
1023 Start
->Type
!= pkgCache::Dep::DpkgBreaks
&&
1024 Start
->Type
!= pkgCache::Dep::Obsoletes
&&
1025 (Flags
[I
->ID
] & Protected
) != Protected
)
1027 bool Installed
= Cache
[I
].Install();
1029 if (Cache
[I
].InstBroken() == false)
1031 // Unwind operation will be keep now
1032 if (OrOp
== OrRemove
)
1036 if (InOr
== true && Installed
== true)
1037 Cache
.MarkInstall(I
, false, 0, false);
1040 clog
<< " Holding Back " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1045 clog
<< " Removing " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
;
1047 Cache
.MarkDelete(I
);
1062 // Apply the kill list now
1063 if (Cache
[I
].InstallVer
!= 0)
1065 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1068 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1070 if (J
->Dep
->Type
== pkgCache::Dep::Conflicts
||
1071 J
->Dep
->Type
== pkgCache::Dep::DpkgBreaks
||
1072 J
->Dep
->Type
== pkgCache::Dep::Obsoletes
)
1075 clog
<< " Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
;
1076 Cache
.MarkDelete(J
->Pkg
);
1082 clog
<< " Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
;
1083 Cache
.MarkKeep(J
->Pkg
, false, false);
1088 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1089 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1097 clog
<< "Done" << endl
;
1099 if (Cache
.BrokenCount() != 0)
1101 // See if this is the result of a hold
1102 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1103 for (;I
.end() != true; I
++)
1105 if (Cache
[I
].InstBroken() == false)
1107 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1108 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1110 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1113 // set the auto-flags (mvo: I'm not sure if we _really_ need this, but
1115 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1116 for (;I
.end() != true; I
++) {
1117 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1118 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1119 std::clog
<< "Resolve installed new pkg: " << I
.Name()
1120 << " (now marking it as auto)" << std::endl
;
1122 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1130 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1131 // ---------------------------------------------------------------------
1132 /* This is the work horse of the soft upgrade routine. It is very gental
1133 in that it does not install or remove any packages. It is assumed that the
1134 system was non-broken previously. */
1135 bool pkgProblemResolver::ResolveByKeep()
1137 pkgDepCache::ActionGroup
group(Cache
);
1139 unsigned long Size
= Cache
.Head().PackageCount
;
1142 clog
<< "Entering ResolveByKeep" << endl
;
1146 /* We have to order the packages so that the broken fixing pass
1147 operates from highest score to lowest. This prevents problems when
1148 high score packages cause the removal of lower score packages that
1149 would cause the removal of even lower score packages. */
1150 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1151 pkgCache::Package
**PEnd
= PList
;
1152 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1155 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1157 // Consider each broken package
1158 pkgCache::Package
**LastStop
= 0;
1159 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1161 pkgCache::PkgIterator
I(Cache
,*K
);
1163 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
1166 /* Keep the package. If this works then great, otherwise we have
1167 to be significantly more agressive and manipulate its dependencies */
1168 if ((Flags
[I
->ID
] & Protected
) == 0)
1171 clog
<< "Keeping package " << I
.Name() << endl
;
1172 Cache
.MarkKeep(I
, false, false);
1173 if (Cache
[I
].InstBroken() == false)
1180 // Isolate the problem dependencies
1181 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1185 D
.GlobOr(Start
,End
);
1187 // We only worry about critical deps.
1188 if (End
.IsCritical() != true)
1192 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1195 /* Hm, the group is broken.. I suppose the best thing to do is to
1196 is to try every combination of keep/not-keep for the set, but thats
1197 slow, and this never happens, just be conservative and assume the
1198 list of ors is in preference and keep till it starts to work. */
1202 clog
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
;
1204 // Look at all the possible provides on this package
1205 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1206 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1208 pkgCache::VerIterator
Ver(Cache
,*V
);
1209 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1211 // It is not keepable
1212 if (Cache
[Pkg
].InstallVer
== 0 ||
1213 Pkg
->CurrentVer
== 0)
1216 if ((Flags
[I
->ID
] & Protected
) == 0)
1219 clog
<< " Keeping Package " << Pkg
.Name() << " due to dep" << endl
;
1220 Cache
.MarkKeep(Pkg
, false, false);
1223 if (Cache
[I
].InstBroken() == false)
1227 if (Cache
[I
].InstBroken() == false)
1235 if (Cache
[I
].InstBroken() == false)
1239 if (Cache
[I
].InstBroken() == true)
1244 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name());
1252 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1253 // ---------------------------------------------------------------------
1254 /* This is used to make sure protected packages are installed */
1255 void pkgProblemResolver::InstallProtect()
1257 pkgDepCache::ActionGroup
group(Cache
);
1259 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1261 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1263 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1264 Cache
.MarkDelete(I
);
1267 // preserve the information whether the package was auto
1268 // or manually installed
1269 bool autoInst
= (Cache
[I
].Flags
& pkgCache::Flag::Auto
);
1270 Cache
.MarkInstall(I
, false, 0, !autoInst
);
1277 // PrioSortList - Sort a list of versions by priority /*{{{*/
1278 // ---------------------------------------------------------------------
1279 /* This is ment to be used in conjunction with AllTargets to get a list
1280 of versions ordered by preference. */
1281 static pkgCache
*PrioCache
;
1282 static int PrioComp(const void *A
,const void *B
)
1284 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1285 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1287 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1288 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1290 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1291 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1294 if (L
->Priority
!= R
->Priority
)
1295 return R
->Priority
- L
->Priority
;
1296 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1298 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1300 unsigned long Count
= 0;
1302 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1304 qsort(List
,Count
,sizeof(*List
),PrioComp
);
1308 // CacheFile::ListUpdate - update the cache files /*{{{*/
1309 // ---------------------------------------------------------------------
1310 /* This is a simple wrapper to update the cache. it will fetch stuff
1311 * from the network (or any other sources defined in sources.list)
1313 bool ListUpdate(pkgAcquireStatus
&Stat
,
1314 pkgSourceList
&List
,
1317 pkgAcquire::RunResult res
;
1318 pkgAcquire
Fetcher(&Stat
);
1320 // Populate it with the source selection
1321 if (List
.GetIndexes(&Fetcher
) == false)
1325 RunScripts("APT::Update::Pre-Invoke");
1329 res
= Fetcher
.Run(PulseInterval
);
1331 res
= Fetcher
.Run();
1333 if (res
== pkgAcquire::Failed
)
1336 bool Failed
= false;
1337 bool TransientNetworkFailure
= false;
1338 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
1339 I
!= Fetcher
.ItemsEnd(); I
++)
1341 if ((*I
)->Status
== pkgAcquire::Item::StatDone
)
1346 ::URI
uri((*I
)->DescURI());
1348 uri
.Password
.clear();
1349 string descUri
= string(uri
);
1351 _error
->Warning(_("Failed to fetch %s %s\n"), descUri
.c_str(),
1352 (*I
)->ErrorText
.c_str());
1354 if ((*I
)->Status
== pkgAcquire::Item::StatTransientNetworkError
)
1356 TransientNetworkFailure
= true;
1363 // Clean out any old list files
1364 // Keep "APT::Get::List-Cleanup" name for compatibility, but
1365 // this is really a global option for the APT library now
1366 if (!TransientNetworkFailure
&& !Failed
&&
1367 (_config
->FindB("APT::Get::List-Cleanup",true) == true &&
1368 _config
->FindB("APT::List-Cleanup",true) == true))
1370 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
1371 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
1372 // something went wrong with the clean
1376 if (TransientNetworkFailure
== true)
1377 _error
->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1378 else if (Failed
== true)
1379 return _error
->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1382 // Run the success scripts if all was fine
1383 if(!TransientNetworkFailure
&& !Failed
)
1384 RunScripts("APT::Update::Post-Invoke-Success");
1386 // Run the other scripts
1387 RunScripts("APT::Update::Post-Invoke");