reassign 562026 consolekit 0.4.1-2
tags 562026 + patch
thanks
After some hours of debugging, I finally found the cause of this bug. It is a
race condition, so no wonder why it is only reproducable on some systems.
What happens is:
1) kdm (or whatever else, I can even reproduce the bug with dbus-send) tries
to call a method from the /org/freedesktop/ConsoleKit/Manager object, using
the org.freedesktop.ConsoleKit.Manager interface.
2) ConsoleKit is not running, so dbus-daemon activates it.
3) console-kit-daemon starts and registers the service.
4) dbus-daemon recognizes the service registration, tries to find the Manager
object, fails, returns error.
5) console-kit-daemon registers the Manager object at the same time that dbus-
daemon returns the error.
Second call to the same method obviously succeeds.
Now if you are lucky the kernel scheduler gives some more time to console-kit-
daemon before it switches back to executing dbus-daemon code, it will succeed.
I guess there was a change in the scheduler of linux 2.6.32 that made this bug
more easy to spot.
So, I have modified console-kit-daemon a bit, so that it registers Manager
before it registers the service name and it works fine. Patch attached.
Regards,
George
PS: This patch of course requires 04-defer_daemonizing.patch from the
consolekit packaging to be applied as well.
This is to register the Manager object on dbus before registering
the service name, so that when calling a method on Manager and
dbus has to activate ConsoleKit, the Manager is available immediately
after the service registration. Otherwise, the remote method call
will fail with a message saying that the Manager interface doesn't exist.
This is a race condition and may not be reproducable on all systems.
Index: consolekit/src/main.c
===================================================================
--- consolekit.orig/src/main.c 2009-12-30 17:17:05.000000000 +0200
+++ consolekit/src/main.c 2009-12-30 17:17:36.000000000 +0200
@@ -338,6 +338,12 @@
goto out;
}
+ manager = ck_manager_new ();
+
+ if (manager == NULL) {
+ goto out;
+ }
+
if (! acquire_name_on_proxy (bus_proxy) ) {
g_warning ("Could not acquire name; bailing out");
goto out;
@@ -353,12 +359,6 @@
create_pid_file ();
- manager = ck_manager_new ();
-
- if (manager == NULL) {
- goto out;
- }
-
loop = g_main_loop_new (NULL, FALSE);
g_signal_connect (bus_proxy,