[rfc] ConsoleKit enhancements

David Zeuthen david at fubar.dk
Fri Feb 9 16:35:09 PST 2007


Hey,

So I was thinking about some of the races that Bill brought up in
another thread and I think we need some kind of interface to allow
applications to sanely and race-free release/acquire resources on
session switching. 

The idea I've got includes adding these methods and signals to the
Session interface

 signals:
   signal ActiveChanging (bool is_being_activated,
                          bool finished_suspending, 
                          string cookie2)
     If is_being_activated==FALSE and finished_suspending=FALSE it means
     the session is about to be suspended; 
     If is_being_activated==TRUE and finished_suspending=FALSE it means
     the session is about to be activated; 
     If finished_suspending==TRUE it means that the session is now
     suspended.

     It is the responsibility of registered handlers, see below, to
     always respond to this signal using ActivationHandlerDone(), see
     below.

 methods:
   string RegisterActivationHandler ()
     Register with the system; returns a cookie

   void ActivationHandlerDone (string cookie, string cookie2)
     Every caller that have registered with RegisterActivationHandler()
     needs to call this method with a) the cookie he obtained from 
     RegisterActivationHandler() and b) the cookie obtained from
     the ActiveChanging() signal. 

So the idea is simply that an app can register with ConsoleKit to do
stuff at three different times at the time of switching from one session
to another; namely

 - when a session transitions from active to inactive
 - the small period when no session is active
 - when a session transitions from inactive to active

This is useful in the following cases.

 - HAL will use this to ensure that ACL's are set / remove on device
   files. When we get revoke() we can use it to revoke access and
   thereby crash apps :-)

 - g-p-m can use this to a) save state (e.g. LCD brightness); and b)
   restore it again without having several instances racing for it

 - Things like PulseAudio can use it to release the device device file
   before another instance tries to open it (most sound cards only
   allow one opener)

 - An animation client, in some star trek future, see
   http://keithp.com/blog/kernel-mode-drivers.html
   can hook into this to provide animations

The workflow will look like this

 o  Session A active: has gpm_a and pa_a (gnome-power-manager and
    PulseAudio); both have registered with CK on Session A
 o  Session B inactive: has gpm_b and pa_b; both have registered with CK
    on Session B
 o  HAL have registered with CK for all sessions

 o  user wants to switch to session B

 o  CK emits ActiveChanging (FALSE, FALSE, "1234") on session A

 --- session A is now suspending ---

 o  gpm_a sees this, saves the LCD backlight and calls 
    ActivationHandlerDone("cookie_obtained by gpm_a", "1234") on CK
 o  pa_a sees this too, closes fd's for files in /dev/snd/* and calls
    ActivationHandlerDone("cookie_obtained by pa_a", "1234") on CK.
 o  HAL sees this too and revoke ACL's for some device files that was
    granted to the user in session A. Then HAL calls
    ActivationHandlerDone("cookie_obtained by HAL for session A",
    "1234") on CK

 o  CK sees that all ActivationHandlers are finished for "1234" and
    emits ActiveChanged (FALSE) on A. CK now also emits
    ActiveChanging(FALSE, TRUE, "1235") on A

 --- session A is now fully suspended ---

 o  HAL sees this and calls revoke() (see
    http://lwn.net/Articles/192632/ for details; notably we want a
    revoke() that only revokes access for a certain user / session / set
    of processes) on all the devices we removed ACL's from. When this
    is complete then HAL calls
    ActivationHandlerDone("cookie_obtained by HAL for session A",
    "1235") on CK
 o  Some mythical animation client hooks in and starts a smooth
    animation from session A to session B on the given seat; e.g.
    rotating cube or whatever. When the animation client is done
    it calls
    ActivationHandlerDone("cookie_obtained by Animation Client for
    session A", "1235") on CK

 o  CK sees that all ActivationHandlers are finished for "1235"
    CK now emits ActiveChanging(TRUE, FALSE, "1236") on B.

 --- session B is now resuming ---

 o  gpm_b sees this, does nothing, and calls
    ActivationHandlerDone("cookie_obtained by gpm_b", "1236") on CK
 o  pa_b sees this too, does nothing, and calls
    ActivationHandlerDone("cookie_obtained by pa_b", "1236") on CK
 o  HAL sees this too and grants ACL's for some device files for the
    user in session B. Then HAL calls
    ActivationHandlerDone("cookie_obtained by HAL for session B",
    "1236") on CK

 o  CK sees that all ActivationHandlers are finished for "1236" and
    emits ActiveChanged (TRUE) on B. CK now also emits an
    ActiveSessionChanged signal on the Seat the session belong to.

 --- session B is now resumed ---

 o  gpm_b sees this, restores LCD backlight
 o  pa_b sees this too and opens device files in /dev/snd/* 

 --- Done ---

We probably want a timeout of 2-5 seconds to ensure that
ActivationHandlers cannot lock up the system; if some ActivationHandler
isn't responding we'll log a message in the syslog (including details
like /proc/<pid>/exe) and ignore him going forward.

I really think we need something like this. Perhaps my API above isn't
perfect; I welcome comments :-) - Thoughts?

     David




More information about the hal mailing list