From ee502e0c28a611470a4e10b0c90bade6ff7fa389 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Dec 2014 19:11:48 +0100 Subject: sd-bus: teach x-container-unix: bus protoocol to connect to the namespace of a PID instead of a container name --- src/libsystemd/sd-bus/bus-container.c | 26 ++++++++----- src/libsystemd/sd-bus/bus-internal.h | 1 + src/libsystemd/sd-bus/sd-bus.c | 69 +++++++++++++++++++++++++++-------- 3 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c index dd4bf1512e..d29b98a269 100644 --- a/src/libsystemd/sd-bus/bus-container.c +++ b/src/libsystemd/sd-bus/bus-container.c @@ -30,19 +30,22 @@ int bus_container_connect_socket(sd_bus *b) { _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1; - pid_t leader, child; + pid_t child; siginfo_t si; int r; assert(b); assert(b->input_fd < 0); assert(b->output_fd < 0); + assert(b->nspid > 0 || b->machine); - r = container_get_leader(b->machine, &leader); - if (r < 0) - return r; + if (b->nspid <= 0) { + r = container_get_leader(b->machine, &b->nspid); + if (r < 0) + return r; + } - r = namespace_open(leader, &pidnsfd, &mntnsfd, NULL, &rootfd); + r = namespace_open(b->nspid, &pidnsfd, &mntnsfd, NULL, &rootfd); if (r < 0) return r; @@ -127,7 +130,7 @@ int bus_container_connect_kernel(sd_bus *b) { .msg_controllen = sizeof(control), }; struct cmsghdr *cmsg; - pid_t leader, child; + pid_t child; siginfo_t si; int r; _cleanup_close_ int fd = -1; @@ -135,12 +138,15 @@ int bus_container_connect_kernel(sd_bus *b) { assert(b); assert(b->input_fd < 0); assert(b->output_fd < 0); + assert(b->nspid > 0 || b->machine); - r = container_get_leader(b->machine, &leader); - if (r < 0) - return r; + if (b->nspid <= 0) { + r = container_get_leader(b->machine, &b->nspid); + if (r < 0) + return r; + } - r = namespace_open(leader, &pidnsfd, &mntnsfd, NULL, &rootfd); + r = namespace_open(b->nspid, &pidnsfd, &mntnsfd, NULL, &rootfd); if (r < 0) return r; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index cb529d5a9e..48c20c97fc 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -245,6 +245,7 @@ struct sd_bus { char *kernel; char *machine; + pid_t nspid; sd_id128_t server_id; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index fd59bac557..69ee239523 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -756,7 +756,7 @@ static int parse_kernel_address(sd_bus *b, const char **p, char **guid) { } static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) { - _cleanup_free_ char *machine = NULL; + _cleanup_free_ char *machine = NULL, *pid = NULL; int r; assert(b); @@ -777,18 +777,36 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) else if (r > 0) continue; + r = parse_address_key(p, "pid", &pid); + if (r < 0) + return r; + else if (r > 0) + continue; + skip_address_key(p); } - if (!machine) + if (!machine == !pid) return -EINVAL; - if (!machine_name_is_valid(machine)) - return -EINVAL; + if (machine) { + if (!machine_name_is_valid(machine)) + return -EINVAL; - free(b->machine); - b->machine = machine; - machine = NULL; + free(b->machine); + b->machine = machine; + machine = NULL; + } else { + free(b->machine); + b->machine = NULL; + } + + if (pid) { + r = parse_pid(pid, &b->nspid); + if (r < 0) + return r; + } else + b->nspid = 0; b->sockaddr.un.sun_family = AF_UNIX; strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path)); @@ -798,7 +816,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) } static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid) { - _cleanup_free_ char *machine = NULL; + _cleanup_free_ char *machine = NULL, *pid = NULL; int r; assert(b); @@ -819,18 +837,36 @@ static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid else if (r > 0) continue; + r = parse_address_key(p, "pid", &pid); + if (r < 0) + return r; + else if (r > 0) + continue; + skip_address_key(p); } - if (!machine) + if (!machine == !pid) return -EINVAL; - if (!machine_name_is_valid(machine)) - return -EINVAL; + if (machine) { + if (!machine_name_is_valid(machine)) + return -EINVAL; - free(b->machine); - b->machine = machine; - machine = NULL; + free(b->machine); + b->machine = machine; + machine = NULL; + } else { + free(b->machine); + b->machine = NULL; + } + + if (pid) { + r = parse_pid(pid, &b->nspid); + if (r < 0) + return r; + } else + b->nspid = 0; free(b->kernel); b->kernel = strdup("/sys/fs/kdbus/0-system/bus"); @@ -854,6 +890,7 @@ static void bus_reset_parsed_address(sd_bus *b) { b->kernel = NULL; free(b->machine); b->machine = NULL; + b->nspid = 0; } static int bus_parse_next_address(sd_bus *b) { @@ -958,9 +995,9 @@ static int bus_start_address(sd_bus *b) { if (b->exec_path) r = bus_socket_exec(b); - else if (b->machine && b->kernel) + else if ((b->nspid > 0 || b->machine) && b->kernel) r = bus_container_connect_kernel(b); - else if (b->machine && b->sockaddr.sa.sa_family != AF_UNSPEC) + else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC) r = bus_container_connect_socket(b); else if (b->kernel) r = bus_kernel_connect(b); -- cgit v1.2.3-54-g00ecf