diff options
26 files changed, 274 insertions, 120 deletions
diff --git a/Makefile.am b/Makefile.am index 5d30d7d51c..783e19b2f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -714,9 +714,9 @@ man/systemd.index.xml: $(top_srcdir)/tools/make-man-index.py $(NON_INDEX_XML_FIL $(AM_V_at)$(MKDIR_P) $(dir $@) $(AM_V_GEN)$(PYTHON) $< $@ $(filter-out $<,$^) -man/systemd.directives.xml: $(top_srcdir)/tools/make-directive-index.py $(SOURCE_XML_FILES) +man/systemd.directives.xml: $(top_srcdir)/tools/make-directive-index.py man/custom-entities.ent $(SOURCE_XML_FILES) $(AM_V_at)$(MKDIR_P) $(dir $@) - $(AM_V_GEN)$(PYTHON) $< $@ $(filter-out $<,$^) + $(AM_V_GEN)$(PYTHON) $< $@ $(SOURCE_XML_FILES) CLEANFILES += \ man/systemd.index.xml \ @@ -762,6 +762,8 @@ libsystemd_shared_la_SOURCES = \ src/shared/udev-util.h \ src/shared/device-nodes.c \ src/shared/device-nodes.h \ + src/shared/dns-domain.c \ + src/shared/dns-domain.h \ src/shared/util.c \ src/shared/util.h \ src/shared/virt.c \ @@ -978,6 +980,7 @@ libsystemd_shared_la_CFLAGS = \ libsystemd_shared_la_LIBADD = \ $(SELINUX_LIBS) \ $(CAP_LIBS) \ + $(LIBIDN_LIBS) \ -lm # ----------------------------------------------------------------------------- @@ -1446,7 +1449,8 @@ tests += \ test-copy \ test-cap-list \ test-sigbus \ - test-verbs + test-verbs \ + test-dns-domain EXTRA_DIST += \ test/a.service \ @@ -1577,6 +1581,15 @@ test_hostname_SOURCES = \ test_hostname_LDADD = \ libsystemd-core.la +test_dns_domain_SOURCES = \ + src/test/test-dns-domain.c + +test_dns_domain_LDADD = \ + libsystemd-network.la \ + libsystemd-internal.la \ + libsystemd-shared.la \ + $(LIBIDN_LIBS) + if ENABLE_EFI manual_tests += \ test-boot-timestamp @@ -3382,7 +3395,8 @@ test_dhcp_client_SOURCES = \ test_dhcp_client_LDADD = \ libsystemd-network.la \ libsystemd-internal.la \ - libsystemd-shared.la + libsystemd-shared.la \ + $(LIBIDN_LIBS) test_dhcp_server_SOURCES = \ src/libsystemd-network/test-dhcp-server.c @@ -3603,6 +3617,9 @@ test_unifont_LDADD = \ src/libsystemd-terminal/unifont-glyph-array.bin: tools/compile-unifont.py $(UNIFONT) $(AM_V_GEN)$(PYTHON) $< <$(UNIFONT) >$@ +EXTRA_DIST += \ + tools/compile-unifont.py + # ------------------------------------------------------------------------------ include_HEADERS += \ src/libudev/libudev.h @@ -5405,8 +5422,6 @@ systemd_resolved_SOURCES = \ src/resolve/resolved-link.h \ src/resolve/resolved-link.c \ src/resolve/resolved-def.h \ - src/resolve/resolved-dns-domain.h \ - src/resolve/resolved-dns-domain.c \ src/resolve/resolved-dns-rr.h \ src/resolve/resolved-dns-rr.c \ src/resolve/resolved-dns-question.h \ @@ -5476,20 +5491,6 @@ GENERAL_ALIASES += \ nodist_pkgsysconf_DATA += \ src/resolve/resolved.conf -tests += \ - test-dns-domain - -test_dns_domain_SOURCES = \ - src/resolve/resolved-dns-domain.h \ - src/resolve/resolved-dns-domain.c \ - src/resolve/test-dns-domain.c - -test_dns_domain_LDADD = \ - libsystemd-network.la \ - libsystemd-internal.la \ - libsystemd-shared.la \ - $(LIBIDN_LIBS) - libnss_resolve_la_SOURCES = \ src/nss-resolve/nss-resolve.sym \ src/nss-resolve/nss-resolve.c @@ -5520,8 +5521,6 @@ systemd_resolve_host_SOURCES = \ src/resolve/resolved-dns-answer.h \ src/resolve/resolved-dns-question.c \ src/resolve/resolved-dns-question.h \ - src/resolve/resolved-dns-domain.c \ - src/resolve/resolved-dns-domain.h \ src/resolve/dns-type.c \ src/resolve/dns-type.h @@ -5551,7 +5550,8 @@ systemd_networkd_SOURCES = \ src/network/networkd.c systemd_networkd_LDADD = \ - libsystemd-networkd-core.la + libsystemd-networkd-core.la \ + $(LIBIDN_LIBS) if HAVE_LIBIPTC systemd_networkd_LDADD += \ @@ -5650,7 +5650,8 @@ test_network_SOURCES = \ src/network/test-network.c test_network_LDADD = \ - libsystemd-networkd-core.la + libsystemd-networkd-core.la \ + $(LIBIDN_LIBS) if HAVE_LIBIPTC test_network_LDADD += \ diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml index b0c88001d4..d14564480d 100644 --- a/man/systemd-cgtop.xml +++ b/man/systemd-cgtop.xml @@ -65,10 +65,12 @@ groups of the local Linux control group hierarchy, ordered by their CPU, memory, or disk I/O load. The display is refreshed in regular intervals (by default every 1s), similar in style to - <citerefentry project='man-pages'><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>. - If <command>systemd-cgtop</command> is not connected to a tty, - only one iteration is performed and no columns headers are - printed. This mode is suitable for scripting.</para> + <citerefentry project='man-pages'><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para> + + <para>If <command>systemd-cgtop</command> is not connected to a tty, no + column headers are printed and the default is to only run one iteration. + The <varname>--iterations</varname> argument, if given, is still honored. + This mode is suitable for scripting.</para> <para>Resource usage is only accounted for control groups in the relevant hierarchy, i.e. CPU usage is only accounted for control @@ -143,11 +145,20 @@ </varlistentry> <varlistentry> + <term><option>-r</option></term> + <term><option>--raw</option></term> + + <listitem><para>Format byte counts (as in memory usage and IO metrics) + with raw numeric values rather than human-readable + numbers.</para></listitem> + </varlistentry> + + <varlistentry> <term><option>-n</option></term> <term><option>--iterations=</option></term> - <listitem><para>Perform only this many iterations. - </para></listitem> + <listitem><para>Perform only this many iterations. A value of 0 + indicates that the program should run indefinitely.</para></listitem> </varlistentry> <varlistentry> diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index a390cf3256..d630e35882 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -60,8 +60,9 @@ typedef struct Group { } Group; static unsigned arg_depth = 3; -static unsigned arg_iterations = 0; +static unsigned arg_iterations = (unsigned)-1; static bool arg_batch = false; +static bool arg_raw = false; static usec_t arg_delay = 1*USEC_PER_SEC; static enum { @@ -96,6 +97,16 @@ static void group_hashmap_free(Hashmap *h) { hashmap_free(h); } +static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, off_t t) { + if (!is_valid) + return "-"; + if (arg_raw) { + snprintf(buf, l, "%jd", t); + return buf; + } + return format_bytes(buf, l, t); +} + static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) { Group *g; int r; @@ -270,11 +281,10 @@ static int process(const char *controller, const char *path, Hashmap *a, Hashmap yr = rd - g->io_input; yw = wr - g->io_output; - if (yr > 0 || yw > 0) { + if (g->io_input > 0 || g->io_output > 0) { g->io_input_bps = (yr * 1000000000ULL) / x; g->io_output_bps = (yw * 1000000000ULL) / x; g->io_valid = true; - } } @@ -532,18 +542,9 @@ static int display(Hashmap *a) { } else printf(" %*s", maxtcpu, format_timespan(buffer, sizeof(buffer), (nsec_t) (g->cpu_usage / NSEC_PER_USEC), 0)); - if (g->memory_valid) - printf(" %8s", format_bytes(buffer, sizeof(buffer), g->memory)); - else - fputs(" -", stdout); - - if (g->io_valid) { - printf(" %8s", - format_bytes(buffer, sizeof(buffer), g->io_input_bps)); - printf(" %8s", - format_bytes(buffer, sizeof(buffer), g->io_output_bps)); - } else - fputs(" - -", stdout); + printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->memory_valid, g->memory)); + printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->io_valid, g->io_input_bps)); + printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->io_valid, g->io_output_bps)); putchar('\n'); } @@ -561,6 +562,7 @@ static void help(void) { " -c Order by CPU load\n" " -m Order by memory load\n" " -i Order by IO load\n" + " -r --raw Provide raw (not human-readable) numbers\n" " --cpu[=TYPE] Show CPU usage as time or percentage (default)\n" " -d --delay=DELAY Delay between updates\n" " -n --iterations=N Run for N iterations before exiting\n" @@ -583,6 +585,7 @@ static int parse_argv(int argc, char *argv[]) { { "delay", required_argument, NULL, 'd' }, { "iterations", required_argument, NULL, 'n' }, { "batch", no_argument, NULL, 'b' }, + { "raw", no_argument, NULL, 'r' }, { "depth", required_argument, NULL, ARG_DEPTH }, { "cpu", optional_argument, NULL, ARG_CPU_TYPE}, {} @@ -594,7 +597,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 1); assert(argv); - while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hptcmin:brd:", options, NULL)) >= 0) switch (c) { @@ -649,6 +652,10 @@ static int parse_argv(int argc, char *argv[]) { arg_batch = true; break; + case 'r': + arg_raw = true; + break; + case 'p': arg_order = ORDER_PATH; break; @@ -707,8 +714,8 @@ int main(int argc, char *argv[]) { signal(SIGWINCH, columns_lines_cache_reset); - if (!on_tty()) - arg_iterations = 1; + if (arg_iterations == (unsigned)-1) + arg_iterations = on_tty() ? 0 : 1; while (!quit) { Hashmap *c; @@ -741,6 +748,10 @@ int main(int argc, char *argv[]) { if (arg_iterations && iteration >= arg_iterations) break; + if (!on_tty()) /* non-TTY: Empty newline as delimiter between polls */ + fputs("\n", stdout); + fflush(stdout); + if (arg_batch) { usleep(last_refresh + arg_delay - t); } else { @@ -754,8 +765,10 @@ int main(int argc, char *argv[]) { } } - fputs("\r \r", stdout); - fflush(stdout); + if (on_tty()) { /* TTY: Clear any user keystroke */ + fputs("\r \r", stdout); + fflush(stdout); + } if (arg_batch) continue; diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 8a4220621b..d8bc76edda 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -32,6 +32,7 @@ #include "dhcp-lease-internal.h" #include "sd-dhcp-lease.h" #include "network-internal.h" +#include "dns-domain.h" int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) { assert_return(lease, -EINVAL); @@ -504,9 +505,18 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, if (e) *e = 0; - if (!hostname_is_valid(domainname) || is_localhost(domainname)) + if (is_localhost(domainname)) break; + r = dns_name_is_valid(domainname); + if (r <= 0) { + if (r < 0) + log_error_errno(r, "Failed to validate domain name: %s: %m", domainname); + if (r == 0) + log_warning("Domain name is not valid, ignoring: %s", domainname); + break; + } + free(lease->domainname); lease->domainname = domainname; domainname = NULL; diff --git a/src/libsystemd/sd-bus/bus-bloom.c b/src/libsystemd/sd-bus/bus-bloom.c index 3556774074..91fab90cb0 100644 --- a/src/libsystemd/sd-bus/bus-bloom.c +++ b/src/libsystemd/sd-bus/bus-bloom.c @@ -116,11 +116,19 @@ void bloom_add_prefixes(uint64_t filter[], size_t size, unsigned k, const char * p = stpcpy(stpcpy(c, a), ":"); strcpy(p, b); + bloom_add_data(filter, size, k, c, n); + for (;;) { char *e; e = strrchr(p, sep); - if (!e || e == p) + if (!e) + break; + + *(e + 1) = 0; + bloom_add_data(filter, size, k, c, e - c + 1); + + if (e == p) break; *e = 0; diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 1103903358..7a59702cb2 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -1291,10 +1291,8 @@ int bus_add_match_internal_kernel( break; case BUS_MATCH_PATH_NAMESPACE: - if (!streq(c->value_str, "/")) { - bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str); - using_bloom = true; - } + bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str); + using_bloom = true; break; case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: { @@ -1310,11 +1308,18 @@ int bus_add_match_internal_kernel( } case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: { - char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")]; - - xsprintf(buf, "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH); - bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str); - using_bloom = true; + /* + * XXX: DBus spec defines arg[0..63]path= matching to be + * a two-way glob. That is, if either string is a prefix + * of the other, it matches. + * This is really hard to realize in bloom-filters, as + * we would have to create a bloom-match for each prefix + * of @c->value_str. This is excessive, hence we just + * ignore all those matches and accept everything from + * the kernel. People should really avoid those matches. + * If they're used in real-life some day, we will have + * to properly support multiple-matches here. + */ break; } diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index 91b288cd25..37793e48ed 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -211,6 +211,17 @@ bool member_name_is_valid(const char *p) { return true; } +/* + * Complex pattern match + * This checks whether @a is a 'complex-prefix' of @b, or @b is a + * 'complex-prefix' of @a, based on strings that consist of labels with @c as + * spearator. This function returns true if: + * - both strings are equal + * - either is a prefix of the other and ends with @c + * The second rule makes sure that either string needs to be fully included in + * the other, and the string which is considered the prefix needs to end with a + * separator. + */ static bool complex_pattern_check(char c, const char *a, const char *b) { bool separator = false; @@ -222,9 +233,7 @@ static bool complex_pattern_check(char c, const char *a, const char *b) { for (;;) { if (*a != *b) - return (separator && (*a == 0 || *b == 0)) || - (*a == 0 && *b == c && b[1] == 0) || - (*b == 0 && *a == c && a[1] == 0); + return (separator && (*a == 0 || *b == 0)); if (*a == 0) return true; @@ -243,7 +252,18 @@ bool path_complex_pattern(const char *pattern, const char *value) { return complex_pattern_check('/', pattern, value); } +/* + * Simple pattern match + * This checks whether @a is a 'simple-prefix' of @b, based on strings that + * consist of labels with @c as separator. This function returns true, if: + * - if @a and @b are equal + * - if @a is a prefix of @b, and the first following character in @b (or the + * last character in @a) is @c + * The second rule basically makes sure that if @a is a prefix of @b, then @b + * must follow with a new label separated by @c. It cannot extend the label. + */ static bool simple_pattern_check(char c, const char *a, const char *b) { + bool separator = false; if (!a && !b) return true; @@ -253,11 +273,13 @@ static bool simple_pattern_check(char c, const char *a, const char *b) { for (;;) { if (*a != *b) - return *a == 0 && *b == c; + return *a == 0 && (*b == c || separator); if (*a == 0) return true; + separator = *a == c; + a++, b++; } } diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c index b11c43bd7b..90eb1f2a33 100644 --- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c +++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c @@ -26,6 +26,14 @@ #include "bus-kernel.h" #include "bus-util.h" +static int test_match(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + int *found = userdata; + + *found = 1; + + return 0; +} + static void test_one( const char *path, const char *interface, @@ -39,7 +47,7 @@ static void test_one( _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; sd_bus *a, *b; - int r; + int r, found = 0; assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); @@ -71,7 +79,7 @@ static void test_one( assert_se(r >= 0); log_debug("match"); - r = sd_bus_add_match(b, NULL, match, NULL, NULL); + r = sd_bus_add_match(b, NULL, match, test_match, &found); assert_se(r >= 0); log_debug("signal"); @@ -83,7 +91,7 @@ static void test_one( assert_se(r >= 0); r = sd_bus_process(b, &m); - assert_se(r >= 0 && (good == !!m)); + assert_se(r >= 0 && good == !!found); sd_bus_unref(a); sd_bus_unref(b); @@ -115,6 +123,17 @@ int main(int argc, char *argv[]) { test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true); test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true); test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false); + test_one("/", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true); + + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo/'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/'", true); + + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/bar/waldo", "arg0path='/foo/'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo'", true); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo/bar/waldo'", false); + test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/", "arg0path='/foo/bar/waldo'", true); return 0; } diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c index 4165c9273a..17c6188ca0 100644 --- a/src/libsystemd/sd-bus/test-bus-signature.c +++ b/src/libsystemd/sd-bus/test-bus-signature.c @@ -95,23 +95,28 @@ int main(int argc, char *argv[]) { assert_se(!namespace_complex_pattern("foo.", "")); assert_se(path_complex_pattern("", "")); - assert_se(path_complex_pattern("", "/")); - assert_se(path_complex_pattern("/", "")); + assert_se(!path_complex_pattern("", "/")); + assert_se(!path_complex_pattern("/", "")); assert_se(path_complex_pattern("/", "/")); assert_se(path_complex_pattern("/foobar/", "/")); - assert_se(path_complex_pattern("/foobar/", "/foobar")); + assert_se(!path_complex_pattern("/foobar/", "/foobar")); assert_se(path_complex_pattern("/foobar", "/foobar")); - assert_se(path_complex_pattern("/foobar", "/foobar/")); + assert_se(!path_complex_pattern("/foobar", "/foobar/")); assert_se(!path_complex_pattern("/foobar", "/foobar/waldo")); assert_se(path_complex_pattern("/foobar/", "/foobar/waldo")); + assert_se(path_complex_pattern("/foobar/waldo", "/foobar/")); + + assert_se(path_simple_pattern("/foo/", "/foo/bar/waldo")); assert_se(namespace_simple_pattern("", "")); + assert_se(namespace_simple_pattern("", ".foobar")); assert_se(namespace_simple_pattern("foobar", "foobar")); assert_se(namespace_simple_pattern("foobar.waldo", "foobar.waldo")); assert_se(namespace_simple_pattern("foobar", "foobar.waldo")); assert_se(!namespace_simple_pattern("foobar.waldo", "foobar")); assert_se(!namespace_simple_pattern("", "foo")); assert_se(!namespace_simple_pattern("foo", "")); + assert_se(namespace_simple_pattern("foo.", "foo.bar.waldo")); assert_se(streq(object_path_startswith("/foo/bar", "/foo"), "bar")); assert_se(streq(object_path_startswith("/foo", "/foo"), "")); diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 587941497d..207eda163b 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -297,8 +297,31 @@ static inline sd_network_monitor* FD_TO_MONITOR(int fd) { return (sd_network_monitor*) (unsigned long) (fd + 1); } +static int monitor_add_inotify_watch(int fd) { + int k; + + k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE); + if (k >= 0) + return 0; + else if (errno != ENOENT) + return -errno; + + k = inotify_add_watch(fd, "/run/systemd/netif/", IN_CREATE|IN_ISDIR); + if (k >= 0) + return 0; + else if (errno != ENOENT) + return -errno; + + k = inotify_add_watch(fd, "/run/systemd/", IN_CREATE|IN_ISDIR); + if (k < 0) + return -errno; + + return 0; +} + _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) { - int fd, k; + _cleanup_close_ int fd = -1; + int k; bool good = false; assert_return(m, -EINVAL); @@ -308,11 +331,9 @@ _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category return -errno; if (!category || streq(category, "links")) { - k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE); - if (k < 0) { - safe_close(fd); - return -errno; - } + k = monitor_add_inotify_watch(fd); + if (k < 0) + return k; good = true; } @@ -323,6 +344,8 @@ _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category } *m = FD_TO_MONITOR(fd); + fd = -1; + return 0; } @@ -338,10 +361,36 @@ _public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) { } _public_ int sd_network_monitor_flush(sd_network_monitor *m) { + union inotify_event_buffer buffer; + struct inotify_event *e; + ssize_t l; + int fd, k; assert_return(m, -EINVAL); - return flush_fd(MONITOR_TO_FD(m)); + fd = MONITOR_TO_FD(m); + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; + + return -errno; + } + + FOREACH_INOTIFY_EVENT(e, buffer, l) { + if (e->mask & IN_ISDIR) { + k = monitor_add_inotify_watch(fd); + if (k < 0) + return k; + + k = inotify_rm_watch(fd, e->wd); + if (k < 0) + return -errno; + } + } + + return 0; } _public_ int sd_network_monitor_get_fd(sd_network_monitor *m) { diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 5947084106..6f32e5f4a4 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -30,6 +30,7 @@ #include "networkd-netdev.h" #include "networkd-link.h" #include "network-internal.h" +#include "dns-domain.h" static int network_load_one(Manager *manager, const char *filename) { _cleanup_network_free_ Network *network = NULL; @@ -466,11 +467,16 @@ int config_parse_domains(const char *unit, STRV_FOREACH(domain, *domains) { if (is_localhost(*domain)) log_syntax(unit, LOG_ERR, filename, line, EINVAL, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain); - else if (!hostname_is_valid(*domain)) { - if (!streq(*domain, "*")) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "domain name is not valid, ignoring assignment: %s", *domain); - } else - continue; + else { + r = dns_name_is_valid(*domain); + if (r <= 0 && !streq(*domain, "*")) { + if (r < 0) + log_error_errno(r, "Failed to validate domain name: %s: %m", *domain); + if (r == 0) + log_warning("Domain name is not valid, ignoring assignment: %s", *domain); + } else + continue; + } strv_remove(*domains, *domain); diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 171141e3a4..6db12511f9 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -22,7 +22,7 @@ #include "bus-common-errors.h" #include "bus-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-bus.h" #include "resolved-def.h" diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index e08eb667cc..f77b98e505 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -20,7 +20,7 @@ ***/ #include "resolved-dns-answer.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" DnsAnswer *dns_answer_new(unsigned n) { DnsAnswer *a; diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 21756f566f..bb74b1828e 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -23,7 +23,7 @@ #include "util.h" #include "strv.h" #include "unaligned.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-packet.h" int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c index 45bcbbf23a..4d71f5e3d4 100644 --- a/src/resolve/resolved-dns-question.c +++ b/src/resolve/resolved-dns-question.c @@ -20,7 +20,7 @@ ***/ #include "resolved-dns-question.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" DnsQuestion *dns_question_new(unsigned n) { DnsQuestion *q; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 78d9e4a412..c1818eef9c 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -23,7 +23,7 @@ #include "strv.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-rr.h" #include "resolved-dns-packet.h" #include "dns-type.h" diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 7369cbf50f..c25ac2216d 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -27,7 +27,7 @@ #include "af-list.h" #include "random-util.h" #include "hostname-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-scope.h" #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC) diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index a4c9b7d7af..32d771a954 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -22,7 +22,7 @@ #include "list.h" #include "resolved-dns-zone.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-packet.h" /* Never allow more than 1K entries */ diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 7fc2803ddb..f8d4db7aad 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -34,7 +34,7 @@ #include "random-util.h" #include "hostname-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-conf.h" #include "resolved-bus.h" #include "resolved-manager.h" diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 9988e5c574..d83cdf7e5f 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -441,9 +441,7 @@ static const char *normalize_controller(const char *controller) { assert(controller); - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - return "systemd"; - else if (startswith(controller, "name=")) + if (startswith(controller, "name=")) return controller + 5; else return controller; @@ -483,7 +481,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch assert(fs); - if (controller && !cg_controller_is_valid(controller, true)) + if (controller && !cg_controller_is_valid(controller)) return -EINVAL; if (_unlikely_(!good)) { @@ -526,7 +524,7 @@ int cg_get_path_and_check(const char *controller, const char *path, const char * assert(fs); - if (!cg_controller_is_valid(controller, true)) + if (!cg_controller_is_valid(controller)) return -EINVAL; /* Normalize the controller syntax */ @@ -742,7 +740,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { assert(pid >= 0); if (controller) { - if (!cg_controller_is_valid(controller, true)) + if (!cg_controller_is_valid(controller)) return -EINVAL; controller = normalize_controller(controller); @@ -971,7 +969,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) { e = strchr(spec, ':'); if (!e) { - if (!cg_controller_is_valid(spec, true)) + if (!cg_controller_is_valid(spec)) return -EINVAL; if (controller) { @@ -994,7 +992,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) { t = strdup(normalize_controller(v)); if (!t) return -ENOMEM; - if (!cg_controller_is_valid(t, true)) { + if (!cg_controller_is_valid(t)) { free(t); return -EINVAL; } @@ -1610,17 +1608,15 @@ char *cg_unescape(const char *p) { DIGITS LETTERS \ "_" -bool cg_controller_is_valid(const char *p, bool allow_named) { +bool cg_controller_is_valid(const char *p) { const char *t, *s; if (!p) return false; - if (allow_named) { - s = startswith(p, "name="); - if (s) - p = s; - } + s = startswith(p, "name="); + if (s) + p = s; if (*p == 0 || *p == '_') return false; diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h index cbf7201370..fd72e9e5c5 100644 --- a/src/shared/cgroup-util.h +++ b/src/shared/cgroup-util.h @@ -122,7 +122,7 @@ int cg_path_decode_unit(const char *cgroup, char **unit); char *cg_escape(const char *p); char *cg_unescape(const char *p) _pure_; -bool cg_controller_is_valid(const char *p, bool allow_named); +bool cg_controller_is_valid(const char *p); int cg_slice_to_path(const char *unit, char **ret); diff --git a/src/shared/def.h b/src/shared/def.h index a3d9fcf388..011c7c667e 100644 --- a/src/shared/def.h +++ b/src/shared/def.h @@ -35,7 +35,7 @@ * the watchdog pings will keep the loop busy. */ #define DEFAULT_EXIT_USEC (30*USEC_PER_SEC) -#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" +#define SYSTEMD_CGROUP_CONTROLLER "systemd" #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT #define SIGNALS_IGNORE SIGPIPE diff --git a/src/resolve/resolved-dns-domain.c b/src/shared/dns-domain.c index e1eb3ddfe5..20a44ce4e1 100644 --- a/src/resolve/resolved-dns-domain.c +++ b/src/shared/dns-domain.c @@ -24,7 +24,7 @@ #include <stringprep.h> #endif -#include "resolved-dns-domain.h" +#include "dns-domain.h" int dns_label_unescape(const char **name, char *dest, size_t sz) { const char *n; diff --git a/src/resolve/resolved-dns-domain.h b/src/shared/dns-domain.h index 516d244f7a..00caf5d700 100644 --- a/src/resolve/resolved-dns-domain.h +++ b/src/shared/dns-domain.h @@ -35,6 +35,15 @@ int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max); int dns_name_normalize(const char *s, char **_ret); +static inline int dns_name_is_valid(const char *s) { + int r; + r = dns_name_normalize(s, NULL); + if (r == -EINVAL) + return 0; + if (r < 0) + return r; + return 1; +} unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]); int dns_name_compare_func(const void *a, const void *b); diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index 4a89f64518..ecc9d70bf4 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -244,16 +244,16 @@ static void test_escape(void) { } static void test_controller_is_valid(void) { - assert_se(cg_controller_is_valid("foobar", false)); - assert_se(cg_controller_is_valid("foo_bar", false)); - assert_se(cg_controller_is_valid("name=foo", true)); - assert_se(!cg_controller_is_valid("", false)); - assert_se(!cg_controller_is_valid("name=", true)); - assert_se(!cg_controller_is_valid("=", false)); - assert_se(!cg_controller_is_valid("cpu,cpuacct", false)); - assert_se(!cg_controller_is_valid("_", false)); - assert_se(!cg_controller_is_valid("_foobar", false)); - assert_se(!cg_controller_is_valid("tatü", false)); + assert_se(cg_controller_is_valid("foobar")); + assert_se(cg_controller_is_valid("foo_bar")); + assert_se(cg_controller_is_valid("name=foo")); + assert_se(!cg_controller_is_valid("")); + assert_se(!cg_controller_is_valid("name=")); + assert_se(!cg_controller_is_valid("=")); + assert_se(!cg_controller_is_valid("cpu,cpuacct")); + assert_se(!cg_controller_is_valid("_")); + assert_se(!cg_controller_is_valid("_foobar")); + assert_se(!cg_controller_is_valid("tatü")); } static void test_slice_to_path_one(const char *unit, const char *path, int error) { diff --git a/src/resolve/test-dns-domain.c b/src/test/test-dns-domain.c index c3208abc78..527cdd3b54 100644 --- a/src/resolve/test-dns-domain.c +++ b/src/test/test-dns-domain.c @@ -20,7 +20,7 @@ ***/ #include "macro.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) { char buffer[buffer_sz]; |