]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #11927 from poettering/network-namespace-path
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 12 Mar 2019 13:29:14 +0000 (14:29 +0100)
committerGitHub <noreply@github.com>
Tue, 12 Mar 2019 13:29:14 +0000 (14:29 +0100)
Add NetworkNamespacePath= to unit files

64 files changed:
.lgtm/cpp-queries/PotentiallyDangerousFunction.ql [new file with mode: 0644]
.lgtm/cpp-queries/fgets.ql [deleted file]
hwdb/60-input-id.hwdb
hwdb/60-keyboard.hwdb
man/systemd.exec.xml
man/systemd.network.xml
po/fr.po
shell-completion/bash/systemctl.in
src/core/dbus-unit.c
src/core/device.c
src/core/execute.c
src/fuzz/fuzz-bus-label.c [new file with mode: 0644]
src/fuzz/fuzz-env-file.c [new file with mode: 0644]
src/fuzz/fuzz-hostname-util.c [new file with mode: 0644]
src/fuzz/fuzz-nspawn-settings.c [new file with mode: 0644]
src/fuzz/meson.build
src/import/import-common.c
src/journal-remote/journal-remote-main.c
src/journal/catalog.c
src/libsystemd/sd-device/device-internal.h
src/libsystemd/sd-device/device-private.c
src/libsystemd/sd-device/device-private.h
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-netlink/netlink-types.c
src/libudev/libudev-device.c
src/login/logind-core.c
src/login/logind.c
src/machine/machinectl.c
src/network/networkd-address.c
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-route.c
src/nspawn/nspawn-mount.c
src/random-seed/random-seed.c
src/shared/efivars.c
src/shared/efivars.h
src/shared/udev-util.c
src/shared/udev-util.h
src/timedate/timedated.c
src/udev/udev-event.c
src/udev/udev-rules.c
src/udev/udevadm-monitor.c
src/udev/udevadm-test.c
src/udev/udevadm-trigger.c
src/udev/udevd.c
test/TEST-24-UNIT-TESTS/test.sh
test/TEST-24-UNIT-TESTS/testsuite.sh
test/TEST-29-UDEV-ID_RENAMING/testsuite.sh
test/fuzz/fuzz-env-file/simple-env-file [new file with mode: 0644]
test/fuzz/fuzz-network-parser/directives.network
test/fuzz/fuzz-nspawn-settings/basic-config [new file with mode: 0644]
test/fuzz/fuzz-nspawn-settings/leak-4ff0e2498f596a77ea68d185c61e9e9ff9bb657f [new file with mode: 0644]
test/test-functions
test/test-network/conf/21-vlan-test1.network [new file with mode: 0644]
test/test-network/conf/21-vlan-test1.network.d/override.conf [new file with mode: 0644]
test/test-network/conf/21-vlan.network
test/test-network/conf/21-vlan.network.d/override.conf [deleted file]
test/test-network/systemd-networkd-tests.py
units/systemd-journald.service.in
units/systemd-networkd.service.in
units/systemd-resolved.service.in

diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
new file mode 100644 (file)
index 0000000..ba80f4a
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * @name Use of potentially dangerous function
+ * @description Certain standard library functions are dangerous to call.
+ * @kind problem
+ * @problem.severity error
+ * @precision high
+ * @id cpp/potentially-dangerous-function
+ * @tags reliability
+ *       security
+ *
+ * Borrowed from
+ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql
+ */
+import cpp
+
+predicate potentiallyDangerousFunction(Function f, string message) {
+  (
+    f.getQualifiedName() = "fgets" and
+    message = "Call to fgets is potentially dangerous. Use read_line() instead."
+  ) or (
+    f.getQualifiedName() = "strtok" and
+    message = "Call to strtok is potentially dangerous. Use extract_first_word() instead."
+  )
+}
+
+from FunctionCall call, Function target, string message
+where
+  call.getTarget() = target and
+  potentiallyDangerousFunction(target, message)
+select call, message
diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql
deleted file mode 100644 (file)
index a4181e4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @name Use of fgets()
- * @description fgets() is dangerous to call. Use read_line() instead.
- * @kind problem
- * @problem.severity error
- * @precision high
- * @id cpp/fgets
- * @tags reliability
- *       security
- */
-import cpp
-
-predicate dangerousFunction(Function function) {
-  exists (string name | name = function.getQualifiedName() |
-    name = "fgets")
-}
-
-from FunctionCall call, Function target
-where call.getTarget() = target
-  and dangerousFunction(target)
-select call, target.getQualifiedName() + " is potentially dangerous"
index 7e9dc99220b2426d25c000b4a8fa1a7eaa1446fd..20c1e7ea0da26a6d80f5a4404a3e07e25d27c9f9 100644 (file)
@@ -66,3 +66,7 @@ id-input:modalias:input:b0003v5543p0081*
 # XP-PEN STAR 06
 id-input:modalias:input:b0003v28bdp0078*
  ID_INPUT_TABLET=1
+
+# Lite-On Tech IBM USB Travel Keyboard with Ultra Nav Mouse
+id-input:modalias:input:b0003v04B3p301Ee0100-e0,1,2,4*
+ ID_INPUT_POINTINGSTICK=1
index f3a7c995c215af489779c2ffdd52ca3266296701..f9ae0fe78c4ad3ae6d46e14323e27b734696c7f0 100644 (file)
@@ -803,6 +803,10 @@ evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr*
  KEYBOARD_KEY_ae=!volumedown
  KEYBOARD_KEY_b0=!volumeup
 
+# Lenovo Y50-70
+evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*20378*:pvr*
+ KEYBOARD_KEY_f3=f21      # Fn+F6 (toggle touchpad)
+
 # V480
 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr*
  KEYBOARD_KEY_f1=f21
index 2ed8c38f37cf3eea071749e57174ea3cac1b590f..94c8e7a2dd3e1dbb4bd5b04b22a2b8b654bf1fdb 100644 (file)
@@ -1157,9 +1157,13 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
         <listitem><para>Takes a boolean argument. When set, sets up a new UTS namespace for the executed
         processes. In addition, changing hostname or domainname is prevented. Defaults to off.</para>
 
-        <para>Note that the implementation of this setting might be impossible (for example if UTS namespaces are not
-        available), and the unit should be written in a way that does not solely rely on this setting for
-        security.</para></listitem>
+        <para>Note that the implementation of this setting might be impossible (for example if UTS namespaces
+        are not available), and the unit should be written in a way that does not solely rely on this setting
+        for security.</para>
+
+        <para>Note that when this option is enabled for a service hostname changes no longer propagate from
+        the system into the service, it is hence not suitable for services that need to take notice of system
+        hostname changes dynamically.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index d44312a9419e720d0ef46d63b7b03c442b0c5f94..1a3d24aa7633144e1a28984b6bbdd97ec0af8e2a 100644 (file)
         <varlistentry>
           <term><varname>DHCPServer=</varname></term>
           <listitem>
-            <para>Takes a boolean. If set to <literal>yes</literal>, DHCPv4 server will be start. Defaults
+            <para>Takes a boolean. If set to <literal>yes</literal>, DHCPv4 server will be started. Defaults
             to <literal>no</literal>. Further settings for the DHCP
             server may be set in the <literal>[DHCPServer]</literal>
             section described below.</para>
             automatic restart off. By default automatic restart is disabled.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>TripleSampling=</varname></term>
+          <listitem>
+            <para>Takes a boolean. When <literal>yes</literal>, three samples (instead of one) are used to determine
+            the value of a received bit by majority rule. When unset, the kernel's default will be used.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
   </refsect1>
 
index ca359016024356c71bb184b25d2ace3e9712519c..3f0997885069ff5b6e57f7808d62e6e3eca65d16 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: systemd\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-11-02 14:28+0100\n"
-"PO-Revision-Date: 2018-11-02 14:32+0100\n"
+"POT-Creation-Date: 2019-03-07 22:43+0100\n"
+"PO-Revision-Date: 2019-03-07 23:09+0100\n"
 "Last-Translator: Sylvain Plantefève <sylvain.plantefeve@gmail.com>\n"
 "Language-Team: French\n"
 "Language: fr\n"
@@ -489,10 +489,9 @@ msgstr ""
 "actives."
 
 #: src/login/org.freedesktop.login1.policy:341
-msgid "Allow indication to the firmware to boot to setup interface"
+msgid "Indicate to the firmware to boot to setup interface"
 msgstr ""
-"Permet d'indiquer au micrologiciel de démarrer sur l'interface de "
-"configuration"
+"Indiquer au micrologiciel de démarrer sur l'interface de configuration"
 
 #: src/login/org.freedesktop.login1.policy:342
 msgid ""
@@ -502,11 +501,35 @@ msgstr ""
 "Authentification requise pour indiquer au micrologiciel de démarrer sur "
 "l'interface de configuration."
 
-#: src/login/org.freedesktop.login1.policy:351
+#: src/login/org.freedesktop.login1.policy:352
+msgid "Indicate to the boot loader to boot to the boot loader menu"
+msgstr "Indiquer au programme d'amorçage d'afficher le menu au démarrage"
+
+#: src/login/org.freedesktop.login1.policy:353
+msgid ""
+"Authentication is required to indicate to the boot loader to boot to the "
+"boot loader menu."
+msgstr ""
+"Authentification requise pour indiquer au programme d'amorçage d'afficher "
+"le menu au démarrage."
+
+#: src/login/org.freedesktop.login1.policy:363
+msgid "Indicate to the boot loader to boot a specific entry"
+msgstr "Indiquer au programme d'amorçage de démarrer une entrée spécifique"
+
+#: src/login/org.freedesktop.login1.policy:364
+msgid ""
+"Authentication is required to indicate to the boot loader to boot into a "
+"specific boot loader entry."
+msgstr ""
+"Authentification requise pour indiquer au programme d'amorçage de démarrer "
+"une entrée spécifique."
+
+#: src/login/org.freedesktop.login1.policy:374
 msgid "Set a wall message"
 msgstr "Définir un message wall"
 
-#: src/login/org.freedesktop.login1.policy:352
+#: src/login/org.freedesktop.login1.policy:375
 msgid "Authentication is required to set a wall message"
 msgstr "Authentification requise pour définir un message wall."
 
