[PATCH] dbus: Flush pending object manager signals in send_message
by Andrew Zaborowski
Make sure the PropertiesChanged and InterfacesAdded/Removed signals
related to one object path are sent to the dbus socket in the order
that they are generated in.
---
ell/dbus-private.h | 2 ++
ell/dbus-service.c | 85 +++++++++++++++++++++++++++++++++++++++---------------
ell/dbus.c | 5 ++++
3 files changed, 68 insertions(+), 24 deletions(-)
diff --git a/ell/dbus-private.h b/ell/dbus-private.h
index 441e668..9ffedb2 100644
--- a/ell/dbus-private.h
+++ b/ell/dbus-private.h
@@ -229,6 +229,8 @@ bool _dbus_object_tree_property_changed(struct l_dbus *dbus,
const char *interface_name,
const char *property_name);
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path);
+
typedef void (*_dbus_name_owner_change_func_t)(const char *name,
uint64_t old_owner,
uint64_t new_owner,
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index 1df8f1b..7212340 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -1024,9 +1024,29 @@ done:
return signal;
}
-static void emit_signals(struct l_idle *idle, void *user_data)
+static bool match_interfaces_added_object(const void *a, const void *b)
+{
+ const struct interface_add_record *rec = a;
+
+ return rec->object == b || !b;
+}
+
+static bool match_interfaces_removed_object(const void *a, const void *b)
+{
+ const struct interface_remove_record *rec = a;
+
+ return rec->object == b || !b;
+}
+
+static bool match_properties_changed_object(const void *a, const void *b)
+{
+ const struct property_change_record *rec = a;
+
+ return rec->object == b || !b;
+}
+
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path)
{
- struct l_dbus *dbus = user_data;
struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
struct interface_add_record *interfaces_added_rec;
struct interface_remove_record *interfaces_removed_rec;
@@ -1034,16 +1054,23 @@ static void emit_signals(struct l_idle *idle, void *user_data)
const struct l_queue_entry *entry;
struct object_manager *manager;
struct l_dbus_message *signal;
+ struct object_node *node = NULL;
+ bool all_done = true;
- l_idle_remove(tree->emit_signals_work);
- tree->emit_signals_work = NULL;
+ if (!tree->emit_signals_work)
+ return;
+
+ if (path)
+ node = _dbus_object_tree_lookup(tree, path);
for (entry = l_queue_get_entries(tree->object_managers); entry;
entry = entry->next) {
manager = entry->data;
- while ((interfaces_removed_rec =
- l_queue_pop_head(manager->announce_removed))) {
+ while ((interfaces_removed_rec = l_queue_remove_if(
+ manager->announce_removed,
+ match_interfaces_removed_object,
+ node))) {
signal = build_interfaces_removed_signal(manager,
interfaces_removed_rec);
interface_removed_record_free(interfaces_removed_rec);
@@ -1052,8 +1079,13 @@ static void emit_signals(struct l_idle *idle, void *user_data)
l_dbus_send(manager->dbus, signal);
}
- while ((interfaces_added_rec =
- l_queue_pop_head(manager->announce_added))) {
+ if (!l_queue_isempty(manager->announce_removed))
+ all_done = false;
+
+ while ((interfaces_added_rec = l_queue_remove_if(
+ manager->announce_added,
+ match_interfaces_added_object,
+ node))) {
signal = build_interfaces_added_signal(manager,
interfaces_added_rec);
interface_add_record_free(interfaces_added_rec);
@@ -1061,10 +1093,14 @@ static void emit_signals(struct l_idle *idle, void *user_data)
if (signal)
l_dbus_send(manager->dbus, signal);
}
+
+ if (!l_queue_isempty(manager->announce_added))
+ all_done = false;
}
- while ((property_changes_rec =
- l_queue_pop_head(tree->property_changes))) {
+ while ((property_changes_rec = l_queue_remove_if(tree->property_changes,
+ match_properties_changed_object,
+ node))) {
if (property_changes_rec->instance->interface->
handle_old_style_properties)
for (entry = l_queue_get_entries(property_changes_rec->
@@ -1089,6 +1125,21 @@ static void emit_signals(struct l_idle *idle, void *user_data)
property_change_record_free(property_changes_rec);
}
+
+ if (!l_queue_isempty(tree->property_changes))
+ all_done = false;
+
+ if (all_done) {
+ l_idle_remove(tree->emit_signals_work);
+ tree->emit_signals_work = NULL;
+ }
+}
+
+static void emit_signals(struct l_idle *idle, void *user_data)
+{
+ struct l_dbus *dbus = user_data;
+
+ _dbus_object_tree_signals_flush(dbus, NULL);
}
static void schedule_emit_signals(struct l_dbus *dbus)
@@ -1347,20 +1398,6 @@ bool _dbus_object_tree_unregister_interface(struct _dbus_object_tree *tree,
return true;
}
-static bool match_interfaces_added_object(const void *a, const void *b)
-{
- const struct interface_add_record *rec = a;
-
- return rec->object == b;
-}
-
-static bool match_interfaces_removed_object(const void *a, const void *b)
-{
- const struct interface_add_record *rec = a;
-
- return rec->object == b;
-}
-
bool _dbus_object_tree_add_interface(struct _dbus_object_tree *tree,
const char *path, const char *interface,
void *user_data)
diff --git a/ell/dbus.c b/ell/dbus.c
index db69c0d..59795a7 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -306,6 +306,7 @@ static uint32_t send_message(struct l_dbus *dbus, bool priority,
{
struct message_callback *callback;
enum dbus_message_type type;
+ const char *path;
type = _dbus_message_get_type(message);
@@ -338,6 +339,10 @@ static uint32_t send_message(struct l_dbus *dbus, bool priority,
return callback->serial;
}
+ path = l_dbus_message_get_path(message);
+ if (path)
+ _dbus_object_tree_signals_flush(dbus, path);
+
l_queue_push_tail(dbus->message_queue, callback);
if (dbus->is_ready)
--
2.9.3
5 years, 3 months
[PATCH] dbus: Flush pending object manager signals in send_message
by Andrew Zaborowski
Make sure the PropertiesChanged and InterfacesAdded/Removed signals
related to one object path are sent to the dbus socket in the order
that they are generated in.
---
ell/dbus-private.h | 2 +
ell/dbus-service.c | 160 ++++++++++++++++++++++++++++++++++++-----------------
ell/dbus.c | 5 ++
3 files changed, 117 insertions(+), 50 deletions(-)
diff --git a/ell/dbus-private.h b/ell/dbus-private.h
index 441e668..9ffedb2 100644
--- a/ell/dbus-private.h
+++ b/ell/dbus-private.h
@@ -229,6 +229,8 @@ bool _dbus_object_tree_property_changed(struct l_dbus *dbus,
const char *interface_name,
const char *property_name);
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path);
+
typedef void (*_dbus_name_owner_change_func_t)(const char *name,
uint64_t old_owner,
uint64_t new_owner,
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index 1df8f1b..5ee7d27 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -132,6 +132,7 @@ struct _dbus_object_tree {
struct l_queue *object_managers;
struct l_queue *property_changes;
struct l_idle *emit_signals_work;
+ bool flushing;
};
void _dbus_method_introspection(struct _dbus_method *info,
@@ -1024,71 +1025,130 @@ done:
return signal;
}
-static void emit_signals(struct l_idle *idle, void *user_data)
-{
- struct l_dbus *dbus = user_data;
- struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
- struct interface_add_record *interfaces_added_rec;
- struct interface_remove_record *interfaces_removed_rec;
- struct property_change_record *property_changes_rec;
- const struct l_queue_entry *entry;
+struct emit_signals_data {
+ struct l_dbus *dbus;
struct object_manager *manager;
+ struct object_node *node;
+};
+
+static bool emit_interfaces_removed(void *data, void *user_data)
+{
+ struct interface_remove_record *rec = data;
+ struct emit_signals_data *es = user_data;
struct l_dbus_message *signal;
- l_idle_remove(tree->emit_signals_work);
- tree->emit_signals_work = NULL;
+ if (es->node && rec->object != es->node)
+ return false;
- for (entry = l_queue_get_entries(tree->object_managers); entry;
- entry = entry->next) {
- manager = entry->data;
+ signal = build_interfaces_removed_signal(es->manager, rec);
+ interface_removed_record_free(rec);
- while ((interfaces_removed_rec =
- l_queue_pop_head(manager->announce_removed))) {
- signal = build_interfaces_removed_signal(manager,
- interfaces_removed_rec);
- interface_removed_record_free(interfaces_removed_rec);
+ if (signal)
+ l_dbus_send(es->manager->dbus, signal);
- if (signal)
- l_dbus_send(manager->dbus, signal);
- }
+ return true;
+}
- while ((interfaces_added_rec =
- l_queue_pop_head(manager->announce_added))) {
- signal = build_interfaces_added_signal(manager,
- interfaces_added_rec);
- interface_add_record_free(interfaces_added_rec);
+static bool emit_interfaces_added(void *data, void *user_data)
+{
+ struct interface_add_record *rec = data;
+ struct emit_signals_data *es = user_data;
+ struct l_dbus_message *signal;
+
+ if (es->node && rec->object != es->node)
+ return false;
+ signal = build_interfaces_added_signal(es->manager, rec);
+ interface_add_record_free(rec);
+
+ if (signal)
+ l_dbus_send(es->manager->dbus, signal);
+
+ return true;
+}
+
+static bool emit_properties_changed(void *data, void *user_data)
+{
+ struct property_change_record *rec = data;
+ struct emit_signals_data *es = user_data;
+ struct l_dbus_message *signal;
+ const struct l_queue_entry *entry;
+
+ if (es->node && rec->object != es->node)
+ return false;
+
+ if (rec->instance->interface->handle_old_style_properties)
+ for (entry = l_queue_get_entries(rec->properties);
+ entry; entry = entry->next) {
+ signal = build_old_property_changed_signal(es->dbus,
+ rec, entry->data);
if (signal)
- l_dbus_send(manager->dbus, signal);
+ l_dbus_send(es->dbus, signal);
}
+
+ if (l_queue_find(rec->object->instances, match_interface_instance,
+ L_DBUS_INTERFACE_PROPERTIES)) {
+ signal = build_properties_changed_signal(es->dbus, rec);
+ if (signal)
+ l_dbus_send(es->dbus, signal);
}
- while ((property_changes_rec =
- l_queue_pop_head(tree->property_changes))) {
- if (property_changes_rec->instance->interface->
- handle_old_style_properties)
- for (entry = l_queue_get_entries(property_changes_rec->
- properties);
- entry; entry = entry->next) {
- signal = build_old_property_changed_signal(dbus,
- property_changes_rec,
- entry->data);
- if (signal)
- l_dbus_send(dbus, signal);
- }
+ property_change_record_free(rec);
+ return true;
+}
- if (l_queue_find(property_changes_rec->object->instances,
- match_interface_instance,
- L_DBUS_INTERFACE_PROPERTIES)) {
- signal = build_properties_changed_signal(dbus,
- property_changes_rec);
- if (signal)
- l_dbus_send(dbus, signal);
- }
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus, const char *path)
+{
+ struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
+ const struct l_queue_entry *entry;
+ struct emit_signals_data data;
+ bool all_done = true;
+
+ if (!tree->emit_signals_work || tree->flushing)
+ return;
- property_change_record_free(property_changes_rec);
+ tree->flushing = true;
+
+ data.dbus = dbus;
+ data.node = path ? _dbus_object_tree_lookup(tree, path) : NULL;
+
+ for (entry = l_queue_get_entries(tree->object_managers); entry;
+ entry = entry->next) {
+ data.manager = entry->data;
+
+ l_queue_foreach_remove(data.manager->announce_removed,
+ emit_interfaces_removed, &data);
+
+ if (!l_queue_isempty(data.manager->announce_removed))
+ all_done = false;
+
+ l_queue_foreach_remove(data.manager->announce_added,
+ emit_interfaces_added, &data);
+
+ if (!l_queue_isempty(data.manager->announce_added))
+ all_done = false;
+ }
+
+ l_queue_foreach_remove(tree->property_changes,
+ emit_properties_changed, &data);
+
+ if (!l_queue_isempty(tree->property_changes))
+ all_done = false;
+
+ if (all_done) {
+ l_idle_remove(tree->emit_signals_work);
+ tree->emit_signals_work = NULL;
}
+
+ tree->flushing = false;
+}
+
+static void emit_signals(struct l_idle *idle, void *user_data)
+{
+ struct l_dbus *dbus = user_data;
+
+ _dbus_object_tree_signals_flush(dbus, NULL);
}
static void schedule_emit_signals(struct l_dbus *dbus)
@@ -1356,7 +1416,7 @@ static bool match_interfaces_added_object(const void *a, const void *b)
static bool match_interfaces_removed_object(const void *a, const void *b)
{
- const struct interface_add_record *rec = a;
+ const struct interface_remove_record *rec = a;
return rec->object == b;
}
diff --git a/ell/dbus.c b/ell/dbus.c
index db69c0d..59795a7 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -306,6 +306,7 @@ static uint32_t send_message(struct l_dbus *dbus, bool priority,
{
struct message_callback *callback;
enum dbus_message_type type;
+ const char *path;
type = _dbus_message_get_type(message);
@@ -338,6 +339,10 @@ static uint32_t send_message(struct l_dbus *dbus, bool priority,
return callback->serial;
}
+ path = l_dbus_message_get_path(message);
+ if (path)
+ _dbus_object_tree_signals_flush(dbus, path);
+
l_queue_push_tail(dbus->message_queue, callback);
if (dbus->is_ready)
--
2.9.3
5 years, 3 months
[PATCH] dbus: Flush pending object manager signals in send_message
by Andrew Zaborowski
Try to warrant the original ordering of PropertiesChanged and
InterfacesAdded/Removed signals in relation to other messages for
clients that rely on this ordering. One case where this may matter
is when a method call causes a property value change followed by the
method return message in the same main loop iteration as the property
change. In this case the property change would always be seen by
dbus after the method return because of the signals being send from
an idle callback. Set a barrier for the object manager signals
before queuing other messages like method returns.
---
ell/dbus-private.h | 2 ++
ell/dbus-service.c | 8 ++++++++
ell/dbus.c | 2 ++
3 files changed, 12 insertions(+)
diff --git a/ell/dbus-private.h b/ell/dbus-private.h
index a4118c6..c22b95a 100644
--- a/ell/dbus-private.h
+++ b/ell/dbus-private.h
@@ -234,6 +234,8 @@ bool _dbus_object_tree_property_changed(struct l_dbus *dbus,
const char *interface_name,
const char *property_name);
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus);
+
void _dbus_kernel_bloom_add(uint64_t filter[], size_t size, uint8_t num_hash,
const char *prefix, const char *str);
void _dbus_kernel_bloom_add_parents(uint64_t filter[], size_t size,
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index 1df8f1b..f54d2dd 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -1101,6 +1101,14 @@ static void schedule_emit_signals(struct l_dbus *dbus)
tree->emit_signals_work = l_idle_create(emit_signals, dbus, NULL);
}
+void _dbus_object_tree_signals_flush(struct l_dbus *dbus)
+{
+ struct _dbus_object_tree *tree = _dbus_get_tree(dbus);
+
+ if (tree->emit_signals_work)
+ emit_signals(tree->emit_signals_work, dbus);
+}
+
static bool match_property_changes_instance(const void *a, const void *b)
{
const struct property_change_record *rec = a;
diff --git a/ell/dbus.c b/ell/dbus.c
index ddc51aa..274e4ae 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -346,6 +346,8 @@ static uint32_t send_message(struct l_dbus *dbus, bool priority,
return callback->serial;
}
+ _dbus_object_tree_signals_flush(dbus);
+
l_queue_push_tail(dbus->message_queue, callback);
if (dbus->is_ready)
--
2.9.3
5 years, 3 months
[PATCH v4] unit: Added generic netlink family unit test
by Ossama Othman
---
unit/test-genl.c | 43 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/unit/test-genl.c b/unit/test-genl.c
index d15d92c..dce9a41 100644
--- a/unit/test-genl.c
+++ b/unit/test-genl.c
@@ -25,6 +25,7 @@
#endif
#include <sys/socket.h>
+#include <assert.h>
#include <ell/ell.h>
@@ -35,14 +36,38 @@ static void do_debug(const char *str, void *user_data)
l_info("%s%s", prefix, str);
}
-static void idle_callback(void *user_data)
+static void family_vanished(void *user_data)
{
- l_main_quit();
+ bool *vanished_called = user_data;
+
+ *vanished_called = true;
+}
+
+static void idle_callback(struct l_idle *idle, void *user_data)
+{
+ static int count = 0;
+
+ /*
+ * Allow the main loop to iterate at least twice to allow the
+ * generic netlink watches to be called.
+ */
+ if (++count > 1)
+ l_main_quit();
}
int main(int argc, char *argv[])
{
struct l_genl *genl;
+ struct l_genl_family *family;
+ struct l_idle *idle;
+
+ /*
+ * Use a bogus family name to trigger the vanished watch to
+ * be called.
+ */
+ static const char BOGUS_GENL_NAME[] = "bogus_genl_family";
+
+ bool vanished_called = false;
if (!l_main_init())
return -1;
@@ -53,13 +78,25 @@ int main(int argc, char *argv[])
l_genl_set_debug(genl, do_debug, "[GENL] ", NULL);
- l_idle_oneshot(idle_callback, NULL, NULL);
+ family = l_genl_family_new(genl, BOGUS_GENL_NAME);
+ l_genl_family_set_watches(family,
+ NULL,
+ family_vanished,
+ &vanished_called,
+ NULL);
+
+ idle = l_idle_create(idle_callback, NULL, NULL);
l_main_run();
+ l_idle_remove(idle);
+
+ l_genl_family_unref(family);
l_genl_unref(genl);
l_main_exit();
+ assert(vanished_called);
+
return 0;
}
--
2.7.4
5 years, 3 months
[PATCH] unit: Added generic netlink family unit test
by Ossama Othman
---
Makefile.am | 3 ++
unit/test-genl-family.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 unit/test-genl-family.c
diff --git a/Makefile.am b/Makefile.am
index d2e33de..39ebe66 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,6 +119,7 @@ unit_tests = unit/test-unit \
unit/test-settings \
unit/test-netlink \
unit/test-genl \
+ unit/test-genl-family \
unit/test-genl-msg \
unit/test-siphash \
unit/test-hwdb \
@@ -174,6 +175,8 @@ unit_test_netlink_LDADD = ell/libell-private.la
unit_test_genl_LDADD = ell/libell-private.la
+unit_test_genl_family_LDADD = ell/libell-private.la
+
unit_test_genl_msg_LDADD = ell/libell-private.la
unit_test_dbus_LDADD = ell/libell-private.la
diff --git a/unit/test-genl-family.c b/unit/test-genl-family.c
new file mode 100644
index 0000000..5109fad
--- /dev/null
+++ b/unit/test-genl-family.c
@@ -0,0 +1,99 @@
+/*
+ *
+ * Embedded Linux library
+ *
+ * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/socket.h>
+
+#include <ell/ell.h>
+
+static void do_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ l_info("%s%s", prefix, str);
+}
+
+static void family_vanished(void *user_data)
+{
+ bool *vanished_called = user_data;
+
+ *vanished_called = true;
+}
+
+static void idle_handler(struct l_idle *idle, void *user_data)
+{
+ static int count = 0;
+
+ /*
+ * Allow the main loop to iterate at least once. Otherwise
+ * the generic netlink watches won't be called.
+ */
+ if (count++ == 1)
+ l_main_quit();
+}
+
+int main(int argc, char *argv[])
+{
+ struct l_genl *genl;
+ struct l_genl_family *family;
+ struct l_idle *idle;
+
+ /*
+ * Use a bogus family name to trigger the vanished watch to
+ * be called.
+ */
+ static const char BOGUS_GENL_NAME[] = "bogus_genl_family";
+
+ bool vanished_called = false;
+
+ if (!l_main_init())
+ return -1;
+
+ l_log_set_stderr();
+
+ genl = l_genl_new_default();
+
+ l_genl_set_debug(genl, do_debug, "[GENL] ", NULL);
+
+ family = l_genl_family_new(genl, BOGUS_GENL_NAME);
+ l_genl_family_set_watches(family,
+ NULL,
+ family_vanished,
+ &vanished_called,
+ NULL);
+
+ idle = l_idle_create(idle_handler, NULL, NULL);
+
+ l_main_run();
+
+ l_idle_remove(idle);
+
+ l_genl_family_unref(family);
+ l_genl_unref(genl);
+
+ l_main_exit();
+
+ return vanished_called ? 0 : -1;
+}
--
2.7.4
5 years, 3 months
[PATCH] unit: Added generic netlink family unit test
by Ossama Othman
---
Makefile.am | 3 ++
unit/test-genl-family.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 103 insertions(+)
create mode 100644 unit/test-genl-family.c
diff --git a/Makefile.am b/Makefile.am
index d2e33de..39ebe66 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,6 +119,7 @@ unit_tests = unit/test-unit \
unit/test-settings \
unit/test-netlink \
unit/test-genl \
+ unit/test-genl-family \
unit/test-genl-msg \
unit/test-siphash \
unit/test-hwdb \
@@ -174,6 +175,8 @@ unit_test_netlink_LDADD = ell/libell-private.la
unit_test_genl_LDADD = ell/libell-private.la
+unit_test_genl_family_LDADD = ell/libell-private.la
+
unit_test_genl_msg_LDADD = ell/libell-private.la
unit_test_dbus_LDADD = ell/libell-private.la
diff --git a/unit/test-genl-family.c b/unit/test-genl-family.c
new file mode 100644
index 0000000..ec644a2
--- /dev/null
+++ b/unit/test-genl-family.c
@@ -0,0 +1,100 @@
+/*
+ *
+ * Embedded Linux library
+ *
+ * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/socket.h>
+
+#include <ell/ell.h>
+
+static void do_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ l_info("%s%s", prefix, str);
+}
+
+static void family_vanished(void *user_data)
+{
+ bool *vanished_called = user_data;
+
+ *vanished_called = true;
+ l_main_quit();
+}
+
+static void idle_handler(struct l_idle *idle, void *user_data)
+{
+ static int count = 0;
+
+ /*
+ * Allow the main loop to iterate at least once. Otherwise
+ * the generic netlink watches won't be called.
+ */
+ if (count++ == 1)
+ l_main_quit();
+}
+
+int main(int argc, char *argv[])
+{
+ struct l_genl *genl;
+ struct l_genl_family *family;
+ struct l_idle *idle;
+
+ /*
+ * Use a bogus family name to trigger the vanished watch to
+ * be called.
+ */
+ static const char BOGUS_GENL_NAME[] = "bogus_genl_family";
+
+ bool vanished_called = false;
+
+ if (!l_main_init())
+ return -1;
+
+ l_log_set_stderr();
+
+ genl = l_genl_new_default();
+
+ l_genl_set_debug(genl, do_debug, "[GENL] ", NULL);
+
+ family = l_genl_family_new(genl, BOGUS_GENL_NAME);
+ l_genl_family_set_watches(family,
+ NULL,
+ family_vanished,
+ &vanished_called,
+ NULL);
+
+ idle = l_idle_create(idle_handler, NULL, NULL);
+
+ l_main_run();
+
+ l_idle_remove(idle);
+
+ l_genl_family_unref(family);
+ l_genl_unref(genl);
+
+ l_main_exit();
+
+ return vanished_called ? 0 : -1;
+}
--
2.7.4
5 years, 3 months
Re: [PATCH 3/5] unit: remove kdbus
by Denis Kenzior
Hi Lukas,
On 03/17/2017 03:59 PM, Lukas Rusak wrote:
> From: Lukas Rusak <lorusak(a)gmail.com>
>
> ---
> unit/test-dbus-message-fds.c | 25 ------
> unit/test-dbus-message.c | 30 -------
> unit/test-dbus-properties.c | 25 ------
> unit/test-kdbus.c | 200 -------------------------------------------
> 4 files changed, 280 deletions(-)
> delete mode 100644 unit/test-kdbus.c
>
I went ahead and applied all 5 patches. I did have to fix up the
affected unit tests in commit 9105f7611653fb8ecd93587c68bf6ab203a6c202
since you forgot to take out a few extra lines.
Thanks!
Regards,
-Denis
5 years, 3 months
[PATCH 1/5] ell: remove kdbus
by Lukas Rusak
From: Lukas Rusak <lorusak(a)gmail.com>
---
ell/dbus-kernel.c | 971 -----------------------------------------------------
ell/dbus-message.c | 129 +------
ell/dbus-private.h | 40 ---
ell/dbus.c | 265 +--------------
4 files changed, 3 insertions(+), 1402 deletions(-)
delete mode 100644 ell/dbus-kernel.c
diff --git a/ell/dbus-kernel.c b/ell/dbus-kernel.c
deleted file mode 100644
index 4d7cae3..0000000
--- a/ell/dbus-kernel.c
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- *
- * Embedded Linux library
- *
- * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <alloca.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <time.h>
-
-#include "linux/kdbus.h"
-
-#include "private.h"
-#include "dbus.h"
-#include "dbus-private.h"
-#include "siphash-private.h"
-
-#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
-#define KDBUS_POOL_SIZE (16*1024*1024)
-
-#define KDBUS_ITEM_FOREACH(item, head, first) \
- for (item = head->first; \
- (void *)(item) < (void *)(head) + (head)->size; \
- item = KDBUS_ITEM_NEXT(item)) \
-
-#define DEFAULT_BLOOM_SIZE (512 / 8)
-#define DEFAULT_BLOOM_N_HASH (8)
-
-#define HASH_KEY(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15) \
- { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
- 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }
-
-#define KDBUS_ITEM_SIZE(actual) \
- align_len(actual + offsetof(struct kdbus_item, data), 8)
-
-static inline struct kdbus_item *KDBUS_ITEM_NEXT(struct kdbus_item *item)
-{
- size_t aligned = align_len(item->size, 8);
- void *start = item;
-
- return start + aligned;
-}
-
-static inline unsigned int __u64_log2(uint64_t n)
-{
- if (n == 0)
- return 0;
-
- return __builtin_clzll(n) ^ 63U;
-}
-
-static inline void set_bit(uint64_t filter[], size_t b)
-{
- filter[b >> 6] |= 1ULL << (b & 63);
-}
-
-static const uint8_t hash_keys[][16] = {
- HASH_KEY(b9,66,0b,f0,46,70,47,c1,88,75,c4,9c,54,b9,bd,15),
- HASH_KEY(aa,a1,54,a2,e0,71,4b,39,bf,e1,dd,2e,9f,c5,4a,3b),
- HASH_KEY(63,fd,ae,be,cd,82,48,12,a1,6e,41,26,cb,fa,a0,c8),
- HASH_KEY(23,be,45,29,32,d2,46,2d,82,03,52,28,fe,37,17,f5),
- HASH_KEY(56,3b,bf,ee,5a,4f,43,39,af,aa,94,08,df,f0,fc,10),
- HASH_KEY(31,80,c8,73,c7,ea,46,d3,aa,25,75,0f,9e,4c,09,29),
- HASH_KEY(7d,f7,18,4b,7b,a4,44,d5,85,3c,06,e0,65,53,96,6d),
- HASH_KEY(f2,77,e9,6f,93,b5,4e,71,9a,0c,34,88,39,25,bf,35),
-};
-
-static void bloom_update(uint64_t filter[], size_t size, uint8_t num_hash,
- const void *data, size_t data_size)
-{
- uint8_t hashed[8];
- uint64_t n_bits;
- unsigned int index_size;
- unsigned int i;
- unsigned int hash_index;
- unsigned int unused_bytes = 0;
-
- if (unlikely(num_hash == 0))
- return;
-
- if (unlikely(size == 0))
- return;
-
- n_bits = size * 8;
- index_size = (__u64_log2(n_bits) + 7) / 8;
-
- if (unlikely(index_size > sizeof(uint32_t)))
- return;
-
- for (i = 0, hash_index = 0; i < num_hash; i++) {
- uint32_t index = 0;
- unsigned int j;
-
- for (j = 0; j < index_size; j++) {
- if (unused_bytes == 0) {
- _siphash24(hashed, data, data_size,
- hash_keys[hash_index++]);
- unused_bytes = 8;
- }
-
- index = index << 8;
- index |= hashed[8 - unused_bytes];
- unused_bytes -= 1;
- }
-
- index &= n_bits - 1;
- set_bit(filter, index);
- }
-}
-
-void _dbus_kernel_bloom_add(uint64_t filter[], size_t size, uint8_t num_hash,
- const char *prefix, const char *str)
-{
- char *buf;
- size_t len;
-
- len = strlen(prefix) + 1 + strlen(str) + 1;
- buf = alloca(len);
-
- sprintf(buf, "%s:%s", prefix, str);
-
- bloom_update(filter, size, num_hash, buf, len - 1);
-}
-
-void _dbus_kernel_bloom_add_parents(uint64_t filter[], size_t size,
- uint8_t num_hash, const char *prefix,
- const char *str, const char sep)
-{
- char *buf;
- size_t len;
- int start;
-
- len = strlen(prefix) + 1 + strlen(str) + 1;
- buf = alloca(len);
-
- sprintf(buf, "%s:%n%s", prefix, &start, str);
-
- while (true) {
- char *s = strrchr(buf + start, sep);
-
- if (!s)
- break;
-
- if (s == buf + start)
- break;
-
- *s = '\0';
- bloom_update(filter, size, num_hash, buf, s - buf);
- }
-}
-
-int _dbus_kernel_create_bus(const char *name)
-{
- struct {
- struct kdbus_cmd head;
- /* bloom size item */
- uint64_t bloom_size;
- uint64_t bloom_type;
- struct kdbus_bloom_parameter bloom_param;
- /* name item */
- uint64_t name_size;
- uint64_t name_type;
- char name_param[64];
- } bus_make;
- int fd;
-
- fd = open("/dev/kdbus/control", O_RDWR | O_CLOEXEC);
- if (fd < 0)
- return -1;
-
- memset(&bus_make, 0, sizeof(bus_make));
- /* bloom size item */
- bus_make.bloom_size = KDBUS_ITEM_HEADER_SIZE +
- sizeof(bus_make.bloom_param);
- bus_make.bloom_type = KDBUS_ITEM_BLOOM_PARAMETER;
- bus_make.bloom_param.size = DEFAULT_BLOOM_SIZE;
- bus_make.bloom_param.n_hash = DEFAULT_BLOOM_N_HASH;
- /* name item */
- snprintf(bus_make.name_param, sizeof(bus_make.name_param), "%s", name);
- bus_make.name_size = KDBUS_ITEM_HEADER_SIZE +
- strlen(bus_make.name_param) + 1;
- bus_make.name_type = KDBUS_ITEM_MAKE_NAME;
- /* bus make head */
- bus_make.head.size = align_len(sizeof(bus_make.head) +
- bus_make.bloom_size +
- bus_make.name_size, 8);
- bus_make.head.flags = KDBUS_MAKE_ACCESS_WORLD;
-
- if (ioctl(fd, KDBUS_CMD_BUS_MAKE, &bus_make) < 0) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-void _dbus_kernel_unmap_pool(void *pool)
-{
- munmap(pool, KDBUS_POOL_SIZE);
-}
-
-int _dbus_kernel_hello(int fd, const char *connection_name,
- size_t *bloom_size, uint8_t *bloom_n_hash,
- uint64_t *id, void **pool, char **guid)
-{
- size_t len = strlen(connection_name);
- size_t size;
- struct kdbus_cmd_hello *hello;
- struct kdbus_item *item;
- int ret;
- struct kdbus_cmd_free cmd_free;
-
- size = align_len(sizeof(struct kdbus_cmd_hello), 8);
- size += KDBUS_ITEM_SIZE(len + 1);
-
- hello = alloca(size);
- memset(hello, 0, size);
-
- hello->size = size;
- hello->flags |= KDBUS_HELLO_ACCEPT_FD;
- hello->pool_size = KDBUS_POOL_SIZE;
-
- item = hello->items;
- item->size = KDBUS_ITEM_HEADER_SIZE + len + 1;
- item->type = KDBUS_ITEM_CONN_DESCRIPTION;
- strcpy(item->str, connection_name);
-
- ret = ioctl(fd, KDBUS_CMD_HELLO, hello);
- if (ret < 0) {
- ret = -errno;
- goto done;
- }
-
- /* Check for incompatible flags (upper 32 bits) */
- if (hello->bus_flags > 0xFFFFFFFFULL ||
- hello->flags > 0xFFFFFFFFULL) {
- ret = -ENOTSUP;
- goto done;
- }
-
- *pool = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0);
- if (*pool == MAP_FAILED) {
- *pool = NULL;
- ret = -errno;
- goto done;
- }
-
- *bloom_size = DEFAULT_BLOOM_SIZE;
- *bloom_n_hash = DEFAULT_BLOOM_N_HASH;
-
- KDBUS_ITEM_FOREACH(item, hello, items) {
- switch (item->type) {
- case KDBUS_ITEM_BLOOM_PARAMETER:
- *bloom_size = item->bloom_parameter.size;
- *bloom_n_hash = item->bloom_parameter.n_hash;
- break;
- }
- }
-
- *id = hello->id;
- *guid = l_strdup_printf("%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
- "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
- "%02hhx%02hhx",
- hello->id128[0], hello->id128[1],
- hello->id128[2], hello->id128[3],
- hello->id128[4], hello->id128[5],
- hello->id128[6], hello->id128[7],
- hello->id128[8], hello->id128[9],
- hello->id128[10], hello->id128[11],
- hello->id128[12], hello->id128[13],
- hello->id128[14], hello->id128[15]);
-
-done:
- memset(&cmd_free, 0, sizeof(cmd_free));
- cmd_free.size = sizeof(cmd_free);
- cmd_free.offset = hello->offset;
-
- ioctl(fd, KDBUS_CMD_FREE, &cmd_free);
-
- return ret;
-}
-
-int _dbus_kernel_send(int fd, size_t bloom_size, uint8_t bloom_n_hash,
- struct l_dbus_message *message)
-{
- size_t kmsg_size;
- bool unique;
- uint64_t uninitialized_var(id);
- const char *dest;
- size_t dest_len;
- struct kdbus_item *item;
- void *header;
- size_t header_size;
- void *footer;
- size_t footer_size;
- int ret;
- struct kdbus_cmd_send cmd;
- uint32_t num_fds;
- int *fds;
- L_AUTO_FREE_VAR(struct kdbus_msg *, kmsg);
-
- dest = l_dbus_message_get_destination(message);
- if (dest)
- unique = _dbus_parse_unique_name(dest, &id);
- else
- unique = false;
-
- dest_len = dest ? strlen(dest) : 0;
-
- kmsg_size = sizeof(struct kdbus_msg);
-
- /* Reserve space for header + body */
- kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
- kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
-
- /* Reserve space for bloom filter */
- if (_dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
- kmsg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter) +
- bloom_size);
-
- /* Reserve space for well-known destination header */
- if (dest && !unique)
- kmsg_size += KDBUS_ITEM_SIZE(dest_len + 1);
-
- /* Reserve space for fds */
- fds = _dbus_message_get_fds(message, &num_fds);
- if (num_fds)
- kmsg_size += KDBUS_ITEM_SIZE(num_fds * sizeof(int));
-
- kmsg = aligned_alloc(8, kmsg_size);
- if (!kmsg)
- return -ENOMEM;
-
- memset(kmsg, 0, kmsg_size);
- item = kmsg->items;
-
- kmsg->payload_type = KDBUS_PAYLOAD_DBUS;
- kmsg->priority = 0;
- kmsg->cookie = _dbus_message_get_serial(message);
-
- if (l_dbus_message_get_no_autostart(message))
- kmsg->flags |= KDBUS_MSG_NO_AUTO_START;
-
- if (!l_dbus_message_get_no_reply(message))
- kmsg->flags |= KDBUS_MSG_EXPECT_REPLY;
-
- if (!unique && dest) {
- kmsg->dst_id = KDBUS_DST_ID_NAME;
- item->size = KDBUS_ITEM_HEADER_SIZE + dest_len + 1;
- item->type = KDBUS_ITEM_DST_NAME;
- strcpy(item->str, dest);
- item = KDBUS_ITEM_NEXT(item);
- } else if (!unique && !dest)
- kmsg->dst_id = KDBUS_DST_ID_BROADCAST;
- else
- kmsg->dst_id = id;
-
- switch(_dbus_message_get_type(message)) {
- case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- case DBUS_MESSAGE_TYPE_ERROR:
- {
- uint32_t reply_cookie = _dbus_message_get_reply_serial(message);
-
- if (reply_cookie == 0)
- return -EINVAL;
-
- kmsg->cookie_reply = reply_cookie;
- break;
- }
- case DBUS_MESSAGE_TYPE_METHOD_CALL:
- if (!l_dbus_message_get_no_reply(message)) {
- struct timespec now;
-
- clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
-
- kmsg->timeout_ns =
- now.tv_sec * 1000000000ULL + now.tv_nsec +
- 30000 * 1000000ULL;
- }
-
- break;
- case DBUS_MESSAGE_TYPE_SIGNAL:
- kmsg->flags |= KDBUS_MSG_SIGNAL;
-
- item->size = KDBUS_ITEM_HEADER_SIZE +
- sizeof(struct kdbus_bloom_filter) + bloom_size;
- item->type = KDBUS_ITEM_BLOOM_FILTER;
-
- item->bloom_filter.generation = 0;
- _dbus_kernel_calculate_bloom(message,
- (uint64_t *) item->bloom_filter.data,
- bloom_size, bloom_n_hash);
-
- item = KDBUS_ITEM_NEXT(item);
- break;
- }
-
- header = _dbus_message_get_header(message, &header_size);
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
- item->type = KDBUS_ITEM_PAYLOAD_VEC;
- item->vec.address = (uintptr_t) header;
- item->vec.size = header_size;
- item = KDBUS_ITEM_NEXT(item);
-
- footer = _dbus_message_get_footer(message, &footer_size);
-
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
- item->type = KDBUS_ITEM_PAYLOAD_VEC;
- item->vec.address = (uintptr_t) footer;
- item->vec.size = footer_size;
- item = KDBUS_ITEM_NEXT(item);
-
- if (num_fds) {
- item->size = KDBUS_ITEM_HEADER_SIZE + num_fds * sizeof(int);
- item->type = KDBUS_ITEM_FDS;
- memcpy(item->fds, fds, num_fds * sizeof(int));
- item = KDBUS_ITEM_NEXT(item);
- }
-
- kmsg->size = (void *)item - (void *)kmsg;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.size = sizeof(cmd);
- cmd.msg_address = (uintptr_t) kmsg;
-
- ret = ioctl(fd, KDBUS_CMD_SEND, &cmd);
- if (ret < 0)
- return -errno;
-
- return 0;
-}
-
-static void collect_body_parts(struct kdbus_msg *kmsg, size_t size, void **data)
-{
- struct kdbus_item *item;
- size_t offset = 0;
-
- *data = l_malloc(size);
-
- KDBUS_ITEM_FOREACH(item, kmsg, items) {
- switch (item->type) {
- case KDBUS_ITEM_PAYLOAD_OFF:
- memcpy(*data + offset, (void *) kmsg + item->vec.offset,
- item->vec.size);
-
- offset += item->vec.size;
-
- break;
- }
- }
-}
-
-static int _dbus_kernel_make_message(struct kdbus_msg *kmsg,
- struct l_dbus_message **out_message)
-{
- struct kdbus_item *item;
- void *data = 0;
- size_t size = 0;
- struct dbus_header *hdr;
- const char *destination = 0;
- char unique_bus_name[128];
- uint32_t num_fds = 0;
- int *fds = NULL;
- unsigned int i;
-
- KDBUS_ITEM_FOREACH(item, kmsg, items) {
- switch (item->type) {
- case KDBUS_ITEM_PAYLOAD_OFF:
- if (!size) {
- if (item->vec.size < sizeof(struct dbus_header))
- return -EBADMSG;
-
- hdr = (void *)kmsg + item->vec.offset;
- }
-
- size += item->vec.size;
-
- break;
- case KDBUS_ITEM_PAYLOAD_MEMFD:
- if (!size)
- return -EBADMSG;
-
- return -ENOTSUP;
- case KDBUS_ITEM_FDS:
- if (fds || item->size <= KDBUS_ITEM_HEADER_SIZE)
- return -EBADMSG;
-
- num_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) /
- sizeof(int);
- fds = item->fds;
-
- /* Set FD_CLOEXEC on all file descriptors */
- for (i = 0; i < num_fds; i++) {
- long flags;
-
- if (fds[i] == -1)
- continue;
-
- flags = fcntl(fds[i], F_GETFD, NULL);
- if (flags < 0 || (flags & FD_CLOEXEC))
- continue;
-
- fcntl(fds[i], F_SETFD, flags | FD_CLOEXEC);
- }
-
- break;
- case KDBUS_ITEM_DST_NAME:
- if (!_dbus_valid_bus_name(item->str))
- return -EBADMSG;
-
- destination = item->str;
- break;
- }
- }
-
- if (!size)
- return -EBADMSG;
-
- if (hdr->endian != DBUS_NATIVE_ENDIAN)
- return -EPROTOTYPE;
-
- if (hdr->version != 2)
- return -EPROTO;
-
- collect_body_parts(kmsg, size, &data);
-
- *out_message = dbus_message_from_blob(data, size, fds, num_fds);
-
- l_free(data);
-
- if (!*out_message)
- return -EBADMSG;
-
- if (kmsg->src_id != KDBUS_SRC_ID_KERNEL) {
- sprintf(unique_bus_name, ":1.%llu", kmsg->src_id);
- _dbus_message_set_sender(*out_message, unique_bus_name);
- } else
- _dbus_message_set_sender(*out_message, "org.freedesktop.DBus");
-
- switch (kmsg->dst_id) {
- case KDBUS_DST_ID_NAME:
- break;
- case KDBUS_DST_ID_BROADCAST:
- break;
- default:
- sprintf(unique_bus_name, ":1.%llu", kmsg->dst_id);
- _dbus_message_set_destination(*out_message, unique_bus_name);
- }
-
- if (destination)
- _dbus_message_set_destination(*out_message, destination);
-
- return 0;
-}
-
-int _dbus_kernel_recv(int fd, void *kdbus_pool,
- l_dbus_message_func_t message_func,
- _dbus_name_owner_change_func_t name_owner_change_func,
- void *user_data)
-{
- struct kdbus_cmd_recv recv_cmd;
- struct kdbus_cmd_free cmd_free;
- struct kdbus_msg *msg;
- struct l_dbus_message *dbus_msg;
- struct kdbus_item *item;
- int r;
- size_t min_size;
- const char *error;
- char unique_bus_name[128];
-
- memset(&recv_cmd, 0, sizeof(recv_cmd));
-
- recv_cmd.size = sizeof(recv_cmd);
-
- r = ioctl(fd, KDBUS_CMD_RECV, &recv_cmd);
- if (r < 0)
- return -errno;
-
- msg = (struct kdbus_msg *)(kdbus_pool + recv_cmd.msg.offset);
-
- switch (msg->payload_type) {
- case KDBUS_PAYLOAD_DBUS:
- r = _dbus_kernel_make_message(msg, &dbus_msg);
- if (!r)
- message_func(dbus_msg, user_data);
- break;
- case KDBUS_PAYLOAD_KERNEL:
- if (msg->size < sizeof(*msg) + KDBUS_ITEM_HEADER_SIZE) {
- r = -EPROTONOSUPPORT;
- break;
- }
-
- item = msg->items;
-
- switch (item->type) {
- case KDBUS_ITEM_NAME_ADD:
- case KDBUS_ITEM_NAME_CHANGE:
- case KDBUS_ITEM_NAME_REMOVE:
- min_size = KDBUS_ITEM_SIZE(sizeof(item->name_change));
- if (msg->size < sizeof(*msg) + min_size ||
- item->size < min_size) {
- r = -EPROTONOSUPPORT;
- break;
- }
-
- name_owner_change_func(item->name_change.name,
- item->name_change.old_id.id,
- item->name_change.new_id.id,
- user_data);
- break;
-
- case KDBUS_ITEM_ID_ADD:
- case KDBUS_ITEM_ID_REMOVE:
- min_size = KDBUS_ITEM_SIZE(sizeof(item->id_change));
- if (msg->size < sizeof(*msg) + min_size ||
- item->size < min_size) {
- r = -EPROTONOSUPPORT;
- break;
- }
-
- sprintf(unique_bus_name, ":1.%llu", item->id_change.id);
-
- if (item->type == KDBUS_ITEM_ID_ADD)
- name_owner_change_func(unique_bus_name,
- 0, item->id_change.id,
- user_data);
- else
- name_owner_change_func(unique_bus_name,
- item->id_change.id, 0,
- user_data);
- break;
-
- case KDBUS_ITEM_REPLY_TIMEOUT:
- case KDBUS_ITEM_REPLY_DEAD:
- if (item->type == KDBUS_ITEM_REPLY_TIMEOUT)
- error = "Did not receive a reply.";
- else
- error = "Message recipient disconnected from "
- "message bus without replying.";
-
- dbus_msg = _dbus_message_new_error(
- 2, msg->cookie_reply, NULL,
- "org.freedesktop.DBus.Error.NoReply",
- error);
- if (dbus_msg)
- message_func(dbus_msg, user_data);
-
- break;
-
- default:
- break;
- }
-
- break;
- default:
- r = -EPROTONOSUPPORT;
- break;
- }
-
- memset(&cmd_free, 0, sizeof(cmd_free));
- cmd_free.size = sizeof(cmd_free);
- cmd_free.offset = recv_cmd.msg.offset;
-
- ioctl(fd, KDBUS_CMD_FREE, &cmd_free);
-
- return r;
-}
-
-int _dbus_kernel_name_acquire(int fd, const char *name, bool allow_replacement,
- bool replace_existing, bool queue, bool *queued)
-{
- struct {
- struct kdbus_cmd head;
- char param[64];
- } cmd_name;
- struct kdbus_item *item;
- size_t nlen;
-
- if (!name)
- return false;
-
- nlen = strlen(name) + 1;
- if (KDBUS_ITEM_SIZE(nlen) > sizeof(cmd_name.param))
- return false;
-
- memset(&cmd_name, 0, sizeof(cmd_name));
-
- cmd_name.head.size = sizeof(cmd_name.head) + KDBUS_ITEM_SIZE(nlen);
-
- item = cmd_name.head.items;
- item->size = KDBUS_ITEM_HEADER_SIZE + nlen;
- item->type = KDBUS_ITEM_NAME;
- strcpy(item->str, name);
-
- if (replace_existing)
- cmd_name.head.flags |= KDBUS_NAME_REPLACE_EXISTING;
-
- if (allow_replacement)
- cmd_name.head.flags |= KDBUS_NAME_ALLOW_REPLACEMENT;
-
- if (queue)
- cmd_name.head.flags |= KDBUS_NAME_QUEUE;
-
- if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, &cmd_name) < 0)
- return -errno;
-
- if (queued)
- *queued = !!(cmd_name.head.flags & KDBUS_NAME_IN_QUEUE);
-
- return 0;
-}
-
-int _dbus_kernel_add_match(int fd, uint64_t bloom_size, uint64_t bloom_n_hash,
- const struct _dbus_filter_condition *rule,
- int rule_len, unsigned int id)
-{
- struct kdbus_item *bloom, *item;
- struct kdbus_cmd_match *cmd;
- size_t cmd_size;
- const char *prefix;
- char argstr[8];
- int r, i;
- uint64_t sender_id;
-
- cmd_size = sizeof(struct kdbus_cmd_match);
- cmd_size += KDBUS_ITEM_SIZE(bloom_size);
-
- for (i = 0; i < rule_len; i++) {
- switch (rule[i].type) {
- case L_DBUS_MATCH_SENDER:
- if (_dbus_parse_unique_name(rule->value, NULL))
- cmd_size += KDBUS_ITEM_SIZE(sizeof(item->id));
- else
- cmd_size += KDBUS_ITEM_SIZE(
- strlen(rule[i].value) + 1);
- break;
- default:
- break;
- }
- }
-
- cmd = alloca(cmd_size);
- memset(cmd, 0, cmd_size);
- cmd->size = cmd_size;
- cmd->cookie = id;
- item = cmd->items;
-
- bloom = item;
- bloom->size = KDBUS_ITEM_HEADER_SIZE + bloom_size;
- bloom->type = KDBUS_ITEM_BLOOM_MASK;
-
- for (; rule_len; rule++, rule_len--) {
- switch ((int) rule->type) {
- case L_DBUS_MATCH_SENDER:
- item = KDBUS_ITEM_NEXT(item);
-
- if (_dbus_parse_unique_name(rule->value, &sender_id)) {
- item->size = KDBUS_ITEM_HEADER_SIZE +
- strlen(rule->value) + 1;
- item->type = KDBUS_ITEM_ID;
- item->id = id;
- } else {
- item->size = KDBUS_ITEM_HEADER_SIZE +
- strlen(rule->value) + 1;
- item->type = KDBUS_ITEM_NAME;
- strcpy(item->str, rule->value);
- }
-
- continue;
- case L_DBUS_MATCH_TYPE:
- prefix = "message-type";
- break;
- case L_DBUS_MATCH_PATH:
- prefix = "path";
- break;
- case L_DBUS_MATCH_INTERFACE:
- prefix = "interface";
- break;
- case L_DBUS_MATCH_MEMBER:
- prefix = "member";
- break;
- case L_DBUS_MATCH_ARG0...(L_DBUS_MATCH_ARG0 + 63):
- prefix = argstr;
- snprintf(argstr, sizeof(argstr), "arg%i",
- rule->type - L_DBUS_MATCH_ARG0);
- break;
- default:
- return -ENOTSUP;
- }
-
- _dbus_kernel_bloom_add((uint64_t *) bloom->data64, bloom_size,
- bloom_n_hash, prefix, rule->value);
- }
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, cmd);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int _dbus_kernel_remove_match(int fd, unsigned int id)
-{
- struct kdbus_cmd_match cmd;
- int r;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.size = sizeof(cmd);
- cmd.cookie = id;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_REMOVE, &cmd);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int _dbus_kernel_enable_name_owner_notify(int fd)
-{
- struct {
- struct kdbus_cmd_match cmd;
- uint8_t param[KDBUS_ITEM_SIZE(
- sizeof(struct kdbus_notify_name_change)) +
- KDBUS_ITEM_SIZE(
- sizeof(struct kdbus_notify_id_change))];
- } cmd_match;
- struct kdbus_item *item;
- int r;
-
- memset(&cmd_match, 0, sizeof(cmd_match));
- item = cmd_match.cmd.items;
- item->type = KDBUS_ITEM_NAME_ADD;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->name_change);
- item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
- item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
- cmd_match.cmd.size = sizeof(cmd_match.cmd) + item->size;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match);
- if (r < 0)
- return -errno;
-
- memset(&cmd_match, 0, sizeof(cmd_match));
- item = cmd_match.cmd.items;
- item->type = KDBUS_ITEM_NAME_CHANGE;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->name_change);
- item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
- item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
- cmd_match.cmd.size = sizeof(cmd_match.cmd) + item->size;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match);
- if (r < 0)
- return -errno;
-
- memset(&cmd_match, 0, sizeof(cmd_match));
- item = cmd_match.cmd.items;
- item->type = KDBUS_ITEM_NAME_REMOVE;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->name_change);
- item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
- item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
- cmd_match.cmd.size = sizeof(cmd_match.cmd) + item->size;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match);
- if (r < 0)
- return -errno;
-
- memset(&cmd_match, 0, sizeof(cmd_match));
- item = cmd_match.cmd.items;
- item->type = KDBUS_ITEM_ID_ADD;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->id_change);
- item->id_change.id = KDBUS_MATCH_ID_ANY;
- cmd_match.cmd.size = sizeof(cmd_match.cmd) + item->size;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match);
- if (r < 0)
- return -errno;
-
- memset(&cmd_match, 0, sizeof(cmd_match));
- item = cmd_match.cmd.items;
- item->type = KDBUS_ITEM_ID_REMOVE;
- item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(item->id_change);
- item->id_change.id = KDBUS_MATCH_ID_ANY;
- cmd_match.cmd.size = sizeof(cmd_match.cmd) + item->size;
-
- r = ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-uint64_t _dbus_kernel_get_name_owner(int fd, void *kdbus_pool,
- const char *name)
-{
- struct kdbus_cmd_list cmd;
- struct kdbus_cmd_free cmd_free;
- struct kdbus_info *entry, *end;
- struct kdbus_item *item;
- const char *entry_name;
- uint64_t owner_id = 0;
- bool is_unique;
- uint64_t uninitialized_var(id);
-
- is_unique = _dbus_parse_unique_name(name, &id);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.size = sizeof(cmd);
- cmd.flags = is_unique ? KDBUS_LIST_UNIQUE : KDBUS_LIST_NAMES;
-
- if (ioctl(fd, KDBUS_CMD_LIST, &cmd) < 0)
- return 0;
-
- entry = kdbus_pool + cmd.offset;
- end = (void *) entry + cmd.list_size;
-
- for (; entry < end; entry = (void *) entry + entry->size) {
- entry_name = NULL;
-
- KDBUS_ITEM_FOREACH(item, entry, items) {
- if (item->type == KDBUS_ITEM_OWNED_NAME) {
- entry_name = item->name.name;
- break;
- }
- }
-
- if (entry_name && !strcmp(entry_name, name)) {
- owner_id = entry->id;
- break;
- }
-
- if (is_unique && id == entry->id) {
- owner_id = id;
- break;
- }
- }
-
- memset(&cmd_free, 0, sizeof(cmd_free));
- cmd_free.size = sizeof(cmd_free);
- cmd_free.offset = cmd.offset;
-
- ioctl(fd, KDBUS_CMD_FREE, &cmd_free);
-
- return owner_id;
-}
diff --git a/ell/dbus-message.c b/ell/dbus-message.c
index b5c9222..fca38f4 100644
--- a/ell/dbus-message.c
+++ b/ell/dbus-message.c
@@ -73,8 +73,6 @@ struct l_dbus_message {
uint32_t num_fds;
bool sealed : 1;
- bool kdbus_sender : 1;
- bool kdbus_destination : 1;
bool signature_free : 1;
};
@@ -137,20 +135,14 @@ void _dbus_message_set_serial(struct l_dbus_message *msg, uint32_t serial)
{
struct dbus_header *hdr = msg->header;
- if (_dbus_message_is_gvariant(msg))
- hdr->kdbus.cookie = serial;
- else
- hdr->dbus1.serial = serial;
+ hdr->dbus1.serial = serial;
}
uint32_t _dbus_message_get_serial(struct l_dbus_message *msg)
{
struct dbus_header *hdr = msg->header;
- if (_dbus_message_is_gvariant(msg))
- return hdr->kdbus.cookie;
- else
- return hdr->dbus1.serial;
+ return hdr->dbus1.serial;
}
LIB_EXPORT bool l_dbus_message_set_no_reply(struct l_dbus_message *msg, bool on)
@@ -430,12 +422,6 @@ LIB_EXPORT void l_dbus_message_unref(struct l_dbus_message *message)
l_free(message->sender);
}
- if (message->kdbus_sender)
- l_free(message->sender);
-
- if (message->kdbus_destination)
- l_free(message->destination);
-
if (message->signature_free)
l_free(message->signature);
@@ -689,10 +675,6 @@ static bool valid_header(const struct dbus_header *hdr)
if (hdr->version == 1) {
if (hdr->dbus1.serial == 0)
return false;
- } else {
- /* We don't support 64-bit GVariant cookies */
- if (hdr->kdbus.cookie == 0 || (hdr->kdbus.cookie >> 32))
- return false;
}
return true;
@@ -1636,7 +1618,6 @@ void _dbus_message_set_sender(struct l_dbus_message *message,
l_free(message->sender);
message->sender = l_strdup(sender);
- message->kdbus_sender = true;
}
void _dbus_message_set_destination(struct l_dbus_message *message,
@@ -1648,112 +1629,6 @@ void _dbus_message_set_destination(struct l_dbus_message *message,
l_free(message->destination);
message->destination = l_strdup(destination);
- message->kdbus_destination = true;
-}
-
-bool _dbus_kernel_calculate_bloom(struct l_dbus_message *message,
- uint64_t filter[], size_t f_size,
- uint8_t num_hash)
-{
- const char *attr;
- const char *signature;
- void *body;
- size_t body_size;
- struct l_dbus_message_iter iter;
- uint8_t argn;
- char buf[256];
- bool (*get_basic)(struct l_dbus_message_iter *, char, void *);
-
- /* The string "interface:" suffixed by the interface name */
- attr = l_dbus_message_get_interface(message);
- if (attr)
- _dbus_kernel_bloom_add(filter, f_size, num_hash,
- "interface", attr);
-
- /* The string "member:" suffixed by the member name */
- attr = l_dbus_message_get_member(message);
- if (attr)
- _dbus_kernel_bloom_add(filter, f_size, num_hash,
- "member", attr);
-
- /*
- * The string "path:" suffixed by the path name
- *
- * The string "path-slash-prefix:" suffixed with the path name, and
- * also all prefixes of the path name (cut off at "/"), also prefixed
- * with "path-slash-prefix"
- */
- attr = l_dbus_message_get_path(message);
- if (attr) {
- _dbus_kernel_bloom_add(filter, f_size, num_hash, "path", attr);
- _dbus_kernel_bloom_add(filter, f_size, num_hash,
- "path-slash-prefix", attr);
- _dbus_kernel_bloom_add_parents(filter, f_size, num_hash,
- "path-slash-prefix", attr, '/');
- }
-
- /*
- * The string "message-type:" suffixed with the strings "signal",
- * "method_call", "error" or "method_return" for the respective
- * message type of the message.
- */
- _dbus_kernel_bloom_add(filter, f_size, num_hash, "message-type",
- _dbus_message_get_type_as_string(message));
-
- signature = l_dbus_message_get_signature(message);
- if (!signature)
- return true;
-
- body = _dbus_message_get_body(message, &body_size);
-
- if (_dbus_message_is_gvariant(message)) {
- if (!_gvariant_iter_init(&iter, message, signature, NULL,
- body, body_size))
- return false;
-
- get_basic = _gvariant_iter_next_entry_basic;
- } else {
- _dbus1_iter_init(&iter, message, signature, NULL,
- body, body_size);
-
- get_basic = _dbus1_iter_next_entry_basic;
- }
-
- argn = 0;
-
- /*
- * systemd-master/src/libsystemd/sd-bus/PORTING-DBUS1:
- *
- * "If the first argument of the message is a string,
- * "arg0-slash-prefix" suffixed with the first argument, and also
- * all prefixes of the argument (cut off at "/"), also prefixed
- * with "arg0-slash-prefix".
- *
- * Similar for all further arguments that are strings up to 63,
- * for the arguments and their "dot" and "slash" prefixes. On the
- * first argument that is not a string, addition to the bloom
- * filter should be stopped however."
- */
- while (*signature == 's' || *signature == 'o' || *signature == 'g') {
- if (!get_basic(&iter, *signature, &attr))
- return false;
-
- sprintf(buf, "arg%hhu", argn);
- _dbus_kernel_bloom_add(filter, f_size, num_hash, buf, attr);
-
- sprintf(buf, "arg%hhu-slash-prefix", argn);
- _dbus_kernel_bloom_add_parents(filter, f_size, num_hash, buf,
- attr, '/');
-
- sprintf(buf, "arg%hhu-dot-prefix", argn);
- _dbus_kernel_bloom_add_parents(filter, f_size, num_hash, buf,
- attr, '.');
-
- argn += 1;
- signature += 1;
- }
-
- return true;
}
LIB_EXPORT struct l_dbus_message_builder *l_dbus_message_builder_new(
diff --git a/ell/dbus-private.h b/ell/dbus-private.h
index a4118c6..441e668 100644
--- a/ell/dbus-private.h
+++ b/ell/dbus-private.h
@@ -56,11 +56,6 @@ struct dbus_header {
uint32_t serial;
uint32_t field_length;
} __attribute__ ((packed)) dbus1;
-
- struct {
- uint32_t reserved1;
- uint64_t cookie;
- } __attribute__ ((packed)) kdbus;
};
} __attribute__ ((packed));
#define DBUS_HEADER_SIZE 16
@@ -234,46 +229,11 @@ bool _dbus_object_tree_property_changed(struct l_dbus *dbus,
const char *interface_name,
const char *property_name);
-void _dbus_kernel_bloom_add(uint64_t filter[], size_t size, uint8_t num_hash,
- const char *prefix, const char *str);
-void _dbus_kernel_bloom_add_parents(uint64_t filter[], size_t size,
- uint8_t num_hash, const char *prefix,
- const char *str, const char sep);
-
-int _dbus_kernel_create_bus(const char *name);
-
-bool _dbus_kernel_calculate_bloom(struct l_dbus_message *message,
- uint64_t filter[], size_t f_size,
- uint8_t num_hash);
-
-int _dbus_kernel_hello(int fd, const char *connection_name,
- size_t *bloom_size, uint8_t *bloom_n_hash,
- uint64_t *id, void **pool, char **guid);
-void _dbus_kernel_unmap_pool(void *pool);
-
typedef void (*_dbus_name_owner_change_func_t)(const char *name,
uint64_t old_owner,
uint64_t new_owner,
void *user_data);
-int _dbus_kernel_send(int fd, size_t bloom_size, uint8_t n_bloom_hash,
- struct l_dbus_message *message);
-int _dbus_kernel_recv(int fd, void *kdbus_pool,
- l_dbus_message_func_t message_func,
- _dbus_name_owner_change_func_t name_owner_change_func,
- void *user_data);
-
-int _dbus_kernel_name_acquire(int fd, const char *name, bool allow_replacement,
- bool replace_existing, bool queue,
- bool *queued);
-int _dbus_kernel_add_match(int fd, uint64_t bloom_size, uint64_t bloom_n_hash,
- const struct _dbus_filter_condition *rule,
- int rule_len, unsigned int id);
-int _dbus_kernel_remove_match(int fd, unsigned int it);
-int _dbus_kernel_enable_name_owner_notify(int fd);
-uint64_t _dbus_kernel_get_name_owner(int fd, void *kdbus_pool,
- const char *name);
-
uint8_t _dbus_get_version(struct l_dbus *dbus);
int _dbus_get_fd(struct l_dbus *dbus);
struct _dbus_object_tree *_dbus_get_tree(struct l_dbus *dbus);
diff --git a/ell/dbus.c b/ell/dbus.c
index ddc51aa..db69c0d 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -101,14 +101,6 @@ struct l_dbus {
const struct l_dbus_ops *driver;
};
-struct l_dbus_kdbus {
- struct l_dbus super;
- uint8_t bloom_n_hash; /* Number of hash indexes to use */
- size_t bloom_size; /* Size of the filter in bytes */
- uint64_t kdbus_id; /* Unique id */
- void *kdbus_pool; /* KDBus Memory pool */
-};
-
struct l_dbus_classic {
struct l_dbus super;
void *auth_command;
@@ -1154,257 +1146,6 @@ static struct l_dbus *setup_unix(char *params)
return setup_dbus1(fd, guid);
}
-static void kdbus_ready(void *user_data)
-{
- struct l_dbus *dbus = user_data;
-
- bus_ready(dbus);
-}
-
-static void kdbus_free(struct l_dbus *dbus)
-{
- struct l_dbus_kdbus *kdbus =
- container_of(dbus, struct l_dbus_kdbus, super);
-
- if (kdbus->kdbus_pool)
- _dbus_kernel_unmap_pool(kdbus->kdbus_pool);
-
- l_free(kdbus);
-}
-
-static bool kdbus_send_message(struct l_dbus *dbus,
- struct l_dbus_message *message)
-{
- struct l_dbus_kdbus *kdbus =
- container_of(dbus, struct l_dbus_kdbus, super);
- int fd = l_io_get_fd(dbus->io);
- int r;
-
- r = _dbus_kernel_send(fd, kdbus->bloom_size,
- kdbus->bloom_n_hash, message);
- if (r < 0) {
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
- return false;
- }
-
- return true;
-}
-
-struct kdbus_message_recv_data {
- struct l_dbus_message *message;
- struct l_dbus *dbus;
-};
-
-static void kdbus_message_func(struct l_dbus_message *message, void *user_data)
-{
- struct kdbus_message_recv_data *recv_data = user_data;
-
- recv_data->message = message;
-
- l_util_debug(recv_data->dbus->debug_handler,
- recv_data->dbus->debug_data, "Read KDBUS Message");
-}
-
-static void kdbus_name_owner_change_func(const char *name, uint64_t old_owner,
- uint64_t new_owner,
- void *user_data)
-{
- struct kdbus_message_recv_data *recv_data = user_data;
- char owner[32];
-
- l_util_debug(recv_data->dbus->debug_handler,
- recv_data->dbus->debug_data,
- "Read KDBUS Name Owner Change notification");
-
- if (new_owner)
- snprintf(owner, sizeof(owner), ":1.%" PRIu64, new_owner);
- else
- owner[0] = '\0';
-
- _dbus_name_cache_notify(recv_data->dbus->name_cache, name, owner);
-}
-
-static struct l_dbus_message *kdbus_recv_message(struct l_dbus *dbus)
-{
- struct l_dbus_kdbus *kdbus =
- container_of(dbus, struct l_dbus_kdbus, super);
- int fd = l_io_get_fd(dbus->io);
- struct kdbus_message_recv_data recv_data = { NULL, dbus };
- int r;
-
- r = _dbus_kernel_recv(fd, kdbus->kdbus_pool, kdbus_message_func,
- kdbus_name_owner_change_func, &recv_data);
- if (r < 0) {
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
- return NULL;
- }
-
- return recv_data.message;
-}
-
-static bool kdbus_add_match(struct l_dbus *dbus, unsigned int id,
- const struct _dbus_filter_condition *rule,
- int rule_len)
-{
- struct l_dbus_kdbus *kdbus =
- container_of(dbus, struct l_dbus_kdbus, super);
- int fd = l_io_get_fd(dbus->io);
- int r;
-
- r = _dbus_kernel_add_match(fd, kdbus->bloom_size, kdbus->bloom_n_hash,
- rule, rule_len, id);
- if (r < 0)
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
-
- return !r;
-}
-
-static bool kdbus_remove_match(struct l_dbus *dbus, unsigned int id)
-{
- int fd = l_io_get_fd(dbus->io);
- int r;
-
- r = _dbus_kernel_remove_match(fd, id);
- if (r < 0)
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
-
- return !r;
-}
-
-static bool kdbus_get_name_owner(struct l_dbus *dbus, const char *name)
-{
- struct l_dbus_kdbus *kdbus =
- container_of(dbus, struct l_dbus_kdbus, super);
- int fd = l_io_get_fd(dbus->io);
- uint64_t owner_id;
- char owner[32];
- int r;
-
- owner_id = _dbus_kernel_get_name_owner(fd, kdbus->kdbus_pool, name);
-
- if (owner_id)
- snprintf(owner, sizeof(owner), ":1.%" PRIu64, owner_id);
- else
- owner[0] = '\0';
-
- _dbus_name_cache_notify(dbus->name_cache, name, owner);
-
- if (!dbus->name_notify_enabled) {
- r = _dbus_kernel_enable_name_owner_notify(fd);
- if (r < 0)
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
-
- dbus->name_notify_enabled = true;
- }
-
- return true;
-}
-
-static uint32_t kdbus_name_acquire(struct l_dbus *dbus, const char *name,
- bool allow_replacement,
- bool replace_existing, bool queue,
- l_dbus_name_acquire_func_t callback,
- void *user_data)
-{
- int fd = l_io_get_fd(dbus->io);
- bool queued = false;
- bool result;
- int r;
-
- r = _dbus_kernel_name_acquire(fd, name, allow_replacement,
- replace_existing, queue, &queued);
-
- result = r >= 0 || r == -EALREADY;
-
- if (!result)
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, strerror(-r));
-
- if (callback)
- callback(dbus, result, queued, user_data);
-
- return 0;
-}
-
-static const struct l_dbus_ops kdbus_ops = {
- .version = 2,
- .free = kdbus_free,
- .send_message = kdbus_send_message,
- .recv_message = kdbus_recv_message,
- .name_ops = {
- .get_name_owner = kdbus_get_name_owner,
- },
- .filter_ops = {
- .add_match = kdbus_add_match,
- .remove_match = kdbus_remove_match,
- },
- .name_acquire = kdbus_name_acquire,
-};
-
-static struct l_dbus *setup_kdbus(int fd)
-{
- struct l_dbus *dbus;
- struct l_dbus_kdbus *kdbus;
-
- kdbus = l_new(struct l_dbus_kdbus, 1);
- dbus = &kdbus->super;
- dbus->driver = &kdbus_ops;
-
- if (_dbus_kernel_hello(fd, "ell-connection",
- &kdbus->bloom_size, &kdbus->bloom_n_hash,
- &kdbus->kdbus_id, &kdbus->kdbus_pool,
- &dbus->guid) < 0) {
- l_free(dbus);
- close(fd);
- return NULL;
- }
-
- dbus_init(dbus, fd);
-
- dbus->unique_name = l_strdup_printf(":1.%llu", kdbus->kdbus_id);
-
- l_idle_oneshot(kdbus_ready, dbus, NULL);
-
- return dbus;
-}
-
-static struct l_dbus *setup_kernel(char *params)
-{
- char *path = NULL;
- int fd;
-
- while (params) {
- char *key = strsep(¶ms, ",");
- char *value;
-
- if (!key)
- break;
-
- value = strchr(key, '=');
- if (!value)
- continue;
-
- *value++ = '\0';
-
- if (!strcmp(key, "path"))
- path = value;
- }
-
- if (!path)
- return NULL;
-
- fd = open(path, O_RDWR | O_CLOEXEC);
- if (fd < 0)
- return NULL;
-
- return setup_kdbus(fd);
-}
-
static struct l_dbus *setup_address(const char *address)
{
struct l_dbus *dbus = NULL;
@@ -1423,11 +1164,7 @@ static struct l_dbus *setup_address(const char *address)
if (params)
*params++ = '\0';
- if (!strcmp(transport, "kernel")) {
- /* Function will modify params string */
- dbus = setup_kernel(params);
- break;
- } else if (!strcmp(transport, "unix")) {
+ if (!strcmp(transport, "unix")) {
/* Function will modify params string */
dbus = setup_unix(params);
break;
--
2.9.3
5 years, 3 months
l_genl_family_new() successfully returns if generic netlink family doesn't exist.
by Othman, Ossama
Hi,
The function l_genl_family_new() successfully returns if the desired
generic netlink family isn't available in the kernel. For example,
suppose one does the following:
struct l_genl_family * family = l_genl_family_new(genl, "foo");
If the "foo" generic netlink family doesn't exist in the kernel, for
whatever reason, l_genl_family_new() will still return a valid
pointer. Is this the expected behavior?
It looks like some code exists in the implementation that would have
allowed one to be notified of such a problem by calling a
user-specified "vanished" watch callback. Specifically,
l_genl_family_new() constructs a CTRL_ATTR_FAMILY_NAME generic netlink
message with a callback function get_family_callback(). The latter
detects and handles an error like so:
error = l_genl_msg_get_error(msg);
if (error < 0) {
if (family->watch_vanished)
family->watch_vanished(family->watch_data);
return;
}
A "vanished" watch never gets called since there is apparently no way
to set it beforehand. Is that correct?
Thanks!
-Ossama
5 years, 3 months
[PATCH] log: Fix systemd journal PRIORITY field logging
by Ossama Othman
When logging messages to the systemd journal the trailing line feed
character was truncated since the message length was incorrectly
reduced by one. That resulted in the next systemd journal field, in
this case PRIORITY, being written as part of the logged message string
(e.g. "fooPRIORITY=6") rather than as a separate journal field.
---
ell/log.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ell/log.c b/ell/log.c
index e6682cf..6a2e86b 100644
--- a/ell/log.c
+++ b/ell/log.c
@@ -214,7 +214,7 @@ static void log_journal(int priority, const char *file, const char *line,
iov[0].iov_base = "MESSAGE=";
iov[0].iov_len = 8;
iov[1].iov_base = str;
- iov[1].iov_len = str_len - 1;
+ iov[1].iov_len = str_len;
iov[2].iov_base = prio;
iov[2].iov_len = prio_len;
iov[3].iov_base = "CODE_FILE=";
--
2.7.4
5 years, 3 months