Merge ~enr0n/ubuntu/+source/systemd:ubuntu-lunar-next into ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-lunar

Proposed by Nick Rosbrook
Status: Merged
Approved by: Lukas Märdian
Approved revision: e6a635d5dc87ed271d30e6bec1edd03d29525b0c
Merged at revision: e6a635d5dc87ed271d30e6bec1edd03d29525b0c
Proposed branch: ~enr0n/ubuntu/+source/systemd:ubuntu-lunar-next
Merge into: ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-lunar
Diff against target: 5254 lines (+1754/-807)
121 files modified
.packit.yml (+5/-0)
debian/changelog (+105/-0)
debian/control (+4/-15)
debian/patches/Deny-list-TEST-74-AUX-UTILS-on-s390x.patch (+16/-0)
debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch (+3/-3)
debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch (+2/-0)
debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch (+1/-1)
debian/patches/lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch (+72/-0)
debian/patches/lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch (+62/-0)
debian/patches/lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch (+64/-0)
debian/patches/lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch (+48/-0)
debian/patches/lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch (+63/-0)
debian/patches/lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch (+34/-0)
debian/patches/p11kit-switch-to-dlopen.patch (+3/-3)
debian/patches/series (+7/-3)
debian/rules (+1/-0)
debian/tests/boot-and-services (+2/-2)
debian/tests/control (+13/-8)
dev/null (+0/-323)
man/org.freedesktop.systemd1.xml (+6/-0)
man/systemd.mount.xml (+3/-1)
man/systemd.scope.xml (+2/-0)
man/systemd.service.xml (+9/-11)
src/basic/alloc-util.c (+4/-0)
src/basic/alloc-util.h (+29/-10)
src/basic/cgroup-util.c (+1/-1)
src/basic/hashmap.c (+1/-1)
src/basic/linux/README (+1/-0)
src/basic/linux/btrfs.h (+50/-12)
src/basic/linux/btrfs_tree.h (+240/-1)
src/basic/linux/genetlink.h (+3/-2)
src/basic/linux/if_bridge.h (+21/-0)
src/basic/linux/if_ether.h (+2/-0)
src/basic/linux/if_link.h (+16/-0)
src/basic/linux/if_macsec.h (+2/-0)
src/basic/linux/if_tun.h (+5/-1)
src/basic/linux/in.h (+9/-14)
src/basic/linux/l2tp.h (+0/-2)
src/basic/linux/netfilter/nf_tables.h (+29/-0)
src/basic/linux/netlink.h (+24/-7)
src/basic/linux/nl80211.h (+128/-7)
src/basic/linux/pkt_sched.h (+11/-0)
src/basic/linux/rtnetlink.h (+1/-1)
src/basic/linux/stddef.h (+46/-0)
src/basic/linux/update.sh (+1/-1)
src/basic/virt.c (+1/-1)
src/boot/efi/boot.c (+5/-2)
src/boot/efi/console.c (+0/-16)
src/boot/efi/cpio.c (+1/-1)
src/boot/efi/meson.build (+11/-2)
src/boot/efi/missing_efi.h (+0/-19)
src/boot/efi/secure-boot.c (+1/-1)
src/boot/efi/util.c (+5/-3)
src/busctl/busctl.c (+19/-2)
src/core/cgroup.c (+1/-1)
src/core/cgroup.h (+1/-0)
src/core/dbus-scope.c (+6/-0)
src/core/execute.c (+17/-0)
src/core/execute.h (+1/-0)
src/core/import-creds.c (+7/-0)
src/core/load-fragment-gperf.gperf.in (+1/-0)
src/core/mount.c (+18/-3)
src/core/scope.c (+20/-3)
src/core/scope.h (+2/-0)
src/core/slice.c (+3/-0)
src/core/swap.c (+1/-1)
src/core/unit.c (+1/-0)
src/cryptsetup/cryptsetup-fido2.c (+72/-57)
src/cryptsetup/cryptsetup-fido2.h (+24/-16)
src/cryptsetup/cryptsetup.c (+27/-42)
src/fundamental/macro-fundamental.h (+1/-0)
src/gpt-auto-generator/gpt-auto-generator.c (+5/-5)
src/import/curl-util.c (+4/-0)
src/import/pull-job.c (+5/-5)
src/journal-remote/microhttpd-util.h (+2/-2)
src/kernel-install/50-depmod.install (+2/-0)
src/libsystemd-network/sd-dhcp-client.c (+18/-20)
src/libsystemd-network/sd-dhcp-lease.c (+4/-4)
src/libsystemd-network/test-ndisc-ra.c (+6/-14)
src/libsystemd-network/test-ndisc-rs.c (+8/-13)
src/libsystemd/sd-device/test-sd-device.c (+8/-7)
src/libsystemd/sd-event/sd-event.c (+6/-1)
src/locale/localed.c (+8/-12)
src/login/logind-dbus.c (+6/-0)
src/network/netdev/l2tp-tunnel.c (+5/-5)
src/network/networkd-address.c (+5/-1)
src/network/networkd-ndisc.c (+11/-10)
src/network/networkd-route.c (+5/-1)
src/nspawn/nspawn-patch-uid.c (+3/-1)
src/partition/growfs.c (+6/-1)
src/resolve/resolvectl.c (+3/-3)
src/resolve/resolved-dns-scope.c (+2/-1)
src/resolve/resolved-dns-search-domain.c (+1/-1)
src/resolve/resolved-dns-server.h (+2/-2)
src/resolve/resolved-varlink.c (+2/-2)
src/shared/bootspec.c (+5/-3)
src/shared/bus-unit-util.c (+3/-0)
src/shared/creds-util.c (+16/-20)
src/shared/generator.c (+10/-1)
src/shared/install.c (+8/-3)
src/shared/install.h (+2/-2)
src/shared/mount-setup.c (+2/-0)
src/shared/sleep-config.c (+15/-17)
src/sleep/sleep.c (+6/-2)
src/test/test-execute.c (+3/-0)
src/test/test-unit-name.c (+3/-1)
src/tmpfiles/tmpfiles.c (+5/-2)
test/TEST-55-OOMD/test.sh (+6/-0)
test/fuzz/fuzz-unit-file/directives.scope (+1/-0)
test/test-functions (+16/-0)
test/test-network/conf/23-bond199.network (+0/-3)
test/test-network/systemd-networkd-tests.py (+19/-3)
test/test-shutdown.py (+1/-1)
test/units/testsuite-26.sh (+1/-1)
test/units/testsuite-55.sh (+3/-0)
test/units/testsuite-64.sh (+6/-5)
test/units/testsuite-65.sh (+10/-0)
test/units/testsuite-73.sh (+14/-3)
test/units/testsuite-74.firstboot.sh (+54/-15)
test/units/testsuite-75.sh (+22/-13)
units/systemd-userdbd.service.in (+1/-1)
Reviewer Review Type Date Requested Status
Lukas Märdian Approve
Review via email: mp+437150@code.launchpad.net

Description of the change

Merge 252.5-2 from Debian unstable, and cherry-pick udev NIC renaming patches for bug 2002445.

PPA build: https://launchpad.net/~enr0n/+archive/ubuntu/systemd/+packages?field.name_filter=systemd&field.status_filter=published&field.series_filter=

autopkgtest:

systemd 252.5-2ubuntu1~ppa2 (ppc64el) -- Pass: https://autopkgtest.staging.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/ppc64el/s/systemd/20230209_190022_7d72f@/log.gz
systemd 252.5-2ubuntu1~ppa2 (s390x) -- Fail: https://autopkgtest.staging.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/s390x/s/systemd/20230209_201045_7d72f@/log.gz
systemd 252.5-2ubuntu1~ppa2 (amd64) -- Pass: https://autopkgtest.staging.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/amd64/s/systemd/20230209_203135_7d72f@/log.gz
systemd 252.5-2ubuntu1~ppa2 (arm64) -- Pass: https://autopkgtest.staging.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/arm64/s/systemd/20230210_060852_7d72f@/log.gz

It looks like armhf wasn't triggered on staging, but the previous PPA build passed for armhf:

systemd 252.5-2ubuntu1~ppa1 (armhf) -- Pass: https://autopkgtest.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/armhf/s/systemd/20230206_220736_e68eb@/log.gz

I think the s390x failure is flaky. I could not reproduce it in Canonistack, it passed just fine. Also, a previous run on arm64 failed with the same thing, but then passed the next run.

To post a comment you must log in.
Revision history for this message
Nick Rosbrook (enr0n) wrote (last edit ):

We tried the s390x test again in staging, and it still failed: https://autopkgtest.staging.ubuntu.com/results/autopkgtest-lunar-enr0n-systemd/lunar/s390x/s/systemd/20230210_182915_66bf1@/log.gz.

I will try again on Canonistack, but if I can't reproduce it maybe we should skip this test on s390x for now.

Revision history for this message
Lukas Märdian (slyon) wrote :

Thank you for preparing another upload, Nick!

I verified it matches upstream v252.5 and the cherry-picked patches match upstream, too. Kudos for dropping the (unused) systemd-fsckd autopkgtest in Debian!

