]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #10814 from poettering/logind-suspend-fallback
authorLennart Poettering <lennart@poettering.net>
Mon, 19 Nov 2018 10:05:48 +0000 (11:05 +0100)
committerGitHub <noreply@github.com>
Mon, 19 Nov 2018 10:05:48 +0000 (11:05 +0100)
if we need to hibernate/suspend-then-hibernate/hybrid-sleep due to keypress/lid switch but can't, fallback to regular suspend

38 files changed:
catalog/systemd.pl.catalog.in
man/systemd-system.conf.xml
meson.build
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/macro.h
src/basic/missing.h
src/basic/util.c
src/basic/util.h
src/cgtop/cgtop.c
src/core/cgroup.c
src/core/dbus-cgroup.c
src/core/load-fragment.h
src/core/main.c
src/fuzz/fuzz-journald-audit.c [new file with mode: 0644]
src/fuzz/fuzz-journald-kmsg.c
src/fuzz/fuzz-journald.c
src/fuzz/fuzz-journald.h
src/fuzz/meson.build
src/journal/journald-audit.c
src/journal/journald-audit.h
src/libsystemd/sd-device/test-sd-device.c
src/rc-local-generator/rc-local-generator.c
src/shared/conf-parser.c
src/shared/efivars.c
src/test/test-cgroup-mask.c
src/test/test-execute.c
src/test/test-util.c
src/udev/net/ethtool-util.c
src/udev/net/ethtool-util.h
src/udev/net/link-config.c
src/udev/net/link-config.h
test/daughter.service
test/fuzz/fuzz-journald-audit/basic [new file with mode: 0644]
test/fuzz/fuzz-journald-audit/crash [new file with mode: 0644]
test/test-execute/exec-basic.service
travis-ci/managers/fedora.sh
travis-ci/managers/travis_wait.bash

index 3664120f8dc02fb42ee999725b5862ee206ec57b..b6c6b542053f5b048d8d6f46c5633408c705de12 100644 (file)
@@ -188,59 +188,67 @@ Zainicjowano wyłączenie systemu. Wyłączenie zostało rozpoczęte i wszystki
 usługi systemowe zostały zakończone, a wszystkie systemy plików odmontowane.
 
 -- 7d4958e842da4a758f6c1cdc7b36dcc5
-Subject: Rozpoczęto uruchamianie jednostki @UNIT@
+Subject: Rozpoczęto wykonywanie zadania uruchamiania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ rozpoczęła uruchamianie.
+Rozpoczęto wykonywanie zadania uruchamiania dla jednostki @UNIT@.
+
+Identyfikator zadania: @JOB_ID@.
 
 -- 39f53479d3a045ac8e11786248231fbf
-Subject: Ukończono uruchamianie jednostki @UNIT@
+Subject: Pomyślnie ukończono zadanie uruchamiania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ ukończyła uruchamianie.
+Pomyślnie ukończono zadanie uruchamiania dla jednostki @UNIT@.
 
-Wynik uruchamiania: @JOB_RESULT@.
+Identyfikator zadania: @JOB_ID@.
 
--- de5b426a63be47a7b6ac3eaac82e2f6f
-Subject: Rozpoczęto wyłączanie jednostki @UNIT@
+-- be02cf6855d2428ba40df7e9d022f03d
+Subject: Zadanie uruchamiania dla jednostki @UNIT@ się nie powiodło
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ rozpoczęła wyłączanie.
+Zadanie uruchamiania dla jednostki @UNIT@ zostało ukończone z niepowodzeniem.
 
--- 9d1aaa27d60140bd96365438aad20286
-Subject: Ukończono wyłączanie jednostki @UNIT@
+Identyfikator zadania: @JOB_ID@, wynik zadania: @JOB_RESULT@.
+
+-- de5b426a63be47a7b6ac3eaac82e2f6f
+Subject: Rozpoczęto wykonywanie zadania zatrzymania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ ukończyła wyłączanie.
+Rozpoczęto wykonywanie zadania zatrzymania dla jednostki @UNIT@.
 
--- be02cf6855d2428ba40df7e9d022f03d
-Subject: Jednostka @UNIT@ się nie powiodła
+Identyfikator zadania: @JOB_ID@.
+
+-- 9d1aaa27d60140bd96365438aad20286
+Subject: Ukończono zadanie zatrzymania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ się nie powiodła.
+Ukończono zadanie zatrzymania dla jednostki @UNIT@.
 
-Wynik: @JOB_RESULT@.
+Identyfikator zadania: @JOB_ID@, wynik zadania: @JOB_RESULT@.
 
 -- d34d037fff1847e6ae669a370e694725
-Subject: Rozpoczęto ponowne wczytywanie konfiguracji jednostki @UNIT@
+Subject: Rozpoczęto wykonywanie zadania ponownego wczytania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ rozpoczęła ponowne wczytywanie swojej konfiguracji.
+Rozpoczęto wykonywanie zadania ponownego wczytania dla jednostki @UNIT@.
+
+Identyfikator zadania: @JOB_ID@.
 
 -- 7b05ebc668384222baa8881179cfda54
-Subject: Ukończono ponowne wczytywanie konfiguracji jednostki @UNIT@
+Subject: Ukończono zadanie ponownego wczytania dla jednostki @UNIT@
 Defined-By: systemd
 Support: %SUPPORT_URL%
 
-Jednostka @UNIT@ ukończyła ponowne wczytywanie swojej konfiguracji.
+Ukończono zadanie ponownego wczytania dla jednostki @UNIT@.
 
-Wynik: @JOB_RESULT@.
+Identyfikator zadania: @JOB_ID@, wynik zadania: @JOB_RESULT@.
 
 -- 641257651c1b4ec9a8624d7a40a9e1e7
 Subject: Nie można wykonać procesu @EXECUTABLE@
@@ -338,6 +346,30 @@ Support: %SUPPORT_URL%
 
 Jednostka @UNIT@ została ukończona, zużywając wskazane zasoby.
 
+-- 7ad2d189f7e94e70a38c781354912448
+Subject: Jednostka się powiodła
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Jednostka @UNIT@ pomyślnie przeszła do stanu „dead” (martwego).
+
+-- d9b373ed55a64feb8242e02dbe79a49c
+Subject: Jednostka się nie powiodła
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Jednostka @UNIT@ przeszła do stanu „failed” (niepowodzenia)
+z wynikiem „@UNIT_RESULT@”.
+
+-- 98e322203f7a4ed290d09fe03c09fe15
+Subject: Proces jednostki zakończył działanie
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Proces @COMMAND@= należący do jednostki @UNIT@ zakończył działanie.
+
+Kod wyjścia procesu: „@EXIT_CODE@”, jego stan wyjścia: @EXIT_STATUS@.
+
 -- 50876a9db00f4c40bde1a2ad381c3a1b
 Subject: System jest skonfigurowany w sposób, który może powodować problemy
 Defined-By: systemd
index ea17111bc59eba7b58c549f301f5b6bee4236b39..35da82ab1a9497b3291ef863d3a3eaecba734b76 100644 (file)
         <varname>TasksAccounting=</varname>, <varname>IOAccounting=</varname> and <varname>IPAccounting=</varname>. See
         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for details on the per-unit settings. <varname>DefaultTasksAccounting=</varname> defaults to yes,
-        <varname>DefaultMemoryAccounting=</varname> to &MEMORY_ACCOUNTING_DEFAULT;, the other four settings to
-        no.</para></listitem>
+        <varname>DefaultMemoryAccounting=</varname> to &MEMORY_ACCOUNTING_DEFAULT;. <varname>DefaultCPUAccounting=</varname>
+        defaults to yes if enabling CPU accounting doesn't require the CPU controller to be enabled (Linux 4.15+ using the
+        unified hierarchy for resource control), otherwise it defaults to no. The other three settings default to no.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index ccea9457209b7e82f9f46f135c1109ed82100325..906960fb7174316c201f14510eb4054a634d04ba 100644 (file)
@@ -449,33 +449,39 @@ endforeach
 
 conf.set10('WANT_LINUX_STAT_H', want_linux_stat_h)
 
