From 1a29929959fd8f59e19ce60c25d1a1f7d910fac0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Nov 2014 21:28:13 +0100 Subject: [PATCH] kdbus: set kernel attach mask before creating the first bus --- src/core/manager.c | 7 +- src/libsystemd/sd-bus/bus-kernel.c | 35 +++++++++- src/libsystemd/sd-bus/bus-kernel.h | 2 + src/libsystemd/sd-bus/test-bus-kernel.c | 2 + src/shared/util.c | 85 +++++++++++++++++-------- src/shared/util.h | 1 + 6 files changed, 103 insertions(+), 29 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 7af502aba..0d1f5bb10 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -722,7 +722,12 @@ static int manager_setup_kdbus(Manager *m) { if (m->test_run || m->kdbus_fd >= 0) return 0; - m->kdbus_fd = bus_kernel_create_bus(m->running_as == SYSTEMD_SYSTEM ? "system" : "user", m->running_as == SYSTEMD_SYSTEM, &p); + bus_kernel_fix_attach_mask(); + + m->kdbus_fd = bus_kernel_create_bus( + m->running_as == SYSTEMD_SYSTEM ? "system" : "user", + m->running_as == SYSTEMD_SYSTEM, &p); + if (m->kdbus_fd < 0) { log_debug("Failed to set up kdbus: %s", strerror(-m->kdbus_fd)); return m->kdbus_fd; diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 3bf7b074e..759d566eb 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -32,6 +32,8 @@ #include "util.h" #include "strv.h" #include "memfd-util.h" +#include "cgroup-util.h" +#include "fileio.h" #include "bus-internal.h" #include "bus-message.h" @@ -39,7 +41,6 @@ #include "bus-bloom.h" #include "bus-util.h" #include "bus-label.h" -#include "cgroup-util.h" #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -1796,3 +1797,35 @@ int bus_kernel_realize_attach_flags(sd_bus *bus) { return 0; } + +int bus_kernel_fix_attach_mask(void) { + _cleanup_free_ char *mask = NULL; + uint64_t m = (uint32_t) -1; + char buf[2+16+2]; + int r; + + r = get_proc_cmdline_key("systemd.kdbus_attach_flags_mask=", &mask); + if (r < 0) { + log_warning_errno(-r, "Failed to read kernel command line: %m"); + return r; + } + + if (mask) { + const char *p = mask; + + if (startswith(p, "0x")) + p += 2; + + if (sscanf(p, "%" PRIx64, &m) != 1) + log_warning("Couldn't parse systemd.kdbus_attach_flags_mask= kernel command line parameter."); + } + + sprintf(buf, "0x%" PRIx64 "\n", m); + r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf); + if (r < 0) { + log_warning_errno(-r, "Failed to write kdbus attach mask: %m"); + return r; + } + + return 0; +} diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h index 8994b35f5..0db8fd35a 100644 --- a/src/libsystemd/sd-bus/bus-kernel.h +++ b/src/libsystemd/sd-bus/bus-kernel.h @@ -89,3 +89,5 @@ int bus_kernel_try_close(sd_bus *bus); int bus_kernel_drop_one(int fd); int bus_kernel_realize_attach_flags(sd_bus *bus); + +int bus_kernel_fix_attach_mask(void); diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c index 0e6c2ac40..485c396bd 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel.c +++ b/src/libsystemd/sd-bus/test-bus-kernel.c @@ -45,6 +45,8 @@ int main(int argc, char *argv[]) { assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); + bus_kernel_fix_attach_mask(); + bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; diff --git a/src/shared/util.c b/src/shared/util.c index e987abc42..d3eec5f87 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6270,38 +6270,16 @@ int split_pair(const char *s, const char *sep, char **l, char **r) { } int shall_restore_state(void) { - _cleanup_free_ char *line = NULL; - const char *p; + _cleanup_free_ char *value = NULL; int r; - r = proc_cmdline(&line); + r = get_proc_cmdline_key("systemd.restore_state=", &value); if (r < 0) return r; + if (r == 0) + return true; - r = 1; - p = line; - - for (;;) { - _cleanup_free_ char *word = NULL; - const char *e; - int k; - - k = unquote_first_word(&p, &word, true); - if (k < 0) - return k; - if (k == 0) - break; - - e = startswith(word, "systemd.restore_state="); - if (!e) - continue; - - k = parse_boolean(e); - if (k >= 0) - r = k; - } - - return r; + return parse_boolean(value) != 0; } int proc_cmdline(char **ret) { @@ -6352,6 +6330,59 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) { return 0; } +int get_proc_cmdline_key(const char *key, char **value) { + _cleanup_free_ char *line = NULL, *ret = NULL; + bool found = false; + const char *p; + int r; + + assert(key); + + r = proc_cmdline(&line); + if (r < 0) + return r; + + p = line; + for (;;) { + _cleanup_free_ char *word = NULL; + const char *e; + + r = unquote_first_word(&p, &word, true); + if (r < 0) + return r; + if (r == 0) + break; + + /* Filter out arguments that are intended only for the + * initrd */ + if (!in_initrd() && startswith(word, "rd.")) + continue; + + if (value) { + e = startswith(word, key); + if (!e) + continue; + + r = free_and_strdup(&ret, e); + if (r < 0) + return r; + + found = true; + } else { + if (streq(word, key)) + found = true; + } + } + + if (value) { + *value = ret; + ret = NULL; + } + + return found; + +} + int container_get_leader(const char *machine, pid_t *pid) { _cleanup_free_ char *s = NULL, *class = NULL; const char *p; diff --git a/src/shared/util.h b/src/shared/util.h index d36a63278..13da9426d 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -972,6 +972,7 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, int proc_cmdline(char **ret); int parse_proc_cmdline(int (*parse_word)(const char *key, const char *value)); +int get_proc_cmdline_key(const char *parameter, char **value); int container_get_leader(const char *machine, pid_t *pid); -- 2.30.2