Saturday, September 15, 2012

systemd, getty spawning and kernel messages interference/configuration

Update:
At least Arch now uses a new xserverrc that uses the XDG_VTNR environment variable to set the VT for X to use. To properly set it, put XDG_VTNR=X X being again the number of the VT to spawn X at in ~/.pam_environment.

Original Post:
Hello, World! It's me again!
You can thank a fellow student of mine, moertarguy, for this post. He wanted to keep a reference to the instructions that will follow and thus suggested making a blogpost.

I've recently switched to systemd on my Arch installation. At least on my netbook, I still need to copy over these changes to my laptop (amongst some other configuration I've been planning to carry over as well).

I don't use a graphical boot, so I get a bunch of messages during the boot process. And I don't use a graphical login manager, so once the boot is complete and getty spawns, it will erase the messages and present a (textual) login screen. And sometimes, some messages will be printed in between the login-lines - not a pretty sight.


Before with Archs initscripts I simply had no getty spawn on tty1. Once the gettys spawned and I've switched to tty2, no additional messages would be printed, so no problems there.

Well, I could just setup systemd like this as well, but systemd offers a nice feature to spawn gettys only when they are required, i.e. you switch to that tty the first time. You can not control specific ttys with that however, only tty1-X. You can set that X in /etc/systemd/logind.conf.
Stopping a getty to spawn at tty1 is fairly easy: mv /etc/systemd/system/getty.target.wants/getty@tty{1,2}.service
(or alternatively: systemctl disable getty@tty1.service && systemctl enable getty@tty2.service)

When you reboot now, you will notice that after the boot sequence is done, you get no getty. You need to manually switch to tty2. I did this before with initscripts as well, but I found a way to automate this: chvt. So let's write a systemd service file!
Paste this in /etc/systemd/system/chvt@.service:
[Unit]
Description=Switch to tty%I
#After=getty@tty%I.service

[Service]
Type=oneshot
ExecStart=/usr/bin/chvt %I

[Install]
WantedBy=getty.target


That commented #After line there is purely for your preference. It might make sense to you, but I though I would keep this service-file from launching a getty as well and let some other service take care of doing whatever it deems necessary.
Now just enable it to switch to tty2: systemctl reload-daemons && systemctl enable chvt@2.service

If you reboot now, it'll automatically switch to tty2 for you. But some messages might now be printed between the login-lines. To fix this, append console=tty1 to your kernel parameters in grub.cfg or syslinux.cfg or whatever. By default this is tty0, which corresponds to the currently active tty.

Are we done here? Almost. If you start X, X will, without further configuration, start on tty1. If you want to leave tty1 alone to be able to review the messages there even while X is running you will want to modify that behavior.
For this, edit /etc/X11/xinit/xserverrc and insert vtX to the exec-command just before "$@" with X being the number where you want X to spawn. You will still be able to explicitly specify another vt-parameter to spawn X in with startx/xinit.


Now you're done.
You could also keep getty on tty1 and direct kernel output to some other tty though. Well, now you know how to do that as well!
Keep on kickin'!