index 0e58e2ba4cbe0b3b055d04d254394c904615bd55..d73f956a3f4c22d0c3d023a3b0f5ab6e487da806 100644 (file)
@@ -84,10 +84,13 @@ __get_restartable_units () {
 
 __get_stoppable_units () {
         # filter out masked and not-found
-        __filter_units_by_properties $1 ActiveState=active,CanStop=yes $(
+        local units=$(
                 { __get_not_masked_unit_files $1 $2
                   __get_active_units $1 $2
                 } | sort -u )
+        __filter_units_by_properties $1 ActiveState=active,CanStop=yes $units
+        __filter_units_by_properties $1 ActiveState=reloading,CanStop=yes $units
+        __filter_units_by_properties $1 ActiveState=activating,CanStop=yes $units
 }
 
 __get_reloadable_units () {
index 17c2003c8fbb50c1763c2becd286916453c317f3..28ae6070a60d0a0cbd8ec184d99322e6ebbbe2f6 100644 (file)
@@ -1674,9 +1674,17 @@ static int bus_unit_set_transient_property(
                         return r;
 
                 STRV_FOREACH(p, l) {
+                        path_simplify(*p, true);
+
                         if (!path_is_absolute(*p))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p);
 
+                        if (!path_is_valid(*p))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s has invalid length: %s", name, *p);
+
+                        if (!path_is_normalized(*p))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not normalized: %s", name, *p);
+
                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                 r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
                                 if (r < 0)
index a979caf21ce5b289393dc098bf61175f990c26ce..506bf744788a2538902ded2e0f582097a989f353 100644 (file)
@@ -893,7 +893,8 @@ static void device_propagate_reload_by_sysfs(Manager *m, const char *sysfs) {
 
 static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
         Manager *m = userdata;
-        const char *action, *sysfs;
+        DeviceAction action;
+        const char *sysfs;
         int r;
 
         assert(m);
@@ -905,19 +906,19 @@ static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *
                 return 0;
         }
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
+        r = device_get_action(dev, &action);
         if (r < 0) {
-                log_device_error_errno(dev, r, "Failed to get udev action string: %m");
+                log_device_error_errno(dev, r, "Failed to get udev action: %m");
                 return 0;
         }
 
-        if (streq(action, "change"))
+        if (action == DEVICE_ACTION_CHANGE)
                 device_propagate_reload_by_sysfs(m, sysfs);
 
         /* A change event can signal that a device is becoming ready, in particular if
          * the device is using the SYSTEMD_READY logic in udev
          * so we need to reach the else block of the follwing if, even for change events */
-        if (streq(action, "remove"))  {
+        if (action == DEVICE_ACTION_REMOVE) {
                 r = swap_process_device_remove(m, dev);
                 if (r < 0)
                         log_device_warning_errno(dev, r, "Failed to process swap device remove event, ignoring: %m");
index 240ec5487b20f8f7958bfe5947a7d606ad5429c9..c6fd82bbf3e5a41b3ec3069b2d15360758f403e7 100644 (file)
@@ -4586,11 +4586,6 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                 else
                         fprintf(f, "%d\n", c->syscall_errno);
         }
-
-        if (c->apparmor_profile)
-                fprintf(f,
-                        "%sAppArmorProfile: %s%s\n",
-                        prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
 }
 
 bool exec_context_maintains_privileges(const ExecContext *c) {
diff --git a/src/fuzz/fuzz-bus-label.c b/src/fuzz/fuzz-bus-label.c
new file mode 100644 (file)
index 0000000..46a3d23
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+
+#include "alloc-util.h"
+#include "bus-label.h"
+#include "fuzz.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_free_ char *unescaped = NULL, *escaped = NULL;
+
+        unescaped = bus_label_unescape_n((const char*)data, size);
+        assert_se(unescaped != NULL);
+        escaped = bus_label_escape(unescaped);
+        assert_se(escaped != NULL);
+
+        return 0;
+}
diff --git a/src/fuzz/fuzz-env-file.c b/src/fuzz/fuzz-env-file.c
new file mode 100644 (file)
index 0000000..51df1aa
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+
+#include "alloc-util.h"
+#include "env-file.h"
+#include "fd-util.h"
+#include "fuzz.h"
+#include "strv.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_strv_free_ char **rl = NULL, **rlp =  NULL;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen((char*) data, size, "re");
+        assert_se(f);
+
+        /* We don't want to fill the logs with messages about parse errors.
+         * Disable most logging if not running standalone */
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        (void) load_env_file(f, NULL, &rl);
+        assert_se(fseek(f, 0, SEEK_SET) == 0);
+        (void) load_env_file_pairs(f, NULL, &rlp);
+
+        return 0;
+}
diff --git a/src/fuzz/fuzz-hostname-util.c b/src/fuzz/fuzz-hostname-util.c
new file mode 100644 (file)
index 0000000..deaf811
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fuzz.h"
+#include "hostname-util.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *ret = NULL;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen((char*) data, size, "re");
+        assert_se(f);
+
+        /* We don't want to fill the logs with messages about parse errors.
+         * Disable most logging if not running standalone */
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        (void) read_etc_hostname_stream(f, &ret);
+
+        return 0;
+}
diff --git a/src/fuzz/fuzz-nspawn-settings.c b/src/fuzz/fuzz-nspawn-settings.c
new file mode 100644 (file)
index 0000000..6c81eb7
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fuzz.h"
+#include "nspawn-settings.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(settings_freep) Settings *s = NULL;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen((char*) data, size, "re");
+        assert_se(f);
+
+        /* We don't want to fill the logs with messages about parse errors.
+         * Disable most logging if not running standalone */
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        (void) settings_load(f, "/dev/null", &s);
+
+        return 0;
+}
index 5138a2c4165303adfd0b84c5c58b0499bd7dd561..4a242f8a6ce17917c2e656612ce6ca8a7ea50e75 100644 (file)
@@ -112,4 +112,21 @@ fuzzers += [
         [['src/fuzz/fuzz-compress.c'],
          [libshared],
          []],
+
+        [['src/fuzz/fuzz-bus-label.c'],
+         [libshared],
+         []],
+
+        [['src/fuzz/fuzz-env-file.c'],
+         [libshared],
+         []],
+
+        [['src/fuzz/fuzz-hostname-util.c'],
+         [libshared],
+         []],
+
+        [['src/fuzz/fuzz-nspawn-settings.c'],
+         [libshared,
+          libnspawn_core],
+         []],
 ]
index 89f03010d1349a972e9097f1b12b32d659d0936c..1f63ebb7619448307b24bf31f50bbe7ee5ea514f 100644 (file)
@@ -15,6 +15,7 @@
 #include "import-common.h"
 #include "os-util.h"
 #include "process-util.h"
+#include "selinux-util.h"
 #include "signal-util.h"
 #include "tmpfile-util.h"
 #include "util.h"
@@ -62,6 +63,7 @@ int import_make_read_only(const char *path) {
 
 int import_fork_tar_x(const char *path, pid_t *ret) {
         _cleanup_close_pair_ int pipefd[2] = { -1, -1 };
+        bool use_selinux;
         pid_t pid;
         int r;
 
@@ -71,6 +73,8 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
         if (pipe2(pipefd, O_CLOEXEC) < 0)
                 return log_error_errno(errno, "Failed to create pipe for tar: %m");
 
+        use_selinux = mac_selinux_use();
+
         r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
         if (r < 0)
                 return r;
@@ -100,7 +104,8 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
                 if (r < 0)
                         log_error_errno(r, "Failed to drop capabilities, ignoring: %m");
 
-                execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", "--xattrs", "--xattrs-include=*", NULL);
+                execlp("tar", "tar", "--numeric-owner", "-C", path, "-px", "--xattrs", "--xattrs-include=*",
+                       use_selinux ? "--selinux" : "--no-selinux", NULL);
                 log_error_errno(errno, "Failed to execute tar: %m");
                 _exit(EXIT_FAILURE);
         }
@@ -112,6 +117,7 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
 
 int import_fork_tar_c(const char *path, pid_t *ret) {
         _cleanup_close_pair_ int pipefd[2] = { -1, -1 };
+        bool use_selinux;
         pid_t pid;
         int r;
 
@@ -121,6 +127,8 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
         if (pipe2(pipefd, O_CLOEXEC) < 0)
                 return log_error_errno(errno, "Failed to create pipe for tar: %m");
 
+        use_selinux = mac_selinux_use();
+
         r = safe_fork("(tar)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
         if (r < 0)
                 return r;
@@ -144,7 +152,8 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
                 if (r < 0)
                         log_error_errno(r, "Failed to drop capabilities, ignoring: %m");
 
-                execlp("tar", "tar", "-C", path, "-c", "--xattrs", "--xattrs-include=*", ".", NULL);
+                execlp("tar", "tar", "-C", path, "-c", "--xattrs", "--xattrs-include=*",
+                       use_selinux ? "--selinux" : "--no-selinux", ".", NULL);
                 log_error_errno(errno, "Failed to execute tar: %m");
                 _exit(EXIT_FAILURE);
         }
index 802c3ea6089a88018f2066e919d14e3d35f588bb..2321a91e7bd57d0e1a6b0642ca5ab9b2ec9f284e 100644 (file)
@@ -265,6 +265,7 @@ static int request_handler(
         const char *header;
         int r, code, fd;
         _cleanup_free_ char *hostname = NULL;
+        bool chunked = false;
         size_t len;
 
         assert(connection);
@@ -290,21 +291,33 @@ static int request_handler(
                 return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
                                    "Content-Type: application/vnd.fdo.journal is required.");
 
+        header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Transfer-Encoding");
+        if (header) {
+                if (!strcaseeq(header, "chunked"))
+                        return mhd_respondf(connection, 0, MHD_HTTP_BAD_REQUEST,
+                                            "Unsupported Transfer-Encoding type: %s", header);
+
+                chunked = true;
+        }
+
         header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length");
-        if (!header)
-                return mhd_respond(connection, MHD_HTTP_LENGTH_REQUIRED,
-                                   "Content-Length header is required.");
-        r = safe_atozu(header, &len);
-        if (r < 0)
-                return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED,
-                                    "Content-Length: %s cannot be parsed: %m", header);
-
-        if (len > ENTRY_SIZE_MAX)
-                /* When serialized, an entry of maximum size might be slightly larger,
-                 * so this does not correspond exactly to the limit in journald. Oh well.
-                 */
-                return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE,
-                                    "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX);
+        if (header) {
+                if (chunked)
+                        return mhd_respond(connection, MHD_HTTP_BAD_REQUEST,
+                                           "Content-Length must not specified when Transfer-Encoding type is 'chuncked'");
+
+                r = safe_atozu(header, &len);
+                if (r < 0)
+                        return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED,
+                                            "Content-Length: %s cannot be parsed: %m", header);
+
+                if (len > ENTRY_SIZE_MAX)
+                        /* When serialized, an entry of maximum size might be slightly larger,
+                         * so this does not correspond exactly to the limit in journald. Oh well.
+                         */
+                        return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE,
+                                            "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX);
+        }
 
         {
                 const union MHD_ConnectionInfo *ci;
index 4062f12c2dfc574eae5d602602d180f29d8e5252..ccee950d1d65df77cb29b91b7289e67e0b81051f 100644 (file)
@@ -33,7 +33,7 @@ const char * const catalog_file_dirs[] = {
         NULL
 };
 
-#define CATALOG_SIGNATURE (uint8_t[]) { 'R', 'H', 'H', 'H', 'K', 'S', 'L', 'P' }
+#define CATALOG_SIGNATURE { 'R', 'H', 'H', 'H', 'K', 'S', 'L', 'P' }
 
 typedef struct CatalogHeader {
         uint8_t signature[8];  /* "RHHHKSLP" */
@@ -209,34 +209,38 @@ int catalog_file_lang(const char* filename, char **lang) {
         return 1;
 }
 
-static int catalog_entry_lang(const char* filename, int line,
-                              const char* t, const char* deflang, char **lang) {
+static int catalog_entry_lang(
+                const char* filename,
+                unsigned line,
+                const char* t,
+                const char* deflang,
+                char **ret) {
+
         size_t c;
+        char *z;
 
         c = strlen(t);
         if (c < 2)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "[%s:%u] Language too short.",
-                                       filename, line);
+                                       "[%s:%u] Language too short.", filename, line);
         if (c > 31)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "[%s:%u] language too long.", filename,
-                                       line);
+                                       "[%s:%u] language too long.", filename, line);
 
         if (deflang) {
                 if (streq(t, deflang)) {
-                        log_warning("[%s:%u] language specified unnecessarily",
-                                    filename, line);
+                        log_warning("[%s:%u] language specified unnecessarily", filename, line);
                         return 0;
-                } else
-                        log_warning("[%s:%u] language differs from default for file",
-                                    filename, line);
+                }
+
+                log_warning("[%s:%u] language differs from default for file", filename, line);
         }
 
-        *lang = strdup(t);
-        if (!*lang)
-                        return -ENOMEM;
+        z = strdup(t);
+        if (!z)
+                return -ENOMEM;
 
+        *ret = z;
         return 0;
 }
 
@@ -367,32 +371,33 @@ int catalog_import_file(Hashmap *h, const char *path) {
         return 0;
 }
 
-static int64_t write_catalog(const char *database, struct strbuf *sb,
-                             CatalogItem *items, size_t n) {
-        CatalogHeader header;
+static int64_t write_catalog(
+                const char *database,
+                struct strbuf *sb,
+                CatalogItem *items,
+                size_t n) {
+
         _cleanup_fclose_ FILE *w = NULL;
-        int r;
-        _cleanup_free_ char *d, *p = NULL;
+        _cleanup_free_ char *p = NULL;
+        CatalogHeader header;
         size_t k;
+        int r;
 
-        d = dirname_malloc(database);
-        if (!d)
-                return log_oom();
-
-        r = mkdir_p(d, 0775);
+        r = mkdir_parents(database, 0755);
         if (r < 0)
-                return log_error_errno(r, "Recursive mkdir %s: %m", d);
+                return log_error_errno(r, "Failed to create parent directories of %s: %m", database);
 
         r = fopen_temporary(database, &w, &p);
         if (r < 0)
                 return log_error_errno(r, "Failed to open database for writing: %s: %m",
                                        database);
 
-        zero(header);
-        memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature));
-        header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8));
-        header.catalog_item_size = htole64(sizeof(CatalogItem));
-        header.n_items = htole64(n);
+        header = (CatalogHeader) {
+                .signature = CATALOG_SIGNATURE,
+                .header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)),
+                .catalog_item_size = htole64(sizeof(CatalogItem)),
+                .n_items = htole64(n),
+        };
 
         r = -EIO;
 
