diff options
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 39 |
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; |