-foreach decl : [['IFLA_INET6_ADDR_GEN_MODE',         'linux/if_link.h'],
-                ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
-                ['IFLA_VRF_TABLE',                   'linux/if_link.h'],
-                ['IFLA_MACVLAN_FLAGS',               'linux/if_link.h'],
-                ['IFLA_IPVLAN_FLAGS',                'linux/if_link.h'],
-                ['IFLA_PHYS_PORT_ID',                'linux/if_link.h'],
-                ['IFLA_BOND_AD_ACTOR_SYSTEM',        'linux/if_link.h'],
-                ['IFLA_VLAN_PROTOCOL',               'linux/if_link.h'],
-                ['IFLA_VXLAN_REMCSUM_NOPARTIAL',     'linux/if_link.h'],
-                ['IFLA_VXLAN_GPE',                   'linux/if_link.h'],
-                ['IFLA_GENEVE_LABEL',                'linux/if_link.h'],
+foreach decl : [['IFLA_INET6_ADDR_GEN_MODE',                'linux/if_link.h'],
+                ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY',        'linux/if_link.h'],
+                ['IFLA_VRF_TABLE',                          'linux/if_link.h'],
+                ['IFLA_MACVLAN_FLAGS',                      'linux/if_link.h'],
+                ['IFLA_IPVLAN_FLAGS',                       'linux/if_link.h'],
+                ['IFLA_PHYS_PORT_ID',                       'linux/if_link.h'],
+                ['IFLA_BOND_AD_ACTOR_SYSTEM',               'linux/if_link.h'],
+                ['IFLA_VLAN_PROTOCOL',                      'linux/if_link.h'],
+                ['IFLA_VXLAN_REMCSUM_NOPARTIAL',            'linux/if_link.h'],
+                ['IFLA_VXLAN_GPE',                          'linux/if_link.h'],
+                ['IFLA_GENEVE_LABEL',                       'linux/if_link.h'],
                 # if_tunnel.h is buggy and cannot be included on its own
-                ['IFLA_VTI_REMOTE',                  'linux/if_tunnel.h', '#include <net/if.h>'],
-                ['IFLA_IPTUN_ENCAP_DPORT',           'linux/if_tunnel.h', '#include <net/if.h>'],
-                ['IFLA_GRE_ENCAP_DPORT',             'linux/if_tunnel.h', '#include <net/if.h>'],
-                ['IFLA_BRIDGE_VLAN_INFO',            'linux/if_bridge.h'],
-                ['IFLA_BRPORT_PROXYARP',             'linux/if_link.h'],
-                ['IFLA_BRPORT_LEARNING_SYNC',        'linux/if_link.h'],
-                ['IFLA_BR_VLAN_DEFAULT_PVID',        'linux/if_link.h'],
-                ['IPVLAN_F_PRIVATE',                 'linux/if_link.h'],
-                ['NDA_IFINDEX',                      'linux/neighbour.h'],
-                ['IFA_FLAGS',                        'linux/if_addr.h'],
-                ['FRA_UID_RANGE',                    'linux/fib_rules.h'],
-                ['LO_FLAGS_PARTSCAN',                'linux/loop.h'],
-                ['VXCAN_INFO_PEER',                  'linux/can/vxcan.h'],
-                ['FOU_ATTR_REMCSUM_NOPARTIAL',       'linux/fou.h'],
-                ['FOU_CMD_GET',                      'linux/fou.h'],
+                ['IFLA_VTI_REMOTE',                         'linux/if_tunnel.h', '#include <net/if.h>'],
+                ['IFLA_IPTUN_ENCAP_DPORT',                  'linux/if_tunnel.h', '#include <net/if.h>'],
+                ['IFLA_GRE_ENCAP_DPORT',                    'linux/if_tunnel.h', '#include <net/if.h>'],
+                ['IFLA_BRIDGE_VLAN_INFO',                   'linux/if_bridge.h'],
+                ['IFLA_BRPORT_PROXYARP',                    'linux/if_link.h'],
+                ['IFLA_BRPORT_LEARNING_SYNC',               'linux/if_link.h'],
+                ['IFLA_BR_VLAN_DEFAULT_PVID',               'linux/if_link.h'],
+                ['IPVLAN_F_PRIVATE',                        'linux/if_link.h'],
+                ['NDA_IFINDEX',                             'linux/neighbour.h'],
+                ['IFA_FLAGS',                               'linux/if_addr.h'],
+                ['FRA_UID_RANGE',                           'linux/fib_rules.h'],
+                ['LO_FLAGS_PARTSCAN',                       'linux/loop.h'],
+                ['VXCAN_INFO_PEER',                         'linux/can/vxcan.h'],
+                ['FOU_ATTR_REMCSUM_NOPARTIAL',              'linux/fou.h'],
+                ['FOU_CMD_GET',                             'linux/fou.h'],
+                ['ETHTOOL_LINK_MODE_10baseT_Half_BIT',      'linux/ethtool.h'],
+                ['ETHTOOL_LINK_MODE_25000baseCR_Full_BIT',  'linux/ethtool.h'],
+                ['ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT', 'linux/ethtool.h'],
+                ['ETHTOOL_LINK_MODE_1000baseX_Full_BIT',    'linux/ethtool.h'],
+                ['ETHTOOL_LINK_MODE_2500baseT_Full_BIT',    'linux/ethtool.h'],
+                ['ETHTOOL_LINK_MODE_FEC_NONE_BIT',          'linux/ethtool.h'],
                ]
         prefix = decl.length() > 2 ? decl[2] : ''
         have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
index 04508508324bbb94e9aa181e4fba33ad69d03898..613801f2c5539c2ced9ec0623acb639ea27437e2 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/stat.h>
 #include <sys/statfs.h>
 #include <sys/types.h>
+#include <sys/utsname.h>
 #include <sys/xattr.h>
 #include <unistd.h>
 
@@ -2822,3 +2823,54 @@ static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);
+
+CGroupMask get_cpu_accounting_mask(void) {
+        static CGroupMask needed_mask = (CGroupMask) -1;
+
+        /* On kernel ≥4.15 with unified hierarchy, cpu.stat's usage_usec is
+         * provided externally from the CPU controller, which means we don't
+         * need to enable the CPU controller just to get metrics. This is good,
+         * because enabling the CPU controller comes at a minor performance
+         * hit, especially when it's propagated deep into large hierarchies.
+         * There's also no separate CPU accounting controller available within
+         * a unified hierarchy.
+         *
+         * This combination of factors results in the desired cgroup mask to
+         * enable for CPU accounting varying as follows:
+         *
+         *                   ╔═════════════════════╤═════════════════════╗
+         *                   ║     Linux ≥4.15     │     Linux <4.15     ║
+         *   ╔═══════════════╬═════════════════════╪═════════════════════╣
+         *   ║ Unified       ║ nothing             │ CGROUP_MASK_CPU     ║
+         *   ╟───────────────╫─────────────────────┼─────────────────────╢
+         *   ║ Hybrid/Legacy ║ CGROUP_MASK_CPUACCT │ CGROUP_MASK_CPUACCT ║
+         *   ╚═══════════════╩═════════════════════╧═════════════════════╝
+         *
+         * We check kernel version here instead of manually checking whether
+         * cpu.stat is present for every cgroup, as that check in itself would
+         * already be fairly expensive.
+         *
+         * Kernels where this patch has been backported will therefore have the
+         * CPU controller enabled unnecessarily. This is more expensive than
+         * necessary, but harmless. ☺️
+         */
+
+        if (needed_mask == (CGroupMask) -1) {
+                if (cg_all_unified()) {
+                        struct utsname u;
+                        assert_se(uname(&u) >= 0);
+
+                        if (str_verscmp(u.release, "4.15") < 0)
+                                needed_mask = CGROUP_MASK_CPU;
+                        else
+                                needed_mask = 0;
+                } else
+                        needed_mask = CGROUP_MASK_CPUACCT;
+        }
+
+        return needed_mask;
+}
+
+bool cpu_accounting_is_cheap(void) {
+        return get_cpu_accounting_mask() == 0;
+}
index 463a8dc84ad6b34b1419ec680acf2e58a295444f..7919864df9198f6919ecff351ce67e2922d7fc37 100644 (file)
@@ -69,6 +69,9 @@ static inline CGroupMask CGROUP_MASK_EXTEND_JOINED(CGroupMask mask) {
         return mask;
 }
 
+CGroupMask get_cpu_accounting_mask(void);
+bool cpu_accounting_is_cheap(void);
+
 /* Special values for all weight knobs on unified hierarchy */
 #define CGROUP_WEIGHT_INVALID ((uint64_t) -1)
 #define CGROUP_WEIGHT_MIN UINT64_C(1)