@@ -420,7 +425,7 @@ static int64_t write_catalog(const char *database, struct strbuf *sb,
                 goto error;
         }
 
-        fchmod(fileno(w), 0644);
+        (void) fchmod(fileno(w), 0644);
 
         if (rename(p, database) < 0) {
                 r = log_error_errno(errno, "rename (%s -> %s) failed: %m", p, database);
@@ -503,10 +508,10 @@ int catalog_update(const char* database, const char* root, const char* const* di
 }
 
 static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p) {
+        _cleanup_close_ int fd = -1;
         const CatalogHeader *h;
-        int fd;
-        void *p;
         struct stat st;
+        void *p;
 
         assert(_fd);
         assert(_st);
@@ -516,35 +521,28 @@ static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p
         if (fd < 0)
                 return -errno;
 
-        if (fstat(fd, &st) < 0) {
-                safe_close(fd);
+        if (fstat(fd, &st) < 0)
                 return -errno;
-        }
 
-        if (st.st_size < (off_t) sizeof(CatalogHeader)) {
-                safe_close(fd);
+        if (st.st_size < (off_t) sizeof(CatalogHeader))
                 return -EINVAL;
-        }
 
         p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0);
-        if (p == MAP_FAILED) {
-                safe_close(fd);
+        if (p == MAP_FAILED)
                 return -errno;
-        }
 
         h = p;
-        if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 ||
+        if (memcmp(h->signature, (const uint8_t[]) CATALOG_SIGNATURE, sizeof(h->signature)) != 0 ||
             le64toh(h->header_size) < sizeof(CatalogHeader) ||
             le64toh(h->catalog_item_size) < sizeof(CatalogItem) ||
             h->incompatible_flags != 0 ||
             le64toh(h->n_items) <= 0 ||
             st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) {
-                safe_close(fd);
                 munmap(p, st.st_size);
                 return -EBADMSG;
         }
 
-        *_fd = fd;
+        *_fd = TAKE_FD(fd);
         *_st = st;
         *_p = p;
 
index 4d03d09cd68887a11bec0aac4ab0c6606b88819d..023fe0fcd702a36375f3c3631aab63fbceff2ba9 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "sd-device.h"
 
+#include "device-private.h"
 #include "hashmap.h"
 #include "set.h"
 #include "time-util.h"
