summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-01-22 16:09:59 +0100
committerLennart Poettering <lennart@poettering.net>2014-01-22 16:09:59 +0100
commit5972fe953ec56c77936a1e612ca87d8a0e6c0c64 (patch)
tree515ee99fed073c4184a84eb5ee7cdb55bdf43900
parentbus: extend memfd api so that we can label memfds for debugging purposes (diff)
downloadsystemd-5972fe953ec56c77936a1e612ca87d8a0e6c0c64.tar.xz
systemd-5972fe953ec56c77936a1e612ca87d8a0e6c0c64.zip
bus: add support for attaching name to bus connections for debugging purposes
-rw-r--r--src/libsystemd/libsystemd.sym2
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h4
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c57
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c30
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel.c14
-rw-r--r--src/systemd/sd-bus.h2
6 files changed, 104 insertions, 5 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 7798fac342..0942a6e93e 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -26,6 +26,7 @@ global:
sd_bus_set_server;
sd_bus_set_anonymous;
sd_bus_set_trusted;
+ sd_bus_set_name;
sd_bus_negotiate_fds;
sd_bus_negotiate_timestamp;
sd_bus_negotiate_creds;
@@ -38,6 +39,7 @@ global:
sd_bus_can_send;
sd_bus_get_server_id;
sd_bus_get_peer_creds;
+ sd_bus_get_name;
sd_bus_send;
sd_bus_send_to;
sd_bus_get_fd;
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 7c92293771..69e07018d8 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -164,6 +164,8 @@ struct sd_bus {
bool trusted:1;
bool fake_creds_valid:1;
bool manual_peer_interface:1;
+ bool is_system:1;
+ bool is_user:1;
int use_memfd;
@@ -267,6 +269,8 @@ struct sd_bus {
char *fake_label;
char *cgroup_root;
+
+ char *connection_name;
};
#define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index fdb4dab2da..78a6c1062a 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <malloc.h>
#include <sys/mman.h>
+#include <sys/prctl.h>
#include "util.h"
#include "strv.h"
@@ -628,7 +629,9 @@ fail:
int bus_kernel_take_fd(sd_bus *b) {
struct kdbus_cmd_hello *hello;
struct kdbus_item *item;
- size_t l = 0, sz;
+ _cleanup_free_ char *g = NULL;
+ const char *name;
+ size_t l = 0, m = 0, sz;
int r;
assert(b);
@@ -638,10 +641,52 @@ int bus_kernel_take_fd(sd_bus *b) {
b->use_memfd = 1;
- sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
+ if (b->connection_name) {
+ g = sd_bus_label_escape(b->connection_name);
+ if (!g)
+ return -ENOMEM;
+
+ name = g;
+ } else {
+ char pr[17] = {};
+
+ /* If no name is explicitly set, we'll include a hint
+ * indicating the library implementation, a hint which
+ * kind of bus this is and the thread name */
+
+ assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
+
+ if (isempty(pr)) {
+ name = b->is_system ? "sd-system" :
+ b->is_user ? "sd-user" : "sd";
+ } else {
+ _cleanup_free_ char *e = NULL;
+
+ e = sd_bus_label_escape(pr);
+ if (!e)
+ return -ENOMEM;
+
+ g = strappend(b->is_system ? "sd-system-" :
+ b->is_user ? "sd-user-" : "sd-",
+ e);
+ if (!g)
+ return -ENOMEM;
+
+ name = g;
+ }
+
+ b->connection_name = sd_bus_label_unescape(name);
+ if (!b->connection_name)
+ return -ENOMEM;
+ }
+
+ m = strlen(name);
+
+ sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
+ ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
if (b->fake_creds_valid)
- sz += ALIGN8(offsetof(struct kdbus_item, creds)) + sizeof(struct kdbus_creds);
+ sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
if (b->fake_label) {
l = strlen(b->fake_label);
@@ -656,6 +701,11 @@ int bus_kernel_take_fd(sd_bus *b) {
item = hello->items;
+ item->size = offsetof(struct kdbus_item, str) + m + 1;
+ item->type = KDBUS_ITEM_CONN_NAME;
+ memcpy(item->str, name, m + 1);
+ item = KDBUS_ITEM_NEXT(item);
+
if (b->fake_creds_valid) {
item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
item->type = KDBUS_ITEM_CREDS;
@@ -666,6 +716,7 @@ int bus_kernel_take_fd(sd_bus *b) {
if (b->fake_label) {
item->size = offsetof(struct kdbus_item, str) + l + 1;
+ item->type = KDBUS_ITEM_SECLABEL;
memcpy(item->str, b->fake_label, l+1);
}
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index edea7c0ef6..a8295b2778 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -144,6 +144,7 @@ static void bus_free(sd_bus *b) {
free(b->machine);
free(b->fake_label);
free(b->cgroup_root);
+ free(b->connection_name);
free(b->exec_path);
strv_free(b->exec_argv);
@@ -334,6 +335,24 @@ _public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
return 0;
}
+_public_ int sd_bus_set_name(sd_bus *bus, const char *name) {
+ char *n;
+
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ n = strdup(name);
+ if (!n)
+ return -ENOMEM;
+
+ free(bus->connection_name);
+ bus->connection_name = n;
+
+ return 0;
+}
+
static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
const char *s;
int r;
@@ -1053,6 +1072,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) {
goto fail;
b->bus_client = true;
+ b->is_system = true;
/* Let's do per-method access control on the system bus. We
* need the caller's UID and capability set for that. */
@@ -1118,6 +1138,7 @@ _public_ int sd_bus_open_user(sd_bus **ret) {
}
b->bus_client = true;
+ b->is_user = true;
/* We don't do any per-method access control on the user
* bus. */
@@ -3034,3 +3055,12 @@ _public_ int sd_bus_try_close(sd_bus *bus) {
sd_bus_close(bus);
return 0;
}
+
+_public_ int sd_bus_get_name(sd_bus *bus, const char **name) {
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ *name = bus->connection_name;
+ return 0;
+}
diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c
index 3dcc5d351d..0fab88021d 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel.c
@@ -39,6 +39,7 @@ int main(int argc, char *argv[]) {
const char *ua = NULL, *ub = NULL, *the_string = NULL;
sd_bus *a, *b;
int r, pipe_fds[2];
+ const char *nn;
log_set_max_level(LOG_DEBUG);
@@ -59,6 +60,9 @@ int main(int argc, char *argv[]) {
r = sd_bus_new(&b);
assert_se(r >= 0);
+ r = sd_bus_set_name(a, "a");
+ assert_se(r >= 0);
+
r = sd_bus_set_address(a, address);
assert_se(r >= 0);
@@ -79,14 +83,20 @@ int main(int argc, char *argv[]) {
r = sd_bus_get_unique_name(a, &ua);
assert_se(r >= 0);
-
printf("unique a: %s\n", ua);
- r = sd_bus_get_unique_name(b, &ub);
+ r = sd_bus_get_name(a, &nn);
assert_se(r >= 0);
+ printf("name of a: %s\n", nn);
+ r = sd_bus_get_unique_name(b, &ub);
+ assert_se(r >= 0);
printf("unique b: %s\n", ub);
+ r = sd_bus_get_name(b, &nn);
+ assert_se(r >= 0);
+ printf("name of b: %s\n", nn);
+
r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay");
assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN));
assert_se(r == -EHOSTUNREACH);
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 4e6c321798..baffd5330e 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -110,6 +110,7 @@ int sd_bus_set_bus_client(sd_bus *bus, int b);
int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id);
int sd_bus_set_anonymous(sd_bus *bus, int b);
int sd_bus_set_trusted(sd_bus *bus, int b);
+int sd_bus_set_name(sd_bus *bus, const char *name);
int sd_bus_negotiate_fds(sd_bus *bus, int b);
int sd_bus_negotiate_timestamp(sd_bus *bus, int b);
int sd_bus_negotiate_creds(sd_bus *bus, uint64_t creds_mask);
@@ -125,6 +126,7 @@ int sd_bus_is_open(sd_bus *bus);
int sd_bus_can_send(sd_bus *bus, char type);
int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *peer);
int sd_bus_get_peer_creds(sd_bus *bus, uint64_t creds_mask, sd_bus_creds **ret);
+int sd_bus_get_name(sd_bus *bus, const char **name);
int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie);
int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie);