Chapter 10: Understanding Shutdown and Reboot Commands

By this point in your career, you most likely know the basic commands for shutting down or rebooting a text-mode Linux server. In this chapter, we'll look at some things that are more specific to the systemd method. So, bear with me. There's a chance that you might learn something that you didn't know before.

Specific topics in this chapter include the following:

  • Shutting down with systemctl
  • Halting with systemctl
  • Rebooting with systemctl
  • Using shutdown instead of systemctl

If you're ready, let's go.

Technical requirements

Although either of your virtual machines will work equally well for this, all you need is a text-mode virtual machine, so there's no need to fire up the Alma desktop virtual machine if you don't want to. Toward the end of the chapter, we'll be working with some shell scripts. If you don't want to type them in yourself, simply download them from our Git repository.

Check out the following link to see the Code in Action video: https://bit.ly/3G6nbkD

Note

Throughout this book, I've been using AlmaLinux 8 as a replacement for the soon-to-be discontinued CentOS 8. (Of course, depending upon when you're reading this, CentOS 8 may have already been discontinued.)

A few days before I started writing this chapter, the stable release of Rocky Linux 8 finally became available. Using it is the same as using AlmaLinux, or any other RHEL 8 clone for that matter. However, if security is your thing, Rocky does have one huge advantage. Unlike the other RHEL 8 clones, Rocky comes with a set of OpenSCAP profiles that you can apply either during or after the installation of the operating system. As things stand now, Rocky Linux is the only RHEL 8 clone that fully supports OpenSCAP. (If you want to learn more about OpenSCAP, be sure to check out my other book, Mastering Linux Security and Hardening, also from Packt Publishing.)

All right, if you're ready, let's get cracking.

Shutting down with systemctl

Shutting down a systemd system is really easy, but there are a few options that you might not know about. Let's start with the basic command to shut down and power off a machine, which looks like this:

donnie@ubuntu20-04:~$ sudo systemctl poweroff

So, what exactly is happening here? If you open the systemctl man page and scroll down to the poweroff item, you'll see that this command starts poweroff.target, which looks like this:

[Unit]

Description=Power-Off

Documentation=man:systemd.special(7)

DefaultDependencies=no

Requires=systemd-poweroff.service

After=systemd-poweroff.service

AllowIsolate=yes

JobTimeoutSec=30min

JobTimeoutAction=poweroff-force

[Install]

Alias=ctrl-alt-del.target

In the [Unit] section, you see that this requires systemd-poweroff.service, which means that this service will now get started. At the bottom of the [Unit] section, you will see two new parameters. The JobTimeoutSec=30min line gives systemd plenty of time to gracefully shut down all running services before it turns off the power. The JobTimeoutAction=poweroff-force line means that if all of the services haven't gracefully shut down within that 30-minute window, then systemd will turn off the power regardless. In the [Install] section, we see the Alias=ctrl-alt-del.target line. That seems a bit odd because the Ctrl + Alt + Del key sequence is for rebooting a machine, not for shutting it down. It's not just an Ubuntu oddity this time – it's the same way on the Alma machine. However, this is easy to explain. It's just that if the system hangs hard during a shutdown, doing the Ctrl + Alt + Del key sequence 7 times within 2 seconds will force the machine to do a reboot. You can then just boot to the GRUB command prompt, and shut the machine down from there. (You can read more about Ctrl + Alt + Del under the SIGINT section of the systemd man page.)

Remember, using Ctrl + Alt + Del to reboot a machine doesn't require root privileges. That's not normally a problem, because mission-critical servers should be locked away in a secure room where only authorized personnel can get to them. Even so, you might want to place restrictions on the ability to reboot servers. If this is the case, disable the Ctrl + Alt + Del reboot feature by masking ctrl-alt-del.target. The command to do that is:

donnie@ubuntu20-04:~$ sudo systemctl mask ctrl-alt-del.target

Now, you can do Ctrl + Alt + Del key sequences until the end of time, and nothing will happen.

On a desktop machine with a graphical interface, the Ctrl + Alt + Del key sequence is controlled by the desktop configuration, which might be different across various desktop environments. On the Alma machine with its Gnome 3 environment, doing Ctrl + Alt + Del brings up the normal shutdown menu, which looks like this:

Figure 10.1 – The Gnome 3 Power Off menu on the Alma machine

Masking ctrl-alt-del.target on a desktop machine does not affect this behavior.

systemd-poweroff.service only has a [Unit] section, which we see here:

[Unit]

Description=Power-Off

Documentation=man:systemd-halt.service(8)

DefaultDependencies=no

Requires=shutdown.target umount.target final.target

After=shutdown.target umount.target final.target

SuccessAction=poweroff-force

This service requires shutdown.target, umount.target, and final.target. If we look in the unit files for these targets, we can see that they don't appear to do anything. For example, here's what the shutdown.target file looks like:

[Unit]

Description=Shutdown

Documentation=man:systemd.special(7)

DefaultDependencies=no

RefuseManualStart=yes

Our good friend strings shows us that shutdown.target is defined in the systemd executable file, as we see here:

donnie@ubuntu20-04:/lib/systemd$ strings systemd | grep 'shutdown.target'

shutdown.target

donnie@ubuntu20-04:/lib/systemd$

The same thing is true of umount.target, as we see here:

donnie@ubuntu20-04:/lib/systemd$ strings systemd | grep 'umount.target'

umount.target

donnie@ubuntu20-04:/lib/systemd$

Finally, we have final.target, as we see here:

[Unit]

Description=Final Step

Documentation=man:systemd.special(7)

DefaultDependencies=no

RefuseManualStart=yes

After=shutdown.target umount.target

Although it also doesn't appear to be doing anything, it's not defined in the systemd executable file, as we see here:

donnie@ubuntu20-04:/lib/systemd$ strings systemd | grep 'final.target'

donnie@ubuntu20-04:/lib/systemd$

So, I don't know where final.target is defined, but that's okay. For our current topic, it's not important. I also couldn't find any information about what final.target actually does, other than this short blurb in the systemd.special man page:

"A special target unit that is used during the shutdown logic and may be used to pull in late services after all normal services are already terminated and all mounts unmounted."

I don't know what those late services are supposed to be, but again, that's okay. For our present discussion, it doesn't matter.

According to the systemctl man page, a systemctl poweroff command is supposed to send a wall message to all users who are logged into the system. However, that is incorrect. No message gets sent out, and there's no option switch to make it happen.

Normally, a systemctl poweroff command would shut down running services and unmount all mounted filesystems in an orderly manner. Using the --force option would shut down the system without taking time to shut down the services first. This could be handy if you have a service that's hung up and refuses to stop normally. Using the --force option twice would shut down the system without taking time to either shut down services normally or to unmount any mounted filesystems. Of course, this isn't recommended unless it's an absolute emergency, because it could corrupt your filesystem and cause data loss. On the other hand, using --force --force could be handy if the systemd process has crashed. This is because --force --force allows the systemctl executable to shut down the system without having to contact the systemd process.

Okay, let's power off the discussion about poweroff. Let's now talk briefly about halting a system.

Halting with systemctl

Using a sudo systemctl halt command halts the operating system, but it doesn't power down the computer. Because I can read your mind, I know that you're saying, But Donnie. Why would I want to halt the operating system but leave the computer running? Well, I don't know. That's something that I've never figured out in my entire Linux career.

But seriously, halt.target works pretty much the same as poweroff.target. So, I'll leave it to you to look at the associated unit files, if you really want to.

All right, let's reboot this discussion by talking about rebooting.

Rebooting with systemctl

You'll never guess what the command is to reboot a system. Okay, if you said sudo systemctl reboot, then you win today's grand prize. (Sadly, the grand prize consists of absolutely nothing, except for the good feeling that comes with giving a correct answer.)

Again, I'll leave it to you to look at the associated reboot.target files, because this also works pretty much the same as poweroff.target. One difference to note is that this time, the Alias=ctrl-alt-del.target line in the [Install] section actually does something for us. On a text mode machine, doing a Ctrl + Alt + Del sequence at the local terminal will reboot the machine. So yes, that old three-finger salute is still with us. (You don't even need to enter an admin password to make this work. So, fortunately, doing Ctrl + Alt + Del from a remote terminal doesn't work.) If you want to try this on your VirtualBox virtual machine, you'll need to click on the virtual machine's Input menu, click on Keyboard, and then click on Insert Ctrl-Alt-Del.

