Quellcode durchsuchen

Handle correctly packages in triggers-awaited state during recovery

* src/packages.c (process_queue): packages which are in triggers-awaited
state without any corresponding triggers-pending can be configured and
can thus satisfy dependencies of other packages.

The core of the problem was that if dpkg is interrupted, you can have
the following situation:

    Package: a
    Triggers-Awaited: b

    Package: b
    Status: ... installed

This is as expected but I obviously hadn't properly tested the
recovery, which is to do a no-op trigger processing step for b.  The
machinery in packages.c would be unimpressed by b's appearance in
progress_bytrigproc.
Raphael Hertzog vor 18 Jahren
Ursprung
Commit
4c57b1459e
3 geänderte Dateien mit 25 neuen und 4 gelöschten Zeilen
  1. 7 0
      ChangeLog
  2. 3 0
      debian/changelog
  3. 15 4
      src/packages.c

+ 7 - 0
ChangeLog

@@ -1,3 +1,10 @@
+2008-07-04  Ian Jackson  <ian@davenant.greenend.org.uk>
+
+	* src/packages.c (process_queue): packages which are in
+	triggers-awaited state without any corresponding triggers-pending
+	can be configured and can thus satisfy dependencies of other
+	packages.
+
 2008-06-24  Raphael Hertzog  <hertzog@debian.org>
 
 	* debian/archtable: Add armel.

+ 3 - 0
debian/changelog

@@ -12,6 +12,9 @@ dpkg (1.14.21) UNRELEASED; urgency=low
   * Modified Dpkg::BuildOptions to recognize and use spaces as separator
     in DEB_BUILD_OPTIONS (in order to conform with the Debian policy
     ruling established in #430649).
+  * Apply patch from Ian Jackson to correctly handle packages in status
+    triggers-awaited while trying to sort out a proper order for configuring
+    packages. Closes: #143307
 
   [ Updated dpkg translations ]
   * Thai (Theppitak Karoonboonyanan). Closes: #488090

+ 15 - 4
src/packages.c

@@ -211,7 +211,12 @@ void process_queue(void) {
     action_todo = cipaction->arg;
 
     if (sincenothing++ > queue.length * 2 + 2) {
-      if (progress_bytrigproc && progress_bytrigproc->trigpend_head) {
+      if (progress_bytrigproc &&
+	  (progress_bytrigproc->trigpend_head ||
+	   (progress_bytrigproc->status >= stat_triggersawaited &&
+	    progress_bytrigproc->othertrigaw_head))) {
+	debug(dbg_depcon, "using progress_bytrigproc %s instead of %s",
+	      progress_bytrigproc->name, pkg->name);
         add_to_queue(pkg);
         pkg = progress_bytrigproc;
         action_todo = act_configure;
@@ -246,7 +251,8 @@ void process_queue(void) {
       /* Fall through. */
     case act_configure:
       /* Do whatever is most needed. */
-      if (pkg->trigpend_head)
+      if (pkg->trigpend_head ||
+	  (pkg->status >= stat_triggersawaited && pkg->othertrigaw_head))
         trigproc(pkg);
       else
         deferred_configure(pkg);
@@ -389,7 +395,7 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
        * anyway, and that trigger processing will be a noop except for
        * sorting out all of the packages which name it in T-Awaited.
        *
-       * (This situation can only arise if modstatdb_note success in
+       * (This situation can only arise if modstatdb_note succeeds in
        * clearing the triggers-pending status of the pending package
        * but then fails to go on to update the awaiters.)
        */
@@ -609,8 +615,13 @@ int dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
   }
   if (ok == 0 && (pkg->clientdata && pkg->clientdata->istobe == itb_remove))
     ok= 1;
-  if (!anycannotfixbytrig && canfixbytrig)
+
+  if (!anycannotfixbytrig && canfixbytrig) {
+    debug(dbg_depcon, "progress_bytrigproc %s (was %s)",
+	  canfixbytrig->name,
+	  progress_bytrigproc ? progress_bytrigproc->name : "<none>");
     progress_bytrigproc = canfixbytrig;
+  }
   
   varbuffree(&oemsgs);
   debug(dbg_depcon,"ok %d msgs >>%.*s<<", ok, (int)aemsgs->used, aemsgs->buf);