After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 535829 - allow using D-Bus as session management mechanism
allow using D-Bus as session management mechanism
Status: RESOLVED FIXED
Product: gnome-session
Classification: Core
Component: gnome-session
git master
Other Linux
: Normal normal
: ---
Assigned To: Session Maintainers
Session Maintainers
Depends on:
Blocks:
 
 
Reported: 2008-05-30 18:45 UTC by William Jon McCann
Modified: 2008-08-04 23:39 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description William Jon McCann 2008-05-30 18:45:45 UTC
So for some/many/all apps the only things that they need from a session management framework are:

 * Start
 * Stop
 * Stay running

In these cases, using XSMP is not necessary.  It would be nice to allow such applications to use D-Bus directly. For example, we'd need:

 * Start - use D-Bus activation and provide a way for the application to advertise a method for the session manager to call
 * Stop  - provide a way for the application to advertise a method for the session manager to call - and rely on the application to handle it and exit
 * Stay running - Provide a way for the application to request that it be kept running

My proposal is for the application to provide the following keys in the autostart .desktop file:

X-DBus-Name:
X-DBus-Path:
X-DBus-Interface:
X-DBus-Method-Start:
X-DBus-Method-Stop:

And when X-GNOME-AutoRestart is enabled we watch for NameOwnerChanged to indicate the service stopped and do Start again.

Thoughts?
Comment 1 William Jon McCann 2008-06-10 14:44:02 UTC
Does this sound reasonable?  Better ideas?
Comment 2 Marco Pesenti Gritti 2008-06-10 16:59:24 UTC
Some questions and comments follows. Keep in mind that my experience with session management is *very* limited. I'm interested in this because I'd like to reuse the protocols (and hopefully bits of the implementation) in Sugar.

The system you are proposing is actually very similar to the application launching mechanism I had initially implemented for Sugar. We replaced it mainly because we needed to run multiple applications instances in different processes.

> * Start - use D-Bus activation and provide a way for the application to
> advertise a method for the session manager to call

Can we actually depend solely on D-Bus activation?

* Some applications might want to run multiple instances in different processes.
* When you run an application from the command line you will want the Stop method to work, so I guess we will need some sort of runtime "registration" mechanism.

> X-DBus-Interface:
> X-DBus-Method-Start:
> X-DBus-Method-Stop:

What is the use case of specifying Start/Stop methods? At first sight specifying an interface seem like it would be enough.
Comment 3 William Jon McCann 2008-06-10 18:23:03 UTC
Thanks for the comments Marco.

Right, I should have mentioned that the above proposal would only be to support single instance applications.  I think it makes sense to use the D-Bus registration mechanism for those apps that support it since that is really the only way to do it in a race free way.  For multiple instance applications we would need a separate registration mechanism.

Starting single instance apps from the command line would still work because we'd simply skip the start step and begin monitoring the lifecycle once the name appears on the bus.

Now for a registration mechanism (for multiple instance apps) we could just expose the following:

org.freedesktop.SessionManager.RegisterClient()
org.freedesktop.SessionManager.UnRegisterClient()

And you can monitor the sender's bus address (eg. :132) for changes.

Now if we still want to support session saving stuff (and I'm not sure it is all that useful) then we could just have org.freedesktop.SessionManager emit SaveSession signals on the bus.  If we want to support something like delaying logout then we could have something like:
org.freedesktop.SessionManager.DelayLogout()

Which an application could send back to the session manager in response to a org.freedesktop.SessionManager.LogoutBegin signal.  The delay logout request would advise the session manager to wait a few seconds before logging out.  We should only honor these types of requests for a short time (or not at all, based on a gconf key).


I think that is pretty simple and covers all or most of the useful parts of xsmp.  What do you think?
Comment 4 Marco Pesenti Gritti 2008-06-10 18:49:14 UTC
(In reply to comment #3)
> Now for a registration mechanism (for multiple instance apps) we could just
> expose the following:
> 
> org.freedesktop.SessionManager.RegisterClient()
> org.freedesktop.SessionManager.UnRegisterClient()
>
> And you can monitor the sender's bus address (eg. :132) for changes.

Make sense to me.
 
> Now if we still want to support session saving stuff (and I'm not sure it is
> all that useful) then we could just have org.freedesktop.SessionManager emit
> SaveSession signals on the bus.  If we want to support something like delaying
> logout then we could have something like:
> org.freedesktop.SessionManager.DelayLogout()
> 
> Which an application could send back to the session manager in response to a
> org.freedesktop.SessionManager.LogoutBegin signal.  The delay logout request
> would advise the session manager to wait a few seconds before logging out.  We
> should only honor these types of requests for a short time (or not at all,
> based on a gconf key).

What about the case where an applications needs to request some user action before it can quit? (saving file for example).

Comment 5 William Jon McCann 2008-06-10 19:09:49 UTC
Yeah, that's the DelayLogout case.  The application could request a "stay of execution".  But it should not be able to block forever.  If they don't get the user input they want then they should deal with it.  At one point Windows allowed applications to block actions and it was abused - so they removed that ability.

Another reason why we shouldn't block the action is that the user may not even be at the console.  Take for example, the FUS case where the logout is initiated by another user.
Comment 6 Marco Pesenti Gritti 2008-06-10 19:13:01 UTC
(In reply to comment #5)
> Yeah, that's the DelayLogout case.  The application could request a "stay of
> execution".  But it should not be able to block forever.  If they don't get the
> user input they want then they should deal with it.  At one point Windows
> allowed applications to block actions and it was abused - so they removed that
> ability.

Yeah, make sense.

Sounds like a pretty good start to me :)
Comment 7 Lucas Rocha 2008-06-10 22:17:14 UTC
Hi guys, first of all, thanks for the heads up on this front. :-)

Here are some comments/suggestion/notes/etc:

The session manager never runs apps through D-Bus activation because if we do that the app will not inherit important environment variables from the running session (which are defined on initialization phase by gnome-keyring, at-spi, bug-buddy, etc after d-bus daemon is started). This is an issue that was kind of discussed in D-Bus mailing list already[1]. This means that the "Start" method is not really needed or wanted here (unless there's a solution for that problem). In gnome-session we basically spawn apps and wait to request to register a client on session manager.

Therefore, what I would suggest is the following protocol setup:

1. gnome-session spawns an app and expect to receive an async RegisterClient(char *client_id) call from the app (this call should be done as soon as possible in the app side). The RegisterClient call should return the registered client_id which is not necessarely the requested one (as there might be clashes or whatever). The client on app side should use the returned client_id from now on, not the requested one. After that, session manager has a new registered session client;
2. if gnome-session wants to simply terminate a client for some reason, it can just call Die D-Bus method on client (you proposed Stop but I think Die is nicer :-P);
3. The session client should call SetClientAutorestart(char *client_id, boolean autorestart) D-Bus method on session manager (after it's fully registered) to define if it should automatically restart in case it disconnects from session manager for some reason;
4. The session client should call SetClientRestartCommand(char *client_id, char *command) D-Bus method on session manager (after it's fully registered) to define its restart command which will be used when restarting apps when they die or when resuming a saved session;
5. As for the state saving and logout, we could follow a similar but much simpler aproach than XSMP. This is something that needs much more thinking though. I suggest you to focus on having the basic session manager and client protocol working. We can continue discussion here about this (tricky) topic anyway. :-)

2 and 3 could be merged in one generic SetClientProperty method but I thought it would be more clear and effective to have specific methods for them.

Some important source code links:

1. It would be nice if you could implement the client part as the d-bus implemention of EggSMClient. Have a look at eggsmclient* in:
http://svn.gnome.org/svn/gnome-session/trunk/egg/

2. To implement D-Bus-based session client support in new gnome-session, you would basically have to implement a GsmClientDBus. Have a look at GsmClientXSMP in:
http://svn.gnome.org/svn/gnome-session/trunk/gnome-session/client-xsmp.c

3. You will have to implement the additional D-Bus bits here:
http://svn.gnome.org/svn/gnome-session/trunk/gnome-session/dbus.c

I would really like to get some input from Dan too.

[1] http://lists.freedesktop.org/archives/dbus/2008-May/009755.html
Comment 8 Dan Winship 2008-06-11 00:21:34 UTC
(In reply to comment #7)
> The session manager never runs apps through D-Bus activation because if we do
> that the app will not inherit important environment variables from the running
> session (which are defined on initialization phase by gnome-keyring, at-spi,
> bug-buddy, etc after d-bus daemon is started). This is an issue that was kind
> of discussed in D-Bus mailing list already[1]. This means that the "Start"
> method is not really needed or wanted here (unless there's a solution for that
> problem).

I think we probably need to solve that problem anyway. (It has a new manifestation in 2.22, which is that apps launched from D-Bus don't have access to gnome-keyring-daemon's SSH agent.)

Also, it would be nice if all of the logic for D-Bus-based .desktop file launching just went into EggDesktopFile/GnomeDesktopItem/whatever, so that other apps would acquire the same smarts automatically as well.

> Therefore, what I would suggest is the following protocol setup:

Blah. Too XSMP-like. :)

If apps want to do something that's like XSMP, then they should just use XSMP, because that's already supported by GNOME, KDE, and XFCE. If they want to do something that *isn't* like XSMP, then we're not helping them by making an XSMP-like API.

I don't think Jon needs session saving or logout management for his use cases, so I think we can punt this issue for now.

> 2. if gnome-session wants to simply terminate a client for some reason, it can
> just call Die D-Bus method on client (you proposed Stop but I think Die is
> nicer :-P);

AFAIR, we never use SmsDie() except at logout time, which we already have a different way of handling over D-Bus (the SessionOver signal). I really don't think we need an explicit way for the SM to kill an app.

(In reply to comment #5)
> Yeah, that's the DelayLogout case.  The application could request a "stay of
> execution".  But it should not be able to block forever.  If they don't get the
> user input they want then they should deal with it.  At one point Windows
> allowed applications to block actions and it was abused - so they removed that
> ability.

Sort of. I'm not sure about Vista, but in XP, if an app doesn't acknowledge the logout request without a certain time limit (eg, because it has a save dialog open), then Windows will pop up a "some app is blocking logout, do you want to kill it" dialog.

However, Jon's right that doing that sort of thing is at least deprecated, and the recommended API for things that want to inhibit logout is to make some call like:

  Win3264ExtSetForbidShutdownReasonEx_W (my_app_handle, "Nautilus is burning a CD.")

which then tweaks the behavior of the logout dialog.

> Another reason why we shouldn't block the action is that the user may not even
> be at the console.  Take for example, the FUS case where the logout is
> initiated by another user.

Well... there are two plausible options regarding FUS and session management:

    1. Completely ignore it
    2. Completely redesign our state-saving infrastructure

It doesn't make any sense to talk about making that case work "within the existing model", because it can't; you'd need to change every single app to autosave its state constantly, or to be able to save its state without interacting with the user, and at that point, you're not in the existing model any more.
Comment 9 Lucas Rocha 2008-06-11 08:03:26 UTC
(In reply to comment #8)
> (In reply to comment #7)
> > The session manager never runs apps through D-Bus activation because if we do
> > that the app will not inherit important environment variables from the running
> > session (which are defined on initialization phase by gnome-keyring, at-spi,
> > bug-buddy, etc after d-bus daemon is started). This is an issue that was kind
> > of discussed in D-Bus mailing list already[1]. This means that the "Start"
> > method is not really needed or wanted here (unless there's a solution for that
> > problem).
> 
> I think we probably need to solve that problem anyway. (It has a new
> manifestation in 2.22, which is that apps launched from D-Bus don't have access
> to gnome-keyring-daemon's SSH agent.)
> 
> Also, it would be nice if all of the logic for D-Bus-based .desktop file
> launching just went into EggDesktopFile/GnomeDesktopItem/whatever, so that
> other apps would acquire the same smarts automatically as well.

Agree.

> > Therefore, what I would suggest is the following protocol setup:
> 
> Blah. Too XSMP-like. :)

Oops, you got me. :-) Maybe I ended up falling in love with XSMP hehe.

> If apps want to do something that's like XSMP, then they should just use XSMP,
> because that's already supported by GNOME, KDE, and XFCE. If they want to do
> something that *isn't* like XSMP, then we're not helping them by making an
> XSMP-like API.
>
> I don't think Jon needs session saving or logout management for his use cases,
> so I think we can punt this issue for now.

If it's just about stuffing some bits in session manager to allow D-Bus based apps to start on session startup and stop on session over, we're almost done already. For starting, we simply spawn a process but we'd need a way to know if the client is fully set. I proposed the XSMP-ish RegisterClient (which would make it easy to integrate on current code base) but I'm open for suggestions. We could just wait the app to acquire a D-Bus name for example. For stopping, we have SessionOver signal. The only missing part is the "stay running" (in which case we'd still need to have a way to tell the session manager how to handle that client).

> > 2. if gnome-session wants to simply terminate a client for some reason, it an
/> > just call Die D-Bus method on client (you proposed Stop but I think Die is
> > nicer :-P);
> 
> AFAIR, we never use SmsDie() except at logout time, which we already have a
> different way of handling over D-Bus (the SessionOver signal). I really don't
> think we need an explicit way for the SM to kill an app.

Indeed.

> (In reply to comment #5)
> > Yeah, that's the DelayLogout case.  The application could request a "stay of
> > execution".  But it should not be able to block forever.  If they don't get the
> > user input they want then they should deal with it.  At one point Windows
> > allowed applications to block actions and it was abused - so they removed that
> > ability.
> 
> Sort of. I'm not sure about Vista, but in XP, if an app doesn't acknowledge the
> logout request without a certain time limit (eg, because it has a save dialog
> open), then Windows will pop up a "some app is blocking logout, do you want to
> kill it" dialog.
> 
> However, Jon's right that doing that sort of thing is at least deprecated, and
> the recommended API for things that want to inhibit logout is to make some call
> like:
> 
>   Win3264ExtSetForbidShutdownReasonEx_W (my_app_handle, "Nautilus is burning a
> CD.")
> 
> which then tweaks the behavior of the logout dialog.

Makes sense.

> > Another reason why we shouldn't block the action is that the user may not even
> > be at the console.  Take for example, the FUS case where the logout is
> > initiated by another user.
> 
> Well... there are two plausible options regarding FUS and session management:
> 
>     1. Completely ignore it
>     2. Completely redesign our state-saving infrastructure
> 
> It doesn't make any sense to talk about making that case work "within the
> existing model", because it can't; you'd need to change every single app to
> autosave its state constantly, or to be able to save its state without
> interacting with the user, and at that point, you're not in the existing model
> any more.

I would say: let's do 1 for 2.24. Start doing 2 for 2.26 :-P
Comment 10 Vincent Untz 2008-06-12 11:10:34 UTC
May I suggest that we also talk to KDE people about this? :-)
Comment 11 Vincent Untz 2008-06-12 11:30:21 UTC
I briefly discussed this with Lubos (who's doing the KDE session management stuff), and he'd like to see some discussion happening on a mailing list about a new dbus-based protocol (like xdg).
Comment 12 William Jon McCann 2008-06-25 15:49:25 UTC
I've made pretty good progress on the following branch:
http://svn.gnome.org/viewvc/gnome-session/branches/dbus_based/

It has a SM server side API:
http://svn.gnome.org/viewvc/gnome-session/branches/dbus_based/gnome-session/gsm-manager.xml?view=markup


This is dogfoodable at this point so please give it a try.  Check out the two test programs test-method-client and test-inhibit.  After you run the test-inhibit program select Log Out from the menu and then click the Log Out button.  When you do you will see another window that warns you that you have a program still running.  This is similar to the dialogs seen here:
http://www.developer.com/net/cplus/print.php/3647411

And uses an API and methodology similar to what is described here:
http://msdn.microsoft.com/en-us/library/ms700677(VS.85).aspx
Comment 13 William Jon McCann 2008-08-04 23:39:40 UTC
While we haven't finalized or standardized an API we now have this capability.  I'll mark this as fixed.

Please see http://live.gnome.org/SessionManagement/GnomeSession for some details.