X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=58f011ff86b65a83827b420f382f2afc7e5ab76c;hb=1797280193ea25a91cc38332c7cee34ba01e7808;hp=3bf7b074efb3ad7a3adcea27b8230233cd848a10;hpb=38ce47e262fbb76b6f6514e8e80cacfc584bee5a;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 3bf7b074e..58f011ff8 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)) @@ -953,24 +954,37 @@ int bus_kernel_connect(sd_bus *b) { return bus_kernel_take_fd(b); } +int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) { + struct kdbus_cmd_free cmd = { + .flags = 0, + .offset = offset, + }; + int r; + + assert(bus); + assert(bus->is_kernel); + + r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd); + if (r < 0) + return -errno; + + return 0; +} + static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { - struct kdbus_cmd_free cmd = {}; struct kdbus_item *d; assert(bus); assert(k); - cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer; - KDBUS_ITEM_FOREACH(d, k, items) { - if (d->type == KDBUS_ITEM_FDS) close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int)); else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD) safe_close(d->memfd.fd); } - (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd); + bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer); } int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) { @@ -1058,7 +1072,7 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call /* Anybody can send us invalid messages, let's just drop them. */ if (r == -EBADMSG || r == -EPROTOTYPE) - log_debug("Ignoring invalid message: %s", strerror(-r)); + log_debug_errno(r, "Ignoring invalid message: %m"); else return r; } @@ -1242,7 +1256,7 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) { /* Anybody can send us invalid messages, let's just drop them. */ if (r == -EBADMSG || r == -EPROTOTYPE) { - log_debug("Ignoring invalid message: %s", strerror(-r)); + log_debug_errno(r, "Ignoring invalid message: %m"); r = 0; } @@ -1796,3 +1810,74 @@ 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 = (uint64_t) -1; + char buf[2+16+2]; + int r; + + /* By default we don't want any kdbus metadata fields to be + * suppressed, hence we reset the kernel mask for it to + * (uint64_t) -1. This is overridable via a kernel command + * line option, however. */ + + r = get_proc_cmdline_key("systemd.kdbus_attach_flags_mask=", &mask); + if (r < 0) + return log_warning_errno(r, "Failed to read kernel command line: %m"); + + 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) + return log_full_errno( + r == -EROFS ? LOG_DEBUG : LOG_WARNING, r, + "Failed to write kdbus attach mask: %m"); + + return 0; +} + +int bus_kernel_get_bus_name(sd_bus *bus, char **name) { + struct kdbus_cmd_info cmd = { + .size = sizeof(struct kdbus_cmd_info), + }; + struct kdbus_info *info; + struct kdbus_item *item; + char *n = NULL; + int r; + + assert(bus); + assert(name); + assert(bus->is_kernel); + + r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd); + if (r < 0) + return -errno; + + info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset); + + KDBUS_ITEM_FOREACH(item, info, items) + if (item->type == KDBUS_ITEM_MAKE_NAME) { + r = free_and_strdup(&n, item->str); + break; + } + + bus_kernel_cmd_free(bus, cmd.offset); + + if (r < 0) + return r; + if (!n) + return -EIO; + + *name = n; + return 0; +}