4

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?

11
  • 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. Jul 15, 2015 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... Jul 16, 2015 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. Jul 16, 2015 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. Jul 16, 2015 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? Jul 16, 2015 at 21:00

2 Answers 2

3

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 [email protected]. (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
[email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

[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 [email protected] 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 [email protected]. 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 [email protected], 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/[email protected]/condition-path.conf (where /lib/systemd/system/[email protected] 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.

2
  • 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 [email protected] on the command line I get Unknown operation 'edit' 'cat' Jul 16, 2015 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. Jul 17, 2015 at 0:01
-1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .