What replaces acpid event handling in SLES 12 SP1?

I am migrating from SLES 11 SP4 to SLES 12 SP1 and I can’t figure out how to handle ACPID events. I understand the the 3.12 kernel does not support the legacy acpid package.
So I have to work with systemd. I want to only power down the computer if the power button is pressed twice within five seconds.

In /etc/systemd/login.conf, there is HandlePowerKey which specifies which action is invoked when the power key is pressed. But the actions seem limited to only these:

[INDENT]ignore, poweroff, reboot, halt, suspend, hibernate, hybrid-sleep, lock or kexec.[/INDENT]

is there a way to call a custom script when the power key is pressed?

Hi
If you look at the man page for logind.conf there are options to
configue eg InhibitDelayMaxSec (which defaults to 5sec) and the next
two options.

Looks like a udev rule with a power-switch tag
(see /usr/lib/udev/rules.d/70-power-switch.rules) should suffice.


Cheers Malcolm °¿° LFCS, SUSE Knowledge Partner (Linux Counter #276890)
openSUSE Leap 42.1|GNOME 3.16.2|4.1.21-14-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks!

Thank you. I will try your suggestion.

Jay

[QUOTE=malcolmlewis;32891]Hi
If you look at the man page for logind.conf there are options to
configue eg InhibitDelayMaxSec (which defaults to 5sec) and the next
two options.

Looks like a udev rule with a power-switch tag
(see /usr/lib/udev/rules.d/70-power-switch.rules) should suffice.


Cheers Malcolm °¿° LFCS, SUSE Knowledge Partner (Linux Counter #276890)
openSUSE Leap 42.1|GNOME 3.16.2|4.1.21-14-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks![/QUOTE]

I figured out how to create my own systemd unit that gets called early in the shutdown process.

But I still do not know how to make the entire power off process conditional. I basically want the computer to shutdown only if the power button is pushed twice within 5 sec.

The Inhibit settings in logind.conf allow you to block the power key while running a command. I don’t see a mechanism to allow conditional execution of a service dynamically.

[QUOTE]Looks like a udev rule with a power-switch tag
(see /usr/lib/udev/rules.d/70-power-switch.rules)[/QUOTE]

I’m not sure what to do with these udev rules. I tried adding a RUN+ clause to them but my script never got called. I tried to replace systemd-logind getting the power key events with my own and then triggering power off target myself. This did not work.

I also tried installing acpid package but no events were triggered by the kernel, as expected.

I came up with a solution that may prove useful to someone else:

I noticed that the system log (journalctl) lists the power-button device:

# journalctl -b-0 --unit=systemd-logind | grep -m 1 '/dev/input' Jul 07 21:23:58 sm-1 systemd-logind[2167]: Watching system buttons on /dev/input/event3 (Power Button)

So I wrote a shell script to extract the power-button device and then call a python script to monitor the power-button for events:

[CODE]BUTTON_DEVICE=$(journalctl -b-0 --unit=systemd-logind | grep -m 1 ‘/dev/input’ | cut -f10 -d\ )

systemd-inhibit --what=handle-power-key --mode=block /usr/local/sbin/power-button.py $BUTTON_DEVICE[/CODE]

Notice that we have to use systemd-inhibit to block systemd-logind from processing the power button.

Recall, my goal is to require a user to press the power-button twice within five seconds to activate. Here is my python script:

[CODE]#!/usr/bin/env python

$COPYRIGHT$

import struct
import time
import sys
import syslog
import os

TRIGGER_INTERVAL = 5

SuperMicro power button

infile_path = sys.argv[1] if len(sys.argv) > 1 else “0”

#long int, long int, unsigned short, unsigned short, unsigned int
FORMAT = ‘llHHI’
EVENT_SIZE = struct.calcsize(FORMAT)

#open file in binary mode
in_file = open(infile_path, “rb”)

last_event_time = None
event = in_file.read(EVENT_SIZE)

while event:
(tv_sec, tv_usec, type, code, value) = struct.unpack(FORMAT, event)

    if type == 1 and code == 116 and value == 1:
            if last_event_time and tv_sec - last_event_time <= TRIGGER_INTERVAL:
                    syslog.syslog('Okay, you really mean it.  Shutting down')
                    os.system('/usr/bin/systemctl start systemd-poweroff.service')
            else:
                last_event_time = tv_sec
                syslog.syslog('Someone just pressed the power button!')
    event = in_file.read(EVENT_SIZE)

in_file.close()
[/CODE]

Resources:

[LIST]
[]https://wiki.archlinux.org/index.php/Power_management#Power_management_with_systemd
[
]http://stackoverflow.com/questions/5060710/format-of-dev-input-event/16682549
[/LIST]