summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-11-28 17:44:05 +0100
committerLennart Poettering <lennart@poettering.net>2014-11-28 20:29:44 +0100
commit1abe54d9a9292d746e5990843bbbc509984b7f2c (patch)
tree803c93dc51bfa1b0a7c65a77279ef2209341ee10 /src/libsystemd
parenta6a6ac16030ea8683dfb1916d13a0b577bf3b512 (diff)
sd-bus: add arrays of strings in the bloom filter
Let's do this right from the beginning, to prepare ground for udev messages that most likely want to store list of strings (for device tags) in messages, and filter on them.
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c77
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c51
2 files changed, 82 insertions, 46 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 58f011ff86..aaf44e3e75 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -135,6 +135,32 @@ static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
*d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
}
+static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
+ char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
+ char *e;
+
+ assert(data);
+ assert(size > 0);
+ assert(i < 64);
+ assert(t);
+
+ e = stpcpy(buf, "arg");
+ if (i < 10)
+ *(e++) = '0' + (char) i;
+ else {
+ *(e++) = '0' + (char) (i / 10);
+ *(e++) = '0' + (char) (i % 10);
+ }
+
+ *e = 0;
+ bloom_add_pair(data, size, n_hash, buf, t);
+
+ strcpy(e, "-dot-prefix");
+ bloom_add_prefixes(data, size, n_hash, buf, t, '.');
+ strcpy(e, "-slash-prefix");
+ bloom_add_prefixes(data, size, n_hash, buf, t, '/');
+}
+
static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
void *data;
unsigned i;
@@ -164,39 +190,42 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter
return r;
for (i = 0; i < 64; i++) {
+ const char *t, *contents;
char type;
- const char *t;
- char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
- char *e;
- r = sd_bus_message_peek_type(m, &type, NULL);
+ r = sd_bus_message_peek_type(m, &type, &contents);
if (r < 0)
return r;
- if (type != SD_BUS_TYPE_STRING &&
- type != SD_BUS_TYPE_OBJECT_PATH &&
- type != SD_BUS_TYPE_SIGNATURE)
- break;
+ if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
- r = sd_bus_message_read_basic(m, type, &t);
- if (r < 0)
- return r;
+ /* The bloom filter includes simple strings of any kind */
+ r = sd_bus_message_read_basic(m, type, &t);
+ if (r < 0)
+ return r;
- e = stpcpy(buf, "arg");
- if (i < 10)
- *(e++) = '0' + (char) i;
- else {
- *(e++) = '0' + (char) (i / 10);
- *(e++) = '0' + (char) (i % 10);
- }
+ add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
+ } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
- *e = 0;
- bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
+ /* As well as array of simple strings of any kinds */
+ r = sd_bus_message_enter_container(m, type, contents);
+ if (r < 0)
+ return r;
+
+ while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
+ add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
+ if (r < 0)
+ return r;
- strcpy(e, "-dot-prefix");
- bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
- strcpy(e, "-slash-prefix");
- bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+
+ } else
+ /* Stop adding to bloom filter as soon as we
+ * run into the first argument we cannot add
+ * to it. */
+ break;
}
return 0;
diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
index 5ee6eea0e8..071b7e0cf9 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
@@ -32,6 +32,7 @@ static void test_one(
const char *path,
const char *interface,
const char *member,
+ bool as_list,
const char *arg0,
const char *match,
bool good) {
@@ -76,7 +77,11 @@ static void test_one(
assert_se(r >= 0);
log_debug("signal");
- r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
+
+ if (as_list)
+ r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0);
+ else
+ r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
assert_se(r >= 0);
r = sd_bus_process(b, &m);
@@ -89,27 +94,29 @@ static void test_one(
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/tuut'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "interface='waldo.com'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Piep'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Pi_ep'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foo_bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/quux'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/quux'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/tuut'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "interface='waldo.com'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Piep'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Pi_ep'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foo_bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
+
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/quux'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false);
return 0;
}