if we need to hibernate/suspend-then-hibernate/hybrid-sleep due to keypress/lid switch but can't, fallback to regular suspend
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@
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
<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>
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)
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/types.h>
+#include <sys/utsname.h>
#include <sys/xattr.h>
#include <unistd.h>
};
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;
+}
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)
#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)
#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"
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;
#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;
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;
/* 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) ||
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;
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;
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);
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);
#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"
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;
{ "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 },
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;
--- /dev/null
+/* 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;
+}
/* 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;
#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;
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);
}
#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,
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]],
}
}
-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;
if (!p)
return;
+ k = 0;
if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n",
&seconds,
&msec,
&id,
- &k) != 3)
+ &k) != 3 || k == 0)
return;
p += k;
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);
#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) {
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;
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;
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;
r = lookup(table, section, lvalue, &func, <ype, &data, userdata);
if (r < 0)
return r;
-
if (r > 0) {
if (func)
return func(unit, filename, line, section, section_line,
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;
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;
+}
#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)
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;
}
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);
}
}
#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);
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
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);
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);
}
static void test_u64log2(void) {
+ log_info("/* %s */", __func__);
+
assert_se(u64log2(0) == 0);
assert_se(u64log2(8) == 3);
assert_se(u64log2(9) == 3);
}
static void test_protect_errno(void) {
+ log_info("/* %s */", __func__);
+
errno = 12;
{
PROTECT_ERRNO;
}
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));
}
static void test_log2i(void) {
+ log_info("/* %s */", __func__);
+
assert_se(log2i(1) == 0);
assert_se(log2i(2) == 1);
assert_se(log2i(3) == 1);
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);
uint64_t p;
char buf[FORMAT_BYTES_MAX];
+ log_info("/* %s */", __func__);
+
p = physical_memory();
assert_se(p > 0);
assert_se(p < UINT64_MAX);
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);
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);
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);
}
int main(int argc, char *argv[]) {
- log_parse_environment();
- log_open();
+ test_setup_logging(LOG_INFO);
test_align_power2();
test_max();
test_protect_errno();
test_in_set();
test_log2i();
+ test_eqzero();
test_raw_clone();
test_physical_memory();
test_physical_memory_scale();
[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;
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)
void *data,
void *userdata) {
link_config *config = data;
- NetDevAdvertise mode, a = 0;
const char *p;
int r;
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)
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;
}
_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)
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);
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);
size_t speed;
Duplex duplex;
int autonegotiation;
- uint32_t advertise;
+ uint32_t advertise[2];
WakeOnLan wol;
NetDevPort port;
int features[_NET_DEV_FEAT_MAX];
Slice=parent.slice
Type=oneshot
ExecStart=/bin/true
+CPUAccounting=true
--- /dev/null
+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
--- /dev/null
+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'
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
$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"
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