[RFC]: Enhanced User Sessions and session shutdown
James Hunt
james.hunt at ubuntu.com
Thu Jan 24 14:18:14 UTC 2013
Hi Steve,
On 24/01/13 07:25, Steve Langasek wrote:
> Hi James,
>
> On Fri, Jan 18, 2013 at 05:35:45PM +0000, James Hunt wrote:
>> I've recently updated the spec above to include details of session shutdown [1].
>> If anyone has comments, please weigh in:
>
>> https://wiki.ubuntu.com/FoundationsTeam/Specs/RaringUpstartUserSessions#Desktop_Session_Shutdown
>
>> Note that on Ubuntu, when the gnome-session job ends, gnome-session will
>> potentially first signal ConsoleKit to shutdown the system. This will ultimately
>> result in the display manager (lightdm on Ubuntu) sending SIGTERM to each
>> Session Init [2] which should preclude the need for a final "shutdown" job that
>> reacts to the session-exiting event, although it may be necessary to modify the
>> 'kill timeout' for the lightdm job.
>
> You write here:
>
> With Upstart sessions, the Session Init will be terminated by:
>
> * The desktop session sending an initctl command request to shutdown.
> * The Session Init Instance will react to this, stop all the jobs and
> then exit itself, closing the session in the process.
>
> I don't think that's accurate. The decision about whether or not the system
> can be shutdown/rebooted by the user needs to be made via system-level
> policy; the shutdown request thus needs to be referred to a system-level
> service before we shut down *any* jobs from the session init.
I think there is some confusion here between session end and system shutdown.
The 2 bullets you're referencing are under the heading 'Desktop Session
Shutdown', not 'system shutdown'. To be clear the 'initctl shutdown' command is
a request to shutdown the Session Init, but in certain circumstances (where
--type is 'shutdown' or 'reboot'), that action may also trigger a system shutdown.
I think the confusion has arisen as I didn't qualify that 'shutdown' refers to
the *session* (not the system) in that first bullet. I've now clarified that in
the spec.
> Only once the system init has been signalled to change runlevels via the
> shutdown command, and the lightdm service has been asked to stop, should the
> session init start generate a session-end event (in response to being
> signalled itself).
Right, but this does not handle the case where the user simply "logs out".
>
> So the first half of the architecture should remain entirely unchanged, we
> only want to switch out some of the components:
>
> * The indicator, or the power button dialog calls 'initctl shutdown' with
> the correct logout, reboot, or shutdown '--type' argument.
> * The session init checks whether the shutdown has been blocked with the
> org.gnome.SessionManager.Inhibit() D-Bus API call (which something
> associated with the upstart session will need to implement).
This would have to be handled by either a job or some sort of bridge to avoid
making Upstart itself dependent on Gnome (that's why the current spec allows
gnome-session to continue to handle the inhibiting bits itself).
> * Once the shutdown is not blocked, on shutdown/reboot:
> * the session init, or a job acting on its behalf, calls the
> corresponding method of ConsoleKit or systemd.
Again, the spec allows a job to perform this action.
> * ConsoleKit ultimately calls /usr/lib/ConsoleKit/scripts/ck-system-stop,
> which in turn calls shutdown(8).
> * shutdown(8) emits the "runlevel" Upstart event.
> * This triggers stopping of the lightdm jobs (among others)
> * The lightdm job sends SIGTERM to all clients (upstart session init
> processes).
> * The session init generates a session-end event, which is processed
> normally.
> * Either the user jobs correctly end in a timely manner in response to
> this event; or they do not, in which case they are instead reaped by
> /etc/init.d/sendsigs.
I'm not clear what you mean here - are you saying that the Session Init should
*not* send any signals to running jobs? If so, this could only work for the
shutdown/reboot scenario (for logout we still need to honour kill_timeout). It
also means that any jobs which do not specify 'stop on' will linger
unnecessarily long. Note too that even in the shutdown/reboot scenario, if we
just wait to die, we're still going to artificially slow down the shutdown since
lightdm will wait 5 seconds for its clients to die. Since that value is the same
as the lightdm kill timeout, we could therefore cause a delay of that many
seconds where we could potentially exit a lot sooner.
There should not be any need for complex
> timeout handling in the session init itself.
The reason for this is threefold:
- it allows upstart to give each job its allocated kill timeout before sending
SIGKILL.
- it allows for a faster shutdown.
- it ensures that the Session Init doesn't wait forever to shutdown (except
where explicitly requested by $WAIT).
(Note however that
> /etc/init.d/sendsigs probably needs some changes in order to not go
> killing user jobs - and session init processes - with *no* delay,
> depriving them of the opportunity to shut down gracefully.)
> * If all session jobs exit and the session init is quiesced (i.e., no
> remaining "blocked" events), the session init exits. Otherwise, it
> will be killed externally (by lightdm or by sendsigs).
Again, this only caters for the system shutdown scenario - we cannot wait
forever for blocked events in the "logout" scenario as those events may never
arrive (for example 'stop on session-end and never-emitted') thus causing the
Session Init to never exit, hence the need for timeouts.
> * lightdm exits.
> * The rest of the shutdown sequence completes.
Another source of confusion is that this doesn't seem to be how it currently
happens in Ubuntu - I raised a bug on gnome-session [1] recently (which does
suggest the system should work as you outline: desktop team investigating).
>
> This architecture has the following important properties:
>
> - We don't assume the shutdown command has been accepted (and start killing
> user jobs in response) until acknowledged as such by a root daemon
> - We preserve the existing interface for inhibiting shutdown that's used by
> existing software
> - We aren't relying on the user's session init to do the cleanup, beyond
> making sure it tells the jobs to shutdown; instead the logic for timeout
> handling is all at the system level, where it needs to be.
>
> Does this make sense?
So, what we're now saying is that for a logout we want to:
(1) stop all running jobs.
(2) exit as quickly as possible, but don't let anything block the exit (unless
explicitly requested with $WAIT).
(3) return control to lightdm.
The current spec handles that I think.
Whereas for a shutdown/reboot we want to:
(a) signal ConsoleKit via a job.
(b) only start the shutdown sequence when signalled by lightdm, indicating that
it is stopping.
(c) exit as quickly as possible, ideally before being SIGKILL'ed by lightdm but
only if $WAIT and the kill timeouts for running jobs permit.
The problems with the shutdown/reboot steps though are:
(*) - $WAIT and kill timeout is ignored: if and when lightdm signals the Session
Init, the window of opportunity to stop all jobs is 5 seconds since:
- lightdm will SIGKILL the Session Init after this period.
- even if lightdm doesn't, the kill timeout for the lightdm job is 5 seconds too
so lightdm will die within 5 seconds regardless.
(*) - how we handle gnome-sessions's Inhibit? We can query if the session is
inhibited, but we're not stopping the gnome-session job yet.
The following suggests we don't have to, but I think we need further input on
this angle:
https://live.gnome.org/SessionManagement/GnomeSession#A5._QueryEndSession
All this aside, the shutdown/reboot scenario is simplified such that we don't
need to re-enable jobs in the quiescent mode (ugly) since the 'shutdown' job can
be run immediately and all this job would do is call the appropriate ConsoleKit
D-Bus API. That job will finish almost immediately as there is no return value
from the CK D-Bus methods to control shutdown.
Kind regards,
James.
[1] - https://bugs.launchpad.net/ubuntu/+source/gnome-session/+bug/1101154
--
James Hunt
____________________________________
http://upstart.ubuntu.com/cookbook
http://upstart.ubuntu.com/cookbook/upstart_cookbook.pdf
More information about the upstart-devel
mailing list