D-Bus-Methodenaufruf am Beispiel von Suspend
Per D-Bus kann man Systemd mitteilen, dass es zum Beispiel den Rechner schlafenlegen soll. Den Weg dorthin will ich hier kurz skizzieren, da mir dies beim ersten Mal nicht so leicht fiel und ich zur Zeit häufiger mit D-Bus zu tun habe.
Die Methode finden
Mit Systemd kommt das Programm busctl, über das auf der Kommandozeile
mit D-Bus interagieren kann. Mit busctl list
kann man sich die Liste der
laufenden Dienste abrufen:
NAME PID PROCESS USER CONNECTION UNIT SESSION DESCRIPTION
:1.0 1 systemd root :1.0 init.scope - -
:1.1 695 avahi-daemon avahi :1.1 avahi-daemon.service - -
:1.10 913 polkitd root :1.10 polkit.service - -
:1.107 26881 Xorg joerg :1.107 session-13.scope 13 -
:1.108 26889 ck-launch-sessi joerg :1.108 session-13.scope 13 -
:1.126 2882 systemd-network systemd-network :1.126 systemd-networkd.service - -
:1.127 2885 systemd-resolve systemd-resolve :1.127 systemd-resolved.service - -
:1.2 697 systemd-logind root :1.2 systemd-logind.service - -
:1.202 3395 busctl joerg :1.202 session-13.scope 13 -
org.bluez - - - (activatable) - -
org.freedesktop.Avahi 695 avahi-daemon avahi :1.1 avahi-daemon.service - -
org.freedesktop.ColorManager - - - (activatable) - -
org.freedesktop.ConsoleKit 847 console-kit-dae root :1.8 console-kit-daemon.ser…ce - -
org.freedesktop.DBus 700 dbus-daemon messagebus org.freedesktop.DBus dbus.service - -
org.freedesktop.PolicyKit1 913 polkitd root :1.10 polkit.service - -
org.freedesktop.RealtimeKit1 704 rtkit-daemon root :1.3 rtkit-daemon.service - -
org.freedesktop.UDisks2 - - - (activatable) - -
org.freedesktop.hostname1 - - - (activatable) - -
org.freedesktop.locale1 - - - (activatable) - -
org.freedesktop.login1 697 systemd-logind root :1.2 systemd-logind.service - -
org.freedesktop.network1 2882 systemd-network systemd-network :1.126 systemd-networkd.service - -
org.freedesktop.resolve1 2885 systemd-resolve systemd-resolve :1.127 systemd-resolved.service - -
org.freedesktop.systemd1 1 systemd root :1.0 init.scope - -
org.freedesktop.timedate1 - - - (activatable) - -
Hier ist der Dienst login1 verzeichnet, der das System in den Schlaf
schicken kann. Mit busctl tree org.freedesktop.login1
kann man sich die
Knoten anzeigen lassen, über die man mit dem Dienst kommunizieren kann:
└─/org
└─/org/freedesktop
└─/org/freedesktop/login1
├─/org/freedesktop/login1/seat
│ ├─/org/freedesktop/login1/seat/seat0
│ └─/org/freedesktop/login1/seat/self
├─/org/freedesktop/login1/session
│ ├─/org/freedesktop/login1/session/_313
│ ├─/org/freedesktop/login1/session/_317
│ └─/org/freedesktop/login1/session/self
└─/org/freedesktop/login1/user
├─/org/freedesktop/login1/user/_0
├─/org/freedesktop/login1/user/_1000
└─/org/freedesktop/login1/user/self
Aufgrund unendlicher Weisheit 😉 (oder man rät halt rum) erkennt man, dass
der Knoten /org/freedesktop/login1 der richtige ist. Von diesem kann man
mit busctl introspect org.freedesktop.login1 /org/freedesktop/login1
die
Eigenschaften abrufen:
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
org.freedesktop.login1.Manager interface - - -
.ActivateSession method s - -
.ActivateSessionOnSeat method ss - -
.AttachDevice method ssb - -
.CanHibernate method - s -
.CanHybridSleep method - s -
.CanPowerOff method - s -
.CanReboot method - s -
.CanRebootToFirmwareSetup method - s -
.CanSuspend method - s -
.CancelScheduledShutdown method - b -
.CreateSession method uusssssussbssa(sv) soshusub -
.FlushDevices method b - -
.GetSeat method s o -
.GetSession method s o -
.GetSessionByPID method u o -
.GetUser method u o -
.GetUserByPID method u o -
.Hibernate method b - -
.HybridSleep method b - -
.Inhibit method ssss h -
.KillSession method ssi - -
.KillUser method ui - -
.ListInhibitors method - a(ssssuu) -
.ListSeats method - a(so) -
.ListSessions method - a(susso) -
.ListUsers method - a(uso) -
.LockSession method s - -
.LockSessions method - - -
.PowerOff method b - -
.Reboot method b - -
.ReleaseSession method s - -
.ScheduleShutdown method st - -
.SetRebootToFirmwareSetup method b - -
.SetUserLinger method ubb - -
.SetWallMessage method sb - -
.Suspend method b - -
.TerminateSeat method s - -
.TerminateSession method s - -
.TerminateUser method u - -
.UnlockSession method s - -
.UnlockSessions method - - -
.BlockInhibited property s "" emits-change
.DelayInhibited property s "sleep" emits-change
.Docked property b false -
.EnableWallMessages property b true writable
.HandleHibernateKey property s "hibernate" const
.HandleLidSwitch property s "suspend" const
.HandleLidSwitchDocked property s "ignore" const
.HandlePowerKey property s "poweroff" const
.HandleSuspendKey property s "suspend" const
.HoldoffTimeoutUSec property t 30000000 const
.IdleAction property s "ignore" const
.IdleActionUSec property t 1800000000 const
.IdleHint property b true emits-change
.IdleSinceHint property t 1493720617977543 emits-change
.IdleSinceHintMonotonic property t 234145519029 emits-change
.InhibitDelayMaxUSec property t 5000000 const
.InhibitorsMax property t 8192 const
.KillExcludeUsers property as 0 const
.KillOnlyUsers property as 0 const
.KillUserProcesses property b false const
.NAutoVTs property u 6 const
.NCurrentInhibitors property t 1 -
.NCurrentSessions property t 2 -
.PreparingForShutdown property b false -
.PreparingForSleep property b false -
.RebootToFirmwareSetup property b false const
.RemoveIPC property b true const
.RuntimeDirectorySize property t 1671409664 const
.ScheduledShutdown property (st) "" 0 -
.SessionsMax property t 8192 const
.UserTasksMax property t 10813 const
.WallMessage property s "" writable
.PrepareForShutdown signal b - -
.PrepareForSleep signal b - -
.SeatNew signal so - -
.SeatRemoved signal so - -
.SessionNew signal so - -
.SessionRemoved signal so - -
.UserNew signal uo - -
.UserRemoved signal uo - -
Die Methode, um das System in den Schlaf zu schicken, ist
Suspend. Irgendwo in den unendlichen Weiten der Systemd-Dokumentation
wird das bestimmt vermerkt sein – oder man rät wieder. Mit all diesen
Informationen kann man jetzt die Methode mittels busctl call <DIENST>
<KNOTEN> <SCHNITTSTELLE> <METHODE> <TYP-PARAM-1> <PARAM-1> <TYP-PARAM-2>
<PARAM-2> …
aufrufen. Auf der Ausgabe von introspect kann man noch die
Schnittstelle, die die Methode bereitstellt, und die Parameter(-typen)
der Methode ablesen:
NAME TYPE SIGNATURE RESULT/VALUE FLAGS org.freedesktop.login1.Manager interface - - - … .Suspend method b - -
Der Parametertyp b steht für boolean. Somit ergibt sich der Aufruf:
busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager Suspend b true
Den Aufruf bzw. das Versenden der Nachricht, wie es in der D-Bus-Sprache bezeichnet wird, kann man auch mit dem Programm dbus-send durchführen. Hierbei muss man aber angeben, dass es ein System-Dienst ist, mit dem man kommunizieren will, da busctl immer von System-Diensten ausgeht und für Benutzer-Dienste einen Parameter erfordert.
% dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager.Suspend boolean:true
method return time=1493727858.922660 sender=:1.2 -> destination=:1.212 serial=1292 reply_serial=2