]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #11513 from poettering/cryptsetup-msg
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 26 Jan 2019 15:43:20 +0000 (16:43 +0100)
committerGitHub <noreply@github.com>
Sat, 26 Jan 2019 15:43:20 +0000 (16:43 +0100)
improve cryptsetup messaging

26 files changed:
hwdb/60-sensor.hwdb
man/systemd.mount.xml
man/timedatectl.xml
meson.build
src/basic/prioq.c
src/basic/prioq.h
src/basic/process-util.c
src/basic/procfs-util.c
src/basic/procfs-util.h
src/cgtop/cgtop.c
src/core/cgroup.c
src/core/mount.c
src/journal/journald-context.c
src/journal/journald-server.h
src/libsystemd-network/dhcp-identifier.c
src/network/netdev/bridge.c
src/network/networkd-link.c
src/network/networkd-link.h
src/nspawn/nspawn.c
src/test/test-bpf.c
src/test/test-prioq.c
src/test/test-procfs-util.c
src/timesync/timesyncd-manager.c
test/test-functions
test/test-network/systemd-networkd-tests.py
units/systemd-tmpfiles-setup-dev.service.in

index eceaa50186c8a54e6e381aeb041aa575e8d59d85..8cfda94f4fca358521d465bae0e821eb6cc03ee8 100644 (file)
@@ -213,6 +213,14 @@ sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t*
 sensor:modalias:acpi:SMO8500*:dmi:*svn*DEXP*:*pn*DEXPOEM*
  ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
 
+#########################################
+# DIGMA
+#########################################
+
+# Digma CITI E203
+sensor:modalias:acpi:BOSC0200*:dmi:*:svnDigma:pnCITIE203ES2010EW:*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
+
 #########################################
 # Endless
 #########################################
index 6d8c873ca52a6ecb3b328efb14d8cc78241a61a5..7355b135e972a46512da513b95981e8c6ba488a5 100644 (file)
         <filename>umount.target</filename> in order to be stopped during shutdown.</para></listitem>
 
         <listitem><para>Mount units referring to local file systems automatically gain
-        an <varname>After=</varname> dependency on <filename>local-fs-pre.target</filename>.</para></listitem>
+        an <varname>After=</varname> dependency on <filename>local-fs-pre.target</filename>, and a
+        <varname>Before=</varname> dependency on <filename>local-fs.target</filename> unless
+        <option>nofail</option> mount option is set.</para></listitem>
 
         <listitem><para>Network mount units
         automatically acquire <varname>After=</varname> dependencies on <filename>remote-fs-pre.target</filename>,
-        <filename>network.target</filename> and <filename>network-online.target</filename>. Towards the latter a
+        <filename>network.target</filename> and <filename>network-online.target</filename>, and gain a
+        <varname>Before=</varname> dependency on <filename>remote-fs.target</filename> unless
+        <option>nofail</option> mount option is set. Towards the latter a
         <varname>Wants=</varname> unit is added as well.</para></listitem>
       </itemizedlist>
 
index a62902423a43f9e944d8ca80f13cf9509157d78c..b75b4cc72ac96e5d6dc688f0e9b6ca36b3d069cf 100644 (file)
@@ -82,7 +82,7 @@
 
       <varlistentry>
         <term><option>-a</option></term>
-        <term><option>-all</option></term>
+        <term><option>--all</option></term>
 
         <listitem><para>When showing properties of
         <citerefentry><refentrytitle>systemd-timesyncd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
