[systemd-devel] Perl Net::DBus, org.freedesktop.system1 and inhibitor locks
Michael Hirmke
mh at mike.franken.de
Wed May 25 10:17:00 UTC 2016
Hi *,
I'd like to write a script, which can listen to the PepareForSleep
signal from systemd-logind. When it catches the signal, it should do a
few things in the context of the user. While doing this, it should
inhibit the sleep process. It gets started as autostart script in KDE.
For this purpose I use perl and the module Net::DBus.
Actually I am able to connect to the bus, attach to the appropriate
signal and run something, when getting the signal.
But:
- I only can take delay locks. Whenever I try to take a *blocking* lock,
nothing happens, as if it is completely ignored. I don't get any
error message, though.
When using *delay* locks and the maximum inhibition time has been
exceeded, I get
"systemd-logind: Delay lock is active (UID <uid>/<user>, PID
<pid>/dbus_logind) but inhibitor timeout is reached."
So it seems to work in this case, but why not with blocking locks?
- I am not able to close the file descriptor in the pre block of the
signal handler. Whenever I try, I get an error, that the descriptor
is closed.
When I try to take the lock again in the post block of the signal
handler, I get a second entry in the inhibitor list with the same
contents. After a few sleep/resume cycles the entries get more and
more.
Does anyone have any hint, what I might do wrong in my script or where
my understanding is wrong?
This is the script in question:
------------------------< snip snip snip >-----------------------------
#!/usr/bin/perl -w
use 5.005;
use strict;
use Getopt::Std;
use IO::Handle;
use Log::Journald;
use Net::DBus;
use Net::DBus::Reactor;
use POSIX qw( _exit );
use Scalar::Util qw( openhandle );
use Sys::Syslog qw( :macros );
$SIG{INT} = \&dbus_logind_SignalHandler;
STDOUT->autoflush( 1 );
STDERR->autoflush( 1 );
my $FD = -1;
my $oif = getInterface();
$oif->connect_to_signal( "PrepareForSleep", \&onPrepareForSleep ) || die $!;
takeLock( $oif );
my( $reactor ) = Net::DBus::Reactor->main();
$reactor->run();
exit( 0 );
sub getInterface {
my $bus = Net::DBus->system || die $!;
my $osvc = $bus->get_service( "org.freedesktop.login1" ) || die $!;
my $oif = $osvc->get_object(
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager"
) || die $!;
return( $oif );
}
sub takeLock {
my( $oif ) = @_;
$FD = $oif->Inhibit( 'sleep', 'dbus_sleep', 'preparing', 'delay' );
}
sub dropLock {
if( defined( $FD ) && $FD >= 0 && openhandle( $FD ) ) {
if( close( $FD ) ) {
$FD= -1;
}
}
}
sub onPrepareForSleep {
my( $prepost ) = @_;
if( $prepost ) {
print "dbus_sleep: in pre\n";
journal_log( LOG_INFO, "dbus_sleep: in pre" );
sleep( 20 );
dropLock();
} else {
print "dbus_sleep: in post\n";
journal_log( LOG_INFO, "dbus_sleep: in post" );
takeLock( getInterface() );
}
return( 0 );
}
sub dbus_logind_SignalHandler {
my( $_sig ) = shift;
if( $_sig eq "INT" ) {
POSIX::_exit( 0 );
}
}
------------------------< snip snip snip >-----------------------------
Thx
More information about the systemd-devel
mailing list