summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am49
-rw-r--r--man/systemd-cgtop.xml23
-rw-r--r--src/cgtop/cgtop.c53
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c12
-rw-r--r--src/libsystemd/sd-bus/bus-bloom.c10
-rw-r--r--src/libsystemd/sd-bus/bus-control.c23
-rw-r--r--src/libsystemd/sd-bus/bus-internal.c30
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c25
-rw-r--r--src/libsystemd/sd-bus/test-bus-signature.c13
-rw-r--r--src/libsystemd/sd-network/sd-network.c63
-rw-r--r--src/network/networkd-network.c16
-rw-r--r--src/resolve/resolved-bus.c2
-rw-r--r--src/resolve/resolved-dns-answer.c2
-rw-r--r--src/resolve/resolved-dns-packet.c2
-rw-r--r--src/resolve/resolved-dns-question.c2
-rw-r--r--src/resolve/resolved-dns-rr.c2
-rw-r--r--src/resolve/resolved-dns-scope.c2
-rw-r--r--src/resolve/resolved-dns-zone.c2
-rw-r--r--src/resolve/resolved-manager.c2
-rw-r--r--src/shared/cgroup-util.c24
-rw-r--r--src/shared/cgroup-util.h2
-rw-r--r--src/shared/def.h2
-rw-r--r--src/shared/dns-domain.c (renamed from src/resolve/resolved-dns-domain.c)2
-rw-r--r--src/shared/dns-domain.h (renamed from src/resolve/resolved-dns-domain.h)9
-rw-r--r--src/test/test-cgroup-util.c20
-rw-r--r--src/test/test-dns-domain.c (renamed from src/resolve/test-dns-domain.c)2
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];