* d/rules: The "-Dstatus-unit-format-default=combined" flag seems to be a change in behavior (for people parsing the log files...). It seems to be a sensible change, but maybe we should document it somewhere, especially how people could roll it back at runtime, by using a "[Manager] StatusUnitFormat=description" configuration (https://fedoraproject.org/wiki/Changes/Unit_Names_in_Systemd_Messages)

* I'm a bit concerned about the TEST-74-AUX-UTILS. It seems to be a real regression, as that one passed in previous build on s390x. It was touched in "252.4-2" and we should check what/why was done there. The test does not run on Debian at all, so they might have missed this regression:

upstream SKIP Test restriction "isolation-machine" requires testbed capability "isolation-machine"

Let's see what you find from your Canonistack investigation. It passes on non-s390x... But I think the very least we should do is open a bug report with Debian and/or upstream about this failure, before skipping it on s390x.

Other than those remarks this LGTM.

Revision history for this message
Nick Rosbrook (enr0n) wrote :

Lukas and I discussed offline, and decided to skip TEST-74-AUX-UTILS on s390x for now. The test passes just fine on Canonistack s390x, so we think it may be a temporary infrastructure issue.

As for the other comment, I will make sure to mention this change in the Lunar Lobster release notes.

Revision history for this message
Lukas Märdian (slyon) wrote :

Thank you! +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.packit.yml b/.packit.yml
2index 1b49ddf..a226252 100644
3--- a/.packit.yml
4+++ b/.packit.yml
5@@ -29,6 +29,11 @@ actions:
6 # cases (see [0]), we can't use -Dc_args=/-Dcpp_args= here because of the
7 # RPM hardening macros, that use $CFLAGS/$CPPFLAGS (see [1]).
8 #
9+ # Remove ukify/new standalone handling, added in 253
10+ - "sed -i '/ukify/d' .packit_rpm/split-files.py"
11+ - "sed -i '/%files ukify/d' .packit_rpm/systemd.spec"
12+ - "sed -i '/%files standalone-repart/d' .packit_rpm/systemd.spec"
13+ - "sed -i '/%files standalone-shutdown/d' .packit_rpm/systemd.spec"
14 # [0] https://github.com/mesonbuild/meson/issues/7360
15 # [1] https://github.com/systemd/systemd/pull/18908#issuecomment-792250110
16 - 'sed -i "/^CONFIGURE_OPTS=(/a--werror" .packit_rpm/systemd.spec'
17diff --git a/debian/changelog b/debian/changelog
18index 8852311..2821604 100644
19--- a/debian/changelog
20+++ b/debian/changelog
21@@ -1,3 +1,108 @@
22+systemd (252.5-2ubuntu1) lunar; urgency=medium
23+
24+ * Merge 252.5-2 from Debian unstable
25+ - Drop test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch.
26+ Applied upstream: https://github.com/systemd/systemd/commit/9b42646b22
27+ File: debian/patches/test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch
28+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=1b0789416172ec60d8086fe2b458b5396bb7e857
29+ - Drop test-make-sure-mount-point-exists-in-testsuite-64.sh.patch.
30+ Applied upstream: https://github.com/systemd/systemd/commit/07e4787106
31+ File: debian/patches/test-make-sure-mount-point-exists-in-testsuite-64.sh.patch
32+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=f97b2d5ae1a1f35668c4648f1c7fc715a588de50
33+ - Drop test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch.
34+ Fixed upstream: https://github.com/systemd/systemd-stable/commit/1c325f6d7f
35+ File: debian/patches/test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch
36+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=5f85226d61393c08d7ea51c2f28db7fd4c79bcc6
37+ * udev: avoid NIC renaming race with kernel (LP: #2002445)
38+ Files:
39+ - debian/patches/lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch
40+ - debian/patches/lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch
41+ - debian/patches/lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch
42+ - debian/patches/lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch
43+ - debian/patches/lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch
44+ - debian/patches/lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch
45+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=58d29c2b376f03c44ed5a719877c95b332018cdc
46+ * Deny-list TEST-74-AUX-UTILS on s390x.
47+ Since this currently is only known to fail on the autopkgtest
48+ infrastructure, we believe this is a temporary issue.
49+ File: debian/patches/Deny-list-TEST-74-AUX-UTILS-on-s390x.patch
50+ https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/systemd/commit/?id=a3a059d86e2fe3a104419ae2afcab557171f9809
51+
52+ -- Nick Rosbrook <nick.rosbrook@canonical.com> Tue, 14 Feb 2023 11:52:31 -0500
53+
54+systemd (252.5-2) unstable; urgency=medium
55+
56+ * Fix boot-and-services autopkgtest.
57+
58+ -- Luca Boccassi <bluca@debian.org> Mon, 30 Jan 2023 01:03:48 +0000
59+
60+systemd (252.5-1) unstable; urgency=medium
61+
62+ [ Nick Rosbrook ]
63+ * debian/tests: remove systemd-fsckd autopkgtest. This test never runs
64+ in Debian autopkgtest because of missing machine isolation
65+ requirements, and it nevers runs in Ubuntu because: SKIP: root file
66+ system is being checked by initramfs already Since the test is not
67+ providing any good feedback, and generally has not been maintained,
68+ let's just remove it.
69+
70+ [ Luca Boccassi ]
71+ * New upstream version 252.5
72+ * Drop patches merged in v252.5
73+ * Refresh patches
74+ * Set default status format to 'combined': show both unit name and
75+ description in logs/boot messages
76+
77+ -- Luca Boccassi <bluca@debian.org> Sun, 29 Jan 2023 19:39:28 +0000
78+
79+systemd (252.4-2) unstable; urgency=medium
80+
81+ [ Michael Biebl ]
82+ * Refresh patches
83+ * Tweak description of systemd and systemd-sysv package.
84+ Remove redundancy and de-emphasize sysvinit.
85+ * autopkgtest: add psmsic to upstream suite.
86+ Needed for the killall binary.
87+ See https://github.com/systemd/systemd/pull/24569
88+ * autopkgtest: add xkb-data, locales and locales-all to upstream suite.
89+ Use locales-all so all necessary locales can be installed into the test
90+ image without having to generate them on-the-fly.
91+ See https://github.com/systemd/systemd/pull/23709
92+ * autopkgtest: prefer knot-dnssecutils over knot-dnsutils for upstream
93+ suite.
94+ The kzonecheck utility required by TEST-75-RESOLVED was split out from
95+ knot-dnsutils into knot-dnssecutils so update the test dependencies
96+ accordingly. Keep knot-dnsutils as alternative dependency to make
97+ backports easier.
98+ * Cherry-pick upstream fixes for TEST-74-AUX-UTILS
99+ * Cherry-pick upstream fix for TEST-73-LOCALE
100+ * Skip firstboot --prompt-keymap check in TEST-74-AUX-UTILS.
101+ This test requires compatible keymaps from kbd which are not available
102+ in Debian.
103+
104+ [ Luca Boccassi ]
105+ * autopkgtest: add netlabel-tools to networkd-test.py suite.
106+ The netlabelctl tool is needed to test the NetLabel integration.
107+ See https://github.com/systemd/systemd/pull/23888
108+ * autopkgtest: add bsdutils to upstream suite.
109+ The logger utility is now used in TEST-04-JOURNAL.
110+ See https://github.com/systemd/systemd/pull/23086
111+ * autopkgtest: add knot, knot-dnsutils, bind9-dnsutils, bind9-host to
112+ upstream suite.
113+ Needed by TEST-75-RESOLVED.
114+ See https://github.com/systemd/systemd/pull/23104
115+ * autopkgtest: add jq to upstream suite.
116+ Needed by TEST-58-REPART.
117+ See https://github.com/systemd/systemd/pull/24572
118+ * autopkgtest: add mtools to upstream suite.
119+ Needed by TEST-58-REPART.
120+ See https://github.com/systemd/systemd/pull/24944
121+ * autopkgtest: add erofs-utils to upstream suite.
122+ Needed by TEST-58-REPART.
123+ See https://github.com/systemd/systemd/pull/25686
124+
125+ -- Michael Biebl <biebl@debian.org> Wed, 25 Jan 2023 09:17:24 +0100
126+
127 systemd (252.4-1ubuntu1) lunar; urgency=medium
128
129 * Drop oomd-fix-unreachable-test-case-in-test-oomd-util.patch.
130diff --git a/debian/control b/debian/control
131index 812a8c5..c84c218 100644
132--- a/debian/control
133+++ b/debian/control
134@@ -118,9 +118,6 @@ Description: system and service manager
135 Linux control groups, maintains mount and automount points and implements an
136 elaborate transactional dependency-based service control logic.
137 .
138- systemd is compatible with SysV and LSB init scripts and can work as a
139- drop-in replacement for sysvinit.
140- .
141 Installing the systemd package will not switch your init system unless you
142 boot with init=/lib/systemd/systemd or install systemd-sysv in addition.
143
144@@ -137,19 +134,11 @@ Depends: systemd (= ${binary:Version}),
145 ${misc:Depends}
146 Recommends: libpam-systemd,
147 libnss-systemd
148-Description: system and service manager - SysV links
149- systemd is a system and service manager for Linux. It provides aggressive
150- parallelization capabilities, uses socket and D-Bus activation for starting
151- services, offers on-demand starting of daemons, keeps track of processes using
152- Linux control groups, maintains mount and automount points and implements an
153- elaborate transactional dependency-based service control logic.
154- .
155- systemd is compatible with SysV and LSB init scripts and can work as a
156- drop-in replacement for sysvinit.
157+Description: system and service manager - SysV compatibility symlinks
158+ This package provides manual pages and compatibility symlinks needed for
159+ systemd to replace sysvinit.
160 .
161- This package provides the manual pages and links needed for systemd
162- to replace sysvinit. Installing systemd-sysv will overwrite /sbin/init with a
163- link to systemd.
164+ Installing systemd-sysv will overwrite /sbin/init with a symlink to systemd.
165
166 Package: systemd-container
167 Build-Profiles: <!stage1>
168diff --git a/debian/patches/Deny-list-TEST-74-AUX-UTILS-on-s390x.patch b/debian/patches/Deny-list-TEST-74-AUX-UTILS-on-s390x.patch
169new file mode 100644
170index 0000000..f230a88
171--- /dev/null
172+++ b/debian/patches/Deny-list-TEST-74-AUX-UTILS-on-s390x.patch
173@@ -0,0 +1,16 @@
174+From: Nick Rosbrook <nick.rosbrook@canonical.com>
175+Date: Tue, 14 Feb 2023 11:43:42 -0500
176+Subject: Deny-list TEST-74-AUX-UTILS on s390x
177+
178+---
179+ test/TEST-74-AUX-UTILS/deny-list-upstream-ci-s390x | 1 +
180+ 1 file changed, 1 insertion(+)
181+ create mode 100644 test/TEST-74-AUX-UTILS/deny-list-upstream-ci-s390x
182+
183+diff --git a/test/TEST-74-AUX-UTILS/deny-list-upstream-ci-s390x b/test/TEST-74-AUX-UTILS/deny-list-upstream-ci-s390x
184+new file mode 100644
185+index 0000000..b7bd53b
186+--- /dev/null
187++++ b/test/TEST-74-AUX-UTILS/deny-list-upstream-ci-s390x
188+@@ -0,0 +1 @@
189++# Currently failing on autopkgtest infra, but appears to be a temporary issue.
190diff --git a/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch b/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch
191index 29b6fa8..7f02cc3 100644
192--- a/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch
193+++ b/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch
194@@ -51,10 +51,10 @@ index 3c5df6c..24eff86 100644
195 "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath);
196
197 diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
198-index 18bb757..1f60913 100644
199+index 3501ccf..d8423dd 100644
200 --- a/src/tmpfiles/tmpfiles.c
201 +++ b/src/tmpfiles/tmpfiles.c
202-@@ -2987,6 +2987,7 @@ static int specifier_expansion_from_arg(const Specifier *specifier_table, Item *
203+@@ -2990,6 +2990,7 @@ static int specifier_expansion_from_arg(const Specifier *specifier_table, Item *
204 static int patch_var_run(const char *fname, unsigned line, char **path) {
205 const char *k;
206 char *n;
207@@ -62,7 +62,7 @@ index 18bb757..1f60913 100644
208
209 assert(path);
210 assert(*path);
211-@@ -3012,7 +3013,8 @@ static int patch_var_run(const char *fname, unsigned line, char **path) {
212+@@ -3015,7 +3016,8 @@ static int patch_var_run(const char *fname, unsigned line, char **path) {
213 /* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence
214 * there's no immediate need for action by the user. However, in the interest of making things less confusing
215 * to the user, let's still inform the user that these snippets should really be updated. */
216diff --git a/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch b/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch
217index 6f4d2ac..4ab8117 100644
218--- a/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch
219+++ b/debian/patches/debian/Make-run-lock-tmpfs-an-API-fs.patch
220@@ -15,6 +15,8 @@ Closes: #751392
221 tmpfiles.d/legacy.conf.in | 1 -
222 2 files changed, 2 insertions(+), 1 deletion(-)
223
224+diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c
225+index 6882b62..c54e632 100644
226 --- a/src/shared/mount-setup.c
227 +++ b/src/shared/mount-setup.c
228 @@ -86,6 +86,8 @@
229diff --git a/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch b/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch
230index 0410005..deafad8 100644
231--- a/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch
232+++ b/debian/patches/debian/Revert-core-one-step-back-again-for-nspawn-we-actual.patch
233@@ -14,7 +14,7 @@ Bug-Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1141137
234 1 file changed, 1 insertion(+), 10 deletions(-)
235
236 diff --git a/src/core/unit.c b/src/core/unit.c
237-index bed5544..48d76f2 100644
238+index 3ac56c1..3b73c7c 100644
239 --- a/src/core/unit.c
240 +++ b/src/core/unit.c
241 @@ -4615,16 +4615,7 @@ int unit_kill_context(
242diff --git a/debian/patches/lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch b/debian/patches/lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch
243new file mode 100644
244index 0000000..8d9f0b3
245--- /dev/null
246+++ b/debian/patches/lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch
247@@ -0,0 +1,72 @@
248+From: Nick Rosbrook <nick.rosbrook@canonical.com>
249+Date: Tue, 22 Nov 2022 17:01:47 -0500
250+Subject: sd-netlink: add a test for rtnl_set_link_name()
251+
252+Origin: upstream, https://github.com/systemd/systemd/commit/b338a8bb40
253+Bug-Ubuntu: https://launchpad.net/bugs/2002445
254+
255+Add a test that verifies a deleted alternative name is restored on error
256+in rtnl_set_link_name().
257+---
258+ src/libsystemd/sd-netlink/test-netlink.c | 27 +++++++++++++++++++++++++++
259+ 1 file changed, 27 insertions(+)
260+
261+diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
262+index 3f74ecc..2d93f9e 100644
263+--- a/src/libsystemd/sd-netlink/test-netlink.c
264++++ b/src/libsystemd/sd-netlink/test-netlink.c
265+@@ -8,6 +8,7 @@
266+ #include <linux/if_macsec.h>
267+ #include <linux/l2tp.h>
268+ #include <linux/nl80211.h>
269++#include <unistd.h>
270+
271+ #include "sd-netlink.h"
272+
273+@@ -16,6 +17,7 @@
274+ #include "macro.h"
275+ #include "netlink-genl.h"
276+ #include "netlink-internal.h"
277++#include "netlink-util.h"
278+ #include "socket-util.h"
279+ #include "stdio-util.h"
280+ #include "string-util.h"
281+@@ -667,6 +669,30 @@ static void test_genl(void) {
282+ }
283+ }
284+
285++static void test_rtnl_set_link_name(sd_netlink *rtnl, int ifindex) {
286++ _cleanup_strv_free_ char **alternative_names = NULL;
287++ int r;
288++
289++ log_debug("/* %s */", __func__);
290++
291++ if (geteuid() != 0)
292++ return (void) log_tests_skipped("not root");
293++
294++ /* Test that the new name (which is currently an alternative name) is
295++ * restored as an alternative name on error. Create an error by using
296++ * an invalid device name, namely one that exceeds IFNAMSIZ
297++ * (alternative names can exceed IFNAMSIZ, but not regular names). */
298++ r = rtnl_set_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"));
299++ if (r == -EPERM)
300++ return (void) log_tests_skipped("missing required capabilities");
301++
302++ assert_se(r >= 0);
303++ assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
304++ assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
305++ assert_se(strv_contains(alternative_names, "testlongalternativename"));
306++ assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
307++}
308++
309+ int main(void) {
310+ sd_netlink *rtnl;
311+ sd_netlink_message *m;
312+@@ -698,6 +724,7 @@ int main(void) {
313+ test_pipe(if_loopback);
314+ test_event_loop(if_loopback);
315+ test_link_configure(rtnl, if_loopback);
316++ test_rtnl_set_link_name(rtnl, if_loopback);
317+
318+ test_get_addresses(rtnl);
319+ test_message_link_bridge(rtnl);
320diff --git a/debian/patches/lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch b/debian/patches/lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch
321new file mode 100644
322index 0000000..2388bf2
323--- /dev/null
324+++ b/debian/patches/lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch
325@@ -0,0 +1,62 @@
326+From: Nick Rosbrook <nick.rosbrook@canonical.com>
327+Date: Fri, 2 Dec 2022 15:26:18 -0500
328+Subject: sd-netlink: do not swap old name and alternative name
329+
330+Origin: upstream, https://github.com/systemd/systemd/commit/080afbb57c
331+Bug-Ubuntu: https://launchpad.net/bugs/2002445
332+
333+Commit 434a348380 ("netlink: do not fail when new interface name is
334+already used as an alternative name") added logic to set the old
335+interface name as an alternative name, but only when the new name is
336+currently an alternative name. This is not the desired outcome in most
337+cases, and the important part of this commit was to delete the new name
338+from the list of alternative names if necessary.
339+---
340+ src/libsystemd/sd-netlink/netlink-util.c | 13 -------------
341+ 1 file changed, 13 deletions(-)
342+
343+diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
344+index 12cdc99..6b4c25f 100644
345+--- a/src/libsystemd/sd-netlink/netlink-util.c
346++++ b/src/libsystemd/sd-netlink/netlink-util.c
347+@@ -3,7 +3,6 @@
348+ #include "sd-netlink.h"
349+
350+ #include "fd-util.h"
351+-#include "format-util.h"
352+ #include "io-util.h"
353+ #include "memory-util.h"
354+ #include "netlink-internal.h"
355+@@ -15,7 +14,6 @@
356+ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
357+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
358+ _cleanup_strv_free_ char **alternative_names = NULL;
359+- char old_name[IF_NAMESIZE] = {};
360+ int r;
361+
362+ assert(rtnl);
363+@@ -35,10 +33,6 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
364+ if (r < 0)
365+ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
366+ name, ifindex);
367+-
368+- r = format_ifname(ifindex, old_name);
369+- if (r < 0)
370+- return log_debug_errno(r, "Failed to get current name of network interface %i: %m", ifindex);
371+ }
372+
373+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
374+@@ -53,13 +47,6 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
375+ if (r < 0)
376+ return r;
377+
378+- if (!isempty(old_name)) {
379+- r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
380+- if (r < 0)
381+- log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
382+- old_name, ifindex);
383+- }
384+-
385+ return 0;
386+ }
387+
388diff --git a/debian/patches/lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch b/debian/patches/lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch
389new file mode 100644
390index 0000000..07ca306
391--- /dev/null
392+++ b/debian/patches/lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch
393@@ -0,0 +1,64 @@
394+From: Nick Rosbrook <nick.rosbrook@canonical.com>
395+Date: Wed, 2 Nov 2022 05:36:14 -0400
396+Subject: sd-netlink: restore altname on error in rtnl_set_link_name
397+
398+Origin: upstream, https://github.com/systemd/systemd/commit/4d600667f8
399+Bug-Ubuntu: https://launchpad.net/bugs/2002445
400+
401+If a current alternative name is to be used to rename a network
402+interface, the alternative name must be removed first. If interface
403+renaming fails, restore the alternative name that was deleted if
404+necessary.
405+---
406+ src/libsystemd/sd-netlink/netlink-util.c | 19 ++++++++++++++++---
407+ 1 file changed, 16 insertions(+), 3 deletions(-)
408+
409+diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
410+index 6b4c25f..cfcf257 100644
411+--- a/src/libsystemd/sd-netlink/netlink-util.c
412++++ b/src/libsystemd/sd-netlink/netlink-util.c
413+@@ -14,6 +14,7 @@
414+ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
415+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
416+ _cleanup_strv_free_ char **alternative_names = NULL;
417++ bool altname_deleted = false;
418+ int r;
419+
420+ assert(rtnl);
421+@@ -33,21 +34,33 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
422+ if (r < 0)
423+ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
424+ name, ifindex);
425++
426++ altname_deleted = true;
427+ }
428+
429+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
430+ if (r < 0)
431+- return r;
432++ goto fail;
433+
434+ r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
435+ if (r < 0)
436+- return r;
437++ goto fail;
438+
439+ r = sd_netlink_call(*rtnl, message, 0, NULL);
440+ if (r < 0)
441+- return r;
442++ goto fail;
443+
444+ return 0;
445++
446++fail:
447++ if (altname_deleted) {
448++ int q = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
449++ if (q < 0)
450++ log_debug_errno(q, "Failed to restore '%s' as an alternative name on network interface %i, ignoring: %m",
451++ name, ifindex);
452++ }
453++
454++ return r;
455+ }
456+
457+ int rtnl_set_link_properties(
458diff --git a/debian/patches/lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch b/debian/patches/lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch
459new file mode 100644
460index 0000000..bea8407
461--- /dev/null
462+++ b/debian/patches/lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch
463@@ -0,0 +1,48 @@
464+From: Nick Rosbrook <nick.rosbrook@canonical.com>
465+Date: Wed, 7 Dec 2022 12:28:28 -0500
466+Subject: test-network: add a test for renaming device to current altname
467+
468+Origin: upstream, https://github.com/systemd/systemd/commit/f68f644a16
469+Bug-Ubuntu: https://launchpad.net/bugs/2002445
470+
471+---
472+ test/test-network/conf/12-dummy-rename-to-altname.link | 7 +++++++
473+ test/test-network/systemd-networkd-tests.py | 11 +++++++++++
474+ 2 files changed, 18 insertions(+)
475+ create mode 100644 test/test-network/conf/12-dummy-rename-to-altname.link
476+
477+diff --git a/test/test-network/conf/12-dummy-rename-to-altname.link b/test/test-network/conf/12-dummy-rename-to-altname.link
478+new file mode 100644
479+index 0000000..bef4bf3
480+--- /dev/null
481++++ b/test/test-network/conf/12-dummy-rename-to-altname.link
482+@@ -0,0 +1,7 @@
483++# SPDX-License-Identifier: LGPL-2.1-or-later
484++[Match]
485++OriginalName=dummy98
486++
487++[Link]
488++Name=dummyalt
489++AlternativeName=dummyalt hogehogehogehogehogehoge
490+diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
491+index 5a731f5..a04f302 100755
492+--- a/test/test-network/systemd-networkd-tests.py
493++++ b/test/test-network/systemd-networkd-tests.py
494+@@ -936,6 +936,17 @@ class NetworkctlTests(unittest.TestCase, Utilities):
495+ output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummy98', env=env)
496+ self.assertRegex(output, 'hogehogehogehogehogehoge')
497+
498++ @expectedFailureIfAlternativeNameIsNotAvailable()
499++ def test_rename_to_altname(self):
500++ copy_network_unit('26-netdev-link-local-addressing-yes.network',
501++ '12-dummy.netdev', '12-dummy-rename-to-altname.link')
502++ start_networkd()
503++ self.wait_online(['dummyalt:degraded'])
504++
505++ output = check_output(*networkctl_cmd, '-n', '0', 'status', 'dummyalt', env=env)
506++ self.assertIn('hogehogehogehogehogehoge', output)
507++ self.assertNotIn('dummy98', output)
508++
509+ def test_reconfigure(self):
510+ copy_network_unit('25-address-static.network', '12-dummy.netdev')
511+ start_networkd()
512diff --git a/debian/patches/lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch b/debian/patches/lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch
513new file mode 100644
514index 0000000..4e0240e
515--- /dev/null
516+++ b/debian/patches/lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch
517@@ -0,0 +1,63 @@
518+From: Nick Rosbrook <nick.rosbrook@canonical.com>
519+Date: Fri, 2 Dec 2022 15:35:25 -0500
520+Subject: udev: attempt device rename even if interface is up
521+
522+Origin: upstream, https://github.com/systemd/systemd/commit/53584e7b61
523+Bug-Ubuntu: https://launchpad.net/bugs/2002445
524+
525+Currently rename_netif() will not attempt to rename a device if it is
526+already up, because the kernel will return -EBUSY unless live renaming
527+is allowed on the device. This restriction will be removed in a future
528+kernel version [1].
529+
530+To cover both cases, always attempt to rename the interface and return 0
531+if we get -EBUSY.
532+
533+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=bd039b5ea2a9
534+---
535+ src/udev/udev-event.c | 18 ++++++------------
536+ 1 file changed, 6 insertions(+), 12 deletions(-)
537+
538+diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
539+index b3d92d5..08d69cf 100644
540+--- a/src/udev/udev-event.c
541++++ b/src/udev/udev-event.c
542+@@ -862,7 +862,6 @@ int udev_event_spawn(
543+ static int rename_netif(UdevEvent *event) {
544+ const char *oldname;
545+ sd_device *dev;
546+- unsigned flags;
547+ int ifindex, r;
548+
549+ assert(event);
550+@@ -896,17 +895,7 @@ static int rename_netif(UdevEvent *event) {
551+ return 0;
552+ }
553+
554+- r = rtnl_get_link_info(&event->rtnl, ifindex, NULL, &flags, NULL, NULL, NULL);
555+- if (r < 0)
556+- return log_device_warning_errno(dev, r, "Failed to get link flags: %m");
557+-
558+- if (FLAGS_SET(flags, IFF_UP)) {
559+- log_device_info(dev, "Network interface '%s' is already up, refusing to rename to '%s'.",
560+- oldname, event->name);
561+- return 0;
562+- }
563+-
564+- /* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
565++ /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
566+ r = device_add_property(dev, "ID_RENAMING", "1");
567+ if (r < 0)
568+ return log_device_warning_errno(dev, r, "Failed to add 'ID_RENAMING' property: %m");
569+@@ -927,6 +916,11 @@ static int rename_netif(UdevEvent *event) {
570+ return log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
571+
572+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
573++ if (r == -EBUSY) {
574++ log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
575++ oldname, event->name);
576++ return 0;
577++ }
578+ if (r < 0)
579+ return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m",
580+ ifindex, oldname, event->name);
581diff --git a/debian/patches/lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch b/debian/patches/lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch
582new file mode 100644
583index 0000000..0b78d7f
584--- /dev/null
585+++ b/debian/patches/lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch
586@@ -0,0 +1,34 @@
587+From: Nick Rosbrook <nick.rosbrook@canonical.com>
588+Date: Wed, 2 Nov 2022 11:05:01 -0400
589+Subject: udev/net: allow new link name as an altname before renaming happens
590+
591+Origin: upstream, https://github.com/systemd/systemd/commit/d0b31efc1a
592+Bug-Ubuntu: https://launchpad.net/bugs/2002445
593+
594+When configuring a link's alternative names, the link's new name to-be
595+is not allowed to be included because interface renaming will fail if
596+the new name is already present as an alternative name. However,
597+rtnl_set_link_name will delete the conflicting alternative name before
598+renaming the device, if necessary.
599+
600+Allow the new link name to be set as an alternative name before the
601+device is renamed. This means that if the rename is later skipped (i.e.
602+because the link is already up), then the name can at least still be
603+present as an alternative name.
604+---
605+ src/udev/net/link-config.c | 2 --
606+ 1 file changed, 2 deletions(-)
607+
608+diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
609+index e408725..5d28526 100644
610+--- a/src/udev/net/link-config.c
611++++ b/src/udev/net/link-config.c
612+@@ -841,8 +841,6 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
613+ }
614+ }
615+
616+- if (link->new_name)
617+- strv_remove(altnames, link->new_name);
618+ strv_remove(altnames, link->ifname);
619+
620+ r = rtnl_get_link_alternative_names(rtnl, link->ifindex, &current_altnames);
621diff --git a/debian/patches/p11kit-switch-to-dlopen.patch b/debian/patches/p11kit-switch-to-dlopen.patch
622index 0cdb8c3..d9fd919 100644
623--- a/debian/patches/p11kit-switch-to-dlopen.patch
624+++ b/debian/patches/p11kit-switch-to-dlopen.patch
625@@ -718,10 +718,10 @@ index 85dbb81..55728c2 100644
626 }
627
628 diff --git a/test/test-functions b/test/test-functions
629-index 5613215..7f0ab56 100644
630+index ae0a993..be3b686 100644
631 --- a/test/test-functions
632 +++ b/test/test-functions
633-@@ -1275,7 +1275,7 @@ install_missing_libraries() {
634+@@ -1276,7 +1276,7 @@ install_missing_libraries() {
635 local lib path
636 # A number of dependencies is now optional via dlopen, so the install
637 # script will not pick them up, since it looks at linkage.
638@@ -730,7 +730,7 @@ index 5613215..7f0ab56 100644
639 ddebug "Searching for $lib via pkg-config"
640 if pkg-config --exists "$lib"; then
641 path="$(pkg-config --variable=libdir "$lib")"
642-@@ -1287,6 +1287,10 @@ install_missing_libraries() {
643+@@ -1288,6 +1288,10 @@ install_missing_libraries() {
644 if ! [[ ${lib} =~ ^lib ]]; then
645 lib="lib${lib}"
646 fi
647diff --git a/debian/patches/series b/debian/patches/series
648index 663fefb..654d909 100644
649--- a/debian/patches/series
650+++ b/debian/patches/series
651@@ -37,9 +37,6 @@ debian/UBUNTU-Don-t-override-Ubuntu-s-default-sysctl-values-LP-1962038.patch
652 test-increase-QEMU_MEM-for-some-tests.patch
653 lp1981042-core-firstboot-workaround-timezone-issues-caused-by-Ubunt.patch
654 test-denylist-TEST-29-PORTABLE-again.patch
655-test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch
656-test-make-sure-mount-point-exists-in-testsuite-64.sh.patch
657-test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch
658 test-skip-some-tests-when-machine-id-is-not-initialized.patch
659 lp1999275-stat-util-introduce-fd_is_read_only_fs.patch
660 lp1999275-binfmt-util-split-out-binfmt_mounted.patch
661@@ -47,3 +44,10 @@ lp1999275-binfmt-util-also-check-if-binfmt-is-mounted-in-read-write.patch
662 lp1999275-binfmt-check-if-binfmt-is-mounted-before-applying-rules.patch
663 lp1999275-unit-check-more-specific-path-to-be-written-by-systemd-bi.patch
664 debian/Skip-flaky-test_resolved_domain_restricted_dns-in-network.patch
665+lp2002445-udev-net-allow-new-link-name-as-an-altname-before-renamin.patch
666+lp2002445-sd-netlink-do-not-swap-old-name-and-alternative-name.patch
667+lp2002445-sd-netlink-restore-altname-on-error-in-rtnl_set_link_name.patch
668+lp2002445-udev-attempt-device-rename-even-if-interface-is-up.patch
669+lp2002445-sd-netlink-add-a-test-for-rtnl_set_link_name.patch
670+lp2002445-test-network-add-a-test-for-renaming-device-to-current-al.patch
671+Deny-list-TEST-74-AUX-UTILS-on-s390x.patch
672diff --git a/debian/patches/test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch b/debian/patches/test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch
673deleted file mode 100644
674index e192136..0000000
675--- a/debian/patches/test-handle-Debian-s-etc-default-locale-in-testsuite-74.f.patch
676+++ /dev/null
677@@ -1,107 +0,0 @@
678-From: Nick Rosbrook <nick.rosbrook@canonical.com>
679-Date: Tue, 22 Nov 2022 12:50:33 -0500
680-Subject: test: handle Debian's /etc/default/locale in
681- testsuite-74.firstboot.sh
682-
683-Origin: upstream, https://github.com/systemd/systemd/commit/bb59fdc1e3a7119f3680d309147020fce9bf67b5
684-
685-This handles a Debian-specific quirk where /etc/default/locale is used
686-instead of /etc/locale.conf. There is currently special handling for
687-this in testsuite-73.sh, so the quirk should be handled here too for
688-consistency.
689-
690-This patch was modified to apply to v251.1.
691----
692- test/units/testsuite-74.firstboot.sh | 40 ++++++++++++++++--------------------
693- 1 file changed, 18 insertions(+), 22 deletions(-)
694-
695-diff --git a/test/units/testsuite-74.firstboot.sh b/test/units/testsuite-74.firstboot.sh
696-index 02f9f5c..1bcc3da 100755
697---- a/test/units/testsuite-74.firstboot.sh
698-+++ b/test/units/testsuite-74.firstboot.sh
699-@@ -24,6 +24,12 @@ ROOT_HASHED_PASSWORD1='$6$foobarsalt$YbwdaATX6IsFxvWbY3QcZj2gB31R/LFRFrjlFrJtTTq
700- # shellcheck disable=SC2016
701- ROOT_HASHED_PASSWORD2='$6$foobarsalt$q.P2932zYMLbKnjFwIxPI8y3iuxeuJ2BgE372LcZMMnj3Gcg/9mJg2LPKUl.ha0TG/.fRNNnRQcLfzM0SNot3.'
702-
703-+# Debian and Ubuntu use /etc/default/locale instead of /etc/locale.conf. Make
704-+# sure we use the appropriate path for locale configuration.
705-+LOCALE_PATH="/etc/locale.conf"
706-+[ -e "$LOCALE_PATH" ] || LOCALE_PATH="/etc/default/locale"
707-+[ -e "$LOCALE_PATH" ] || systemd-firstboot --locale=C.UTF-8
708-+
709- # Create a minimal root so we don't modify the testbed
710- ROOT=test-root
711- mkdir -p "$ROOT/bin"
712-@@ -31,15 +37,15 @@ mkdir -p "$ROOT/bin"
713- touch "$ROOT/bin/fooshell" "$ROOT/bin/barshell"
714-
715- systemd-firstboot --root="$ROOT" --locale=foo
716--grep -q "LANG=foo" "$ROOT/etc/locale.conf"
717--rm -fv "$ROOT/etc/locale.conf"
718-+grep -q "LANG=foo" "$ROOT$LOCALE_PATH"
719-+rm -fv "$ROOT$LOCALE_PATH"
720- # FIXME: https://github.com/systemd/systemd/issues/25249
721- #systemd-firstboot --root="$ROOT" --locale-messages=foo
722--#grep -q "LC_MESSAGES=foo" "$ROOT/etc/locale.conf"
723--#rm -fv "$ROOT/etc/locale.conf"
724-+#grep -q "LC_MESSAGES=foo" "$ROOT$LOCALE_PATH"
725-+#rm -fv "$ROOT$LOCALE_PATH"
726- systemd-firstboot --root="$ROOT" --locale=foo --locale-messages=bar
727--grep -q "LANG=foo" "$ROOT/etc/locale.conf"
728--grep -q "LC_MESSAGES=bar" "$ROOT/etc/locale.conf"
729-+grep -q "LANG=foo" "$ROOT$LOCALE_PATH"
730-+grep -q "LC_MESSAGES=bar" "$ROOT$LOCALE_PATH"
731-
732- systemd-firstboot --root="$ROOT" --keymap=foo
733- grep -q "KEYMAP=foo" "$ROOT/etc/vconsole.conf"
734-@@ -83,8 +89,8 @@ systemd-firstboot --root="$ROOT" \
735- --root-password-hashed="$ROOT_HASHED_PASSWORD2" \
736- --root-shell=/bin/barshell \
737- --kernel-command-line="hello.world=0"
738--grep -q "LANG=foo" "$ROOT/etc/locale.conf"
739--grep -q "LC_MESSAGES=bar" "$ROOT/etc/locale.conf"
740-+grep -q "LANG=foo" "$ROOT$LOCALE_PATH"
741-+grep -q "LC_MESSAGES=bar" "$ROOT$LOCALE_PATH"
742- grep -q "KEYMAP=foo" "$ROOT/etc/vconsole.conf"
743- readlink "$ROOT/etc/localtime" | grep -q "Europe/Berlin$"
744- grep -q "foobar" "$ROOT/etc/hostname"
745-@@ -104,8 +110,8 @@ systemd-firstboot --root="$ROOT" --force \
746- --root-password-hashed="$ROOT_HASHED_PASSWORD2" \
747- --root-shell=/bin/barshell \
748- --kernel-command-line="hello.world=0"
749--grep -q "LANG=locale-overwrite" "$ROOT/etc/locale.conf"
750--grep -q "LC_MESSAGES=messages-overwrite" "$ROOT/etc/locale.conf"
751-+grep -q "LANG=locale-overwrite" "$ROOT$LOCALE_PATH"
752-+grep -q "LC_MESSAGES=messages-overwrite" "$ROOT$LOCALE_PATH"
753- grep -q "KEYMAP=keymap-overwrite" "$ROOT/etc/vconsole.conf"
754- readlink "$ROOT/etc/localtime" | grep -q "/CET$"
755- grep -q "hostname-overwrite" "$ROOT/etc/hostname"
756-@@ -119,7 +125,7 @@ rm -fr "$ROOT"
757- mkdir "$ROOT"
758- # Copy everything at once (--copy)
759- systemd-firstboot --root="$ROOT" --copy
760--diff /etc/locale.conf "$ROOT/etc/locale.conf"
761-+diff $LOCALE_PATH "$ROOT$LOCALE_PATH"
762- diff <(awk -F: '/^root/ { print $7; }' /etc/passwd) <(awk -F: '/^root/ { print $7; }' "$ROOT/etc/passwd")
763- diff <(awk -F: '/^root/ { print $2; }' /etc/shadow) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
764- [[ -e /etc/vconsole.conf ]] && diff /etc/vconsole.conf "$ROOT/etc/vconsole.conf"
765-@@ -128,18 +134,8 @@ rm -fr "$ROOT"
766- mkdir "$ROOT"
767- # Copy everything at once, but now by using separate switches
768- systemd-firstboot --root="$ROOT" --copy-locale --copy-keymap --copy-timezone --copy-root-password --copy-root-shell
769--diff /etc/locale.conf "$ROOT/etc/locale.conf"
770-+diff $LOCALE_PATH "$ROOT$LOCALE_PATH"
771- diff <(awk -F: '/^root/ { print $7; }' /etc/passwd) <(awk -F: '/^root/ { print $7; }' "$ROOT/etc/passwd")
772- diff <(awk -F: '/^root/ { print $2; }' /etc/shadow) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
773- [[ -e /etc/vconsole.conf ]] && diff /etc/vconsole.conf "$ROOT/etc/vconsole.conf"
774- [[ -e /etc/localtime ]] && diff <(readlink /etc/localtime) <(readlink "$ROOT/etc/localtime")
775--
776--# Assorted tests
777--rm -fr "$ROOT"
778--mkdir "$ROOT"
779--
780--systemd-firstboot --root="$ROOT" --setup-machine-id
781--grep -E "[a-z0-9]{32}" "$ROOT/etc/machine-id"
782--
783--systemd-firstboot --root="$ROOT" --delete-root-password
784--diff <(echo) <(awk -F: '/^root/ { print $2; }' "$ROOT/etc/shadow")
785diff --git a/debian/patches/test-make-sure-mount-point-exists-in-testsuite-64.sh.patch b/debian/patches/test-make-sure-mount-point-exists-in-testsuite-64.sh.patch
786deleted file mode 100644
787index ab71bce..0000000
788--- a/debian/patches/test-make-sure-mount-point-exists-in-testsuite-64.sh.patch
789+++ /dev/null
790@@ -1,22 +0,0 @@
791-From: Nick Rosbrook <nick.rosbrook@canonical.com>
792-Date: Tue, 22 Nov 2022 12:43:51 -0500
793-Subject: test: make sure mount point exists in testsuite-64.sh
794-
795-Origin: upstream, https://github.com/systemd/systemd/commit/84e5b9225d12f8a1a7d414ef01f97fcd6881c14f
796-
797----
798- test/units/testsuite-64.sh | 1 +
799- 1 file changed, 1 insertion(+)
800-
801-diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh
802-index 7673036..8e46533 100755
803---- a/test/units/testsuite-64.sh
804-+++ b/test/units/testsuite-64.sh
805-@@ -243,6 +243,7 @@ EOF
806- echo "${FUNCNAME[0]}: test failover"
807- local device expected link mpoint part
808- local -a devices
809-+ mkdir -p /mnt
810- mpoint="$(mktemp -d /mnt/mpathXXX)"
811- wwid="deaddeadbeef0000"
812- path="/dev/disk/by-id/wwn-0x$wwid"
813diff --git a/debian/patches/test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch b/debian/patches/test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch
814deleted file mode 100644
815index 0adbd1f..0000000
816--- a/debian/patches/test-remove-no-longer-needed-quirk-for-set-locale-on-Debi.patch
817+++ /dev/null
818@@ -1,23 +0,0 @@
819-From: Nick Rosbrook <nick.rosbrook@canonical.com>
820-Date: Thu, 17 Nov 2022 11:29:03 -0500
821-Subject: test: remove no-longer-needed quirk for set-locale on Debian/Ubuntu
822-
823----
824- test/units/testsuite-73.sh | 4 +---
825- 1 file changed, 1 insertion(+), 3 deletions(-)
826-
827-diff --git a/test/units/testsuite-73.sh b/test/units/testsuite-73.sh
828-index f9e2dce..1e493c0 100755
829---- a/test/units/testsuite-73.sh
830-+++ b/test/units/testsuite-73.sh
831-@@ -118,9 +118,7 @@ LC_CTYPE=$i"
832-
833- assert_rc 0 localectl set-locale "$i"
834- if [[ -f /etc/default/locale ]]; then
835-- # Debian/Ubuntu patch is buggy, and LC_CTYPE= still exists.
836-- assert_eq "$(cat /etc/default/locale)" "LANG=$i
837--LC_CTYPE=$i"
838-+ assert_eq "$(cat /etc/default/locale)" "LANG=$i"
839- else
840- assert_eq "$(cat /etc/locale.conf)" "LANG=$i"
841- fi
842diff --git a/debian/rules b/debian/rules
843index 73ef33f..ce2c49f 100755
844--- a/debian/rules
845+++ b/debian/rules
846@@ -100,6 +100,7 @@ CONFFLAGS = \
847 -Dnss-resolve=true \
848 -Dnss-systemd=true \
849 -Dresolve=true \
850+ -Dstatus-unit-format-default=combined \
851 -Dstandalone-binaries=true
852
853 ifeq (, $(filter stage1, $(DEB_BUILD_PROFILES)))
854diff --git a/debian/tests/boot-and-services b/debian/tests/boot-and-services
855index 4c2d7a8..fc0eb9b 100755
856--- a/debian/tests/boot-and-services
857+++ b/debian/tests/boot-and-services
858@@ -119,7 +119,7 @@ class ServicesTest(unittest.TestCase):
859 # has kernel messages
860 self.assertRegex(log, 'kernel:.*')
861 # has init messages
862- self.assertRegex(log, 'systemd.*Reached target Graphical Interface')
863+ self.assertRegex(log, 'systemd.*Reached target(?: graphical.target -)? Graphical Interface')
864 # has other services
865 self.assertRegex(log, 'NetworkManager.*:')
866
867@@ -199,7 +199,7 @@ class JournalTest(unittest.TestCase):
868 # has kernel messages
869 self.assertRegex(out, b'kernel:.*')
870 # has init messages
871- self.assertRegex(out, b'systemd.*Reached target Graphical Interface')
872+ self.assertRegex(out, b'systemd.*Reached target(?: graphical.target -)? Graphical Interface')
873 # has other services
874 self.assertRegex(out, b'NetworkManager.*:.*starting')
875
876diff --git a/debian/tests/control b/debian/tests/control
877index 34a3a05..0e0a97c 100644
878--- a/debian/tests/control
879+++ b/debian/tests/control
880@@ -48,6 +48,7 @@ Depends: systemd,
881 cryptsetup-bin,
882 systemd-sysv,
883 polkitd | policykit-1,
884+ netlabel-tools,
885 dnsmasq-base
886 Restrictions: needs-root, isolation-container, breaks-testbed
887
888@@ -182,6 +183,8 @@ Depends: systemd-tests,
889 squashfs-tools,
890 vim-tiny,
891 dosfstools,
892+ mtools,
893+ erofs-utils,
894 libdw-dev,
895 libelf-dev,
896 dbus-user-session,
897@@ -195,6 +198,16 @@ Depends: systemd-tests,
898 tpm2-tools,
899 libgcc-s1,
900 openssl,
901+ bsdutils,
902+ knot,
903+ knot-dnssecutils | knot-dnsutils,
904+ bind9-dnsutils,
905+ bind9-host,
906+ jq,
907+ psmisc,
908+ xkb-data,
909+ locales,
910+ locales-all,
911 Restrictions: needs-root, allow-stderr, isolation-machine
912
913 Tests: boot-smoke
914@@ -205,11 +218,3 @@ Depends: systemd-sysv,
915 systemd,
916 udev,
917 Restrictions: needs-root, isolation-container, allow-stderr, breaks-testbed
918-
919-# NOUPSTREAM: Do not run these tests for upstream builds
920-
921-Tests: systemd-fsckd
922-Depends: systemd-sysv,
923- python3,
924- plymouth
925-Restrictions: needs-root, isolation-machine, breaks-testbed, skippable, flaky
926diff --git a/debian/tests/fsck b/debian/tests/fsck
927deleted file mode 100755
928index 77b50d7..0000000
929--- a/debian/tests/fsck
930+++ /dev/null
931@@ -1,27 +0,0 @@
932-#!/bin/bash
933-fd=0
934-
935-OPTIND=1
936-while getopts "C:aTlM" opt; do
937- case "$opt" in
938- C)
939- fd=$OPTARG
940- ;;
941- \?);;
942- esac
943-done
944-
945-shift "$((OPTIND-1))"
946-device=$1
947-
948-echo "Running fake fsck on $device"
949-
950-declare -a maxpass=(30 5 2 30 60)
951-
952-for pass in {1..5}; do
953- maxprogress=${maxpass[$((pass-1))]}
954- for (( current=0; current<=${maxprogress}; current++)); do
955- echo "$pass $current $maxprogress $device">&$fd
956- sleep 0.1
957- done
958-done
959diff --git a/debian/tests/systemd-fsckd b/debian/tests/systemd-fsckd
960deleted file mode 100755
961index 7f5e535..0000000
962--- a/debian/tests/systemd-fsckd
963+++ /dev/null
964@@ -1,323 +0,0 @@
965-#!/usr/bin/python3
966-# autopkgtest check: Ensure that systemd-fsckd can report progress and cancel
967-# (C) 2015 Canonical Ltd.
968-# Author: Didier Roche <didrocks@ubuntu.com>
969-
970-import fileinput
971-import inspect
972-import os
973-import platform
974-import re
975-import shutil
976-import stat
977-import subprocess
978-import sys
979-import time
980-import unittest
981-
982-from contextlib import suppress
983-from pathlib import Path
984-
985-SYSTEMD_FSCK_ROOT_DROPIN_PATH = '/etc/systemd/system/systemd-fsck-root.service.d/autopkgtest.conf'
986-SYSTEMD_FSCK_ROOT_DROPIN_CONTENT = '''
987-[Unit]
988-ConditionPathIsReadWrite=
989-ConditionPathExists=
990-
991-[Install]
992-WantedBy=local-fs.target
993-'''
994-
995-KILL_SERVICE_PATH = '/etc/systemd/system/kill@.service'
996-KILL_SERVICE_CONTENT = '''
997-[Unit]
998-DefaultDependencies=no
999-StartLimitInterval=0
1000-Before=systemd-fsckd.service
1001-
1002-[Service]
1003-RestartSec=1
1004-Restart=on-failure
1005-ExecStart=/bin/sh -c "/bin/sleep 5; /usr/bin/pkill -x %i"
1006-
1007-[Install]
1008-WantedBy=systemd-fsckd.service
1009-'''
1010-
1011-DEFAULT_SYSTEM_RUNNING_TIMEOUT = 600
1012-DEFAULT_SYSTEMD_FSCKD_TIMEOUT = 600
1013-
1014-FSCK_PATH = '/sbin/fsck'
1015-FSCK_BACKUP_PATH = '/sbin/fsck.backup'
1016-
1017-RE_SPLASH_QUIET = r'\b\s*(splash|quiet)\b'
1018-
1019-
1020-def tests_setup():
1021- # enable persistent journal
1022- Path('/var/log/journal').mkdir(parents=True, exist_ok=True)
1023- subprocess.run('systemctl -q restart systemd-journald'.split())
1024- Path(SYSTEMD_FSCK_ROOT_DROPIN_PATH).parent.mkdir(parents=True, exist_ok=True)
1025- Path(SYSTEMD_FSCK_ROOT_DROPIN_PATH).write_text(SYSTEMD_FSCK_ROOT_DROPIN_CONTENT)
1026- Path(KILL_SERVICE_PATH).parent.mkdir(parents=True, exist_ok=True)
1027- Path(KILL_SERVICE_PATH).write_text(KILL_SERVICE_CONTENT)
1028- subprocess.run('systemctl -q daemon-reload'.split())
1029- subprocess.run('systemctl -q enable systemd-fsck-root'.split())
1030- Path(FSCK_PATH).rename(FSCK_BACKUP_PATH)
1031- Path(FSCK_PATH).write_text(Path(__file__).with_name('fsck').read_text())
1032- Path(FSCK_PATH).chmod(0o755)
1033-
1034-def tests_teardown():
1035- Path('/etc/systemd/system/local-fs.target.wants/systemd-fsck-root.service').unlink()
1036- subprocess.run('systemctl -q disable systemd-fsck-root'.split())
1037- Path(SYSTEMD_FSCK_ROOT_DROPIN_PATH).unlink()
1038- Path(KILL_SERVICE_PATH).unlink()
1039- subprocess.run('systemctl -q daemon-reload'.split())
1040- Path(FSCK_BACKUP_PATH).replace(FSCK_PATH)
1041-
1042-def is_system_running():
1043- running = subprocess.run('systemctl is-system-running'.split(),
1044- encoding='utf-8',
1045- stdout=subprocess.PIPE).stdout.strip()
1046- return running in ['running', 'degraded']
1047-
1048-def is_unit_active(unit):
1049- return subprocess.run(f'systemctl -q is-active {unit}'.split()).returncode == 0
1050-
1051-def has_unit_failed(unit):
1052- '''check if this unit failed at least once, this boot'''
1053- journal = subprocess.run(f'journalctl -b -u {unit}'.split(),
1054- encoding='utf-8',
1055- stdout=subprocess.PIPE).stdout.strip()
1056- return f'{unit}.service: Failed' in journal
1057-
1058-def has_unit_started(unit):
1059- return subprocess.run(f'systemctl show --value -p ExecMainStartTimestampMonotonic {unit}'.split(),
1060- encoding='utf-8',
1061- stdout=subprocess.PIPE).stdout.strip() != '0'
1062-
1063-def get_unit_exec_status(unit):
1064- return subprocess.run(f'systemctl show --value -p ExecMainStatus {unit}'.split(),
1065- encoding='utf-8',
1066- stdout=subprocess.PIPE).stdout.strip()
1067-
1068-class FsckdTest(unittest.TestCase):
1069- '''Check that we run, report and can cancel fsck'''
1070- def __init__(self, test_name, after_reboot):
1071- super().__init__(test_name)
1072- self._test_name = test_name
1073- self._after_reboot = after_reboot
1074-
1075- def setUp(self):
1076- super().setUp()
1077- if self._after_reboot:
1078- self.wait_system_running()
1079- self.wait_systemd_fsckd()
1080- else:
1081- configure_plymouth()
1082-
1083- def tearDown(self):
1084- super().tearDown()
1085-
1086- def enable_kill_service(self, proc):
1087- subprocess.run(f'systemctl -q enable kill@{proc}'.split())
1088-
1089- def disable_kill_service(self, proc):
1090- subprocess.run(f'systemctl -q disable kill@{proc}'.split())
1091-
1092- def wait_system_running(self, timeout=DEFAULT_SYSTEM_RUNNING_TIMEOUT):
1093- end = time.monotonic() + timeout
1094- while time.monotonic() <= end:
1095- if is_system_running():
1096- return
1097- time.sleep(1)
1098- self.fail('timeout waiting for system running')
1099-
1100- def wait_systemd_fsckd(self, timeout=DEFAULT_SYSTEMD_FSCKD_TIMEOUT):
1101- end = time.monotonic() + timeout
1102- while time.monotonic() <= end:
1103- if not is_unit_active('systemd-fsckd'):
1104- return
1105- time.sleep(1)
1106- self.fail('timeout waiting for systemd-fsckd to finish')
1107-
1108- def check_systemd_fsckd(self):
1109- unit = 'systemd-fsckd'
1110- self.assertUnitStarted(unit)
1111- self.assertUnitNotActive(unit)
1112- self.assertSystemdFsckdNotFailed()
1113-
1114- def check_systemd_fsck_root(self):
1115- unit = 'systemd-fsck-root'
1116- self.assertUnitStarted(unit)
1117- self.assertUnitActive(unit)
1118- self.assertUnitNotFailed(unit)
1119-
1120- def check_plymouth_start(self):
1121- unit = 'plymouth-start'
1122- self.assertUnitStarted(unit)
1123- # stays active in 20.10 and later
1124- self.assertUnitActive(unit)
1125- self.assertUnitNotFailed(unit)
1126-
1127- def test_systemd_fsckd_run(self):
1128- '''Ensure we can boot after a fsck was processed'''
1129- if not self._after_reboot:
1130- self.reboot()
1131- else:
1132- self.check_systemd_fsckd()
1133- self.check_systemd_fsck_root()
1134- self.check_plymouth_start()
1135-
1136- def test_systemd_fsckd_run_without_plymouth(self):
1137- '''Ensure we can boot without plymouth after a fsck was processed'''
1138- if not self._after_reboot:
1139- configure_plymouth(enable=False)
1140- self.reboot()
1141- else:
1142- self.check_systemd_fsckd()
1143- self.check_systemd_fsck_root()
1144- self.assertUnitNeverStarted('plymouth-start')
1145-
1146- def test_fsck_failure(self):
1147- '''Ensure that a failing fsck doesn't prevent fsckd to stop'''
1148- if not self._after_reboot:
1149- self.enable_kill_service('fsck')
1150- self.reboot()
1151- else:
1152- self.check_systemd_fsckd()
1153- self.assertUnitFailed('systemd-fsck-root')
1154- self.check_plymouth_start()
1155- self.disable_kill_service('fsck')
1156-
1157- def test_systemd_fsck_failure(self):
1158- '''Ensure that a failing systemd-fsck doesn't prevent fsckd to stop'''
1159- if not self._after_reboot:
1160- self.enable_kill_service('systemd-fsck')
1161- self.reboot()
1162- else:
1163- self.check_systemd_fsckd()
1164- self.assertUnitFailed('systemd-fsck-root')
1165- self.check_plymouth_start()
1166- self.disable_kill_service('systemd-fsck')
1167-
1168- def test_systemd_fsckd_failure(self):
1169- '''Ensure that a failing systemd-fsckd doesn't prevent system to boot'''
1170- if not self._after_reboot:
1171- self.enable_kill_service('systemd-fsckd')
1172- self.reboot()
1173- else:
1174- self.assertSystemdFsckdFailed()
1175- self.assertUnitFailed('systemd-fsck-root')
1176- self.check_plymouth_start()
1177- self.disable_kill_service('systemd-fsckd')
1178-
1179- def assertUnitActive(self, unit):
1180- self.assertTrue(is_unit_active(unit))
1181-
1182- def assertUnitNotActive(self, unit):
1183- self.assertFalse(is_unit_active(unit))
1184-
1185- def assertUnitFailed(self, unit):
1186- self.assertTrue(has_unit_failed(unit))
1187-
1188- def assertUnitNotFailed(self, unit):
1189- self.assertFalse(has_unit_failed(unit))
1190-
1191- def assertUnitStarted(self, unit):
1192- self.assertTrue(has_unit_started(unit))
1193-
1194- def assertUnitNeverStarted(self, unit):
1195- self.assertFalse(has_unit_started(unit))
1196-
1197- def assertSystemdFsckdFailed(self):
1198- self.assertNotEqual(get_unit_exec_status('systemd-fsckd'), '0')
1199-
1200- def assertSystemdFsckdNotFailed(self):
1201- self.assertEqual(get_unit_exec_status('systemd-fsckd'), '0')
1202-
1203- def reboot(self):
1204- '''Reboot the system with the current test marker'''
1205- subprocess.run(f'/tmp/autopkgtest-reboot {self._test_name}'.split())
1206-
1207-
1208-def configure_plymouth_grub(enable=True):
1209- grubcfg = Path('/etc/default/grub')
1210- grubcfgdir = Path('/etc/default/grub.d')
1211- grubcfgdir.mkdir(parents=True, exist_ok=True)
1212- mygrubcfg = grubcfgdir.joinpath('99-autopkgtest.cfg')
1213- if enable:
1214- content = 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT splash quiet"'
1215- mygrubcfg.write_text(content)
1216- else:
1217- mygrubcfg.unlink()
1218- for f in [grubcfg] + list(grubcfgdir.glob('*.cfg')):
1219- content = f.read_text()
1220- if re.search(RE_SPLASH_QUIET, content):
1221- f.write_text(re.sub(RE_SPLASH_QUIET, ' ', content))
1222- subprocess.run(['update-grub'], stderr=subprocess.DEVNULL, check=True)
1223-
1224-def configure_plymouth_zipl(enable=True):
1225- ziplcfg = Path('/etc/zipl.conf')
1226- content = re.sub(RE_SPLASH_QUIET, ' ', ziplcfg.read_text())
1227- if enable:
1228- content = re.sub(r'(?m)^(parameters.*[^\'"])(\s*[\'"]?)$', r'\1 splash quiet\2', content)
1229- ziplcfg.write_text(content)
1230- subprocess.run(['zipl'], stderr=subprocess.DEVNULL, check=True)
1231-
1232-def configure_plymouth(enable=True):
1233- if platform.processor() == 's390x':
1234- configure_plymouth_zipl(enable)
1235- else:
1236- configure_plymouth_grub(enable)
1237-
1238-def getAllTests(unitTestClass):
1239- '''get all test names in predictable sorted order from unitTestClass'''
1240- return sorted([test[0] for test in inspect.getmembers(unitTestClass, predicate=inspect.isfunction)
1241- if test[0].startswith('test_')])
1242-
1243-
1244-# AUTOPKGTEST_REBOOT_MARK contains the test name to pursue after reboot
1245-# (to check results and states after reboot, mostly).
1246-# we append the previous global return code (0 or 1) to it.
1247-# Example: AUTOPKGTEST_REBOOT_MARK=test_foo:0
1248-if __name__ == '__main__':
1249- if os.path.exists('/run/initramfs/fsck-root'):
1250- print('SKIP: root file system is being checked by initramfs already')
1251- sys.exit(77)
1252-
1253- if platform.processor() == 'aarch64':
1254- print('SKIP: cannot reboot properly on arm64, see https://bugs.launchpad.net/ubuntu/+source/nova/+bug/1748280')
1255- sys.exit(77)
1256-
1257- all_tests = getAllTests(FsckdTest)
1258- current_test = os.getenv('AUTOPKGTEST_REBOOT_MARK')
1259-
1260- if not current_test:
1261- tests_setup()
1262- after_reboot = False
1263- current_test = all_tests[0]
1264- else:
1265- after_reboot = True
1266-
1267- # loop on remaining tests to run
1268- try:
1269- remaining_tests = all_tests[all_tests.index(current_test):]
1270- except ValueError:
1271- print(f'Invalid value for AUTOPKGTEST_REBOOT_MARK, {current_test} is not a valid test name')
1272- sys.exit(2)
1273-
1274- # run all remaining tests
1275- for test_name in remaining_tests:
1276- suite = unittest.TestSuite()
1277- suite.addTest(FsckdTest(test_name, after_reboot))
1278- result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite)
1279- if len(result.failures) != 0 or len(result.errors) != 0:
1280- j = os.path.join(os.getenv('AUTOPKGTEST_ARTIFACTS'), 'systemd-fsckd-journal.txt')
1281- with open(j, 'w') as f:
1282- subprocess.run('journalctl -a --no-pager'.split(), encoding='utf-8', stdout=f)
1283- sys.exit(1)
1284- after_reboot = False
1285-
1286- tests_teardown()
1287- sys.exit(0)
1288diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
1289index 5e08b35..7dbf98d 100644
1290--- a/man/org.freedesktop.systemd1.xml
1291+++ b/man/org.freedesktop.systemd1.xml
1292@@ -10139,6 +10139,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
1293 readonly t RuntimeMaxUSec = ...;
1294 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
1295 readonly t RuntimeRandomizedExtraUSec = ...;
1296+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
1297+ readonly s OOMPolicy = '...';
1298 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
1299 readonly s Slice = '...';
1300 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
1301@@ -10313,6 +10315,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
1302
1303 <!--property RuntimeRandomizedExtraUSec is not documented!-->
1304
1305+ <!--property OOMPolicy is not documented!-->
1306+
1307 <!--property Slice is not documented!-->
1308
1309 <!--property ControlGroupId is not documented!-->
1310@@ -10495,6 +10499,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
1311
1312 <variablelist class="dbus-property" generated="True" extra-ref="RuntimeRandomizedExtraUSec"/>
1313
1314+ <variablelist class="dbus-property" generated="True" extra-ref="OOMPolicy"/>
1315+
1316 <variablelist class="dbus-property" generated="True" extra-ref="Slice"/>
1317
1318 <variablelist class="dbus-property" generated="True" extra-ref="ControlGroup"/>
1319diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
1320index 773ca04..da6ade8 100644
1321--- a/man/systemd.mount.xml
1322+++ b/man/systemd.mount.xml
1323@@ -476,7 +476,9 @@
1324 <term><varname>Where=</varname></term>
1325 <listitem><para>Takes an absolute path of a file or directory for the mount point; in particular, the
1326 destination cannot be a symbolic link. If the mount point does not exist at the time of mounting, it
1327- is created as directory. This string must be reflected in the unit filename. (See above.) This option
1328+ is created as either a directory or a file. The former is the usual case; the latter is done only if this mount
1329+ is a bind mount and the source (<varname>What=</varname>) is not a directory.
1330+ This string must be reflected in the unit filename. (See above.) This option
1331 is mandatory.</para></listitem>
1332 </varlistentry>
1333
1334diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
1335index 17d2700..95969bf 100644
1336--- a/man/systemd.scope.xml
1337+++ b/man/systemd.scope.xml
1338@@ -105,6 +105,8 @@
1339 of scope units are the following:</para>
1340
1341 <variablelist class='unit-directives'>
1342+ <xi:include href="systemd.service.xml" xpointer="oom-policy" />
1343+
1344 <varlistentry>
1345 <term><varname>RuntimeMaxSec=</varname></term>
1346
1347diff --git a/man/systemd.service.xml b/man/systemd.service.xml
1348index 8d8dd77..6d3537b 100644
1349--- a/man/systemd.service.xml
1350+++ b/man/systemd.service.xml
1351@@ -1120,7 +1120,7 @@
1352 above.</para></listitem>
1353 </varlistentry>
1354
1355- <varlistentry>
1356+ <varlistentry id='oom-policy'>
1357 <term><varname>OOMPolicy=</varname></term>
1358
1359 <listitem><para>Configure the out-of-memory (OOM) kernel killer policy. Note that the userspace OOM
1360@@ -1133,17 +1133,16 @@
1361 for itself, it might decide to kill a running process in order to free up memory and reduce memory
1362 pressure. This setting takes one of <constant>continue</constant>, <constant>stop</constant> or
1363 <constant>kill</constant>. If set to <constant>continue</constant> and a process of the service is
1364- killed by the kernel's OOM killer this is logged but the service continues running. If set to
1365- <constant>stop</constant> the event is logged but the service is terminated cleanly by the service
1366- manager. If set to <constant>kill</constant> and one of the service's processes is killed by the OOM
1367- killer the kernel is instructed to kill all remaining processes of the service too, by setting the
1368+ killed by the OOM killer, this is logged but the unit continues running. If set to
1369+ <constant>stop</constant> the event is logged but the unit is terminated cleanly by the service
1370+ manager. If set to <constant>kill</constant> and one of the unit's processes is killed by the OOM
1371+ killer the kernel is instructed to kill all remaining processes of the unit too, by setting the
1372 <filename>memory.oom.group</filename> attribute to <constant>1</constant>; also see <ulink
1373- url="https://docs.kernel.org/admin-guide/cgroup-v2.html">kernel documentation</ulink>.
1374- </para>
1375+ url="https://docs.kernel.org/admin-guide/cgroup-v2.html">kernel documentation</ulink>.</para>
1376
1377 <para>Defaults to the setting <varname>DefaultOOMPolicy=</varname> in
1378 <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
1379- is set to, except for services where <varname>Delegate=</varname> is turned on, where it defaults to
1380+ is set to, except for units where <varname>Delegate=</varname> is turned on, where it defaults to
1381 <constant>continue</constant>.</para>
1382
1383 <para>Use the <varname>OOMScoreAdjust=</varname> setting to configure whether processes of the unit
1384@@ -1153,10 +1152,9 @@
1385 details.</para>
1386
1387 <para>This setting also applies to <command>systemd-oomd</command>. Similarly to the kernel OOM
1388- kills, this setting determines the state of the service after <command>systemd-oomd</command> kills a
1389- cgroup associated with the service.</para></listitem>
1390+ kills, this setting determines the state of the unit after <command>systemd-oomd</command> kills a
1391+ cgroup associated with it.</para></listitem>
1392 </varlistentry>
1393-
1394 </variablelist>
1395
1396 <para id='shared-unit-options'>Check
1397diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c
1398index b030f45..6063943 100644
1399--- a/src/basic/alloc-util.c
1400+++ b/src/basic/alloc-util.c
1401@@ -102,3 +102,7 @@ void* greedy_realloc0(
1402
1403 return q;
1404 }
1405+
1406+void *expand_to_usable(void *ptr, size_t newsize _unused_) {
1407+ return ptr;
1408+}
1409diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h
1410index b38db7d..bf783b1 100644
1411--- a/src/basic/alloc-util.h
1412+++ b/src/basic/alloc-util.h
1413@@ -2,6 +2,7 @@
1414 #pragma once
1415
1416 #include <alloca.h>
1417+#include <malloc.h>
1418 #include <stddef.h>
1419 #include <stdlib.h>
1420 #include <string.h>
1421@@ -184,17 +185,35 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
1422 # define msan_unpoison(r, s)
1423 #endif
1424
1425-/* This returns the number of usable bytes in a malloc()ed region as per malloc_usable_size(), in a way that
1426- * is compatible with _FORTIFY_SOURCES. If _FORTIFY_SOURCES is used many memory operations will take the
1427- * object size as returned by __builtin_object_size() into account. Hence, let's return the smaller size of
1428- * malloc_usable_size() and __builtin_object_size() here, so that we definitely operate in safe territory by
1429- * both the compiler's and libc's standards. Note that __builtin_object_size() evaluates to SIZE_MAX if the
1430- * size cannot be determined, hence the MIN() expression should be safe with dynamically sized memory,
1431- * too. Moreover, when NULL is passed malloc_usable_size() is documented to return zero, and
1432- * __builtin_object_size() returns SIZE_MAX too, hence we also return a sensible value of 0 in this corner
1433- * case. */
1434+/* Dummy allocator to tell the compiler that the new size of p is newsize. The implementation returns the
1435+ * pointer as is; the only reason for its existence is as a conduit for the _alloc_ attribute. This must not
1436+ * be inlined (hence a non-static function with _noinline_ because LTO otherwise tries to inline it) because
1437+ * gcc then loses the attributes on the function.
1438+ * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96503 */
1439+void *expand_to_usable(void *p, size_t newsize) _alloc_(2) _returns_nonnull_ _noinline_;
1440+
1441+static inline size_t malloc_sizeof_safe(void **xp) {
1442+ if (_unlikely_(!xp || !*xp))
1443+ return 0;
1444+
1445+ size_t sz = malloc_usable_size(*xp);
1446+ *xp = expand_to_usable(*xp, sz);
1447+ /* GCC doesn't see the _returns_nonnull_ when built with ubsan, so yet another hint to make it doubly
1448+ * clear that expand_to_usable won't return NULL.
1449+ * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79265 */
1450+ if (!*xp)
1451+ assert_not_reached();
1452+ return sz;
1453+}
1454+
1455+/* This returns the number of usable bytes in a malloc()ed region as per malloc_usable_size(), which may
1456+ * return a value larger than the size that was actually allocated. Access to that additional memory is
1457+ * discouraged because it violates the C standard; a compiler cannot see that this as valid. To help the
1458+ * compiler out, the MALLOC_SIZEOF_SAFE macro 'allocates' the usable size using a dummy allocator function
1459+ * expand_to_usable. There is a possibility of malloc_usable_size() returning different values during the
1460+ * lifetime of an object, which may cause problems, but the glibc allocator does not do that at the moment. */
1461 #define MALLOC_SIZEOF_SAFE(x) \
1462- MIN(malloc_usable_size(x), __builtin_object_size(x, 0))
1463+ malloc_sizeof_safe((void**) &__builtin_choose_expr(__builtin_constant_p(x), (void*) { NULL }, (x)))
1464
1465 /* Inspired by ELEMENTSOF() but operates on malloc()'ed memory areas: typesafely returns the number of items
1466 * that fit into the specified memory block */
1467diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
1468index b03cc70..17c0170 100644
1469--- a/src/basic/cgroup-util.c
1470+++ b/src/basic/cgroup-util.c
1471@@ -1238,7 +1238,7 @@ static const char *skip_session(const char *p) {
1472 * here. */
1473
1474 if (!session_id_valid(buf))
1475- return false;
1476+ return NULL;
1477
1478 p += n;
1479 p += strspn(p, "/");
1480diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
1481index f68cd36..6a14ea9 100644
1482--- a/src/basic/hashmap.c
1483+++ b/src/basic/hashmap.c
1484@@ -1751,7 +1751,7 @@ HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) {
1485 }
1486
1487 if (r < 0)
1488- return _hashmap_free(copy, false, false);
1489+ return _hashmap_free(copy, NULL, NULL);
1490
1491 return copy;
1492 }
1493diff --git a/src/basic/linux/README b/src/basic/linux/README
1494index 2bb70fd..1abc945 100644
1495--- a/src/basic/linux/README
1496+++ b/src/basic/linux/README
1497@@ -4,3 +4,4 @@ The files in this directory are copied from current kernel master
1498 modifications are applied:
1499 - btrfs.h: drop '__user' attributes
1500 - if.h: drop '#include <linux/compiler.h>' and '__user' attributes
1501+- stddef.h: drop '#include <linux/compiler_types.h>'
1502diff --git a/src/basic/linux/btrfs.h b/src/basic/linux/btrfs.h
1503index 6a0442b..0a53bdc 100644
1504--- a/src/basic/linux/btrfs.h
1505+++ b/src/basic/linux/btrfs.h
1506@@ -19,8 +19,14 @@
1507
1508 #ifndef _UAPI_LINUX_BTRFS_H
1509 #define _UAPI_LINUX_BTRFS_H
1510+
1511+#ifdef __cplusplus
1512+extern "C" {
1513+#endif
1514+
1515 #include <linux/types.h>
1516 #include <linux/ioctl.h>
1517+#include <linux/fs.h>
1518
1519 #define BTRFS_IOCTL_MAGIC 0x94
1520 #define BTRFS_VOL_NAME_MAX 255
1521@@ -93,7 +99,7 @@ struct btrfs_qgroup_inherit {
1522 __u64 num_ref_copies;
1523 __u64 num_excl_copies;
1524 struct btrfs_qgroup_limit lim;
1525- __u64 qgroups[0];
1526+ __u64 qgroups[];
1527 };
1528
1529 struct btrfs_ioctl_qgroup_limit_args {
1530@@ -290,6 +296,12 @@ struct btrfs_ioctl_fs_info_args {
1531 #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1)
1532 #define BTRFS_FEATURE_COMPAT_RO_VERITY (1ULL << 2)
1533
1534+/*
1535+ * Put all block group items into a dedicated block group tree, greatly
1536+ * reducing mount time for large filesystem due to better locality.
1537+ */
1538+#define BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE (1ULL << 3)
1539+
1540 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
1541 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
1542 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
1543@@ -327,6 +339,12 @@ struct btrfs_ioctl_feature_flags {
1544 */
1545 struct btrfs_balance_args {
1546 __u64 profiles;
1547+
1548+ /*
1549+ * usage filter
1550+ * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'
1551+ * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max
1552+ */
1553 union {
1554 __u64 usage;
1555 struct {
1556@@ -543,7 +561,7 @@ struct btrfs_ioctl_search_header {
1557 __u64 offset;
1558 __u32 type;
1559 __u32 len;
1560-};
1561+} __attribute__ ((__may_alias__));
1562
1563 #define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
1564 /*
1565@@ -556,18 +574,23 @@ struct btrfs_ioctl_search_args {
1566 char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
1567 };
1568
1569+/*
1570+ * Extended version of TREE_SEARCH ioctl that can return more than 4k of bytes.
1571+ * The allocated size of the buffer is set in buf_size.
1572+ */
1573 struct btrfs_ioctl_search_args_v2 {
1574 struct btrfs_ioctl_search_key key; /* in/out - search parameters */
1575 __u64 buf_size; /* in - size of buffer
1576 * out - on EOVERFLOW: needed size
1577 * to store item */
1578- __u64 buf[0]; /* out - found items */
1579+ __u64 buf[]; /* out - found items */
1580 };
1581
1582+/* With a @src_length of zero, the range from @src_offset->EOF is cloned! */
1583 struct btrfs_ioctl_clone_range_args {
1584- __s64 src_fd;
1585- __u64 src_offset, src_length;
1586- __u64 dest_offset;
1587+ __s64 src_fd;
1588+ __u64 src_offset, src_length;
1589+ __u64 dest_offset;
1590 };
1591
1592 /*
1593@@ -632,7 +655,7 @@ struct btrfs_ioctl_same_args {
1594 __u16 dest_count; /* in - total elements in info array */
1595 __u16 reserved1;
1596 __u32 reserved2;
1597- struct btrfs_ioctl_same_extent_info info[0];
1598+ struct btrfs_ioctl_same_extent_info info[];
1599 };
1600
1601 struct btrfs_ioctl_space_info {
1602@@ -644,7 +667,7 @@ struct btrfs_ioctl_space_info {
1603 struct btrfs_ioctl_space_args {
1604 __u64 space_slots;
1605 __u64 total_spaces;
1606- struct btrfs_ioctl_space_info spaces[0];
1607+ struct btrfs_ioctl_space_info spaces[];
1608 };
1609
1610 struct btrfs_data_container {
1611@@ -652,7 +675,7 @@ struct btrfs_data_container {
1612 __u32 bytes_missing; /* out -- additional bytes needed for result */
1613 __u32 elem_cnt; /* out */
1614 __u32 elem_missed; /* out */
1615- __u64 val[0]; /* out */
1616+ __u64 val[]; /* out */
1617 };
1618
1619 struct btrfs_ioctl_ino_path_args {
1620@@ -671,8 +694,11 @@ struct btrfs_ioctl_logical_ino_args {
1621 /* struct btrfs_data_container *inodes; out */
1622 __u64 inodes;
1623 };
1624-/* Return every ref to the extent, not just those containing logical block.
1625- * Requires logical == extent bytenr. */
1626+
1627+/*
1628+ * Return every ref to the extent, not just those containing logical block.
1629+ * Requires logical == extent bytenr.
1630+ */
1631 #define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET (1ULL << 0)
1632
1633 enum btrfs_dev_stat_values {
1634@@ -777,11 +803,19 @@ struct btrfs_ioctl_received_subvol_args {
1635 */
1636 #define BTRFS_SEND_FLAG_VERSION 0x8
1637
1638+/*
1639+ * Send compressed data using the ENCODED_WRITE command instead of decompressing
1640+ * the data and sending it with the WRITE command. This requires protocol
1641+ * version >= 2.
1642+ */
1643+#define BTRFS_SEND_FLAG_COMPRESSED 0x10
1644+
1645 #define BTRFS_SEND_FLAG_MASK \
1646 (BTRFS_SEND_FLAG_NO_FILE_DATA | \
1647 BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | \
1648 BTRFS_SEND_FLAG_OMIT_END_CMD | \
1649- BTRFS_SEND_FLAG_VERSION)
1650+ BTRFS_SEND_FLAG_VERSION | \
1651+ BTRFS_SEND_FLAG_COMPRESSED)
1652
1653 struct btrfs_ioctl_send_args {
1654 __s64 send_fd; /* in */
1655@@ -1130,4 +1164,8 @@ enum btrfs_err_code {
1656 #define BTRFS_IOC_ENCODED_WRITE _IOW(BTRFS_IOCTL_MAGIC, 64, \
1657 struct btrfs_ioctl_encoded_io_args)
1658
1659+#ifdef __cplusplus
1660+}
1661+#endif
1662+
1663 #endif /* _UAPI_LINUX_BTRFS_H */
1664diff --git a/src/basic/linux/btrfs_tree.h b/src/basic/linux/btrfs_tree.h
1665index d411715..ab38d0f 100644
1666--- a/src/basic/linux/btrfs_tree.h
1667+++ b/src/basic/linux/btrfs_tree.h
1668@@ -10,6 +10,23 @@
1669 #include <stddef.h>
1670 #endif
1671
1672+/* ASCII for _BHRfS_M, no terminating nul */
1673+#define BTRFS_MAGIC 0x4D5F53665248425FULL
1674+
1675+#define BTRFS_MAX_LEVEL 8
1676+
1677+/*
1678+ * We can actually store much bigger names, but lets not confuse the rest of
1679+ * linux.
1680+ */
1681+#define BTRFS_NAME_LEN 255
1682+
1683+/*
1684+ * Theoretical limit is larger, but we keep this down to a sane value. That
1685+ * should limit greatly the possibility of collisions on inode ref items.
1686+ */
1687+#define BTRFS_LINK_MAX 65535U
1688+
1689 /*
1690 * This header contains the structure definitions and constants used
1691 * by file system objects that can be retrieved using
1692@@ -359,6 +376,50 @@ enum btrfs_csum_type {
1693 #define BTRFS_FT_SYMLINK 7
1694 #define BTRFS_FT_XATTR 8
1695 #define BTRFS_FT_MAX 9
1696+/* Directory contains encrypted data */
1697+#define BTRFS_FT_ENCRYPTED 0x80
1698+
1699+static inline __u8 btrfs_dir_flags_to_ftype(__u8 flags)
1700+{
1701+ return flags & ~BTRFS_FT_ENCRYPTED;
1702+}
1703+
1704+/*
1705+ * Inode flags
1706+ */
1707+#define BTRFS_INODE_NODATASUM (1U << 0)
1708+#define BTRFS_INODE_NODATACOW (1U << 1)
1709+#define BTRFS_INODE_READONLY (1U << 2)
1710+#define BTRFS_INODE_NOCOMPRESS (1U << 3)
1711+#define BTRFS_INODE_PREALLOC (1U << 4)
1712+#define BTRFS_INODE_SYNC (1U << 5)
1713+#define BTRFS_INODE_IMMUTABLE (1U << 6)
1714+#define BTRFS_INODE_APPEND (1U << 7)
1715+#define BTRFS_INODE_NODUMP (1U << 8)
1716+#define BTRFS_INODE_NOATIME (1U << 9)
1717+#define BTRFS_INODE_DIRSYNC (1U << 10)
1718+#define BTRFS_INODE_COMPRESS (1U << 11)
1719+
1720+#define BTRFS_INODE_ROOT_ITEM_INIT (1U << 31)
1721+
1722+#define BTRFS_INODE_FLAG_MASK \
1723+ (BTRFS_INODE_NODATASUM | \
1724+ BTRFS_INODE_NODATACOW | \
1725+ BTRFS_INODE_READONLY | \
1726+ BTRFS_INODE_NOCOMPRESS | \
1727+ BTRFS_INODE_PREALLOC | \
1728+ BTRFS_INODE_SYNC | \
1729+ BTRFS_INODE_IMMUTABLE | \
1730+ BTRFS_INODE_APPEND | \
1731+ BTRFS_INODE_NODUMP | \
1732+ BTRFS_INODE_NOATIME | \
1733+ BTRFS_INODE_DIRSYNC | \
1734+ BTRFS_INODE_COMPRESS | \
1735+ BTRFS_INODE_ROOT_ITEM_INIT)
1736+
1737+#define BTRFS_INODE_RO_VERITY (1U << 0)
1738+
1739+#define BTRFS_INODE_RO_FLAG_MASK (BTRFS_INODE_RO_VERITY)
1740
1741 /*
1742 * The key defines the order in the tree, and so it also defines (optimal)
1743@@ -389,6 +450,109 @@ struct btrfs_key {
1744 __u64 offset;
1745 } __attribute__ ((__packed__));
1746
1747+/*
1748+ * Every tree block (leaf or node) starts with this header.
1749+ */
1750+struct btrfs_header {
1751+ /* These first four must match the super block */
1752+ __u8 csum[BTRFS_CSUM_SIZE];
1753+ /* FS specific uuid */
1754+ __u8 fsid[BTRFS_FSID_SIZE];
1755+ /* Which block this node is supposed to live in */
1756+ __le64 bytenr;
1757+ __le64 flags;
1758+
1759+ /* Allowed to be different from the super from here on down */
1760+ __u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
1761+ __le64 generation;
1762+ __le64 owner;
1763+ __le32 nritems;
1764+ __u8 level;
1765+} __attribute__ ((__packed__));
1766+
1767+/*
1768+ * This is a very generous portion of the super block, giving us room to
1769+ * translate 14 chunks with 3 stripes each.
1770+ */
1771+#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
1772+
1773+/*
1774+ * Just in case we somehow lose the roots and are not able to mount, we store
1775+ * an array of the roots from previous transactions in the super.
1776+ */
1777+#define BTRFS_NUM_BACKUP_ROOTS 4
1778+struct btrfs_root_backup {
1779+ __le64 tree_root;
1780+ __le64 tree_root_gen;
1781+
1782+ __le64 chunk_root;
1783+ __le64 chunk_root_gen;
1784+
1785+ __le64 extent_root;
1786+ __le64 extent_root_gen;
1787+
1788+ __le64 fs_root;
1789+ __le64 fs_root_gen;
1790+
1791+ __le64 dev_root;
1792+ __le64 dev_root_gen;
1793+
1794+ __le64 csum_root;
1795+ __le64 csum_root_gen;
1796+
1797+ __le64 total_bytes;
1798+ __le64 bytes_used;
1799+ __le64 num_devices;
1800+ /* future */
1801+ __le64 unused_64[4];
1802+
1803+ __u8 tree_root_level;
1804+ __u8 chunk_root_level;
1805+ __u8 extent_root_level;
1806+ __u8 fs_root_level;
1807+ __u8 dev_root_level;
1808+ __u8 csum_root_level;
1809+ /* future and to align */
1810+ __u8 unused_8[10];
1811+} __attribute__ ((__packed__));
1812+
1813+/*
1814+ * A leaf is full of items. offset and size tell us where to find the item in
1815+ * the leaf (relative to the start of the data area)
1816+ */
1817+struct btrfs_item {
1818+ struct btrfs_disk_key key;
1819+ __le32 offset;
1820+ __le32 size;
1821+} __attribute__ ((__packed__));
1822+
1823+/*
1824+ * Leaves have an item area and a data area:
1825+ * [item0, item1....itemN] [free space] [dataN...data1, data0]
1826+ *
1827+ * The data is separate from the items to get the keys closer together during
1828+ * searches.
1829+ */
1830+struct btrfs_leaf {
1831+ struct btrfs_header header;
1832+ struct btrfs_item items[];
1833+} __attribute__ ((__packed__));
1834+
1835+/*
1836+ * All non-leaf blocks are nodes, they hold only keys and pointers to other
1837+ * blocks.
1838+ */
1839+struct btrfs_key_ptr {
1840+ struct btrfs_disk_key key;
1841+ __le64 blockptr;
1842+ __le64 generation;
1843+} __attribute__ ((__packed__));
1844+
1845+struct btrfs_node {
1846+ struct btrfs_header header;
1847+ struct btrfs_key_ptr ptrs[];
1848+} __attribute__ ((__packed__));
1849+
1850 struct btrfs_dev_item {
1851 /* the internal btrfs device id */
1852 __le64 devid;
1853@@ -472,6 +636,69 @@ struct btrfs_chunk {
1854 /* additional stripes go here */
1855 } __attribute__ ((__packed__));
1856
1857+/*
1858+ * The super block basically lists the main trees of the FS.
1859+ */
1860+struct btrfs_super_block {
1861+ /* The first 4 fields must match struct btrfs_header */
1862+ __u8 csum[BTRFS_CSUM_SIZE];
1863+ /* FS specific UUID, visible to user */
1864+ __u8 fsid[BTRFS_FSID_SIZE];
1865+ /* This block number */
1866+ __le64 bytenr;
1867+ __le64 flags;
1868+
1869+ /* Allowed to be different from the btrfs_header from here own down */
1870+ __le64 magic;
1871+ __le64 generation;
1872+ __le64 root;
1873+ __le64 chunk_root;
1874+ __le64 log_root;
1875+
1876+ /*
1877+ * This member has never been utilized since the very beginning, thus
1878+ * it's always 0 regardless of kernel version. We always use
1879+ * generation + 1 to read log tree root. So here we mark it deprecated.
1880+ */
1881+ __le64 __unused_log_root_transid;
1882+ __le64 total_bytes;
1883+ __le64 bytes_used;
1884+ __le64 root_dir_objectid;
1885+ __le64 num_devices;
1886+ __le32 sectorsize;
1887+ __le32 nodesize;
1888+ __le32 __unused_leafsize;
1889+ __le32 stripesize;
1890+ __le32 sys_chunk_array_size;
1891+ __le64 chunk_root_generation;
1892+ __le64 compat_flags;
1893+ __le64 compat_ro_flags;
1894+ __le64 incompat_flags;
1895+ __le16 csum_type;
1896+ __u8 root_level;
1897+ __u8 chunk_root_level;
1898+ __u8 log_root_level;
1899+ struct btrfs_dev_item dev_item;
1900+
1901+ char label[BTRFS_LABEL_SIZE];
1902+
1903+ __le64 cache_generation;
1904+ __le64 uuid_tree_generation;
1905+
1906+ /* The UUID written into btree blocks */
1907+ __u8 metadata_uuid[BTRFS_FSID_SIZE];
1908+
1909+ __u64 nr_global_roots;
1910+
1911+ /* Future expansion */
1912+ __le64 reserved[27];
1913+ __u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
1914+ struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
1915+
1916+ /* Padded to 4096 bytes */
1917+ __u8 padding[565];
1918+} __attribute__ ((__packed__));
1919+
1920 #define BTRFS_FREE_SPACE_EXTENT 1
1921 #define BTRFS_FREE_SPACE_BITMAP 2
1922
1923@@ -526,6 +753,14 @@ struct btrfs_extent_item_v0 {
1924 /* use full backrefs for extent pointers in the block */
1925 #define BTRFS_BLOCK_FLAG_FULL_BACKREF (1ULL << 8)
1926
1927+#define BTRFS_BACKREF_REV_MAX 256
1928+#define BTRFS_BACKREF_REV_SHIFT 56
1929+#define BTRFS_BACKREF_REV_MASK (((u64)BTRFS_BACKREF_REV_MAX - 1) << \
1930+ BTRFS_BACKREF_REV_SHIFT)
1931+
1932+#define BTRFS_OLD_BACKREF_REV 0
1933+#define BTRFS_MIXED_BACKREF_REV 1
1934+
1935 /*
1936 * this flag is only used internally by scrub and may be changed at any time
1937 * it is only declared here to avoid collisions
1938@@ -575,7 +810,7 @@ struct btrfs_inode_extref {
1939 __le64 parent_objectid;
1940 __le64 index;
1941 __le16 name_len;
1942- __u8 name[0];
1943+ __u8 name[];
1944 /* name goes here */
1945 } __attribute__ ((__packed__));
1946
1947@@ -965,6 +1200,10 @@ static inline __u16 btrfs_qgroup_level(__u64 qgroupid)
1948 */
1949 #define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1ULL << 2)
1950
1951+#define BTRFS_QGROUP_STATUS_FLAGS_MASK (BTRFS_QGROUP_STATUS_FLAG_ON | \
1952+ BTRFS_QGROUP_STATUS_FLAG_RESCAN | \
1953+ BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT)
1954+
1955 #define BTRFS_QGROUP_STATUS_VERSION 1
1956
1957 struct btrfs_qgroup_status_item {
1958diff --git a/src/basic/linux/genetlink.h b/src/basic/linux/genetlink.h
1959index d83f214..ddba3ca 100644
1960--- a/src/basic/linux/genetlink.h
1961+++ b/src/basic/linux/genetlink.h
1962@@ -87,6 +87,8 @@ enum {
1963 __CTRL_ATTR_MCAST_GRP_MAX,
1964 };
1965
1966+#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
1967+
1968 enum {
1969 CTRL_ATTR_POLICY_UNSPEC,
1970 CTRL_ATTR_POLICY_DO,
1971@@ -96,7 +98,6 @@ enum {
1972 CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1
1973 };
1974
1975-#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
1976-
1977+#define CTRL_ATTR_POLICY_MAX (__CTRL_ATTR_POLICY_DUMP_MAX - 1)
1978
1979 #endif /* _UAPI__LINUX_GENERIC_NETLINK_H */
1980diff --git a/src/basic/linux/if_bridge.h b/src/basic/linux/if_bridge.h
1981index a86a7e7..d9de241 100644
1982--- a/src/basic/linux/if_bridge.h
1983+++ b/src/basic/linux/if_bridge.h
1984@@ -723,10 +723,31 @@ enum {
1985 enum {
1986 MDBE_ATTR_UNSPEC,
1987 MDBE_ATTR_SOURCE,
1988+ MDBE_ATTR_SRC_LIST,
1989+ MDBE_ATTR_GROUP_MODE,
1990+ MDBE_ATTR_RTPROT,
1991 __MDBE_ATTR_MAX,
1992 };
1993 #define MDBE_ATTR_MAX (__MDBE_ATTR_MAX - 1)
1994
1995+/* per mdb entry source */
1996+enum {
1997+ MDBE_SRC_LIST_UNSPEC,
1998+ MDBE_SRC_LIST_ENTRY,
1999+ __MDBE_SRC_LIST_MAX,
2000+};
2001+#define MDBE_SRC_LIST_MAX (__MDBE_SRC_LIST_MAX - 1)
2002+
2003+/* per mdb entry per source attributes
2004+ * these are embedded in MDBE_SRC_LIST_ENTRY
2005+ */
2006+enum {
2007+ MDBE_SRCATTR_UNSPEC,
2008+ MDBE_SRCATTR_ADDRESS,
2009+ __MDBE_SRCATTR_MAX,
2010+};
2011+#define MDBE_SRCATTR_MAX (__MDBE_SRCATTR_MAX - 1)
2012+
2013 /* Embedded inside LINK_XSTATS_TYPE_BRIDGE */
2014 enum {
2015 BRIDGE_XSTATS_UNSPEC,
2016diff --git a/src/basic/linux/if_ether.h b/src/basic/linux/if_ether.h
2017index 1d0bccc..69e0457 100644
2018--- a/src/basic/linux/if_ether.h
2019+++ b/src/basic/linux/if_ether.h
2020@@ -116,6 +116,7 @@
2021 #define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
2022 #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
2023 #define ETH_P_DSA_8021Q 0xDADB /* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
2024+#define ETH_P_DSA_A5PSW 0xE001 /* A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ] */
2025 #define ETH_P_IFE 0xED3E /* ForCES inter-FE LFB type */
2026 #define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
2027
2028@@ -137,6 +138,7 @@
2029 #define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
2030 #define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
2031 #define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
2032+#define ETH_P_CANXL 0x000E /* CANXL: eXtended frame Length */
2033 #define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
2034 #define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
2035 #define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
2036diff --git a/src/basic/linux/if_link.h b/src/basic/linux/if_link.h
2037index 5f58dcf..1021a7e 100644
2038--- a/src/basic/linux/if_link.h
2039+++ b/src/basic/linux/if_link.h
2040@@ -370,6 +370,9 @@ enum {
2041 IFLA_GRO_MAX_SIZE,
2042 IFLA_TSO_MAX_SIZE,
2043 IFLA_TSO_MAX_SEGS,
2044+ IFLA_ALLMULTI, /* Allmulti count: > 0 means acts ALLMULTI */
2045+
2046+ IFLA_DEVLINK_PORT,
2047
2048 __IFLA_MAX
2049 };
2050@@ -560,6 +563,7 @@ enum {
2051 IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
2052 IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
2053 IFLA_BRPORT_LOCKED,
2054+ IFLA_BRPORT_MAB,
2055 __IFLA_BRPORT_MAX
2056 };
2057 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
2058@@ -694,6 +698,7 @@ enum {
2059 IFLA_XFRM_UNSPEC,
2060 IFLA_XFRM_LINK,
2061 IFLA_XFRM_IF_ID,
2062+ IFLA_XFRM_COLLECT_METADATA,
2063 __IFLA_XFRM_MAX
2064 };
2065
2066@@ -963,6 +968,7 @@ enum {
2067 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
2068 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
2069 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
2070+ IFLA_BOND_SLAVE_PRIO,
2071 __IFLA_BOND_SLAVE_MAX,
2072 };
2073
2074@@ -1373,4 +1379,14 @@ enum {
2075
2076 #define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
2077
2078+/* DSA section */
2079+
2080+enum {
2081+ IFLA_DSA_UNSPEC,
2082+ IFLA_DSA_MASTER,
2083+ __IFLA_DSA_MAX,
2084+};
2085+
2086+#define IFLA_DSA_MAX (__IFLA_DSA_MAX - 1)
2087+
2088 #endif /* _UAPI_LINUX_IF_LINK_H */
2089diff --git a/src/basic/linux/if_macsec.h b/src/basic/linux/if_macsec.h
2090index 3af2aa0..d5b6d1f 100644
2091--- a/src/basic/linux/if_macsec.h
2092+++ b/src/basic/linux/if_macsec.h
2093@@ -22,6 +22,8 @@
2094
2095 #define MACSEC_KEYID_LEN 16
2096
2097+#define MACSEC_SALT_LEN 12
2098+
2099 /* cipher IDs as per IEEE802.1AE-2018 (Table 14-1) */
2100 #define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL
2101 #define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL
2102diff --git a/src/basic/linux/if_tun.h b/src/basic/linux/if_tun.h
2103index 454ae31..287cdc8 100644
2104--- a/src/basic/linux/if_tun.h
2105+++ b/src/basic/linux/if_tun.h
2106@@ -67,6 +67,8 @@
2107 #define IFF_TAP 0x0002
2108 #define IFF_NAPI 0x0010
2109 #define IFF_NAPI_FRAGS 0x0020
2110+/* Used in TUNSETIFF to bring up tun/tap without carrier */
2111+#define IFF_NO_CARRIER 0x0040
2112 #define IFF_NO_PI 0x1000
2113 /* This flag has no real effect */
2114 #define IFF_ONE_QUEUE 0x2000
2115@@ -88,6 +90,8 @@
2116 #define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
2117 #define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
2118 #define TUN_F_UFO 0x10 /* I can handle UFO packets */
2119+#define TUN_F_USO4 0x20 /* I can handle USO for IPv4 packets */
2120+#define TUN_F_USO6 0x40 /* I can handle USO for IPv6 packets */
2121
2122 /* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
2123 #define TUN_PKT_STRIP 0x0001
2124@@ -108,7 +112,7 @@ struct tun_pi {
2125 struct tun_filter {
2126 __u16 flags; /* TUN_FLT_ flags see above */
2127 __u16 count; /* Number of addresses */
2128- __u8 addr[0][ETH_ALEN];
2129+ __u8 addr[][ETH_ALEN];
2130 };
2131
2132 #endif /* _UAPI__IF_TUN_H */
2133diff --git a/src/basic/linux/in.h b/src/basic/linux/in.h
2134index 1416822..07a4cb1 100644
2135--- a/src/basic/linux/in.h
2136+++ b/src/basic/linux/in.h
2137@@ -20,6 +20,7 @@
2138 #define _UAPI_LINUX_IN_H
2139
2140 #include <linux/types.h>
2141+#include <linux/stddef.h>
2142 #include <linux/libc-compat.h>
2143 #include <linux/socket.h>
2144
2145@@ -68,6 +69,8 @@ enum {
2146 #define IPPROTO_PIM IPPROTO_PIM
2147 IPPROTO_COMP = 108, /* Compression Header Protocol */
2148 #define IPPROTO_COMP IPPROTO_COMP
2149+ IPPROTO_L2TP = 115, /* Layer 2 Tunnelling Protocol */
2150+#define IPPROTO_L2TP IPPROTO_L2TP
2151 IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
2152 #define IPPROTO_SCTP IPPROTO_SCTP
2153 IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
2154@@ -188,21 +191,13 @@ struct ip_mreq_source {
2155 };
2156
2157 struct ip_msfilter {
2158+ __be32 imsf_multiaddr;
2159+ __be32 imsf_interface;
2160+ __u32 imsf_fmode;
2161+ __u32 imsf_numsrc;
2162 union {
2163- struct {
2164- __be32 imsf_multiaddr_aux;
2165- __be32 imsf_interface_aux;
2166- __u32 imsf_fmode_aux;
2167- __u32 imsf_numsrc_aux;
2168- __be32 imsf_slist[1];
2169- };
2170- struct {
2171- __be32 imsf_multiaddr;
2172- __be32 imsf_interface;
2173- __u32 imsf_fmode;
2174- __u32 imsf_numsrc;
2175- __be32 imsf_slist_flex[];
2176- };
2177+ __be32 imsf_slist[1];
2178+ __DECLARE_FLEX_ARRAY(__be32, imsf_slist_flex);
2179 };
2180 };
2181
2182diff --git a/src/basic/linux/l2tp.h b/src/basic/linux/l2tp.h
2183index bab8c97..7d81c3e 100644
2184--- a/src/basic/linux/l2tp.h
2185+++ b/src/basic/linux/l2tp.h
2186@@ -13,8 +13,6 @@
2187 #include <linux/in.h>
2188 #include <linux/in6.h>
2189
2190-#define IPPROTO_L2TP 115
2191-
2192 /**
2193 * struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets
2194 * @l2tp_family: address family number AF_L2TPIP.
2195diff --git a/src/basic/linux/netfilter/nf_tables.h b/src/basic/linux/netfilter/nf_tables.h
2196index 466fd3f..cfa844d 100644
2197--- a/src/basic/linux/netfilter/nf_tables.h
2198+++ b/src/basic/linux/netfilter/nf_tables.h
2199@@ -97,6 +97,7 @@ enum nft_verdicts {
2200 * @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes)
2201 * @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes)
2202 * @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes)
2203+ * @NFT_MSG_GETRULE_RESET: get rules and reset stateful expressions (enum nft_obj_attributes)
2204 */
2205 enum nf_tables_msg_types {
2206 NFT_MSG_NEWTABLE,
2207@@ -124,6 +125,7 @@ enum nf_tables_msg_types {
2208 NFT_MSG_NEWFLOWTABLE,
2209 NFT_MSG_GETFLOWTABLE,
2210 NFT_MSG_DELFLOWTABLE,
2211+ NFT_MSG_GETRULE_RESET,
2212 NFT_MSG_MAX,
2213 };
2214
2215@@ -760,6 +762,7 @@ enum nft_payload_bases {
2216 NFT_PAYLOAD_NETWORK_HEADER,
2217 NFT_PAYLOAD_TRANSPORT_HEADER,
2218 NFT_PAYLOAD_INNER_HEADER,
2219+ NFT_PAYLOAD_TUN_HEADER,
2220 };
2221
2222 /**
2223@@ -779,6 +782,32 @@ enum nft_payload_csum_flags {
2224 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0),
2225 };
2226
2227+enum nft_inner_type {
2228+ NFT_INNER_UNSPEC = 0,
2229+ NFT_INNER_VXLAN,
2230+ NFT_INNER_GENEVE,
2231+};
2232+
2233+enum nft_inner_flags {
2234+ NFT_INNER_HDRSIZE = (1 << 0),
2235+ NFT_INNER_LL = (1 << 1),
2236+ NFT_INNER_NH = (1 << 2),
2237+ NFT_INNER_TH = (1 << 3),
2238+};
2239+#define NFT_INNER_MASK (NFT_INNER_HDRSIZE | NFT_INNER_LL | \
2240+ NFT_INNER_NH | NFT_INNER_TH)
2241+
2242+enum nft_inner_attributes {
2243+ NFTA_INNER_UNSPEC,
2244+ NFTA_INNER_NUM,
2245+ NFTA_INNER_TYPE,
2246+ NFTA_INNER_FLAGS,
2247+ NFTA_INNER_HDRSIZE,
2248+ NFTA_INNER_EXPR,
2249+ __NFTA_INNER_MAX
2250+};
2251+#define NFTA_INNER_MAX (__NFTA_INNER_MAX - 1)
2252+
2253 /**
2254 * enum nft_payload_attributes - nf_tables payload expression netlink attributes
2255 *
2256diff --git a/src/basic/linux/netlink.h b/src/basic/linux/netlink.h
2257index 855dffb..e2ae82e 100644
2258--- a/src/basic/linux/netlink.h
2259+++ b/src/basic/linux/netlink.h
2260@@ -20,7 +20,7 @@
2261 #define NETLINK_CONNECTOR 11
2262 #define NETLINK_NETFILTER 12 /* netfilter subsystem */
2263 #define NETLINK_IP6_FW 13
2264-#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
2265+#define NETLINK_DNRTMSG 14 /* DECnet routing messages (obsolete) */
2266 #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
2267 #define NETLINK_GENERIC 16
2268 /* leave room for NETLINK_DM (DM Events) */
2269@@ -41,12 +41,20 @@ struct sockaddr_nl {
2270 __u32 nl_groups; /* multicast groups mask */
2271 };
2272
2273+/**
2274+ * struct nlmsghdr - fixed format metadata header of Netlink messages
2275+ * @nlmsg_len: Length of message including header
2276+ * @nlmsg_type: Message content type
2277+ * @nlmsg_flags: Additional flags
2278+ * @nlmsg_seq: Sequence number
2279+ * @nlmsg_pid: Sending process port ID
2280+ */
2281 struct nlmsghdr {
2282- __u32 nlmsg_len; /* Length of message including header */
2283- __u16 nlmsg_type; /* Message content */
2284- __u16 nlmsg_flags; /* Additional flags */
2285- __u32 nlmsg_seq; /* Sequence number */
2286- __u32 nlmsg_pid; /* Sending process port ID */
2287+ __u32 nlmsg_len;
2288+ __u16 nlmsg_type;
2289+ __u16 nlmsg_flags;
2290+ __u32 nlmsg_seq;
2291+ __u32 nlmsg_pid;
2292 };
2293
2294 /* Flags values */
2295@@ -54,7 +62,7 @@ struct nlmsghdr {
2296 #define NLM_F_REQUEST 0x01 /* It is request message. */
2297 #define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */
2298 #define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */
2299-#define NLM_F_ECHO 0x08 /* Echo this request */
2300+#define NLM_F_ECHO 0x08 /* Receive resulting notifications */
2301 #define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */
2302 #define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */
2303
2304@@ -132,6 +140,10 @@ struct nlmsgerr {
2305 * be used - in the success case - to identify a created
2306 * object or operation or similar (binary)
2307 * @NLMSGERR_ATTR_POLICY: policy for a rejected attribute
2308+ * @NLMSGERR_ATTR_MISS_TYPE: type of a missing required attribute,
2309+ * %NLMSGERR_ATTR_MISS_NEST will not be present if the attribute was
2310+ * missing at the message level
2311+ * @NLMSGERR_ATTR_MISS_NEST: offset of the nest where attribute was missing
2312 * @__NLMSGERR_ATTR_MAX: number of attributes
2313 * @NLMSGERR_ATTR_MAX: highest attribute number
2314 */
2315@@ -141,6 +153,8 @@ enum nlmsgerr_attrs {
2316 NLMSGERR_ATTR_OFFS,
2317 NLMSGERR_ATTR_COOKIE,
2318 NLMSGERR_ATTR_POLICY,
2319+ NLMSGERR_ATTR_MISS_TYPE,
2320+ NLMSGERR_ATTR_MISS_NEST,
2321
2322 __NLMSGERR_ATTR_MAX,
2323 NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
2324@@ -337,6 +351,9 @@ enum netlink_attribute_type {
2325 * bitfield32 type (U32)
2326 * @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64)
2327 * @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment
2328+ *
2329+ * @__NL_POLICY_TYPE_ATTR_MAX: number of attributes
2330+ * @NL_POLICY_TYPE_ATTR_MAX: highest attribute number
2331 */
2332 enum netlink_policy_type_attr {
2333 NL_POLICY_TYPE_ATTR_UNSPEC,
2334diff --git a/src/basic/linux/nl80211.h b/src/basic/linux/nl80211.h
2335index d9490e3..c14a91b 100644
2336--- a/src/basic/linux/nl80211.h
2337+++ b/src/basic/linux/nl80211.h
2338@@ -324,6 +324,17 @@
2339 */
2340
2341 /**
2342+ * DOC: Multi-Link Operation
2343+ *
2344+ * In Multi-Link Operation, a connection between to MLDs utilizes multiple
2345+ * links. To use this in nl80211, various commands and responses now need
2346+ * to or will include the new %NL80211_ATTR_MLO_LINKS attribute.
2347+ * Additionally, various commands that need to operate on a specific link
2348+ * now need to be given the %NL80211_ATTR_MLO_LINK_ID attribute, e.g. to
2349+ * use %NL80211_CMD_START_AP or similar functions.
2350+ */
2351+
2352+/**
2353 * enum nl80211_commands - supported nl80211 commands
2354 *
2355 * @NL80211_CMD_UNSPEC: unspecified command to catch errors
2356@@ -366,14 +377,22 @@
2357 * the non-transmitting interfaces are deleted as well.
2358 *
2359 * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
2360- * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
2361+ * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. %NL80211_ATTR_MAC
2362+ * represents peer's MLD address for MLO pairwise key. For MLO group key,
2363+ * the link is identified by %NL80211_ATTR_MLO_LINK_ID.
2364 * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
2365 * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
2366+ * For MLO connection, the link to set default key is identified by
2367+ * %NL80211_ATTR_MLO_LINK_ID.
2368 * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
2369 * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
2370- * and %NL80211_ATTR_KEY_SEQ attributes.
2371+ * and %NL80211_ATTR_KEY_SEQ attributes. %NL80211_ATTR_MAC represents
2372+ * peer's MLD address for MLO pairwise key. The link to add MLO
2373+ * group key is identified by %NL80211_ATTR_MLO_LINK_ID.
2374 * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
2375- * or %NL80211_ATTR_MAC.
2376+ * or %NL80211_ATTR_MAC. %NL80211_ATTR_MAC represents peer's MLD address
2377+ * for MLO pairwise key. The link to delete group key is identified by
2378+ * %NL80211_ATTR_MLO_LINK_ID.
2379 *
2380 * @NL80211_CMD_GET_BEACON: (not used)
2381 * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface
2382@@ -753,6 +772,13 @@
2383 * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
2384 * counters which will be updated to the current value. This attribute
2385 * is used during CSA period.
2386+ * For TX on an MLD, the frequency can be omitted and the link ID be
2387+ * specified, or if transmitting to a known peer MLD (with MLD addresses
2388+ * in the frame) both can be omitted and the link will be selected by
2389+ * lower layers.
2390+ * For RX notification, %NL80211_ATTR_RX_HW_TIMESTAMP may be included to
2391+ * indicate the frame RX timestamp and %NL80211_ATTR_TX_HW_TIMESTAMP may
2392+ * be included to indicate the ack TX timestamp.
2393 * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
2394 * command may be used with the corresponding cookie to cancel the wait
2395 * time if it is known that it is no longer necessary. This command is
2396@@ -763,7 +789,9 @@
2397 * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
2398 * the TX command and %NL80211_ATTR_FRAME includes the contents of the
2399 * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged
2400- * the frame.
2401+ * the frame. %NL80211_ATTR_TX_HW_TIMESTAMP may be included to indicate the
2402+ * tx timestamp and %NL80211_ATTR_RX_HW_TIMESTAMP may be included to
2403+ * indicate the ack RX timestamp.
2404 * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for
2405 * backward compatibility.
2406 *
2407@@ -1108,6 +1136,12 @@
2408 * has been received. %NL80211_ATTR_FRAME is used to specify the
2409 * frame contents. The frame is the raw EAPoL data, without ethernet or
2410 * 802.11 headers.
2411+ * For an MLD transmitter, the %NL80211_ATTR_MLO_LINK_ID may be given and
2412+ * its effect will depend on the destination: If the destination is known
2413+ * to be an MLD, this will be used as a hint to select the link to transmit
2414+ * the frame on. If the destination is not an MLD, this will select both
2415+ * the link to transmit on and the source address will be set to the link
2416+ * address of that link.
2417 * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
2418 * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
2419 * indicating the protocol type of the received frame; whether the frame
2420@@ -1237,6 +1271,16 @@
2421 * to describe the BSSID address of the AP and %NL80211_ATTR_TIMEOUT to
2422 * specify the timeout value.
2423 *
2424+ * @NL80211_CMD_ADD_LINK: Add a new link to an interface. The
2425+ * %NL80211_ATTR_MLO_LINK_ID attribute is used for the new link.
2426+ * @NL80211_CMD_REMOVE_LINK: Remove a link from an interface. This may come
2427+ * without %NL80211_ATTR_MLO_LINK_ID as an easy way to remove all links
2428+ * in preparation for e.g. roaming to a regular (non-MLO) AP.
2429+ *
2430+ * @NL80211_CMD_ADD_LINK_STA: Add a link to an MLD station
2431+ * @NL80211_CMD_MODIFY_LINK_STA: Modify a link of an MLD station
2432+ * @NL80211_CMD_REMOVE_LINK_STA: Remove a link of an MLD station
2433+ *
2434 * @NL80211_CMD_MAX: highest used command number
2435 * @__NL80211_CMD_AFTER_LAST: internal use
2436 */
2437@@ -1481,6 +1525,13 @@ enum nl80211_commands {
2438
2439 NL80211_CMD_ASSOC_COMEBACK,
2440
2441+ NL80211_CMD_ADD_LINK,
2442+ NL80211_CMD_REMOVE_LINK,
2443+
2444+ NL80211_CMD_ADD_LINK_STA,
2445+ NL80211_CMD_MODIFY_LINK_STA,
2446+ NL80211_CMD_REMOVE_LINK_STA,
2447+
2448 /* add new commands above here */
2449
2450 /* used to define NL80211_CMD_MAX below */
2451@@ -2340,8 +2391,10 @@ enum nl80211_commands {
2452 *
2453 * @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes:
2454 * %NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
2455- * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
2456- * interface type.
2457+ * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities and
2458+ * other interface-type specific capabilities per interface type. For MLO,
2459+ * %NL80211_ATTR_EML_CAPABILITY and %NL80211_ATTR_MLD_CAPA_AND_OPS are
2460+ * present.
2461 *
2462 * @NL80211_ATTR_MU_MIMO_GROUP_DATA: array of 24 bytes that defines a MU-MIMO
2463 * groupID for monitor mode.
2464@@ -2663,6 +2716,41 @@ enum nl80211_commands {
2465 * association request when used with NL80211_CMD_NEW_STATION). Can be set
2466 * only if %NL80211_STA_FLAG_WME is set.
2467 *
2468+ * @NL80211_ATTR_MLO_LINK_ID: A (u8) link ID for use with MLO, to be used with
2469+ * various commands that need a link ID to operate.
2470+ * @NL80211_ATTR_MLO_LINKS: A nested array of links, each containing some
2471+ * per-link information and a link ID.
2472+ * @NL80211_ATTR_MLD_ADDR: An MLD address, used with various commands such as
2473+ * authenticate/associate.
2474+ *
2475+ * @NL80211_ATTR_MLO_SUPPORT: Flag attribute to indicate user space supports MLO
2476+ * connection. Used with %NL80211_CMD_CONNECT. If this attribute is not
2477+ * included in NL80211_CMD_CONNECT drivers must not perform MLO connection.
2478+ *
2479+ * @NL80211_ATTR_MAX_NUM_AKM_SUITES: U16 attribute. Indicates maximum number of
2480+ * AKM suites allowed for %NL80211_CMD_CONNECT, %NL80211_CMD_ASSOCIATE and
2481+ * %NL80211_CMD_START_AP in %NL80211_CMD_GET_WIPHY response. If this
2482+ * attribute is not present userspace shall consider maximum number of AKM
2483+ * suites allowed as %NL80211_MAX_NR_AKM_SUITES which is the legacy maximum
2484+ * number prior to the introduction of this attribute.
2485+ *
2486+ * @NL80211_ATTR_EML_CAPABILITY: EML Capability information (u16)
2487+ * @NL80211_ATTR_MLD_CAPA_AND_OPS: MLD Capabilities and Operations (u16)
2488+ *
2489+ * @NL80211_ATTR_TX_HW_TIMESTAMP: Hardware timestamp for TX operation in
2490+ * nanoseconds (u64). This is the device clock timestamp so it will
2491+ * probably reset when the device is stopped or the firmware is reset.
2492+ * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the frame TX
2493+ * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
2494+ * the ack TX timestamp.
2495+ * @NL80211_ATTR_RX_HW_TIMESTAMP: Hardware timestamp for RX operation in
2496+ * nanoseconds (u64). This is the device clock timestamp so it will
2497+ * probably reset when the device is stopped or the firmware is reset.
2498+ * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX
2499+ * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
2500+ * the incoming frame RX timestamp.
2501+ * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
2502+ * (re)associations.
2503 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
2504 * @NL80211_ATTR_MAX: highest attribute number currently defined
2505 * @__NL80211_ATTR_AFTER_LAST: internal use
2506@@ -3177,6 +3265,21 @@ enum nl80211_attrs {
2507
2508 NL80211_ATTR_DISABLE_EHT,
2509
2510+ NL80211_ATTR_MLO_LINKS,
2511+ NL80211_ATTR_MLO_LINK_ID,
2512+ NL80211_ATTR_MLD_ADDR,
2513+
2514+ NL80211_ATTR_MLO_SUPPORT,
2515+
2516+ NL80211_ATTR_MAX_NUM_AKM_SUITES,
2517+
2518+ NL80211_ATTR_EML_CAPABILITY,
2519+ NL80211_ATTR_MLD_CAPA_AND_OPS,
2520+
2521+ NL80211_ATTR_TX_HW_TIMESTAMP,
2522+ NL80211_ATTR_RX_HW_TIMESTAMP,
2523+ NL80211_ATTR_TD_BITMAP,
2524+
2525 /* add attributes here, update the policy in nl80211.c */
2526
2527 __NL80211_ATTR_AFTER_LAST,
2528@@ -3231,6 +3334,11 @@ enum nl80211_attrs {
2529 #define NL80211_HE_MIN_CAPABILITY_LEN 16
2530 #define NL80211_HE_MAX_CAPABILITY_LEN 54
2531 #define NL80211_MAX_NR_CIPHER_SUITES 5
2532+
2533+/*
2534+ * NL80211_MAX_NR_AKM_SUITES is obsolete when %NL80211_ATTR_MAX_NUM_AKM_SUITES
2535+ * present in %NL80211_CMD_GET_WIPHY response.
2536+ */
2537 #define NL80211_MAX_NR_AKM_SUITES 2
2538 #define NL80211_EHT_MIN_CAPABILITY_LEN 13
2539 #define NL80211_EHT_MAX_CAPABILITY_LEN 51
2540@@ -4853,6 +4961,8 @@ enum nl80211_bss_scan_width {
2541 * Contains a nested array of signal strength attributes (u8, dBm),
2542 * using the nesting index as the antenna number.
2543 * @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
2544+ * @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8).
2545+ * @NL80211_BSS_MLD_ADDR: MLD address of this BSS if connected to it.
2546 * @__NL80211_BSS_AFTER_LAST: internal
2547 * @NL80211_BSS_MAX: highest BSS attribute
2548 */
2549@@ -4878,6 +4988,8 @@ enum nl80211_bss {
2550 NL80211_BSS_PARENT_BSSID,
2551 NL80211_BSS_CHAIN_SIGNAL,
2552 NL80211_BSS_FREQUENCY_OFFSET,
2553+ NL80211_BSS_MLO_LINK_ID,
2554+ NL80211_BSS_MLD_ADDR,
2555
2556 /* keep last */
2557 __NL80211_BSS_AFTER_LAST,
2558@@ -5874,7 +5986,7 @@ enum nl80211_ap_sme_features {
2559 * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up
2560 * the connected inactive stations in AP mode.
2561 * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
2562- * to work properly to suppport receiving regulatory hints from
2563+ * to work properly to support receiving regulatory hints from
2564 * cellular base stations.
2565 * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
2566 * here to reserve the value for API/ABI compatibility)
2567@@ -6174,6 +6286,14 @@ enum nl80211_feature_flags {
2568 * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC
2569 * detection.
2570 *
2571+ * @NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE: Device can perform a MAC address
2572+ * change without having to bring the underlying network device down
2573+ * first. For example, in station mode this can be used to vary the
2574+ * origin MAC address prior to a connection to a new AP for privacy
2575+ * or other reasons. Note that certain driver specific restrictions
2576+ * might apply, e.g. no scans in progress, no offchannel operations
2577+ * in progress, and no active connections.
2578+ *
2579 * @NUM_NL80211_EXT_FEATURES: number of extended features.
2580 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
2581 */
2582@@ -6241,6 +6361,7 @@ enum nl80211_ext_feature_index {
2583 NL80211_EXT_FEATURE_BSS_COLOR,
2584 NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
2585 NL80211_EXT_FEATURE_RADAR_BACKGROUND,
2586+ NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
2587
2588 /* add new features before the definition below */
2589 NUM_NL80211_EXT_FEATURES,
2590diff --git a/src/basic/linux/pkt_sched.h b/src/basic/linux/pkt_sched.h
2591index f292b46..000eec1 100644
2592--- a/src/basic/linux/pkt_sched.h
2593+++ b/src/basic/linux/pkt_sched.h
2594@@ -1233,6 +1233,16 @@ enum {
2595 #define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD _BITUL(1)
2596
2597 enum {
2598+ TCA_TAPRIO_TC_ENTRY_UNSPEC,
2599+ TCA_TAPRIO_TC_ENTRY_INDEX, /* u32 */
2600+ TCA_TAPRIO_TC_ENTRY_MAX_SDU, /* u32 */
2601+
2602+ /* add new constants above here */
2603+ __TCA_TAPRIO_TC_ENTRY_CNT,
2604+ TCA_TAPRIO_TC_ENTRY_MAX = (__TCA_TAPRIO_TC_ENTRY_CNT - 1)
2605+};
2606+
2607+enum {
2608 TCA_TAPRIO_ATTR_UNSPEC,
2609 TCA_TAPRIO_ATTR_PRIOMAP, /* struct tc_mqprio_qopt */
2610 TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST, /* nested of entry */
2611@@ -1245,6 +1255,7 @@ enum {
2612 TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION, /* s64 */
2613 TCA_TAPRIO_ATTR_FLAGS, /* u32 */
2614 TCA_TAPRIO_ATTR_TXTIME_DELAY, /* u32 */
2615+ TCA_TAPRIO_ATTR_TC_ENTRY, /* nest */
2616 __TCA_TAPRIO_ATTR_MAX,
2617 };
2618
2619diff --git a/src/basic/linux/rtnetlink.h b/src/basic/linux/rtnetlink.h
2620index 83849a3..eb2747d 100644
2621--- a/src/basic/linux/rtnetlink.h
2622+++ b/src/basic/linux/rtnetlink.h
2623@@ -440,7 +440,7 @@ struct rtnexthop {
2624 /* RTA_VIA */
2625 struct rtvia {
2626 __kernel_sa_family_t rtvia_family;
2627- __u8 rtvia_addr[0];
2628+ __u8 rtvia_addr[];
2629 };
2630
2631 /* RTM_CACHEINFO */
2632diff --git a/src/basic/linux/stddef.h b/src/basic/linux/stddef.h
2633new file mode 100644
2634index 0000000..1a73963
2635--- /dev/null
2636+++ b/src/basic/linux/stddef.h
2637@@ -0,0 +1,46 @@
2638+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2639+#ifndef _UAPI_LINUX_STDDEF_H
2640+#define _UAPI_LINUX_STDDEF_H
2641+
2642+
2643+#ifndef __always_inline
2644+#define __always_inline inline
2645+#endif
2646+
2647+/**
2648+ * __struct_group() - Create a mirrored named and anonyomous struct
2649+ *
2650+ * @TAG: The tag name for the named sub-struct (usually empty)
2651+ * @NAME: The identifier name of the mirrored sub-struct
2652+ * @ATTRS: Any struct attributes (usually empty)
2653+ * @MEMBERS: The member declarations for the mirrored structs
2654+ *
2655+ * Used to create an anonymous union of two structs with identical layout
2656+ * and size: one anonymous and one named. The former's members can be used
2657+ * normally without sub-struct naming, and the latter can be used to
2658+ * reason about the start, end, and size of the group of struct members.
2659+ * The named struct can also be explicitly tagged for layer reuse, as well
2660+ * as both having struct attributes appended.
2661+ */
2662+#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
2663+ union { \
2664+ struct { MEMBERS } ATTRS; \
2665+ struct TAG { MEMBERS } ATTRS NAME; \
2666+ }
2667+
2668+/**
2669+ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
2670+ *
2671+ * @TYPE: The type of each flexible array element
2672+ * @NAME: The name of the flexible array member
2673+ *
2674+ * In order to have a flexible array member in a union or alone in a
2675+ * struct, it needs to be wrapped in an anonymous struct with at least 1
2676+ * named member, but that member can be empty.
2677+ */
2678+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
2679+ struct { \
2680+ struct { } __empty_ ## NAME; \
2681+ TYPE NAME[]; \
2682+ }
2683+#endif
2684diff --git a/src/basic/linux/update.sh b/src/basic/linux/update.sh
2685index 72e133d..6aff039 100755
2686--- a/src/basic/linux/update.sh
2687+++ b/src/basic/linux/update.sh
2688@@ -6,5 +6,5 @@ set -o pipefail
2689 for i in *.h */*.h; do
2690 curl --fail "https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/$i" -o "$i"
2691
2692- sed -i -e 's/__user //g' -e '/^#include <linux\/compiler.h>/ d' "$i"
2693+ sed -r -i -e 's/__user //g' -e '/^#include <linux\/compiler(_types)?.h>/ d' "$i"
2694 done
2695diff --git a/src/basic/virt.c b/src/basic/virt.c
2696index f800bba..c6914d5 100644
2697--- a/src/basic/virt.c
2698+++ b/src/basic/virt.c
2699@@ -778,7 +778,7 @@ translate_name:
2700 /* Some images hardcode container=oci, but OCI is not a specific container manager.
2701 * Try to detect one based on well-known files. */
2702 v = detect_container_files();
2703- if (v != VIRTUALIZATION_NONE)
2704+ if (v == VIRTUALIZATION_NONE)
2705 v = VIRTUALIZATION_CONTAINER_OTHER;
2706 goto finish;
2707 }
2708diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
2709index 25a0215..1f4a7db 100644
2710--- a/src/boot/efi/boot.c
2711+++ b/src/boot/efi/boot.c
2712@@ -1573,7 +1573,7 @@ static EFI_STATUS efivar_get_timeout(const char16_t *var, uint32_t *ret_value) {
2713
2714 static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
2715 _cleanup_free_ char *content = NULL;
2716- UINTN value;
2717+ UINTN value = 0; /* avoid false maybe-uninitialized warning */
2718 EFI_STATUS err;
2719
2720 assert(root_dir);
2721@@ -2257,7 +2257,7 @@ static void config_load_xbootldr(
2722 EFI_HANDLE *device) {
2723
2724 _cleanup_(file_closep) EFI_FILE *root_dir = NULL;
2725- EFI_HANDLE new_device;
2726+ EFI_HANDLE new_device = NULL; /* avoid false maybe-uninitialized warning */
2727 EFI_STATUS err;
2728
2729 assert(config);
2730@@ -2319,6 +2319,9 @@ static EFI_STATUS initrd_prepare(
2731 if (err != EFI_SUCCESS)
2732 return err;
2733
2734+ if (info->FileSize == 0) /* Automatically skip over empty files */
2735+ continue;
2736+
2737 UINTN new_size, read_size = info->FileSize;
2738 if (__builtin_add_overflow(size, read_size, &new_size))
2739 return EFI_OUT_OF_RESOURCES;
2740diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
2741index cd980fd..14c0008 100644
2742--- a/src/boot/efi/console.c
2743+++ b/src/boot/efi/console.c
2744@@ -12,20 +12,6 @@
2745 #define VERTICAL_MAX_OK 1080
2746 #define VIEWPORT_RATIO 10
2747
2748-static EFI_STATUS console_connect(void) {
2749- EFI_BOOT_MANAGER_POLICY_PROTOCOL *boot_policy;
2750- EFI_STATUS err;
2751-
2752- /* This should make console devices appear/fully initialize on fastboot firmware. */
2753-
2754- err = BS->LocateProtocol(
2755- &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID, NULL, (void **) &boot_policy);
2756- if (err != EFI_SUCCESS)
2757- return err;
2758-
2759- return boot_policy->ConnectDeviceClass(boot_policy, &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID);
2760-}
2761-
2762 static inline void event_closep(EFI_EVENT *event) {
2763 if (!*event)
2764 return;
2765@@ -61,8 +47,6 @@ EFI_STATUS console_key_read(uint64_t *key, uint64_t timeout_usec) {
2766 assert(key);
2767
2768 if (!checked) {
2769- console_connect();
2770-
2771 /* Get the *first* TextInputEx device.*/
2772 err = BS->LocateProtocol(&SimpleTextInputExProtocol, NULL, (void **) &extraInEx);
2773 if (err != EFI_SUCCESS || BS->CheckEvent(extraInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
2774diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c
2775index 76e2cd7..79b5d43 100644
2776--- a/src/boot/efi/cpio.c
2777+++ b/src/boot/efi/cpio.c
2778@@ -468,7 +468,7 @@ EFI_STATUS pack_cpio(
2779
2780 for (UINTN i = 0; i < n_items; i++) {
2781 _cleanup_free_ char *content = NULL;
2782- UINTN contentsize;
2783+ UINTN contentsize = 0; /* avoid false maybe-uninitialized warning */
2784
2785 err = file_read(extra_dir, items[i], 0, 0, &content, &contentsize);
2786 if (err != EFI_SUCCESS) {
2787diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
2788index 0de4399..fa61c3e 100644
2789--- a/src/boot/efi/meson.build
2790+++ b/src/boot/efi/meson.build
2791@@ -55,6 +55,7 @@ if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64',
2792 endif
2793
2794 objcopy = run_command(cc.cmd_array(), '-print-prog-name=objcopy', check: true).stdout().strip()
2795+objcopy_2_38 = find_program('objcopy', version: '>=2.38', required: false)
2796
2797 efi_ld = get_option('efi-ld')
2798 if efi_ld == 'auto'
2799@@ -283,9 +284,17 @@ foreach arg : ['-Wl,--no-warn-execstack',
2800 endif
2801 endforeach
2802
2803-if efi_arch[1] in ['aarch64', 'arm', 'riscv64']
2804+# If using objcopy, crt0 must not include the PE/COFF header
2805+if run_command('grep', '-q', 'coff_header', efi_crt0, check: false).returncode() == 0
2806+ coff_header_in_crt0 = true
2807+else
2808+ coff_header_in_crt0 = false
2809+endif
2810+
2811+if efi_arch[1] in ['arm', 'riscv64'] or (efi_arch[1] == 'aarch64' and (not objcopy_2_38.found() or coff_header_in_crt0))
2812 efi_ldflags += ['-shared']
2813- # Aarch64, ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
2814+ # ARM32 and 64bit RISC-V don't have an EFI capable objcopy.
2815+ # Older objcopy doesn't support Aarch64 either.
2816 # Use 'binary' instead, and add required symbols manually.
2817 efi_ldflags += ['-Wl,--defsym=EFI_SUBSYSTEM=0xa']
2818 efi_format = ['-O', 'binary']
2819diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h
2820index b446e03..250c84c 100644
2821--- a/src/boot/efi/missing_efi.h
2822+++ b/src/boot/efi/missing_efi.h
2823@@ -398,22 +398,3 @@ typedef struct {
2824 void *StdErr;
2825 } EFI_SHELL_PARAMETERS_PROTOCOL;
2826 #endif
2827-
2828-#ifndef EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID
2829-#define EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID \
2830- { 0xFEDF8E0C, 0xE147, 0x11E3, { 0x99, 0x03, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
2831-#define EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID \
2832- { 0xCAB0E94C, 0xE15F, 0x11E3, { 0x91, 0x8D, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
2833-
2834-typedef struct EFI_BOOT_MANAGER_POLICY_PROTOCOL EFI_BOOT_MANAGER_POLICY_PROTOCOL;
2835-struct EFI_BOOT_MANAGER_POLICY_PROTOCOL {
2836- UINT64 Revision;
2837- EFI_STATUS (EFIAPI *ConnectDevicePath)(
2838- EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
2839- EFI_DEVICE_PATH *DevicePath,
2840- BOOLEAN Recursive);
2841- EFI_STATUS (EFIAPI *ConnectDeviceClass)(
2842- EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
2843- EFI_GUID *Class);
2844-};
2845-#endif
2846diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
2847index 65457bf..6212868 100644
2848--- a/src/boot/efi/secure-boot.c
2849+++ b/src/boot/efi/secure-boot.c
2850@@ -6,7 +6,7 @@
2851 #include "util.h"
2852
2853 bool secure_boot_enabled(void) {
2854- bool secure;
2855+ bool secure = false; /* avoid false maybe-uninitialized warning */
2856 EFI_STATUS err;
2857
2858 err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure);
2859diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
2860index f9aeeb4..51e483e 100644
2861--- a/src/boot/efi/util.c
2862+++ b/src/boot/efi/util.c
2863@@ -309,9 +309,11 @@ EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, UINTN off, UINTN size,
2864 UINTN extra = size % sizeof(char16_t) + sizeof(char16_t);
2865
2866 buf = xmalloc(size + extra);
2867- err = handle->Read(handle, &size, buf);
2868- if (err != EFI_SUCCESS)
2869- return err;
2870+ if (size > 0) {
2871+ err = handle->Read(handle, &size, buf);
2872+ if (err != EFI_SUCCESS)
2873+ return err;
2874+ }
2875
2876 /* Note that handle->Read() changes size to reflect the actually bytes read. */
2877 memset(buf + size, 0, extra);
2878diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
2879index f57a5d6..cc2d0e3 100644
2880--- a/src/busctl/busctl.c
2881+++ b/src/busctl/busctl.c
2882@@ -1022,10 +1022,11 @@ static int introspect(int argc, char **argv, void *userdata) {
2883
2884 for (;;) {
2885 Member *z;
2886- _cleanup_free_ char *buf = NULL;
2887+ _cleanup_free_ char *buf = NULL, *signature = NULL;
2888 _cleanup_fclose_ FILE *mf = NULL;
2889 size_t sz = 0;
2890- const char *name;
2891+ const char *name, *contents;
2892+ char type;
2893
2894 r = sd_bus_message_enter_container(reply, 'e', "sv");
2895 if (r < 0)
2896@@ -1042,6 +1043,21 @@ static int introspect(int argc, char **argv, void *userdata) {
2897 if (r < 0)
2898 return bus_log_parse_error(r);
2899
2900+ r = sd_bus_message_peek_type(reply, &type, &contents);
2901+ if (r <= 0)
2902+ return bus_log_parse_error(r == 0 ? EINVAL : r);
2903+
2904+ if (type == SD_BUS_TYPE_STRUCT_BEGIN)
2905+ signature = strjoin(CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END));
2906+ else if (type == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2907+ signature = strjoin(CHAR_TO_STR(SD_BUS_TYPE_DICT_ENTRY_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_DICT_ENTRY_END));
2908+ else if (contents)
2909+ signature = strjoin(CHAR_TO_STR(type), contents);
2910+ else
2911+ signature = strdup(CHAR_TO_STR(type));
2912+ if (!signature)
2913+ return log_oom();
2914+
2915 mf = open_memstream_unlocked(&buf, &sz);
2916 if (!mf)
2917 return log_oom();
2918@@ -1055,6 +1071,7 @@ static int introspect(int argc, char **argv, void *userdata) {
2919 z = set_get(members, &((Member) {
2920 .type = "property",
2921 .interface = m->interface,
2922+ .signature = signature,
2923 .name = (char*) name }));
2924 if (z)
2925 free_and_replace(z->value, buf);
2926diff --git a/src/core/cgroup.c b/src/core/cgroup.c
2927index 4c0a821..ba26066 100644
2928--- a/src/core/cgroup.c
2929+++ b/src/core/cgroup.c
2930@@ -2471,7 +2471,7 @@ static bool unit_has_mask_enables_realized(
2931 ((u->cgroup_enabled_mask | enable_mask) & CGROUP_MASK_V2) == (u->cgroup_enabled_mask & CGROUP_MASK_V2);
2932 }
2933
2934-static void unit_add_to_cgroup_realize_queue(Unit *u) {
2935+void unit_add_to_cgroup_realize_queue(Unit *u) {
2936 assert(u);
2937
2938 if (u->in_cgroup_realize_queue)
2939diff --git a/src/core/cgroup.h b/src/core/cgroup.h
2940index 4413eea..49fbd4f 100644
2941--- a/src/core/cgroup.h
2942+++ b/src/core/cgroup.h
2943@@ -262,6 +262,7 @@ int unit_realize_cgroup(Unit *u);
2944 void unit_prune_cgroup(Unit *u);
2945 int unit_watch_cgroup(Unit *u);
2946 int unit_watch_cgroup_memory(Unit *u);
2947+void unit_add_to_cgroup_realize_queue(Unit *u);
2948
2949 void unit_release_cgroup(Unit *u);
2950 /* Releases the cgroup only if it is recursively empty.
2951diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
2952index 7d2ceb0..7b07bb8 100644
2953--- a/src/core/dbus-scope.c
2954+++ b/src/core/dbus-scope.c
2955@@ -5,6 +5,7 @@
2956 #include "bus-get-properties.h"
2957 #include "dbus-cgroup.h"
2958 #include "dbus-kill.h"
2959+#include "dbus-manager.h"
2960 #include "dbus-scope.h"
2961 #include "dbus-unit.h"
2962 #include "dbus-util.h"
2963@@ -39,6 +40,7 @@ int bus_scope_method_abandon(sd_bus_message *message, void *userdata, sd_bus_err
2964 }
2965
2966 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResult);
2967+static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string);
2968
2969 const sd_bus_vtable bus_scope_vtable[] = {
2970 SD_BUS_VTABLE_START(0),
2971@@ -47,6 +49,7 @@ const sd_bus_vtable bus_scope_vtable[] = {
2972 SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2973 SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec, offsetof(Scope, runtime_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2974 SD_BUS_PROPERTY("RuntimeRandomizedExtraUSec", "t", bus_property_get_usec, offsetof(Scope, runtime_rand_extra_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2975+ SD_BUS_PROPERTY("OOMPolicy", "s", bus_property_get_oom_policy, offsetof(Scope, oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
2976 SD_BUS_SIGNAL("RequestStop", NULL, 0),
2977 SD_BUS_METHOD("Abandon", NULL, NULL, bus_scope_method_abandon, SD_BUS_VTABLE_UNPRIVILEGED),
2978 SD_BUS_VTABLE_END
2979@@ -77,6 +80,9 @@ static int bus_scope_set_transient_property(
2980 if (streq(name, "RuntimeRandomizedExtraUSec"))
2981 return bus_set_transient_usec(u, name, &s->runtime_rand_extra_usec, message, flags, error);
2982
2983+ if (streq(name, "OOMPolicy"))
2984+ return bus_set_transient_oom_policy(u, name, &s->oom_policy, message, flags, error);
2985+
2986 if (streq(name, "PIDs")) {
2987 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
2988 unsigned n = 0;
2989diff --git a/src/core/execute.c b/src/core/execute.c
2990index 6c3fbc2..13222dd 100644
2991--- a/src/core/execute.c
2992+++ b/src/core/execute.c
2993@@ -5479,6 +5479,23 @@ int exec_context_destroy_credentials(const ExecContext *c, const char *runtime_p
2994 return 0;
2995 }
2996
2997+int exec_context_destroy_mount_ns_dir(Unit *u) {
2998+ _cleanup_free_ char *p = NULL;
2999+
3000+ if (!u || !MANAGER_IS_SYSTEM(u->manager))
3001+ return 0;
3002+
3003+ p = path_join("/run/systemd/propagate/", u->id);
3004+ if (!p)
3005+ return -ENOMEM;
3006+
3007+ /* This is only filled transiently (see mount_in_namespace()), should be empty or even non-existent*/
3008+ if (rmdir(p) < 0 && errno != ENOENT)
3009+ log_unit_debug_errno(u, errno, "Unable to remove propagation dir '%s', ignoring: %m", p);
3010+
3011+ return 0;
3012+}
3013+
3014 static void exec_command_done(ExecCommand *c) {
3015 assert(c);
3016
3017diff --git a/src/core/execute.h b/src/core/execute.h
3018index a2cf228..4c54422 100644
3019--- a/src/core/execute.h
3020+++ b/src/core/execute.h
3021@@ -453,6 +453,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix);
3022
3023 int exec_context_destroy_runtime_directory(const ExecContext *c, const char *runtime_root);
3024 int exec_context_destroy_credentials(const ExecContext *c, const char *runtime_root, const char *unit);
3025+int exec_context_destroy_mount_ns_dir(Unit *u);
3026
3027 const char* exec_context_fdname(const ExecContext *c, int fd_index);
3028
3029diff --git a/src/core/import-creds.c b/src/core/import-creds.c
3030index 4685e43..dab7d36 100644
3031--- a/src/core/import-creds.c
3032+++ b/src/core/import-creds.c
3033@@ -19,6 +19,7 @@
3034 #include "proc-cmdline.h"
3035 #include "recurse-dir.h"
3036 #include "strv.h"
3037+#include "virt.h"
3038
3039 /* This imports credentials passed in from environments higher up (VM manager, boot loader, …) and rearranges
3040 * them so that later code can access them using our regular credential protocol
3041@@ -369,6 +370,9 @@ static int import_credentials_qemu(ImportCredentialContext *c) {
3042
3043 assert(c);
3044
3045+ if (detect_container() > 0) /* don't access /sys/ in a container */
3046+ return 0;
3047+
3048 source_dir_fd = open(QEMU_FWCFG_PATH, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
3049 if (source_dir_fd < 0) {
3050 if (errno == ENOENT) {
3051@@ -560,6 +564,9 @@ static int import_credentials_smbios(ImportCredentialContext *c) {
3052
3053 /* Parses DMI OEM strings fields (SMBIOS type 11), as settable with qemu's -smbios type=11,value=… switch. */
3054
3055+ if (detect_container() > 0) /* don't access /sys/ in a container */
3056+ return 0;
3057+
3058 for (unsigned i = 0;; i++) {
3059 struct dmi_field_header {
3060 uint8_t type;
3061diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
3062index 7675b7b..81a5971 100644
3063--- a/src/core/load-fragment-gperf.gperf.in
3064+++ b/src/core/load-fragment-gperf.gperf.in
3065@@ -555,6 +555,7 @@ Path.TriggerLimitBurst, config_parse_unsigned,
3066 Scope.RuntimeMaxSec, config_parse_sec, 0, offsetof(Scope, runtime_max_usec)
3067 Scope.RuntimeRandomizedExtraSec, config_parse_sec, 0, offsetof(Scope, runtime_rand_extra_usec)
3068 Scope.TimeoutStopSec, config_parse_sec, 0, offsetof(Scope, timeout_stop_usec)
3069+Scope.OOMPolicy, config_parse_oom_policy, 0, offsetof(Scope, oom_policy)
3070 {# The [Install] section is ignored here #}
3071 Install.Alias, NULL, 0, 0
3072 Install.WantedBy, NULL, 0, 0
3073diff --git a/src/core/mount.c b/src/core/mount.c
3074index dea7cd9..283426b 100644
3075--- a/src/core/mount.c
3076+++ b/src/core/mount.c
3077@@ -13,6 +13,7 @@
3078 #include "device.h"
3079 #include "exit-status.h"
3080 #include "format-util.h"
3081+#include "fs-util.h"
3082 #include "fstab-util.h"
3083 #include "libmount-util.h"
3084 #include "log.h"
3085@@ -26,6 +27,7 @@
3086 #include "process-util.h"
3087 #include "serialize.h"
3088 #include "special.h"
3089+#include "stat-util.h"
3090 #include "string-table.h"
3091 #include "string-util.h"
3092 #include "strv.h"
3093@@ -1073,6 +1075,7 @@ fail:
3094 static void mount_enter_mounting(Mount *m) {
3095 int r;
3096 MountParameters *p;
3097+ bool source_is_dir = true;
3098
3099 assert(m);
3100
3101@@ -1080,16 +1083,28 @@ static void mount_enter_mounting(Mount *m) {
3102 if (r < 0)
3103 goto fail;
3104
3105- (void) mkdir_p_label(m->where, m->directory_mode);
3106+ p = get_mount_parameters_fragment(m);
3107+ if (p && mount_is_bind(p)) {
3108+ r = is_dir(p->what, /* follow = */ true);
3109+ if (r < 0 && r != -ENOENT)
3110+ log_unit_info_errno(UNIT(m), r, "Failed to determine type of bind mount source '%s', ignoring: %m", p->what);
3111+ else if (r == 0)
3112+ source_is_dir = false;
3113+ }
3114
3115- unit_warn_if_dir_nonempty(UNIT(m), m->where);
3116+ if (source_is_dir)
3117+ (void) mkdir_p_label(m->where, m->directory_mode);
3118+ else
3119+ (void) touch_file(m->where, /* parents = */ true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
3120+
3121+ if (source_is_dir)
3122+ unit_warn_if_dir_nonempty(UNIT(m), m->where);
3123 unit_warn_leftover_processes(UNIT(m), unit_log_leftover_process_start);
3124
3125 m->control_command_id = MOUNT_EXEC_MOUNT;
3126 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
3127
3128 /* Create the source directory for bind-mounts if needed */
3129- p = get_mount_parameters_fragment(m);
3130 if (p && mount_is_bind(p)) {
3131 r = mkdir_p_label(p->what, m->directory_mode);
3132 /* mkdir_p_label() can return -EEXIST if the target path exists and is not a directory - which is
3133diff --git a/src/core/scope.c b/src/core/scope.c
3134index 54a6cc6..914d1cc 100644
3135--- a/src/core/scope.c
3136+++ b/src/core/scope.c
3137@@ -43,6 +43,7 @@ static void scope_init(Unit *u) {
3138 s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
3139 u->ignore_on_isolate = true;
3140 s->user = s->group = NULL;
3141+ s->oom_policy = _OOM_POLICY_INVALID;
3142 }
3143
3144 static void scope_done(Unit *u) {
3145@@ -194,6 +195,11 @@ static int scope_add_extras(Scope *s) {
3146 if (r < 0)
3147 return r;
3148
3149+ if (s->oom_policy < 0)
3150+ s->oom_policy = s->cgroup_context.delegate ? OOM_CONTINUE : UNIT(s)->manager->default_oom_policy;
3151+
3152+ s->cgroup_context.memory_oom_group = s->oom_policy == OOM_KILL;
3153+
3154 return scope_add_default_dependencies(s);
3155 }
3156
3157@@ -286,11 +292,13 @@ static void scope_dump(Unit *u, FILE *f, const char *prefix) {
3158 "%sScope State: %s\n"
3159 "%sResult: %s\n"
3160 "%sRuntimeMaxSec: %s\n"
3161- "%sRuntimeRandomizedExtraSec: %s\n",
3162+ "%sRuntimeRandomizedExtraSec: %s\n"
3163+ "%sOOMPolicy: %s\n",
3164 prefix, scope_state_to_string(s->state),
3165 prefix, scope_result_to_string(s->result),
3166 prefix, FORMAT_TIMESPAN(s->runtime_max_usec, USEC_PER_SEC),
3167- prefix, FORMAT_TIMESPAN(s->runtime_rand_extra_usec, USEC_PER_SEC));
3168+ prefix, FORMAT_TIMESPAN(s->runtime_rand_extra_usec, USEC_PER_SEC),
3169+ prefix, oom_policy_to_string(s->oom_policy));
3170
3171 cgroup_context_dump(UNIT(s), f, prefix);
3172 kill_context_dump(&s->kill_context, f, prefix);
3173@@ -635,11 +643,16 @@ static void scope_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
3174 else
3175 log_unit_debug(u, "Process of control group was killed by the OOM killer.");
3176
3177- /* This will probably need to be modified when scope units get an oom-policy */
3178+ if (s->oom_policy == OOM_CONTINUE)
3179+ return;
3180+
3181 switch (s->state) {
3182
3183 case SCOPE_START_CHOWN:
3184 case SCOPE_RUNNING:
3185+ scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_FAILURE_OOM_KILL);
3186+ break;
3187+
3188 case SCOPE_STOP_SIGTERM:
3189 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_OOM_KILL);
3190 break;
3191@@ -776,6 +789,10 @@ static void scope_enumerate_perpetual(Manager *m) {
3192
3193 unit_add_to_load_queue(u);
3194 unit_add_to_dbus_queue(u);
3195+ /* Enqueue an explicit cgroup realization here. Unlike other cgroups this one already exists and is
3196+ * populated (by us, after all!) already, even when we are not in a reload cycle. Hence we cannot
3197+ * apply the settings at creation time anymore, but let's at least apply them asynchronously. */
3198+ unit_add_to_cgroup_realize_queue(u);
3199 }
3200
3201 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
3202diff --git a/src/core/scope.h b/src/core/scope.h
3203index 6a228f1..c9574a3 100644
3204--- a/src/core/scope.h
3205+++ b/src/core/scope.h
3206@@ -38,6 +38,8 @@ struct Scope {
3207
3208 char *user;
3209 char *group;
3210+
3211+ OOMPolicy oom_policy;
3212 };
3213
3214 extern const UnitVTable scope_vtable;
3215diff --git a/src/core/slice.c b/src/core/slice.c
3216index c453aa0..4824a30 100644
3217--- a/src/core/slice.c
3218+++ b/src/core/slice.c
3219@@ -381,6 +381,9 @@ static int slice_freezer_action(Unit *s, FreezerAction action) {
3220 }
3221
3222 UNIT_FOREACH_DEPENDENCY(member, s, UNIT_ATOM_SLICE_OF) {
3223+ if (!member->cgroup_realized)
3224+ continue;
3225+
3226 if (action == FREEZER_FREEZE)
3227 r = UNIT_VTABLE(member)->freeze(member);
3228 else
3229diff --git a/src/core/swap.c b/src/core/swap.c
3230index 2196793..5c83c47 100644
3231--- a/src/core/swap.c
3232+++ b/src/core/swap.c
3233@@ -827,7 +827,7 @@ static void swap_enter_activating(Swap *s) {
3234 }
3235 }
3236
3237- r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
3238+ r = exec_command_set(s->control_command, "/sbin/swapon", "--fixpgsz", NULL);
3239 if (r < 0)
3240 goto fail;
3241
3242diff --git a/src/core/unit.c b/src/core/unit.c
3243index bed5544..3ac56c1 100644
3244--- a/src/core/unit.c
3245+++ b/src/core/unit.c
3246@@ -5732,6 +5732,7 @@ void unit_destroy_runtime_data(Unit *u, const ExecContext *context) {
3247 exec_context_destroy_runtime_directory(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
3248
3249 exec_context_destroy_credentials(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME], u->id);
3250+ exec_context_destroy_mount_ns_dir(u);
3251 }
3252
3253 int unit_clean(Unit *u, ExecCleanMask mask) {
3254diff --git a/src/cryptsetup/cryptsetup-fido2.c b/src/cryptsetup/cryptsetup-fido2.c
3255index 74053b8..a3bdedb 100644
3256--- a/src/cryptsetup/cryptsetup-fido2.c
3257+++ b/src/cryptsetup/cryptsetup-fido2.c
3258@@ -38,6 +38,10 @@ int acquire_fido2_key(
3259 size_t salt_size;
3260 int r;
3261
3262+ if ((required & (FIDO2ENROLL_PIN | FIDO2ENROLL_UP | FIDO2ENROLL_UV)) && headless)
3263+ return log_error_errno(SYNTHETIC_ERRNO(ENOPKG),
3264+ "Local verification is required to unlock this volume, but the 'headless' parameter was set.");
3265+
3266 ask_password_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
3267
3268 assert(cid);
3269@@ -76,28 +80,6 @@ int acquire_fido2_key(
3270 }
3271
3272 for (;;) {
3273- if (!FLAGS_SET(required, FIDO2ENROLL_PIN) || pins) {
3274- r = fido2_use_hmac_hash(
3275- device,
3276- rp_id ?: "io.systemd.cryptsetup",
3277- salt, salt_size,
3278- cid, cid_size,
3279- pins,
3280- required,
3281- ret_decrypted_key,
3282- ret_decrypted_key_size);
3283- if (!IN_SET(r,
3284- -ENOANO, /* needs pin */
3285- -ENOLCK)) /* pin incorrect */
3286- return r;
3287-
3288- device_exists = true; /* that a PIN is needed/wasn't correct means that we managed to
3289- * talk to a device */
3290- }
3291-
3292- if (headless)
3293- return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
3294-
3295 if (!device_exists) {
3296 /* Before we inquire for the PIN we'll need, if we never talked to the device, check
3297 * if the device actually is plugged in. Otherwise we'll ask for the PIN already when
3298@@ -112,6 +94,30 @@ int acquire_fido2_key(
3299 device_exists = true; /* now we know for sure, a device exists, no need to ask again */
3300 }
3301
3302+ /* Always make an attempt before asking for PIN.
3303+ * fido2_use_hmac_hash() will perform a pre-flight check for whether the credential for
3304+ * can be found on one of the connected devices. This way, we can avoid prompting the user
3305+ * for a PIN when we are sure that no device can be used. */
3306+ r = fido2_use_hmac_hash(
3307+ device,
3308+ rp_id ?: "io.systemd.cryptsetup",
3309+ salt, salt_size,
3310+ cid, cid_size,
3311+ pins,
3312+ required,
3313+ ret_decrypted_key,
3314+ ret_decrypted_key_size);
3315+ if (!IN_SET(r,
3316+ -ENOANO, /* needs pin */
3317+ -ENOLCK)) /* pin incorrect */
3318+ return r;
3319+
3320+ device_exists = true; /* that a PIN is needed/wasn't correct means that we managed to
3321+ * talk to a device */
3322+
3323+ if (headless)
3324+ return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
3325+
3326 pins = strv_free_erase(pins);
3327 r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, ask_password_flags, &pins);
3328 if (r < 0)
3329@@ -121,35 +127,38 @@ int acquire_fido2_key(
3330 }
3331 }
3332
3333-int find_fido2_auto_data(
3334+int acquire_fido2_key_auto(
3335 struct crypt_device *cd,
3336- char **ret_rp_id,
3337- void **ret_salt,
3338- size_t *ret_salt_size,
3339- void **ret_cid,
3340- size_t *ret_cid_size,
3341- int *ret_keyslot,
3342- Fido2EnrollFlags *ret_required) {
3343-
3344- _cleanup_free_ void *cid = NULL, *salt = NULL;
3345- size_t cid_size = 0, salt_size = 0;
3346- _cleanup_free_ char *rp = NULL;
3347- int r, keyslot = -1;
3348+ const char *name,
3349+ const char *friendly_name,
3350+ const char *fido2_device,
3351+ const char *key_file,
3352+ size_t key_file_size,
3353+ uint64_t key_file_offset,
3354+ usec_t until,
3355+ bool headless,
3356+ void **ret_decrypted_key,
3357+ size_t *ret_decrypted_key_size,
3358+ AskPasswordFlags ask_password_flags) {
3359+
3360+ _cleanup_free_ void *cid = NULL;
3361+ size_t cid_size = 0;
3362+ int r, ret = -ENOENT;
3363 Fido2EnrollFlags required = 0;
3364
3365 assert(cd);
3366- assert(ret_salt);
3367- assert(ret_salt_size);
3368- assert(ret_cid);
3369- assert(ret_cid_size);
3370- assert(ret_keyslot);
3371- assert(ret_required);
3372+ assert(name);
3373+ assert(ret_decrypted_key);
3374+ assert(ret_decrypted_key_size);
3375
3376 /* Loads FIDO2 metadata from LUKS2 JSON token headers. */
3377
3378 for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token ++) {
3379 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
3380 JsonVariant *w;
3381+ _cleanup_free_ void *salt = NULL;
3382+ _cleanup_free_ char *rp = NULL;
3383+ size_t salt_size = 0;
3384 int ks;
3385
3386 r = cryptsetup_get_token_as_json(cd, token, "systemd-fido2", &v);
3387@@ -166,13 +175,6 @@ int find_fido2_auto_data(
3388 continue;
3389 }
3390
3391- if (cid)
3392- return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
3393- "Multiple FIDO2 tokens enrolled, cannot automatically determine token.");
3394-
3395- assert(keyslot < 0);
3396- keyslot = ks;
3397-
3398 w = json_variant_by_key(v, "fido2-credential");
3399 if (!w || !json_variant_is_string(w))
3400 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
3401@@ -243,20 +245,33 @@ int find_fido2_auto_data(
3402 SET_FLAG(required, FIDO2ENROLL_UV, json_variant_boolean(w));
3403 } else
3404 required |= FIDO2ENROLL_UV_OMIT; /* compat with 248 */
3405+
3406+ ret = acquire_fido2_key(
3407+ name,
3408+ friendly_name,
3409+ fido2_device,
3410+ rp,
3411+ cid, cid_size,
3412+ key_file, key_file_size, key_file_offset,
3413+ salt, salt_size,
3414+ until,
3415+ headless,
3416+ required,
3417+ ret_decrypted_key, ret_decrypted_key_size,
3418+ ask_password_flags);
3419+ if (ret == 0)
3420+ break;
3421 }
3422
3423 if (!cid)
3424 return log_error_errno(SYNTHETIC_ERRNO(ENXIO),
3425 "No valid FIDO2 token data found.");
3426
3427- log_info("Automatically discovered security FIDO2 token unlocks volume.");
3428+ if (ret == -EAGAIN) /* fido2 device does not exist, or UV is blocked; caller will prompt for retry */
3429+ return log_debug_errno(ret, "FIDO2 token does not exist, or UV is blocked.");
3430+ if (ret < 0)
3431+ return log_error_errno(ret, "Failed to unlock LUKS volume with FIDO2 token: %m");
3432
3433- *ret_rp_id = TAKE_PTR(rp);
3434- *ret_cid = TAKE_PTR(cid);
3435- *ret_cid_size = cid_size;
3436- *ret_salt = TAKE_PTR(salt);
3437- *ret_salt_size = salt_size;
3438- *ret_keyslot = keyslot;
3439- *ret_required = required;
3440- return 0;
3441+ log_info("Unlocked volume via automatically discovered security FIDO2 token.");
3442+ return ret;
3443 }
3444diff --git a/src/cryptsetup/cryptsetup-fido2.h b/src/cryptsetup/cryptsetup-fido2.h
3445index 204f1e0..371bf21 100644
3446--- a/src/cryptsetup/cryptsetup-fido2.h
3447+++ b/src/cryptsetup/cryptsetup-fido2.h
3448@@ -29,15 +29,19 @@ int acquire_fido2_key(
3449 size_t *ret_decrypted_key_size,
3450 AskPasswordFlags ask_password_flags);
3451
3452-int find_fido2_auto_data(
3453+int acquire_fido2_key_auto(
3454 struct crypt_device *cd,
3455- char **ret_rp_id,
3456- void **ret_salt,
3457- size_t *ret_salt_size,
3458- void **ret_cid,
3459- size_t *ret_cid_size,
3460- int *ret_keyslot,
3461- Fido2EnrollFlags *ret_required);
3462+ const char *name,
3463+ const char *friendly_name,
3464+ const char *fido2_device,
3465+ const char *key_file,
3466+ size_t key_file_size,
3467+ uint64_t key_file_offset,
3468+ usec_t until,
3469+ bool headless,
3470+ void **ret_decrypted_key,
3471+ size_t *ret_decrypted_key_size,
3472+ AskPasswordFlags ask_password_flags);
3473
3474 #else
3475
3476@@ -64,15 +68,19 @@ static inline int acquire_fido2_key(
3477 "FIDO2 token support not available.");
3478 }
3479
3480-static inline int find_fido2_auto_data(
3481+static inline int acquire_fido2_key_auto(
3482 struct crypt_device *cd,
3483- char **ret_rp_id,
3484- void **ret_salt,
3485- size_t *ret_salt_size,
3486- void **ret_cid,
3487- size_t *ret_cid_size,
3488- int *ret_keyslot,
3489- Fido2EnrollFlags *ret_required) {
3490+ const char *name,
3491+ const char *friendly_name,
3492+ const char *fido2_device,
3493+ const char *key_file,
3494+ size_t key_file_size,
3495+ uint64_t key_file_offset,
3496+ usec_t until,
3497+ bool headless,
3498+ void **ret_decrypted_key,
3499+ size_t *ret_decrypted_key_size,
3500+ AskPasswordFlags ask_password_flags) {
3501
3502 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
3503 "FIDO2 token support not available.");
3504diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
3505index 7aa36b4..a8cfc6d 100644
3506--- a/src/cryptsetup/cryptsetup.c
3507+++ b/src/cryptsetup/cryptsetup.c
3508@@ -1061,9 +1061,8 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
3509 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
3510 _cleanup_(erase_and_freep) void *decrypted_key = NULL;
3511 _cleanup_(sd_event_unrefp) sd_event *event = NULL;
3512- _cleanup_free_ void *discovered_salt = NULL, *discovered_cid = NULL;
3513- size_t discovered_salt_size, discovered_cid_size, decrypted_key_size, cid_size = 0;
3514- _cleanup_free_ char *friendly = NULL, *discovered_rp_id = NULL;
3515+ size_t decrypted_key_size, cid_size = 0;
3516+ _cleanup_free_ char *friendly = NULL;
3517 int keyslot = arg_key_slot, r;
3518 const char *rp_id = NULL;
3519 const void *cid = NULL;
3520@@ -1088,32 +1087,6 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
3521 * use PIN + UP when needed, and do not configure UV at all. Eventually, we should make this
3522 * explicitly configurable. */
3523 required = FIDO2ENROLL_PIN_IF_NEEDED | FIDO2ENROLL_UP_IF_NEEDED | FIDO2ENROLL_UV_OMIT;
3524- } else if (!use_libcryptsetup_plugin) {
3525- r = find_fido2_auto_data(
3526- cd,
3527- &discovered_rp_id,
3528- &discovered_salt,
3529- &discovered_salt_size,
3530- &discovered_cid,
3531- &discovered_cid_size,
3532- &keyslot,
3533- &required);
3534-
3535- if (IN_SET(r, -ENOTUNIQ, -ENXIO))
3536- return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
3537- "Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
3538- if (r < 0)
3539- return r;
3540-
3541- if ((required & (FIDO2ENROLL_PIN | FIDO2ENROLL_UP | FIDO2ENROLL_UV)) && arg_headless)
3542- return log_error_errno(SYNTHETIC_ERRNO(ENOPKG),
3543- "Local verification is required to unlock this volume, but the 'headless' parameter was set.");
3544-
3545- rp_id = discovered_rp_id;
3546- key_data = discovered_salt;
3547- key_data_size = discovered_salt_size;
3548- cid = discovered_cid;
3549- cid_size = discovered_cid_size;
3550 }
3551
3552 friendly = friendly_disk_name(crypt_get_device_name(cd), name);
3553@@ -1128,19 +1101,31 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
3554 "Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
3555
3556 } else {
3557- r = acquire_fido2_key(
3558- name,
3559- friendly,
3560- arg_fido2_device,
3561- rp_id,
3562- cid, cid_size,
3563- key_file, arg_keyfile_size, arg_keyfile_offset,
3564- key_data, key_data_size,
3565- until,
3566- arg_headless,
3567- required,
3568- &decrypted_key, &decrypted_key_size,
3569- arg_ask_password_flags);
3570+ if (cid)
3571+ r = acquire_fido2_key(
3572+ name,
3573+ friendly,
3574+ arg_fido2_device,
3575+ rp_id,
3576+ cid, cid_size,
3577+ key_file, arg_keyfile_size, arg_keyfile_offset,
3578+ key_data, key_data_size,
3579+ until,
3580+ arg_headless,
3581+ required,
3582+ &decrypted_key, &decrypted_key_size,
3583+ arg_ask_password_flags);
3584+ else
3585+ r = acquire_fido2_key_auto(
3586+ cd,
3587+ name,
3588+ friendly,
3589+ arg_fido2_device,
3590+ key_file, arg_keyfile_size, arg_keyfile_offset,
3591+ until,
3592+ arg_headless,
3593+ &decrypted_key, &decrypted_key_size,
3594+ arg_ask_password_flags);
3595 if (r >= 0)
3596 break;
3597 }
3598diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
3599index c11a5b1..e73174a 100644
3600--- a/src/fundamental/macro-fundamental.h
3601+++ b/src/fundamental/macro-fundamental.h
3602@@ -20,6 +20,7 @@
3603 #define _hidden_ __attribute__((__visibility__("hidden")))
3604 #define _likely_(x) (__builtin_expect(!!(x), 1))
3605 #define _malloc_ __attribute__((__malloc__))
3606+#define _noinline_ __attribute__((noinline))
3607 #define _noreturn_ _Noreturn
3608 #define _packed_ __attribute__((__packed__))
3609 #define _printf_(a, b) __attribute__((__format__(printf, a, b)))
3610diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
3611index 143faa0..30639b3 100644
3612--- a/src/gpt-auto-generator/gpt-auto-generator.c
3613+++ b/src/gpt-auto-generator/gpt-auto-generator.c
3614@@ -414,14 +414,14 @@ static int add_automount(
3615 static const char *esp_or_xbootldr_options(const DissectedPartition *p) {
3616 assert(p);
3617
3618- /* if we probed vfat or have no idea about the file system then assume these file systems are vfat
3619- * and thus understand "umask=0077". If we detected something else then don't specify any options and
3620- * use kernel defaults. */
3621+ /* Discoveried ESP and XBOOTLDR partition are always hardened with "noexec,nosuid,nodev".
3622+ * If we probed vfat or have no idea about the file system then assume these file systems are vfat
3623+ * and thus understand "umask=0077". */
3624
3625 if (!p->fstype || streq(p->fstype, "vfat"))
3626- return "umask=0077";
3627+ return "umask=0077,noexec,nosuid,nodev";
3628
3629- return NULL;
3630+ return "noexec,nosuid,nodev";
3631 }
3632
3633 static int add_partition_xbootldr(DissectedPartition *p) {
3634diff --git a/src/import/curl-util.c b/src/import/curl-util.c
3635index c124c98..94f718d 100644
3636--- a/src/import/curl-util.c
3637+++ b/src/import/curl-util.c
3638@@ -252,7 +252,11 @@ int curl_glue_make(CURL **ret, const char *url, void *userdata) {
3639 if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_LIMIT, 30L) != CURLE_OK)
3640 return -EIO;
3641
3642+#if LIBCURL_VERSION_NUM >= 0x075500 /* libcurl 7.85.0 */
3643+ if (curl_easy_setopt(c, CURLOPT_PROTOCOLS_STR, "HTTP,HTTPS,FILE") != CURLE_OK)
3644+#else
3645 if (curl_easy_setopt(c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_FILE) != CURLE_OK)
3646+#endif
3647 return -EIO;
3648
3649 *ret = TAKE_PTR(c);
3650diff --git a/src/import/pull-job.c b/src/import/pull-job.c
3651index 1e105bc..d4d07a0 100644
3652--- a/src/import/pull-job.c
3653+++ b/src/import/pull-job.c
3654@@ -124,8 +124,8 @@ static int pull_job_restart(PullJob *j, const char *new_url) {
3655
3656 void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
3657 PullJob *j = NULL;
3658+ char *scheme = NULL;
3659 CURLcode code;
3660- long protocol;
3661 int r;
3662
3663 if (curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&j) != CURLE_OK)
3664@@ -139,13 +139,13 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
3665 goto finish;
3666 }
3667
3668- code = curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol);
3669- if (code != CURLE_OK) {
3670- r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
3671+ code = curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme);
3672+ if (code != CURLE_OK || !scheme) {
3673+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve URL scheme.");
3674 goto finish;
3675 }
3676
3677- if (IN_SET(protocol, CURLPROTO_HTTP, CURLPROTO_HTTPS)) {
3678+ if (STRCASE_IN_SET(scheme, "HTTP", "HTTPS")) {
3679 long status;
3680
3681 code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
3682diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
3683index 7e7d1b5..df18335 100644
3684--- a/src/journal-remote/microhttpd-util.h
3685+++ b/src/journal-remote/microhttpd-util.h
3686@@ -64,11 +64,11 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0);
3687
3688 int mhd_respondf(struct MHD_Connection *connection,
3689 int error,
3690- unsigned code,
3691+ enum MHD_RequestTerminationCode code,
3692 const char *format, ...) _printf_(4,5);
3693
3694 int mhd_respond(struct MHD_Connection *connection,
3695- unsigned code,
3696+ enum MHD_RequestTerminationCode code,
3697 const char *message);
3698
3699 int mhd_respond_oom(struct MHD_Connection *connection);
3700diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
3701index 43bd87c..88f858f 100755
3702--- a/src/kernel-install/50-depmod.install
3703+++ b/src/kernel-install/50-depmod.install
3704@@ -23,6 +23,8 @@ set -e
3705 COMMAND="${1:?}"
3706 KERNEL_VERSION="${2:?}"
3707
3708+[ -w "/lib/modules" ] || exit 0
3709+
3710 case "$COMMAND" in
3711 add)
3712 [ -d "/lib/modules/$KERNEL_VERSION/kernel" ] || exit 0
3713diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
3714index a106f7f..b755c12 100644
3715--- a/src/libsystemd-network/sd-dhcp-client.c
3716+++ b/src/libsystemd-network/sd-dhcp-client.c
3717@@ -188,35 +188,33 @@ int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret) {
3718 r = asprintf(&t, "DATA");
3719 break;
3720 case 1:
3721- if (len != sizeof_field(sd_dhcp_client_id, eth))
3722- return -EINVAL;
3723-
3724- r = asprintf(&t, "%02x:%02x:%02x:%02x:%02x:%02x",
3725- client_id->eth.haddr[0],
3726- client_id->eth.haddr[1],
3727- client_id->eth.haddr[2],
3728- client_id->eth.haddr[3],
3729- client_id->eth.haddr[4],
3730- client_id->eth.haddr[5]);
3731+ if (len == sizeof_field(sd_dhcp_client_id, eth))
3732+ r = asprintf(&t, "%02x:%02x:%02x:%02x:%02x:%02x",
3733+ client_id->eth.haddr[0],
3734+ client_id->eth.haddr[1],
3735+ client_id->eth.haddr[2],
3736+ client_id->eth.haddr[3],
3737+ client_id->eth.haddr[4],
3738+ client_id->eth.haddr[5]);
3739+ else
3740+ r = asprintf(&t, "ETHER");
3741 break;
3742 case 2 ... 254:
3743 r = asprintf(&t, "ARP/LL");
3744 break;
3745 case 255:
3746- if (len < 6)
3747- return -EINVAL;
3748-
3749- uint32_t iaid = be32toh(client_id->ns.iaid);
3750- uint16_t duid_type = be16toh(client_id->ns.duid.type);
3751- if (dhcp_validate_duid_len(duid_type, len - 6, true) < 0)
3752- return -EINVAL;
3753-
3754- r = asprintf(&t, "IAID:0x%x/DUID", iaid);
3755+ if (len < sizeof(uint32_t))
3756+ r = asprintf(&t, "IAID/DUID");
3757+ else {
3758+ uint32_t iaid = be32toh(client_id->ns.iaid);
3759+ /* TODO: check and stringify DUID */
3760+ r = asprintf(&t, "IAID:0x%x/DUID", iaid);
3761+ }
3762 break;
3763 }
3764-
3765 if (r < 0)
3766 return -ENOMEM;
3767+
3768 *ret = TAKE_PTR(t);
3769 return 0;
3770 }
3771diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
3772index d9db35f..b14ad57 100644
3773--- a/src/libsystemd-network/sd-dhcp-lease.c
3774+++ b/src/libsystemd-network/sd-dhcp-lease.c
3775@@ -995,7 +995,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
3776 r = sd_dhcp_lease_get_router(lease, &addresses);
3777 if (r > 0) {
3778 fputs("ROUTER=", f);
3779- serialize_in_addrs(f, addresses, r, false, NULL);
3780+ serialize_in_addrs(f, addresses, r, NULL, NULL);
3781 fputc('\n', f);
3782 }
3783
3784@@ -1030,21 +1030,21 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
3785 r = sd_dhcp_lease_get_dns(lease, &addresses);
3786 if (r > 0) {
3787 fputs("DNS=", f);
3788- serialize_in_addrs(f, addresses, r, false, NULL);
3789+ serialize_in_addrs(f, addresses, r, NULL, NULL);
3790 fputc('\n', f);
3791 }
3792
3793 r = sd_dhcp_lease_get_ntp(lease, &addresses);
3794 if (r > 0) {
3795 fputs("NTP=", f);
3796- serialize_in_addrs(f, addresses, r, false, NULL);
3797+ serialize_in_addrs(f, addresses, r, NULL, NULL);
3798 fputc('\n', f);
3799 }
3800
3801 r = sd_dhcp_lease_get_sip(lease, &addresses);
3802 if (r > 0) {
3803 fputs("SIP=", f);
3804- serialize_in_addrs(f, addresses, r, false, NULL);
3805+ serialize_in_addrs(f, addresses, r, NULL, NULL);
3806 fputc('\n', f);
3807 }
3808
3809diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c
3810index 001df4d..bd8c0fd 100644
3811--- a/src/libsystemd-network/test-ndisc-ra.c
3812+++ b/src/libsystemd-network/test-ndisc-ra.c
3813@@ -53,7 +53,6 @@ static uint8_t advertisement[] = {
3814
3815 static bool test_stopped;
3816 static int test_fd[2];
3817-static sd_event_source *recv_router_advertisement;
3818 static struct {
3819 struct in6_addr address;
3820 unsigned char prefixlen;
3821@@ -281,9 +280,9 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
3822 }
3823
3824 TEST(ra) {
3825- sd_event *e;
3826- sd_radv *ra;
3827- unsigned i;
3828+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
3829+ _cleanup_(sd_event_source_unrefp) sd_event_source *recv_router_advertisement = NULL;
3830+ _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
3831
3832 assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
3833
3834@@ -303,7 +302,7 @@ TEST(ra) {
3835 assert_se(sd_radv_set_rdnss(ra, 60, &test_rdnss, 1) >= 0);
3836 assert_se(sd_radv_set_dnssl(ra, 60, (char **)test_dnssl) >= 0);
3837
3838- for (i = 0; i < ELEMENTSOF(prefix); i++) {
3839+ for (unsigned i = 0; i < ELEMENTSOF(prefix); i++) {
3840 sd_radv_prefix *p;
3841
3842 printf("Test prefix %u\n", i);
3843@@ -324,8 +323,8 @@ TEST(ra) {
3844 assert_se(!p);
3845 }
3846
3847- assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0],
3848- EPOLLIN, radv_recv, ra) >= 0);
3849+ assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0], EPOLLIN, radv_recv, ra) >= 0);
3850+ assert_se(sd_event_source_set_io_fd_own(recv_router_advertisement, true) >= 0);
3851
3852 assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME,
3853 2 * USEC_PER_SEC, 0,
3854@@ -334,13 +333,6 @@ TEST(ra) {
3855 assert_se(sd_radv_start(ra) >= 0);
3856
3857 assert_se(sd_event_loop(e) >= 0);
3858-
3859- ra = sd_radv_unref(ra);
3860- assert_se(!ra);
3861-
3862- close(test_fd[0]);
3863-
3864- sd_event_unref(e);
3865 }
3866
3867 DEFINE_TEST_MAIN(LOG_DEBUG);
3868diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c
3869index 3c679f6..e501b64 100644
3870--- a/src/libsystemd-network/test-ndisc-rs.c
3871+++ b/src/libsystemd-network/test-ndisc-rs.c
3872@@ -10,6 +10,7 @@
3873 #include "sd-ndisc.h"
3874
3875 #include "alloc-util.h"
3876+#include "fd-util.h"
3877 #include "hexdecoct.h"
3878 #include "icmp6-util.h"
3879 #include "socket-util.h"
3880@@ -255,8 +256,8 @@ static void test_callback(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router
3881 }
3882
3883 TEST(rs) {
3884- sd_event *e;
3885- sd_ndisc *nd;
3886+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
3887+ _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
3888
3889 send_ra_function = send_ra;
3890
3891@@ -279,17 +280,13 @@ TEST(rs) {
3892 assert_se(sd_ndisc_start(nd) >= 0);
3893 assert_se(sd_ndisc_start(nd) >= 0);
3894 assert_se(sd_ndisc_stop(nd) >= 0);
3895+ test_fd[1] = safe_close(test_fd[1]);
3896
3897 assert_se(sd_ndisc_start(nd) >= 0);
3898
3899 assert_se(sd_event_loop(e) >= 0);
3900
3901- nd = sd_ndisc_unref(nd);
3902- assert_se(!nd);
3903-
3904- close(test_fd[1]);
3905-
3906- sd_event_unref(e);
3907+ test_fd[1] = safe_close(test_fd[1]);
3908 }
3909
3910 static int test_timeout_value(uint8_t flags) {
3911@@ -342,8 +339,8 @@ static int test_timeout_value(uint8_t flags) {
3912 }
3913
3914 TEST(timeout) {
3915- sd_event *e;
3916- sd_ndisc *nd;
3917+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
3918+ _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
3919
3920 send_ra_function = test_timeout_value;
3921
3922@@ -367,9 +364,7 @@ TEST(timeout) {
3923
3924 assert_se(sd_event_loop(e) >= 0);
3925
3926- nd = sd_ndisc_unref(nd);
3927-
3928- sd_event_unref(e);
3929+ test_fd[1] = safe_close(test_fd[1]);
3930 }
3931
3932 DEFINE_TEST_MAIN(LOG_DEBUG);
3933diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c
3934index 4ab8b38..ff4209e 100644
3935--- a/src/libsystemd/sd-device/test-sd-device.c
3936+++ b/src/libsystemd/sd-device/test-sd-device.c
3937@@ -180,15 +180,16 @@ static void test_sd_device_one(sd_device *d) {
3938 } else
3939 assert_se(r == -ENOENT);
3940
3941- r = sd_device_get_sysattr_value(d, "name_assign_type", &val);
3942- assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || IN_SET(r, -ENOENT, -EINVAL));
3943-
3944- if (r > 0) {
3945+ r = sd_device_get_sysattr_value(d, "nsid", NULL);
3946+ if (r >= 0) {
3947 unsigned x;
3948
3949- assert_se(device_get_sysattr_unsigned(d, "name_assign_type", NULL) >= 0);
3950- assert_se(device_get_sysattr_unsigned(d, "name_assign_type", &x) >= 0);
3951- }
3952+ assert_se(device_get_sysattr_unsigned(d, "nsid", NULL) >= 0);
3953+ r = device_get_sysattr_unsigned(d, "nsid", &x);
3954+ assert_se(r >= 0);
3955+ assert_se((x > 0) == (r > 0));
3956+ } else
3957+ assert_se(ERRNO_IS_PRIVILEGE(r) || IN_SET(r, -ENOENT, -EINVAL));
3958 }
3959
3960 TEST(sd_device_enumerator_devices) {
3961diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
3962index 778070a..4a4cc3a 100644
3963--- a/src/libsystemd/sd-event/sd-event.c
3964+++ b/src/libsystemd/sd-event/sd-event.c
3965@@ -658,7 +658,9 @@ static int event_make_signal_data(
3966 ss_copy = d->sigset;
3967 assert_se(sigaddset(&ss_copy, sig) >= 0);
3968
3969- r = signalfd(d->fd, &ss_copy, SFD_NONBLOCK|SFD_CLOEXEC);
3970+ r = signalfd(d->fd >= 0 ? d->fd : -1, /* the first arg must be -1 or a valid signalfd */
3971+ &ss_copy,
3972+ SFD_NONBLOCK|SFD_CLOEXEC);
3973 if (r < 0) {
3974 r = -errno;
3975 goto fail;
3976@@ -2723,6 +2725,9 @@ _public_ int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec
3977 assert_return(s, -EINVAL);
3978 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
3979
3980+ if (usec == USEC_INFINITY)
3981+ return sd_event_source_set_time(s, USEC_INFINITY);
3982+
3983 r = sd_event_now(s->event, event_source_type_to_clock(s->type), &t);
3984 if (r < 0)
3985 return r;
3986diff --git a/src/locale/localed.c b/src/locale/localed.c
3987index 7aa47f1..8b1f0de 100644
3988--- a/src/locale/localed.c
3989+++ b/src/locale/localed.c
3990@@ -32,7 +32,7 @@
3991 #include "strv.h"
3992 #include "user-util.h"
3993
3994-static int locale_update_system_manager(sd_bus *bus, char **l_set, char **l_unset) {
3995+static int reload_system_manager(sd_bus *bus) {
3996 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
3997 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3998 int r;
3999@@ -43,21 +43,13 @@ static int locale_update_system_manager(sd_bus *bus, char **l_set, char **l_unse
4000 "org.freedesktop.systemd1",
4001 "/org/freedesktop/systemd1",
4002 "org.freedesktop.systemd1.Manager",
4003- "UnsetAndSetEnvironment");
4004- if (r < 0)
4005- return bus_log_create_error(r);
4006-
4007- r = sd_bus_message_append_strv(m, l_unset);
4008- if (r < 0)
4009- return bus_log_create_error(r);
4010-
4011- r = sd_bus_message_append_strv(m, l_set);
4012+ "Reload");
4013 if (r < 0)
4014 return bus_log_create_error(r);
4015
4016 r = sd_bus_call(bus, m, 0, &error, NULL);
4017 if (r < 0)
4018- return log_error_errno(r, "Failed to update the manager environment: %s", bus_error_message(&error, r));
4019+ return log_error_errno(r, "Failed to reload system manager: %s", bus_error_message(&error, r));
4020
4021 return 0;
4022 }
4023@@ -393,7 +385,11 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
4024 return sd_bus_error_set_errnof(error, r, "Failed to set locale: %m");
4025 }
4026
4027- (void) locale_update_system_manager(sd_bus_message_get_bus(m), l_set, l_unset);
4028+ /* Since we just updated the locale configuration file, ask the system manager to read it again to
4029+ * update its default locale settings. It's important to not use UnsetAndSetEnvironment or a similar
4030+ * method because in this case unsetting variables means restoring them to PID1 default values, which
4031+ * may be outdated, since locale.conf has just changed and PID1 hasn't read it */
4032+ (void) reload_system_manager(sd_bus_message_get_bus(m));
4033
4034 if (!strv_isempty(l_set)) {
4035 _cleanup_free_ char *line = NULL;
4036diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
4037index 86a5dec..2ab26b9 100644
4038--- a/src/login/logind-dbus.c
4039+++ b/src/login/logind-dbus.c
4040@@ -3970,6 +3970,12 @@ int manager_start_scope(
4041 if (r < 0)
4042 return r;
4043
4044+ /* For login session scopes, if a process is OOM killed by the kernel, *don't* terminate the rest of
4045+ the scope */
4046+ r = sd_bus_message_append(m, "(sv)", "OOMPolicy", "s", "continue");
4047+ if (r < 0)
4048+ return r;
4049+
4050 /* disable TasksMax= for the session scope, rely on the slice setting for it */
4051 r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", UINT64_MAX);
4052 if (r < 0)
4053diff --git a/src/network/netdev/l2tp-tunnel.c b/src/network/netdev/l2tp-tunnel.c
4054index 2bce0fc..fd2783e 100644
4055--- a/src/network/netdev/l2tp-tunnel.c
4056+++ b/src/network/netdev/l2tp-tunnel.c
4057@@ -522,7 +522,7 @@ int config_parse_l2tp_tunnel_local_address(
4058 return log_oom();
4059 }
4060
4061- type = l2tp_local_address_type_from_string(rvalue);
4062+ type = l2tp_local_address_type_from_string(addr_or_type);
4063 if (type >= 0) {
4064 free_and_replace(t->local_ifname, ifname);
4065 t->local_address_type = type;
4066@@ -535,15 +535,15 @@ int config_parse_l2tp_tunnel_local_address(
4067 return 0;
4068 }
4069
4070- r = in_addr_from_string_auto(rvalue, &f, &a);
4071+ r = in_addr_from_string_auto(addr_or_type, &f, &a);
4072 if (r < 0) {
4073 log_syntax(unit, LOG_WARNING, filename, line, r,
4074- "Invalid L2TP Tunnel local address specified, ignoring assignment: %s", rvalue);
4075+ "Invalid L2TP Tunnel local address \"%s\" specified, ignoring assignment: %s", addr_or_type, rvalue);
4076 return 0;
4077 }
4078
4079 if (in_addr_is_null(f, &a)) {
4080- log_syntax(unit, LOG_WARNING, filename, line, r,
4081+ log_syntax(unit, LOG_WARNING, filename, line, 0,
4082 "L2TP Tunnel local address cannot be null, ignoring assignment: %s", rvalue);
4083 return 0;
4084 }
4085@@ -599,7 +599,7 @@ int config_parse_l2tp_tunnel_remote_address(
4086 }
4087
4088 if (in_addr_is_null(f, &a)) {
4089- log_syntax(unit, LOG_WARNING, filename, line, r,
4090+ log_syntax(unit, LOG_WARNING, filename, line, 0,
4091 "L2TP Tunnel remote address cannot be null, ignoring assignment: %s", rvalue);
4092 return 0;
4093 }
4094diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
4095index b614f6b..08b5bd8 100644
4096--- a/src/network/networkd-address.c
4097+++ b/src/network/networkd-address.c
4098@@ -1230,9 +1230,13 @@ int link_request_address(
4099
4100 (void) address_get(link, address, &existing);
4101
4102- if (address->lifetime_valid_usec == 0)
4103+ if (address->lifetime_valid_usec == 0) {
4104+ if (consume_object)
4105+ address_free(address);
4106+
4107 /* The requested address is outdated. Let's remove it. */
4108 return address_remove_and_drop(existing);
4109+ }
4110
4111 if (!existing) {
4112 _cleanup_(address_freep) Address *tmp = NULL;
4113diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
4114index a1402d7..5fb5d96 100644
4115--- a/src/network/networkd-ndisc.c
4116+++ b/src/network/networkd-ndisc.c
4117@@ -794,31 +794,24 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
4118 return log_link_error_errno(link, r, "Failed to get RA option type: %m");
4119
4120 switch (type) {
4121-
4122 case SD_NDISC_OPTION_PREFIX_INFORMATION:
4123 r = ndisc_router_process_prefix(link, rt);
4124- if (r < 0)
4125- return r;
4126 break;
4127
4128 case SD_NDISC_OPTION_ROUTE_INFORMATION:
4129 r = ndisc_router_process_route(link, rt);
4130- if (r < 0)
4131- return r;
4132 break;
4133
4134 case SD_NDISC_OPTION_RDNSS:
4135 r = ndisc_router_process_rdnss(link, rt);
4136- if (r < 0)
4137- return r;
4138 break;
4139
4140 case SD_NDISC_OPTION_DNSSL:
4141 r = ndisc_router_process_dnssl(link, rt);
4142- if (r < 0)
4143- return r;
4144 break;
4145 }
4146+ if (r < 0 && r != -EBADMSG)
4147+ return r;
4148 }
4149 }
4150
4151@@ -1001,6 +994,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
4152 assert(rt);
4153
4154 r = sd_ndisc_router_get_address(rt, &router);
4155+ if (r == -ENODATA) {
4156+ log_link_debug(link, "Received RA without router address, ignoring.");
4157+ return 0;
4158+ }
4159 if (r < 0)
4160 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
4161
4162@@ -1015,6 +1012,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
4163 }
4164
4165 r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
4166+ if (r == -ENODATA) {
4167+ log_link_debug(link, "Received RA without timestamp, ignoring.");
4168+ return 0;
4169+ }
4170 if (r < 0)
4171 return r;
4172
4173@@ -1061,7 +1062,7 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router
4174
4175 case SD_NDISC_EVENT_ROUTER:
4176 r = ndisc_router_handler(link, rt);
4177- if (r < 0) {
4178+ if (r < 0 && r != -EBADMSG) {
4179 link_enter_failed(link);
4180 return;
4181 }
4182diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
4183index d1f3bab..5214a8a 100644
4184--- a/src/network/networkd-route.c
4185+++ b/src/network/networkd-route.c
4186@@ -1437,9 +1437,13 @@ int link_request_route(
4187
4188 (void) route_get(link->manager, link, route, &existing);
4189
4190- if (route->lifetime_usec == 0)
4191+ if (route->lifetime_usec == 0) {
4192+ if (consume_object)
4193+ route_free(route);
4194+
4195 /* The requested route is outdated. Let's remove it. */
4196 return route_remove_and_drop(existing);
4197+ }
4198
4199 if (!existing) {
4200 _cleanup_(route_freep) Route *tmp = NULL;
4201diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c
4202index 1535d19..75fa931 100644
4203--- a/src/nspawn/nspawn-patch-uid.c
4204+++ b/src/nspawn/nspawn-patch-uid.c
4205@@ -181,7 +181,9 @@ static int patch_acls(int fd, const char *name, const struct stat *st, uid_t shi
4206
4207 if (S_ISDIR(st->st_mode)) {
4208 acl_free(acl);
4209- acl_free(shifted);
4210+
4211+ if (shifted)
4212+ acl_free(shifted);
4213
4214 acl = shifted = NULL;
4215
4216diff --git a/src/partition/growfs.c b/src/partition/growfs.c
4217index 8a04071..6280a24 100644
4218--- a/src/partition/growfs.c
4219+++ b/src/partition/growfs.c
4220@@ -3,12 +3,17 @@
4221 #include <errno.h>
4222 #include <fcntl.h>
4223 #include <getopt.h>
4224-#include <linux/btrfs.h>
4225 #include <linux/magic.h>
4226 #include <sys/ioctl.h>
4227 #include <sys/mount.h>
4228 #include <sys/types.h>
4229 #include <sys/vfs.h>
4230+/* This needs to be included after sys/mount.h, as since [0] linux/btrfs.h
4231+ * includes linux/fs.h causing build errors
4232+ * See: https://github.com/systemd/systemd/issues/8507
4233+ * [0] https://github.com/torvalds/linux/commit/a28135303a669917002f569aecebd5758263e4aa
4234+ */
4235+#include <linux/btrfs.h>
4236
4237 #include "sd-device.h"
4238
4239diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
4240index b07761a..2d1caf7 100644
4241--- a/src/resolve/resolvectl.c
4242+++ b/src/resolve/resolvectl.c
4243@@ -1933,15 +1933,15 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
4244 return table_log_add_error(r);
4245 }
4246
4247- r = dump_list(table, "DNS Servers:", global_info.dns_ex ?: global_info.dns);
4248+ r = dump_list(table, "DNS Servers", global_info.dns_ex ?: global_info.dns);
4249 if (r < 0)
4250 return r;
4251
4252- r = dump_list(table, "Fallback DNS Servers:", global_info.fallback_dns_ex ?: global_info.fallback_dns);
4253+ r = dump_list(table, "Fallback DNS Servers", global_info.fallback_dns_ex ?: global_info.fallback_dns);
4254 if (r < 0)
4255 return r;
4256
4257- r = dump_list(table, "DNS Domain:", global_info.domains);
4258+ r = dump_list(table, "DNS Domain", global_info.domains);
4259 if (r < 0)
4260 return r;
4261
4262diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
4263index 4f74449..88830fb 100644
4264--- a/src/resolve/resolved-dns-scope.c
4265+++ b/src/resolve/resolved-dns-scope.c
4266@@ -474,7 +474,8 @@ static int dns_scope_socket(
4267 * host result in EHOSTUNREACH, since Linux won't send the packets out of the specified
4268 * interface, but delivers them directly to the local socket. */
4269 if (s->link &&
4270- !manager_find_link_address(s->manager, sa.sa.sa_family, sockaddr_in_addr(&sa.sa))) {
4271+ !manager_find_link_address(s->manager, sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) &&
4272+ in_addr_is_localhost(sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) == 0) {
4273 r = socket_bind_to_ifindex(fd, ifindex);
4274 if (r < 0)
4275 return r;
4276diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c
4277index bcbb275..647c0bd 100644
4278--- a/src/resolve/resolved-dns-search-domain.c
4279+++ b/src/resolve/resolved-dns-search-domain.c
4280@@ -52,7 +52,7 @@ int dns_search_domain_new(
4281 l->n_search_domains++;
4282 break;
4283
4284- case DNS_SERVER_SYSTEM:
4285+ case DNS_SEARCH_DOMAIN_SYSTEM:
4286 LIST_APPEND(domains, m->search_domains, d);
4287 m->n_search_domains++;
4288 break;
4289diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
4290index be9efb0..f939b53 100644
4291--- a/src/resolve/resolved-dns-server.h
4292+++ b/src/resolve/resolved-dns-server.h
4293@@ -44,8 +44,8 @@ typedef enum DnsServerFeatureLevel {
4294 #define DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_DO)
4295 #define DNS_SERVER_FEATURE_LEVEL_IS_UDP(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_UDP, DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_DO)
4296
4297-const char* dns_server_feature_level_to_string(int i) _const_;
4298-int dns_server_feature_level_from_string(const char *s) _pure_;
4299+const char* dns_server_feature_level_to_string(DnsServerFeatureLevel i) _const_;
4300+DnsServerFeatureLevel dns_server_feature_level_from_string(const char *s) _pure_;
4301
4302 struct DnsServer {
4303 Manager *manager;
4304diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c
4305index 8ba5eb9..f878d9e 100644
4306--- a/src/resolve/resolved-varlink.c
4307+++ b/src/resolve/resolved-varlink.c
4308@@ -243,7 +243,7 @@ static void vl_method_resolve_hostname_complete(DnsQuery *query) {
4309 JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q)))));
4310 finish:
4311 if (r < 0) {
4312- log_error_errno(r, "Failed to send hostname reply: %m");
4313+ log_full_errno(ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_ERR, r, "Failed to send hostname reply: %m");
4314 r = varlink_error_errno(q->varlink_request, r);
4315 }
4316 }
4317@@ -462,7 +462,7 @@ static void vl_method_resolve_address_complete(DnsQuery *query) {
4318 JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(dns_query_reply_flags_make(q)))));
4319 finish:
4320 if (r < 0) {
4321- log_error_errno(r, "Failed to send address reply: %m");
4322+ log_full_errno(ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_ERR, r, "Failed to send address reply: %m");
4323 r = varlink_error_errno(q->varlink_request, r);
4324 }
4325 }
4326diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
4327index 14bcbf6..ceb7012 100644
4328--- a/src/shared/bootspec.c
4329+++ b/src/shared/bootspec.c
4330@@ -740,9 +740,11 @@ static int boot_entry_load_unified(
4331 if (!tmp.title)
4332 return log_oom();
4333
4334- tmp.sort_key = strdup(good_sort_key);
4335- if (!tmp.sort_key)
4336- return log_oom();
4337+ if (good_sort_key) {
4338+ tmp.sort_key = strdup(good_sort_key);
4339+ if (!tmp.sort_key)
4340+ return log_oom();
4341+ }
4342
4343 if (good_version) {
4344 tmp.version = strdup(good_version);
4345diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
4346index b850a28..922011e 100644
4347--- a/src/shared/bus-unit-util.c
4348+++ b/src/shared/bus-unit-util.c
4349@@ -2142,6 +2142,9 @@ static int bus_append_scope_property(sd_bus_message *m, const char *field, const
4350 if (STR_IN_SET(field, "User", "Group"))
4351 return bus_append_string(m, field, eq);
4352
4353+ if (streq(field, "OOMPolicy"))
4354+ return bus_append_string(m, field, eq);
4355+
4356 return 0;
4357 }
4358
4359diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c
4360index ecf90e2..eab0ca1 100644
4361--- a/src/shared/creds-util.c
4362+++ b/src/shared/creds-util.c
4363@@ -9,6 +9,7 @@
4364 #include "sd-id128.h"
4365
4366 #include "blockdev-util.h"
4367+#include "capability-util.h"
4368 #include "chattr-util.h"
4369 #include "creds-util.h"
4370 #include "def.h"
4371@@ -173,10 +174,15 @@ static int make_credential_host_secret(
4372 assert(dfd >= 0);
4373 assert(fn);
4374
4375- fd = openat(dfd, ".", O_CLOEXEC|O_WRONLY|O_TMPFILE, 0400);
4376+ /* For non-root users creating a temporary file using the openat(2) over "." will fail later, in the
4377+ * linkat(2) step at the end. The reason is that linkat(2) requires the CAP_DAC_READ_SEARCH
4378+ * capability when it uses the AT_EMPTY_PATH flag. */
4379+ if (have_effective_cap(CAP_DAC_READ_SEARCH) > 0) {
4380+ fd = openat(dfd, ".", O_CLOEXEC|O_WRONLY|O_TMPFILE, 0400);
4381+ if (fd < 0)
4382+ log_debug_errno(errno, "Failed to create temporary credential file with O_TMPFILE, proceeding without: %m");
4383+ }
4384 if (fd < 0) {
4385- log_debug_errno(errno, "Failed to create temporary credential file with O_TMPFILE, proceeding without: %m");
4386-
4387 if (asprintf(&t, "credential.secret.%016" PRIx64, random_u64()) < 0)
4388 return -ENOMEM;
4389
4390@@ -602,24 +608,14 @@ int encrypt_credential_and_warn(
4391
4392 #if HAVE_TPM2
4393 bool try_tpm2;
4394- if (sd_id128_equal(with_key, _CRED_AUTO)) {
4395- /* If automatic mode is selected and we are running in a container, let's not try TPM2. OTOH
4396- * if user picks TPM2 explicitly, let's always honour the request and try. */
4397-
4398- r = detect_container();
4399- if (r < 0)
4400- log_debug_errno(r, "Failed to determine whether we are running in a container, ignoring: %m");
4401- else if (r > 0)
4402- log_debug("Running in container, not attempting to use TPM2.");
4403-
4404- try_tpm2 = r <= 0;
4405- } else if (sd_id128_equal(with_key, _CRED_AUTO_INITRD)) {
4406- /* If automatic mode for initrds is selected, we'll use the TPM2 key if the firmware does it,
4407- * otherwise we'll use a fixed key */
4408+ if (sd_id128_in_set(with_key, _CRED_AUTO, _CRED_AUTO_INITRD)) {
4409+ /* If automatic mode is selected lets see if a TPM2 it is present. If we are running in a
4410+ * container tpm2_support will detect this, and will return a different flag combination of
4411+ * TPM2_SUPPORT_FULL, effectively skipping the use of TPM2 when inside one. */
4412
4413- try_tpm2 = efi_has_tpm2();
4414+ try_tpm2 = tpm2_support() == TPM2_SUPPORT_FULL;
4415 if (!try_tpm2)
4416- log_debug("Firmware lacks TPM2 support, not attempting to use TPM2.");
4417+ log_debug("System lacks TPM2 support or running in a container, not attempting to use TPM2.");
4418 } else
4419 try_tpm2 = sd_id128_in_set(with_key,
4420 CRED_AES256_GCM_BY_TPM2_HMAC,
4421@@ -660,7 +656,7 @@ int encrypt_credential_and_warn(
4422 &tpm2_primary_alg);
4423 if (r < 0) {
4424 if (sd_id128_equal(with_key, _CRED_AUTO_INITRD))
4425- log_warning("Firmware reported a TPM2 being present and used, but we didn't manage to talk to it. Credential will be refused if SecureBoot is enabled.");
4426+ log_warning("TPM2 present and used, but we didn't manage to talk to it. Credential will be refused if SecureBoot is enabled.");
4427 else if (!sd_id128_equal(with_key, _CRED_AUTO))
4428 return r;
4429
4430diff --git a/src/shared/generator.c b/src/shared/generator.c
4431index 5d019f4..85a6316 100644
4432--- a/src/shared/generator.c
4433+++ b/src/shared/generator.c
4434@@ -467,6 +467,14 @@ int generator_hook_up_mkfs(
4435
4436 log_debug("Creating %s", unit_file);
4437
4438+ const char *fsck_unit;
4439+ if (in_initrd() && path_equal(where, "/sysroot"))
4440+ fsck_unit = SPECIAL_FSCK_ROOT_SERVICE;
4441+ else if (in_initrd() && path_equal(where, "/sysusr/usr"))
4442+ fsck_unit = SPECIAL_FSCK_USR_SERVICE;
4443+ else
4444+ fsck_unit = "systemd-fsck@%i.service";
4445+
4446 escaped = cescape(node);
4447 if (!escaped)
4448 return log_oom();
4449@@ -492,7 +500,7 @@ int generator_hook_up_mkfs(
4450 "After=%%i.device\n"
4451 /* fsck might or might not be used, so let's be safe and order
4452 * ourselves before both systemd-fsck@.service and the mount unit. */
4453- "Before=shutdown.target systemd-fsck@%%i.service %s\n"
4454+ "Before=shutdown.target %s %s\n"
4455 "\n"
4456 "[Service]\n"
4457 "Type=oneshot\n"
4458@@ -500,6 +508,7 @@ int generator_hook_up_mkfs(
4459 "ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
4460 "TimeoutSec=0\n",
4461 program_invocation_short_name,
4462+ fsck_unit,
4463 where_unit,
4464 type,
4465 escaped);
4466diff --git a/src/shared/install.c b/src/shared/install.c
4467index 834a1c5..2c030b8 100644
4468--- a/src/shared/install.c
4469+++ b/src/shared/install.c
4470@@ -284,6 +284,9 @@ InstallChangeType install_changes_add(
4471 assert(!changes == !n_changes);
4472 assert(INSTALL_CHANGE_TYPE_VALID(type));
4473
4474+ /* Message formatting requires <path> to be set. */
4475+ assert(path);
4476+
4477 /* Register a change or error. Note that the return value may be the error
4478 * that was passed in, or -ENOMEM generated internally. */
4479
4480@@ -339,7 +342,9 @@ void install_changes_dump(int r, const char *verb, const InstallChange *changes,
4481 assert(verb || r >= 0);
4482
4483 for (size_t i = 0; i < n_changes; i++) {
4484- assert(verb || changes[i].type >= 0);
4485+ if (changes[i].type < 0)
4486+ assert(verb);
4487+ assert(changes[i].path);
4488
4489 /* When making changes here, make sure to also change install_error() in dbus-manager.c. */
4490
4491@@ -376,7 +381,7 @@ void install_changes_dump(int r, const char *verb, const InstallChange *changes,
4492 break;
4493 case INSTALL_CHANGE_AUXILIARY_FAILED:
4494 if (!quiet)
4495- log_warning("Failed to enable auxiliary unit %s, ignoring.", changes[i].source);
4496+ log_warning("Failed to enable auxiliary unit %s, ignoring.", changes[i].path);
4497 break;
4498 case -EEXIST:
4499 if (changes[i].source)
4500@@ -2126,7 +2131,7 @@ static int install_context_apply(
4501 q = install_info_traverse(ctx, lp, i, flags, NULL);
4502 if (q < 0) {
4503 if (i->auxiliary) {
4504- q = install_changes_add(changes, n_changes, INSTALL_CHANGE_AUXILIARY_FAILED, NULL, i->name);
4505+ q = install_changes_add(changes, n_changes, INSTALL_CHANGE_AUXILIARY_FAILED, i->name, NULL);
4506 if (q < 0)
4507 return q;
4508 continue;
4509diff --git a/src/shared/install.h b/src/shared/install.h
4510index 9bb412b..0abc738 100644
4511--- a/src/shared/install.h
4512+++ b/src/shared/install.h
4513@@ -197,7 +197,7 @@ int unit_file_exists(LookupScope scope, const LookupPaths *paths, const char *na
4514 int unit_file_get_list(LookupScope scope, const char *root_dir, Hashmap *h, char **states, char **patterns);
4515 Hashmap* unit_file_list_free(Hashmap *h);
4516
4517-InstallChangeType install_changes_add(InstallChange **changes, size_t *n_changes, int type, const char *path, const char *source);
4518+InstallChangeType install_changes_add(InstallChange **changes, size_t *n_changes, InstallChangeType type, const char *path, const char *source);
4519 void install_changes_free(InstallChange *changes, size_t n_changes);
4520 void install_changes_dump(int r, const char *verb, const InstallChange *changes, size_t n_changes, bool quiet);
4521
4522@@ -224,7 +224,7 @@ UnitFileState unit_file_state_from_string(const char *s) _pure_;
4523 /* from_string conversion is unreliable because of the overlap between -EPERM and -1 for error. */
4524
4525 const char *install_change_type_to_string(InstallChangeType t) _const_;
4526-int install_change_type_from_string(const char *s) _pure_;
4527+InstallChangeType install_change_type_from_string(const char *s) _pure_;
4528
4529 const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
4530 UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;
4531diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c
4532index 975c027..6882b62 100644
4533--- a/src/shared/mount-setup.c
4534+++ b/src/shared/mount-setup.c
4535@@ -102,8 +102,10 @@ static const MountPoint mount_table[] = {
4536 cg_is_legacy_wanted, MNT_IN_CONTAINER },
4537 { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV,
4538 cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
4539+#if ENABLE_PSTORE
4540 { "pstore", "/sys/fs/pstore", "pstore", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
4541 NULL, MNT_NONE },
4542+#endif
4543 #if ENABLE_EFI
4544 { "efivarfs", "/sys/firmware/efi/efivars", "efivarfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
4545 is_efi_boot, MNT_NONE },
4546diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
4547index efc066c..1632132 100644
4548--- a/src/shared/sleep-config.c
4549+++ b/src/shared/sleep-config.c
4550@@ -116,7 +116,7 @@ int parse_sleep_config(SleepConfig **ret_sleep_config) {
4551 if (sc->hibernate_delay_sec == 0)
4552 sc->hibernate_delay_sec = 2 * USEC_PER_HOUR;
4553
4554- /* ensure values set for all required fields */
4555+ /* Ensure values set for all required fields */
4556 if (!sc->states[SLEEP_SUSPEND] || !sc->modes[SLEEP_HIBERNATE]
4557 || !sc->states[SLEEP_HIBERNATE] || !sc->modes[SLEEP_HYBRID_SLEEP] || !sc->states[SLEEP_HYBRID_SLEEP])
4558 return log_oom();
4559@@ -172,11 +172,11 @@ static int read_battery_capacity_percentage(sd_device *dev) {
4560
4561 r = sd_device_get_property_value(dev, "POWER_SUPPLY_CAPACITY", &power_supply_capacity);
4562 if (r < 0)
4563- return log_device_debug_errno(dev, r, "Failed to read battery capacity: %m");
4564+ return log_device_debug_errno(dev, r, "Failed to get property POWER_SUPPLY_CAPACITY: %m");
4565
4566 r = safe_atoi(power_supply_capacity, &battery_capacity);
4567 if (r < 0)
4568- return log_device_debug_errno(dev, r, "Failed to parse battery capacity: %m");
4569+ return log_device_debug_errno(dev, r, "Failed to parse property POWER_SUPPLY_CAPACITY: %m");
4570
4571 if (battery_capacity < 0 || battery_capacity > 100)
4572 return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ERANGE), "Invalid battery capacity");
4573@@ -184,14 +184,14 @@ static int read_battery_capacity_percentage(sd_device *dev) {
4574 return battery_capacity;
4575 }
4576
4577-/* If battery percentage capacity is less than equal to 5% return success */
4578+/* If battery percentage capacity is <= 5%, return success */
4579 int battery_is_low(void) {
4580 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
4581 sd_device *dev;
4582 int r;
4583
4584 /* We have not used battery capacity_level since value is set to full
4585- * or Normal in case acpi is not working properly. In case of no battery
4586+ * or Normal in case ACPI is not working properly. In case of no battery
4587 * 0 will be returned and system will be suspended for 1st cycle then hibernated */
4588
4589 r = battery_enumerator_new(&e);
4590@@ -234,14 +234,12 @@ int fetch_batteries_capacity_by_name(Hashmap **ret) {
4591 int battery_capacity;
4592
4593 battery_capacity = r = read_battery_capacity_percentage(dev);
4594- if (r < 0) {
4595- log_device_debug_errno(dev, r, "Failed to get battery capacity, ignoring: %m");
4596+ if (r < 0)
4597 continue;
4598- }
4599
4600 r = sd_device_get_property_value(dev, "POWER_SUPPLY_NAME", &battery_name);
4601 if (r < 0) {
4602- log_device_debug_errno(dev, r, "Failed to read battery name, ignoring: %m");
4603+ log_device_debug_errno(dev, r, "Failed to get POWER_SUPPLY_NAME property, ignoring: %m");
4604 continue;
4605 }
4606
4607@@ -272,11 +270,11 @@ static int get_battery_identifier(sd_device *dev, const char *property, struct s
4608
4609 r = sd_device_get_property_value(dev, property, &x);
4610 if (r == -ENOENT)
4611- log_device_debug_errno(dev, r, "battery device property %s is unavailable, ignoring: %m", property);
4612+ log_device_debug_errno(dev, r, "Battery device property %s is unavailable, ignoring: %m", property);
4613 else if (r < 0)
4614- return log_device_debug_errno(dev, r, "Failed to read battery device property %s: %m", property);
4615+ return log_device_debug_errno(dev, r, "Failed to get battery device property %s: %m", property);
4616 else if (isempty(x))
4617- log_device_debug(dev, "battery device property '%s' is null.", property);
4618+ log_device_debug(dev, "Battery device property '%s' is empty.", property);
4619 else
4620 siphash24_compress_string(x, state);
4621
4622@@ -319,7 +317,7 @@ static int get_system_battery_identifier_hash(sd_device *dev, uint64_t *ret) {
4623 return 0;
4624 }
4625
4626-/* battery percentage discharge rate per hour is in range 1-199 then return success */
4627+/* Return success if battery percentage discharge rate per hour is in the range 1–199 */
4628 static bool battery_discharge_rate_is_valid(int battery_discharge_rate) {
4629 return battery_discharge_rate > 0 && battery_discharge_rate < 200;
4630 }
4631@@ -470,7 +468,7 @@ int estimate_battery_discharge_rate_per_hour(
4632 return 0;
4633 }
4634
4635-/* calculate the suspend interval for each battery and then return the sum of it */
4636+/* Calculate the suspend interval for each battery and then return their sum */
4637 int get_total_suspend_interval(Hashmap *last_capacity, usec_t *ret) {
4638 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
4639 usec_t total_suspend_interval = 0;
4640@@ -495,7 +493,7 @@ int get_total_suspend_interval(Hashmap *last_capacity, usec_t *ret) {
4641 continue;
4642 }
4643
4644- battery_last_capacity = PTR_TO_CAPACITY(hashmap_get(last_capacity, battery_name));
4645+ battery_last_capacity = get_capacity_by_name(last_capacity, battery_name);
4646 if (battery_last_capacity <= 0)
4647 continue;
4648
4649@@ -516,8 +514,8 @@ int get_total_suspend_interval(Hashmap *last_capacity, usec_t *ret) {
4650
4651 total_suspend_interval = usec_add(total_suspend_interval, suspend_interval);
4652 }
4653- /* The previous discharge rate is stored in per hour basis so converted to minutes.
4654- * Subtracted 30 minutes from the result to keep a buffer of 30 minutes before battery gets critical */
4655+ /* Previous discharge rate is stored in per hour basis converted to usec.
4656+ * Subtract 30 minutes from the result to keep a buffer of 30 minutes before battery gets critical */
4657 total_suspend_interval = usec_sub_unsigned(total_suspend_interval, 30 * USEC_PER_MINUTE);
4658 if (total_suspend_interval == 0)
4659 return -ENOENT;
4660diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
4661index 30ba5d2..84fd5d3 100644
4662--- a/src/sleep/sleep.c
4663+++ b/src/sleep/sleep.c
4664@@ -267,12 +267,12 @@ static int execute(
4665 }
4666
4667 static int custom_timer_suspend(const SleepConfig *sleep_config) {
4668- _cleanup_hashmap_free_ Hashmap *last_capacity = NULL, *current_capacity = NULL;
4669 int r;
4670
4671 assert(sleep_config);
4672
4673 while (battery_is_low() == 0) {
4674+ _cleanup_hashmap_free_ Hashmap *last_capacity = NULL, *current_capacity = NULL;
4675 _cleanup_close_ int tfd = -1;
4676 struct itimerspec ts = {};
4677 usec_t suspend_interval = sleep_config->hibernate_delay_sec, before_timestamp = 0, after_timestamp = 0, total_suspend_interval;
4678@@ -327,7 +327,8 @@ static int custom_timer_suspend(const SleepConfig *sleep_config) {
4679 }
4680
4681 after_timestamp = now(CLOCK_BOOTTIME);
4682- log_debug("Attempting to estimate battery discharge rate after wakeup from %s sleep", FORMAT_TIMESPAN(after_timestamp - before_timestamp, USEC_PER_HOUR));
4683+ log_debug("Attempting to estimate battery discharge rate after wakeup from %s sleep",
4684+ FORMAT_TIMESPAN(after_timestamp - before_timestamp, USEC_PER_HOUR));
4685
4686 if (after_timestamp != before_timestamp) {
4687 r = estimate_battery_discharge_rate_per_hour(last_capacity, current_capacity, before_timestamp, after_timestamp);
4688@@ -366,6 +367,9 @@ static int freeze_thaw_user_slice(const char **method) {
4689 if (r < 0)
4690 return log_debug_errno(r, "Failed to open connection to systemd: %m");
4691
4692+ /* Wait for 1.5 seconds at maximum for freeze operation */
4693+ (void) sd_bus_set_method_call_timeout(bus, 1500 * USEC_PER_MSEC);
4694+
4695 r = bus_call_method(bus, bus_systemd_mgr, *method, &error, NULL, "s", SPECIAL_USER_SLICE);
4696 if (r < 0)
4697 return log_debug_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
4698diff --git a/src/test/test-execute.c b/src/test/test-execute.c
4699index 0283cae..ce3489d 100644
4700--- a/src/test/test-execute.c
4701+++ b/src/test/test-execute.c
4702@@ -1228,6 +1228,9 @@ int main(int argc, char *argv[]) {
4703 if (r == -ENOMEDIUM)
4704 return log_tests_skipped("cgroupfs not available");
4705
4706+ if (path_is_read_only_fs("/sys") > 0)
4707+ return log_tests_skipped("/sys is mounted read-only");
4708+
4709 _cleanup_free_ char *unit_dir = NULL, *unit_paths = NULL;
4710 assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
4711 assert_se(runtime_dir = setup_fake_runtime_dir());
4712diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
4713index 43fdb15..eec4831 100644
4714--- a/src/test/test-unit-name.c
4715+++ b/src/test/test-unit-name.c
4716@@ -241,11 +241,13 @@ TEST_RET(unit_printf, .sd_booted = true) {
4717 *user, *group, *uid, *gid, *home, *shell,
4718 *tmp_dir, *var_tmp_dir;
4719 _cleanup_(manager_freep) Manager *m = NULL;
4720+ _cleanup_close_ int fd = -EBADF;
4721 Unit *u;
4722 int r;
4723
4724 _cleanup_(unlink_tempfilep) char filename[] = "/tmp/test-unit_printf.XXXXXX";
4725- assert_se(mkostemp_safe(filename) >= 0);
4726+ fd = mkostemp_safe(filename);
4727+ assert_se(fd >= 0);
4728
4729 /* Using the specifier functions is admittedly a bit circular, but we don't want to reimplement the
4730 * logic a second time. We're at least testing that the hookup works. */
4731diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
4732index 18bb757..3501ccf 100644
4733--- a/src/tmpfiles/tmpfiles.c
4734+++ b/src/tmpfiles/tmpfiles.c
4735@@ -2849,8 +2849,11 @@ static void item_free_contents(Item *i) {
4736 strv_free(i->xattrs);
4737
4738 #if HAVE_ACL
4739- acl_free(i->acl_access);
4740- acl_free(i->acl_default);
4741+ if (i->acl_access)
4742+ acl_free(i->acl_access);
4743+
4744+ if (i->acl_default)
4745+ acl_free(i->acl_default);
4746 #endif
4747 }
4748
4749diff --git a/test/TEST-55-OOMD/test.sh b/test/TEST-55-OOMD/test.sh
4750index 4dc4142..4032896 100755
4751--- a/test/TEST-55-OOMD/test.sh
4752+++ b/test/TEST-55-OOMD/test.sh
4753@@ -17,6 +17,12 @@ test_append_files() {
4754 cat >>"${initdir:?}/etc/fstab" <<EOF
4755 UUID=$(blkid -o value -s UUID "${LOOPDEV}p2") none swap defaults 0 0
4756 EOF
4757+
4758+ mkdir -p "${initdir:?}/etc/systemd/system/init.scope.d/"
4759+ cat >>"${initdir:?}/etc/systemd/system/init.scope.d/test-55-oomd.conf" <<EOF
4760+[Scope]
4761+MemoryHigh=10G
4762+EOF
4763 )
4764 }
4765
4766diff --git a/test/fuzz/fuzz-unit-file/directives.scope b/test/fuzz/fuzz-unit-file/directives.scope
4767index 4552d0b..2285587 100644
4768--- a/test/fuzz/fuzz-unit-file/directives.scope
4769+++ b/test/fuzz/fuzz-unit-file/directives.scope
4770@@ -47,6 +47,7 @@ MemoryMax=
4771 MemoryMin=
4772 MemorySwapMax=
4773 NetClass=
4774+OOMPolicy=
4775 RestartKillSignal=
4776 RestrictNetworkInterfaces=
4777 RuntimeMaxSec=
4778diff --git a/test/test-functions b/test/test-functions
4779index 5613215..ae0a993 100644
4780--- a/test/test-functions
4781+++ b/test/test-functions
4782@@ -158,6 +158,7 @@ BASICTOOLS=(
4783 cat
4784 chmod
4785 chown
4786+ chroot
4787 cmp
4788 cryptsetup
4789 cut
4790@@ -1908,6 +1909,21 @@ install_dbus() {
4791 </policy>
4792 </busconfig>
4793 EOF
4794+
4795+ # If we run without KVM, bump the service start timeout
4796+ if ! get_bool "$QEMU_KVM"; then
4797+ cat >"$initdir/etc/dbus-1/system.d/service.timeout.conf" <<EOF
4798+<?xml version="1.0"?>
4799+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
4800+ "https://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
4801+<busconfig>
4802+ <limit name="service_start_timeout">60000</limit>
4803+</busconfig>
4804+EOF
4805+ # Bump the client-side timeout in sd-bus as well
4806+ mkdir -p "$initdir/etc/systemd/system.conf.d"
4807+ echo -e '[Manager]\nDefaultEnvironment=SYSTEMD_BUS_TIMEOUT=60' >"$initdir/etc/systemd/system.conf.d/bus-timeout.conf"
4808+ fi
4809 }
4810
4811 install_user_dbus() {
4812diff --git a/test/test-network/conf/23-bond199.network b/test/test-network/conf/23-bond199.network
4813index 6a1f9a1..9f4879f 100644
4814--- a/test/test-network/conf/23-bond199.network
4815+++ b/test/test-network/conf/23-bond199.network
4816@@ -4,6 +4,3 @@ Name=bond199
4817
4818 [Network]
4819 IPv6AcceptRA=no
4820-
4821-[Link]
4822-MACAddress=00:11:22:33:44:55
4823diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
4824index 693ddfa..5a731f5 100755
4825--- a/test/test-network/systemd-networkd-tests.py
4826+++ b/test/test-network/systemd-networkd-tests.py
4827@@ -1063,6 +1063,10 @@ class NetworkctlTests(unittest.TestCase, Utilities):
4828 self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
4829 self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
4830
4831+ # This test may be run on the system that has older udevd than 70f32a260b5ebb68c19ecadf5d69b3844896ba55 (v249).
4832+ # In that case, the udev DB for the loopback network interface may already have ID_NET_LINK_FILE property.
4833+ # Let's reprocess the interface and drop the property.
4834+ check_output(*udevadm_cmd, 'trigger', '--settle', '--action=add', '/sys/class/net/lo')
4835 output = check_output(*networkctl_cmd, '-n', '0', 'status', 'lo', env=env)
4836 print(output)
4837 self.assertRegex(output, r'Link File: n/a')
4838@@ -3799,7 +3803,7 @@ class NetworkdBondTests(unittest.TestCase, Utilities):
4839
4840 output = check_output('ip -d link show bond199')
4841 print(output)
4842- self.assertRegex(output, 'active_slave dummy98')
4843+ self.assertIn('active_slave dummy98', output)
4844
4845 def test_bond_primary_slave(self):
4846 copy_network_unit('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
4847@@ -3808,8 +3812,20 @@ class NetworkdBondTests(unittest.TestCase, Utilities):
4848
4849 output = check_output('ip -d link show bond199')
4850 print(output)
4851- self.assertRegex(output, 'primary dummy98')
4852- self.assertIn('link/ether 00:11:22:33:44:55', output)
4853+ self.assertIn('primary dummy98', output)
4854+
4855+ # for issue #25627
4856+ mkdir_p(os.path.join(network_unit_dir, '23-bond199.network.d'))
4857+ for mac in ['00:11:22:33:44:55', '00:11:22:33:44:56']:
4858+ with open(os.path.join(network_unit_dir, '23-bond199.network.d/mac.conf'), mode='w', encoding='utf-8') as f:
4859+ f.write(f'[Link]\nMACAddress={mac}\n')
4860+
4861+ networkctl_reload()
4862+ self.wait_online(['dummy98:enslaved', 'bond199:degraded'])
4863+
4864+ output = check_output('ip -d link show bond199')
4865+ print(output)
4866+ self.assertIn(f'link/ether {mac}', output)
4867
4868 def test_bond_operstate(self):
4869 copy_network_unit('25-bond.netdev', '11-dummy.netdev', '12-dummy.netdev',
4870diff --git a/test/test-shutdown.py b/test/test-shutdown.py
4871index e181f97..13e18ec 100755
4872--- a/test/test-shutdown.py
4873+++ b/test/test-shutdown.py
4874@@ -17,7 +17,7 @@ def run(args):
4875 logger.info("spawning test")
4876 console = pexpect.spawn(args.command, args.arg, env={
4877 "TERM": "linux",
4878- }, encoding='utf-8', timeout=30)
4879+ }, encoding='utf-8', timeout=60)
4880
4881 if args.verbose:
4882 console.logfile = sys.stdout
4883diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh
4884index a8e7a5a..37ae606 100755
4885--- a/test/units/testsuite-26.sh
4886+++ b/test/units/testsuite-26.sh
4887@@ -294,7 +294,7 @@ systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO
4888
4889 # test for sysv-generator (issue #24990)
4890 if [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]]; then
4891-
4892+ mkdir -p /etc/init.d
4893 # invalid dependency
4894 cat >/etc/init.d/issue-24990 <<\EOF
4895 #!/bin/bash
4896diff --git a/test/units/testsuite-55.sh b/test/units/testsuite-55.sh
4897index 8fa1d01..0887eac 100755
4898--- a/test/units/testsuite-55.sh
4899+++ b/test/units/testsuite-55.sh
4900@@ -5,6 +5,9 @@ set -o pipefail
4901
4902 systemd-analyze log-level debug
4903
4904+# Ensure that the init.scope.d drop-in is applied on boot
4905+test "$(cat /sys/fs/cgroup/init.scope/memory.high)" != "max"
4906+
4907 # Loose checks to ensure the environment has the necessary features for systemd-oomd
4908 [[ -e /proc/pressure ]] || echo "no PSI" >>/skipped
4909 cgroup_type="$(stat -fc %T /sys/fs/cgroup/)"
4910diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh
4911index 7673036..c4406f3 100755
4912--- a/test/units/testsuite-64.sh
4913+++ b/test/units/testsuite-64.sh
4914@@ -192,7 +192,7 @@ testcase_nvme_subsystem() {
4915 testcase_virtio_scsi_identically_named_partitions() {
4916 local num
4917
4918- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then
4919+ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then
4920 num=$((4 * 4))
4921 else
4922 num=$((16 * 8))
4923@@ -243,6 +243,7 @@ EOF
4924 echo "${FUNCNAME[0]}: test failover"
4925 local device expected link mpoint part
4926 local -a devices
4927+ mkdir -p /mnt
4928 mpoint="$(mktemp -d /mnt/mpathXXX)"
4929 wwid="deaddeadbeef0000"
4930 path="/dev/disk/by-id/wwn-0x$wwid"
4931@@ -305,7 +306,7 @@ testcase_simultaneous_events() {
4932 local -a devices symlinks
4933 local -A running
4934
4935- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then
4936+ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then
4937 num_part=2
4938 iterations=10
4939 timeout=240
4940@@ -400,7 +401,7 @@ testcase_lvm_basic() {
4941 /dev/disk/by-id/ata-foobar_deadbeeflvm{0..3}
4942 )
4943
4944- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then
4945+ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then
4946 timeout=180
4947 else
4948 timeout=30
4949@@ -453,7 +454,7 @@ testcase_lvm_basic() {
4950 helper_check_device_units
4951
4952 # Same as above, but now with more "stress"
4953- if [[ -n "${ASAN_OPTIONS:-}" ]] || [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then
4954+ if [[ -v ASAN_OPTIONS || "$(systemd-detect-virt -v)" == "qemu" ]]; then
4955 iterations=10
4956 else
4957 iterations=50
4958@@ -478,7 +479,7 @@ testcase_lvm_basic() {
4959 helper_check_device_units
4960
4961 # Create & remove LVs in a loop, i.e. with more "stress"
4962- if [[ -n "${ASAN_OPTIONS:-}" ]]; then
4963+ if [[ -v ASAN_OPTIONS ]]; then
4964 iterations=8
4965 partitions=16
4966 elif [[ "$(systemd-detect-virt -v)" == "qemu" ]]; then
4967diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
4968index 1f34308..ebe1f57 100755
4969--- a/test/units/testsuite-65.sh
4970+++ b/test/units/testsuite-65.sh
4971@@ -139,6 +139,16 @@ systemd-analyze cat-config systemd/system.conf systemd/journald.conf >/dev/null
4972 systemd-analyze cat-config systemd/system.conf foo/bar systemd/journald.conf >/dev/null
4973 systemd-analyze cat-config foo/bar
4974
4975+if [[ ! -v ASAN_OPTIONS ]]; then
4976+ # check that systemd-analyze cat-config paths work in a chroot
4977+ mkdir -p /tmp/root
4978+ mount --bind / /tmp/root
4979+ systemd-analyze cat-config systemd/system-preset >/tmp/out1
4980+ chroot /tmp/root systemd-analyze cat-config systemd/system-preset >/tmp/out2
4981+ diff /tmp/out{1,2}
4982+fi
4983+
4984+# verify
4985 mkdir -p /tmp/img/usr/lib/systemd/system/
4986 mkdir -p /tmp/img/opt/
4987
4988diff --git a/test/units/testsuite-73.sh b/test/units/testsuite-73.sh
4989index f9e2dce..4eae0f6 100755
4990--- a/test/units/testsuite-73.sh
4991+++ b/test/units/testsuite-73.sh
4992@@ -92,6 +92,19 @@ test_locale() {
4993 return
4994 fi
4995
4996+ # start with a known default environment and make sure to also give a
4997+ # default value to LC_CTYPE= since we're about to also set/unset it. We
4998+ # also reload PID1 configuration to make sure that PID1 environment itself
4999+ # is updated as it's not always been the case.
5000+ assert_rc 0 localectl set-locale "LANG=en_US.UTF-8" "LC_CTYPE=C"
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches