Re: 答复: Stunned by aptitude.
On Wed, Jul 02, 2008 at 06:39:26AM -0700, Daniel Burrows <dburrows@debian.org> was heard to say:
> I put the apt-get and aptitude code up side-by-side and I can only see
> one difference in the conditions they use to determine whether to clean
> the lists. I don't see why this would matter (surely pkgAcquire::Run
> returns Failure if files can't be downloaded?), but if there's anyone
> who *can* reproduce this on demand, it would be interesting to know if
> the attached patch helps.
Once more, with feeling.
Daniel
diff -r ce31088c455a src/generic/apt/download_update_manager.cc
--- a/src/generic/apt/download_update_manager.cc Sat Jun 28 13:05:54 2008 -0700
+++ b/src/generic/apt/download_update_manager.cc Wed Jul 02 07:39:54 2008 -0700
@@ -279,9 +279,37 @@
if(res != pkgAcquire::Continue)
return failure;
+ bool transientNetworkFailure = true;
+ result rval = success;
+
+ // We need to claim that the download failed if any source failed,
+ // and invoke Finished() on any failed items. Also, we shouldn't
+ // clean the package lists if any individual item failed because it
+ // makes users grumpy (see Debian bugs #201842 and #479620).
+ //
+ // See also apt-get.cc.
+ for(pkgAcquire::ItemIterator it = fetcher->ItemsBegin();
+ it != fetcher->ItemsEnd(); ++it)
+ {
+ if((*it)->Status == pkgAcquire::Item::StatDone)
+ continue;
+
+ (*it)->Finished();
+
+ if((*it)->Status == pkgAcquire::Item::StatTransientNetworkError)
+ {
+ transientNetworkFailure = true;
+ continue;
+ }
+
+ // Q: should I display an error message for this source?
+ rval = failure;
+ }
+
// Clean old stuff out
- if(fetcher->Clean(aptcfg->FindDir("Dir::State::lists")) == false ||
- fetcher->Clean(aptcfg->FindDir("Dir::State::lists")+"partial/") == false)
+ if(rval == success && !transientNetworkFailure &&
+ (fetcher->Clean(aptcfg->FindDir("Dir::State::lists")) == false ||
+ fetcher->Clean(aptcfg->FindDir("Dir::State::lists")+"partial/") == false))
{
_error->Error(_("Couldn't clean out list directories"));
return failure;
@@ -387,27 +415,6 @@
if(need_forget_new || need_autoclean)
apt_load_cache(&progress, true);
- result rval = success;
-
- // We need to claim that the download failed if any source failed,
- // and invoke Finished() on any failed items.
- //
- // See also apt-get.cc.
- for(pkgAcquire::ItemIterator it = fetcher->ItemsBegin();
- it != fetcher->ItemsEnd(); ++it)
- {
- if((*it)->Status == pkgAcquire::Item::StatDone)
- continue;
-
- (*it)->Finished();
-
- if((*it)->Status == pkgAcquire::Item::StatTransientNetworkError)
- continue;
-
- // Q: should I display an error message for this source?
- rval = failure;
- }
-
if(apt_cache_file != NULL && need_forget_new)
{
(*apt_cache_file)->forget_new(NULL);
Reply to: