diff options
Diffstat (limited to 'src/libsystemd/sd-bus')
26 files changed, 195 insertions, 139 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 95c7d4ebe4..aeb48bedd1 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -32,6 +32,7 @@ #include "bus-message.h" #include "bus-control.h" #include "bus-bloom.h" +#include "bus-util.h" #include "capability.h" _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { @@ -1308,7 +1309,16 @@ int bus_add_match_internal_kernel( break; } - case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: { + case BUS_MATCH_ARG_HAS...BUS_MATCH_ARG_HAS_LAST: { + char buf[sizeof("arg")-1 + 2 + sizeof("-has")]; + + xsprintf(buf, "arg%i-has", c->type - BUS_MATCH_ARG_HAS); + bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str); + using_bloom = true; + break; + } + + case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: /* * XXX: DBus spec defines arg[0..63]path= matching to be * a two-way glob. That is, if either string is a prefix @@ -1322,7 +1332,6 @@ int bus_add_match_internal_kernel( * to properly support multiple-matches here. */ break; - } case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: { char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")]; @@ -1333,7 +1342,7 @@ int bus_add_match_internal_kernel( break; } - case BUS_MATCH_DESTINATION: { + case BUS_MATCH_DESTINATION: /* * Kernel only supports matching on destination IDs, but * not on destination names. So just skip the @@ -1351,7 +1360,6 @@ int bus_add_match_internal_kernel( matches_name_change = false; break; - } case BUS_MATCH_ROOT: case BUS_MATCH_VALUE: diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 79747e058b..af5f7da11c 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -22,6 +22,7 @@ #include "bus-internal.h" #include "bus-message.h" #include "bus-signature.h" +#include "bus-util.h" #include "bus-type.h" _public_ int sd_bus_emit_signal( diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 130fbf7a23..1c365b7fcd 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -31,10 +31,10 @@ #include "fileio.h" #include "audit.h" #include "bus-message.h" +#include "bus-util.h" #include "strv.h" #include "bus-creds.h" #include "bus-label.h" -#include "bus-internal.h" enum { CAP_OFFSET_INHERITABLE = 0, diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index f4ab57f5bc..fea796cd30 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -371,45 +371,3 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) { return 1; } - -bool is_kdbus_wanted(void) { - _cleanup_free_ char *value = NULL; -#ifdef ENABLE_KDBUS - const bool configured = true; -#else - const bool configured = false; -#endif - int r; - - if (get_proc_cmdline_key("kdbus", NULL) > 0) - return true; - - r = get_proc_cmdline_key("kdbus=", &value); - if (r <= 0) - return configured; - - return parse_boolean(value) == 1; -} - -bool is_kdbus_available(void) { - static int cached = -1; - _cleanup_close_ int fd = -1; - struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE }; - - if (cached >= 0) - return (bool) cached; - - if (!is_kdbus_wanted()) { - cached = false; - return false; - } - - fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY); - if (fd < 0) { - cached = false; - return false; - } - - cached = ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0; - return cached; -} diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 9b68fdd642..7af61a9433 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -37,29 +37,6 @@ #include "bus-kernel.h" #include "kdbus.h" -typedef enum BusTransport { - BUS_TRANSPORT_LOCAL, - BUS_TRANSPORT_REMOTE, - BUS_TRANSPORT_MACHINE, - _BUS_TRANSPORT_MAX, - _BUS_TRANSPORT_INVALID = -1 -} BusTransport; - -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_flush_close_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref); - -#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp) -#define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp) -#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp) -#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp) -#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp) -#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp) -#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free) - struct reply_callback { sd_bus_message_handler_t callback; usec_t timeout; @@ -417,9 +394,6 @@ int bus_get_root_path(sd_bus *bus); int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error); -bool is_kdbus_wanted(void); -bool is_kdbus_available(void); - #define bus_assert_return(expr, r, error) \ do { \ if (!assert_log(expr)) \ diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index c2233d0cf3..3107d00092 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -81,6 +81,9 @@ static void introspect_write_flags(struct introspect *i, int type, int flags) { fputs(" <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f); if (type == _SD_BUS_VTABLE_PROPERTY || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) { + if (flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT) + fputs(" <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->f); + if (flags & SD_BUS_VTABLE_PROPERTY_CONST) fputs(" <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f); else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 21f3700128..577a8b44c3 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -45,6 +45,7 @@ #include "bus-message.h" #include "bus-kernel.h" #include "bus-bloom.h" +#include "bus-util.h" #include "bus-label.h" #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -167,6 +168,27 @@ static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, bloom_add_prefixes(data, size, n_hash, buf, t, '/'); } +static void add_bloom_arg_has(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) { + char buf[sizeof("arg")-1 + 2 + sizeof("-has")]; + 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); + } + + strcpy(e, "-has"); + bloom_add_pair(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; @@ -221,7 +243,7 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter 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); + add_bloom_arg_has(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t); if (r < 0) return r; diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index f3b49c0c90..2b83f439a7 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -22,6 +22,7 @@ #include "bus-internal.h" #include "bus-message.h" #include "bus-match.h" +#include "bus-util.h" #include "strv.h" /* Example: @@ -61,12 +62,13 @@ */ static inline bool BUS_MATCH_IS_COMPARE(enum bus_match_node_type t) { - return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_NAMESPACE_LAST; + return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_HAS_LAST; } static inline bool BUS_MATCH_CAN_HASH(enum bus_match_node_type t) { return (t >= BUS_MATCH_MESSAGE_TYPE && t <= BUS_MATCH_PATH) || - (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST); + (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST) || + (t >= BUS_MATCH_ARG_HAS && t <= BUS_MATCH_ARG_HAS_LAST); } static void bus_match_node_free(struct bus_match_node *node) { @@ -178,12 +180,16 @@ static bool value_node_test( case BUS_MATCH_INTERFACE: case BUS_MATCH_MEMBER: case BUS_MATCH_PATH: - case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: { - char **i; + case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: if (value_str) return streq_ptr(node->value.str, value_str); + return false; + + case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: { + char **i; + STRV_FOREACH(i, value_strv) if (streq_ptr(node->value.str, *i)) return true; @@ -191,33 +197,20 @@ static bool value_node_test( return false; } - case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: { - char **i; - + case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: if (value_str) return namespace_simple_pattern(node->value.str, value_str); - STRV_FOREACH(i, value_strv) - if (namespace_simple_pattern(node->value.str, *i)) - return true; return false; - } case BUS_MATCH_PATH_NAMESPACE: return path_simple_pattern(node->value.str, value_str); - case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: { - char **i; - + case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: if (value_str) return path_complex_pattern(node->value.str, value_str); - STRV_FOREACH(i, value_strv) - if (path_complex_pattern(node->value.str, *i)) - return true; - return false; - } default: assert_not_reached("Invalid node type"); @@ -248,6 +241,7 @@ static bool value_node_same( case BUS_MATCH_MEMBER: case BUS_MATCH_PATH: case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: + case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: case BUS_MATCH_PATH_NAMESPACE: case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: @@ -371,15 +365,19 @@ int bus_match_run( break; case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: - (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str, &test_strv); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str); break; case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: - (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str, &test_strv); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str); break; case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: - (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str, &test_strv); + (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str); + break; + + case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: + (void) bus_message_get_arg_strv(m, node->type - BUS_MATCH_ARG_HAS, &test_strv); break; default: @@ -742,6 +740,32 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n return t; } + if (n == 7 && startswith(k, "arg") && startswith(k + 4, "has")) { + int j; + + j = undecchar(k[3]); + if (j < 0) + return -EINVAL; + + return BUS_MATCH_ARG_HAS + j; + } + + if (n == 8 && startswith(k, "arg") && startswith(k + 5, "has")) { + enum bus_match_node_type t; + int a, b; + + a = undecchar(k[3]); + b = undecchar(k[4]); + if (a <= 0 || b < 0) + return -EINVAL; + + t = BUS_MATCH_ARG_HAS + a * 10 + b; + if (t > BUS_MATCH_ARG_HAS_LAST) + return -EINVAL; + + return t; + } + return -EINVAL; } @@ -1110,6 +1134,10 @@ const char* bus_match_node_type_to_string(enum bus_match_node_type t, char buf[] snprintf(buf, l, "arg%inamespace", t - BUS_MATCH_ARG_NAMESPACE); return buf; + case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: + snprintf(buf, l, "arg%ihas", t - BUS_MATCH_ARG_HAS); + return buf; + default: return NULL; } diff --git a/src/libsystemd/sd-bus/bus-match.h b/src/libsystemd/sd-bus/bus-match.h index 56516be9fa..53ee0463ca 100644 --- a/src/libsystemd/sd-bus/bus-match.h +++ b/src/libsystemd/sd-bus/bus-match.h @@ -44,6 +44,8 @@ enum bus_match_node_type { BUS_MATCH_ARG_PATH_LAST = BUS_MATCH_ARG_PATH + 63, BUS_MATCH_ARG_NAMESPACE, BUS_MATCH_ARG_NAMESPACE_LAST = BUS_MATCH_ARG_NAMESPACE + 63, + BUS_MATCH_ARG_HAS, + BUS_MATCH_ARG_HAS_LAST = BUS_MATCH_ARG_HAS + 63, _BUS_MATCH_NODE_TYPE_MAX, _BUS_MATCH_NODE_TYPE_INVALID = -1 }; diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index bc531c2e3a..366a026426 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -35,6 +35,7 @@ #include "bus-type.h" #include "bus-signature.h" #include "bus-gvariant.h" +#include "bus-util.h" static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored); @@ -5613,21 +5614,23 @@ _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) { return 1; } -int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) { - const char *contents; +static int bus_message_get_arg_skip( + sd_bus_message *m, + unsigned i, + char *_type, + const char **_contents) { + unsigned j; - char type; int r; - assert(m); - assert(str); - assert(strv); - r = sd_bus_message_rewind(m, true); if (r < 0) return r; for (j = 0;; j++) { + const char *contents; + char type; + r = sd_bus_message_peek_type(m, &type, &contents); if (r < 0) return r; @@ -5639,31 +5642,56 @@ int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ** !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g"))) return -ENXIO; - if (j >= i) - break; + if (j >= i) { + if (_contents) + *_contents = contents; + if (_type) + *_type = type; + return 0; + } r = sd_bus_message_skip(m, NULL); if (r < 0) return r; } - if (type == SD_BUS_TYPE_ARRAY) { +} - r = sd_bus_message_read_strv(m, strv); - if (r < 0) - return r; +int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str) { + char type; + int r; - *str = NULL; + assert(m); + assert(str); - } else { - r = sd_bus_message_read_basic(m, type, str); - if (r < 0) - return r; + r = bus_message_get_arg_skip(m, i, &type, NULL); + if (r < 0) + return r; - *strv = NULL; - } + if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) + return -ENXIO; - return 0; + return sd_bus_message_read_basic(m, type, str); +} + +int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv) { + const char *contents; + char type; + int r; + + assert(m); + assert(strv); + + r = bus_message_get_arg_skip(m, i, &type, &contents); + if (r < 0) + return r; + + if (type != SD_BUS_TYPE_ARRAY) + return -ENXIO; + if (!STR_IN_SET(contents, "s", "o", "g")) + return -ENXIO; + + return sd_bus_message_read_strv(m, strv); } _public_ int sd_bus_message_get_errno(sd_bus_message *m) { diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index 088d5b1109..ff25003461 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -218,7 +218,8 @@ int bus_message_from_malloc( const char *label, sd_bus_message **ret); -int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv); +int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str); +int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv); int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap); diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index b2e617ada4..0593aa658a 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -26,6 +26,7 @@ #include "bus-type.h" #include "bus-signature.h" #include "bus-introspect.h" +#include "bus-util.h" #include "bus-slot.h" #include "bus-objects.h" @@ -749,6 +750,9 @@ static int vtable_append_all_properties( if (v->flags & SD_BUS_VTABLE_HIDDEN) continue; + if (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT) + continue; + r = vtable_append_one_property(bus, reply, path, c, v, userdata, error); if (r < 0) return r; @@ -1740,8 +1744,9 @@ static int add_object_vtable_internal( if (!member_name_is_valid(v->x.property.member) || !signature_is_single(v->x.property.signature, false) || !(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) || - v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY || + (v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) || (!!(v->flags & SD_BUS_VTABLE_PROPERTY_CONST) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) > 1 || + ((v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) && (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)) || (v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) { r = -EINVAL; goto fail; diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index 7803e39c3d..e43891be25 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -20,6 +20,7 @@ ***/ #include "sd-bus.h" +#include "bus-util.h" #include "bus-internal.h" #include "bus-track.h" diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index 181621ffc7..a1f0f30d6c 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -30,6 +30,7 @@ #include "set.h" #include "sd-bus.h" +#include "bus-internal.h" #include "bus-util.h" #include "bus-dump.h" #include "bus-signature.h" diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 31cdcb4e5b..5285278d92 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -44,6 +44,7 @@ #include "bus-kernel.h" #include "bus-control.h" #include "bus-objects.h" +#include "bus-util.h" #include "bus-container.h" #include "bus-protocol.h" #include "bus-track.h" @@ -1001,6 +1002,8 @@ static int bus_parse_next_address(sd_bus *b) { } static int bus_start_address(sd_bus *b) { + bool container_kdbus_available = false; + bool kdbus_available = false; int r; assert(b); @@ -1010,15 +1013,29 @@ static int bus_start_address(sd_bus *b) { bus_close_fds(b); + /* + * Usually, if you provide multiple different bus-addresses, we + * try all of them in order. We use the first one that + * succeeds. However, if you mix kernel and unix addresses, we + * never try unix-addresses if a previous kernel address was + * tried and kdbus was available. This is required to prevent + * clients to fallback to the bus-proxy if kdbus is available + * but failed (eg., too many connections). + */ + if (b->exec_path) r = bus_socket_exec(b); - else if ((b->nspid > 0 || b->machine) && b->kernel) + else if ((b->nspid > 0 || b->machine) && b->kernel) { r = bus_container_connect_kernel(b); - else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC) + if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT)) + container_kdbus_available = true; + } else if (!container_kdbus_available && (b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC) r = bus_container_connect_socket(b); - else if (b->kernel) + else if (b->kernel) { r = bus_kernel_connect(b); - else if (b->sockaddr.sa.sa_family != AF_UNSPEC) + if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT)) + kdbus_available = true; + } else if (!kdbus_available && b->sockaddr.sa.sa_family != AF_UNSPEC) r = bus_socket_connect(b); else skipped = true; @@ -1173,10 +1190,7 @@ int bus_set_address_system(sd_bus *b) { if (e) return sd_bus_set_address(b, e); - if (is_kdbus_available()) - return sd_bus_set_address(b, KERNEL_SYSTEM_BUS_ADDRESS); - - return sd_bus_set_address(b, UNIX_SYSTEM_BUS_ADDRESS); + return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS); } _public_ int sd_bus_open_system(sd_bus **ret) { @@ -1224,17 +1238,16 @@ int bus_set_address_user(sd_bus *b) { return sd_bus_set_address(b, e); e = secure_getenv("XDG_RUNTIME_DIR"); - if (is_kdbus_available()) - (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()); - else if (e) { + if (e) { _cleanup_free_ char *ee = NULL; ee = bus_address_escape(e); if (!ee) return -ENOMEM; - (void) asprintf(&b->address, UNIX_USER_BUS_ADDRESS_FMT, ee); - } + (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, getuid(), ee); + } else + (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()); if (!b->address) return -ENOMEM; diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c index d3bf6da850..d14110aa04 100644 --- a/src/libsystemd/sd-bus/test-bus-benchmark.c +++ b/src/libsystemd/sd-bus/test-bus-benchmark.c @@ -28,6 +28,7 @@ #include "sd-bus.h" #include "bus-kernel.h" #include "bus-internal.h" +#include "bus-util.h" #define MAX_SIZE (2*1024*1024) diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index a0aecc1f55..20f1b532b7 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -33,6 +33,7 @@ #include "bus-error.h" #include "bus-match.h" #include "bus-internal.h" +#include "bus-util.h" static int match_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m))); diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c index b483d47468..f586880593 100644 --- a/src/libsystemd/sd-bus/test-bus-cleanup.c +++ b/src/libsystemd/sd-bus/test-bus-cleanup.c @@ -22,6 +22,7 @@ #include <stdio.h> #include "sd-bus.h" +#include "bus-util.h" #include "bus-internal.h" #include "bus-message.h" #include "refcnt.h" diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index f2cfbc706f..5753c04b0e 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -20,6 +20,7 @@ ***/ #include "sd-bus.h" +#include "bus-error.h" #include "bus-util.h" #include "errno-list.h" #include "bus-common-errors.h" diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c index 414d4e9a58..b078bdc5f6 100644 --- a/src/libsystemd/sd-bus/test-bus-gvariant.c +++ b/src/libsystemd/sd-bus/test-bus-gvariant.c @@ -27,6 +27,7 @@ #include "macro.h" #include "sd-bus.h" #include "bus-gvariant.h" +#include "bus-util.h" #include "bus-internal.h" #include "bus-message.h" #include "bus-dump.h" diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c index b2caa02870..f39dedeb24 100644 --- a/src/libsystemd/sd-bus/test-bus-introspect.c +++ b/src/libsystemd/sd-bus/test-bus-introspect.c @@ -41,7 +41,7 @@ static const sd_bus_vtable vtable[] = { SD_BUS_PROPERTY("AReadOnlyDeprecatedProperty", "(ut)", prop_get, 0, SD_BUS_VTABLE_DEPRECATED), SD_BUS_PROPERTY("ChangingProperty", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Invalidating", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), - SD_BUS_PROPERTY("Constant", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Constant", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EXPLICIT), SD_BUS_VTABLE_END }; diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c index 90eb1f2a33..f3d1099dd2 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c +++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c @@ -108,8 +108,10 @@ int main(int argc, char *argv[]) { 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='foobar'", false); test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0has='foobar'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0has='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); diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c index 6284153a58..6506eaab2e 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel.c +++ b/src/libsystemd/sd-bus/test-bus-kernel.c @@ -25,8 +25,8 @@ #include "log.h" #include "sd-bus.h" -#include "bus-util.h" #include "bus-kernel.h" +#include "bus-util.h" #include "bus-dump.h" int main(int argc, char *argv[]) { diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c index f659ba3124..75ea28371b 100644 --- a/src/libsystemd/sd-bus/test-bus-match.c +++ b/src/libsystemd/sd-bus/test-bus-match.c @@ -24,6 +24,7 @@ #include "bus-match.h" #include "bus-message.h" +#include "bus-util.h" #include "bus-slot.h" static bool mask[32]; @@ -114,10 +115,10 @@ int main(int argc, char *argv[]) { assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0); assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0); assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0); - assert_se(match_add(slots, &root, "arg4='pi'", 15) >= 0); - assert_se(match_add(slots, &root, "arg4='pa'", 16) >= 0); - assert_se(match_add(slots, &root, "arg4='po'", 17) >= 0); - assert_se(match_add(slots, &root, "arg4='pu'", 18) >= 0); + assert_se(match_add(slots, &root, "arg4has='pi'", 15) >= 0); + assert_se(match_add(slots, &root, "arg4has='pa'", 16) >= 0); + assert_se(match_add(slots, &root, "arg4has='po'", 17) >= 0); + assert_se(match_add(slots, &root, "arg4='pi'", 18) >= 0); bus_match_dump(&root, 0); diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c index 6b3bfad5b6..0a35b750b3 100644 --- a/src/libsystemd/sd-bus/test-bus-objects.c +++ b/src/libsystemd/sd-bus/test-bus-objects.c @@ -30,6 +30,7 @@ #include "sd-bus.h" #include "bus-internal.h" #include "bus-message.h" +#include "bus-util.h" #include "bus-dump.h" struct context { @@ -217,6 +218,7 @@ static const sd_bus_vtable vtable2[] = { SD_BUS_PROPERTY("Value2", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), SD_BUS_PROPERTY("Value3", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Value4", "s", value_handler, 10, 0), + SD_BUS_PROPERTY("AnExplicitProperty", "s", NULL, offsetof(struct context, something), SD_BUS_VTABLE_PROPERTY_EXPLICIT|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), SD_BUS_VTABLE_END }; diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c index 604df098cc..080d8eddb7 100644 --- a/src/libsystemd/sd-bus/test-bus-server.c +++ b/src/libsystemd/sd-bus/test-bus-server.c @@ -28,6 +28,7 @@ #include "sd-bus.h" #include "bus-internal.h" +#include "bus-util.h" struct context { int fds[2]; |