Shutdown your machine automatically (or from remote)

July 11, 2009

I was wondering whether it is possible to shutdown a KDE 4 session programmatically. The obvious solution is “sudo shutdown -h now”, but this requires me to enter my root password. The manpage shutdown(8) mentions a file /etc/shutdown.allow which could define users allowed to shutdown the machine, but this does not seem to work. (I put myself into that file, and shutdown keeps telling me that I must be root to do that.)

That was too much of a hassle for me, so I looked for a KDE-ish solution to the problem. And whenever you need to access KDE functionality from the command line, DBus is your friend. I quickly found on the session bus the org.kde.ksmserver service, which contains no shutdown() method, but a logout() method. Technically, both things are fairly similar, so let’s look into this method: Okay, it takes three int parameters. What would MacGyver do now?

I eventually found what these parameters are. Reading the code of KSMServer and the KWorkspace library, the three parameters are values from the enumerations KWorkspace::ShutdownConfirm, KWorkspace::ShutdownType, KWorkspace::ShutdownMode (in that particular order). The possible values for these enumerations can be found in the API documentation for KWorkspace. For example, to shutdown your machine from the command line, say:

$ qdbus org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 2 2

The parameters mean that, without confirmation (the 0), the machine should be shut down (the first 2) immediately (the second 2). So if you ever wanted e.g. to shutdown your machine from remote, now you know how to do it. (Perhaps this could be put on one of our wikis, but I’m unsure which one of Techbase and Userbase is the right one, and where to put it there.)

Update 1: Milian Wolff correctly mentioned in the comments that KShutdown simplifies this task very much. I had also used KShutdown in KDE 3, but had forgotten about it because the port was not done when I switched to KDE 4 as my main desktop.

Update 2: A commenter asked for a more detailed guide on how to get to such information. As an example, I’ll show you how to find the command that toggles KWin’s compositing: (I know of Alt-Shift-F12, but one might want to do this in a script)

  1. Call qdbus without parameters to get a list of all registered services. Tthe numerical names such as “:1.42” can be ignored, as most programs register more readable names such as “org.kde.ksmserver. Some of thesed named services have some numerical suffix, this is the process ID for applications which can have multiple instances at once.
  2. When you’ve found the right service, give its name as the first parameter to qdbus. In this example, you would then invoke “qdbus org.kde.kwin”. qdbus will now print all interfaces in this service. All KDE applications have a “/MainApplication” interface to control the application in a generic name. (This generic interface is used by kquitapp, for instance.)
  3. Pass the name of the right interface (“/KWin” in our case) as the second parameter to qdbus. Now, you’ll see an extensive list of all methods and signals that this interface provides. While signals allow the service to pass information to its clients, methods allow to invoke certain things in the service. In our case, the right method is:

    method Q_NOREPLY void org.kde.KWin.toggleCompositing()
  4. Add the name of the method, which is “org.kde.KWin.toggleCompositing” in the above example, as the third and last parameter to your final qdbus call. If the method in question has arguments (like the above “org.kde.KSMServerInterface.logout” method), give these in the right order as further arguments. (Of course, you have to know what these parameters mean, which was not that apparent in the KSMServer case.)

14 Responses to “Shutdown your machine automatically (or from remote)”

  1. jiveaxe Says:

    I have a newbie question: how did you found the org.kde.ksmserver service, in some docs or with a console command.
    By the way, very interesting article.

  2. Milian Wolff Says:

    You could just use kshutdown for that 😉

  3. Chris Says:

    I use “sudo pm-suspend” to shut down my computer remotely. In the sudoers file, the command is configured to be issued without asking for the password. Additionally, I’ve set up wake-on-lan, so I can send my computer to sleep and wake up remotely whenever I need it.

    • Stefan Says:

      On my suse it spells
      powersave -u for suspend to RAM resp.
      powersave -U for suspend to disk.
      And I cannot imagine for which I should shutdown my machine completely.

      Or wait,
      in case in case of emergency (KDE/kwin/plasma/dbus not responsive) I sometimes have to resort to
      sudo rckdm restart
      which basically has mostly the same effects as shutting down the X server (Ctrl-Alt-Backspace for about 5 seonds).

    • Niall Says:

      I using something similar but noted that it leaves my remote shell stuck so now use:

      nohup sleep 30 && sudo pm-suspend

      which gives me a chance to logout first.

  4. Ahmed Kamal Says:

    For anyone wanting more info on qdbus, may I suggest the following article

  5. Frank Says:

    in my manpage to shutdown I have a /etc/shutdown.allow, but I have to explicitly say I want to use it via ‘shutdown -a’.

    Next is, that you can have programs started from sudo without asking for password. You just have to add in /etc/sudoers
    user ALL=NOPASSWD: /sbin/shutdown

    But I guess your dbus method is more elegant and clean, because kde gets said to do a shutdown and can act different from the machine just going down…

    BTW: Who want’s to shutdown his computer anyway? 😉

  6. seezer Says:

    Thanks for searching the correct parameters. Wanted to know that for a long time..

    To search for the correct service/interface, i can only suggest giving qdbusviewer a try.

  7. notoveryet Says:

    I’m running KDE trunk (KDE 4.3.61) right now….
    my shutdown, logout and shutdown buttons from the menu (even power button) are not working….they just don’t do anything…
    i tried to send message to ksmserver via dbus from CLI (the way you suggested), still the same result…
    do you have any clue…what could be wrong?

    Thanks in advance,

    • Stefan Majewsky Says:

      Not really. This regression seems to relate to ksmserver and powerdevil, but I’m not on track about the recent developments there.

  8. jos van riswick Says:

    how do I find out what arguments are valid for the methods?

    I want to set the opacity of a window so maybe

    qdbus org.kde.kwin /KWin org.kde.KWin.reconfigureEffect and then what?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s