Once again, I'm reading your mind. I know that you're saying, But Donnie. These systemctl commands don't give us the cool options that we used to have with the old shutdown commands. Yeah, you're right, which is why I still use the old shutdown commands. So, let's talk about them next, shall we?

Using shutdown instead of systemctl

The old shutdown commands that we used on SysV systems came with some cool options. We could schedule a shutdown or reboot for some time in the future, cancel a scheduled shutdown, and broadcast a message about an impending shutdown or reboot to all users who were logged into the system. With the systemctl commands, you can't do any of that. Fortunately, the old shutdown options are still with us, in the form of a symbolic link that points to the systemctl executable, as we see here:

donnie@ubuntu20-04:~$ cd /usr/sbin/

donnie@ubuntu20-04:/usr/sbin$ ls -l shutdown

lrwxrwxrwx 1 root root 14 May 27 11:16 shutdown -> /bin/systemctl

donnie@ubuntu20-04:/usr/sbin$

Even though you can't use the old shutdown options with systemctl, you can use them with the shutdown link that points to systemctl. (Strange, but true.) Now, I realize that you old-timers might know these shutdown commands already, and that's okay. You won't hurt my feelings if you're tempted to just skim over this. On the other hand, if you bear with me until the end, you'll see some cool stuff that you might not currently know about. If you're a Linux newbie, you're almost sure to find some useful information here. So, let's go.

Whenever you do a shutdown command, you can specify the time at which you want the shutdown to occur. For example, to perform an immediate shutdown, just do:

donnie@ubuntu20-04:~$ sudo shutdown now

On an old SysV system, this command would have just halted the operating system. To power down the machine, you would have had to use the -h option. On a systemd machine, this command powers off the machine, so the -h option switch is no longer necessary. (Curiously, the -h switch is still mentioned in the shutdown man page, even though it no longer does anything.)

You can also specify the time at which you want the shutdown to occur, using the 24-hour time format. For example, to shut down the machine at 6:00 P.M., do:

donnie@ubuntu20-04:~$ sudo shutdown 18:00

Shutdown scheduled for Sun 2021-06-27 18:00:00 EDT, use 'shutdown -c' to cancel.

donnie@ubuntu20-04:~$

At about 25 minutes before the scheduled shutdown time, the system will start sending broadcast messages to all logged-in users, as we see here for Goldie:

goldie@ubuntu20-04:~$

Broadcast message from root@ubuntu20-04 on pts/0 (Sun 2021-06-27 17:50:00 EDT):

The system is going down for poweroff at Sun 2021-06-27 18:00:00 EDT!

Broadcast message from root@ubuntu20-04 on pts/0 (Sun 2021-06-27 17:51:00 EDT):

The system is going down for poweroff at Sun 2021-06-27 18:00:00 EDT!

The system will continue sending out this broadcast message until the shutdown actually occurs. The frequency with which the message gets sent out depends upon how soon the shutdown is scheduled to occur. Within the last ten minutes, the message will get sent out every minute. Fortunately, Goldie can regain use of the command prompt by just hitting the Enter key, which will allow her to finish what she's doing. (In case you're wondering, Goldie is the name of my youngest kitty. You'll never guess what color she is.)

If you change your mind and want to cancel the shutdown, use the -c option switch, as shown here:

donnie@ubuntu20-04:~$ sudo shutdown -c

donnie@ubuntu20-04:~$

You can also send out your own customized broadcast message by simply placing it after the shutdown command:

donnie@ubuntu20-04:~$ sudo shutdown 18:45 "At 6:45 PM, this server will go down for maintenance. So, get your work done and log off."

Shutdown scheduled for Sun 2021-06-27 18:45:00 EDT, use 'shutdown -c' to cancel.

donnie@ubuntu20-04:~$

At five minutes before the scheduled shutdown time, a nologin file will get created in the /run/ directory, as we see here:

donnie@ubuntu20-04:/run$ ls -l no*

-rw-r--r-- 1 root root 121 Jun 27 18:40 nologin

donnie@ubuntu20-04:/run$

