4

I have a series of script with which I was able to install and configure newly Debian stable systems. To automatically start programs I use /etc/rc.local but for other cases I had to manually change the /etc/inittab file. I have other changes as well such as adding --noclear to the line 1:2345:respawn:/sbin/getty --noclear 38400 tty1.

Because I had to customize the shut down process, I ended up doing this:

l0:0:wait:/etc/rc.halt 0
...
l6:6:wait:/etc/rc.halt 6

and my /etc/rc.halt looks like this

#!/bin/sh
#   
# rc.halt
#   
# This script is executed when entering level 6/0 (on halt or reboot)

su - teststand -c "/home/teststand/stop_server.sh"  # my custom command

# making sure the halt/reboot process is resumed
test -n "${1}" && /etc/init.d/rc ${1}

exit 0

Today was my fist time installing a new Debian 8 with systemd as the default init system. I didn't think about that and was first surprised that the /etc/inittab file was missing.

On my running systems (@work & @home) I'm still running my systems with sysvinit and that's why I have 0 experience with systemd.

I know that I can change to the old sysvinit but I want to see the differences with systemd. Besides I'm customizing a new installation right now and I don't have too much time to finish it, that's why I don't have the time right now to look at the documentation.

My question: is there a way to quickly change systemd behaviour so that I can add --noclear to getty and using /etc/rc.halt as the starting point for reboot/halt?

Basically can I quickly import my old inittab changes to systemd?

Thanks

9

systemd is not backwards compatible with System 5 init, only System 5 rc.

Linux System 5-style system management comprises two parts, init which runs as process #1 and rc which is in charge of running start and stop scripts. These are actually from two distinct packages in Debian. init is from the sysvinit package; and rc is usually from the sysv-rc package, but could be from the file-rc or the openrc package.

/etc/inittab is a configuration file processed by init. systemd does not provide any backwards compatibility mechanism for this. systemd's System 5 backwards compatibility mechanism is only for System 5 rc, which runs the programs in /etc/init.d/. (It's only for that specific flavour of rc, moreover. systemd implements no backwards compatibility mechanism for file-rc's and openrc's configuration mechanisms.)

This is not something that is specific to systemd. Pretty much no replacement init/system manager (with just 1 exception in three decades) processes /etc/inittab.

To plumb a service in to systemd, you must use the mechanisms that it does support, namely its own service unit files and (via a generator that auto-converts into unit files) the System 5 rc configuration files in /etc/init.d/.

Forget about run levels.

All of that runlevel stuff that you are working with has been declared "obsolete" on systemd Linux operating systems. There is no run level 0 or 6 to enter. They don't exist outwith a few compatibility shims.

To make a service run at shutdown, the obvious answer, given by many, is to create a service unit that is WantedBy the shutdown.target. This has some subtle pitfalls, though. A better, but less obvious, answer is to create an otherwise normal service unit, with DefaultDependencies=yes to ensure that it conflicts with the shutdown target, and put the meat of the service in ExecStop instead of in ExecStart.

[Unit]
Documentation=https://unix.stackexchange.com/questions/233561/

[Service]
Type=oneshot
User=teststand
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/teststand/stop_server.sh

[Install]
WantedBy=multi-user.target

Don't roll your own Poor Man's Dæmon Supervisor in shell script.

Such things are always badly written.

If your "service" is simply the running of a command named "stop_server.sh", then the inference is that this is a script that stops a server under some hand-rolled shell-script service management system.

It is for these badly written, rickety, unreliable, and dangerous disasters: stop_server.sh stop_server.sh stop_server.sh stop_server.sh stop_server.sh stop_server.sh

You have systemd. Make use of it, and run whatever service is being run here using proper service management mechanisms. You won't need this oddball ExecStop-only service at all if you make your actual service runnable via systemd with DefaultDependencies=true, as systemd will handle shutting down the service at shutdown time.

