From b97e7fabaeaf12c88d6a10b2bfead54a77812105 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Nov 2015 11:16:17 +0100 Subject: [PATCH 1/3] man: add more (and simpler examples) to network.link(5) --- man/systemd.link.xml | 47 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 29b837834c..a9f8a654c8 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -1,4 +1,4 @@ - + @@ -387,10 +387,53 @@ - Example + Examples + + + /usr/lib/systemd/network/99-default.link + + The link file 99-default.link that is + shipped with systemd defines the default naming policy for + links. + + [Link] +NamePolicy=kernel database onboard slot path +MACAddressPolicy=persistent + + + + /etc/systemd/network/10-dmz.link + + This example assigns the fixed name + dmz0 to the interface with the MAC address + 00:a0:de:63:7a:e6: + + [Match] +MACAddress=00:a0:de:63:7a:e6 + +[Link] +Name=dmz0 + + + + /etc/systemd/network/10-internet.link + + This example assigns the fixed name + internet0 to the interface with the device + path pci-0000:00:1a.0-*: + + [Match] +Path=pci-0000:00:1a.0-* + +[Link] +Name=internet0 + + /etc/systemd/network/25-wireless.link + Here's an overly complex example that shows the use of a large number of [Match] and [Link] settings. + [Match] MACAddress=12:34:56:78:9a:bc Driver=brcmsmac From 33d52ab92f2f0bfd706e6f343d172618d1e03f3d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Nov 2015 11:17:01 +0100 Subject: [PATCH 2/3] journald: rework --sync/--rotate logic to use CLOCK_MONOTONIC timestamp files Previously, we'd rely on the mtime timestamps of the touch files to see if our sync/rotation requests were already suppressed. This means we rely on CLOCK_REALTIME timestamps. With this patch we instead store the CLOCK_MONOTONIC timestamp *in* the touch files, and avoid relying on mtime. This should make things more reliable when the clock or underlying mtime granularity is not very good. This also adds warning messages if writing any of the flag files fails. --- src/basic/fileio.c | 36 +++++++++++++++++++++++++++++++++++ src/basic/fileio.h | 4 ++++ src/journal/journalctl.c | 18 ++++++++---------- src/journal/journald-server.c | 16 +++++++++++++--- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 619dafb517..be6e327690 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -28,8 +28,10 @@ #include "fileio.h" #include "fs-util.h" #include "hexdecoct.h" +#include "parse-util.h" #include "path-util.h" #include "random-util.h" +#include "stdio-util.h" #include "string-util.h" #include "strv.h" #include "umask-util.h" @@ -1149,3 +1151,37 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { *ret = path_kill_slashes(t); return 0; } + +int write_timestamp_file_atomic(const char *fn, usec_t n) { + char ln[DECIMAL_STR_MAX(n)+2]; + + /* Creates a "timestamp" file, that contains nothing but a + * usec_t timestamp, formatted in ASCII. */ + + if (n <= 0 || n >= USEC_INFINITY) + return -ERANGE; + + xsprintf(ln, USEC_FMT "\n", n); + + return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); +} + +int read_timestamp_file(const char *fn, usec_t *ret) { + _cleanup_free_ char *ln = NULL; + uint64_t t; + int r; + + r = read_one_line_file(fn, &ln); + if (r < 0) + return r; + + r = safe_atou64(ln, &t); + if (r < 0) + return r; + + if (t <= 0 || t >= (uint64_t) USEC_INFINITY) + return -ERANGE; + + *ret = (usec_t) t; + return 0; +} diff --git a/src/basic/fileio.h b/src/basic/fileio.h index fa7f192331..5f2c941498 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -28,6 +28,7 @@ #include #include "macro.h" +#include "time-util.h" typedef enum { WRITE_STRING_FILE_CREATE = 1, @@ -77,3 +78,6 @@ int open_tmpfile(const char *path, int flags); int tempfn_xxxxxx(const char *p, const char *extra, char **ret); int tempfn_random(const char *p, const char *extra, char **ret); int tempfn_random_child(const char *p, const char *extra, char **ret); + +int write_timestamp_file_atomic(const char *fn, usec_t n); +int read_timestamp_file(const char *fn, usec_t *ret); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index ac0751c547..75a48c761c 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1838,7 +1838,7 @@ static int send_signal_and_wait(int sig, const char *watch_path) { return -EOPNOTSUPP; } - start = now(CLOCK_REALTIME); + start = now(CLOCK_MONOTONIC); /* This call sends the specified signal to journald, and waits * for acknowledgment by watching the mtime of the specified @@ -1846,16 +1846,14 @@ static int send_signal_and_wait(int sig, const char *watch_path) { * then wait for the operation to complete. */ for (;;) { - struct stat st; + usec_t tstamp; /* See if a sync happened by now. */ - if (stat(watch_path, &st) < 0) { - if (errno != ENOENT) - return log_error_errno(errno, "Failed to stat %s: %m", watch_path); - } else { - if (timespec_load(&st.st_mtim) >= start) - return 0; - } + r = read_timestamp_file(watch_path, &tstamp); + if (r < 0 && r != -ENOENT) + return log_error_errno(errno, "Failed to read %s: %m", watch_path); + if (r >= 0 && tstamp >= start) + return 0; /* Let's ask for a sync, but only once. */ if (!bus) { @@ -1889,7 +1887,7 @@ static int send_signal_and_wait(int sig, const char *watch_path) { if (watch_fd < 0) return log_error_errno(errno, "Failed to create inotify watch: %m"); - r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_ATTRIB|IN_DONT_FOLLOW|IN_ONLYDIR); + r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR); if (r < 0) return log_error_errno(errno, "Failed to watch journal directory: %m"); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 70ff101d5f..762b810109 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -41,6 +41,7 @@ #include "dirent-util.h" #include "extract-word.h" #include "fd-util.h" +#include "fileio.h" #include "formats-util.h" #include "fs-util.h" #include "hashmap.h" @@ -1240,6 +1241,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { Server *s = userdata; + int r; assert(s); @@ -1249,13 +1251,16 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo * server_sync(s); server_vacuum(s, false, false); - (void) touch("/run/systemd/journal/flushed"); + r = touch("/run/systemd/journal/flushed"); + if (r < 0) + log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m"); return 0; } static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { Server *s = userdata; + int r; assert(s); @@ -1264,7 +1269,9 @@ static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo * server_vacuum(s, true, true); /* Let clients know when the most recent rotation happened. */ - (void) touch("/run/systemd/journal/rotated"); + r = write_timestamp_file_atomic("/run/systemd/journal/rotated", now(CLOCK_MONOTONIC)); + if (r < 0) + log_warning_errno(r, "Failed to write /run/systemd/journal/rotated, ignoring: %m"); return 0; } @@ -1282,6 +1289,7 @@ static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo * static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { Server *s = userdata; + int r; assert(s); @@ -1290,7 +1298,9 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo server_sync(s); /* Let clients know when the most recent sync happened. */ - (void) touch("/run/systemd/journal/synced"); + r = write_timestamp_file_atomic("/run/systemd/journal/synced", now(CLOCK_MONOTONIC)); + if (r < 0) + log_warning_errno(r, "Failed to write /run/systemd/journal/synced, ignoring: %m"); return 0; } From 4de2402b603ea2f518f451d06f09e15aeae54fab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Nov 2015 12:33:10 +0100 Subject: [PATCH 3/3] journald: fix accuracy of watchdog timer event Adding 3/4th of the watchdog frequency as accuracy on top of 1/2 of the watchdog frequency means we might end up at 5/4th of the frequency which means we might miss the message from time to time. Maybe fixes #1804 --- src/journal/journald-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 762b810109..be913d26ef 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1670,7 +1670,7 @@ static int server_connect_notify(Server *s) { if (sd_watchdog_enabled(false, &s->watchdog_usec) > 0) { s->send_watchdog = true; - r = sd_event_add_time(s->event, &s->watchdog_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->watchdog_usec/2, s->watchdog_usec*3/4, dispatch_watchdog, s); + r = sd_event_add_time(s->event, &s->watchdog_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->watchdog_usec/2, s->watchdog_usec/4, dispatch_watchdog, s); if (r < 0) return log_error_errno(r, "Failed to add watchdog time event: %m"); }