[systemd-devel] dbus-1/kdbus - question about 'queued owners'
Lukasz Skalski
l.skalski at samsung.com
Fri Apr 10 07:20:28 PDT 2015
Hi,
Currently I'm working on some testsuite (let's call it dbus1-spec-test)
for dbus-1 specification. My idea is to test dbus-1 specification
coverage on systems with dbus-daemon and on systems without dbus-daemon
(but with latest systemd, bus-proxyd and kdbus) which will allow us (and
all userspace apps) to smoothly switch to kdbus. First results of tests
are really good:
Run Summary: Type Total Ran Passed Failed Inactive
suites 11 11 n/a 0 0
tests 34 34 33 1 0
asserts 286 286 285 1 n/a
My testsuite have found only one inconsistency between dbus-1 and
kdbus-enabled system. Problematic testcase (this one tests rather some
dbus-daemon/bus-proxyd behaviors than specification) is as follow:
test_request_name_6 (void)
{
GDBusConnection *connection_a;
GDBusConnection *connection_b;
BusRequestNameFlagsReply request_reply;
BusReleaseNameFlagsReply release_reply;
/* connect and set up two D-Bus client connections */
connection_a = connect_to_bus();
connection_b = connect_to_bus();
/* 'connection_a' - synchronously acquire name on the bus */
request_reply = request_name (connection_a, "org.my.busname",
DBUS_NAME_FLAG_REPLACE_EXISTING |
DBUS_NAME_FLAG_DO_NOT_QUEUE);
/* 'connection_a' should be primary owner */
CU_ASSERT (request_reply == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
/* 'connection_b' tries to own the same well-known name */
request_reply = request_name (connection_b, "org.my.busname",
DBUS_NAME_FLAG_REPLACE_EXISTING);
/* 'connection_b' should be appended to the queue */
CU_ASSERT (request_reply == DBUS_REQUEST_NAME_REPLY_IN_QUEUE);
/* once again 'connection_b' tries to own the same name */
request_reply = request_name (connection_b, "org.my.busname",
DBUS_NAME_FLAG_REPLACE_EXISTING);
/* and once again we should get the same return code */
CU_ASSERT (request_reply == DBUS_REQUEST_NAME_REPLY_IN_QUEUE);
/* 'connection_a' releases name */
release_reply = release_name (connection_a, "org.my.busname");
CU_ASSERT (release_reply == DBUS_RELEASE_NAME_REPLY_RELEASED);
/* 'connection_b' (now primary owner) also release name
release_reply = release_name (connection_b, "org.my.busname");
CU_ASSERT (release_reply == DBUS_RELEASE_NAME_REPLY_RELEASED);
/* 'connection_b' tries to release once again the same name */
release_reply = release_name (connection_b, "org.my.busname");
/* This assert is source of failure - what we should get
here: REPLY_RELEASED or NON_EXISTENT ? */
CU_ASSERT (release_reply == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT);
g_object_unref (connection_a);
g_object_unref (connection_b);
}
I think that code comments explain scenario of this test quite well. In
this testcase I create two D-Bus client connections. Both connections
request the same well-known name on bus. 'connection_a' becomes primary
owner of the name. Because name replacement is not possible,
'connection_b' is appended to the queue. Next, 'connection_b' once again
tries to own the same name and once again we have 'IN_QUEUE' as a return
code. After this, 'connection_a' releases previously owned name. Now
primary owner of "org.my.busname" name is 'connection_b'. First
'ReleaseName' returns RELEASED as it was expected. Inconsistency between
dbus-daemon and kdbus has place when 'connection_b' once again tries to
release "org.my.busname" name. After last 'ReleaseName' dbus-daemon
returns NON_EXISTENT. In case of kdbus/bus-proxyd, we have RELEASED
return code (if we add next/third 'ReleaseName' call for 'connection_b'
it will return NON_EXISTENT) - it causes problems with last assert().
The main source of above problem is difference how dbus-daemon and kdbus
handles placing the same connection in queue two times for the same
well-know name.
Which solution, kdbus or dbus-daemon, do it correctly?
--
Lukasz Skalski
Samsung R&D Institute Poland
Samsung Electronics
l.skalski at samsung.com
More information about the systemd-devel
mailing list