@@ -64,6 +65,10 @@ struct sd_device {
         uid_t devuid;
         gid_t devgid;
 
+        /* only set when device is passed through netlink */
+        DeviceAction action;
+        uint64_t seqnum;
+
         bool parent_set:1; /* no need to try to reload parent */
         bool sysattrs_read:1; /* don't try to re-read sysattrs once read */
         bool property_tags_outdated:1; /* need to update TAGS= property */
index 0d0bdca800feb9d838b4bf420cfd4eed4d4c4314..6f17eeeee9c5237df05e44dfbbc77cdf62a88652 100644 (file)
@@ -183,6 +183,72 @@ static int device_set_devgid(sd_device *device, const char *gid) {
         return 0;
 }
 
+int device_get_action(sd_device *device, DeviceAction *action) {
+        assert(device);
+
+        if (device->action < 0)
+                return -ENOENT;
+
+        if (action)
+                *action = device->action;
+
+        return 0;
+}
+
+static int device_set_action(sd_device *device, const char *action) {
+        DeviceAction a;
+        int r;
+
+        assert(device);
+        assert(action);
+
+        a = device_action_from_string(action);
+        if (a < 0)
+                return -EINVAL;
+
+        r = device_add_property_internal(device, "ACTION", action);
+        if (r < 0)
+                return r;
+
+        device->action = a;
+
+        return 0;
+}
+
+int device_get_seqnum(sd_device *device, uint64_t *seqnum) {
+        assert(device);
+
+        if (device->seqnum == 0)
+                return -ENOENT;
+
+        if (seqnum)
+                *seqnum = device->seqnum;
+
+        return 0;
+}
+
+static int device_set_seqnum(sd_device *device, const char *str) {
+        uint64_t seqnum;
+        int r;
+
+        assert(device);
+        assert(str);
+
+        r = safe_atou64(str, &seqnum);
+        if (r < 0)
+                return r;
+        if (seqnum == 0)
+                return -EINVAL;
+
+        r = device_add_property_internal(device, "SEQNUM", str);
+        if (r < 0)
+                return r;
+
+        device->seqnum = seqnum;
+
+        return 0;
+}
+
 static int device_amend(sd_device *device, const char *key, const char *value) {
         int r;
 
@@ -241,6 +307,14 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
                 r = device_set_devgid(device, value);
                 if (r < 0)
                         return log_device_debug_errno(device, r, "sd-device: Failed to set devgid to '%s': %m", value);
+        } else if (streq(key, "ACTION")) {
+                r = device_set_action(device, value);
+                if (r < 0)
+                        return log_device_debug_errno(device, r, "sd-device: Failed to set action to '%s': %m", value);
+        } else if (streq(key, "SEQNUM")) {
+                r = device_set_seqnum(device, value);
+                if (r < 0)
+                        return log_device_debug_errno(device, r, "sd-device: Failed to set SEQNUM to '%s': %m", value);
         } else if (streq(key, "DEVLINKS")) {
                 const char *word, *state;
                 size_t l;
@@ -278,23 +352,7 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
         return 0;
 }
 
-static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
-        [DEVICE_ACTION_ADD] = "add",
-        [DEVICE_ACTION_REMOVE] = "remove",
-        [DEVICE_ACTION_CHANGE] = "change",
-        [DEVICE_ACTION_MOVE] = "move",
-        [DEVICE_ACTION_ONLINE] = "online",
-        [DEVICE_ACTION_OFFLINE] = "offline",
-        [DEVICE_ACTION_BIND] = "bind",
-        [DEVICE_ACTION_UNBIND] = "unbind",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
-
-static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
-                         DeviceAction *_action) {
-        DeviceAction action = _DEVICE_ACTION_INVALID;
-        uint64_t seqnum = 0;
+static int device_append(sd_device *device, char *key, const char **_major, const char **_minor) {
         const char *major = NULL, *minor = NULL;
         char *value;
         int r;
@@ -303,8 +361,6 @@ static int device_append(sd_device *device, char *key, const char **_major, cons
         assert(key);
         assert(_major);
         assert(_minor);
-        assert(_seqnum);
-        assert(_action);
 
         value = strchr(key, '=');
         if (!value) {
@@ -321,19 +377,6 @@ static int device_append(sd_device *device, char *key, const char **_major, cons
         else if (streq(key, "MINOR"))
                 minor = value;
         else {
-                if (streq(key, "ACTION")) {
-                        action = device_action_from_string(value);
-                        if (action == _DEVICE_ACTION_INVALID)
-                                return -EINVAL;
-                } else if (streq(key, "SEQNUM")) {
-                        r = safe_atou64(value, &seqnum);
-                        if (r < 0)
-                                return r;
-                        else if (seqnum == 0)
-                                 /* kernel only sends seqnum > 0 */
-                                return -EINVAL;
-                }
-
                 r = device_amend(device, key, value);
                 if (r < 0)
                         return r;
@@ -345,12 +388,6 @@ static int device_append(sd_device *device, char *key, const char **_major, cons
         if (minor != 0)
                 *_minor = minor;
 
-        if (action != _DEVICE_ACTION_INVALID)
-                *_action = action;
-
-        if (seqnum > 0)
-                *_seqnum = seqnum;
-
         return 0;
 }
 
@@ -360,10 +397,10 @@ void device_seal(sd_device *device) {
         device->sealed = true;
 }
 
-static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
+static int device_verify(sd_device *device) {
         assert(device);
 
-        if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
+        if (!device->devpath || !device->subsystem || device->action < 0 || device->seqnum == 0) {
                 log_device_debug(device, "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum.");
                 return -EINVAL;
         }
@@ -377,8 +414,6 @@ int device_new_from_strv(sd_device **ret, char **strv) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         char **key;
         const char *major = NULL, *minor = NULL;
-        DeviceAction action = _DEVICE_ACTION_INVALID;
-        uint64_t seqnum = 0;
         int r;
 
         assert(ret);
@@ -389,7 +424,7 @@ int device_new_from_strv(sd_device **ret, char **strv) {
                 return r;
 
         STRV_FOREACH(key, strv) {
-                r = device_append(device, *key, &major, &minor, &seqnum, &action);
+                r = device_append(device, *key, &major, &minor);
                 if (r < 0)
                         return r;
         }
@@ -400,7 +435,7 @@ int device_new_from_strv(sd_device **ret, char **strv) {
                         return log_device_debug_errno(device, r, "sd-device: Failed to set devnum %s:%s: %m", major, minor);
         }
 
-        r = device_verify(device, action, seqnum);
+        r = device_verify(device);
         if (r < 0)
                 return r;
 
@@ -412,8 +447,6 @@ int device_new_from_strv(sd_device **ret, char **strv) {
 int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         const char *major = NULL, *minor = NULL;
-        DeviceAction action = _DEVICE_ACTION_INVALID;
-        uint64_t seqnum = 0;
         unsigned i = 0;
         int r;
 
@@ -437,7 +470,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
                 }
                 i += end - key + 1;
 
-                r = device_append(device, key, &major, &minor, &seqnum, &action);
+                r = device_append(device, key, &major, &minor);
                 if (r < 0)
                         return r;
         }
@@ -448,7 +481,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
                         return log_device_debug_errno(device, r, "sd-device: Failed to set devnum %s:%s: %m", major, minor);
         }
 
-        r = device_verify(device, action, seqnum);
+        r = device_verify(device);
         if (r < 0)
                 return r;
 
@@ -674,7 +707,7 @@ int device_new_from_synthetic_event(sd_device **new_device, const char *syspath,
         if (r < 0)
                 return r;
 
-        r = device_add_property_internal(ret, "ACTION", action);
+        r = device_set_action(ret, action);
         if (r < 0)
                 return r;
 
@@ -953,3 +986,16 @@ int device_delete_db(sd_device *device) {
 
         return 0;
 }
+
+static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
+        [DEVICE_ACTION_ADD]     = "add",
+        [DEVICE_ACTION_REMOVE]  = "remove",
+        [DEVICE_ACTION_CHANGE]  = "change",
+        [DEVICE_ACTION_MOVE]    = "move",
+        [DEVICE_ACTION_ONLINE]  = "online",
+        [DEVICE_ACTION_OFFLINE] = "offline",
+        [DEVICE_ACTION_BIND]    = "bind",
+        [DEVICE_ACTION_UNBIND]  = "unbind",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
index 46e10105c9808a66f80c15d2a78e46a3f3cae979..9696f9c02dcc4e343308409a4d8e2cd46930834c 100644 (file)
 
 #include "macro.h"
 
+typedef enum DeviceAction {
+        DEVICE_ACTION_ADD,
+        DEVICE_ACTION_REMOVE,
+        DEVICE_ACTION_CHANGE,
+        DEVICE_ACTION_MOVE,
+        DEVICE_ACTION_ONLINE,
+        DEVICE_ACTION_OFFLINE,
+        DEVICE_ACTION_BIND,
+        DEVICE_ACTION_UNBIND,
+        _DEVICE_ACTION_MAX,
+        _DEVICE_ACTION_INVALID = -1,
+} DeviceAction;
+
 int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len);
 int device_new_from_strv(sd_device **ret, char **strv);
 int device_new_from_stat_rdev(sd_device **ret, const struct stat *st);
@@ -21,6 +34,8 @@ int device_get_watch_handle(sd_device *device, int *handle);
 int device_get_devnode_mode(sd_device *device, mode_t *mode);
 int device_get_devnode_uid(sd_device *device, uid_t *uid);
 int device_get_devnode_gid(sd_device *device, gid_t *gid);
+int device_get_action(sd_device *device, DeviceAction *action);
+int device_get_seqnum(sd_device *device, uint64_t *seqnum);
 
 void device_seal(sd_device *device);
 void device_set_is_initialized(sd_device *device);
@@ -58,18 +73,5 @@ static inline int device_read_db(sd_device *device) {
         return device_read_db_internal(device, false);
 }
 
-typedef enum DeviceAction {
-        DEVICE_ACTION_ADD,
-        DEVICE_ACTION_REMOVE,
-        DEVICE_ACTION_CHANGE,
-        DEVICE_ACTION_MOVE,
-        DEVICE_ACTION_ONLINE,
-        DEVICE_ACTION_OFFLINE,
-        DEVICE_ACTION_BIND,
-        DEVICE_ACTION_UNBIND,
-        _DEVICE_ACTION_MAX,
-        _DEVICE_ACTION_INVALID = -1,
-} DeviceAction;
-
 DeviceAction device_action_from_string(const char *s) _pure_;
 const char *device_action_to_string(DeviceAction a) _const_;
index 584e7def8a546dfe51c30089b87f68229062d96a..f455a4eb27cba6145f84fad59a065d07ea58691c 100644 (file)
@@ -43,6 +43,7 @@ int device_new_aux(sd_device **ret) {
                 .devmode = (mode_t) -1,
                 .devuid = (uid_t) -1,
                 .devgid = (gid_t) -1,
+                .action = _DEVICE_ACTION_INVALID,
         };
 
         *ret = device;
index 5ef2ba37809fcc10473f0392df5f3936a0268bbb..803de54712a0099107aed8ca4df2660fce21d113 100644 (file)
@@ -308,6 +308,7 @@ static const NLType rtnl_link_info_data_geneve_types[] = {
 static const NLType rtnl_link_info_data_can_types[] = {
         [IFLA_CAN_BITTIMING]            = { .size = sizeof(struct can_bittiming) },
         [IFLA_CAN_RESTART_MS]           = { .type = NETLINK_TYPE_U32 },
+        [IFLA_CAN_CTRLMODE]             = { .size = sizeof(struct can_ctrlmode) },
 };
 
 /* these strings must match the .kind entries in the kernel */
index 1e7d774ba9ad5a387c92529157f2074c79d8b3e5..357adf696440ef2377c6f4d783b2de7ff4a277d5 100644 (file)
  *
  * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
  **/
-_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) {
-        const char *seqnum;
-        unsigned long long ret;
-        int r;
+_public_ unsigned long long udev_device_get_seqnum(struct udev_device *udev_device) {
+        uint64_t seqnum;
 
         assert_return_errno(udev_device, 0, EINVAL);
 
-        r = sd_device_get_property_value(udev_device->device, "SEQNUM", &seqnum);
-        if (r == -ENOENT)
+        if (device_get_seqnum(udev_device->device, &seqnum) < 0)
                 return 0;
-        else if (r < 0)
-                return_with_errno(0, r);
-
-        r = safe_atollu(seqnum, &ret);
-        if (r < 0)
-                return_with_errno(0, r);
 
-        return ret;
+        return seqnum;
 }
 
 /**
@@ -652,18 +643,14 @@ _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct ud
  * Returns: the kernel action value, or #NULL if there is no action value available.
  **/
 _public_ const char *udev_device_get_action(struct udev_device *udev_device) {
-        const char *action;
-        int r;
+        DeviceAction action;
 
         assert_return_errno(udev_device, NULL, EINVAL);
 
-        r = sd_device_get_property_value(udev_device->device, "ACTION", &action);
-        if (r == -ENOENT)
+        if (device_get_action(udev_device->device, &action) < 0)
                 return NULL;
-        if (r < 0)
-                return_with_errno(NULL, r);
 
-        return action;
+        return device_action_to_string(action);
 }
 
 /**
index 60831bb1c327b463e79cb7f1b70fbbf58e08d3aa..f3d8de4f143f4b3dd54c71574e0dbd3b5087aba7 100644 (file)
@@ -24,6 +24,7 @@
 #include "process-util.h"
 #include "strv.h"
 #include "terminal-util.h"
+#include "udev-util.h"
 #include "user-util.h"
 
 void manager_reset_config(Manager *m) {
@@ -238,14 +239,12 @@ int manager_add_button(Manager *m, const char *name, Button **_button) {
 }
 
 int manager_process_seat_device(Manager *m, sd_device *d) {
-        const char *action;
         Device *device;
         int r;
 
         assert(m);
 
-        if (sd_device_get_property_value(d, "ACTION", &action) >= 0 &&
-            streq(action, "remove")) {
+        if (device_for_action(d, DEVICE_ACTION_REMOVE)) {
                 const char *syspath;
 
                 r = sd_device_get_syspath(d, &syspath);
@@ -305,7 +304,7 @@ int manager_process_seat_device(Manager *m, sd_device *d) {
 }
 
 int manager_process_button_device(Manager *m, sd_device *d) {
-        const char *action, *sysname;
+        const char *sysname;
         Button *b;
         int r;
 
@@ -315,8 +314,7 @@ int manager_process_button_device(Manager *m, sd_device *d) {
         if (r < 0)
                 return r;
 
-        if (sd_device_get_property_value(d, "ACTION", &action) >= 0 &&
-            streq(action, "remove")) {
+        if (device_for_action(d, DEVICE_ACTION_REMOVE)) {
 
                 b = hashmap_get(m->buttons, sysname);
                 if (!b)
index 95ec0a57c600c10214840f68c234495c4b6b39cf..c78994aae669770a229dc7a90f0f0cb90ecc97a4 100644 (file)
@@ -26,6 +26,7 @@
 #include "signal-util.h"
 #include "strv.h"
 #include "terminal-util.h"
+#include "udev-util.h"
 
 static Manager* manager_unref(Manager *m);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
@@ -559,7 +560,7 @@ static int manager_dispatch_device_udev(sd_device_monitor *monitor, sd_device *d
 
 static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
         Manager *m = userdata;
-        const char *name, *action;
+        const char *name;
 
         assert(m);
         assert(device);
@@ -569,8 +570,7 @@ static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *dev
 
         if (sd_device_get_sysname(device, &name) >= 0 &&
             startswith(name, "vcsa") &&
-            sd_device_get_property_value(device, "ACTION", &action) >= 0 &&
-            streq(action, "remove"))
+            device_for_action(device, DEVICE_ACTION_REMOVE))
                 seat_preallocate_vts(m->seat0);
 
         return 0;
index 30f2e26a1e8cf89f897628d4ca6cad6c0b1fd502..8b97b4d8cef02248f382963a80c67a77fe0b8964 100644 (file)
@@ -2666,10 +2666,15 @@ static int clean_images(int argc, char *argv[], void *userdata) {
                 return bus_log_parse_error(r);
 
         while ((r = sd_bus_message_read(reply, "(st)", &name, &usage)) > 0) {
-                log_info("Removed image '%s'. Freed exclusive disk space: %s",
-                         name, format_bytes(fb, sizeof(fb), usage));
-
-                total += usage;
+                if (usage == UINT64_MAX) {
+                        log_info("Removed image '%s'", name);
+                        total = UINT64_MAX;
+                } else {
+                        log_info("Removed image '%s'. Freed exclusive disk space: %s",
+                                 name, format_bytes(fb, sizeof(fb), usage));
+                        if (total != UINT64_MAX)
+                                total += usage;
+                }
                 c++;
         }
 
@@ -2677,8 +2682,11 @@ static int clean_images(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        log_info("Removed %u images in total. Total freed exclusive disk space %s.",
-                 c, format_bytes(fb, sizeof(fb), total));
+        if (total == UINT64_MAX)
+                log_info("Removed %u images in total.", c);
+        else
+                log_info("Removed %u images in total. Total freed exclusive disk space: %s.",
+                         c, format_bytes(fb, sizeof(fb), total));
 
         return 0;
 }
index e057978400d05eee999cf67013d7f1eee8321c1d..7712fd6ae3d97161a655c5759d8ea7ab2a249481 100644 (file)
@@ -223,7 +223,7 @@ static int address_establish(Address *address, Link *link) {
 
                 r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
                 if (r < 0)
-                        log_link_warning_errno(link, r, "Could not enable IP masquerading: %m");
+                        return r;
 
                 address->ip_masquerade_done = masq;
         }
@@ -321,7 +321,7 @@ static int address_release(Address *address) {
 
                 r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
                 if (r < 0)
-                        log_link_warning_errno(address->link, r, "Failed to disable IP masquerading: %m");
+                        return r;
 
                 address->ip_masquerade_done = false;
         }
@@ -371,13 +371,17 @@ int address_update(
 int address_drop(Address *address) {
         Link *link;
         bool ready;
+        int r;
 
         assert(address);
 
         ready = address_is_ready(address);
         link = address->link;
 
-        address_release(address);
+        r = address_release(address);
+        if (r < 0)
+                log_link_warning_errno(link, r, "Failed to disable IP masquerading, ignoring: %m");
+
         address_free(address);
 
         link_update_operstate(link, true);
@@ -445,7 +449,6 @@ int address_remove(
                 link_netlink_message_handler_t callback) {
 
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
-        _cleanup_free_ char *b = NULL;
         int r;
 
         assert(address);
@@ -456,28 +459,30 @@ int address_remove(
         assert(link->manager->rtnl);
 
         if (DEBUG_LOGGING) {
-                if (in_addr_to_string(address->family, &address->in_addr, &b) >= 0)
-                        log_link_debug(link, "Removing address %s", b);
+                _cleanup_free_ char *b = NULL;
+
+                (void) in_addr_to_string(address->family, &address->in_addr, &b);
+                log_link_debug(link, "Removing address %s", strna(b));
         }
 
         r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR,
                                      link->ifindex, address->family);
         if (r < 0)
-                return log_error_errno(r, "Could not allocate RTM_DELADDR message: %m");
+                return log_link_error_errno(link, r, "Could not allocate RTM_DELADDR message: %m");
 
         r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
         if (r < 0)
-                return log_error_errno(r, "Could not set prefixlen: %m");
+                return log_link_error_errno(link, r, "Could not set prefixlen: %m");
 
         r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
         if (r < 0)
-                return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");
+                return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
 
         r = netlink_call_async(link->manager->rtnl, NULL, req,
                                callback ?: address_remove_handler,
                                link_netlink_destroy_callback, link);
         if (r < 0)
-                return log_error_errno(r, "Could not send rtnetlink message: %m");
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
 
@@ -503,11 +508,9 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
          * Then let's acquire something more useful from the pool. */
         r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
         if (r < 0)
-                return log_link_error_errno(link, r, "Failed to acquire address from pool: %m");
-        if (r == 0) {
-                log_link_error(link, "Couldn't find free address for interface, all taken.");
+                return r;
+        if (r == 0)
                 return -EBUSY;
-        }
 
         if (original->family == AF_INET) {
                 /* Pick first address in range for ourselves ... */
@@ -566,11 +569,12 @@ int address_configure(
         /* If this is a new address, then refuse adding more than the limit */
         if (address_get(link, address->family, &address->in_addr, address->prefixlen, NULL) <= 0 &&
             set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
-                return -E2BIG;
+                return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
+                                            "Too many addresses are configured, refusing: %m");
 
         r = address_acquire(link, address, &address);
         if (r < 0)
-                return r;
+                return log_link_error_errno(link, r, "Failed to acquire an address from pool: %m");
 
         if (update)
                 r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
@@ -579,11 +583,11 @@ int address_configure(
                 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR,
                                              link->ifindex, address->family);
         if (r < 0)
-                return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
+                return log_link_error_errno(link, r, "Could not allocate RTM_NEWADDR message: %m");
 
         r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
         if (r < 0)
-                return log_error_errno(r, "Could not set prefixlen: %m");
+                return log_link_error_errno(link, r, "Could not set prefixlen: %m");
 
         address->flags |= IFA_F_PERMANENT;
 
@@ -604,50 +608,50 @@ int address_configure(
 
         r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff));
         if (r < 0)
-                return log_error_errno(r, "Could not set flags: %m");
+                return log_link_error_errno(link, r, "Could not set flags: %m");
 
         if (address->flags & ~0xff) {
                 r = sd_netlink_message_append_u32(req, IFA_FLAGS, address->flags);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set extended flags: %m");
+                        return log_link_error_errno(link, r, "Could not set extended flags: %m");
         }
 
         r = sd_rtnl_message_addr_set_scope(req, address->scope);
         if (r < 0)
-                return log_error_errno(r, "Could not set scope: %m");
+                return log_link_error_errno(link, r, "Could not set scope: %m");
 
         r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
         if (r < 0)
-                return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m");
+                return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
 
         if (in_addr_is_null(address->family, &address->in_addr_peer) == 0) {
                 r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
         } else if (address->family == AF_INET && address->prefixlen <= 30) {
                 r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
         }
 
         if (address->label) {
                 r = sd_netlink_message_append_string(req, IFA_LABEL, address->label);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append IFA_LABEL attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append IFA_LABEL attribute: %m");
         }
 
         r = sd_netlink_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
         if (r < 0)
-                return log_error_errno(r, "Could not append IFA_CACHEINFO attribute: %m");
+                return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m");
 
         r = address_establish(address, link);
         if (r < 0)
-                return r;
+                log_link_warning_errno(link, r, "Could not enable IP masquerading, ignoring: %m");
 
         r = netlink_call_async(link->manager->rtnl, NULL, req, callback, link_netlink_destroy_callback, link);
         if (r < 0) {
                 address_release(address);
-                return log_error_errno(r, "Could not send rtnetlink message: %m");
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
         }
 
         link_ref(link);
@@ -658,7 +662,7 @@ int address_configure(
                 r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
         if (r < 0) {
                 address_release(address);
-                return log_error_errno(r, "Could not add address: %m");
+                return log_link_error_errno(link, r, "Could not add address: %m");
         }
 
         return 0;
index 9e3cd71a095896f415afd8a64b2acfb7083364c0..de112a2ef80bf69ea5c0fcc0f0b1369eafafebbe 100644 (file)
@@ -2163,6 +2163,19 @@ static int link_set_can(Link *link) {
                         return log_link_error_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m");
         }
 
+        if (link->network->can_triple_sampling >= 0) {
+                struct can_ctrlmode cm = {
+                        .mask = CAN_CTRLMODE_3_SAMPLES,
+                        .flags = link->network->can_triple_sampling ? CAN_CTRLMODE_3_SAMPLES : 0,
+                };
+
+                log_link_debug(link, "%sabling triple-sampling", link->network->can_triple_sampling ? "En" : "Dis");
+
+                r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
+        }
+
         r = sd_netlink_message_close_container(m);
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to close netlink container: %m");
index c87f907957a9d688e1e96144c331243c07f993b4..53d1cfb446e10b1a6a913a12f53359e34b0d589e 100644 (file)
@@ -12,6 +12,7 @@
 #include "bus-util.h"
 #include "conf-parser.h"
 #include "def.h"
+#include "device-private.h"
 #include "device-util.h"
 #include "dns-domain.h"
 #include "fd-util.h"
@@ -182,21 +183,21 @@ int manager_connect_bus(Manager *m) {
 
 static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
         Manager *m = userdata;
-        const char *action;
+        DeviceAction action;
         Link *link = NULL;
         int r, ifindex;
 
         assert(m);
         assert(device);
 
-        r = sd_device_get_property_value(device, "ACTION", &action);
+        r = device_get_action(device, &action);
         if (r < 0) {
-                log_device_debug_errno(device, r, "Failed to get 'ACTION' property, ignoring device: %m");
+                log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
                 return 0;
         }
 
-        if (!STR_IN_SET(action, "add", "change", "move")) {
-                log_device_debug(device, "Ignoring udev %s event for device.", action);
+        if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_CHANGE, DEVICE_ACTION_MOVE)) {
+                log_device_debug(device, "Ignoring udev %s event for device.", device_action_to_string(action));
                 return 0;
         }
 
@@ -208,7 +209,8 @@ static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *devi
 
         r = device_is_renaming(device);
         if (r < 0) {
-                log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m", action);
+                log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
+                                       device_action_to_string(action));
                 return 0;
         }
         if (r > 0) {
index 7888bdf07af270140600abf67c03a12bc2cab9c4..51123d12ef0cacd1751b55cd7f3e6d15db6beb90 100644 (file)
@@ -195,6 +195,7 @@ IPv6Prefix.PreferredLifetimeSec,        config_parse_prefix_lifetime,
 CAN.BitRate,                            config_parse_si_size,                           0,                             offsetof(Network, can_bitrate)
 CAN.SamplePoint,                        config_parse_permille,                          0,                             offsetof(Network, can_sample_point)
 CAN.RestartSec,                         config_parse_sec,                               0,                             offsetof(Network, can_restart_us)
+CAN.TripleSampling,                     config_parse_tristate,                          0,                             offsetof(Network, can_triple_sampling)
 /* backwards compatibility: do not add new entries to this section */
 Network.IPv4LL,                         config_parse_ipv4ll,                            0,                             offsetof(Network, link_local)
 DHCPv4.UseDNS,                          config_parse_bool,                              0,                             offsetof(Network, dhcp_use_dns)
index ab4e90543c3a67e3101a9693db5f6c9b190e2f40..5f12df907afe9afcc8127c89fa2f49b44fac116f 100644 (file)
@@ -428,6 +428,8 @@ int network_load_one(Manager *manager, const char *filename) {
                 .ipv6_accept_ra_use_onlink_prefix = true,
                 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
                 .ipv6_accept_ra_route_table_set = false,
+
+                .can_triple_sampling = -1,
         };
 
         r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
index 63d0328750f37e85acf89f1c649c1f2dd01cc11a..2f7b6133fd506a3ebdda3b0d6f8cbeb7b2adbb02 100644 (file)
@@ -202,6 +202,7 @@ struct Network {
         size_t can_bitrate;
         unsigned can_sample_point;
         usec_t can_restart_us;
+        int can_triple_sampling;
 
         AddressFamilyBoolean ip_forward;
         bool ip_masquerade;
index 5594ba1224e9553dfc6cd4f9049751e491f83fba..207469878055785b539a32a3fab41d23f6c86eef 100644 (file)
@@ -407,59 +407,59 @@ int route_remove(Route *route, Link *link,
                                       RTM_DELROUTE, route->family,
                                       route->protocol);
         if (r < 0)
-                return log_error_errno(r, "Could not create RTM_DELROUTE message: %m");
+                return log_link_error_errno(link, r, "Could not create RTM_DELROUTE message: %m");
 
         if (in_addr_is_null(route->family, &route->gw) == 0) {
                 r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->family, &route->gw);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
         }
 
         if (route->dst_prefixlen) {
                 r = netlink_message_append_in_addr_union(req, RTA_DST, route->family, &route->dst);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_DST attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_DST attribute: %m");
 
                 r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set destination prefix length: %m");
+                        return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
         }
 
         if (route->src_prefixlen) {
                 r = netlink_message_append_in_addr_union(req, RTA_SRC, route->family, &route->src);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_SRC attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_SRC attribute: %m");
 
                 r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set source prefix length: %m");
+                        return log_link_error_errno(link, r, "Could not set source prefix length: %m");
         }
 
         if (in_addr_is_null(route->family, &route->prefsrc) == 0) {
                 r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_PREFSRC attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
         }
 
         r = sd_rtnl_message_route_set_scope(req, route->scope);
         if (r < 0)
-                return log_error_errno(r, "Could not set scope: %m");
+                return log_link_error_errno(link, r, "Could not set scope: %m");
 
         r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
         if (r < 0)
-                return log_error_errno(r, "Could not append RTA_PRIORITY attribute: %m");
+                return log_link_error_errno(link, r, "Could not append RTA_PRIORITY attribute: %m");
 
         if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW)) {
                 r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
         }
 
         r = netlink_call_async(link->manager->rtnl, NULL, req,
                                callback ?: route_remove_handler,
                                link_netlink_destroy_callback, link);
         if (r < 0)
-                return log_error_errno(r, "Could not send rtnetlink message: %m");
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
 
@@ -500,7 +500,8 @@ int route_configure(
 
         if (route_get(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL) <= 0 &&
             set_size(link->routes) >= routes_max())
-                return -E2BIG;
+                return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
+                                            "Too many routes are configured, refusing: %m");
 
         if (DEBUG_LOGGING) {
                 _cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL;
@@ -524,133 +525,133 @@ int route_configure(
                                       RTM_NEWROUTE, route->family,
                                       route->protocol);
         if (r < 0)
-                return log_error_errno(r, "Could not create RTM_NEWROUTE message: %m");
+                return log_link_error_errno(link, r, "Could not create RTM_NEWROUTE message: %m");
 
         if (in_addr_is_null(route->family, &route->gw) == 0) {
                 r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->family, &route->gw);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
 
                 r = sd_rtnl_message_route_set_family(req, route->family);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set route family: %m");
+                        return log_link_error_errno(link, r, "Could not set route family: %m");
         }
 
         if (route->dst_prefixlen) {
                 r = netlink_message_append_in_addr_union(req, RTA_DST, route->family, &route->dst);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_DST attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_DST attribute: %m");
 
                 r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set destination prefix length: %m");
+                        return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
         }
 
         if (route->src_prefixlen) {
                 r = netlink_message_append_in_addr_union(req, RTA_SRC, route->family, &route->src);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_SRC attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_SRC attribute: %m");
 
                 r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
                 if (r < 0)
-                        return log_error_errno(r, "Could not set source prefix length: %m");
+                        return log_link_error_errno(link, r, "Could not set source prefix length: %m");
         }
 
         if (in_addr_is_null(route->family, &route->prefsrc) == 0) {
                 r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_PREFSRC attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
         }
 
         r = sd_rtnl_message_route_set_scope(req, route->scope);
         if (r < 0)
-                return log_error_errno(r, "Could not set scope: %m");
+                return log_link_error_errno(link, r, "Could not set scope: %m");
 
         if (route->gateway_onlink >= 0)
                 SET_FLAG(route->flags, RTNH_F_ONLINK, route->gateway_onlink);
 
         r = sd_rtnl_message_route_set_flags(req, route->flags);
         if (r < 0)
-                return log_error_errno(r, "Could not set flags: %m");
+                return log_link_error_errno(link, r, "Could not set flags: %m");
 
         if (route->table != RT_TABLE_MAIN) {
                 if (route->table < 256) {
                         r = sd_rtnl_message_route_set_table(req, route->table);
                         if (r < 0)
-                                return log_error_errno(r, "Could not set route table: %m");
+                                return log_link_error_errno(link, r, "Could not set route table: %m");
                 } else {
                         r = sd_rtnl_message_route_set_table(req, RT_TABLE_UNSPEC);
                         if (r < 0)
-                                return log_error_errno(r, "Could not set route table: %m");
+                                return log_link_error_errno(link, r, "Could not set route table: %m");
 
                         /* Table attribute to allow more than 256. */
                         r = sd_netlink_message_append_data(req, RTA_TABLE, &route->table, sizeof(route->table));
                         if (r < 0)
-                                return log_error_errno(r, "Could not append RTA_TABLE attribute: %m");
+                                return log_link_error_errno(link, r, "Could not append RTA_TABLE attribute: %m");
                 }
         }
 
         r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
         if (r < 0)
-                return log_error_errno(r, "Could not append RTA_PRIORITY attribute: %m");
+                return log_link_error_errno(link, r, "Could not append RTA_PRIORITY attribute: %m");
 
         r = sd_netlink_message_append_u8(req, RTA_PREF, route->pref);
         if (r < 0)
-                return log_error_errno(r, "Could not append RTA_PREF attribute: %m");
+                return log_link_error_errno(link, r, "Could not append RTA_PREF attribute: %m");
 
         if (route->lifetime != USEC_INFINITY && kernel_route_expiration_supported()) {
                 r = sd_netlink_message_append_u32(req, RTA_EXPIRES,
                         DIV_ROUND_UP(usec_sub_unsigned(route->lifetime, now(clock_boottime_or_monotonic())), USEC_PER_SEC));
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_EXPIRES attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_EXPIRES attribute: %m");
         }
 
         r = sd_rtnl_message_route_set_type(req, route->type);
         if (r < 0)
-                return log_error_errno(r, "Could not set route type: %m");
+                return log_link_error_errno(link, r, "Could not set route type: %m");
 
         if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW)) {
                 r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
         }
 
         r = sd_netlink_message_open_container(req, RTA_METRICS);
         if (r < 0)
-                return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+                return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
 
         if (route->mtu > 0) {
                 r = sd_netlink_message_append_u32(req, RTAX_MTU, route->mtu);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTAX_MTU attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTAX_MTU attribute: %m");
         }
 
         if (route->initcwnd > 0) {
                 r = sd_netlink_message_append_u32(req, RTAX_INITCWND, route->initcwnd);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTAX_INITCWND attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTAX_INITCWND attribute: %m");
         }
 
         if (route->initrwnd > 0) {
                 r = sd_netlink_message_append_u32(req, RTAX_INITRWND, route->initrwnd);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTAX_INITRWND attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTAX_INITRWND attribute: %m");
         }
 
         if (route->quickack != -1) {
                 r = sd_netlink_message_append_u32(req, RTAX_QUICKACK, route->quickack);
                 if (r < 0)
-                        return log_error_errno(r, "Could not append RTAX_QUICKACK attribute: %m");
+                        return log_link_error_errno(link, r, "Could not append RTAX_QUICKACK attribute: %m");
         }
 
         r = sd_netlink_message_close_container(req);
         if (r < 0)
-                return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+                return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
 
         r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
                                link_netlink_destroy_callback, link);
         if (r < 0)
-                return log_error_errno(r, "Could not send rtnetlink message: %m");
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
 
@@ -658,7 +659,7 @@ int route_configure(
 
         r = route_add(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, &route);
         if (r < 0)
-                return log_error_errno(r, "Could not add route: %m");
+                return log_link_error_errno(link, r, "Could not add route: %m");
 
         /* TODO: drop expiration handling once it can be pushed into the kernel */
         route->lifetime = lifetime;
@@ -667,7 +668,7 @@ int route_configure(
                 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(),
                                       route->lifetime, 0, route_expire_handler, route);
                 if (r < 0)
-                        return log_error_errno(r, "Could not arm expiration timer: %m");
+                        return log_link_error_errno(link, r, "Could not arm expiration timer: %m");
         }
 
         sd_event_source_unref(route->expire);
index eb0a26ef35bf491d935c77312fb142b37b46b67a..13f50b2d37b9cca7f020b2fc4de5e4cdb4a0f8a3 100644 (file)
@@ -206,7 +206,7 @@ int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only)
         }
 
         if (isempty(source))
-                source = NULL;
+                source = mfree(source);
         else if (!source_path_is_valid(source))
                 return -EINVAL;
 
@@ -219,12 +219,10 @@ int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only)
         if (!m)
                 return -ENOMEM;
 
-        m->source = source;
-        m->destination = destination;
+        m->source = TAKE_PTR(source);
+        m->destination = TAKE_PTR(destination);
         m->read_only = read_only;
-        m->options = opts;
-
-        source = destination = opts = NULL;
+        m->options = TAKE_PTR(opts);
         return 0;
 }
 
index 0c5f3297567f1c1f37d873eb6b0b4b98a6423148..71c2dba4318b73b74e3296a53b00ccab518b4893 100644 (file)
@@ -51,7 +51,7 @@ static int run(int argc, char *argv[]) {
         if (buf_size < POOL_SIZE_MIN)
                 buf_size = POOL_SIZE_MIN;
 
-        r = mkdir_parents_label(RANDOM_SEED, 0755);
+        r = mkdir_parents(RANDOM_SEED, 0755);
         if (r < 0)
                 return log_error_errno(r, "Failed to create directory " RANDOM_SEED_DIR ": %m");
 
index 885f03118a5fbd133474281e6075a968137f4e0c..04c0a697b4803fc31b6691370097c85a1d4d1172 100644 (file)
@@ -789,16 +789,6 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
         return 0;
 }
 
-bool efi_loader_entry_name_valid(const char *s) {
-        if (isempty(s))
-                return false;
-
-        if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
-                return false;
-
-        return in_charset(s, ALPHANUMERICAL "-_.");
-}
-
 int efi_loader_get_entries(char ***ret) {
         _cleanup_free_ char16_t *entries = NULL;
         _cleanup_strv_free_ char **l = NULL;
@@ -903,6 +893,16 @@ int efi_loader_get_features(uint64_t *ret) {
 
 #endif
 
+bool efi_loader_entry_name_valid(const char *s) {
+        if (isempty(s))
+                return false;
+
+        if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
+                return false;
+
+        return in_charset(s, ALPHANUMERICAL "-_.");
+}
+
 char *efi_tilt_backslashes(char *s) {
         char *p;
 
index 92670c82c7d9c2aa5a59c248178f3071b6b14d9c..d8f18aae90e1d3bb893295e760c5d1fbd45d8ccb 100644 (file)
@@ -50,8 +50,6 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
 
 int efi_loader_get_entries(char ***ret);
 
-bool efi_loader_entry_name_valid(const char *s);
-
 int efi_loader_get_features(uint64_t *ret);
 
 #else
@@ -138,4 +136,6 @@ static inline int efi_loader_get_features(uint64_t *ret) {
 
 #endif
 
+bool efi_loader_entry_name_valid(const char *s);
+
 char *efi_tilt_backslashes(char *s);
index 6847d715f6660f58504489865b692f5357ab0922..19d823c11d3e1f3ded4442cbf63c603498ea0674 100644 (file)
@@ -181,3 +181,14 @@ int device_is_renaming(sd_device *dev) {
 
         return r >= 0;
 }
+
+bool device_for_action(sd_device *dev, DeviceAction action) {
+        DeviceAction a;
+
+        assert(dev);
+
+        if (device_get_action(dev, &a) < 0)
+                return false;
+
+        return a == action;
+}
index c45d6a11fd7838ad80e15a3b0a4e2bdb95973c5a..3c45447515651df15077dd53f7dcf085721a68b3 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "sd-device.h"
 
+#include "device-private.h"
 #include "time-util.h"
 
 typedef enum ResolveNameTiming {
@@ -28,3 +29,4 @@ static inline int udev_parse_config(void) {
 
 int device_wait_for_initialization(sd_device *device, const char *subsystem, sd_device **ret);
 int device_is_renaming(sd_device *dev);
+bool device_for_action(sd_device *dev, DeviceAction action);
index eeb17b613e7f9d339c47ae4088733ec34724cefd..324d4a41c76634f89138b2896066ba17eecec95c 100644 (file)
@@ -377,9 +377,9 @@ static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *er
                         n += !!u->path;
 
         if (n == 0) {
-                (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL);
-
                 c->slot_job_removed = sd_bus_slot_unref(c->slot_job_removed);
+
+                (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "NTP", NULL);
         }
 
         return 0;
index cefc2f4445fd824d5649bba7697290b9bb87d91b..cab1b5ac0c56aa5524e035435ac797eba7096421 100644 (file)
@@ -28,6 +28,7 @@
 #include "strxcpyx.h"
 #include "udev-builtin.h"
 #include "udev-node.h"
+#include "udev-util.h"
 #include "udev-watch.h"
 #include "udev.h"
 
@@ -695,7 +696,7 @@ int udev_event_spawn(UdevEvent *event,
 
 static int rename_netif(UdevEvent *event) {
         sd_device *dev = event->dev;
-        const char *action, *oldname;
+        const char *oldname;
         int ifindex, r;
 
         if (!event->name)
@@ -708,11 +709,7 @@ static int rename_netif(UdevEvent *event) {
         if (streq(event->name, oldname))
                 return 0; /* The interface name is already requested name. */
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
-        if (r < 0)
-                return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
-
-        if (!streq(action, "add"))
+        if (!device_for_action(dev, DEVICE_ACTION_ADD))
                 return 0; /* Rename the interface only when it is added. */
 
         r = sd_device_get_ifindex(dev, &ifindex);
@@ -742,7 +739,6 @@ static int rename_netif(UdevEvent *event) {
 
 static int update_devnode(UdevEvent *event) {
         sd_device *dev = event->dev;
-        const char *action;
         bool apply;
         int r;
 
@@ -782,11 +778,7 @@ static int update_devnode(UdevEvent *event) {
                 }
         }
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
-        if (r < 0)
-                return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
-
-        apply = streq(action, "add") || event->owner_set || event->group_set || event->mode_set;
+        apply = device_for_action(dev, DEVICE_ACTION_ADD) || event->owner_set || event->group_set || event->mode_set;
         return udev_node_add(dev, apply, event->mode, event->uid, event->gid, event->seclabel_list);
 }
 
@@ -843,7 +835,8 @@ int udev_event_execute_rules(UdevEvent *event,
                              usec_t timeout_usec,
                              Hashmap *properties_list,
                              UdevRules *rules) {
-        const char *subsystem, *action;
+        const char *subsystem;
+        DeviceAction action;
         sd_device *dev;
         int r;
 
@@ -856,11 +849,11 @@ int udev_event_execute_rules(UdevEvent *event,
         if (r < 0)
                 return log_device_error_errno(dev, r, "Failed to get subsystem: %m");
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
+        r = device_get_action(dev, &action);
         if (r < 0)
-                return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
+                return log_device_error_errno(dev, r, "Failed to get ACTION: %m");
 
-        if (streq(action, "remove")) {
+        if (action == DEVICE_ACTION_REMOVE) {
                 event_execute_rules_on_remove(event, timeout_usec, properties_list, rules);
                 return 0;
         }
@@ -873,7 +866,7 @@ int udev_event_execute_rules(UdevEvent *event,
                 /* Disable watch during event processing. */
                 (void) udev_watch_end(event->dev_db_clone);
 
-        if (streq(action, "move"))
+        if (action == DEVICE_ACTION_MOVE)
                 (void) udev_event_on_move(event);
 
         (void) udev_rules_apply_to_event(rules, event, timeout_usec, properties_list);
index d4aeca2fd328b2251183de8135688cc06cd3f01d..835ce17165a334ff1447a2fd25f225d75d873b70 100644 (file)
@@ -1156,6 +1156,7 @@ static void add_rule(UdevRules *rules, char *line,
                         else {
                                 if (STR_IN_SET(attr,
                                                "ACTION",
+                                               "SEQNUM",
                                                "SUBSYSTEM",
                                                "DEVTYPE",
                                                "MAJOR",
@@ -1767,18 +1768,19 @@ int udev_rules_apply_to_event(
         sd_device *dev = event->dev;
         enum escape_type esc = ESCAPE_UNSET;
         struct token *cur, *rule;
-        const char *action, *val;
+        DeviceAction action;
+        const char *val;
         bool can_set_name;
         int r;
 
         if (!rules->tokens)
                 return 0;
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
+        r = device_get_action(dev, &action);
         if (r < 0)
                 return r;
 
-        can_set_name = (!streq(action, "remove") &&
+        can_set_name = (action != DEVICE_ACTION_REMOVE &&
                         (sd_device_get_devnum(dev, NULL) >= 0 ||
                          sd_device_get_ifindex(dev, NULL) >= 0));
 
@@ -1797,7 +1799,7 @@ int udev_rules_apply_to_event(
                         esc = ESCAPE_UNSET;
                         break;
                 case TK_M_ACTION:
-                        if (!match_key(rules, cur, action))
+                        if (!match_key(rules, cur, device_action_to_string(action)))
                                 goto nomatch;
                         break;
                 case TK_M_DEVPATH:
index 3dde3f338a7460daa81e65bab700c32283f7494a..07caaa37949798924a15a6059184f181284f02f8 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "alloc-util.h"
 #include "device-monitor-private.h"
+#include "device-private.h"
 #include "device-util.h"
 #include "fd-util.h"
 #include "format-util.h"
@@ -26,14 +27,15 @@ static Set *arg_tag_filter = NULL;
 static Hashmap *arg_subsystem_filter = NULL;
 
 static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
-        const char *action = NULL, *devpath = NULL, *subsystem = NULL;
+        DeviceAction action = _DEVICE_ACTION_INVALID;
+        const char *devpath = NULL, *subsystem = NULL;
         MonitorNetlinkGroup group = PTR_TO_INT(userdata);
         struct timespec ts;
 
         assert(device);
         assert(IN_SET(group, MONITOR_GROUP_UDEV, MONITOR_GROUP_KERNEL));
 
-        (void) sd_device_get_property_value(device, "ACTION", &action);
+        (void) device_get_action(device, &action);
         (void) sd_device_get_devpath(device, &devpath);
         (void) sd_device_get_subsystem(device, &subsystem);
 
@@ -42,7 +44,8 @@ static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device,
         printf("%-6s[%"PRI_TIME".%06"PRI_NSEC"] %-8s %s (%s)\n",
                group == MONITOR_GROUP_UDEV ? "UDEV" : "KERNEL",
                ts.tv_sec, (nsec_t)ts.tv_nsec/1000,
-               action, devpath, subsystem);
+               strna(device_action_to_string(action)),
+               devpath, subsystem);
 
         if (arg_show_property) {
                 const char *key, *value;
index 9c1784489a86602f554fe657998605f0cb9b6b76..da4c4cb87cc0e4725cba3ebd7fde684dfcdf62ad 100644 (file)
@@ -53,9 +53,17 @@ static int parse_argv(int argc, char *argv[]) {
 
         while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0)
                 switch (c) {
-                case 'a':
+                case 'a': {
+                        DeviceAction a;
+
+                        a = device_action_from_string(optarg);
+                        if (a < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Invalid action '%s'", optarg);
+
                         arg_action = optarg;
                         break;
+                }
                 case 'N':
                         arg_resolve_name_timing = resolve_name_timing_from_string(optarg);
                         if (arg_resolve_name_timing < 0)
index b5e5f091ca01254f09f453125ba3053e88c8db29..b7dafb775575d7e6bbafc8d4a4413ba266750fcc 100644 (file)
@@ -60,6 +60,7 @@ static int exec_list(sd_device_enumerator *e, const char *action, Set *settle_se
 }
 
 static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *userdata) {
+        _cleanup_free_ char *val = NULL;
         Set *settle_set = userdata;
         const char *syspath;
 
@@ -72,7 +73,8 @@ static int device_monitor_handler(sd_device_monitor *m, sd_device *dev, void *us
         if (arg_verbose)
                 printf("settle %s\n", syspath);
 
-        if (!set_remove(settle_set, syspath))
+        val = set_remove(settle_set, syspath);
+        if (!val)
                 log_debug("Got epoll event on syspath %s not present in syspath set", syspath);
 
         if (set_isempty(settle_set))
index 2e31994b587241d4ba119b8545e70618ce288773..0da82dca554aa476b9f0a5b44f1328d4e09def87 100644 (file)
@@ -333,11 +333,7 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) {
          * udev has finished its event handling.
          */
 
-        r = sd_device_get_property_value(dev, "ACTION", &val);
-        if (r < 0)
-                return log_device_debug_errno(dev, r, "Failed to get the value of property 'ACTION': %m");
-
-        if (streq(val, "remove"))
+        if (device_for_action(dev, DEVICE_ACTION_REMOVE))
                 return 0;
 
         r = sd_device_get_subsystem(dev, &val);
@@ -385,21 +381,23 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) {
 static int worker_process_device(Manager *manager, sd_device *dev) {
         _cleanup_(udev_event_freep) UdevEvent *udev_event = NULL;
         _cleanup_close_ int fd_lock = -1;
-        const char *seqnum, *action;
+        DeviceAction action;
+        uint64_t seqnum;
         int r;
 
         assert(manager);
         assert(dev);
 
-        r = sd_device_get_property_value(dev, "SEQNUM", &seqnum);
+        r = device_get_seqnum(dev, &seqnum);
         if (r < 0)
                 return log_device_debug_errno(dev, r, "Failed to get SEQNUM: %m");
 
-        r = sd_device_get_property_value(dev, "ACTION", &action);
+        r = device_get_action(dev, &action);
         if (r < 0)
                 return log_device_debug_errno(dev, r, "Failed to get ACTION: %m");
 
-        log_device_debug(dev, "Processing device (SEQNUM=%s, ACTION=%s)", seqnum, action);
+        log_device_debug(dev, "Processing device (SEQNUM=%"PRIu64", ACTION=%s)",
+                         seqnum, device_action_to_string(action));
 
         udev_event = udev_event_new(dev, arg_exec_delay_usec, manager->rtnl);
         if (!udev_event)
@@ -425,7 +423,8 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
                         return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m");
         }
 
-        log_device_debug(dev, "Device (SEQNUM=%s, ACTION=%s) processed", seqnum, action);
+        log_device_debug(dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) processed",
+                         seqnum, device_action_to_string(action));
 
         return 0;
 }
@@ -581,8 +580,8 @@ static void event_run(Manager *manager, struct event *event) {
 
 static int event_queue_insert(Manager *manager, sd_device *dev) {
         _cleanup_(sd_device_unrefp) sd_device *clone = NULL;
-        const char *val, *action;
         struct event *event;
+        DeviceAction action;
         uint64_t seqnum;
         int r;
 
@@ -596,19 +595,12 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
         assert(manager->pid == getpid_cached());
 
         /* We only accepts devices received by device monitor. */
-        r = sd_device_get_property_value(dev, "SEQNUM", &val);
-        if (r < 0)
-                return r;
-
-        r = safe_atou64(val, &seqnum);
+        r = device_get_seqnum(dev, &seqnum);
         if (r < 0)
                 return r;
 
-        if (seqnum == 0)
-                return -EINVAL;
-
         /* Refuse devices do not have ACTION property. */
-        r = sd_device_get_property_value(dev, "ACTION", &action);
+        r = device_get_action(dev, &action);
         if (r < 0)
                 return r;
 
@@ -641,7 +633,8 @@ static int event_queue_insert(Manager *manager, sd_device *dev) {
 
         LIST_APPEND(event, manager->events, event);
 
-        log_device_debug(dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) is queued", seqnum, action);
+        log_device_debug(dev, "Device (SEQNUM=%"PRIu64", ACTION=%s) is queued",
+                         seqnum, device_action_to_string(action));
 
         return 0;
 }
index 014ee52277eb8de3411994c3939d7e05a6bb8a79..fc8c89fe0aeb0642be616c01d2aef2ab8b3fe79e 100755 (executable)
@@ -78,6 +78,8 @@ test_setup() {
         setup_basic_environment
         install_keymaps yes
         install_zoneinfo
+        # Install nproc to determine # of CPUs for correct parallelization
+        inst_binary nproc
 
         # setup the testsuite service
         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
index 7c0e495dbda6e1e6babe3b550be2d92b30463cc6..7c7a068556235e17d25e9eecf1a1eacd0c866201 100755 (executable)
@@ -4,31 +4,84 @@
 #set -ex
 #set -o pipefail
 
-for i in /usr/lib/systemd/tests/test-*; do
-    if [[ ! -x $i ]]; then continue; fi
-    NAME=${i##*/}
-    echo "Running $NAME"
-    $i > /$NAME.log 2>&1
-    ret=$?
-    if (( $ret && $ret != 77 )); then
-        echo "$NAME failed with $ret"
-        echo $NAME >> /failed-tests
-        echo "--- $NAME begin ---" >> /failed
-        cat /$NAME.log >> /failed
-        echo "--- $NAME end ---" >> /failed
-    elif (( $ret == 77 )); then
-        echo "$NAME skipped"
-        echo $NAME >> /skipped-tests
-        echo "--- $NAME begin ---" >> /skipped
-        cat /$NAME.log >> /skipped
-        echo "--- $NAME end ---" >> /skipped
+NPROC=$(nproc)
+MAX_QUEUE_SIZE=${NPROC:-2}
+IFS=$'\n' TEST_LIST=($(ls /usr/lib/systemd/tests/test-*))
+
+# Check & report test results
+# Arguments:
+#   $1: test path
+#   $2: test exit code
+function report_result() {
+    if [[ $# -ne 2 ]]; then
+        echo >&2 "check_result: missing arguments"
+        exit 1
+    fi
+
+    local name="${1##*/}"
+    local ret=$2
+
+    if [[ $ret -ne 0 && $ret != 77 ]]; then
+        echo "$name failed with $ret"
+        echo "$name" >> /failed-tests
+        {
+            echo "--- $name begin ---"
+            cat "/$name.log"
+            echo "--- $name end ---"
+        } >> /failed
+    elif [[ $ret == 77 ]]; then
+        echo "$name skipped"
+        echo "$name" >> /skipped-tests
+        {
+            echo "--- $name begin ---"
+            cat "/$name.log"
+            echo "--- $name end ---"
+        } >> /skipped
     else
-        echo "$NAME OK"
-        echo $NAME >> /testok
+        echo "$name OK"
+        echo "$name" >> /testok
+    fi
+
+    systemd-cat echo "--- $name ---"
+    systemd-cat cat "/$name.log"
+}
+
+# Associative array for running tasks, where running[test-path]=PID
+declare -A running=()
+for task in "${TEST_LIST[@]}"; do
+    # If there's MAX_QUEUE_SIZE running tasks, keep checking the running queue
+    # until one of the tasks finishes, so we can replace it.
+    while [[ ${#running[@]} -ge $MAX_QUEUE_SIZE ]]; do
+        for key in "${!running[@]}"; do
+            if ! kill -0 ${running[$key]} &>/dev/null; then
+                # Task has finished, report its result and drop it from the queue
+                wait ${running[$key]}
+                ec=$?
+                report_result "$key" $ec
+                unset running["$key"]
+                # Break from inner for loop and outer while loop to skip
+                # the sleep below when we find a free slot in the queue
+                break 2
+            fi
+        done
+
+        # Precisely* calculated constant to keep the spinlock from burning the CPU(s)
+        sleep 0.01
+    done
+
+    if [[ -x $task ]]; then
+        log_file="/${task##*/}.log"
+        $task &> "$log_file" &
+        running[$task]=$!
     fi
+done
 
-    systemd-cat echo "--- $NAME ---"
-    systemd-cat cat /$NAME.log
+# Wait for remaining running tasks
+for key in "${!running[@]}"; do
+    wait ${running[$key]}
+    ec=$?
+    report_result "$key" $ec
+    unset running["$key"]
 done
 
 exit 0
index e5c2b5c7abfa703c454afd4ec8d26ed9f2e0492d..3d6f8a0bbe790ad97d302a0a69beb8d81adc3e8e 100755 (executable)
@@ -21,19 +21,19 @@ EOF
 udevadm control --log-priority=debug --reload
 udevadm trigger --action=add --settle /sys/devices/virtual/net/lo
 udevadm info /sys/devices/virtual/net/lo
-
+sleep 1
 STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
 [[ $STATE == "active" ]] || exit 1
 
 udevadm trigger --action=change --settle /sys/devices/virtual/net/lo
 udevadm info /sys/devices/virtual/net/lo
-
+sleep 1
 STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
 [[ $STATE == "inactive" ]] || exit 1
 
 udevadm trigger --action=move --settle /sys/devices/virtual/net/lo
 udevadm info /sys/devices/virtual/net/lo
-
+sleep 1
 STATE=$(systemctl show --property=ActiveState --value sys-devices-virtual-net-lo.device)
 [[ $STATE == "active" ]] || exit 1
 
diff --git a/test/fuzz/fuzz-env-file/simple-env-file b/test/fuzz/fuzz-env-file/simple-env-file
new file mode 100644 (file)
index 0000000..2cad6f7
--- /dev/null
@@ -0,0 +1,5 @@
+VARIABLE="value"
+OPTION="--option=1234"
+NUMBER=1
+EMPTY=""
+PATH=/var/lib/xxx
index d77c6989cddf56980c1fc7252859b3e23a125df7..9a60eb712df2ce2fcdb85ce26431412b9a399cd2 100644 (file)
@@ -132,6 +132,7 @@ PVID=
 SamplePoint=
 BitRate=
 RestartSec=
+TripleSampling=
 [Address]
 DuplicateAddressDetection=
 AutoJoin=
diff --git a/test/fuzz/fuzz-nspawn-settings/basic-config b/test/fuzz/fuzz-nspawn-settings/basic-config
new file mode 100644 (file)
index 0000000..be0d4e7
--- /dev/null
@@ -0,0 +1,36 @@
+[Exec]
+Boot=off
+ProcessTwo=off
+Parameters=/sbin/init -x=1
+Environment=THIS=that
+User=user
+WorkingDirectory=/cwd
+PivotRoot=/newroot
+Capability=CAP_NET
+DropCapability=CAP_ADMIN
+KillSignal=SIGTERM
+Personality=shy
+MachineID=edbfea3309ba41ea83e2318c58a8d498
+PrivateUser=1:2
+NotifyReady=no
+SystemCallFilters=write
+
+[Files]
+ReadOnly=no
+Volatile=no
+Bind=/bindthis
+BindReadOnly=/bindthisro
+TemporaryFileSystem=/thisismytmpfs:rw
+Overlay=/thisisanoverlay:/thisisanoverlaytoo
+PrivateUsersChown=no
+
+[Network]
+Private=off
+VirtualEthernet=yes
+VirtualEthernetExtra=veth1:veth2
+Interface=eth1 enp0s1
+MacVLAN=eno1 eno2
+IPVLAN=eno3 enp2s124
+Bridge=bridge123 bridge125
+Zone=myzone
+Port=1234 156 -1
diff --git a/test/fuzz/fuzz-nspawn-settings/leak-4ff0e2498f596a77ea68d185c61e9e9ff9bb657f b/test/fuzz/fuzz-nspawn-settings/leak-4ff0e2498f596a77ea68d185c61e9e9ff9bb657f
new file mode 100644 (file)
index 0000000..7be2d2c
Binary files /dev/null and b/test/fuzz/fuzz-nspawn-settings/leak-4ff0e2498f596a77ea68d185c61e9e9ff9bb657f differ
index a936202e4a79baf3682b814fe6ce54b4ba3f0eb9..d8a3502a4ada02d3f33881f517117c7b38a4444b 100644 (file)
@@ -134,7 +134,16 @@ run_qemu() {
         fi
     fi
 
-    [ "$QEMU_SMP" ]   || QEMU_SMP=1
+    # If QEMU_SMP was not explicitly set, try to determine the value 'dynamically'
+    # i.e. use the number of online CPUs on the host machine. If the nproc utility
+    # is not installed or there's some other error when calling it, fall back
+    # to the original value (QEMU_SMP=1).
+    if ! [ "$QEMU_SMP" ]; then
+        if ! QEMU_SMP=$(nproc); then
+            dwarn "nproc utility is not installed, falling back to QEMU_SMP=1"
+            QEMU_SMP=1
+        fi
+    fi
 
     find_qemu_bin || return 1
 
diff --git a/test/test-network/conf/21-vlan-test1.network b/test/test-network/conf/21-vlan-test1.network
new file mode 100644 (file)
index 0000000..afe1deb
--- /dev/null
@@ -0,0 +1,2 @@
+[Match]
+Name=test1
diff --git a/test/test-network/conf/21-vlan-test1.network.d/override.conf b/test/test-network/conf/21-vlan-test1.network.d/override.conf
new file mode 100644 (file)
index 0000000..06307ff
--- /dev/null
@@ -0,0 +1,5 @@
+[Network]
+VLAN=vlan99
+Address=192.168.24.5/24
+Address=192.168.25.5/24
+IPv6AcceptRA=false
index afe1debe081b766c2f79663e3816bc13e6893fe7..0cd901def89cbac6c34c172a97eb5be330f0b04b 100644 (file)
@@ -1,2 +1,6 @@
 [Match]
-Name=test1
+Name=vlan99
+
+[Network]
+IPv6AcceptRA=false
+Address=192.168.23.5/24
diff --git a/test/test-network/conf/21-vlan.network.d/override.conf b/test/test-network/conf/21-vlan.network.d/override.conf
deleted file mode 100644 (file)
index 363fc90..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[Network]
-VLAN=vlan99
index 757e6da6571e659c32a7e96e0e55d0c6fcaa3b6c..856960ad65f8d761f57b0adab3813fae2b07ff3e 100755 (executable)
@@ -214,6 +214,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         '12-dummy.netdev',
         '21-macvlan.netdev',
         '21-macvtap.netdev',
+        '21-vlan-test1.network',
         '21-vlan.netdev',
         '21-vlan.network',
         '25-6rd-tunnel.netdev',
@@ -341,7 +342,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         self.assertEqual('1',             self.read_link_attr('bond99', 'bonding', 'tlb_dynamic_lb'))
 
     def test_vlan(self):
-        self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
+        self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev',
+                                             '21-vlan.network', '21-vlan-test1.network')
         self.start_networkd()
 
         self.assertTrue(self.link_exits('test1'))
@@ -360,6 +362,15 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
         self.assertTrue(output, 'MVRP')
         self.assertTrue(output, ' id 99 ')
 
+        output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'test1']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'inet 192.168.24.5/24 brd 192.168.24.255 scope global test1')
+        self.assertRegex(output, 'inet 192.168.25.5/24 brd 192.168.25.255 scope global test1')
+
+        output = subprocess.check_output(['ip', '-4', 'address', 'show', 'dev', 'vlan99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'inet 192.168.23.5/24 brd 192.168.23.255 scope global vlan99')
+
     def test_macvtap(self):
         self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
         self.start_networkd()
index 1807d73c68586297776b2053816670ce56f79e45..4684f095c0778f4d21d376bab2c6c1e36dba9bab 100644 (file)
@@ -23,7 +23,6 @@ IPAddressDeny=any
 LockPersonality=yes
 MemoryDenyWriteExecute=yes
 NoNewPrivileges=yes
-ProtectHostname=yes
 Restart=always
 RestartSec=0
 RestrictAddressFamilies=AF_UNIX AF_NETLINK
index 5da0e1e3307e720e6558d22b6b95fe322a702cce..472ef045de9e5cce5f421ef27a2ff4643a0be22b 100644 (file)
@@ -27,7 +27,6 @@ MemoryDenyWriteExecute=yes
 NoNewPrivileges=yes
 ProtectControlGroups=yes
 ProtectHome=yes
-ProtectHostname=yes
 ProtectKernelModules=yes
 ProtectSystem=strict
 Restart=on-failure
index eac3f31012ca8f59b1dfc41f26aaf0bd495f4fb4..3144b70063ee3acc4bd4a1fb704e7824143b1d23 100644 (file)
@@ -30,7 +30,6 @@ PrivateDevices=yes
 PrivateTmp=yes
 ProtectControlGroups=yes
 ProtectHome=yes
-ProtectHostname=yes
 ProtectKernelModules=yes
 ProtectKernelTunables=yes
 ProtectSystem=strict