index ae88fa5b93de4b00c342689203acf18f3b955b8a..00fb3212dba9f0f1af1bf3ee245355ecdbb2ab85 100644 (file)
@@ -383,7 +383,7 @@ static inline int __coverity_check__(int condition) {
 #define SET_FLAG(v, flag, b) \
         (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
 #define FLAGS_SET(v, flags) \
-        (((v) & (flags)) == (flags))
+        ((~(v) & (flags)) == 0)
 
 #define CASE_F(X) case X:
 #define CASE_F_1(CASE, X) CASE_F(X)
index d6712025519f9952e00d43edbf882c3a714a9d0e..45788af9e70b4765c2fed5a246f0abc6f804d116 100644 (file)
@@ -1457,4 +1457,124 @@ struct statx {
 #define FOU_ENCAP_MAX (__FOU_ENCAP_MAX - 1)
 #endif
 
+#if !HAVE_ETHTOOL_LINK_MODE_10baseT_Half_BIT /* linux@3f1ac7a700d039c61d8d8b99f28d605d489a60cf (4.6) */
+struct ethtool_link_settings {
+        __u32 cmd;
+        __u32 speed;
+        __u8  duplex;
+        __u8  port;
+        __u8  phy_address;
+        __u8  autoneg;
+        __u8  mdio_support;
+        __u8  eth_tp_mdix;
+        __u8  eth_tp_mdix_ctrl;
+        __s8  link_mode_masks_nwords;
+        __u8  transceiver;
+        __u8  reserved1[3];
+        __u32 reserved[7];
+        __u32 link_mode_masks[0];
+        /* layout of link_mode_masks fields:
+         * __u32 map_supported[link_mode_masks_nwords];
+         * __u32 map_advertising[link_mode_masks_nwords];
+         * __u32 map_lp_advertising[link_mode_masks_nwords];
+         */
+};
+enum ethtool_link_mode_bit_indices {
+        ETHTOOL_LINK_MODE_10baseT_Half_BIT           = 0,
+        ETHTOOL_LINK_MODE_10baseT_Full_BIT           = 1,
+        ETHTOOL_LINK_MODE_100baseT_Half_BIT          = 2,
+        ETHTOOL_LINK_MODE_100baseT_Full_BIT          = 3,
+        ETHTOOL_LINK_MODE_1000baseT_Half_BIT         = 4,
+        ETHTOOL_LINK_MODE_1000baseT_Full_BIT         = 5,
+        ETHTOOL_LINK_MODE_Autoneg_BIT                = 6,
+        ETHTOOL_LINK_MODE_TP_BIT                     = 7,
+        ETHTOOL_LINK_MODE_AUI_BIT                    = 8,
+        ETHTOOL_LINK_MODE_MII_BIT                    = 9,
+        ETHTOOL_LINK_MODE_FIBRE_BIT                  = 10,
+        ETHTOOL_LINK_MODE_BNC_BIT                    = 11,
+        ETHTOOL_LINK_MODE_10000baseT_Full_BIT        = 12,
+        ETHTOOL_LINK_MODE_Pause_BIT                  = 13,
+        ETHTOOL_LINK_MODE_Asym_Pause_BIT             = 14,
+        ETHTOOL_LINK_MODE_2500baseX_Full_BIT         = 15,
+        ETHTOOL_LINK_MODE_Backplane_BIT              = 16,
+        ETHTOOL_LINK_MODE_1000baseKX_Full_BIT        = 17,
+        ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT      = 18,
+        ETHTOOL_LINK_MODE_10000baseKR_Full_BIT       = 19,
+        ETHTOOL_LINK_MODE_10000baseR_FEC_BIT         = 20,
+        ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT     = 21,
+        ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT      = 22,
+        ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT      = 23,
+        ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT      = 24,
+        ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT      = 25,
+        ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT      = 26,
+        ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT      = 27,
+        ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT      = 28,
+        ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT      = 29,
+        ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT      = 30,
+        ETHTOOL_LINK_MODE_25000baseCR_Full_BIT       = 31,
+        ETHTOOL_LINK_MODE_25000baseKR_Full_BIT       = 32,
+        ETHTOOL_LINK_MODE_25000baseSR_Full_BIT       = 33,
+        ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT      = 34,
+        ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT      = 35,
+        ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT     = 36,
+        ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT     = 37,
+        ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT     = 38,
+        ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39,
+        ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT      = 40,
+        ETHTOOL_LINK_MODE_1000baseX_Full_BIT         = 41,
+        ETHTOOL_LINK_MODE_10000baseCR_Full_BIT       = 42,
+        ETHTOOL_LINK_MODE_10000baseSR_Full_BIT       = 43,
+        ETHTOOL_LINK_MODE_10000baseLR_Full_BIT       = 44,
+        ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT      = 45,
+        ETHTOOL_LINK_MODE_10000baseER_Full_BIT       = 46,
+        ETHTOOL_LINK_MODE_2500baseT_Full_BIT         = 47,
+        ETHTOOL_LINK_MODE_5000baseT_Full_BIT         = 48,
+
+        ETHTOOL_LINK_MODE_FEC_NONE_BIT               = 49,
+        ETHTOOL_LINK_MODE_FEC_RS_BIT                 = 50,
+        ETHTOOL_LINK_MODE_FEC_BASER_BIT              = 51,
+
+        /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
+         * 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
+         * macro for bits > 31. The only way to use indices > 31 is to
+         * use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API.
+         */
+
+        __ETHTOOL_LINK_MODE_LAST
+          = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
+};
+#else
+#if !HAVE_ETHTOOL_LINK_MODE_25000baseCR_Full_BIT /* linux@3851112e4737cd52aaeda0ce8d084be9ee128106 (4.7) */
+#define ETHTOOL_LINK_MODE_25000baseCR_Full_BIT       31
+#define ETHTOOL_LINK_MODE_25000baseKR_Full_BIT       32
+#define ETHTOOL_LINK_MODE_25000baseSR_Full_BIT       33
+#define ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT      34
+#define ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT      35
+#define ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT     36
+#define ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT     37
+#define ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT     38
+#define ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT 39
+#endif
+#if !HAVE_ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT /* linux@89da45b8b5b2187734a11038b8593714f964ffd1 (4.8) */
+#define ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT      40
+#endif
+#if !HAVE_ETHTOOL_LINK_MODE_1000baseX_Full_BIT /* linux@5711a98221443aec54c4c81ee98c6ae46acccb65 (4.9) */
+#define ETHTOOL_LINK_MODE_1000baseX_Full_BIT         41
+#define ETHTOOL_LINK_MODE_10000baseCR_Full_BIT       42
+#define ETHTOOL_LINK_MODE_10000baseSR_Full_BIT       43
+#define ETHTOOL_LINK_MODE_10000baseLR_Full_BIT       44
+#define ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT      45
+#define ETHTOOL_LINK_MODE_10000baseER_Full_BIT       46
+#endif
+#if !HAVE_ETHTOOL_LINK_MODE_2500baseT_Full_BIT /* linux@94842b4fc4d6b1691cfc86c6f5251f299d27f4ba (4.10) */
+#define ETHTOOL_LINK_MODE_2500baseT_Full_BIT         47
+#define ETHTOOL_LINK_MODE_5000baseT_Full_BIT         48
+#endif
+#if !HAVE_ETHTOOL_LINK_MODE_FEC_NONE_BIT /* linux@1a5f3da20bd966220931239fbd31e6ac6ff42251 (4.14) */
+#define ETHTOOL_LINK_MODE_FEC_NONE_BIT               49
+#define ETHTOOL_LINK_MODE_FEC_RS_BIT                 50
+#define ETHTOOL_LINK_MODE_FEC_BASER_BIT              51
+#endif
+#endif
+
 #include "missing_syscall.h"
index cd75529cfe38981e2c7a3f03df6f465825c5344d..00052c5e1dea00417e35c3da7a42fa833e2ea83d 100644 (file)
@@ -165,6 +165,28 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
         return NULL;
 }
 
+bool memeqzero(const void *data, size_t length) {
+        /* Does the buffer consist entirely of NULs?
+         * Copied from https://github.com/systemd/casync/, copied in turn from
+         * https://github.com/rustyrussell/ccan/blob/master/ccan/mem/mem.c#L92,
+         * which is licensed CC-0.
+         */
+
+        const uint8_t *p = data;
+        size_t i;
+
+        /* Check first 16 bytes manually */
+        for (i = 0; i < 16; i++, length--) {
+                if (length == 0)
+                        return true;
+                if (p[i])
+                        return false;
+        }
+
+        /* Now we know first 16 bytes are NUL, memcmp with self.  */
+        return memcmp(data, p + i, length) == 0;
+}
+
 int on_ac_power(void) {
         bool found_offline = false, found_online = false;
         _cleanup_closedir_ DIR *d = NULL;
index 8cba4ed7260e2380a9a46f7d098aa4445bee5eeb..fd180cb78741b2e7470dca59a50a6989ff0064ec 100644 (file)
@@ -159,6 +159,10 @@ int on_ac_power(void);
 
 #define zero(x) (memzero(&(x), sizeof(x)))
 
+bool memeqzero(const void *data, size_t length);
+
+#define eqzero(x) memeqzero(x, sizeof(x))
+
 static inline void *mempset(void *s, int c, size_t n) {
         memset(s, c, n);
         return (uint8_t*)s + n;
index efbfd240a6bfd05b2d6dca833b349ca070640021..af2ef853bd5ac5562603487dc444c01361391940 100644 (file)
@@ -231,7 +231,7 @@ static int process(
                 if (g->n_tasks > 0)
                         g->n_tasks_valid = true;
 
-        } else if (STR_IN_SET(controller, "cpu", "cpuacct")) {
+        } else if (STR_IN_SET(controller, "cpu", "cpuacct") || cpu_accounting_is_cheap()) {
                 _cleanup_free_ char *p = NULL, *v = NULL;
                 uint64_t new_usage;
                 nsec_t timestamp;
index 45a7581d45c77d6ed13a89233a06e6d9814ce668..0fb09935e1fb0a2c0f68b213247ec7c5e28a0916 100644 (file)
@@ -1178,7 +1178,7 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
         /* Figure out which controllers we need, based on the cgroup context object */
 
         if (c->cpu_accounting)
-                mask |= CGROUP_MASK_CPUACCT;
+                mask |= get_cpu_accounting_mask();
 
         if (cgroup_context_has_cpu_weight(c) ||
             cgroup_context_has_cpu_shares(c) ||
@@ -2617,13 +2617,15 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
         r = cg_all_unified();
         if (r < 0)
                 return r;
+
+        /* Requisite controllers for CPU accounting are not enabled */
+        if ((get_cpu_accounting_mask() & ~u->cgroup_realized_mask) != 0)
+                return -ENODATA;
+
         if (r > 0) {
                 _cleanup_free_ char *val = NULL;
                 uint64_t us;
 
-                if ((u->cgroup_realized_mask & CGROUP_MASK_CPU) == 0)
-                        return -ENODATA;
-
                 r = cg_get_keyed_attribute("cpu", u->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
                 if (r < 0)
                         return r;
@@ -2636,9 +2638,6 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
 
                 ns = us * NSEC_PER_USEC;
         } else {
-                if ((u->cgroup_realized_mask & CGROUP_MASK_CPUACCT) == 0)
-                        return -ENODATA;
-
                 r = cg_get_attribute("cpuacct", u->cgroup_path, "cpuacct.usage", &v);
                 if (r == -ENOENT)
                         return -ENODATA;
index 856d9d91b222f174a4cb73b5f39f2963d68315e5..a2f532076dcdf0798c24b10f98d154c3ff471e76 100644 (file)
@@ -603,7 +603,7 @@ int bus_cgroup_set_property(
         flags |= UNIT_PRIVATE;
 
         if (streq(name, "CPUAccounting"))
-                return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU, message, flags, error);
+                return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, get_cpu_accounting_mask(), message, flags, error);
 
         if (streq(name, "CPUWeight"))
                 return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error);
index c9e54ddfb3e223c1b04806381de49a457e71eb30..d236f66a39ad010f5fcaf0ff9850cc1414765b4e 100644 (file)
@@ -75,7 +75,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_io_limit);
 CONFIG_PARSER_PROTOTYPE(config_parse_blockio_weight);
 CONFIG_PARSER_PROTOTYPE(config_parse_blockio_device_weight);
 CONFIG_PARSER_PROTOTYPE(config_parse_blockio_bandwidth);
-CONFIG_PARSER_PROTOTYPE(config_parse_netclass);
 CONFIG_PARSER_PROTOTYPE(config_parse_job_mode);
 CONFIG_PARSER_PROTOTYPE(config_parse_job_mode_isolate);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_selinux_context);
index cabcb9ec165cd51ee269e45ac0d5fa06646a1cd1..f1dad983b722d657db6017ce09f760eecf6d53ff 100644 (file)
@@ -28,6 +28,7 @@
 #include "bus-error.h"
 #include "bus-util.h"
 #include "capability-util.h"
+#include "cgroup-util.h"
 #include "clock-util.h"
 #include "conf-parser.h"
 #include "cpu-set-util.h"
@@ -119,7 +120,7 @@ static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
 static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
 static Set* arg_syscall_archs = NULL;
 static FILE* arg_serialization = NULL;
-static bool arg_default_cpu_accounting = false;
+static int arg_default_cpu_accounting = -1;
 static bool arg_default_io_accounting = false;
 static bool arg_default_ip_accounting = false;
 static bool arg_default_blockio_accounting = false;
@@ -702,7 +703,7 @@ static int parse_config_file(void) {
                 { "Manager", "DefaultLimitNICE",          config_parse_rlimit,           RLIMIT_NICE, arg_default_rlimit           },
                 { "Manager", "DefaultLimitRTPRIO",        config_parse_rlimit,           RLIMIT_RTPRIO, arg_default_rlimit         },
                 { "Manager", "DefaultLimitRTTIME",        config_parse_rlimit,           RLIMIT_RTTIME, arg_default_rlimit         },
-                { "Manager", "DefaultCPUAccounting",      config_parse_bool,             0, &arg_default_cpu_accounting            },
+                { "Manager", "DefaultCPUAccounting",      config_parse_tristate,         0, &arg_default_cpu_accounting            },
                 { "Manager", "DefaultIOAccounting",       config_parse_bool,             0, &arg_default_io_accounting             },
                 { "Manager", "DefaultIPAccounting",       config_parse_bool,             0, &arg_default_ip_accounting             },
                 { "Manager", "DefaultBlockIOAccounting",  config_parse_bool,             0, &arg_default_blockio_accounting        },
@@ -751,7 +752,14 @@ static void set_manager_defaults(Manager *m) {
         m->default_restart_usec = arg_default_restart_usec;
         m->default_start_limit_interval = arg_default_start_limit_interval;
         m->default_start_limit_burst = arg_default_start_limit_burst;
-        m->default_cpu_accounting = arg_default_cpu_accounting;
+
+        /* On 4.15+ with unified hierarchy, CPU accounting is essentially free as it doesn't require the CPU
+         * controller to be enabled, so the default is to enable it unless we got told otherwise. */
+        if (arg_default_cpu_accounting >= 0)
+                m->default_cpu_accounting = arg_default_cpu_accounting;
+        else
+                m->default_cpu_accounting = cpu_accounting_is_cheap();
+
         m->default_io_accounting = arg_default_io_accounting;
         m->default_ip_accounting = arg_default_ip_accounting;
         m->default_blockio_accounting = arg_default_blockio_accounting;
diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
new file mode 100644 (file)
index 0000000..3f3ce7e
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-audit.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        Server s;
+
+        dummy_server_init(&s, data, size);
+        process_audit_string(&s, 0, s.buffer, size);
+        server_done(&s);
+
+        return 0;
+}
index e2611c6d453e5128fd9a42670b006d7efbf10602..f7426c84002a81338f0b035bdcd4bede289cae09 100644 (file)
@@ -1,29 +1,17 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "fuzz.h"
+#include "fuzz-journald.h"
 #include "journald-kmsg.h"
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        Server s = {};
-        _cleanup_free_ char *buffer = NULL;
+        Server s;
 
         if (size == 0)
                 return 0;
 
-        s = (Server) {
-                .syslog_fd = -1,
-                .native_fd = -1,
-                .stdout_fd = -1,
-                .dev_kmsg_fd = -1,
-                .audit_fd = -1,
-                .hostname_fd = -1,
-                .notify_fd = -1,
-                .storage = STORAGE_NONE,
-        };
-        assert_se(sd_event_default(&s.event) >= 0);
-        buffer = memdup(data, size);
-        assert_se(buffer);
-        dev_kmsg_record(&s, buffer, size);
+        dummy_server_init(&s, data, size);
+        dev_kmsg_record(&s, s.buffer, size);
         server_done(&s);
 
         return 0;
index f271d7f2fe06bcbd56ee75d64e3b8cce1dae4cad..0659b92ba3cf7a543c555829cd17c4638c14e93c 100644 (file)
@@ -5,12 +5,29 @@
 #include "journald-server.h"
 #include "sd-event.h"
 
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
+        *s = (Server) {
+                .syslog_fd = -1,
+                .native_fd = -1,
+                .stdout_fd = -1,
+                .dev_kmsg_fd = -1,
+                .audit_fd = -1,
+                .hostname_fd = -1,
+                .notify_fd = -1,
+                .storage = STORAGE_NONE,
+        };
+        assert_se(sd_event_default(&s->event) >= 0);
+        s->buffer = memdup_suffix0(buffer, size);
+        assert_se(s->buffer);
+        s->buffer_size = size + 1;
+}
+
 void fuzz_journald_processing_function(
                 const uint8_t *data,
                 size_t size,
                 void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
         ) {
-        Server s = {};
+        Server s;
         char *label = NULL;
         size_t label_len = 0;
         struct ucred *ucred = NULL;
@@ -19,12 +36,7 @@ void fuzz_journald_processing_function(
         if (size == 0)
                 return;
 
-        assert_se(sd_event_default(&s.event) >= 0);
-        s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
-        s.buffer = memdup_suffix0(data, size);
-        assert_se(s.buffer);
-        s.buffer_size = size + 1;
-        s.storage = STORAGE_NONE;
+        dummy_server_init(&s, data, size);
         (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
         server_done(&s);
 }
index e9d32a74aaff9f74a2d3ecbbe6f2cc74f23536c8..77e3b0c064c4f6ec03814bb7aa1317596df1bf33 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "journald-server.h"
 
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size);
+
 void fuzz_journald_processing_function(
                 const uint8_t *data,
                 size_t size,
index 5fd3093f077a84019d0bd36b93d0384118a7fc2c..89f312fee7c2f23b0eb0c34a9ebc80ec24fa4c09 100644 (file)
@@ -51,7 +51,14 @@ fuzzers += [
           libshared],
          [libmount]],
 
-        [['src/fuzz/fuzz-journald-kmsg.c'],
+        [['src/fuzz/fuzz-journald-audit.c',
+          'src/fuzz/fuzz-journald.c'],
+         [libjournal_core,
+          libshared],
+         [libselinux]],
+
+        [['src/fuzz/fuzz-journald-kmsg.c',
+          'src/fuzz/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
index f591e53d78bb0e6cd77142f2f2c3b811fb97f685..345e43ef44f7d3627be1b50cf922c24d397345fb 100644 (file)
@@ -313,7 +313,7 @@ static int map_all_fields(
         }
 }
 
-static void process_audit_string(Server *s, int type, const char *data, size_t size) {
+void process_audit_string(Server *s, int type, const char *data, size_t size) {
         size_t n_iov_allocated = 0, n_iov = 0, z;
         _cleanup_free_ struct iovec *iov = NULL;
         uint64_t seconds, msec, id;
@@ -341,11 +341,12 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
         if (!p)
                 return;
 
+        k = 0;
         if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n",
                    &seconds,
                    &msec,
                    &id,
-                   &k) != 3)
+                   &k) != 3 || k == 0)
                 return;
 
         p += k;
index 57bb1711c96c24a3d85e72d04cb5bbc850a1e966..7766618c986cd317f491876fe5f7c6e9fa760331 100644 (file)
@@ -6,4 +6,6 @@
 
 void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const union sockaddr_union *sa, socklen_t salen);
 
+void process_audit_string(Server *s, int type, const char *data, size_t size);
+
 int server_open_audit(Server*s);
index 1dda6625d2054dfe71ead7cf35229de0260289ac..e459b13b9625a17181d3d4e762f7eb8a67b3ceaa 100644 (file)
@@ -8,62 +8,77 @@
 #include "tests.h"
 #include "util.h"
 
-static void test_sd_device_basic(void) {
-        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
-        sd_device *d;
+static void test_sd_device_one(sd_device *d) {
+        const char *syspath, *subsystem, *val;
+        dev_t devnum;
+        usec_t usec;
+        int i, r;
 
-        log_info("/* %s */", __func__);
+        assert_se(sd_device_get_syspath(d, &syspath) >= 0);
 
-        assert_se(sd_device_enumerator_new(&e) >= 0);
-        assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0);
-        FOREACH_DEVICE(e, d) {
-                const char *syspath, *subsystem, *val;
-                dev_t devnum;
-                usec_t usec;
-                int i, r;
+        r = sd_device_get_subsystem(d, &subsystem);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                assert_se(sd_device_get_syspath(d, &syspath) >= 0);
+        r = sd_device_get_devtype(d, &val);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                r = sd_device_get_subsystem(d, &subsystem);
-                assert_se(r >= 0 || r == -ENOENT);
+        r = sd_device_get_devnum(d, &devnum);
+        assert_se((r >= 0 && major(devnum) > 0) || r == -ENOENT);
 
-                r = sd_device_get_devtype(d, &val);
-                assert_se(r >= 0 || r == -ENOENT);
+        r = sd_device_get_ifindex(d, &i);
+        assert_se((r >= 0 && i > 0) || r == -ENOENT);
 
-                r = sd_device_get_devnum(d, &devnum);
-                assert_se((r >= 0 && major(devnum) > 0) || r == -ENOENT);
+        r = sd_device_get_driver(d, &val);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                r = sd_device_get_ifindex(d, &i);
-                assert_se((r >= 0 && i > 0) || r == -ENOENT);
+        assert_se(sd_device_get_devpath(d, &val) >= 0);
 
-                r = sd_device_get_driver(d, &val);
-                assert_se(r >= 0 || r == -ENOENT);
+        r = sd_device_get_devname(d, &val);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                assert_se(sd_device_get_devpath(d, &val) >= 0);
+        assert_se(sd_device_get_sysname(d, &val) >= 0);
 
-                r = sd_device_get_devname(d, &val);
-                assert_se(r >= 0 || r == -ENOENT);
+        r = sd_device_get_sysnum(d, &val);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                assert_se(sd_device_get_sysname(d, &val) >= 0);
+        i = sd_device_get_is_initialized(d);
+        assert_se(i >= 0);
+        if (i > 0) {
+                r = sd_device_get_usec_since_initialized(d, &usec);
+                assert_se((r >= 0 && usec > 0) || r == -ENODATA);
+        }
 
-                r = sd_device_get_sysnum(d, &val);
-                assert_se(r >= 0 || r == -ENOENT);
+        r = sd_device_get_sysattr_value(d, "name_assign_type", &val);
+        assert_se(r >= 0 || IN_SET(r, -ENOENT, -EINVAL));
 
-                i = sd_device_get_is_initialized(d);
-                assert_se(i >= 0);
-                if (i > 0) {
-                        r = sd_device_get_usec_since_initialized(d, &usec);
-                        assert_se((r >= 0 && usec > 0) || r == -ENODATA);
-                }
+        r = sd_device_get_property_value(d, "ID_NET_DRIVER", &val);
+        assert_se(r >= 0 || r == -ENOENT);
 
-                r = sd_device_get_sysattr_value(d, "name_assign_type", &val);
-                assert_se(r >= 0 || IN_SET(r, -ENOENT, -EINVAL));
+        log_info("syspath:%s subsystem:%s initialized:%s", syspath, strna(subsystem), yes_no(i));
+}
 
-                r = sd_device_get_property_value(d, "ID_NET_DRIVER", &val);
-                assert_se(r >= 0 || r == -ENOENT);
+static void test_sd_device_enumerator_devices(void) {
+        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
+        sd_device *d;
 
-                log_debug("subsystem:%s syspath:%s initialized:%s", strna(subsystem), syspath, yes_no(i));
-        }
+        log_info("/* %s */", __func__);
+
+        assert_se(sd_device_enumerator_new(&e) >= 0);
+        assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0);
+        FOREACH_DEVICE(e, d)
+                test_sd_device_one(d);
+}
+
+static void test_sd_device_enumerator_subsystems(void) {
+        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
+        sd_device *d;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(sd_device_enumerator_new(&e) >= 0);
+        assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0);
+        FOREACH_SUBSYSTEM(e, d)
+                test_sd_device_one(d);
 }
 
 static void test_sd_device_enumerator_filter_subsystem_one(const char *subsystem, Hashmap *h) {
@@ -133,7 +148,8 @@ static void test_sd_device_enumerator_filter_subsystem(void) {
 int main(int argc, char **argv) {
         test_setup_logging(LOG_INFO);
 
-        test_sd_device_basic();
+        test_sd_device_enumerator_devices();
+        test_sd_device_enumerator_subsystems();
         test_sd_device_enumerator_filter_subsystem();
 
         return 0;
index 44b2edec05de933e208a19f8ac362e189c2f47d9..ba5e336a34f615a87cf4c9bfe4efd49396a56924 100644 (file)
 
 static const char *arg_dest = "/tmp";
 
+/* So you are reading this, and might wonder: why is this implemented as a generator rather than as a plain, statically
+ * enabled service that carries appropriate ConditionFileIsExecutable= lines? The answer is this: conditions bypass
+ * execution of a service's binary, but they have no influence on unit dependencies. Thus, a service that is
+ * conditioned out will still act as synchronization point in the dependency tree, and we'd rather not have that for
+ * these two legacy scripts. */
+
 static int add_symlink(const char *service, const char *where) {
         const char *from, *to;
         int r;
index b417ac2d6d8716debc4fd6c55d908c50da9fd0ac..8110b2cb16884e66bc8f2e0250463365d3780148 100644 (file)
@@ -82,19 +82,13 @@ int config_item_perf_lookup(
         assert(ltype);
         assert(data);
 
-        if (!section)
-                p = lookup(lvalue, strlen(lvalue));
-        else {
-                char *key;
-
-                key = strjoin(section, ".", lvalue);
-                if (!key)
-                        return -ENOMEM;
+        if (section) {
+                const char *key;
 
+                key = strjoina(section, ".", lvalue);
                 p = lookup(key, strlen(key));
-                free(key);
-        }
-
+        } else
+                p = lookup(lvalue, strlen(lvalue));
         if (!p)
                 return 0;
 
@@ -132,7 +126,6 @@ static int next_assignment(
         r = lookup(table, section, lvalue, &func, &ltype, &data, userdata);
         if (r < 0)
                 return r;
-
         if (r > 0) {
                 if (func)
                         return func(unit, filename, line, section, section_line,
index fbed9027c10598eefb73fcf0457984fd7ecef303..6815fc69b82a342001ac3b01be726a9fdc240b5e 100644 (file)
@@ -834,18 +834,6 @@ int efi_loader_get_entries(char ***ret) {
         return 0;
 }
 
-#endif
-
-char *efi_tilt_backslashes(char *s) {
-        char *p;
-
-        for (p = s; *p; p++)
-                if (*p == '\\')
-                        *p = '/';
-
-        return s;
-}
-
 int efi_loader_get_features(uint64_t *ret) {
         _cleanup_free_ void *v = NULL;
         size_t s;
@@ -895,3 +883,15 @@ int efi_loader_get_features(uint64_t *ret) {
         memcpy(ret, v, sizeof(uint64_t));
         return 0;
 }
+
+#endif
+
+char *efi_tilt_backslashes(char *s) {
+        char *p;
+
+        for (p = s; *p; p++)
+                if (*p == '\\')
+                        *p = '/';
+
+        return s;
+}
index d9223f5f61f252d6812ab0392f329e79bd5643df..143e7aa42477edb1f7c72f6a70111369d3511754 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <stdio.h>
 
+#include "cgroup.h"
+#include "cgroup-util.h"
 #include "macro.h"
 #include "manager.h"
 #include "rm-rf.h"
 #include "tests.h"
 #include "unit.h"
 
+#define ASSERT_CGROUP_MASK(got, expected) \
+        log_cgroup_mask(got, expected); \
+        assert_se(got == expected)
+
+#define ASSERT_CGROUP_MASK_JOINED(got, expected) ASSERT_CGROUP_MASK(got, CGROUP_MASK_EXTEND_JOINED(expected))
+
+static void log_cgroup_mask(CGroupMask got, CGroupMask expected) {
+        _cleanup_free_ char *e_store = NULL, *g_store = NULL;
+
+        assert_se(cg_mask_to_string(expected, &e_store) >= 0);
+        log_info("Expected mask: %s\n", e_store);
+        assert_se(cg_mask_to_string(got, &g_store) >= 0);
+        log_info("Got mask: %s\n", g_store);
+}
+
 static int test_cgroup_mask(void) {
         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
         _cleanup_(manager_freep) Manager *m = NULL;
         Unit *son, *daughter, *parent, *root, *grandchild, *parent_deep;
         int r;
+        CGroupMask cpu_accounting_mask = get_cpu_accounting_mask();
 
         r = enter_cgroup_subroot();
         if (r == -ENOMEDIUM)
@@ -57,36 +75,36 @@ static int test_cgroup_mask(void) {
         root = UNIT_DEREF(parent->slice);
 
         /* Verify per-unit cgroups settings. */
-        assert_se(unit_get_own_mask(son) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT));
-        assert_se(unit_get_own_mask(daughter) == 0);
-        assert_se(unit_get_own_mask(grandchild) == 0);
-        assert_se(unit_get_own_mask(parent_deep) == CGROUP_MASK_MEMORY);
-        assert_se(unit_get_own_mask(parent) == (CGROUP_MASK_IO | CGROUP_MASK_BLKIO));
-        assert_se(unit_get_own_mask(root) == 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(son), CGROUP_MASK_CPU);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(daughter), cpu_accounting_mask);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(grandchild), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(parent_deep), CGROUP_MASK_MEMORY);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(parent), (CGROUP_MASK_IO | CGROUP_MASK_BLKIO));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(root), 0);
 
         /* Verify aggregation of member masks */
-        assert_se(unit_get_members_mask(son) == 0);
-        assert_se(unit_get_members_mask(daughter) == 0);
-        assert_se(unit_get_members_mask(grandchild) == 0);
-        assert_se(unit_get_members_mask(parent_deep) == 0);
-        assert_se(unit_get_members_mask(parent) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
-        assert_se(unit_get_members_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(son), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(daughter), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(grandchild), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(parent_deep), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(parent), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(root), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
 
         /* Verify aggregation of sibling masks. */
-        assert_se(unit_get_siblings_mask(son) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
-        assert_se(unit_get_siblings_mask(daughter) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
-        assert_se(unit_get_siblings_mask(grandchild) == 0);
-        assert_se(unit_get_siblings_mask(parent_deep) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY));
-        assert_se(unit_get_siblings_mask(parent) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
-        assert_se(unit_get_siblings_mask(root) == (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(son), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(daughter), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(grandchild), 0);
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(parent_deep), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(parent), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
+        ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(root), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
 
         /* Verify aggregation of target masks. */
-        assert_se(unit_get_target_mask(son) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
-        assert_se(unit_get_target_mask(daughter) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
-        assert_se(unit_get_target_mask(grandchild) == 0);
-        assert_se(unit_get_target_mask(parent_deep) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_MEMORY) & m->cgroup_supported));
-        assert_se(unit_get_target_mask(parent) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
-        assert_se(unit_get_target_mask(root) == ((CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+        ASSERT_CGROUP_MASK(unit_get_target_mask(son), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+        ASSERT_CGROUP_MASK(unit_get_target_mask(daughter), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+        ASSERT_CGROUP_MASK(unit_get_target_mask(grandchild), 0);
+        ASSERT_CGROUP_MASK(unit_get_target_mask(parent_deep), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+        ASSERT_CGROUP_MASK(unit_get_target_mask(parent), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
+        ASSERT_CGROUP_MASK(unit_get_target_mask(root), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
 
         return 0;
 }
index e6715f9574994818e03cf87a8ee93a34afa2a48a..0e378f68c01dc28b5e74a28bd5731c75c7198c98 100644 (file)
@@ -54,6 +54,9 @@ static void check(Manager *m, Unit *unit, int status_expected, int code_expected
                 n = now(CLOCK_MONOTONIC);
                 if (ts + timeout < n) {
                         log_error("Test timeout when testing %s", unit->id);
+                        r = UNIT_VTABLE(unit)->kill(unit, KILL_ALL, 9, NULL);
+                        if (r < 0)
+                                log_error_errno(r, "Failed to kill %s: %m", unit->id);
                         exit(EXIT_FAILURE);
                 }
         }
index 21d58dd86b0cc8c62dec416e09553ffcc00cc18d..eeee09a7d2b1cb55b523b3c86a41cf306a4b0e9e 100644 (file)
 #include "raw-clone.h"
 #include "rm-rf.h"
 #include "string-util.h"
+#include "tests.h"
 #include "util.h"
 
 static void test_align_power2(void) {
         unsigned long i, p2;
 
+        log_info("/* %s */", __func__);
+
         assert_se(ALIGN_POWER2(0) == 0);
         assert_se(ALIGN_POWER2(1) == 1);
         assert_se(ALIGN_POWER2(2) == 2);
@@ -60,6 +63,8 @@ static void test_max(void) {
         void *p = (void *)str;
         void *q = (void *)&str[16];
 
+        log_info("/* %s */", __func__);
+
         assert_cc(sizeof(val1.b) == sizeof(int) * 100);
 
         /* CONST_MAX returns (void) instead of a value if the passed arguments
@@ -135,6 +140,8 @@ static void test_container_of(void) {
                 uint32_t v2;
         } _packed_ myval = { };
 
+        log_info("/* %s */", __func__);
+
         assert_cc(sizeof(myval) == 17);
         assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
         assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
@@ -150,6 +157,8 @@ static void test_container_of(void) {
 static void test_div_round_up(void) {
         int div;
 
+        log_info("/* %s */", __func__);
+
         /* basic tests */
         assert_se(DIV_ROUND_UP(0, 8) == 0);
         assert_se(DIV_ROUND_UP(1, 8) == 1);
@@ -181,6 +190,8 @@ static void test_div_round_up(void) {
 }
 
 static void test_u64log2(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(u64log2(0) == 0);
         assert_se(u64log2(8) == 3);
         assert_se(u64log2(9) == 3);
@@ -191,6 +202,8 @@ static void test_u64log2(void) {
 }
 
 static void test_protect_errno(void) {
+        log_info("/* %s */", __func__);
+
         errno = 12;
         {
                 PROTECT_ERRNO;
@@ -200,6 +213,8 @@ static void test_protect_errno(void) {
 }
 
 static void test_in_set(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(IN_SET(1, 1));
         assert_se(IN_SET(1, 1, 2, 3, 4));
         assert_se(IN_SET(2, 1, 2, 3, 4));
@@ -210,6 +225,8 @@ static void test_in_set(void) {
 }
 
 static void test_log2i(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(log2i(1) == 0);
         assert_se(log2i(2) == 1);
         assert_se(log2i(3) == 1);
@@ -220,9 +237,25 @@ static void test_log2i(void) {
         assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
 }
 
+static void test_eqzero(void) {
+        const uint32_t zeros[] = {0, 0, 0};
+        const uint32_t ones[] = {1, 1};
+        const uint32_t mixed[] = {0, 1, 0, 0, 0};
+        const uint8_t longer[] = {[55] = 255};
+
+        log_info("/* %s */", __func__);
+
+        assert_se(eqzero(zeros));
+        assert_se(!eqzero(ones));
+        assert_se(!eqzero(mixed));
+        assert_se(!eqzero(longer));
+}
+
 static void test_raw_clone(void) {
         pid_t parent, pid, pid2;
 
+        log_info("/* %s */", __func__);
+
         parent = getpid();
         log_info("before clone: getpid()→"PID_FMT, parent);
         assert_se(raw_getpid() == parent);
@@ -253,6 +286,8 @@ static void test_physical_memory(void) {
         uint64_t p;
         char buf[FORMAT_BYTES_MAX];
 
+        log_info("/* %s */", __func__);
+
         p = physical_memory();
         assert_se(p > 0);
         assert_se(p < UINT64_MAX);
@@ -264,6 +299,8 @@ static void test_physical_memory(void) {
 static void test_physical_memory_scale(void) {
         uint64_t p;
 
+        log_info("/* %s */", __func__);
+
         p = physical_memory();
 
         assert_se(physical_memory_scale(0, 100) == 0);
@@ -298,6 +335,8 @@ static void test_physical_memory_scale(void) {
 static void test_system_tasks_max(void) {
         uint64_t t;
 
+        log_info("/* %s */", __func__);
+
         t = system_tasks_max();
         assert_se(t > 0);
         assert_se(t < UINT64_MAX);
@@ -308,6 +347,8 @@ static void test_system_tasks_max(void) {
 static void test_system_tasks_max_scale(void) {
         uint64_t t;
 
+        log_info("/* %s */", __func__);
+
         t = system_tasks_max();
 
         assert_se(system_tasks_max_scale(0, 100) == 0);
@@ -333,8 +374,7 @@ static void test_system_tasks_max_scale(void) {
 }
 
 int main(int argc, char *argv[]) {
-        log_parse_environment();
-        log_open();
+        test_setup_logging(LOG_INFO);
 
         test_align_power2();
         test_max();
@@ -344,6 +384,7 @@ int main(int argc, char *argv[]) {
         test_protect_errno();
         test_in_set();
         test_log2i();
+        test_eqzero();
         test_raw_clone();
         test_physical_memory();
         test_physical_memory_scale();
index 1897f97a0454c43e76f93d9c3811e85cc5f1dbba..177b273e48694d0049256b7add6bf50eadedfcea 100644 (file)
@@ -56,24 +56,64 @@ static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
         [NET_DEV_FEAT_TSO6] = "tx-tcp6-segmentation",
 };
 
-static const char* const advertise_table[_NET_DEV_ADVERTISE_MAX] = {
-        [NET_DEV_ADVERTISE_10BASET_HALF]        = "10baset-half",
-        [NET_DEV_ADVERTISE_10BASET_FULL]        = "10baset-full",
-        [NET_DEV_ADVERTISE_100BASET_HALF]       = "100baset-half",
-        [NET_DEV_ADVERTISE_100BASET_FULL]       = "100baset-full",
-        [NET_DEV_ADVERTISE_1000BASET_HALF]      = "1000baset-half",
-        [NET_DEV_ADVERTISE_1000BASET_FULL]      = "1000baset-full",
-        [NET_DEV_ADVERTISE_10000BASET_FULL]     = "10000baset-full",
-        [NET_DEV_ADVERTISE_2500BASEX_FULL]      = "2500basex-full",
-        [NET_DEV_ADVERTISE_1000BASEKX_FULL]     = "1000basekx-full",
-        [NET_DEV_ADVERTISE_10000BASEKX4_FULL]   = "10000basekx4-full",
-        [NET_DEV_ADVERTISE_10000BASEKR_FULL]    = "10000basekr-full",
-        [NET_DEV_ADVERTISE_10000BASER_FEC]      = "10000baser-fec",
-        [NET_DEV_ADVERTISE_20000BASEMLD2_Full]  = "20000basemld2-full",
-        [NET_DEV_ADVERTISE_20000BASEKR2_Full]   = "20000basekr2-full",
+static const char* const ethtool_link_mode_bit_table[] = {
+        [ETHTOOL_LINK_MODE_10baseT_Half_BIT]           = "10baset-half",
+        [ETHTOOL_LINK_MODE_10baseT_Full_BIT]           = "10baset-full",
+        [ETHTOOL_LINK_MODE_100baseT_Half_BIT]          = "100baset-half",
+        [ETHTOOL_LINK_MODE_100baseT_Full_BIT]          = "100baset-full",
+        [ETHTOOL_LINK_MODE_1000baseT_Half_BIT]         = "1000baset-half",
+        [ETHTOOL_LINK_MODE_1000baseT_Full_BIT]         = "1000baset-full",
+        [ETHTOOL_LINK_MODE_Autoneg_BIT]                = "autonegotiation",
+        [ETHTOOL_LINK_MODE_TP_BIT]                     = "tp",
+        [ETHTOOL_LINK_MODE_AUI_BIT]                    = "aui",
+        [ETHTOOL_LINK_MODE_MII_BIT]                    = "mii",
+        [ETHTOOL_LINK_MODE_FIBRE_BIT]                  = "fibre",
+        [ETHTOOL_LINK_MODE_BNC_BIT]                    = "bnc",
+        [ETHTOOL_LINK_MODE_10000baseT_Full_BIT]        = "10000baset-full",
+        [ETHTOOL_LINK_MODE_Pause_BIT]                  = "pause",
+        [ETHTOOL_LINK_MODE_Asym_Pause_BIT]             = "asym-pause",
+        [ETHTOOL_LINK_MODE_2500baseX_Full_BIT]         = "2500basex-full",
+        [ETHTOOL_LINK_MODE_Backplane_BIT]              = "backplane",
+        [ETHTOOL_LINK_MODE_1000baseKX_Full_BIT]        = "1000basekx-full",
+        [ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT]      = "10000basekx4-full",
+        [ETHTOOL_LINK_MODE_10000baseKR_Full_BIT]       = "10000basekr-full",
+        [ETHTOOL_LINK_MODE_10000baseR_FEC_BIT]         = "10000baser-fec",
+        [ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT]     = "20000basemld2-full",
+        [ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT]      = "20000basekr2-full",
+        [ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT]      = "40000basekr4-full",
+        [ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT]      = "40000basecr4-full",
+        [ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT]      = "40000basesr4-full",
+        [ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT]      = "40000baselr4-full",
+        [ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT]      = "56000basekr4-full",
+        [ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT]      = "56000basecr4-full",
+        [ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT]      = "56000basesr4-full",
+        [ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT]      = "56000baselr4-full",
+        [ETHTOOL_LINK_MODE_25000baseCR_Full_BIT]       = "25000basecr-full",
+        [ETHTOOL_LINK_MODE_25000baseKR_Full_BIT]       = "25000basekr-full",
+        [ETHTOOL_LINK_MODE_25000baseSR_Full_BIT]       = "25000basesr-full",
+        [ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT]      = "50000basecr2-full",
+        [ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT]      = "50000basekr2-full",
+        [ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT]     = "100000basekr4-full",
+        [ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT]     = "100000basesr4-full",
+        [ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT]     = "100000basecr4-full",
+        [ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT] = "100000baselr4-er4-full",
+        [ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT]      = "50000basesr2-full",
+        [ETHTOOL_LINK_MODE_1000baseX_Full_BIT]         = "1000basex-full",
+        [ETHTOOL_LINK_MODE_10000baseCR_Full_BIT]       = "10000basecr-full",
+        [ETHTOOL_LINK_MODE_10000baseSR_Full_BIT]       = "10000basesr-full",
+        [ETHTOOL_LINK_MODE_10000baseLR_Full_BIT]       = "10000baselr-full",
+        [ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT]      = "10000baselrm-full",
+        [ETHTOOL_LINK_MODE_10000baseER_Full_BIT]       = "10000baseer-full",
+        [ETHTOOL_LINK_MODE_2500baseT_Full_BIT]         = "2500baset-full",
+        [ETHTOOL_LINK_MODE_5000baseT_Full_BIT]         = "5000baset-full",
+        [ETHTOOL_LINK_MODE_FEC_NONE_BIT]               = "fec-none",
+        [ETHTOOL_LINK_MODE_FEC_RS_BIT]                 = "fec-rs",
+        [ETHTOOL_LINK_MODE_FEC_BASER_BIT]              = "fec-baser",
 };
+/* Make sure the array is large enough to fit all bits */
+assert_cc((ELEMENTSOF(ethtool_link_mode_bit_table)-1) / 32 < ELEMENTSOF(((struct link_config){}).advertise));
 
-DEFINE_STRING_TABLE_LOOKUP(advertise, NetDevAdvertise);
+DEFINE_STRING_TABLE_LOOKUP(ethtool_link_mode_bit, enum ethtool_link_mode_bit_indices);
 
 int ethtool_connect(int *ret) {
         int fd;
@@ -574,11 +614,10 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l
 
         u->base.autoneg = link->autonegotiation;
 
-        if (link->advertise) {
-                uint32_t advertise[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] = {};
-
-                advertise[0] = link->advertise;
-                memcpy(&u->link_modes.advertising, advertise, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
+        if (!eqzero(link->advertise)) {
+                memcpy(&u->link_modes.advertising, link->advertise, sizeof(link->advertise));
+                memzero((uint8_t*) &u->link_modes.advertising + sizeof(link->advertise),
+                        ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES - sizeof(link->advertise));
         }
 
         if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
@@ -704,7 +743,6 @@ int config_parse_advertise(const char *unit,
                            void *data,
                            void *userdata) {
         link_config *config = data;
-        NetDevAdvertise mode, a = 0;
         const char *p;
         int r;
 
@@ -716,12 +754,13 @@ int config_parse_advertise(const char *unit,
 
         if (isempty(rvalue)) {
                 /* Empty string resets the value. */
-                config->advertise = 0;
+                zero(config->advertise);
                 return 0;
         }
 
         for (p = rvalue;;) {
                 _cleanup_free_ char *w = NULL;
+                enum ethtool_link_mode_bit_indices mode;
 
                 r = extract_first_word(&p, &w, NULL, 0);
                 if (r == -ENOMEM)
@@ -733,15 +772,14 @@ int config_parse_advertise(const char *unit,
                 if (r == 0)
                         break;
 
-                mode = advertise_from_string(w);
-                if (mode == _NET_DEV_ADVERTISE_INVALID) {
+                mode = ethtool_link_mode_bit_from_string(w);
+                if (mode < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse advertise mode, ignoring: %s", w);
                         continue;
                 }
-                a |= mode;
-        }
 
-        config->advertise |= a;
+                config->advertise[mode / 32] |= 1UL << (mode % 32);
+        }
 
         return 0;
 }
index 73c4d447d1c3997f40f7aeebd96135bad304c7e2..93d4ea4d3f38046a8ad09fc7ec8a252cc4396d97 100644 (file)
@@ -54,25 +54,6 @@ typedef enum NetDevPort {
         _NET_DEV_PORT_INVALID = -1
 } NetDevPort;
 
-typedef enum NetDevAdvertise {
-        NET_DEV_ADVERTISE_10BASET_HALF        =  1 << ETHTOOL_LINK_MODE_10baseT_Half_BIT,
-        NET_DEV_ADVERTISE_10BASET_FULL        =  1 << ETHTOOL_LINK_MODE_10baseT_Full_BIT,
-        NET_DEV_ADVERTISE_100BASET_HALF       =  1 << ETHTOOL_LINK_MODE_100baseT_Half_BIT,
-        NET_DEV_ADVERTISE_100BASET_FULL       =  1 << ETHTOOL_LINK_MODE_100baseT_Full_BIT,
-        NET_DEV_ADVERTISE_1000BASET_HALF      =  1 << ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
-        NET_DEV_ADVERTISE_1000BASET_FULL      =  1 << ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
-        NET_DEV_ADVERTISE_10000BASET_FULL     =  1 << ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-        NET_DEV_ADVERTISE_2500BASEX_FULL      =  1 << ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
-        NET_DEV_ADVERTISE_1000BASEKX_FULL     =  1 << ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
-        NET_DEV_ADVERTISE_10000BASEKX4_FULL   =  1 << ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
-        NET_DEV_ADVERTISE_10000BASEKR_FULL    =  1 << ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
-        NET_DEV_ADVERTISE_10000BASER_FEC      =  1 << ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
-        NET_DEV_ADVERTISE_20000BASEMLD2_Full  =  1 << ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,
-        NET_DEV_ADVERTISE_20000BASEKR2_Full   =  1 << ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
-        _NET_DEV_ADVERTISE_MAX,
-        _NET_DEV_ADVERTISE_INVALID = -1,
-} NetDevAdvertise;
-
 #define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32    (SCHAR_MAX)
 #define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES  (4 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32)
 
@@ -117,8 +98,8 @@ WakeOnLan wol_from_string(const char *wol) _pure_;
 const char *port_to_string(NetDevPort port) _const_;
 NetDevPort port_from_string(const char *port) _pure_;
 
-const char *advertise_to_string(NetDevAdvertise advertise) _const_;
-NetDevAdvertise advertise_from_string(const char *advertise) _pure_;
+const char *ethtool_link_mode_bit_to_string(enum ethtool_link_mode_bit_indices val) _const_;
+enum ethtool_link_mode_bit_indices ethtool_link_mode_bit_from_string(const char *str) _pure_;
 
 CONFIG_PARSER_PROTOTYPE(config_parse_duplex);
 CONFIG_PARSER_PROTOTYPE(config_parse_wol);
index b9c95e6139b8c706afe77b4c2fd825b1fa8483ee..becaffe0d6cb2911749f8579cb1700d332c2baa8 100644 (file)
@@ -372,11 +372,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                 if (config->port != _NET_DEV_PORT_INVALID)
                         log_warning_errno(r,  "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
 
-                if (config->advertise)
-                        log_warning_errno(r, "Could not set advertise mode to 0x%X: %m", config->advertise);
+                if (!eqzero(config->advertise))
+                        log_warning_errno(r, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */
 
                 if (config->speed) {
-
                         speed = DIV_ROUND_UP(config->speed, 1000000);
                         if (r == -EOPNOTSUPP) {
                                 r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
index 88e3651b7bbb7391a3aea825fb6c13e8bebd0993..820495903462d7873532658be6d890b894c0e769 100644 (file)
@@ -55,7 +55,7 @@ struct link_config {
         size_t speed;
         Duplex duplex;
         int autonegotiation;
-        uint32_t advertise;
+        uint32_t advertise[2];
         WakeOnLan wol;
         NetDevPort port;
         int features[_NET_DEV_FEAT_MAX];
index aebedca348491e19b95e3ddf36e5470547816818..c790b9d04bb7cb6a59494871a346f435b37fcfcd 100644 (file)
@@ -5,3 +5,4 @@ Description=Daughter Service
 Slice=parent.slice
 Type=oneshot
 ExecStart=/bin/true
+CPUAccounting=true
diff --git a/test/fuzz/fuzz-journald-audit/basic b/test/fuzz/fuzz-journald-audit/basic
new file mode 100644 (file)
index 0000000..d1ce8cc
--- /dev/null
@@ -0,0 +1 @@
+audit(1542398162.211:744): pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
\ No newline at end of file
diff --git a/test/fuzz/fuzz-journald-audit/crash b/test/fuzz/fuzz-journald-audit/crash
new file mode 100644 (file)
index 0000000..91bd85c
--- /dev/null
@@ -0,0 +1 @@
+audit(1542398162.211:744) pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
index 456f06951acbc3cd8aca7842e2ef2fbc2dd4f1c2..8b672fcecbc88083b5030f3da787cb16a22bce75 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for basic execution
 
 [Service]
-ExecStart=touch /tmp/a ; /bin/touch /tmp/b ; touch /tmp/c
+ExecStart=touch /tmp/a ; /bin/sh -c 'touch /tmp/b' ; touch /tmp/c
 ExecStart=test -f /tmp/a
 ExecStart=!test -f /tmp/b
 ExecStart=!!test -f /tmp/c
index 077595c482a20a04b0b6eaed9d4de654328dab81..09122f723231d4e2c442a35cad4f6373be323087 100755 (executable)
@@ -57,7 +57,11 @@ for phase in "${PHASES[@]}"; do
             $DOCKER_EXEC ninja -v -C build
 
             # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
-            travis_wait docker exec --interactive=false -t $CONT_NAME sh -c "UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs"
+            travis_wait docker exec --interactive=false \
+                -e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \
+                -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \
+                -t $CONT_NAME \
+                meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
             ;;
         CLEANUP)
             info "Cleanup phase"
index 3de9b9b0cde2132b65dfeff531e40671f9439343..acf6ad15e461bfeadaa11b66d87cfbdffc58b660 100644 (file)
@@ -41,9 +41,11 @@ travis_wait() {
   local result
 
   {
+    set +e
     wait "${cmd_pid}" 2>/dev/null
     result="${?}"
     ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}"
+    set -e
   }
 
   if [[ "${result}" -eq 0 ]]; then