[gdm-list] ConsoleKit shutdown api



(sent to gdm-list for lack of a better venue to discuss ConsoleKit
development...)

ConsoleKit currently offers a somewhat simplistic API for
shutdown/reboot of the system. While working on the PolicyKit one
conversion of CK and gnome-session, it has become apparent that that
simplistic API is not really sufficient.

Currently, gnome-session does some gymnastics with getting the
PolicyKit privileges beforehand, then saving the
session, then calling Restart, but that doesn't work anymore with PolicyKit 1.

Some things that are not currently supported by the CK shutdown API are:
- Showing a list of currently active sessions (and their status)
- Preventing shutdown when it would interrupt important system processes
- Saving of sessions other than the one that initated the shutdown

I sat down with Jon McCann last week to come up with a proposal that
addresses these deficiencies.


Inhibit API for ConsoleKit
--------------------------

Goal: allow to inhibit shutdown/reboot during uninterruptible system
processes, such as
- disk formatting (inhibitor set by DeviceKit-disks)
- software update (inhibitor set by PackageKit)
- system backup (inhibitor set by backup application)

The api can be very similar to gnome-session inhibit api:
Inhibit/Uninhibit/IsInhibited/GetInhibitors functions
Inhibitor objects
InhibitorAdded/Removed signals

See http://www.gnome.org/~mccann/gnome-session/docs/gnome-session.html#org.gnome.SessionManager


Shutdown API for ConsoleKit
---------------------------

Keep Restart/Stop as they are now, and add a new function

QueryStop (out 'u' can_proceed, out 'u' inhibitors, out 'u' sessions)

can_proceed:
    Returns information about whether privileges are required to
    go ahead:
    * 0: Cannot proceed
    * 1: Extra privileges required; a PolicyKit dialog may be shown
    * 2: No extra privileges required
inhibitors:
    The number of inhibitors
sessions:
    The number of sessions

This function should be called when the users clicks a 'Restart'
button. It is supposed to return enough information for the session
manager to show an inhibit dialog that lists not only applications in
the session itself, but also other sessions and system processes that
might be affected.


ConsoleKit.Session interface extensions
---------------------------------------

StopResponse (in 'b' ok, in 's' reason)

Session managers are supposed to call this in response to QueryStop
and Stop signals,  on 'their' session object.


QueryStop signal

Gets emitted by CK in response to a QueryStop call. Sessions should
handle this by doing their own QueryEndSession dance and reporting
back by calling StopResponse. No dialogs should be shown in response
to this, and no user interaction. Sessions may set inhibitors in
response to signal (so-called just-in-time inhibitors). ConsoleKit
will wait for a short time (X seconds) for the StopResponse calls
before continuing.


Stop signal

Gets emitted by CK in response to a Restart or Stop call. Sessions
should handle this by doing their own EndSession dance, end the
session and report back by calling StopResponse. No user interaction.
ConsoleKit will wait for a short time (X seconds) for the StopResponse
calls before continuing.


IsStopping property

A boolean property that ConsoleKit sets during the Restart/Stop calls.
A typical user for this is gdm, which should not allow any new logins
if a restart is in progress.


Run through
-----------

1) User clicks Shutdown button
2) gnome-session calls QueryStop on CK
3) CK emits QueryStop
4) All sessions do their own QueryEndSession dance
5) All sessions respond back with StopResponse
6) QueryStop call returns telling gnome-session if privileges are
needed and how many inhibitors and sessions there are
7) gnome-session uses GetInhibitors and GetSessions apis to assemble
list of things to show in the inhibit dialog, in addition to its own
inhibitors. Depending on the can_proceed value returned by QueryStop,
the dialog will have a 'Sorry, can't do' text, or a 'Stop' button or a
'Stop anyway...' button.

+-------------------------------------------+
| [II] MyEditor (unsaved changes)        |
| - - - - - - - - - - - - - - - - - - - - - - - - |
| [II] Jon (burning CD)                        |
| [II] Ray (active user)                        |
| [II] David (idle for 2 hours)               |
| [II] Tom (formatting disk)                |
| - - - - - - - - - -  - - -  - - - - - - - - - - |
| [II] System backup                         |
|---------------------------------------------|
| Restarting now wlll disrupt other    |
| users and system processes.          |
| Additional privileges are required.    |
|                                                     |
|            [Cancel] [Restart anyway...]  |
+-------------------------------------------+

8) User does whatever he needs to with the information, like closing
apps, calling fellow users, etc
9) User clicks on 'Stop anyway...'
10) gnome-session calls Stop on CK
11) CK does the PolicyKit dance to get privileges, possibly showing an
auth dialog
12) CK sets the IsStopping property
13) CK emits Stop
14) Sessions do their own EndSession dance
15) Sessions respond back with StopResponse
16) CK shuts down


Notes and open questions
------------------------

- In the single-user case, the QueryStop response would indicate 0
sessions, and the Inhibit dialog would become just the regular inhibit
dialog.

- The password dialog comes up _after_ the inhibit dialog. This is
probably fine, since we have enough in formation in the inhibit dialog
to tell the user that extra privileges will be required.

- What identifying information do we need for CK inhibitors. Are app
name and session id (for the session in which an operation originated)
sufficient ? Are object paths nullable, so that they can be optional ?

- Do we need to register sessions with CK, or is it ok to just
broadcast a signal and match up responses with session ids ?

- Is the summary information (number of inhibitors/sessions) in the
QueryStop response useful ? And is it ok to require session managers
to  collect the necessary information for the dialog itself with
GetInhibitors/GetSessions or should all that information be returned
by QueryStop ?

- Do we need to have an explicit CancelStop signal if the user cancels
in the inhibit dialog or the password dialog ? Do the sessions return
to the 'running' phase on their own after the QueryEndSession dance ?

- What is the deal with the StopResponse 'reason'. How does that
relate to just-in-time inhibitors ?


Matthias


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]