summaryrefslogtreecommitdiff
path: root/src/trigproc.c
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2014-11-14 18:35:32 +0100
committerGuillem Jover <guillem@debian.org>2014-11-22 18:52:16 +0100
commit75a857d79d3d3a5cb8367bbd49d5e89bb94af0a1 (patch)
tree2a6468912441425142e5bf84af3aac5192dfd112 /src/trigproc.c
parent54526e8773218199ef588c17509ec6fc5c044da7 (diff)
downloaddpkg-75a857d79d3d3a5cb8367bbd49d5e89bb94af0a1.tar.gz
libdpkg: Register all pending triggers for deferred processing
Trigger processing on the deferred stage is just opportunistic, but we enqueue all currently pending triggers that might have been activated on a previous unpack run, only when being called as «dpkg --configure pkgname…». This is a mostly conformant workaround for frontends like apt that do not correctly call «dpkg --configure -a» or «dpkg --triggers-only -a» after their normal runs, and leave packages in triggers-pending and triggers-awaited states. Closes: #766758
Diffstat (limited to 'src/trigproc.c')
-rw-r--r--src/trigproc.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/trigproc.c b/src/trigproc.c
index 4d61d7054..ea91c7400 100644
--- a/src/trigproc.c
+++ b/src/trigproc.c
@@ -103,6 +103,44 @@ trigproc_enqueue_deferred(struct pkginfo *pend)
pkg_name(pend, pnaw_always));
}
+/**
+ * Populate the deferred trigger queue.
+ *
+ * When dpkg is called with a specific set of packages to act on, we might
+ * have packages pending trigger processing. But because there are frontends
+ * that do not perform a final «dpkg --configure --pending» call (i.e. apt),
+ * the system is left in a state with packages not fully installed.
+ *
+ * We have to populate the deferred trigger queue from the entire package
+ * database, so that we might try to do opportunistic trigger processing
+ * when going through the deferred trigger queue, because a fixed apt will
+ * not request the necessary processing anyway.
+ *
+ * XXX: This can be removed once apt is fixed in the next stable release.
+ */
+void
+trigproc_populate_deferred(void)
+{
+ struct pkgiterator *iter;
+ struct pkginfo *pkg;
+
+ iter = pkg_db_iter_new();
+ while ((pkg = pkg_db_iter_next_pkg(iter))) {
+ if (!pkg->trigpend_head)
+ continue;
+
+ if (pkg->status != PKG_STAT_TRIGGERSAWAITED &&
+ pkg->status != PKG_STAT_TRIGGERSPENDING)
+ continue;
+
+ if (pkg->want != PKG_WANT_INSTALL)
+ continue;
+
+ trigproc_enqueue_deferred(pkg);
+ }
+ pkg_db_iter_free(iter);
+}
+
void
trigproc_run_deferred(void)
{