From 822db23cfa98a9fbc48f41e11caafb6f1017e052 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Apr 2015 17:23:27 +0200 Subject: [PATCH] resolved: maintain order when writing resolv.conf entries http://lists.freedesktop.org/archives/systemd-devel/2015-March/029850.html --- src/resolve/resolved-manager.c | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 167bea39b3..adaa6c6e7f 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -30,6 +30,7 @@ #include "af-list.h" #include "utf8.h" #include "fileio-label.h" +#include "ordered-set.h" #include "resolved-dns-domain.h" #include "resolved-conf.h" @@ -702,8 +703,11 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) { (*count) ++; } -static void write_resolv_conf_search(const char *domain, FILE *f, - unsigned *count, unsigned *length) { +static void write_resolv_conf_search( + const char *domain, FILE *f, + unsigned *count, + unsigned *length) { + assert(domain); assert(f); assert(length); @@ -724,7 +728,7 @@ static void write_resolv_conf_search(const char *domain, FILE *f, (*count) ++; } -static int write_resolv_conf_contents(FILE *f, Set *dns, Set *domains) { +static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) { Iterator i; fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n" @@ -733,22 +737,22 @@ static int write_resolv_conf_contents(FILE *f, Set *dns, Set *domains) { "# resolv.conf(5) in a different way, replace the symlink by a\n" "# static file or a different symlink.\n\n", f); - if (set_isempty(dns)) + if (ordered_set_isempty(dns)) fputs("# No DNS servers known.\n", f); else { DnsServer *s; unsigned count = 0; - SET_FOREACH(s, dns, i) + ORDERED_SET_FOREACH(s, dns, i) write_resolv_conf_server(s, f, &count); } - if (!set_isempty(domains)) { + if (!ordered_set_isempty(domains)) { unsigned length = 0, count = 0; char *domain; fputs("search", f); - SET_FOREACH(domain, domains, i) + ORDERED_SET_FOREACH(domain, domains, i) write_resolv_conf_search(domain, f, &count, &length); fputs("\n", f); } @@ -756,12 +760,11 @@ static int write_resolv_conf_contents(FILE *f, Set *dns, Set *domains) { return fflush_and_check(f); } - int manager_write_resolv_conf(Manager *m) { static const char path[] = "/run/systemd/resolve/resolv.conf"; _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; - _cleanup_set_free_ Set *dns = NULL, *domains = NULL; + _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL; DnsServer *s; Iterator i; Link *l; @@ -773,17 +776,17 @@ int manager_write_resolv_conf(Manager *m) { manager_read_resolv_conf(m); /* Add the full list to a set, to filter out duplicates */ - dns = set_new(&dns_server_hash_ops); + dns = ordered_set_new(&dns_server_hash_ops); if (!dns) return -ENOMEM; - domains = set_new(&dns_name_hash_ops); + domains = ordered_set_new(&dns_name_hash_ops); if (!domains) return -ENOMEM; /* First add the system-wide servers */ LIST_FOREACH(servers, s, m->dns_servers) { - r = set_put(dns, s); + r = ordered_set_put(dns, s); if (r == -EEXIST) continue; if (r < 0) @@ -795,7 +798,7 @@ int manager_write_resolv_conf(Manager *m) { char **domain; LIST_FOREACH(servers, s, l->dns_servers) { - r = set_put(dns, s); + r = ordered_set_put(dns, s); if (r == -EEXIST) continue; if (r < 0) @@ -806,7 +809,7 @@ int manager_write_resolv_conf(Manager *m) { continue; STRV_FOREACH(domain, l->unicast_scope->domains) { - r = set_put(domains, *domain); + r = ordered_set_put(domains, *domain); if (r == -EEXIST) continue; if (r < 0) @@ -815,9 +818,9 @@ int manager_write_resolv_conf(Manager *m) { } /* If we found nothing, add the fallback servers */ - if (set_isempty(dns)) { + if (ordered_set_isempty(dns)) { LIST_FOREACH(servers, s, m->fallback_dns_servers) { - r = set_put(dns, s); + r = ordered_set_put(dns, s); if (r == -EEXIST) continue; if (r < 0) @@ -843,8 +846,8 @@ int manager_write_resolv_conf(Manager *m) { return 0; fail: - unlink(path); - unlink(temp_path); + (void) unlink(path); + (void) unlink(temp_path); return r; }