From df9578498f3f566409fcb71229d9fc99e4ab0568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 20 Apr 2020 11:02:39 +0200 Subject: [PATCH] resolve: allow setting the log level dynamically as in pid1 This is useful to raise the log level for a single transaction or a few, without affecting other state of the resolved as a restart would. The log level can only be set, I didn't bother with having the ability to restore the original as in pid1. --- man/org.freedesktop.resolve1.xml | 7 +++++ man/resolvectl.xml | 1 + man/systemctl.xml | 2 +- src/resolve/resolvectl.c | 43 +++++++++++++++++++++++++ src/resolve/resolved-bus.c | 54 +++++++++++++++++++++++++++++++- 5 files changed, 105 insertions(+), 2 deletions(-) diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml index 83ab0ed3d9..3a01a3a8ee 100644 --- a/man/org.freedesktop.resolve1.xml +++ b/man/org.freedesktop.resolve1.xml @@ -145,6 +145,9 @@ node /org/freedesktop/resolve1 { readonly as DNSSECNegativeTrustAnchors = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DNSStubListener = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + @org.freedesktop.systemd1.Privileged("true") + readwrite s LogLevel = '...'; }; interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Introspectable { ... }; @@ -460,6 +463,10 @@ node /org/freedesktop/resolve1 { which DNS is configured and for the system-wide settings if there are any. Note that systemd-resolved assumes DNSSEC is supported by DNS servers until it verifies that this is not the case. Thus, the reported value may initially be true, until the first transactions are executed. + + The LogLevel property shows the (maximum) log level of the manager, with the + same values as the option described in + systemd1. diff --git a/man/resolvectl.xml b/man/resolvectl.xml index 594e22c03f..75be5fe072 100644 --- a/man/resolvectl.xml +++ b/man/resolvectl.xml @@ -175,6 +175,7 @@ automatically, an explicit reverting is not necessary in that case. + diff --git a/man/systemctl.xml b/man/systemctl.xml index fe8b77423a..30880b4110 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1067,7 +1067,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - + log-level [LEVEL] If no argument is given, print the current log level of the manager. If an diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index f20e8c44b8..831901e9b4 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -2516,6 +2516,48 @@ static int verb_revert_link(int argc, char **argv, void *userdata) { return 0; } +static int verb_log_level(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus = userdata; + int r; + + assert(bus); + + if (argc == 1) { + _cleanup_free_ char *level = NULL; + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.resolve1", + "/org/freedesktop/resolve1", + "org.freedesktop.resolve1.Manager", + "LogLevel", + &error, + &level); + if (r < 0) + return log_error_errno(r, "Failed to get log level: %s", bus_error_message(&error, r)); + + puts(level); + + } else { + assert(argc == 2); + + r = sd_bus_set_property( + bus, + "org.freedesktop.resolve1", + "/org/freedesktop/resolve1", + "org.freedesktop.resolve1.Manager", + "LogLevel", + &error, + "s", + argv[1]); + if (r < 0) + return log_error_errno(r, "Failed to set log level: %s", bus_error_message(&error, r)); + } + + return 0; +} + static void help_protocol_types(void) { if (arg_legend) puts("Known protocol types:"); @@ -3190,6 +3232,7 @@ static int native_main(int argc, char *argv[], sd_bus *bus) { { "dnssec", VERB_ANY, 3, 0, verb_dnssec }, { "nta", VERB_ANY, VERB_ANY, 0, verb_nta }, { "revert", VERB_ANY, 2, 0, verb_revert_link }, + { "log-level", VERB_ANY, 2, 0, verb_log_level }, {} }; diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 0f60c42963..badb0ee739 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -16,6 +16,7 @@ #include "socket-netlink.h" #include "stdio-util.h" #include "strv.h" +#include "syslog-util.h" #include "user-util.h" #include "utf8.h" @@ -1835,6 +1836,57 @@ static int bus_method_unregister_service(sd_bus_message *message, void *userdata return call_dnssd_method(m, message, bus_dnssd_method_unregister, error); } +static int property_get_log_level( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + _cleanup_free_ char *t = NULL; + int r; + + assert(bus); + assert(reply); + + r = log_level_to_string_alloc(log_get_max_level(), &t); + if (r < 0) + return r; + + return sd_bus_message_append(reply, "s", t); +} + +static int property_set_log_level( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *value, + void *userdata, + sd_bus_error *error) { + + const char *t; + int r; + + assert(bus); + assert(value); + + r = sd_bus_message_read(value, "s", &t); + if (r < 0) + return r; + + r = log_level_from_string(t); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t); + + log_info("Setting log level to %s.", t); + log_set_max_level(r); + + return 0; +} + static const sd_bus_vtable resolve_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), @@ -1853,7 +1905,7 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0), SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0), - + SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0), SD_BUS_METHOD_WITH_NAMES("ResolveHostname", "isit",