[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: