]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #11540 from taro-yamada/mytest
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Jan 2019 10:27:42 +0000 (11:27 +0100)
committerGitHub <noreply@github.com>
Tue, 29 Jan 2019 10:27:42 +0000 (11:27 +0100)
ReFix #11128

58 files changed:
hwdb/60-sensor.hwdb
man/systemd.mount.xml
man/timedatectl.xml
meson.build
src/basic/alloc-util.h
src/basic/in-addr-util.c
src/basic/in-addr-util.h
src/basic/path-util.h
src/basic/prioq.c
src/basic/prioq.h
src/basic/process-util.c
src/basic/process-util.h
src/basic/procfs-util.c
src/basic/procfs-util.h
src/basic/string-util.h
src/cgtop/cgtop.c
src/core/cgroup.c
src/core/mount.c
src/cryptsetup/cryptsetup.c
src/journal/audit-type.h
src/journal/journal-send.c
src/journal/journald-audit.c
src/journal/journald-context.c
src/journal/journald-server.h
src/kernel-install/90-loaderentry.install
src/kernel-install/kernel-install
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/network-internal.c
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/netlink-types.c
src/libsystemd/sd-netlink/netlink-types.h
src/network/netdev/bridge.c
src/network/netdev/netdev.c
src/network/netdev/wireguard.c
src/network/networkd-address.c
src/network/networkd-link.c
src/network/networkd-link.h
src/nspawn/nspawn-network.c
src/nspawn/nspawn.c
src/resolve/resolved-dns-dnssec.c
src/systemd/sd-netlink.h
src/test/test-barrier.c
src/test/test-bpf.c
src/test/test-in-addr-util.c
src/test/test-prioq.c
src/test/test-procfs-util.c
src/timesync/timesyncd-manager.c
src/tmpfiles/tmpfiles.c
test/test-functions
test/test-network/conf/24-search-domain.network
test/test-network/conf/25-wireguard.netdev
test/test-network/conf/dhcp-server-veth-peer.network
test/test-network/conf/dhcp-v4-server-veth-peer.network
test/test-network/systemd-networkd-tests.py
units/initrd-switch-root.target
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 ff7a46793afca27dc025b052d95c699546edf395..893a1238ff1a0bcac7ad68cbb44979ab53b31ffe 100644 (file)
 
 typedef void (*free_func_t)(void *p);
 
+/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
+ * proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */
+#define ALLOCA_MAX (4U*1024U*1024U)
+
 #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
 
 #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
 
-#define newa(t, n)                                              \
-        ({                                                      \
-                assert(!size_multiply_overflow(sizeof(t), n));  \
-                (t*) alloca(sizeof(t)*(n));                     \
+#define newa(t, n)                                                      \
+        ({                                                              \
+                size_t _n_ = n;                                         \
+                assert(!size_multiply_overflow(sizeof(t), _n_));        \
+                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
+                (t*) alloca(sizeof(t)*_n_);                             \
         })
 
-#define newa0(t, n)                                             \
-        ({                                                      \
-                assert(!size_multiply_overflow(sizeof(t), n));  \
-                (t*) alloca0(sizeof(t)*(n));                    \
+#define newa0(t, n)                                                     \
+        ({                                                              \
+                size_t _n_ = n;                                         \
+                assert(!size_multiply_overflow(sizeof(t), _n_));        \
+                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
+                (t*) alloca0(sizeof(t)*_n_);                            \
         })
 
 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
@@ -51,16 +59,20 @@ void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
 #define memdupa(p, l)                           \
         ({                                      \
                 void *_q_;                      \
-                _q_ = alloca(l);                \
-                memcpy(_q_, p, l);              \
+                size_t _l_ = l;                 \
+                assert(_l_ <= ALLOCA_MAX);      \
+                _q_ = alloca(_l_);              \
+                memcpy(_q_, p, _l_);            \
         })
 
 #define memdupa_suffix0(p, l)                   \
         ({                                      \
                 void *_q_;                      \
-                _q_ = alloca(l + 1);            \
-                ((uint8_t*) _q_)[l] = 0;        \
-                memcpy(_q_, p, l);              \
+                size_t _l_ = l;                 \
+                assert(_l_ <= ALLOCA_MAX);      \
+                _q_ = alloca(_l_ + 1);          \
+                ((uint8_t*) _q_)[_l_] = 0;      \
+                memcpy(_q_, p, _l_);            \
         })
 
 static inline void freep(void *p) {
@@ -116,6 +128,7 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
         ({                                              \
                 char *_new_;                            \
                 size_t _len_ = n;                       \
+                assert(_len_ <= ALLOCA_MAX);            \
                 _new_ = alloca(_len_);                  \
                 (void *) memset(_new_, 0, _len_);       \
         })
@@ -125,16 +138,18 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
         ({                                                              \
                 void *_ptr_;                                            \
                 size_t _mask_ = (align) - 1;                            \
-                _ptr_ = alloca((size) + _mask_);                        \
+                size_t _size_ = size;                                   \
+                assert(_size_ <= ALLOCA_MAX);                           \
+                _ptr_ = alloca(_size_ + _mask_);                        \
                 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \
         })
 
 #define alloca0_align(size, align)                                      \
         ({                                                              \
                 void *_new_;                                            \
-                size_t _size_ = (size);                                 \
-                _new_ = alloca_align(_size_, (align));                  \
-                (void*)memset(_new_, 0, _size_);                        \
+                size_t _xsize_ = (size);                                \
+                _new_ = alloca_align(_xsize_, (align));                 \
+                (void*)memset(_new_, 0, _xsize_);                       \
         })
 
 /* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to
index 411efb242b9abd49c0f2d4b2d52595e84b3b23f6..2bffe473ca696d4fd76f76a07afe20f1d9a34ac5 100644 (file)
@@ -495,9 +495,8 @@ int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret) {
         return 0;
 }
 
-int in_addr_prefix_from_string_internal(
+int in_addr_prefix_from_string(
                 const char *p,
-                bool use_default_prefixlen,
                 int family,
                 union in_addr_union *ret_prefix,
                 unsigned char *ret_prefixlen) {
@@ -531,13 +530,6 @@ int in_addr_prefix_from_string_internal(
                 r = in_addr_parse_prefixlen(family, e+1, &k);
                 if (r < 0)
                         return r;
-        } else if (use_default_prefixlen) {
-                if (family == AF_INET) {
-                        r = in4_addr_default_prefixlen(&buffer.in, &k);
-                        if (r < 0)
-                                return r;
-                } else
-                        k = 0;
         } else
                 k = FAMILY_ADDRESS_SIZE(family) * 8;
 
@@ -551,7 +543,7 @@ int in_addr_prefix_from_string_internal(
 
 int in_addr_prefix_from_string_auto_internal(
                 const char *p,
-                bool use_default_prefixlen,
+                InAddrPrefixLenMode mode,
                 int *ret_family,
                 union in_addr_union *ret_prefix,
                 unsigned char *ret_prefixlen) {
@@ -582,15 +574,24 @@ int in_addr_prefix_from_string_auto_internal(
                 r = in_addr_parse_prefixlen(family, e+1, &k);
                 if (r < 0)
                         return r;
-        } else if (use_default_prefixlen) {
-                if (family == AF_INET) {
-                        r = in4_addr_default_prefixlen(&buffer.in, &k);
-                        if (r < 0)
-                                return r;
-                } else
-                        k = 0;
         } else
-                k = FAMILY_ADDRESS_SIZE(family) * 8;
+                switch (mode) {
+                case PREFIXLEN_FULL:
+                        k = FAMILY_ADDRESS_SIZE(family) * 8;
+                        break;
+                case PREFIXLEN_REFUSE:
+                        return -ENOANO; /* To distinguish this error from others. */
+                case PREFIXLEN_LEGACY:
+                        if (family == AF_INET) {
+                                r = in4_addr_default_prefixlen(&buffer.in, &k);
+                                if (r < 0)
+                                        return r;
+                        } else
+                                k = 0;
+                        break;
+                default:
+                        assert_not_reached("Invalid prefixlen mode");
+                }
 
         if (ret_family)
                 *ret_family = family;
index 5de85cc422084dc33fa583d878a14532fce16ee8..3069790519b5c5527d1cafa563eab2b29d7cce8a 100644 (file)
@@ -45,19 +45,17 @@ int in4_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mas
 int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen);
 int in_addr_prefix_covers(int family, const union in_addr_union *prefix, unsigned char prefixlen, const union in_addr_union *address);
 int in_addr_parse_prefixlen(int family, const char *p, unsigned char *ret);
-int in_addr_prefix_from_string_internal(const char *p, bool use_default_prefixlen, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
-int in_addr_prefix_from_string_auto_internal(const char *p, bool use_default_prefixlen, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
-static inline int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
-        return in_addr_prefix_from_string_internal(p, false, family, ret_prefix, ret_prefixlen);
-}
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
+
+typedef enum InAddrPrefixLenMode {
+        PREFIXLEN_FULL,   /* Default to prefixlen of address size, 32 for IPv4 or 128 for IPv6, if not specified. */
+        PREFIXLEN_REFUSE, /* Fail with -ENOANO if prefixlen is not specified. */
+        PREFIXLEN_LEGACY, /* Default to legacy default prefixlen calculation from address if not specified. */
+} InAddrPrefixLenMode;
+
+int in_addr_prefix_from_string_auto_internal(const char *p, InAddrPrefixLenMode mode, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen);
 static inline int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
-        return in_addr_prefix_from_string_auto_internal(p, false, ret_family, ret_prefix, ret_prefixlen);
-}
-static inline int in_addr_default_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
-        return in_addr_prefix_from_string_internal(p, true, family, ret_prefix, ret_prefixlen);
-}
-static inline int in_addr_default_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) {
-        return in_addr_prefix_from_string_auto_internal(p, true, ret_family, ret_prefix, ret_prefixlen);
+        return in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_FULL, ret_family, ret_prefix, ret_prefixlen);
 }
 
 static inline size_t FAMILY_ADDRESS_SIZE(int family) {
index 094aa47c01deb87e5da3d00a319d0992205c8369..86c5a577cb46d2db8ad0cf3e1256fe91a5878c15 100644 (file)
@@ -131,7 +131,7 @@ char *prefix_root(const char *root, const char *path);
                         _ret = _path;                                   \
                 else {                                                  \
                         _l = strlen(_root) + 1 + strlen(_path) + 1;     \
-                        _n = alloca(_l);                                \
+                        _n = newa(char, _l);                            \
                         _p = stpcpy(_n, _root);                         \
                         while (_p > _n && _p[-1] == '/')                \
                                 _p--;                                   \
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 496e14d3de17667217e455c43471bf9f9dd39b8c..c85ea30ecc78544719b22ec625c3ca7e9d61b20a 100644 (file)
@@ -24,8 +24,8 @@
                 if (_pid_ == 0) {                                       \
                         _r_ = ("/proc/self/" field);                    \
                 } else {                                                \
-                        _r_ = alloca(STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
-                        sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_);                       \
+                        _r_ = newa(char, STRLEN("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
+                        sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
                 }                                                       \
                 _r_;                                                    \
         })
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 a5b5a16a5d0f553d3c1713d5b4de1fce0e8f8601..38070abb22f89ecd2a78702055c6e5840b61aaf0 100644 (file)
@@ -6,6 +6,7 @@
 #include <stddef.h>
 #include <string.h>
 
+#include "alloc-util.h"
 #include "macro.h"
 
 /* What is interpreted as whitespace? */
@@ -111,7 +112,7 @@ char *strjoin_real(const char *x, ...) _sentinel_;
                 size_t _i_;                                           \
                 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
                         _len_ += strlen(_appendees_[_i_]);              \
-                _p_ = _d_ = alloca(_len_ + 1);                          \
+                _p_ = _d_ = newa(char, _len_ + 1);                      \
                 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
                         _p_ = stpcpy(_p_, _appendees_[_i_]);            \
                 *_p_ = 0;                                               \
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 daf26aad70a23a9e44af3a2f95d07bcafdb53c8d..9cb52ddf264513e96775d50c3c7b2c7222418ed6 100644 (file)
@@ -408,8 +408,7 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
                         return log_oom();
 
                 strncpy(c, *p, arg_key_size);
-                free(*p);
-                *p = c;
+                free_and_replace(*p, c);
         }
 
         *ret = TAKE_PTR(passwords);
@@ -451,7 +450,7 @@ static int attach_tcrypt(
                 r = read_one_line_file(key_file, &passphrase);
                 if (r < 0) {
                         log_error_errno(r, "Failed to read password file '%s': %m", key_file);
-                        return -EAGAIN;
+                        return -EAGAIN; /* log with the actual error, but return EAGAIN */
                 }
 
                 params.passphrase = passphrase;
@@ -461,14 +460,19 @@ static int attach_tcrypt(
 
         r = crypt_load(cd, CRYPT_TCRYPT, &params);
         if (r < 0) {
-                if (key_file && r == -EPERM)
-                        return log_error_errno(SYNTHETIC_ERRNO(EAGAIN),
-                                               "Failed to activate using password file '%s'.",
-                                               key_file);
-                return r;
+                if (key_file && r == -EPERM) {
+                        log_error_errno(r, "Failed to activate using password file '%s'. (Key data not correct?)", key_file);
+                        return -EAGAIN; /* log the actual error, but return EAGAIN */
+                }
+
+                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", crypt_get_device_name(cd));
         }
 
-        return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
+        r = crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
+        if (r < 0)
+                return log_error_errno(r, "Failed to activate tcrypt device %s: %m", crypt_get_device_name(cd));
+
+        return 0;
 }
 
 static int attach_luks_or_plain(struct crypt_device *cd,
@@ -486,10 +490,8 @@ static int attach_luks_or_plain(struct crypt_device *cd,
 
         if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
                 r = crypt_load(cd, CRYPT_LUKS, NULL);
-                if (r < 0) {
-                        log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
-                        return r;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd));
 
                 if (data_device)
                         r = crypt_set_data_device(cd, data_device);
@@ -530,23 +532,16 @@ static int attach_luks_or_plain(struct crypt_device *cd,
                         cipher_mode = "cbc-essiv:sha256";
                 }
 
-                /* for CRYPT_PLAIN limit reads
-                 * from keyfile to key length, and
-                 * ignore keyfile-size */
+                /* for CRYPT_PLAIN limit reads from keyfile to key length, and ignore keyfile-size */
                 arg_keyfile_size = arg_key_size;
 
-                /* In contrast to what the name
-                 * crypt_setup() might suggest this
-                 * doesn't actually format anything,
-                 * it just configures encryption
-                 * parameters when used for plain
-                 * mode. */
+                /* In contrast to what the name crypt_setup() might suggest this doesn't actually format
+                 * anything, it just configures encryption parameters when used for plain mode. */
                 r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, &params);
 
                 /* hash == NULL implies the user passed "plain" */
                 pass_volume_key = (params.hash == NULL);
         }
-
         if (r < 0)
                 return log_error_errno(r, "Loading of cryptographic parameters failed: %m");
 
@@ -558,22 +553,30 @@ static int attach_luks_or_plain(struct crypt_device *cd,
 
         if (key_file) {
                 r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
-                        return -EAGAIN;
+                if (r == -EPERM) {
+                        log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file);
+                        return -EAGAIN; /* Log actual error, but return EAGAIN */
                 }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
         } else {
                 char **p;
 
+                r = -EINVAL;
                 STRV_FOREACH(p, passwords) {
                         if (pass_volume_key)
                                 r = crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags);
                         else
                                 r = crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags);
-
                         if (r >= 0)
                                 break;
                 }
+                if (r == -EPERM) {
+                        log_error_errno(r, "Failed to activate with specified passphrase. (Passphrase incorrect?)");
+                        return -EAGAIN; /* log actual error, but return EAGAIN */
+                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to activate with specified passphrase: %m");
         }
 
         return r;
@@ -624,10 +627,8 @@ static int run(int argc, char *argv[]) {
 
                 /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
 
-                if (argc < 4) {
-                        log_error("attach requires at least two arguments.");
-                        return -EINVAL;
-                }
+                if (argc < 4)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least two arguments.");
 
                 if (argc >= 5 &&
                     argv[4][0] &&
@@ -635,7 +636,7 @@ static int run(int argc, char *argv[]) {
                     !streq(argv[4], "none")) {
 
                         if (!path_is_absolute(argv[4]))
-                                log_error("Password file path '%s' is not absolute. Ignoring.", argv[4]);
+                                log_warning("Password file path '%s' is not absolute. Ignoring.", argv[4]);
                         else
                                 key_file = argv[4];
                 }
@@ -709,20 +710,15 @@ static int run(int argc, char *argv[]) {
                                                          flags);
                         if (r >= 0)
                                 break;
-                        if (r == -EAGAIN) {
-                                key_file = NULL;
-                                continue;
-                        }
-                        if (r != -EPERM)
-                                return log_error_errno(r, "Failed to activate: %m");
+                        if (r != -EAGAIN)
+                                return r;
 
-                        log_warning("Invalid passphrase.");
+                        /* Passphrase not correct? Let's try again! */
+                        key_file = NULL;
                 }
 
-                if (arg_tries != 0 && tries >= arg_tries) {
-                        log_error("Too many attempts; giving up.");
-                        return -EPERM;
-                }
+                if (arg_tries != 0 && tries >= arg_tries)
+                        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up.");
 
         } else if (streq(argv[1], "detach")) {
 
@@ -740,10 +736,8 @@ static int run(int argc, char *argv[]) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to deactivate: %m");
 
-        } else {
-                log_error("Unknown verb %s.", argv[1]);
-                return -EINVAL;
-        }
+        } else
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
 
         return 0;
 }
index 069a883490d69b0b071d3327996bd2caa1a82db9..98e5c39420e6360e812fa5f24c6d618f95b8b34a 100644 (file)
@@ -4,6 +4,7 @@
 #include <alloca.h>
 #include <stdio.h>
 
+#include "alloc-util.h"
 #include "macro.h"
 
 const char *audit_type_to_string(int type);
@@ -15,7 +16,7 @@ int audit_type_from_string(const char *s);
                 const char *_s_;                                        \
                 _s_ = audit_type_to_string(type);                       \
                 if (!_s_) {                                             \
-                        _s_ = alloca(STRLEN("AUDIT") + DECIMAL_STR_MAX(int)); \
+                        _s_ = newa(char, STRLEN("AUDIT") + DECIMAL_STR_MAX(int)); \
                         sprintf((char*) _s_, "AUDIT%04i", type);        \
                 }                                                       \
                 _s_;                                                    \
index 87056435fcdd9973237e1f8c230884b4a5057975..8618454131bcb70c02c0a9d90d012fcc1de873bb 100644 (file)
@@ -30,7 +30,7 @@
                 const char *_func = (func);       \
                 char **_f = &(f);                 \
                 _fl = strlen(_func) + 1;          \
-                *_f = alloca(_fl + 10);           \
+                *_f = newa(char, _fl + 10);       \
                 memcpy(*_f, "CODE_FUNC=", 10);    \
                 memcpy(*_f + 10, _func, _fl);     \
         } while (false)
@@ -403,7 +403,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
         identifier = strempty(identifier);
 
         l = strlen(identifier);
-        header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
+        header = newa(char, l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
 
         memcpy(header, identifier, l);
         header[l++] = '\n';
index 345e43ef44f7d3627be1b50cf922c24d397345fb..accbad418047c1d5f1e21ea56b3159e67f8542a5 100644 (file)
@@ -162,7 +162,7 @@ static int map_generic_field(const char *prefix, const char **p, struct iovec **
         if (e <= *p || e >= *p + 16)
                 return 0;
 
-        c = alloca(strlen(prefix) + (e - *p) + 2);
+        c = newa(char, strlen(prefix) + (e - *p) + 2);
 
         t = stpcpy(c, prefix);
         for (f = *p; f < e; f++) {
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 e5fb232f35c24826fadc97d99042a41d367fd59c..75dd5a1b7dcc9c7799fe650c68f48d7518488598 100644 (file)
@@ -83,7 +83,9 @@ cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" &&
     exit 1
 }
 
-for initrd in "${@:${INITRD_OPTIONS_START}}"; do
+INITRD_OPTIONS=( "${@:${INITRD_OPTIONS_START}}" )
+
+for initrd in "${INITRD_OPTIONS[@]}"; do
     if [[ -f "${initrd}" ]]; then
         initrd_basename="$(basename ${initrd})"
         cp "${initrd}" "$BOOT_DIR_ABS/${initrd_basename}" &&
@@ -95,6 +97,10 @@ for initrd in "${@:${INITRD_OPTIONS_START}}"; do
     fi
 done
 
+# If no initrd option is supplied, fallback to "initrd" which is
+# the name used by dracut when generating it in its kernel-install hook
+[[ ${#INITRD_OPTIONS[@]} == 0 ]] && INITRD_OPTIONS=( initrd )
+
 mkdir -p "${LOADER_ENTRY%/*}" || {
     echo "Could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2
     exit 1
@@ -106,7 +112,7 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
     echo "machine-id $MACHINE_ID"
     echo "options    ${BOOT_OPTIONS[*]}"
     echo "linux      $BOOT_DIR/linux"
-    for initrd in "${@:${INITRD_OPTIONS_START}}"; do
+    for initrd in "${INITRD_OPTIONS[@]}"; do
         [[ -f $BOOT_DIR_ABS/$(basename ${initrd}) ]] && \
             echo "initrd     $BOOT_DIR/$(basename ${initrd})"
     done
index 7973818bcadb0b04952866d491d329debbce2495..b85c7c557e24f8f3a066f095eef276b3c19f0439 100644 (file)
@@ -65,14 +65,16 @@ done
 
 if [[ "${0##*/}" == 'installkernel' ]]; then
     COMMAND='add'
+    # make install doesn't pass any parameter wrt initrd handling
+    INITRD_OPTIONS=()
 else
     COMMAND="$1"
     shift
+    INITRD_OPTIONS=( "${@:3}" )
 fi
 
 KERNEL_VERSION="$1"
 KERNEL_IMAGE="$2"
-INITRD_OPTIONS_START="3"
 
 if [[ -f /etc/machine-id ]]; then
     read MACHINE_ID < /etc/machine-id
@@ -124,7 +126,7 @@ case $COMMAND in
 
         for f in "${PLUGINS[@]}"; do
             if [[ -x $f ]]; then
-                "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" "${@:${INITRD_OPTIONS_START}}"
+                "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" "${INITRD_OPTIONS[@]}"
                 x=$?
                 if [[ $x == $SKIP_REMAINING ]]; then
                     ret=0
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 b3b134d65057c467d108c222da695313198b4c63..0348e7fa9dabe93ce39f2bddc8c5f1c5300afa8b 100644 (file)
@@ -52,7 +52,7 @@ int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
 
         l = strlen(name);
         sz = sizeof(sd_id128_t) + l;
-        v = alloca(sz);
+        v = newa(uint8_t, sz);
 
         /* fetch some persistent data unique to this machine */
         r = sd_id128_get_machine((sd_id128_t*) v);
index d0538104ae251100f2e1ffd1f366040d646d6bfc..58329f3fe7885b9b68fa6fc7932e1317ff35760d 100644 (file)
@@ -1149,7 +1149,7 @@ static int object_manager_serialize_path_and_fallbacks(
                 return 0;
 
         /* Second, add fallback vtables registered for any of the prefixes */
-        prefix = alloca(strlen(path) + 1);
+        prefix = newa(char, strlen(path) + 1);
         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                 r = object_manager_serialize_path(bus, reply, prefix, path, true, error);
                 if (r < 0)
@@ -1500,7 +1500,7 @@ static int bus_find_parent_object_manager(sd_bus *bus, struct node **out, const
         if (!n) {
                 char *prefix;
 
-                prefix = alloca(strlen(path) + 1);
+                prefix = newa(char, strlen(path) + 1);
                 OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                         n = hashmap_get(bus->nodes, prefix);
                         if (n)
@@ -2114,7 +2114,7 @@ _public_ int sd_bus_emit_properties_changed_strv(
                 if (bus->nodes_modified)
                         continue;
 
-                prefix = alloca(strlen(path) + 1);
+                prefix = newa(char, strlen(path) + 1);
                 OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                         r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names);
                         if (r != 0)
@@ -2291,7 +2291,7 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
         if (bus->nodes_modified)
                 return 0;
 
-        prefix = alloca(strlen(path) + 1);
+        prefix = newa(char, strlen(path) + 1);
         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                 r = object_added_append_all_prefix(bus, m, s, prefix, path, true);
                 if (r < 0)
@@ -2462,7 +2462,7 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
         if (bus->nodes_modified)
                 return 0;
 
-        prefix = alloca(strlen(path) + 1);
+        prefix = newa(char, strlen(path) + 1);
         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                 r = object_removed_append_all_prefix(bus, m, s, prefix, path, true);
                 if (r < 0)
@@ -2626,7 +2626,7 @@ static int interfaces_added_append_one(
         if (bus->nodes_modified)
                 return 0;
 
-        prefix = alloca(strlen(path) + 1);
+        prefix = newa(char, strlen(path) + 1);
         OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
                 r = interfaces_added_append_one_prefix(bus, m, prefix, path, interface, true);
                 if (r != 0)
index ed185131b83ae40215398b0453191cc67b2db2b4..30d6455b6fc76344ecdde97a402690e3e5548726 100644 (file)
@@ -981,7 +981,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
                 return r;
 
         n = m->n_iovec * sizeof(struct iovec);
-        iov = alloca(n);
+        iov = newa(struct iovec, n);
         memcpy_safe(iov, m->iovec, n);
 
         j = 0;
index b0b25639f44e71d11597c42978726a9e84e24da3..5e9bc4513970fc96107786203f6b5f06cce25972 100644 (file)
@@ -370,6 +370,42 @@ int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short typ
         return 0;
 }
 
+int sd_netlink_message_append_sockaddr_in(sd_netlink_message *m, unsigned short type, const struct sockaddr_in *data) {
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(!m->sealed, -EPERM);
+        assert_return(data, -EINVAL);
+
+        r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_SOCKADDR);
+        if (r < 0)
+                return r;
+
+        r = add_rtattr(m, type, data, sizeof(struct sockaddr_in));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_netlink_message_append_sockaddr_in6(sd_netlink_message *m, unsigned short type, const struct sockaddr_in6 *data) {
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(!m->sealed, -EPERM);
+        assert_return(data, -EINVAL);
+
+        r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_SOCKADDR);
+        if (r < 0)
+                return r;
+
+        r = add_rtattr(m, type, data, sizeof(struct sockaddr_in6));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short type, const struct ether_addr *data) {
         int r;
 
index bb7e8c33bae3b9b979d09d9678167f284f078ec9..9dcd3f2ac8cc2e97c57780c833ea76e7fe24ba3f 100644 (file)
@@ -721,7 +721,7 @@ static const NLType genl_wireguard_peer_types[] = {
         [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 },
         [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN },
         [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 },
-        [WGPEER_A_ENDPOINT] = { /* either size of sockaddr_in or sockaddr_in6 depending on address family */ },
+        [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR },
         [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system },
 };
 
index 3133e4863d1e2a2b862fcb44077c128318fc1c78..b84fa4762b074ef8e62ec7b1b02249b75483a369 100644 (file)
@@ -16,6 +16,7 @@ enum {
         NETLINK_TYPE_CACHE_INFO,
         NETLINK_TYPE_NESTED,                    /* NLA_NESTED */
         NETLINK_TYPE_UNION,
+        NETLINK_TYPE_SOCKADDR,
 };
 
 typedef enum NLMatchType {
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 65959f4a03f308a22699b0cb77f573db28154349..0263917468789f8884b3393d7325a3eaa60ab6f6 100644 (file)
@@ -481,7 +481,7 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
 
         l = strlen(ifname);
         sz = sizeof(sd_id128_t) + l;
-        v = alloca(sz);
+        v = newa(uint8_t, sz);
 
         /* fetch some persistent data unique to the machine */
         r = sd_id128_get_machine((sd_id128_t*) v);
index 1efd8863f682823ba20f013e4d1f91df54f27e29..0c0b16d1da547dfdf2a393c30e72a9da6e6e6abc 100644 (file)
@@ -109,7 +109,7 @@ static int wireguard_set_peer_one(NetDev *netdev, sd_netlink_message *message, c
         if (r < 0)
                 goto cancel;
 
-        if (!start) {
+        if (!*mask_start) {
                 r = sd_netlink_message_append_data(message, WGPEER_A_PRESHARED_KEY, &peer->preshared_key, WG_KEY_LEN);
                 if (r < 0)
                         goto cancel;
@@ -123,9 +123,9 @@ static int wireguard_set_peer_one(NetDev *netdev, sd_netlink_message *message, c
                         goto cancel;
 
                 if (peer->endpoint.sa.sa_family == AF_INET)
-                        r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in, sizeof(peer->endpoint.in));
+                        r = sd_netlink_message_append_sockaddr_in(message, WGPEER_A_ENDPOINT, &peer->endpoint.in);
                 else if (peer->endpoint.sa.sa_family == AF_INET6)
-                        r = sd_netlink_message_append_data(message, WGPEER_A_ENDPOINT, &peer->endpoint.in6, sizeof(peer->endpoint.in6));
+                        r = sd_netlink_message_append_sockaddr_in6(message, WGPEER_A_ENDPOINT, &peer->endpoint.in6);
                 if (r < 0)
                         goto cancel;
         }
index 502b9e39dad3a32e12325077afabd0bd74bb52ba..fa7f9b8d74ac2e54a0ea61a2265c0024266442c3 100644 (file)
@@ -748,7 +748,15 @@ int config_parse_address(const char *unit,
                 return r;
 
         /* Address=address/prefixlen */
-        r = in_addr_default_prefix_from_string_auto(rvalue, &f, &buffer, &prefixlen);
+        r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
+        if (r == -ENOANO) {
+                log_syntax(unit, LOG_ERR, filename, line, r,
+                           "An address '%s' is specified without prefix length. "
+                           "The behavior of parsing addresses without prefix length will be changed in the future release. "
+                           "Please specify prefix length explicitly.", rvalue);
+
+                r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_LEGACY, &f, &buffer, &prefixlen);
+        }
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid address '%s', ignoring assignment: %m", rvalue);
                 return 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 9d0f8a9956b3fc47b93728f93915183f397c31da..c028b5755a841bf39890c94c8b0f238aff072f1e 100644 (file)
@@ -67,7 +67,7 @@ static int generate_mac(
         if (idx > 0)
                 sz += sizeof(idx);
 
-        v = alloca(sz);
+        v = newa(uint8_t, sz);
 
         /* fetch some persistent data unique to the host */
         r = sd_id128_get_machine((sd_id128_t*) v);
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 335fd477800888ad587ab8165c7fd66bf91d6d5c..14acc4e77db58c9029d1ce72c8e223f3fdd26d6a 100644 (file)
@@ -402,7 +402,7 @@ static int dnssec_ecdsa_verify(
         if (rrsig->rrsig.signature_size != key_size * 2)
                 return -EINVAL;
 
-        q = alloca(key_size*2 + 1);
+        q = newa(uint8_t, key_size*2 + 1);
         q[0] = 0x04; /* Prepend 0x04 to indicate an uncompressed key */
         memcpy(q+1, dnskey->dnskey.key, key_size*2);
 
index a97a965ec403f706a9c99c88e558a9e5f2edc8df..9e6e437babcc7f8ddb3c1237a34da70bb74b87a7 100644 (file)
@@ -78,6 +78,8 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui
 int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, const void *data, size_t len);
 int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type, const struct in_addr *data);
 int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short type, const struct in6_addr *data);
+int sd_netlink_message_append_sockaddr_in(sd_netlink_message *m, unsigned short type, const struct sockaddr_in *data);
+int sd_netlink_message_append_sockaddr_in6(sd_netlink_message *m, unsigned short type, const struct sockaddr_in6 *data);
 int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short type, const struct ether_addr *data);
 int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short type, const struct ifa_cacheinfo *info);
 
index 6ae84cd6fcfcf38daebba54fe8f9517fb46b3975..6469129fa4e1f0b0c048abe8f932cb32bfabb1b4 100644 (file)
@@ -17,6 +17,7 @@
 #include "barrier.h"
 #include "util.h"
 #include "tests.h"
+#include "virt.h"
 
 /* 20ms to test deadlocks; All timings use multiples of this constant as
  * alarm/sleep timers. If this timeout is too small for slow machines to perform
@@ -420,11 +421,27 @@ TEST_BARRIER(test_barrier_pending_exit,
         TEST_BARRIER_WAIT_SUCCESS(pid2));
 
 int main(int argc, char *argv[]) {
+        int v;
         test_setup_logging(LOG_INFO);
 
         if (!slow_tests_enabled())
                 return log_tests_skipped("slow tests are disabled");
 
+        /*
+         * This test uses real-time alarms and sleeps to test for CPU races
+         * explicitly. This is highly fragile if your system is under load. We
+         * already increased the BASE_TIME value to make the tests more robust,
+         * but that just makes the test take significantly longer. Given the recent
+         * issues when running the test in a virtualized environments, limit it
+         * to bare metal machines only, to minimize false-positives in CIs.
+         */
+        v = detect_virtualization();
+        if (IN_SET(v, -EPERM, -EACCES))
+                return log_tests_skipped("Cannot detect virtualization");
+
+        if (v != VIRTUALIZATION_NONE)
+                return log_tests_skipped("This test requires a baremetal machine");
+
         test_barrier_sync();
         test_barrier_wait_next();
         test_barrier_wait_next_twice();
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 75c3e305c38255edd7dba120251f68b694a9d71e..16844e95652533316e24cebf1da05bffc8b56abc 100644 (file)
@@ -2,83 +2,85 @@
 
 #include <netinet/in.h>
 
+#include "log.h"
 #include "in-addr-util.h"
 
-static void test_in_addr_prefix_from_string(const char *p, int family, int ret, const union in_addr_union *u, unsigned char prefixlen, bool use_default) {
+static void test_in_addr_prefix_from_string(
+                const char *p,
+                int family,
+                int ret,
+                const union in_addr_union *u,
+                unsigned char prefixlen,
+                int ret_refuse,
+                unsigned char prefixlen_refuse,
+                int ret_legacy,
+                unsigned char prefixlen_legacy) {
+
         union in_addr_union q;
         unsigned char l;
-        int r;
+        int f, r;
 
-        r = in_addr_prefix_from_string_internal(p, use_default, family, &q, &l);
+        r = in_addr_prefix_from_string(p, family, &q, &l);
         assert_se(r == ret);
 
-        if (r >= 0) {
-                int f;
+        if (r < 0)
+                return;
+
+        assert_se(in_addr_equal(family, &q, u));
+        assert_se(l == prefixlen);
+
+        r = in_addr_prefix_from_string_auto(p, &f, &q, &l);
+        assert_se(r >= 0);
+
+        assert_se(f == family);
+        assert_se(in_addr_equal(family, &q, u));
+        assert_se(l == prefixlen);
+
+        r = in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_REFUSE, &f, &q, &l);
+        assert_se(r == ret_refuse);
 
+        if (r >= 0) {
+                assert_se(f == family);
                 assert_se(in_addr_equal(family, &q, u));
-                assert_se(l == prefixlen);
+                assert_se(l == prefixlen_refuse);
+        }
 
-                r = in_addr_prefix_from_string_auto_internal(p, use_default, &f, &q, &l);
-                assert_se(r >= 0);
+        r = in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_LEGACY, &f, &q, &l);
+        assert_se(r == ret_legacy);
 
+        if (r >= 0) {
                 assert_se(f == family);
                 assert_se(in_addr_equal(family, &q, u));
-                assert_se(l == prefixlen);
+                assert_se(l == prefixlen_legacy);
         }
 }
 
 int main(int argc, char *argv[]) {
-        test_in_addr_prefix_from_string("", AF_INET, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("/", AF_INET, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("/8", AF_INET, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("1.2.3.4", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, false);
-        test_in_addr_prefix_from_string("1.2.3.4/0", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 0, false);
-        test_in_addr_prefix_from_string("1.2.3.4/1", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 1, false);
-        test_in_addr_prefix_from_string("1.2.3.4/2", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 2, false);
-        test_in_addr_prefix_from_string("1.2.3.4/32", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, false);
-        test_in_addr_prefix_from_string("1.2.3.4/33", AF_INET, -ERANGE, NULL, 0, false);
-        test_in_addr_prefix_from_string("1.2.3.4/-1", AF_INET, -ERANGE, NULL, 0, false);
-        test_in_addr_prefix_from_string("::1", AF_INET, -EINVAL, NULL, 0, false);
-
-        test_in_addr_prefix_from_string("", AF_INET6, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("/", AF_INET6, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("/8", AF_INET6, -EINVAL, NULL, 0, false);
-        test_in_addr_prefix_from_string("::1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, false);
-        test_in_addr_prefix_from_string("::1/0", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, false);
-        test_in_addr_prefix_from_string("::1/1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 1, false);
-        test_in_addr_prefix_from_string("::1/2", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 2, false);
-        test_in_addr_prefix_from_string("::1/32", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 32, false);
-        test_in_addr_prefix_from_string("::1/33", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 33, false);
-        test_in_addr_prefix_from_string("::1/64", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 64, false);
-        test_in_addr_prefix_from_string("::1/128", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, false);
-        test_in_addr_prefix_from_string("::1/129", AF_INET6, -ERANGE, NULL, 0, false);
-        test_in_addr_prefix_from_string("::1/-1", AF_INET6, -ERANGE, NULL, 0, false);
-
-        test_in_addr_prefix_from_string("", AF_INET, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("/", AF_INET, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("/8", AF_INET, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("1.2.3.4", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 8, true);
-        test_in_addr_prefix_from_string("1.2.3.4/0", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 0, true);
-        test_in_addr_prefix_from_string("1.2.3.4/1", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 1, true);
-        test_in_addr_prefix_from_string("1.2.3.4/2", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 2, true);
-        test_in_addr_prefix_from_string("1.2.3.4/32", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, true);
-        test_in_addr_prefix_from_string("1.2.3.4/33", AF_INET, -ERANGE, NULL, 0, true);
-        test_in_addr_prefix_from_string("1.2.3.4/-1", AF_INET, -ERANGE, NULL, 0, true);
-        test_in_addr_prefix_from_string("::1", AF_INET, -EINVAL, NULL, 0, true);
-
-        test_in_addr_prefix_from_string("", AF_INET6, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("/", AF_INET6, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("/8", AF_INET6, -EINVAL, NULL, 0, true);
-        test_in_addr_prefix_from_string("::1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, true);
-        test_in_addr_prefix_from_string("::1/0", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, true);
-        test_in_addr_prefix_from_string("::1/1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 1, true);
-        test_in_addr_prefix_from_string("::1/2", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 2, true);
-        test_in_addr_prefix_from_string("::1/32", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 32, true);
-        test_in_addr_prefix_from_string("::1/33", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 33, true);
-        test_in_addr_prefix_from_string("::1/64", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 64, true);
-        test_in_addr_prefix_from_string("::1/128", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, true);
-        test_in_addr_prefix_from_string("::1/129", AF_INET6, -ERANGE, NULL, 0, true);
-        test_in_addr_prefix_from_string("::1/-1", AF_INET6, -ERANGE, NULL, 0, true);
+        test_in_addr_prefix_from_string("", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("/", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("/8", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("1.2.3.4", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, -ENOANO, 0, 0, 8);
+        test_in_addr_prefix_from_string("1.2.3.4/0", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 0, 0, 0, 0, 0);
+        test_in_addr_prefix_from_string("1.2.3.4/1", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 1, 0, 1, 0, 1);
+        test_in_addr_prefix_from_string("1.2.3.4/2", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 2, 0, 2, 0, 2);
+        test_in_addr_prefix_from_string("1.2.3.4/32", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, 0, 32, 0, 32);
+        test_in_addr_prefix_from_string("1.2.3.4/33", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0);
+        test_in_addr_prefix_from_string("1.2.3.4/-1", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0);
+        test_in_addr_prefix_from_string("::1", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+
+        test_in_addr_prefix_from_string("", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("/", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("/8", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0);
+        test_in_addr_prefix_from_string("::1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, -ENOANO, 0, 0, 0);
+        test_in_addr_prefix_from_string("::1/0", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, 0, 0, 0, 0);
+        test_in_addr_prefix_from_string("::1/1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 1, 0, 1, 0, 1);
+        test_in_addr_prefix_from_string("::1/2", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 2, 0, 2, 0, 2);
+        test_in_addr_prefix_from_string("::1/32", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 32, 0, 32, 0, 32);
+        test_in_addr_prefix_from_string("::1/33", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 33, 0, 33, 0, 33);
+        test_in_addr_prefix_from_string("::1/64", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 64, 0, 64, 0, 64);
+        test_in_addr_prefix_from_string("::1/128", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, 0, 128, 0, 128);
+        test_in_addr_prefix_from_string("::1/129", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0);
+        test_in_addr_prefix_from_string("::1/-1", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0);
 
         return 0;
 }
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 03a9e1d1f0243df99fb9899bb047b16e30b44f92..b66765b407ee5c1ca9545dd118e84a5a3676136e 100644 (file)
@@ -3130,7 +3130,7 @@ static int link_parent(ItemArray *a) {
                 return 0;
 
         path = a->items[0].path;
-        prefix = alloca(strlen(path) + 1);
+        prefix = newa(char, strlen(path) + 1);
         PATH_FOREACH_PREFIX(prefix, path) {
                 ItemArray *j;
 
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 970b130ab00b2e2ec71faf91ef654add5a404ebe..124af438a3dd9747de84db37d8c52abdbe5f01b4 100644 (file)
@@ -2,6 +2,6 @@
 Name=dummy98
 
 [Network]
-Address=192.168.42.100
+Address=192.168.42.100/24
 DNS=192.168.42.1
 Domains= one two three four five six seven eight nine ten
index 01c5f2a28d37a324fc231d179881b9a5c497190c..4866c31ccac68b39837e86561e613631e634d4bd 100644 (file)
@@ -10,6 +10,7 @@ FwMark=1234
 [WireGuardPeer]
 PublicKey=RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=
 AllowedIPs=fd31:bf08:57cb::/48,192.168.26.0/24
-Endpoint=wireguard.example.com:51820
+#Endpoint=wireguard.example.com:51820
+Endpoint=192.168.27.3:51820
 PresharedKey=IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=
 PersistentKeepalive=20
index 7b38e72b7e970672469d8587a2b50806fc8c69e7..33d8be3964becb2b3c1e0ef375979ecb346e1281 100644 (file)
@@ -2,5 +2,5 @@
 Name=veth-peer
 
 [Network]
-Address=2600::1
+Address=2600::1/0
 Address=192.168.5.1/24
index 5c91d654329a7870c70f57dc8f94c467d0b037f2..3dfc5290ad35fc2ad221c208ba54839c7f621bbb 100644 (file)
@@ -2,5 +2,5 @@
 Name=veth-peer
 
 [Network]
-Address=192.168.0.1
-Address=192.168.5.1
+Address=192.168.0.1/24
+Address=192.168.5.1/24
index 33ec40b012997bdafe8f4125fa2cdf6fee486653..08ceb2d599f97f3c97b577e844d6ab0053cc80f5 100755 (executable)
@@ -390,6 +390,16 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
         if shutil.which('wg'):
             subprocess.call('wg')
+            output = subprocess.check_output(['wg', 'show', 'wg99', 'listen-port']).rstrip().decode('utf-8')
+            self.assertTrue(output, '51820')
+            output = subprocess.check_output(['wg', 'show', 'wg99', 'fwmark']).rstrip().decode('utf-8')
+            self.assertTrue(output, '0x4d2')
+            output = subprocess.check_output(['wg', 'show', 'wg99', 'allowed-ips']).rstrip().decode('utf-8')
+            self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
+            output = subprocess.check_output(['wg', 'show', 'wg99', 'persistent-keepalive']).rstrip().decode('utf-8')
+            self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20')
+            output = subprocess.check_output(['wg', 'show', 'wg99', 'endpoints']).rstrip().decode('utf-8')
+            self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820')
 
         self.assertTrue(self.link_exits('wg99'))
 
@@ -1039,8 +1049,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 +1231,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 ad8224512152921f25520967e8bba3f232ad5c48..ea4f02618f1c175460cf3d78a4fd5a6994790505 100644 (file)
@@ -15,4 +15,4 @@ Requires=initrd-switch-root.service
 Before=initrd-switch-root.service
 AllowIsolate=yes
 Wants=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target systemd-journald.service initrd-cleanup.service
-After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target
+After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target initrd-cleanup.service
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