2 * dpkg - main program for package management
3 * trigproc.c - trigger processing
5 * Copyright © 2007 Canonical Ltd
6 * written by Ian Jackson <ijackson@chiark.greenend.org.uk>
7 * Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
9 * This is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
31 #include <dpkg/i18n.h>
32 #include <dpkg/dpkg.h>
33 #include <dpkg/dpkg-db.h>
35 #include <dpkg/pkg-queue.h>
36 #include <dpkg/db-ctrl.h>
37 #include <dpkg/db-fsys.h>
38 #include <dpkg/triglib.h>
43 * Trigger processing algorithms:
46 * There is a separate queue (‘deferred trigproc list’) for triggers
47 * ‘relevant’ to what we just did; when we find something triggered ‘now’
48 * we add it to that queue (unless --no-triggers).
51 * We want to prefer configuring packages where possible to doing trigger
52 * processing, although it would be better to prefer trigger processing
53 * to cycle-breaking we need to do the latter first or we might generate
54 * artificial trigger cycles, but we always want to prefer trigger
55 * processing to dependency forcing. This is achieved as follows:
57 * Each time during configure processing where a package D is blocked by
58 * only (ie Depends unsatisfied but would be satisfied by) a t-awaiter W
59 * we make a note of (one of) W's t-pending, T. (Only the last such T.)
60 * (If --no-triggers and nonempty argument list and package isn't in
61 * argument list then we don't do this.)
63 * Each time in process_queue() where we increment dependtry, we instead
64 * see if we have encountered such a t-pending T. If we do and are in
65 * a trigger processing try, we trigproc T instead of incrementing
66 * dependtry and this counts as having done something so we reset
70 * For --triggers-only and --configure, we go through each thing in the
71 * argument queue (the enqueue_package queue) and check what its state is
72 * and if appropriate we trigproc it. If we didn't have a queue (or had
73 * just --pending) we search all triggers-pending packages and add them
74 * to the deferred trigproc list.
77 * Before quitting from most operations, we trigproc each package in the
78 * deferred trigproc list. This may (if not --no-triggers) of course add
79 * new things to the deferred trigproc list.
82 * Note that ‘we trigproc T’ must involve trigger cycle detection and
83 * also automatic setting of t-awaiters to t-pending or installed. In
84 * particular, we do cycle detection even for trigger processing in the
85 * configure dependtry loop (and it is OK to do it for explicitly
86 * specified packages from the command line arguments; duplicates are
87 * removed by packages.c:process_queue).
90 /*========== Deferred trigger queue. ==========*/
92 static struct pkg_queue deferred
= PKG_QUEUE_INIT
;
95 trigproc_enqueue_deferred(struct pkginfo
*pend
)
99 ensure_package_clientdata(pend
);
100 if (pend
->clientdata
->trigprocdeferred
)
102 pend
->clientdata
->trigprocdeferred
= pkg_queue_push(&deferred
, pend
);
103 debug(dbg_triggers
, "trigproc_enqueue_deferred pend=%s",
104 pkg_name(pend
, pnaw_always
));
108 * Populate the deferred trigger queue.
110 * When dpkg is called with a specific set of packages to act on, we might
111 * have packages pending trigger processing. But because there are frontends
112 * that do not perform a final «dpkg --configure --pending» call (i.e. apt),
113 * the system is left in a state with packages not fully installed.
115 * We have to populate the deferred trigger queue from the entire package
116 * database, so that we might try to do opportunistic trigger processing
117 * when going through the deferred trigger queue, because a fixed apt will
118 * not request the necessary processing anyway.
120 * XXX: This can be removed once apt is fixed in the next stable release.
123 trigproc_populate_deferred(void)
125 struct pkg_hash_iter
*iter
;
128 iter
= pkg_hash_iter_new();
129 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
130 if (!pkg
->trigpend_head
)
133 if (pkg
->status
!= PKG_STAT_TRIGGERSAWAITED
&&
134 pkg
->status
!= PKG_STAT_TRIGGERSPENDING
)
137 if (pkg
->want
!= PKG_WANT_INSTALL
&&
138 pkg
->want
!= PKG_WANT_HOLD
)
141 trigproc_enqueue_deferred(pkg
);
143 pkg_hash_iter_free(iter
);
147 trigproc_run_deferred(void)
151 debug(dbg_triggers
, "trigproc_run_deferred");
152 while (!pkg_queue_is_empty(&deferred
)) {
155 pkg
= pkg_queue_pop(&deferred
);
160 pop_error_context(ehflag_bombout
);
163 push_error_context_jump(&ejbuf
, print_error_perpackage
,
164 pkg_name(pkg
, pnaw_nonambig
));
166 ensure_package_clientdata(pkg
);
167 pkg
->clientdata
->trigprocdeferred
= NULL
;
168 trigproc(pkg
, TRIGPROC_TRY_DEFERRED
);
170 pop_error_context(ehflag_normaltidy
);
175 * Called by modstatdb_note.
178 trig_activate_packageprocessing(struct pkginfo
*pkg
)
180 debug(dbg_triggersdetail
, "trigproc_activate_packageprocessing pkg=%s",
181 pkg_name(pkg
, pnaw_always
));
183 trig_parse_ci(pkg_infodb_get_file(pkg
, &pkg
->installed
, TRIGGERSCIFILE
),
184 NULL
, trig_cicb_statuschange_activate
,
185 pkg
, &pkg
->installed
);
188 /*========== Actual trigger processing. ==========*/
190 struct trigcyclenode
{
191 struct trigcyclenode
*next
;
192 struct trigcycleperpkg
*pkgs
;
193 struct pkginfo
*then_processed
;
196 struct trigcycleperpkg
{
197 struct trigcycleperpkg
*next
;
199 struct trigpend
*then_trigs
;
202 static bool tortoise_advance
;
203 static struct trigcyclenode
*tortoise
, *hare
;
206 trigproc_reset_cycle(void)
208 tortoise_advance
= false;
209 tortoise
= hare
= NULL
;
213 tortoise_in_hare(struct pkginfo
*processing_now
,
214 struct trigcycleperpkg
*tortoise_pkg
)
216 const char *processing_now_name
, *tortoise_name
;
217 struct trigpend
*hare_trig
, *tortoise_trig
;
219 processing_now_name
= pkg_name(processing_now
, pnaw_nonambig
);
220 tortoise_name
= pkg_name(tortoise_pkg
->pkg
, pnaw_nonambig
);
222 debug(dbg_triggersdetail
, "%s pnow=%s tortoise=%s", __func__
,
223 processing_now_name
, tortoise_name
);
224 for (tortoise_trig
= tortoise_pkg
->then_trigs
;
226 tortoise_trig
= tortoise_trig
->next
) {
227 debug(dbg_triggersdetail
,
228 "%s pnow=%s tortoise=%s tortoisetrig=%s", __func__
,
229 processing_now_name
, tortoise_name
, tortoise_trig
->name
);
231 /* hare is now so we can just look up in the actual data. */
232 for (hare_trig
= tortoise_pkg
->pkg
->trigpend_head
;
234 hare_trig
= hare_trig
->next
) {
235 debug(dbg_triggersstupid
, "%s pnow=%s tortoise=%s"
236 " tortoisetrig=%s haretrig=%s", __func__
,
237 processing_now_name
, tortoise_name
,
238 tortoise_trig
->name
, hare_trig
->name
);
239 if (strcmp(hare_trig
->name
, tortoise_trig
->name
) == 0)
243 if (hare_trig
== NULL
) {
244 /* Not found in hare, yay! */
245 debug(dbg_triggersdetail
, "%s pnow=%s tortoise=%s OK",
246 __func__
, processing_now_name
, tortoise_name
);
254 static struct trigcyclenode
*
255 trigproc_new_cyclenode(struct pkginfo
*processing_now
)
257 struct trigcyclenode
*tcn
;
258 struct trigcycleperpkg
*tcpp
;
260 struct pkg_hash_iter
*iter
;
262 tcn
= nfmalloc(sizeof(*tcn
));
265 tcn
->then_processed
= processing_now
;
267 iter
= pkg_hash_iter_new();
268 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
269 if (!pkg
->trigpend_head
)
271 tcpp
= nfmalloc(sizeof(*tcpp
));
273 tcpp
->then_trigs
= pkg
->trigpend_head
;
274 tcpp
->next
= tcn
->pkgs
;
277 pkg_hash_iter_free(iter
);
283 * Returns package we are to give up on.
285 static struct pkginfo
*
286 check_trigger_cycle(struct pkginfo
*processing_now
)
288 struct trigcyclenode
*tcn
;
289 struct trigcycleperpkg
*tortoise_pkg
;
290 struct trigpend
*tortoise_trig
;
291 struct pkginfo
*giveup
;
294 debug(dbg_triggers
, "check_triggers_cycle pnow=%s",
295 pkg_name(processing_now
, pnaw_always
));
297 tcn
= trigproc_new_cyclenode(processing_now
);
300 debug(dbg_triggersdetail
, "check_triggers_cycle pnow=%s first",
301 pkg_name(processing_now
, pnaw_always
));
302 hare
= tortoise
= tcn
;
308 if (tortoise_advance
)
309 tortoise
= tortoise
->next
;
310 tortoise_advance
= !tortoise_advance
;
312 /* Now we compare hare to tortoise.
313 * We want to find a trigger pending in tortoise which is not in hare
314 * if we find such a thing we have proved that hare isn't a superset
315 * of tortoise and so that we haven't found a loop (yet). */
316 for (tortoise_pkg
= tortoise
->pkgs
;
318 tortoise_pkg
= tortoise_pkg
->next
) {
319 if (!tortoise_in_hare(processing_now
, tortoise_pkg
))
322 /* Oh dear. hare is a superset of tortoise. We are making no
324 notice(_("cycle found while processing triggers:\n"
325 " chain of packages whose triggers are or may be responsible:"));
327 for (tcn
= tortoise
; tcn
; tcn
= tcn
->next
) {
328 fprintf(stderr
, "%s%s", sep
,
329 pkg_name(tcn
->then_processed
, pnaw_nonambig
));
332 fprintf(stderr
, _("\n" " packages' pending triggers which are"
333 " or may be unresolvable:\n"));
334 for (tortoise_pkg
= tortoise
->pkgs
;
336 tortoise_pkg
= tortoise_pkg
->next
) {
337 fprintf(stderr
, " %s",
338 pkg_name(tortoise_pkg
->pkg
, pnaw_nonambig
));
340 for (tortoise_trig
= tortoise_pkg
->then_trigs
;
342 tortoise_trig
= tortoise_trig
->next
) {
343 fprintf(stderr
, "%s%s", sep
, tortoise_trig
->name
);
345 fprintf(stderr
, "\n");
348 /* We give up on the _earliest_ package involved. */
349 giveup
= tortoise
->pkgs
->pkg
;
350 debug(dbg_triggers
, "check_triggers_cycle pnow=%s giveup=%s",
351 pkg_name(processing_now
, pnaw_always
),
352 pkg_name(giveup
, pnaw_always
));
353 if (giveup
->status
!= PKG_STAT_TRIGGERSAWAITED
&&
354 giveup
->status
!= PKG_STAT_TRIGGERSPENDING
)
355 internerr("package %s in non-trigger state %s",
356 pkg_name(giveup
, pnaw_always
),
357 pkg_status_name(giveup
));
358 giveup
->clientdata
->istobe
= PKG_ISTOBE_NORMAL
;
359 pkg_set_status(giveup
, PKG_STAT_HALFCONFIGURED
);
360 modstatdb_note(giveup
);
361 print_error_perpackage(_("triggers looping, abandoned"),
362 pkg_name(giveup
, pnaw_nonambig
));
368 * Does cycle checking. Doesn't mind if pkg has no triggers pending - in
369 * that case does nothing but fix up any stale awaiters.
372 trigproc(struct pkginfo
*pkg
, enum trigproc_type type
)
374 static struct varbuf namesarg
;
376 struct varbuf depwhynot
= VARBUF_INIT
;
378 debug(dbg_triggers
, "trigproc %s", pkg_name(pkg
, pnaw_always
));
380 ensure_package_clientdata(pkg
);
381 if (pkg
->clientdata
->trigprocdeferred
)
382 pkg
->clientdata
->trigprocdeferred
->pkg
= NULL
;
383 pkg
->clientdata
->trigprocdeferred
= NULL
;
385 if (pkg
->trigpend_head
) {
386 struct pkginfo
*gaveup
;
390 if (pkg
->status
!= PKG_STAT_TRIGGERSPENDING
&&
391 pkg
->status
!= PKG_STAT_TRIGGERSAWAITED
)
392 internerr("package %s in non-trigger state %s",
393 pkg_name(pkg
, pnaw_always
),
394 pkg_status_name(pkg
));
396 if (dependtry
< DEPEND_TRY_TRIGGERS
&&
397 type
== TRIGPROC_TRY_QUEUED
) {
398 /* We are not yet in a triggers run, so postpone this
399 * package completely. */
400 enqueue_package(pkg
);
404 if (dependtry
>= DEPEND_TRY_CYCLES
) {
405 if (findbreakcycle(pkg
))
409 ok
= dependencies_ok(pkg
, NULL
, &depwhynot
);
410 if (ok
== DEP_CHECK_DEFER
) {
411 if (dependtry
>= DEPEND_TRY_TRIGGERS_CYCLES
) {
412 gaveup
= check_trigger_cycle(pkg
);
417 varbuf_destroy(&depwhynot
);
418 enqueue_package(pkg
);
420 } else if (ok
== DEP_CHECK_HALT
) {
421 /* When doing opportunistic deferred trigger processing,
422 * nothing requires us to be able to make progress;
423 * skip the package and silently ignore the error due
424 * to unsatisfiable dependencies. And because we can
425 * end up here repeatedly, if this package is required
426 * to make progress for other packages, we need to
427 * reset the trigger cycle tracking to avoid detecting
429 if (type
== TRIGPROC_TRY_DEFERRED
) {
430 trigproc_reset_cycle();
432 varbuf_destroy(&depwhynot
);
437 varbuf_end_str(&depwhynot
);
438 notice(_("dependency problems prevent processing "
439 "triggers for %s:\n%s"),
440 pkg_name(pkg
, pnaw_nonambig
), depwhynot
.buf
);
441 varbuf_destroy(&depwhynot
);
442 ohshit(_("dependency problems - leaving triggers unprocessed"));
443 } else if (depwhynot
.used
) {
444 varbuf_end_str(&depwhynot
);
445 notice(_("%s: dependency problems, but processing "
446 "triggers anyway as you requested:\n%s"),
447 pkg_name(pkg
, pnaw_nonambig
), depwhynot
.buf
);
448 varbuf_destroy(&depwhynot
);
451 gaveup
= check_trigger_cycle(pkg
);
455 printf(_("Processing triggers for %s (%s) ...\n"),
456 pkg_name(pkg
, pnaw_nonambig
),
457 versiondescribe(&pkg
->installed
.version
, vdew_nonambig
));
458 log_action("trigproc", pkg
, &pkg
->installed
);
460 varbuf_reset(&namesarg
);
461 for (tp
= pkg
->trigpend_head
; tp
; tp
= tp
->next
) {
462 varbuf_add_char(&namesarg
, ' ');
463 varbuf_add_str(&namesarg
, tp
->name
);
465 varbuf_end_str(&namesarg
);
467 /* Setting the status to half-configured
468 * causes modstatdb_note to clear pending triggers. */
469 pkg_set_status(pkg
, PKG_STAT_HALFCONFIGURED
);
474 maintscript_postinst(pkg
, "triggered",
475 namesarg
.buf
+ 1, NULL
);
478 post_postinst_tasks(pkg
, PKG_STAT_INSTALLED
);
480 /* In other branch is done by modstatdb_note(), from inside
481 * post_postinst_tasks(). */
482 trig_clear_awaiters(pkg
);
486 /*========== Transitional global activation. ==========*/
489 transitional_interest_callback_ro(const char *trig
, struct pkginfo
*pkg
,
490 struct pkgbin
*pkgbin
, enum trig_options opts
)
492 struct pkginfo
*pend
= pkg
;
493 struct pkgbin
*pendbin
= pkgbin
;
495 debug(dbg_triggersdetail
,
496 "trig_transitional_interest_callback trig=%s pend=%s",
497 trig
, pkgbin_name(pend
, pendbin
, pnaw_always
));
498 if (pend
->status
>= PKG_STAT_TRIGGERSAWAITED
)
499 trig_note_pend(pend
, nfstrsave(trig
));
503 transitional_interest_callback(const char *trig
, struct pkginfo
*pkg
,
504 struct pkgbin
*pkgbin
, enum trig_options opts
)
506 struct pkginfo
*pend
= pkg
;
507 struct pkgbin
*pendbin
= pkgbin
;
509 trig_cicb_interest_add(trig
, pend
, pendbin
, opts
);
510 transitional_interest_callback_ro(trig
, pend
, pendbin
, opts
);
514 * cstatus might be msdbrw_readonly if we're in --no-act mode, in which
515 * case we don't write out all of the interest files etc. but we do
516 * invent all of the activations for our own benefit.
519 trig_transitional_activate(enum modstatdb_rw cstatus
)
521 struct pkg_hash_iter
*iter
;
524 iter
= pkg_hash_iter_new();
525 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
526 if (pkg
->status
<= PKG_STAT_HALFINSTALLED
)
528 debug(dbg_triggersdetail
, "trig_transitional_activate %s %s",
529 pkg_name(pkg
, pnaw_always
),
530 pkg_status_name(pkg
));
531 pkg
->trigpend_head
= NULL
;
532 trig_parse_ci(pkg_infodb_get_file(pkg
, &pkg
->installed
,
534 cstatus
>= msdbrw_write
?
535 transitional_interest_callback
:
536 transitional_interest_callback_ro
, NULL
,
537 pkg
, &pkg
->installed
);
538 /* Ensure we're not creating incoherent data that can't
539 * be written down. This should never happen in theory but
540 * can happen if you restore an old status file that is
541 * not in sync with the infodb files. */
542 if (pkg
->status
< PKG_STAT_TRIGGERSAWAITED
)
545 if (pkg
->trigaw
.head
)
546 pkg_set_status(pkg
, PKG_STAT_TRIGGERSAWAITED
);
547 else if (pkg
->trigpend_head
)
548 pkg_set_status(pkg
, PKG_STAT_TRIGGERSPENDING
);
550 pkg_set_status(pkg
, PKG_STAT_INSTALLED
);
552 pkg_hash_iter_free(iter
);
554 if (cstatus
>= msdbrw_write
) {
555 modstatdb_checkpoint();
556 trig_file_interests_save();
560 /*========== Hook setup. ==========*/
562 TRIGHOOKS_DEFINE_NAMENODE_ACCESSORS
564 static const struct trig_hooks trig_our_hooks
= {
565 .enqueue_deferred
= trigproc_enqueue_deferred
,
566 .transitional_activate
= trig_transitional_activate
,
567 .namenode_find
= th_nn_find
,
568 .namenode_interested
= th_nn_interested
,
569 .namenode_name
= th_nn_name
,
573 trigproc_install_hooks(void)
575 trig_override_hooks(&trig_our_hooks
);