summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/sd-bus.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-10-30 15:34:50 +0100
committerLennart Poettering <lennart@poettering.net>2013-10-30 15:37:02 +0100
commita7893c6b28772edbc7e1fea3c209caa54d465648 (patch)
treeae9e44874c63592f44321b9fc9ed07b2c808ef58 /src/libsystemd-bus/sd-bus.c
parent0f8bd8debb0ff7f5bff7738841931f6c41e40bc1 (diff)
bus: add API call to create bus connection to the system bus of local containers
Also, add support for this to machinectl, so that we can enumerate the machines that run inside a container. We must go deeper!
Diffstat (limited to 'src/libsystemd-bus/sd-bus.c')
-rw-r--r--src/libsystemd-bus/sd-bus.c109
1 files changed, 102 insertions, 7 deletions
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 383b035b7e..f42d5d0ee1 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -46,6 +46,7 @@
#include "bus-signature.h"
#include "bus-objects.h"
#include "bus-util.h"
+#include "bus-container.h"
static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
@@ -117,6 +118,7 @@ static void bus_free(sd_bus *b) {
free(b->auth_buffer);
free(b->address);
free(b->kernel);
+ free(b->machine);
free(b->exec_path);
strv_free(b->exec_argv);
@@ -753,6 +755,45 @@ static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
return 0;
}
+static int parse_container_address(sd_bus *b, const char **p, char **guid) {
+ _cleanup_free_ char *machine = NULL;
+ int r;
+
+ assert(b);
+ assert(p);
+ assert(*p);
+ assert(guid);
+
+ while (**p != 0 && **p != ';') {
+ r = parse_address_key(p, "guid", guid);
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ continue;
+
+ r = parse_address_key(p, "machine", &machine);
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ continue;
+
+ skip_address_key(p);
+ }
+
+ if (!machine)
+ return -EINVAL;
+
+ free(b->machine);
+ b->machine = machine;
+ machine = NULL;
+
+ 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));
+ b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1;
+
+ return 0;
+}
+
static void bus_reset_parsed_address(sd_bus *b) {
assert(b);
@@ -765,6 +806,8 @@ static void bus_reset_parsed_address(sd_bus *b) {
b->server_id = SD_ID128_NULL;
free(b->kernel);
b->kernel = NULL;
+ free(b->machine);
+ b->machine = NULL;
}
static int bus_parse_next_address(sd_bus *b) {
@@ -824,6 +867,14 @@ static int bus_parse_next_address(sd_bus *b) {
return r;
break;
+ } else if (startswith(a, "x-container:")) {
+
+ a += 12;
+ r = parse_container_address(b, &a, &guid);
+ if (r < 0)
+ return r;
+
+ break;
}
a = strchr(a, ';');
@@ -849,24 +900,32 @@ static int bus_start_address(sd_bus *b) {
for (;;) {
sd_bus_close(b);
- if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
+ if (b->exec_path) {
- r = bus_socket_connect(b);
+ r = bus_socket_exec(b);
if (r >= 0)
return r;
b->last_connect_error = -r;
+ } else if (b->kernel) {
- } else if (b->exec_path) {
+ r = bus_kernel_connect(b);
+ if (r >= 0)
+ return r;
- r = bus_socket_exec(b);
+ b->last_connect_error = -r;
+
+ } else if (b->machine) {
+
+ r = bus_container_connect(b);
if (r >= 0)
return r;
b->last_connect_error = -r;
- } else if (b->kernel) {
- r = bus_kernel_connect(b);
+ } else if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
+
+ r = bus_socket_connect(b);
if (r >= 0)
return r;
@@ -937,7 +996,7 @@ int sd_bus_start(sd_bus *bus) {
if (bus->input_fd >= 0)
r = bus_start_fd(bus);
- else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel)
+ else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel || bus->machine)
r = bus_start_address(bus);
else
return -EINVAL;
@@ -1069,6 +1128,42 @@ int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
return 0;
}
+int sd_bus_open_system_container(const char *machine, sd_bus **ret) {
+ _cleanup_free_ char *e = NULL;
+ sd_bus *bus;
+ char *p;
+ int r;
+
+ assert_return(machine, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ e = bus_address_escape(machine);
+ if (!e)
+ return -ENOMEM;
+
+ p = strjoin("x-container:machine=", e, NULL);
+ if (!p)
+ return -ENOMEM;
+
+ r = sd_bus_new(&bus);
+ if (r < 0) {
+ free(p);
+ return r;
+ }
+
+ bus->address = p;
+ bus->bus_client = true;
+
+ r = sd_bus_start(bus);
+ if (r < 0) {
+ bus_free(bus);
+ return r;
+ }
+
+ *ret = bus;
+ return 0;
+}
+
void sd_bus_close(sd_bus *bus) {
if (!bus)
return;