Comment 7 for bug 1575572

Revision history for this message
Martin Pitt (pitti) wrote :

I had a closer look how systemd emulates the old runlevels. systemd-update-utmp-runlevel.service runs after graphical.target, multi-user.target etc. started (After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target, those are activated in multi-user.target etc.). src/update-utmp/update-utmp.c determines which runlevel to report in get_current_runlevel() using this table:

        static const struct {
                const int runlevel;
                const char *special;
        } table[] = {
                /* The first target of this list that is active or has
                 * a job scheduled wins. We prefer runlevels 5 and 3
                 * here over the others, since these are the main
                 * runlevels used on Fedora. It might make sense to
                 * change the order on some distributions. */
                { '5', SPECIAL_GRAPHICAL_TARGET },
                { '3', SPECIAL_MULTI_USER_TARGET },
                { '1', SPECIAL_RESCUE_TARGET },

But targets only have states "dead" and "active", unlike units there is no "activating". So we cannot use this approach to see if multi-user.target *will* be active (or not) at some point in the future if we just made it past basic.target. So fixing this in systemd itself will require larger architectural changes which we presumably don't want in an SRU (and maybe also don't want at all, as sysvinit and its runlevel concept haven't mapped well to parallel/dynamic init systems such as upstart or systemd).

Therefore I'd rather fix this in invoke-rc.d -- use runlevel only for SysVinit, and drop the whole runlevel and /etc/rc?.d/ parsing stuff under systemctl and just use "systemctl is-enabled" to determine whether to start a service or not. That avoids the guesswork on both sides, is structurally much simpler, and more robust.