Przeglądaj źródła

Fix up packages in an inconsistent triggers-awaited state

When loading the status file fix up any inconsistent package in state
triggers-awaited w/o the corresponding package with pending triggers.

Closes: #487637, #486843, #489068
Guillem Jover 18 lat temu
rodzic
commit
587b8d8696
6 zmienionych plików z 68 dodań i 0 usunięć
  1. 11 0
      ChangeLog
  2. 5 0
      debian/changelog
  3. 1 0
      lib/dbmodify.c
  4. 3 0
      lib/dpkg-db.h
  5. 2 0
      lib/fields.c
  6. 46 0
      lib/triglib.c

+ 11 - 0
ChangeLog

@@ -1,3 +1,14 @@
+2008-08-15  Guillem Jover  <guillem@debian.org>
+
+	* lib/dpkg-db.h (trig_enqueue_awaited_pend): New function prototype.
+	(trig_fixup_awaiters): Likewise.
+	* lib/dbmodify.c (modstatdb_init): Call trig_fixup_awaiters.
+	* lib/fields.c (f_trigaw): Call trig_enqueue_awaited_pend.
+	* lib/triglib.c (struct pkg_list): New type.
+	(trig_awaited_pend_head): New variable.
+	(trig_enqueue_awaited_pend): New function definition.
+	(trig_fixup_awaiters): Likewise.
+
 2008-06-24  Raphael Hertzog  <hertzog@debian.org>
 
 	* debian/archtable: Add armel.

+ 5 - 0
debian/changelog

@@ -14,6 +14,11 @@ dpkg (1.14.21) UNRELEASED; urgency=low
     in DEB_BUILD_OPTIONS (in order to conform with the Debian policy
     ruling established in #430649).
 
+  [ Guillem Jover ]
+  * When loading the status file fix up any inconsistent package in state
+    triggers-awaited w/o the corresponding package with pending triggers.
+    Closes: #487637, #486843, #489068
+
   [ Updated scripts translations ]
   * Russian (Yuri Kozlov). Closes: #490076
   * German (Helge Kreutzmann).

+ 1 - 0
lib/dbmodify.c

@@ -196,6 +196,7 @@ enum modstatdb_rw modstatdb_init(const char *adir, enum modstatdb_rw readwritere
     uvb.buf= m_malloc(uvb.size);
   }
 
+  trig_fixup_awaiters(cstatus);
   trig_incorporate(cstatus, admindir);
 
   return cstatus;

+ 3 - 0
lib/dpkg-db.h

@@ -289,6 +289,9 @@ int trig_note_pend(struct pkginfo *pend, char *trig /*not copied!*/);
 int trig_note_aw(struct pkginfo *pend, struct pkginfo *aw);
 void trig_clear_awaiters(struct pkginfo *notpend);
 
+void trig_enqueue_awaited_pend(struct pkginfo *pend);
+void trig_fixup_awaiters(enum modstatdb_rw cstatus);
+
 void trig_file_interests_ensure(void);
 void trig_file_interests_save(void);
 

+ 2 - 0
lib/fields.c

@@ -543,6 +543,8 @@ f_trigaw(struct pkginfo *aw, struct pkginfoperfile *pifp,
     if (!trig_note_aw(pend, aw))
       parseerr(NULL, filename, lno, warnto, warncount, aw, 0,
                _("duplicate awaited trigger package `%.255s'"), word);
+
+    trig_enqueue_awaited_pend(pend);
   }
 }
 

+ 46 - 0
lib/triglib.c

@@ -169,6 +169,52 @@ trig_clear_awaiters(struct pkginfo *notpend)
 	}
 }
 
+/* FIXME: switch to use the generic pkg list for lenny+1 */
+struct pkg_list {
+	struct pkg_list *next;
+	struct pkginfo *pkg;
+};
+
+static struct pkg_list *trig_awaited_pend_head;
+
+void
+trig_enqueue_awaited_pend(struct pkginfo *pend)
+{
+	struct pkg_list *tp;
+
+	for (tp = trig_awaited_pend_head; tp; tp = tp->next)
+		if (tp->pkg == pend)
+			return;
+
+	tp = nfmalloc(sizeof(*tp));
+	tp->pkg = pend;
+	tp->next = trig_awaited_pend_head;
+	trig_awaited_pend_head = tp;
+}
+
+/*
+ * Fix up packages in state triggers-awaited w/o the corresponding package
+ * with pending triggers. This can happen when dpkg was interrupted
+ * while in modstatdb_note, and the package in triggers-pending had its
+ * state modified but dpkg could not clearing the awaiters.
+ *
+ * XXX: possibly get rid of some of the checks done somewhere else for
+ *      this condition at run-time.
+ */
+void
+trig_fixup_awaiters(enum modstatdb_rw cstatus)
+{
+	struct pkg_list *tp;
+
+	if (cstatus < msdbrw_write)
+		return;
+
+	for (tp = trig_awaited_pend_head; tp; tp = tp->next)
+		if (!tp->pkg->trigpend_head)
+			trig_clear_awaiters(tp->pkg);
+	trig_awaited_pend_head = NULL;
+}
+
 /*---------- generalised handling of trigger kinds ----------*/
 
 static const struct trigkindinfo tki_explicit, tki_file, tki_unknown;