From 5972fe953ec56c77936a1e612ca87d8a0e6c0c64 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Jan 2014 16:09:59 +0100 Subject: [PATCH] bus: add support for attaching name to bus connections for debugging purposes --- src/libsystemd/libsystemd.sym | 2 + src/libsystemd/sd-bus/bus-internal.h | 4 ++ src/libsystemd/sd-bus/bus-kernel.c | 57 +++++++++++++++++++++++-- src/libsystemd/sd-bus/sd-bus.c | 30 +++++++++++++ src/libsystemd/sd-bus/test-bus-kernel.c | 14 +++++- src/systemd/sd-bus.h | 2 + 6 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 7798fac34..0942a6e93 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 7c9229377..69e07018d 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 fdb4dab2d..78a6c1062 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -26,6 +26,7 @@ #include #include #include +#include #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 edea7c0ef..a8295b277 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 3dcc5d351..0fab88021 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 4e6c32179..baffd5330 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); -- 2.30.2