Merge pull request #15495 from keszybz/resolve-debugging-and-stub-handling
Resolve debugging and stub handling
This commit is contained in:
@@ -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 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -1350,7 +1350,16 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
||||
}
|
||||
|
||||
if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
|
||||
dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
|
||||
DnsTransactionState result;
|
||||
|
||||
if (t->scope->protocol == DNS_PROTOCOL_LLMNR)
|
||||
/* If we didn't find anything on LLMNR, it's not an error, but a failure to resolve
|
||||
* the name. */
|
||||
result = DNS_TRANSACTION_NOT_FOUND;
|
||||
else
|
||||
result = DNS_TRANSACTION_ATTEMPTS_MAX_REACHED;
|
||||
|
||||
dns_transaction_complete(t, result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "dns-domain.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "ordered-set.h"
|
||||
#include "resolved-conf.h"
|
||||
#include "resolved-dns-server.h"
|
||||
@@ -27,41 +28,30 @@
|
||||
#define PRIVATE_STATIC_RESOLV_CONF ROOTLIBEXECDIR "/resolv.conf"
|
||||
|
||||
int manager_check_resolv_conf(const Manager *m) {
|
||||
const char *path;
|
||||
struct stat st;
|
||||
int r;
|
||||
struct stat st, own;
|
||||
|
||||
assert(m);
|
||||
|
||||
/* This warns only when our stub listener is disabled and /etc/resolv.conf is a symlink to
|
||||
* PRIVATE_STATIC_RESOLV_CONF or PRIVATE_STUB_RESOLV_CONF. */
|
||||
* PRIVATE_STATIC_RESOLV_CONF. */
|
||||
|
||||
if (m->dns_stub_listener_mode != DNS_STUB_LISTENER_NO)
|
||||
return 0;
|
||||
|
||||
r = stat("/etc/resolv.conf", &st);
|
||||
if (r < 0) {
|
||||
if (stat("/etc/resolv.conf", &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
return log_warning_errno(errno, "Failed to stat /etc/resolv.conf: %m");
|
||||
}
|
||||
|
||||
FOREACH_STRING(path,
|
||||
PRIVATE_STUB_RESOLV_CONF,
|
||||
PRIVATE_STATIC_RESOLV_CONF) {
|
||||
|
||||
struct stat own;
|
||||
|
||||
/* Is it symlinked to our own uplink file? */
|
||||
if (stat(path, &own) >= 0 &&
|
||||
st.st_dev == own.st_dev &&
|
||||
st.st_ino == own.st_ino) {
|
||||
log_warning("DNSStubListener= is disabled, but /etc/resolv.conf is a symlink to %s "
|
||||
"which expects DNSStubListener= to be enabled.", path);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
/* Is it symlinked to our own uplink file? */
|
||||
if (stat(PRIVATE_STATIC_RESOLV_CONF, &own) >= 0 &&
|
||||
st.st_dev == own.st_dev &&
|
||||
st.st_ino == own.st_ino)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"DNSStubListener= is disabled, but /etc/resolv.conf is a symlink to "
|
||||
PRIVATE_STATIC_RESOLV_CONF " which expects DNSStubListener= to be enabled.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -355,45 +345,49 @@ int manager_write_resolv_conf(Manager *m) {
|
||||
|
||||
r = fopen_temporary_label(PRIVATE_UPLINK_RESOLV_CONF, PRIVATE_UPLINK_RESOLV_CONF, &f_uplink, &temp_path_uplink);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to open private resolv.conf file for writing: %m");
|
||||
return log_warning_errno(r, "Failed to open new %s for writing: %m", PRIVATE_UPLINK_RESOLV_CONF);
|
||||
|
||||
(void) fchmod(fileno(f_uplink), 0644);
|
||||
|
||||
r = fopen_temporary_label(PRIVATE_STUB_RESOLV_CONF, PRIVATE_STUB_RESOLV_CONF, &f_stub, &temp_path_stub);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to open private stub-resolv.conf file for writing: %m");
|
||||
|
||||
(void) fchmod(fileno(f_stub), 0644);
|
||||
|
||||
r = write_uplink_resolv_conf_contents(f_uplink, dns, domains);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to write private resolv.conf contents: %m");
|
||||
log_error_errno(r, "Failed to write new %s: %m", PRIVATE_UPLINK_RESOLV_CONF);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(temp_path_uplink, PRIVATE_UPLINK_RESOLV_CONF) < 0) {
|
||||
r = log_error_errno(errno, "Failed to move private resolv.conf file into place: %m");
|
||||
goto fail;
|
||||
if (m->dns_stub_listener_mode != DNS_STUB_LISTENER_NO) {
|
||||
r = fopen_temporary_label(PRIVATE_STUB_RESOLV_CONF, PRIVATE_STUB_RESOLV_CONF, &f_stub, &temp_path_stub);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to open new %s for writing: %m", PRIVATE_STUB_RESOLV_CONF);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
(void) fchmod(fileno(f_stub), 0644);
|
||||
|
||||
r = write_stub_resolv_conf_contents(f_stub, dns, domains);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to write new %s: %m", PRIVATE_STUB_RESOLV_CONF);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(temp_path_stub, PRIVATE_STUB_RESOLV_CONF) < 0)
|
||||
r = log_error_errno(errno, "Failed to move new %s into place: %m", PRIVATE_STUB_RESOLV_CONF);
|
||||
|
||||
} else {
|
||||
r = symlink_atomic(basename(PRIVATE_UPLINK_RESOLV_CONF), PRIVATE_STUB_RESOLV_CONF);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to symlink %s: %m", PRIVATE_STUB_RESOLV_CONF);
|
||||
}
|
||||
|
||||
r = write_stub_resolv_conf_contents(f_stub, dns, domains);
|
||||
if (rename(temp_path_uplink, PRIVATE_UPLINK_RESOLV_CONF) < 0)
|
||||
r = log_error_errno(errno, "Failed to move new %s into place: %m", PRIVATE_UPLINK_RESOLV_CONF);
|
||||
|
||||
fail:
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to write private stub-resolv.conf contents: %m");
|
||||
goto fail;
|
||||
/* Something went wrong, perform cleanup... */
|
||||
(void) unlink(temp_path_uplink);
|
||||
(void) unlink(temp_path_stub);
|
||||
}
|
||||
|
||||
if (rename(temp_path_stub, PRIVATE_STUB_RESOLV_CONF) < 0) {
|
||||
r = log_error_errno(errno, "Failed to move private stub-resolv.conf file into place: %m");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) unlink(PRIVATE_UPLINK_RESOLV_CONF);
|
||||
(void) unlink(temp_path_uplink);
|
||||
(void) unlink(PRIVATE_STUB_RESOLV_CONF);
|
||||
(void) unlink(temp_path_stub);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user