2

I have a service unit file that installs and configures a couple applications and needs to reboot the system when it exits. I am migrating this script over from sysVinit scripts to systemD on centOS 7.1 and am having trouble getting the system login screen to wait until the script has completed.

I have tried setting to RequiredBy, WantedBy, before, after to sysinit.target, basic.target, network-online.target but they all fail to stall the login screen until the reboot is complete.

Has anyone dealt with this before or know which service controls the login screen?

  • The login screen is likely started by graphical.target, which starts after multi-user.target, so having your unit file install to multi-user.target along with Before=graphical.target might work. – saiarcot895 Jul 15 '15 at 23:11
  • Default run-level is multi-user.target and I've tried that too. Also tried systemd-logind.service but no luck. Grub2 boot menu also seems to only show details until logind.service is up and running... Not sure what else to try... – user2946437 Jul 16 '15 at 16:59
  • What about having Conflicts=display-manager.service? (check to see that there is a service aliased to display-manager.service; otherwise, use the service that starts your graphical environment). This will make sure that while the script is running, the login screen (or rather, the GUI) isn't active. That being said, if, while the script is running, I say systemctl start display-manager.service, then the script will be killed, so you might need to play with the Before= and After= settings. – saiarcot895 Jul 16 '15 at 17:07
  • Alternatively, you can have your script or the systemd unit (in ExecStartPre= create a file called /etc/no-login-screen (don't use /etc/nologin; see man pam_nologin) and then edit the login screen's unit file to add ConditionPathExists=! /etc/no-login-screen, so that the login screen doesn't start up if that file exists. – saiarcot895 Jul 16 '15 at 17:12
  • @saiacrot895. My system will not have GUI (multi-user.target) so there is no display-manager.service. I've tried to edit the unit systemd-logind.service for ConditionPathExists= to a file that my script will create when it is finished but the login screen still pops up. Do you know what unit file controls the display of the login screen? – user2946437 Jul 16 '15 at 21:00
2

One way to do this is to specify that your service is started before another service, by using Before=. In this case, because there is no GUI, and you want to prevent console logins, you'll need to use getty@.service. (Note, however, that that's a parametrized service, and, in this case, the part after the @ represents what device to run getty on). For example:

[Unit]
Description=Run script to set up environment
Before=getty@tty1.service getty@tty2.service getty@tty3.service getty@tty4.service getty@tty5.service getty@tty6.service

[Service]
Type=oneshot
ExecStart=/bin/myscript

This will make sure that your script runs before getty starts on TTY 1-6.

Alternatively, you can instead create an (empty) file that will tell getty@.service not to start up. This has the advantage that it will automatically add the condition to all instances of getty, and not just 1-6.

To do that, first create the file before your service starts:

[Unit]
Description=Run script to set up environment

[Service]
Type=oneshot
ExecStartPre=/bin/touch /etc/no-login-console
ExecStart=/bin/myscript
ExecStopPost=/bin/rm /etc/no-login-console

Then, run systemctl edit getty@.service. This will open your editor and create an "override" file, which will effectively be appended to the main service file. That way, you can make your own customizations to the service, but still be able to use the latest versions of the service file form CentOS. In the editor that opens up, enter:

[Unit]
ConditionPathExists=!/etc/no-login-console

This tells the service to start only if /etc/no-login-console doesn't exist. Save and exit the editor. When you run systemctl cat getty@.service, you should see the main service file, followed by your override.

Edit: It looks like systemctl edit and systemctl cat isn't available in the version of systemd shipped in CentOS 7.1. Instead, run sudo vim /lib/systemd/system/getty@.service.d/condition-path.conf (where /lib/systemd/system/getty@.service is the path to the service file) and add the above text into the file. Then, run systemctl daemon-reload followed by systemctl status getty@. The output should indicate that a drop-in file was read.

  • I like the idea of creating an empty file not to startup but how and where do you run the edit and cat commands? Running systemctl edit/cat getty@.service on the command line I get Unknown operation 'edit' 'cat' – user2946437 Jul 16 '15 at 23:04
  • Based on a Red Hat help page, the edit command doesn't exist in the version of systemd shipped. I'll update my answer shortly with the manual method. – saiarcot895 Jul 17 '15 at 0:01
0

On Ubuntu 16.04 it's the display-manager service. E.g.:

[Unit]
Description=Purge home
Before=display-manager.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/clean-home.sh

[Install]
WantedBy=display-manager.service

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.