summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-12-23 19:11:48 +0100
committerLennart Poettering <lennart@poettering.net>2014-12-23 19:15:27 +0100
commitee502e0c28a611470a4e10b0c90bade6ff7fa389 (patch)
treeaaab86433eaf963b6615962534ccee5463390b77
parent080bfdbb8e9f3d23594b101d7f50e7e2f9e4699b (diff)
sd-bus: teach x-container-unix: bus protoocol to connect to the namespace of a PID instead of a container name
-rw-r--r--src/libsystemd/sd-bus/bus-container.c26
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h1
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c69
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);