index 5cf2fc266458a4abb4dbf3e81834e38535a42a51..56c98b9c1b7bff4abb77f9fb51df62375d2aa192 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 project('systemd', 'c',
-        version : '240',
+        version : '241',
         license : 'LGPLv2+',
         default_options: [
                 'c_std=gnu99',
@@ -12,8 +12,8 @@ project('systemd', 'c',
         meson_version : '>= 0.46',
        )
 
-libsystemd_version = '0.24.0'
-libudev_version = '1.6.12'
+libsystemd_version = '0.25.0'
+libudev_version = '1.6.13'
 
 # We need the same data in two different formats, ugh!
 # Also, for hysterical reasons, we use different variable
index cfd08d5d23223ac4164e2a19c42914c660cb28e9..76b27fa0a8e65e52c449e6e9bd009609bc0c5fc9 100644 (file)
@@ -259,15 +259,14 @@ int prioq_reshuffle(Prioq *q, void *data, unsigned *idx) {
         return 1;
 }
 
-void *prioq_peek(Prioq *q) {
-
+void *prioq_peek_by_index(Prioq *q, unsigned idx) {
         if (!q)
                 return NULL;
 
-        if (q->n_items <= 0)
+        if (idx >= q->n_items)
                 return NULL;
 
-        return q->items[0].data;
+        return q->items[idx].data;
 }
 
 void *prioq_pop(Prioq *q) {
index bba5c7caa49ca6d047b799f2c8c441e759757361..1fb57bfa4ca433b3c6010fd0def8ebb6414de4f4 100644 (file)
@@ -19,8 +19,14 @@ int prioq_put(Prioq *q, void *data, unsigned *idx);
 int prioq_remove(Prioq *q, void *data, unsigned *idx);
 int prioq_reshuffle(Prioq *q, void *data, unsigned *idx);
 
-void *prioq_peek(Prioq *q) _pure_;
+void *prioq_peek_by_index(Prioq *q, unsigned idx) _pure_;
+static inline void *prioq_peek(Prioq *q) {
+        return prioq_peek_by_index(q, 0);
+}
 void *prioq_pop(Prioq *q);
 
+#define PRIOQ_FOREACH_ITEM(q, p)                                \
+        for (unsigned _i = 0; (p = prioq_peek_by_index(q, _i)); _i++)
+
 unsigned prioq_size(Prioq *q) _pure_;
 bool prioq_isempty(Prioq *q) _pure_;
index 31fdbd9346870570490f93dd53e6e1c267d9d0a9..78ce43b944c126be095680446e9aeaa88583a708 100644 (file)
@@ -102,7 +102,8 @@ int get_process_comm(pid_t pid, char **ret) {
 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
         _cleanup_fclose_ FILE *f = NULL;
         bool space = false;
-        char *k, *ans = NULL;
+        char *k;
+        _cleanup_free_ char *ans = NULL;
         const char *p;
         int c;
 
@@ -143,7 +144,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
                 if (!ans)
                         return -ENOMEM;
 
-                *line = ans;
+                *line = TAKE_PTR(ans);
                 return 0;
 
         } else {
@@ -208,7 +209,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
                 _cleanup_free_ char *t = NULL;
                 int h;
 
-                free(ans);
+                ans = mfree(ans);
 
                 if (!comm_fallback)
                         return -ENOENT;
@@ -241,9 +242,18 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
                         if (!ans)
                                 return -ENOMEM;
                 }
+
+                *line = TAKE_PTR(ans);
+                return 0;
         }
 
-        *line = ans;
+        k = realloc(ans, strlen(ans) + 1);
+        if (!k)
+                return -ENOMEM;
+
+        ans = NULL;
+        *line = k;
+
         return 0;
 }
 
index a159e344b3778fcc163b8b0b01df6ee17be3fde8..7aaf95bfced24f93a8caea16302da2332a85ed5c 100644 (file)
@@ -201,13 +201,11 @@ int procfs_cpu_get_usage(nsec_t *ret) {
         return 0;
 }
 
-int procfs_memory_get_current(uint64_t *ret) {
+int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) {
         uint64_t mem_total = UINT64_MAX, mem_free = UINT64_MAX;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
-        assert(ret);
-
         f = fopen("/proc/meminfo", "re");
         if (!f)
                 return -errno;
@@ -262,6 +260,9 @@ int procfs_memory_get_current(uint64_t *ret) {
         if (mem_free > mem_total)
                 return -EINVAL;
 
-        *ret = (mem_total - mem_free) * 1024U;
+        if (ret_total)
+                *ret_total = mem_total * 1024U;
+        if (ret_used)
+                *ret_used = (mem_total - mem_free) * 1024U;
         return 0;
 }
index f697ed92bce5d000f26f4752146a2474fd7ca1ab..5a44e9eff7996883cdcc4b300b860c122279ac60 100644 (file)
@@ -11,4 +11,7 @@ int procfs_tasks_get_current(uint64_t *ret);
 
 int procfs_cpu_get_usage(nsec_t *ret);
 
-int procfs_memory_get_current(uint64_t *ret);
+int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used);
+static inline int procfs_memory_get_used(uint64_t *ret) {
+        return procfs_memory_get(NULL, ret);
+}
index 11cc5fa2e9d211d44eb08018c4d84f11c97e4349..b3bda30cec04d27ce45eb33222c7651644d5c86e 100644 (file)
@@ -291,7 +291,7 @@ static int process(
         } else if (streq(controller, "memory")) {
 
                 if (is_root_cgroup(path)) {
-                        r = procfs_memory_get_current(&g->memory);
+                        r = procfs_memory_get_used(&g->memory);
                         if (r < 0)
                                 return r;
                 } else {
index ed2f331b33eb1563df24ce94086ef80b55fde60c..18d470b6d675eead53b8a0281ec597d282cf8280 100644 (file)
@@ -2780,7 +2780,7 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
 
         /* The root cgroup doesn't expose this information, let's get it from /proc instead */
         if (unit_has_host_root_cgroup(u))
-                return procfs_memory_get_current(ret);
+                return procfs_memory_get_used(ret);
 
         if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
                 return -ENODATA;
index 4c5a02948c61a9bed1291d501dd168b0774bd8ad..be02e05f09ac100f2f43cc34da38bed370939c97 100644 (file)
@@ -251,6 +251,32 @@ _pure_ static MountParameters* get_mount_parameters(Mount *m) {
         return get_mount_parameters_fragment(m);
 }
 
+static int update_parameters_proc_self_mount_info(
+                Mount *m,
+                const char *what,
+                const char *options,
+                const char *fstype) {
+
+        MountParameters *p;
+        int r, q, w;
+
+        p = &m->parameters_proc_self_mountinfo;
+
+        r = free_and_strdup(&p->what, what);
+        if (r < 0)
+                return r;
+
+        q = free_and_strdup(&p->options, options);
+        if (q < 0)
+                return q;
+
+        w = free_and_strdup(&p->fstype, fstype);
+        if (w < 0)
+                return w;
+
+        return r > 0 || q > 0 || w > 0;
+}
+
 static int mount_add_mount_dependencies(Mount *m) {
         MountParameters *pm;
         Unit *other;
@@ -352,7 +378,8 @@ static int mount_add_device_dependencies(Mount *m) {
          * automatically stopped when the device disappears suddenly. */
         dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
 
-        mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT;
+        /* We always use 'what' from /proc/self/mountinfo if mounted */
+        mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT : UNIT_DEPENDENCY_FILE;
 
         r = unit_add_node_dependency(UNIT(m), p->what, device_wants_mount, dep, mask);
         if (r < 0)
@@ -426,6 +453,7 @@ static int mount_add_default_dependencies(Mount *m) {
         const char *after, *before;
         UnitDependencyMask mask;
         MountParameters *p;
+        bool nofail;
         int r;
 
         assert(m);
@@ -444,6 +472,7 @@ static int mount_add_default_dependencies(Mount *m) {
                 return 0;
 
         mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT;
+        nofail = m->from_fragment ? fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0") : false;
 
         if (mount_is_network(p)) {
                 /* We order ourselves after network.target. This is
@@ -474,9 +503,11 @@ static int mount_add_default_dependencies(Mount *m) {
                 before = SPECIAL_LOCAL_FS_TARGET;
         }
 
-        r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
-        if (r < 0)
-                return r;
+        if (!nofail) {
+                r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask);
+                if (r < 0)
+                        return r;
+        }
 
         r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask);
         if (r < 0)
@@ -823,6 +854,9 @@ static void mount_enter_dead(Mount *m, MountResult f) {
         unit_unref_uid_gid(UNIT(m), true);
 
         dynamic_creds_destroy(&m->dynamic_creds);
+
+        /* Any dependencies based on /proc/self/mountinfo are now stale */
+        unit_remove_dependencies(UNIT(m), UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT);
 }
 
 static void mount_enter_mounted(Mount *m, MountResult f) {
@@ -1428,32 +1462,6 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
         return 0;
 }
 
-static int update_parameters_proc_self_mount_info(
-                Mount *m,
-                const char *what,
-                const char *options,
-                const char *fstype) {
-
-        MountParameters *p;
-        int r, q, w;
-
-        p = &m->parameters_proc_self_mountinfo;
-
-        r = free_and_strdup(&p->what, what);
-        if (r < 0)
-                return r;
-
-        q = free_and_strdup(&p->options, options);
-        if (q < 0)
-                return q;
-
-        w = free_and_strdup(&p->fstype, fstype);
-        if (w < 0)
-                return w;
-
-        return r > 0 || q > 0 || w > 0;
-}
-
 static int mount_setup_new_unit(
                 Manager *m,
                 const char *name,
@@ -1844,6 +1852,7 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
                         }
 
                         mount->from_proc_self_mountinfo = false;
+                        assert_se(update_parameters_proc_self_mount_info(mount, NULL, NULL, NULL) >= 0);
 
                         switch (mount->state) {
 
index 80bbc34e3706e33bfa1f5d88988c11803f4c8c4c..7c51f2f633605d11ea2bb2df866679077074fab0 100644 (file)
@@ -16,6 +16,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "procfs-util.h"
 #include "string-util.h"
 #include "syslog-util.h"
 #include "unaligned.h"
 /* Keep at most 16K entries in the cache. (Note though that this limit may be violated if enough streams pin entries in
  * the cache, in which case we *do* permit this limit to be breached. That's safe however, as the number of stream
  * clients itself is limited.) */
-#define CACHE_MAX (16*1024)
+#define CACHE_MAX_FALLBACK 128U
+#define CACHE_MAX_MAX (16*1024U)
+#define CACHE_MAX_MIN 64U
+
+static size_t cache_max(void) {
+        static size_t cached = -1;
+
+        if (cached == (size_t) -1) {
+                uint64_t mem_total;
+                int r;
+
+                r = procfs_memory_get(&mem_total, NULL);
+                if (r < 0) {
+                        log_warning_errno(r, "Cannot query /proc/meminfo for MemTotal: %m");
+                        cached = CACHE_MAX_FALLBACK;
+                } else {
+                        /* Cache entries are usually a few kB, but the process cmdline is controlled by the
+                         * user and can be up to _SC_ARG_MAX, usually 2MB. Let's say that approximately up to
+                         * 1/8th of memory may be used by the cache.
+                         *
+                         * In the common case, this formula gives 64 cache entries for each GB of RAM.
+                         */
+                        long l = sysconf(_SC_ARG_MAX);
+                        assert(l > 0);
+
+                        cached = CLAMP(mem_total / 8 / (uint64_t) l, CACHE_MAX_MIN, CACHE_MAX_MAX);
+                }
+        }
+
+        return cached;
+}
 
 static int client_context_compare(const void *a, const void *b) {
         const ClientContext *x = a, *y = b;
@@ -550,15 +581,39 @@ refresh:
 }
 
 static void client_context_try_shrink_to(Server *s, size_t limit) {
+        ClientContext *c;
+        usec_t t;
+
         assert(s);
 
+        /* Flush any cache entries for PIDs that have already moved on. Don't do this
+         * too often, since it's a slow process. */
+        t = now(CLOCK_MONOTONIC);
+        if (s->last_cache_pid_flush + MAX_USEC < t) {
+                unsigned n = prioq_size(s->client_contexts_lru), idx = 0;
+
+                /* We do a number of iterations based on the initial size of the prioq.  When we remove an
+                 * item, a new item is moved into its places, and items to the right might be reshuffled.
+                 */
+                for (unsigned i = 0; i < n; i++) {
+                        c = prioq_peek_by_index(s->client_contexts_lru, idx);
+
+                        assert(c->n_ref == 0);
+
+                        if (!pid_is_unwaited(c->pid))
+                                client_context_free(s, c);
+                        else
+                                idx ++;
+                }
+
+                s->last_cache_pid_flush = t;
+        }
+
         /* Bring the number of cache entries below the indicated limit, so that we can create a new entry without
          * breaching the limit. Note that we only flush out entries that aren't pinned here. This means the number of
          * cache entries may very well grow beyond the limit, if all entries stored remain pinned. */
 
         while (hashmap_size(s->client_contexts) > limit) {
-                ClientContext *c;
-
                 c = prioq_pop(s->client_contexts_lru);
                 if (!c)
                         break; /* All remaining entries are pinned, give up */
@@ -627,7 +682,7 @@ static int client_context_get_internal(
                 return 0;
         }
 
-        client_context_try_shrink_to(s, CACHE_MAX-1);
+        client_context_try_shrink_to(s, cache_max()-1);
 
         r = client_context_new(s, pid, &c);
         if (r < 0)
index 6d4847b0cd869af4cbdac9d38f02464ddb23a40f..3f6b42ddd5089910afab213a141dc1b712fda2a1 100644 (file)
@@ -161,6 +161,8 @@ struct Server {
         Hashmap *client_contexts;
         Prioq *client_contexts_lru;
 
+        usec_t last_cache_pid_flush;
+
         ClientContext *my_context; /* the context of journald itself */
         ClientContext *pid1_context; /* the context of PID 1 */
 };
index 4221b9c5044e1b8e7dd949d03df4ae4a5171b342..04bf64cce5f2f702423094f31e17021128c73732 100644 (file)
@@ -196,7 +196,7 @@ int dhcp_identifier_set_iaid(
 
         if (legacy_unstable_byteorder)
                 /* for historical reasons (a bug), the bits were swapped and thus
-                 * the result was endianness dependant. Preserve that behavior. */
+                 * the result was endianness dependent. Preserve that behavior. */
                 id32 = __bswap_32(id32);
         else
                 /* the fixed behavior returns a stable byte order. Since LE is expected
index 0c804adb2ef92d77e2b6de9dca27263d73265dad..aadb3ab905eac951ae47ae90f6b85f927d6cba73 100644 (file)
@@ -47,7 +47,7 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
 
         r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
         if (r < 0)
-                return log_netdev_error_errno(netdev, r, "Could not append IFLA_PROTINFO attribute: %m");
+                return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
 
         r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
         if (r < 0)
index ae0fc8403e8fda30f67cebf228cef2d4756088c1..736373ae347d4bc71b97c29193dcdc804ffe9220 100644 (file)
@@ -1101,7 +1101,11 @@ static int link_request_set_addresses(Link *link) {
                 return r;
 
         LIST_FOREACH(addresses, ad, link->network->static_addresses) {
-                r = address_configure(ad, link, address_handler, false);
+                bool update;
+
+                update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
+
+                r = address_configure(ad, link, address_handler, update);
                 if (r < 0) {
                         log_link_warning_errno(link, r, "Could not set addresses: %m");
                         link_enter_failed(link);
@@ -1775,7 +1779,7 @@ static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
         return 1;
 }
 
-int link_up(Link *link) {
+static int link_up(Link *link) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         uint8_t ipv6ll_mode;
         int r;
index e417ea26ef3089ca177635f20da7530dbb7e0820..dcb1ea68dd987ae5ad170dbdc298edb38a2bdb73 100644 (file)
@@ -143,7 +143,6 @@ int link_get(Manager *m, int ifindex, Link **ret);
 int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
 void link_drop(Link *link);
 
-int link_up(Link *link);
 int link_down(Link *link);
 
 void link_enter_failed(Link *link);
index 8e81f40e0db50b8286dd99b7ca8b999f9d518127..e0c2d711e60a9f3d17a202343ef01f55d5a7c1d1 100644 (file)
@@ -4230,6 +4230,11 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
+        /* Ignore SIGPIPE here, because we use splice() on the ptyfwd stuff and that will generate SIGPIPE if
+         * the result is closed. Note that the container payload child will reset signal mask+handler anyway,
+         * so just turning this off here means we only turn it off in nspawn itself, not any children. */
+        (void) ignore_signals(SIGPIPE, -1);
+
         n_fd_passed = sd_listen_fds(false);
         if (n_fd_passed > 0) {
                 r = fdset_new_listen_fds(&fds, false);
index 7341f7f1eadaf1d840971d18f35fd119e6391314..cd8d68f215b2074b702784da880e231dab5c9a8a 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/libbpf.h>
 #include <string.h>
+#include <sys/mman.h>
 #include <unistd.h>
 
 #include "bpf-firewall.h"
 #include "tests.h"
 #include "unit.h"
 
+/* We use the same limit here that PID 1 bumps RLIMIT_MEMLOCK to if it can */
+#define CAN_MEMLOCK_SIZE (64U*1024U*1024U)
+
+static bool can_memlock(void) {
+        void *p;
+        bool b;
+
+        /* Let's see if we can mlock() a larger blob of memory. BPF programs are charged against
+         * RLIMIT_MEMLOCK, hence let's first make sure we can lock memory at all, and skip the test if we
+         * cannot. Why not check RLIMIT_MEMLOCK explicitly? Because in container environments the
+         * RLIMIT_MEMLOCK value we see might not match the RLIMIT_MEMLOCK value actually in effect. */
+
+        p = mmap(NULL, CAN_MEMLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0);
+        if (p == MAP_FAILED)
+                return false;
+
+        b = mlock(p, CAN_MEMLOCK_SIZE) >= 0;
+        if (b)
+                assert_se(munlock(p, CAN_MEMLOCK_SIZE) >= 0);
+
+        assert_se(munmap(p, CAN_MEMLOCK_SIZE) >= 0);
+        return b;
+}
+
 int main(int argc, char *argv[]) {
         struct bpf_insn exit_insn[] = {
                 BPF_MOV64_IMM(BPF_REG_0, 1),
@@ -26,6 +51,7 @@ int main(int argc, char *argv[]) {
         _cleanup_(manager_freep) Manager *m = NULL;
         Unit *u;
         char log_buf[65535];
+        struct rlimit rl;
         int r;
 
         test_setup_logging(LOG_DEBUG);
@@ -33,6 +59,13 @@ int main(int argc, char *argv[]) {
         if (is_run_on_travis_ci())
                 return log_tests_skipped("test-bpf fails on Travis CI: https://github.com/systemd/systemd/issues/9666");
 
+        assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0);
+        rl.rlim_cur = rl.rlim_max = MAX3(rl.rlim_cur, rl.rlim_max, CAN_MEMLOCK_SIZE);
+        (void) setrlimit(RLIMIT_MEMLOCK, &rl);
+
+        if (!can_memlock())
+                return log_tests_skipped("Can't use mlock(), skipping.");
+
         r = enter_cgroup_subroot();
         if (r == -ENOMEDIUM)
                 return log_tests_skipped("cgroupfs not available");
index bc5fdd15b269b19afe958705d3ce86587f6abe6c..53c9e090a70235bb3a3d0289a207f1e5841314b1 100644 (file)
@@ -69,6 +69,11 @@ static void test_struct(void) {
         assert_se(q = prioq_new((compare_func_t) test_compare));
         assert_se(s = set_new(&test_hash_ops));
 
+        assert_se(prioq_peek(q) == NULL);
+        assert_se(prioq_peek_by_index(q, 0) == NULL);
+        assert_se(prioq_peek_by_index(q, 1) == NULL);
+        assert_se(prioq_peek_by_index(q, (unsigned) -1) == NULL);
+
         for (i = 0; i < SET_SIZE; i++) {
                 assert_se(t = new0(struct test, 1));
                 t->value = (unsigned) rand();
@@ -79,6 +84,17 @@ static void test_struct(void) {
                         assert_se(set_consume(s, t) >= 0);
         }
 
+        for (i = 0; i < SET_SIZE; i++)
+                assert_se(prioq_peek_by_index(q, i));
+        assert_se(prioq_peek_by_index(q, SET_SIZE) == NULL);
+
+        unsigned count = 0;
+        PRIOQ_FOREACH_ITEM(q, t) {
+                assert_se(t);
+                count++;
+        }
+        assert_se(count == SET_SIZE);
+
         while ((t = set_steal_first(s))) {
                 assert_se(prioq_remove(q, t, &t->idx) == 1);
                 assert_se(prioq_remove(q, t, &t->idx) == 0);
index 08af380cc7901300c95b4014cb5556972a09d14e..1d0612985bf9f4c480e8c754cdf8437969a79de4 100644 (file)
@@ -18,7 +18,7 @@ int main(int argc, char *argv[]) {
         assert_se(procfs_cpu_get_usage(&nsec) >= 0);
         log_info("Current system CPU time: %s", format_timespan(buf, sizeof(buf), nsec/NSEC_PER_USEC, 1));
 
-        assert_se(procfs_memory_get_current(&v) >= 0);
+        assert_se(procfs_memory_get_used(&v) >= 0);
         log_info("Current memory usage: %s", format_bytes(buf, sizeof(buf), v));
 
         assert_se(procfs_tasks_get_current(&v) >= 0);
index b3bd7235c90973372ea49e72eb57c289b3aa4ed0..6fde4a316b13bef33389e50560af6950577bab6b 100644 (file)
@@ -616,8 +616,9 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
                 m->good = true;
 
                 server_address_pretty(m->current_server_address, &pretty);
-                log_info("Synchronized to time server %s (%s).", strna(pretty), m->current_server_name->string);
-                sd_notifyf(false, "STATUS=Synchronized to time server %s (%s).", strna(pretty), m->current_server_name->string);
+                /* "for the first time", as further successful syncs will not be logged. */
+                log_info("Synchronized to time server for the first time %s (%s).", strna(pretty), m->current_server_name->string);
+                sd_notifyf(false, "STATUS=Synchronized to time server for the first time %s (%s).", strna(pretty), m->current_server_name->string);
         }
 
         r = manager_arm_timer(m, m->poll_interval_usec);
index a8c79496682457ecc09d5ff49496839156c9f4d9..cb83761a6c3a440f555df028bfda199df9cfc01e 100644 (file)
@@ -99,11 +99,22 @@ run_qemu() {
             && KERNEL_BIN="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux"
     fi
 
+    CONSOLE=ttyS0
+
     if [[ ! "$KERNEL_BIN" ]]; then
         if [[ "$LOOKS_LIKE_ARCH" ]]; then
             KERNEL_BIN=/boot/vmlinuz-linux
         else
-            KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+            [ "$ARCH" ] || ARCH=$(uname -m)
+            case $ARCH in
+                ppc64*)
+                KERNEL_BIN=/boot/vmlinux-$KERNEL_VER
+                CONSOLE=hvc0
+                ;;
+                *)
+                KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+                ;;
+            esac
         fi
     fi
 
@@ -150,7 +161,7 @@ root=/dev/sda1 \
 raid=noautodetect \
 loglevel=2 \
 init=$PATH_TO_INIT \
-console=ttyS0 \
+console=$CONSOLE \
 selinux=0 \
 printk.devkmsg=on \
 $_cgroup_args \
index 33ec40b012997bdafe8f4125fa2cdf6fee486653..9e72d35a54054109b05adc987e89336a63d4ff99 100755 (executable)
@@ -1039,8 +1039,10 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         'dhcp-client-listen-port.network',
         'dhcp-client-route-metric.network',
         'dhcp-client-route-table.network',
+        'dhcp-client.network'
         'dhcp-server-veth-peer.network',
-        'dhcp-v4-server-veth-peer.network']
+        'dhcp-v4-server-veth-peer.network',
+        'static.network']
 
     def setUp(self):
         self.link_remove(self.links)
@@ -1219,6 +1221,43 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
         print(output)
         self.assertRegex(output, '192.168.5.*')
 
+    def test_dhcp_client_reuse_address_as_static(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.5')
+        self.assertRegex(output, '2600::')
+
+        ipv4_address = re.search('192\.168\.5\.[0-9]*/24', output)
+        ipv6_address = re.search('2600::[0-9a-f:]*/128', output)
+        static_network = '\n'.join(['[Match]', 'Name=veth99', '[Network]', 'IPv6AcceptRA=no', 'Address=' + ipv4_address.group(), 'Address=' + ipv6_address.group()])
+        print(static_network)
+
+        self.remove_unit_from_networkd_path(['dhcp-client.network'])
+
+        with open(os.path.join(network_unit_file_path, 'static.network'), mode='w') as f:
+            f.write(static_network)
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.5')
+        self.assertRegex(output, 'valid_lft forever preferred_lft forever')
+
+        output = subprocess.check_output(['ip', '-6', 'address', 'show', 'dev', 'veth99', 'scope', 'global']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '2600::')
+        self.assertRegex(output, 'valid_lft forever preferred_lft forever')
+
 if __name__ == '__main__':
     unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
                                                      verbosity=3))
index 1d06b369d4149effc1862de7620bebefcd7cf6d9..50df15c291c15400c105cd6546086b408224cb35 100644 (file)
@@ -14,7 +14,6 @@ DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-sysusers.service
 Before=sysinit.target local-fs-pre.target systemd-udevd.service shutdown.target
-ConditionCapability=CAP_SYS_MODULE
 
 [Service]
 Type=oneshot