1. Introduction
When we’re working in GUI mode, turning off the computer entails a flurry of events. Usually, we’re asked to confirm, and may be warned about other users logged in. However, while working on a remote server or in text mode, we’re not in such a comfortable position.
In this tutorial, we’ll learn how to avoid accidentally shutting down the computer with the power button.
2. What Are Input Events?
The Linux kernel translates all inputs generated by the peripheral devices into standard input events. Next, they feed all user-end applications. In turn, the application can react to them, in a configurable way. With this, we can set the GNOME action for switching off:
Let’s read input events from the device files with evtest:
$ sudo evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: Power Button
/dev/input/event1: Power Button
/dev/input/event2: Logitech Wireless Keyboard PID:4023
# ...
Subsequently, examining event1 reveals that it produces events while we’re pressing the power button:
$ sudo evtest /dev/input/event1
# ...
Input device name: "Power Button"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 116 (KEY_POWER)
Properties:
Testing ... (interrupt to exit)
Event: time 1691523460.535468, type 1 (EV_KEY), code 116 (KEY_POWER), value 1
Event: time 1691523460.535468, -------------- SYN_REPORT ------------
Event: time 1691523460.535495, type 1 (EV_KEY), code 116 (KEY_POWER), value 0
Event: time 1691523460.535495, -------------- SYN_REPORT ------------
Throughout this tutorial, we’ll run Linux in text mode. In this way, we’ll avoid interference from GUI-based applications and services, which would take their own actions otherwise.
3. How to Block the Button Events
We can intercept input events by using the –grab option of evtest:
$ sudo evtest --grab /dev/input/event1
Now we see events as they’re coming while we’re pressing the button. However, there’s no reaction to events because all interested applications are cut off from them.
4. The Inhibit Functionality
The systemd-inhibit functionality protects a command against being interrupted. The idea is to avoid disruption of actions such as CD burning or to give applications time to take appropriate actions before shutdown.
Here’s its basic syntax:
$ systemd-inhibit <command>
This runs the command and blocks system actions shutdown, sleep, and idle. However, we can pass other actions with the –what option. Additionally, we can specify the reason for protection with the –why option.
So, let’s start the stress-ng command and make sure that it won’t be interrupted by the power button:
$ systemd-inhibit --what=handle-power-key --why="stress-ng test run" stress-ng --cpu 4 --timeout 60s --metrics-brief
Then, let’s list existing inhibitors with the –list option:
$ systemd-inhibit --list
WHO UID USER PID COMM WHAT WHY MODE
WHO UID USER PID COMM WHAT WHY MODE
ModemManager 0 root 690 ModemManager sleep ModemManager needs to reset devices delay
NetworkManager 0 root 709 NetworkManager sleep NetworkManager needs to turn off networks delay
stress-ng --cpu 4 --timeout 120s 1000 joe 994 systemd-inhibit handle-power-key stress-ng test run block
3 inhibitors listed.
5. The logind Service
The systemd-logind service is responsible for an action taken upon clicking the power key. First, let’s check the status of the service:
$ systemctl status systemd-logind
● systemd-logind.service - User Login Management
# ...
Aug 08 17:25:39 fedora systemd-logind[728]: Watching system buttons on /dev/input/event1 (Power Button)
Aug 08 17:25:39 fedora systemd-logind[728]: Watching system buttons on /dev/input/event0 (Power Button)
# ...
Notably, the service listens to event interfaces /dev/input/event0 and event1.
The service parameter HandlePowerKey assigns the action to the power button event. By default, it’s poweroff. To change it, let’s edit logind.conf file:
$ sudo nano /etc/systemd/logind.conf
Then, let’s set the parameter’s value to ignore:
[Login]
# ...
HandlePowerKey=ignore
Afterwards, we need to restart the service:
$ sudo systemctl restart systemd-logind
6. Conclusion
In this article, we talked about input events triggered by pushing the power button. Then, we learned how to suppress them altogether. Next, we discussed the use of systemd-inhibit to protect the execution of commands. Finally, we configured the systemd-logind service to ignore the use of this button.
Finally, it’s worth noting that we can’t use the above methods to thwart the effect of long-time pressing, because this is handled by the computer firmware.