Taking a Poor Man's Dæmon Supervisor in shell script that "manages" one service, and then wrapping that in a systemd service unit for a second service that one then arranges to start at shutdown, when the aim is no more than to manage the first service and have it shut down when the system is halted or powered off, is a good way to an entry in the systemd House of Horror.

The world wants you to clean your screen.

Wanting not to clear a virtual terminal between log-off and subsequent log-on is very much swimming against the tide, as Greg Wooledge and others have discovered. The presence of sensitive output from privileged users, or bosses, remaining after log-off has been a security problem for Unices (and indeed other timesharing remote-access operating systems) since the 1970s, and it takes a lot of effort to undo all of the things that people have put in to avert this problem.

  • Many systems have a clear_console command in their shell logout scripts as standard. (This is problematic in its own right, as it doesn't play well with graphical programs running on kernel virtual terminal #1, and doesn't work with any other kinds of terminals, virtual or real.)

    This command has to be removed.

  • The default in getty programs aimed at virtual terminals, such as mingetty, is to clear the terminal. (It does this before log-on, meaning that terminal output can remain unerased if a TTY login service is stopped. Ironically, this functionality would have been better placed in login, which thanks to the necessities of PAM is still running at log-off.)

    The --noclear option has to be deployed to disable this. This involves writing one or more unit file override files, changing the ExecStart setting, or simply pointing autovt@.service at a local unit file of one's own devising.

  • systemd's supplied getty@.service template service unit sets TTYVTDisallocate=yes which instructs systemd to clear a kernel virtual terminal. (This again doesn't work with any other kinds of terminals, not even user-space virtual terminals, as partly reflected in its name.)

    This too has to be removed, again with an override or a different service template pointed to by autovt@.service.

Further reading

  • Thanks a lot for the very comprehensive explanation :) The reason I want not to clear the first tty after booting is debugging, looking when and how or services start, or why something fails or takes forever. Our (industrial) PCs are berried deep in switching cabinets and our customers couldn't care less if we run Linux, Windows or a monkey, they don't open the switching cabinets, they don't see our system. It's only me that wants that, after all when I have to go onsite because "the system is not working", I plug a monitor to the system and see what is going on during booting time. – Pablo Oct 4 '15 at 17:05
2

I'm working from CentOS 7, which may have a different setup. However, for me, the invocation of getty is controlled by the service file /usr/lib/systemd/system/getty@.service. (The @ is for templating; it's started as getty@tty1.service, and the string tty1 is passed into the file and controls which TTY it's run on.) Within this file, there's a line beginning ExecStart=, which specifies the command line. Options would be added here. (It's best not to edit the file under /usr directly, as it might be overwritten by system upgrades; you should copy it to somewhere under /etc first, probably /etc/systemd/system, where it will shadow the vendor-provided file.)

It looks as if what you want on shutdown/reboot is best handled not by tweaking the shutdown/reboot process directly, but by adding the action to the list of service shutdown actions, which systemd will automatically carry out on a system halt or reboot (or when you turn off the service manually with systemctl). The quick way to do this is to turn the script into an ExecStop line of a system service command; depending on how things are set up, you might also make a user service file governing the whole thing and put the ExecStop there.

  • Thanks. I', not @work till Monday, so I cannot test it until then. About the shutdown: I know I can have my own service shutdown. However this doesn't work as I need. I need to close very large HD5 data files and this can sometimes take up to several minutes. At least with sysvinit the actual shutdown ocurred before my service could close all HD5 files thus leaving me with corrupted files. – Pablo Oct 3 '15 at 1:34
  • That's the reason why I needed my service to be executed at reboot/shutdown and to take as much time as it needs before resuming the shutdown/reboot. I tried sleeps (in my service) and making more services depend on it, but in the end sysvinit would always eventually kill it. The easiest way was to execute my own script whenin init 0 or init 6, that's why I tweaked good old inittab – Pablo Oct 3 '15 at 1:38
  • 1
    I'm pretty sure systemd will wait until the ExecStop has finished before continuing with shutdown. If you do run into a problem, you should tweak the TimeoutStopSec value in the same file. – Tom Hunt Oct 3 '15 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.