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,

Reply via email to