This will prevent any other users from logging in. The next time you boot up this system, this nologin file will get deleted.

Any time you schedule a future shutdown job, a scheduled file gets created in the /run/systemd/shutdown/ directory. Look inside the file, and you'll see something like this:

donnie@ubuntu20-04:/run/systemd/shutdown$ cat scheduled

USEC=1624917600000000

WARN_WALL=1

MODE=poweroff

donnie@ubuntu20-04:/run/systemd/shutdown$

The USEC= line specifies the time for the scheduled shutdown, in Unix epoch format. If you don't know when the system is scheduled to shut down and you want to find out, you can use a shell script to translate this to human-readable format. The first example of this type of script uses a perl command to do the actual translation. Here's what it looks like:

#!/usr/bin/bash

if [ -f /run/systemd/shutdown/scheduled ]; then

        perl -wne 'm/^USEC=(d+)d{6}$/ and printf("Shutting down at: %s ", scalar localtime $1)' < /run/systemd/shutdown/scheduled

else

        echo "No shutdown is scheduled."

fi

exit

Save the file as scheduled_shutdown_1.sh, and set the executable permission, like this:

donnie@ubuntu20-04:~$ chmod u+x scheduled_shutdown_1.sh

donnie@ubuntu20-04:~$

Schedule a shutdown for whatever time you want, and then run the script. The output should look something like this:

donnie@ubuntu20-04:~$ ./scheduled_shutdown_1.sh

Shutting down at: Tue Jun 29 19:05:00 2021

donnie@ubuntu20-04:~$

If perl isn't installed on your system or if you'd prefer to not use perl, then you can use awk to perform the translation. The script with awk looks like this:

#/bin/bash

if [ -f /run/systemd/shutdown/scheduled ]; then

        date -d "@$( awk -F '=' '/USEC/{ $2=substr($2,1,10); print $2 }' /run/systemd/shutdown/scheduled )"

else

        echo "No shutdown is scheduled."

fi

exit

Both of these scripts are set up to search for the scheduled file, and to only run the translation command if the scheduled file exists. If the file doesn't exist, the script will inform you of that, and then exit gracefully.

To reboot a machine, just use shutdown with the -r option, like this:

donnie@ubuntu20-04:~$ sudo shutdown -r now

You can schedule a reboot and send custom broadcast messages the same way that you would do for a shutdown operation.

Note

You old-timers might remember that on SysV systems, there was also an f option that you could use with the -r option. Doing a sudo shutdown -rf now command would reboot the machine, and would cause an fsck operation to be performed on the machine's filesystems before mounting them. That f option is now gone, because systemd systems are set up to always do an fsck operation on all supported filesystems every time you boot the machine. This happens because systemd-fsckd.service runs as part of the boot-up process if any supported filesystems are detected. (By supported filesystems, I mean that fsck works on the ext4 filesystem that's the default for Ubuntu, but it doesn't work on the xfs filesystem, which is the default for RHEL and RHEL clones. So, don't be too disappointed if you see that systemd-fsckd.service doesn't run on your Alma machine.)

In Chapter 7, Understanding systemd Timers, we learned how to set up a job to automatically run when you boot up your machine. Now, let's see how to set up a job to run when you shut down the machine.

Running a job before shutting down

Let's say that you want to have a job automatically run every time you shut down your computer. (I'll let you use your imagination about what kind of job that could be.) To set that up, just create your own custom service that's WantedBy the shutdown.target. Let's check out how.

We'll demonstrate this by creating a dummy shell script that goes along with our new service. In the /usr/local/bin/ directory, create the script.sh file with the following contents:

#!/bin/bash

# Run script with systemd only at shutdown, and not for reboot.

systemctl list-jobs | egrep -q 'reboot.target.*start' && echo "Testing myscript.service for reboot" > /root/reboot_test.txt

systemctl list-jobs | egrep -q 'shutdown.target.*start' && echo "Testing myscript.service for shutdown" > /root/shutdown_test.txt

The first systemctl list-jobs command will search through the list of running jobs, looking for the reboot.target.*start* text string. If the text string is found, the && operator will cause the echo command to run. The echo output will go to the reboot_test.txt file in the /root/ directory. However, this will never actually happen, because this service will only get activated by shutdown.target, and not by reboot.target. The next line is the same, except it's looking for the shutdown.target.*start* text string. If that text string is found, the echo command will send its output to the /root/shutdown_test.txt file. After you've saved the file, set the executable permission by doing:

donnie@ubuntu20-04:/usr/local/bin$ sudo chmod u+x script.sh

Next, use sudo systemctl edit --full --force myscript.service to create the service. Add the following contents:

[Unit]

Description=Run this service only when shutting down

DefaultDependencies=no

Conflicts=reboot.target

Before=poweroff.target halt.target shutdown.target

Requires=poweroff.target

[Service]

Type=oneshot

ExecStart=/usr/local/bin/script.sh

RemainAfterExit=yes

[Install]

WantedBy=shutdown.target

The ExecStart= line activates our shell script. In the [Install] section, we see that this service is WantedBy the shutdown.target.

Once you've saved this file, do the normal sudo systemctl daemon-reload and sudo systemctl enable myscript.service operations. To test things out, first shut the machine down and then start it back up. You should now see the shutdown_test.txt file in the /root/ directory:

donnie@ubuntu20-04:~$ sudo ls -l /root/

[sudo] password for donnie:

total 8

-rw-r--r-- 1 root root   38 Jun 29 18:19 shutdown_test.txt

drwxr-xr-x 3 root root 4096 Jun  3 20:20 snap

donnie@ubuntu20-04:~$ sudo cat /root/shutdown_test.txt

Testing myscript.service for shutdown

donnie@ubuntu20-04:~$

Next, reboot the machine. This time, you'll see that no file gets created, proving that this service will run only for a shutdown, and not for a reboot.

Okay, I think that's about it. Let's wrap this baby up.

Summary

As usual, we've seen some cool stuff in this chapter. We started out by looking at the systemctl commands for shutting down, halting, or rebooting a machine. We then saw that the old-style shutdown commands still work, and will allow you to use the scheduling and messaging features that you've always been used to using. We ended by creating a service that would run a job whenever you shut down the machine.

I realize that a lot of you might already have been familiar with a lot of what I presented in this chapter, but I did present some cool things at the end, and I hope that you enjoyed it.

This concludes part 1 of Mastering systemd. In part 2, we'll delve into the mysteries of cgroups. I'll see you there.

Questions

  1. What is the command for rebooting a Linux machine?

    a) sudo shutdown now

    b) sudo systemctl -r now

    c) sudo systemctl reboot now

    d) sudo systemctl reboot

    e) sudo shutdown --reboot

  2. What happens 5 minutes before a scheduled shutdown time?

    a) The scheduled file gets created in the /run/systemd/shutdown/ directory.

    b) The scheduled file gets created in the /run/ directory.

    c) The nologin file gets created in the /run/systemd/shutdown/ directory.

    d) The nologin file gets created in the /run/ directory.

  3. When you schedule a future shutdown, which of the following happens?

    a) A nologin file gets created in the /run/systemd/shutdown/ directory.

    b) A scheduled file gets created in the /run/systemd/shutdown/ directory.

    c) A nologin file gets created in the /run/systemd/ directory.

    d) A scheduled file gets created in the /run/ directory.

  4. What could happen if you do a sudo systemctl poweroff --force --force command?

    a) Using the --force option twice would result in an error message.

    b) The system will ignore the second --force option.

    c) You could damage your filesystem, which could result in data loss.

    d) If the first --force doesn't ensure that the power off command works, the second one surely will.

Answers

  1. d
  2. d
  3. b
  4. c

Further reading

Run a script on a systemd system at shutdown: Note that the script doesn't work as it's shown in this article. This is because it has you create the script and save the output files in the /tmp/ directory, which gets cleaned out every time you shut down the machine:

https://www.golinuxcloud.com/run-script-with-systemd-at-shutdown-only-rhel/

How to check the time for a delayed shutdown: You can find the answers to lots of your Linux admin questions with simple DuckDuckGo searches, as I did with this. Learn how to use DuckDuckGo. It can be a Linux administrator's best friend:

https://unix.stackexchange.com/questions/229745/systemd-how-to-check-scheduled-time-of-a-delayed-shutdown

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.193.207