summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/sd-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c39
1 files changed, 26 insertions, 13 deletions
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;