Skip to content

4 or 5 out of 7 targets triggered by SIGRTMIN+X use the wrong job mode #6484

@sourcejedi

Description

@sourcejedi

Submission type

  • Bug report

systemd version the issue has been seen with

v234-git-01a45898f

/* Starting SIGRTMIN+0 */

Bug report

  1. The correct mode for starting shutdown-type targets is replace-irreversably, to guarantee shutdown is not interrupted by the activation of a unit with a conflict. This is used by systemctl reboot, /dev/initctl, etc. But when shutdown targets are triggered by SIGRTMIN+X, the job mode replace is used instead.
  2. Usually the correct mode for starting runlevel-like targets is isolate, to make sure services which don't belong to the target are shut down. But for default.target, job mode replace is being used instead. This differs from the other runlevel-like targets: rescue.target and emergency.target. The difference is technically documented in man systemd, but no reason is given in either the doc or the code. If I take time to think about it, I can see that using start default.target will most often not cause a problem. But I can't think of an explanation to add, that would avoid making the reader think about it in the first place.

It might be slightly clearer to move the job mode into target_table[] at the same time, similar to systemctl.c or initctl.c. Particularly if we needed DEFAULT_TARGET to keep using mode replace, and it would make that easier to comment as well.

                    /* Starting SIGRTMIN+0 */
                    static const char * const target_table[] = {
                            [0] = SPECIAL_DEFAULT_TARGET,
                            [1] = SPECIAL_RESCUE_TARGET,
                            [2] = SPECIAL_EMERGENCY_TARGET,
                            [3] = SPECIAL_HALT_TARGET,
                            [4] = SPECIAL_POWEROFF_TARGET,
                            [5] = SPECIAL_REBOOT_TARGET,
                            [6] = SPECIAL_KEXEC_TARGET
                    };

                    /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
                    static const ManagerExitCode code_table[] = {
                            [0] = MANAGER_HALT,
                            [1] = MANAGER_POWEROFF,
                            [2] = MANAGER_REBOOT,
                            [3] = MANAGER_KEXEC
                    };

                    if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
                        (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
                            int idx = (int) sfsi.ssi_signo - SIGRTMIN;
                            manager_start_target(m, target_table[idx],
(idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐛Programming errors, that need preferential fixingpid1

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions