summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/mkosi.yml294
-rw-r--r--docs/ENVIRONMENT.md14
-rw-r--r--hwdb.d/60-evdev.hwdb7
-rw-r--r--hwdb.d/60-keyboard.hwdb49
-rw-r--r--hwdb.d/60-sensor.hwdb2
-rw-r--r--man/networkd.conf.xml12
-rw-r--r--man/systemd.network.xml18
-rw-r--r--meson.version2
-rwxr-xr-xmkosi.conf.d/10-arch/mkosi.prepare8
-rwxr-xr-xmkosi.conf.d/10-centos-fedora/mkosi.prepare6
-rw-r--r--mkosi.conf.d/10-debian-ubuntu/mkosi.conf5
-rwxr-xr-xmkosi.conf.d/10-debian-ubuntu/mkosi.prepare26
-rw-r--r--mkosi.conf.d/10-fedora/mkosi.conf.d/rawhide.conf7
-rwxr-xr-xmkosi.conf.d/10-opensuse/mkosi.prepare8
-rw-r--r--mkosi.conf.d/10-ubuntu/mkosi.conf3
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot11
-rw-r--r--mkosi.images/build/mkosi.conf.d/arch/mkosi.conf2
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.build.chroot16
-rw-r--r--mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf2
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.prepare5
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot6
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot10
-rw-r--r--mkosi.images/build/mkosi.conf.d/opensuse/mkosi.conf6
-rwxr-xr-xmkosi.images/build/mkosi.conf.d/opensuse/mkosi.prepare5
-rwxr-xr-xmkosi.images/build/mkosi.sync2
-rw-r--r--mkosi.presets/20-final/mkosi.extra/root/.gdbinit3
-rwxr-xr-xmkosi.sanitizers/mkosi.postinst5
-rw-r--r--src/basic/audit-util.c2
-rw-r--r--src/basic/missing_loop.h4
-rw-r--r--src/basic/process-util.c26
-rw-r--r--src/basic/virt.c7
-rw-r--r--src/boot/bootctl-install.c2
-rw-r--r--src/core/namespace.c22
-rw-r--r--src/home/homectl.c2
-rw-r--r--src/libsystemd-network/sd-lldp-tx.c1
-rw-r--r--src/libsystemd-network/test-dhcp-server.c6
-rw-r--r--src/libsystemd/sd-netlink/test-netlink.c16
-rw-r--r--src/login/logind-dbus.c12
-rw-r--r--src/login/logind-dbus.h1
-rw-r--r--src/login/logind-session.c8
-rw-r--r--src/network/networkd-lldp-tx.c30
-rw-r--r--src/network/networkd-lldp-tx.h1
-rw-r--r--src/network/networkd-sysctl.c63
-rw-r--r--src/nspawn/nspawn.c10
-rw-r--r--src/partition/repart.c12
-rw-r--r--src/resolve/resolved-dns-packet.h1
-rw-r--r--src/resolve/resolved-dns-stub.c10
-rw-r--r--src/shared/ask-password-api.c29
-rw-r--r--src/shared/copy.c8
-rw-r--r--src/shared/copy.h39
-rw-r--r--src/shared/dissect-image.c1
-rw-r--r--src/shared/tests.c19
-rw-r--r--src/shared/tests.h34
-rw-r--r--src/test/test-acl-util.c2
-rw-r--r--src/test/test-capability.c7
-rw-r--r--src/test/test-chase.c4
-rw-r--r--src/test/test-chown-rec.c4
-rw-r--r--src/test/test-condition.c7
-rw-r--r--src/test/test-fs-util.c4
-rw-r--r--src/test/test-macro.c12
-rw-r--r--src/test/test-rm-rf.c3
-rw-r--r--src/test/test-socket-util.c2
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c4
-rw-r--r--src/udev/udevadm-test-builtin.c1
-rw-r--r--src/udev/udevadm-test.c1
-rwxr-xr-xsrc/ukify/test/test_ukify.py7
-rwxr-xr-xtest/TEST-13-NSPAWN/test.sh2
-rwxr-xr-xtest/integration-test-wrapper.py2
-rw-r--r--test/test-functions25
-rw-r--r--test/test-systemctl-enable.sh2
-rwxr-xr-xtest/units/TEST-13-NSPAWN.nspawn.sh60
-rwxr-xr-xtest/units/TEST-58-REPART.sh45
-rwxr-xr-xtest/units/TEST-74-AUX-UTILS.detect-virt.sh7
73 files changed, 772 insertions, 329 deletions
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
index 5842158..d76a935 100644
--- a/.github/workflows/mkosi.yml
+++ b/.github/workflows/mkosi.yml
@@ -10,36 +10,36 @@ on:
- main
- v[0-9]+-stable
paths:
- - '**'
- - '!README*'
- - '!LICENSE*'
- - '!LICENSES/**'
- - '!TODO'
- - '!docs/**'
- - '!man/**'
- - '!catalog/**'
- - '!shell-completion/**'
- - '!po/**'
- - '!.**'
- - '.github/**'
+ - "**"
+ - "!README*"
+ - "!LICENSE*"
+ - "!LICENSES/**"
+ - "!TODO"
+ - "!docs/**"
+ - "!man/**"
+ - "!catalog/**"
+ - "!shell-completion/**"
+ - "!po/**"
+ - "!.**"
+ - ".github/**"
pull_request:
branches:
- main
- v[0-9]+-stable
paths:
- - '**'
- - '!README*'
- - '!LICENSE*'
- - '!LICENSES/**'
- - '!TODO'
- - '!docs/**'
- - '!man/**'
- - '!catalog/**'
- - '!shell-completion/**'
- - '!po/**'
- - '!.**'
- - '.github/**'
+ - "**"
+ - "!README*"
+ - "!LICENSE*"
+ - "!LICENSES/**"
+ - "!TODO"
+ - "!docs/**"
+ - "!man/**"
+ - "!catalog/**"
+ - "!shell-completion/**"
+ - "!po/**"
+ - "!.**"
+ - ".github/**"
permissions:
contents: read
@@ -104,126 +104,126 @@ jobs:
relabel: yes
steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- - uses: systemd/mkosi@4eba736412c702bbbe2c6d4a58a92fa977219249
-
- # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
- # immediately, we remove the files in the background. However, we first move them to a different location
- # so that nothing tries to use anything in these directories anymore while we're busy deleting them.
- - name: Free disk space
- run: |
- sudo mv /usr/local /usr/local.trash
- sudo mv /opt/hostedtoolcache /opt/hostedtoolcache.trash
- sudo systemd-run rm -rf /usr/local.trash /opt/hostedtoolcache.trash
-
- - name: Btrfs
- run: |
- truncate --size=100G btrfs.raw
- mkfs.btrfs btrfs.raw
- sudo mkdir /mnt/mkosi
- LOOP="$(sudo losetup --find --show --direct-io=on btrfs.raw)"
- sudo mount "$LOOP" /mnt/mkosi --options compress=zstd:1,user_subvol_rm_allowed,noatime,discard=async,space_cache=v2
- sudo chown "$(id -u):$(id -g)" /mnt/mkosi
- mkdir /mnt/mkosi/tmp
- echo "TMPDIR=/mnt/mkosi/tmp" >>"$GITHUB_ENV"
- ln -s /mnt/mkosi/build build
-
- - name: Configure
- run: |
- # XXX: drop after the HyperV bug that breaks secure boot KVM guests is solved
- sed -i "s/'firmware'\s*:\s*'auto'/'firmware' : 'uefi'/g" test/*/meson.build
- tee mkosi.local.conf <<EOF
- [Distribution]
- Distribution=${{ matrix.distro }}
- Release=${{ matrix.release }}
-
- [Output]
- # Build a disk image in CI as this logic is much more prone to breakage.
- Format=disk
- UseSubvolumes=yes
-
- WorkspaceDirectory=$TMPDIR
- PackageCacheDirectory=$TMPDIR/cache
-
- [Content]
- Environment=
- # Build debuginfo packages since we'll be publishing the packages as artifacts.
- WITH_DEBUG=1
- CFLAGS="${{ matrix.cflags }}"
- SANITIZERS=${{ matrix.sanitizers }}
- MESON_OPTIONS=--werror
- LLVM=${{ matrix.llvm }}
- SYSEXT=1
-
- SELinuxRelabel=${{ matrix.relabel }}
-
- [Host]
- QemuMem=4G
- EOF
-
- - name: Generate secure boot key
- run: mkosi --debug genkey
-
- - name: Show image summary
- run: mkosi summary
-
- - name: Install dependencies
- run: |
- mkosi dependencies |
- xargs -d '\n' sudo apt-get install \
- gperf \
- libblkid-dev \
- libcap-dev \
- libcryptsetup-dev \
- libcurl4-openssl-dev \
- libfdisk-dev \
- libmicrohttpd-dev \
- libmount-dev \
- libtss2-dev \
- meson
-
- - name: Configure meson
- run: |
- meson setup build \
- --buildtype=debugoptimized \
- -Dintegration-tests=true \
- -Dremote=enabled \
- -Dopenssl=enabled \
- -Dblkid=enabled \
- -Dtpm2=enabled \
- -Dlibcryptsetup=enabled \
- -Dlibcurl=enabled \
- -Drepart=enabled \
- -Dfirstboot=true \
- -Dsysusers=true \
- -Dtmpfiles=true \
- -Dhwdb=true \
- -Dvmspawn=enabled
-
- - name: Build image
- run: sudo meson compile -C build mkosi
-
- - name: Run integration tests
- run: sudo --preserve-env meson test -C build --no-rebuild --suite integration-tests --print-errorlogs --no-stdsplit --num-processes "$(($(nproc) - 1))"
-
- - name: Archive failed test journals
- uses: actions/upload-artifact@v4
- if: failure() && (github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable')
- with:
- name: ci-mkosi-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.distro }}-${{ matrix.release }}-failed-test-journals
- path: |
- build/test/journal/*.journal
- build/meson-logs/*
- retention-days: 7
-
- - name: Archive packages
- uses: actions/upload-artifact@v4
- if: (success() || failure()) && (github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable')
- with:
- name: ci-mkosi-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.distro }}-${{ matrix.release }}-packages
- path: |
- build/mkosi.output/*.rpm
- build/mkosi.output/*.deb
- build/mkosi.output/*.ddeb
- build/mkosi.output/*.pkg.tar
- retention-days: 4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+ - uses: systemd/mkosi@31b4e756c1484c302435653da5d3b9bdfae38518
+
+ # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
+ # immediately, we remove the files in the background. However, we first move them to a different location
+ # so that nothing tries to use anything in these directories anymore while we're busy deleting them.
+ - name: Free disk space
+ run: |
+ sudo mv /usr/local /usr/local.trash
+ sudo mv /opt/hostedtoolcache /opt/hostedtoolcache.trash
+ sudo systemd-run rm -rf /usr/local.trash /opt/hostedtoolcache.trash
+
+ - name: Btrfs
+ run: |
+ truncate --size=100G btrfs.raw
+ mkfs.btrfs btrfs.raw
+ sudo mkdir /mnt/mkosi
+ LOOP="$(sudo losetup --find --show --direct-io=on btrfs.raw)"
+ sudo mount "$LOOP" /mnt/mkosi --options compress=zstd:1,user_subvol_rm_allowed,noatime,discard=async,space_cache=v2
+ sudo chown "$(id -u):$(id -g)" /mnt/mkosi
+ mkdir /mnt/mkosi/tmp
+ echo "TMPDIR=/mnt/mkosi/tmp" >>"$GITHUB_ENV"
+ ln -s /mnt/mkosi/build build
+
+ - name: Configure
+ run: |
+ # XXX: drop after the HyperV bug that breaks secure boot KVM guests is solved
+ sed -i "s/'firmware'\s*:\s*'auto'/'firmware' : 'uefi'/g" test/*/meson.build
+ tee mkosi.local.conf <<EOF
+ [Distribution]
+ Distribution=${{ matrix.distro }}
+ Release=${{ matrix.release }}
+
+ [Output]
+ # Build a disk image in CI as this logic is much more prone to breakage.
+ Format=disk
+ UseSubvolumes=yes
+
+ WorkspaceDirectory=$TMPDIR
+ PackageCacheDirectory=$TMPDIR/cache
+
+ [Content]
+ Environment=
+ # Build debuginfo packages since we'll be publishing the packages as artifacts.
+ WITH_DEBUG=1
+ CFLAGS="${{ matrix.cflags }}"
+ SANITIZERS=${{ matrix.sanitizers }}
+ MESON_OPTIONS=--werror
+ LLVM=${{ matrix.llvm }}
+ SYSEXT=1
+
+ SELinuxRelabel=${{ matrix.relabel }}
+
+ [Host]
+ QemuMem=4G
+ EOF
+
+ - name: Generate secure boot key
+ run: mkosi --debug genkey
+
+ - name: Show image summary
+ run: mkosi summary
+
+ - name: Install dependencies
+ run: |
+ mkosi dependencies |
+ xargs -d '\n' sudo apt-get install \
+ gperf \
+ libblkid-dev \
+ libcap-dev \
+ libcryptsetup-dev \
+ libcurl4-openssl-dev \
+ libfdisk-dev \
+ libmicrohttpd-dev \
+ libmount-dev \
+ libtss2-dev \
+ meson
+
+ - name: Configure meson
+ run: |
+ meson setup build \
+ --buildtype=debugoptimized \
+ -Dintegration-tests=true \
+ -Dremote=enabled \
+ -Dopenssl=enabled \
+ -Dblkid=enabled \
+ -Dtpm2=enabled \
+ -Dlibcryptsetup=enabled \
+ -Dlibcurl=enabled \
+ -Drepart=enabled \
+ -Dfirstboot=true \
+ -Dsysusers=true \
+ -Dtmpfiles=true \
+ -Dhwdb=true \
+ -Dvmspawn=enabled
+
+ - name: Build image
+ run: sudo meson compile -C build mkosi
+
+ - name: Run integration tests
+ run: sudo --preserve-env meson test -C build --no-rebuild --suite integration-tests --print-errorlogs --no-stdsplit --num-processes "$(($(nproc) - 1))"
+
+ - name: Archive failed test journals
+ uses: actions/upload-artifact@v4
+ if: failure() && (github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable')
+ with:
+ name: ci-mkosi-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.distro }}-${{ matrix.release }}-failed-test-journals
+ path: |
+ build/test/journal/*.journal
+ build/meson-logs/*
+ retention-days: 7
+
+ - name: Archive packages
+ uses: actions/upload-artifact@v4
+ if: (success() || failure()) && (github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable')
+ with:
+ name: ci-mkosi-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.distro }}-${{ matrix.release }}-packages
+ path: |
+ build/mkosi.output/*.rpm
+ build/mkosi.output/*.deb
+ build/mkosi.output/*.ddeb
+ build/mkosi.output/*.pkg.tar
+ retention-days: 4
diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md
index c8b75ac..6081351 100644
--- a/docs/ENVIRONMENT.md
+++ b/docs/ENVIRONMENT.md
@@ -23,17 +23,17 @@ All tools:
* `$SYSTEMD_OFFLINE=[0|1]` — if set to `1`, then `systemctl` will refrain from
talking to PID 1; this has the same effect as the historical detection of
`chroot()`. Setting this variable to `0` instead has a similar effect as
- `$SYSTEMD_IGNORE_CHROOT=1`; i.e. tools will try to communicate with PID 1
+ `$SYSTEMD_IN_CHROOT=0`; i.e. tools will try to communicate with PID 1
even if a `chroot()` environment is detected. You almost certainly want to
set this to `1` if you maintain a package build system or similar and are
trying to use a modern container system and not plain `chroot()`.
-* `$SYSTEMD_IGNORE_CHROOT=1` — if set, don't check whether being invoked in a
- `chroot()` environment. This is particularly relevant for systemctl, as it
- will not alter its behaviour for `chroot()` environments if set. Normally it
- refrains from talking to PID 1 in such a case; turning most operations such
- as `start` into no-ops. If that's what's explicitly desired, you might
- consider setting `$SYSTEMD_OFFLINE=1`.
+* `$SYSTEMD_IN_CHROOT=0|1` — takes a boolean. If set, overrides chroot detection.
+ This is particularly relevant for systemctl, as it will not alter its behaviour
+ for `chroot()` environments if `SYSTEMD_IN_CHROOT=0`. Normally it refrains from
+ talking to PID 1 in such a case; turning most operations such as `start` into
+ no-ops. If that's what's explicitly desired, you might consider setting
+ `$SYSTEMD_OFFLINE=1`.
* `$SYSTEMD_FIRST_BOOT=0|1` — if set, assume "first boot" condition to be false
or true, instead of checking the flag file created by PID 1.
diff --git a/hwdb.d/60-evdev.hwdb b/hwdb.d/60-evdev.hwdb
index 0b70a82..372ae68 100644
--- a/hwdb.d/60-evdev.hwdb
+++ b/hwdb.d/60-evdev.hwdb
@@ -255,6 +255,13 @@ evdev:input:b0003v0ED1p7821*
# Dell
#########################################
+# Dell AlpsPS/2 ALPS DualPoint TouchPad
+evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*:svnDellInc.*:pnLatitudeE7440*:
+ EVDEV_ABS_00=:::28
+ EVDEV_ABS_01=:::28
+ EVDEV_ABS_35=:::28
+ EVDEV_ABS_36=:::28
+
# Dell Vostro 1510
evdev:name:AlpsPS/2 ALPS GlidePoint*:dmi:bvn*:bvr*:bd*:svnDellInc.:pnVostro1510:*
EVDEV_ABS_00=::14
diff --git a/hwdb.d/60-keyboard.hwdb b/hwdb.d/60-keyboard.hwdb
index 15c0d4c..5a08931 100644
--- a/hwdb.d/60-keyboard.hwdb
+++ b/hwdb.d/60-keyboard.hwdb
@@ -223,7 +223,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pn*:*
# Swift SF314-511
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnSwiftSF314-511:pvr*
- KEYBOARD_KEY_8a=f20 # Fn+F12, microphone mute
+ KEYBOARD_KEY_8a=f20 # Fn+F12, microphone mute
# Predator PHN16-71
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-71:*
@@ -231,6 +231,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-71:*
KEYBOARD_KEY_f5=prog1 # "predator sense" button
KEYBOARD_KEY_66=micmute # Microphone mute button
+# Predator PHN16-72
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-72:*
+ KEYBOARD_KEY_66=micmute # Microphone mute button
+
# Nitro AN515-58
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnNitro*AN*515-58:pvr*
KEYBOARD_KEY_8a=f20 # Microphone mute button
@@ -259,7 +263,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pnM17xR3:*
# Aquarius Cmp NS483
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAquarius*:pnCmp*NS483*:*
KEYBOARD_KEY_56=backslash
- KEYBOARD_KEY_76=f21 # Touchpad Toggle
+ KEYBOARD_KEY_76=f21 # Touchpad Toggle
###########################################################
# Asus
@@ -341,6 +345,9 @@ evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV54x_6x_TU:*
KEYBOARD_KEY_f7=f21 # Touchpad Toggle
KEYBOARD_KEY_f8=f21 # Touchpad Toggle
+evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV5xTNC_TND_TNE:*
+ KEYBOARD_KEY_81=f20 # Fn+4; Mic Mute
+
###########################################################
# Compal
###########################################################
@@ -973,7 +980,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnJP-IK:pnLEAPW502:pvr*
# LE14U/LE15U
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnKVADRA*:pn*LE1*U*:*
- KEYBOARD_KEY_76=f21 # Fn+F1 Toggle touchpad, sends meta+ctrl+toggle
+ KEYBOARD_KEY_76=f21 # Fn+F1 Toggle touchpad, sends meta+ctrl+toggle
###########################################################
# Lenovo
@@ -1901,9 +1908,9 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:*
# Galaxy Book (2021) NP750XDA-KD4SE
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn750XDA:pvr*
KEYBOARD_KEY_81=!esc
- KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings
- KEYBOARD_KEY_ae=!volumedown # Fn+F7 volume down
- KEYBOARD_KEY_b0=!volumeup # Fn+F8 volume up
+ KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings
+ KEYBOARD_KEY_ae=!volumedown # Fn+F7 volume down
+ KEYBOARD_KEY_b0=!volumeup # Fn+F8 volume up
###########################################################
@@ -2028,13 +2035,13 @@ evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:
# Portege Z830 ACPI quickstart buttons
evdev:name:Quickstart Button 1:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
- KEYBOARD_KEY_1=prog1 # TOSHIBA eco button
+ KEYBOARD_KEY_1=prog1 # TOSHIBA eco button
evdev:name:Quickstart Button 2:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
- KEYBOARD_KEY_1=prog2 # TOSHIBA Presentation button
+ KEYBOARD_KEY_1=prog2 # TOSHIBA Presentation button
evdev:name:Quickstart Button 3:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
- KEYBOARD_KEY_1=f21 # Touchpad toggle
+ KEYBOARD_KEY_1=f21 # Touchpad toggle
###########################################################
# VIA
@@ -2067,11 +2074,11 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINET:pnP325J:*
# Home: LeftCtrl + Esc -> LeftMeta (ignore LeftCtrl, map Esc to LeftMeta)
# Back: Backspace -> back (map backspace to back)
evdev:name:FTSC1000:00 2808:509C Keyboard:dmi:*:svnXiaomiInc:pnMipad2:*
- KEYBOARD_KEY_700e0=unknown # LeftCtrl -> ignore
- KEYBOARD_KEY_700e3=unknown # LeftMeta -> ignore
- KEYBOARD_KEY_70016=menu # S -> menu
- KEYBOARD_KEY_70029=leftmeta # Esc -> LeftMeta (Windows key / Win8 tablets home)
- KEYBOARD_KEY_7002a=back # Backspace -> back
+ KEYBOARD_KEY_700e0=unknown # LeftCtrl -> ignore
+ KEYBOARD_KEY_700e3=unknown # LeftMeta -> ignore
+ KEYBOARD_KEY_70016=menu # S -> menu
+ KEYBOARD_KEY_70029=leftmeta # Esc -> LeftMeta (Windows key / Win8 tablets home)
+ KEYBOARD_KEY_7002a=back # Backspace -> back
###########################################################
# Zepto
@@ -2183,7 +2190,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnViewSonic:pnVPAD10:*
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJPW1[12]F11X*:pvr*:*
# Vaio FE14 (VJFE41F11X, VJE42F11X, VJFE44F11X, VJFE54F11X)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJFE*:pvr*:*
- KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad
+ KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad
###########################################################
# Positivo
@@ -2288,6 +2295,18 @@ evdev:input:b0003v05FEp1010*
#
# Presence of a LED is implicit when the property is absent.
+# Apple Wireless keyboards
+evdev:input:b0005v05aCp022C*
+evdev:input:b0005v05aCp022D*
+evdev:input:b0005v05aCp022E*
+evdev:input:b0005v05aCp0239*
+evdev:input:b0005v05aCp023A*
+evdev:input:b0005v05aCp023B*
+evdev:input:b0005v05aCp0255*
+evdev:input:b0005v05aCp0256*
+evdev:input:b0005v05aCp0257*
+ KEYBOARD_LED_NUMLOCK=0
+
# Logitech K750
evdev:input:b0003v046Dp4002*
KEYBOARD_LED_NUMLOCK=0
diff --git a/hwdb.d/60-sensor.hwdb b/hwdb.d/60-sensor.hwdb
index 21f4380..8054783 100644
--- a/hwdb.d/60-sensor.hwdb
+++ b/hwdb.d/60-sensor.hwdb
@@ -152,6 +152,7 @@ sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnM80TA:*
sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TA:*
sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TAF:*
sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TAM:*
+sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pnT100TAS:*
sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:pnT200TA:*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
@@ -163,6 +164,7 @@ sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LA:*
sensor:modalias:acpi:INVN6500*:dmi:*svn*ASUSTeK*:*pn*TP300LD:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
+sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pn*Q551LB:*
sensor:modalias:acpi:INVN6500*:dmi:*svnASUSTeK*:*pn*Q551LN:*
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
index cac1d3b..9daa125 100644
--- a/man/networkd.conf.xml
+++ b/man/networkd.conf.xml
@@ -131,6 +131,12 @@
for more details about the sysctl options. Defaults to unset and the sysctl options will not be
changed.</para>
+ <para>If an interface is configured with a .network file that enables <varname>IPMasquerade=</varname>
+ for IPv4 (that is, <literal>ipv4</literal> or <literal>both</literal>), this setting is implied
+ unless explicitly specified. See <varname>IPMasquerade=</varname> in
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more details.</para>
+
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
@@ -145,6 +151,12 @@
for more details about the sysctl options. Defaults to unset and the sysctl options will not be
changed.</para>
+ <para>If an interface is configured with a .network file that enables <varname>IPMasquerade=</varname>
+ for IPv6 (that is, <literal>ipv6</literal> or <literal>both</literal>), this setting is implied
+ unless explicitly specified. See <varname>IPMasquerade=</varname> in
+ <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more details.</para>
+
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 1e3f244..708c37d 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -888,15 +888,15 @@ DuplicateAddressDetection=none</programlisting></para>
<literal>ipv6</literal>, <literal>both</literal>, or <literal>no</literal>. Defaults to
<literal>no</literal>. Note. Any positive boolean values such as <literal>yes</literal> or
<literal>true</literal> are now deprecated. Please use one of the values above. Specifying
- <literal>ipv4</literal> or <literal>both</literal> implies <varname>IPv4Forwarding=</varname>,
- unless it is explicitly specified. Similarly for <varname>IPv6Forwarding=</varname> when
- <literal>ipv6</literal> or <literal>both</literal> is specified. These implications are only on
- this interface. Hence, to make the IP packet forwarding works,
- <varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> need to be enabled on an
- upstream interface, or globally enabled by specifying them in
- <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- See <varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> in the above for more
- details.</para>
+ <literal>ipv4</literal> or <literal>both</literal> implies <varname>IPv4Forwarding=</varname>
+ settings in both .network file for this interface and the global
+ <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ unless they are explicitly specified. Similarly for <varname>IPv6Forwarding=</varname> when
+ <literal>ipv6</literal> or <literal>both</literal> is specified. See
+ <varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> in the above for the per-link
+ settings, and
+ <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for the global settings.</para>
<xi:include href="version-info.xml" xpointer="v219"/>
</listitem>
diff --git a/meson.version b/meson.version
index e162ee4..9516687 100644
--- a/meson.version
+++ b/meson.version
@@ -1 +1 @@
-256.5
+256.6
diff --git a/mkosi.conf.d/10-arch/mkosi.prepare b/mkosi.conf.d/10-arch/mkosi.prepare
index aac7b3d..76f67c1 100755
--- a/mkosi.conf.d/10-arch/mkosi.prepare
+++ b/mkosi.conf.d/10-arch/mkosi.prepare
@@ -6,9 +6,11 @@ if [[ "$1" == "build" ]]; then
exit 0
fi
+mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
+
DEPS=""
-while read -r PACKAGE; do
+for PACKAGE in "${PACKAGES[@]}"; do
DEPS="$DEPS $(
pacman --sync --info "$PACKAGE" |
sed '1,/^$/d' | # Only keep result from first repository (delete everything after first blank line).
@@ -23,11 +25,11 @@ while read -r PACKAGE; do
sed 's/ *\(.*\):.*/\1/' | # Drop descriptions (everything after first colon for all lines).
tr '\n' ' ' # Transform newlines to whitespace.
)"
-done < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
+done
echo "$DEPS" |
xargs | # Remove extra whitespace.
tr ' ' '\n' |
- grep --invert-match --regexp systemd --regexp None | # systemd packages will be installed later on.
+ grep --extended-regexp --invert-match --regexp "$(IFS=\| ; echo "${PACKAGES[*]}")" --regexp None | # systemd packages will be installed later on.
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install
diff --git a/mkosi.conf.d/10-centos-fedora/mkosi.prepare b/mkosi.conf.d/10-centos-fedora/mkosi.prepare
index 2a890bc..9aca009 100755
--- a/mkosi.conf.d/10-centos-fedora/mkosi.prepare
+++ b/mkosi.conf.d/10-centos-fedora/mkosi.prepare
@@ -11,9 +11,9 @@ mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
for DEPS in --requires --recommends --suggests; do
# We need --latest-limit=1 to only consider the newest version of the packages.
# --latest-limit=1 is per <name>.<arch> so we have to pass --arch= explicitly to make sure i686 packages
- # are not considerd on x86-64.
- dnf repoquery --arch="$DISTRIBUTION_ARCHITECTURE" --latest-limit=1 --quiet "$DEPS" "${PACKAGES[@]}" |
- grep --invert-match --regexp systemd --regexp udev --regexp /bin/sh --regexp grubby --regexp sdubby --regexp libcurl-minimal |
+ # are not considered on x86-64.
+ dnf repoquery --arch="$DISTRIBUTION_ARCHITECTURE,noarch" --latest-limit=1 --quiet "$DEPS" "${PACKAGES[@]}" |
+ grep --extended-regexp --invert-match --regexp "$(IFS=\| ; echo "${PACKAGES[*]}")" --regexp /bin/sh --regexp grubby --regexp sdubby --regexp libcurl-minimal |
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install
done
diff --git a/mkosi.conf.d/10-debian-ubuntu/mkosi.conf b/mkosi.conf.d/10-debian-ubuntu/mkosi.conf
index d14746f..472064e 100644
--- a/mkosi.conf.d/10-debian-ubuntu/mkosi.conf
+++ b/mkosi.conf.d/10-debian-ubuntu/mkosi.conf
@@ -8,10 +8,6 @@ Distribution=|ubuntu
PackageManagerTrees=mkosi-pinning.pref:/etc/apt/preferences.d/mkosi-pinning.pref
[Content]
-# Debian ships /usr/bin/login from shadow instead of util-linux which doesn't support credentials so we
-# enable autologin the old-fashioned way.
-Autologin=yes
-
VolatilePackages=
libnss-myhostname
libnss-mymachines
@@ -58,6 +54,7 @@ Packages=
knot
libcap-ng-utils
locales
+ login
man-db
multipath-tools
ncat
diff --git a/mkosi.conf.d/10-debian-ubuntu/mkosi.prepare b/mkosi.conf.d/10-debian-ubuntu/mkosi.prepare
index acab113..bf2c5eb 100755
--- a/mkosi.conf.d/10-debian-ubuntu/mkosi.prepare
+++ b/mkosi.conf.d/10-debian-ubuntu/mkosi.prepare
@@ -8,9 +8,23 @@ fi
mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
-apt-cache depends "${PACKAGES[@]}" |
- grep --invert-match --regexp "<" --regexp "|" --regexp systemd | # Remove e.g. <python3:any> and |dbus-broker like results
- grep --extended-regexp "Depends|Suggests|Recommends" |
- sed --quiet 's/.*: //p' | # Get every line with ": " in it and strip it at the same time.
- sort --unique |
- xargs --delimiter '\n' --no-run-if-empty mkosi-install
+PATTERNS=()
+
+# The ?reverse-depends() pattern for some weird reason lists all the packages providing systemd-sysusers
+# instead of just excluding it, so we add another pattern to filter out anything that conflicts with
+# any other systemd packages so we filter out both opensysusers and systemd-sysusers-standalone. We also
+# exclude packages that belong to the systemd source package as we'll install these later. Finally, we
+# exclude virtual packages as trying to install these makes apt fail with an error saying we need to install
+# a specific implementation even if one is already installed.
+COMMON="?not(?virtual), ?not(?reverse-conflicts(?source-package(^systemd$))), ?not(?reverse-breaks(?source-package(^systemd$))), ?not(?source-package(^systemd$))"
+
+for PACKAGE in "${PACKAGES[@]}"; do
+ # Get all the dependencies of the systemd packages including recommended and suggested dependencies.
+ PATTERNS+=(
+ "?and(?reverse-depends(?exact-name($PACKAGE)), $COMMON)"
+ "?and(?reverse-recommends(?exact-name($PACKAGE)), $COMMON)"
+ "?and(?reverse-suggests(?exact-name($PACKAGE)), $COMMON)"
+ )
+done
+
+mkosi-install "${PATTERNS[@]}"
diff --git a/mkosi.conf.d/10-fedora/mkosi.conf.d/rawhide.conf b/mkosi.conf.d/10-fedora/mkosi.conf.d/rawhide.conf
new file mode 100644
index 0000000..f657b3d
--- /dev/null
+++ b/mkosi.conf.d/10-fedora/mkosi.conf.d/rawhide.conf
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+[Match]
+Release=rawhide
+
+[Content]
+Packages=util-linux-script
diff --git a/mkosi.conf.d/10-opensuse/mkosi.prepare b/mkosi.conf.d/10-opensuse/mkosi.prepare
index 6ee0af2..728b502 100755
--- a/mkosi.conf.d/10-opensuse/mkosi.prepare
+++ b/mkosi.conf.d/10-opensuse/mkosi.prepare
@@ -6,18 +6,20 @@ if [[ "$1" == "build" ]]; then
exit 0
fi
+mapfile -t PACKAGES < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
+
DEPS=""
-while read -r PACKAGE; do
+for PACKAGE in "${PACKAGES[@]}"; do
# zypper's output is not machine readable so we make do with sed instead.
DEPS="$DEPS\n$(
zypper info --requires --recommends --suggests "$PACKAGE" |
sed '/Requires/,$!d' | # Remove everything before Requires line
sed --quiet 's/^ //p' # All indented lines have dependencies
)"
-done < <(jq --raw-output .VolatilePackages[] <"$MKOSI_CONFIG")
+done
echo -e "$DEPS" |
- grep --invert-match --regexp systemd --regexp udev --regexp qemu |
+ grep --extended-regexp --invert-match --regexp "$(IFS=\| ; echo "${PACKAGES[*]}")" --regexp qemu |
sort --unique |
xargs --delimiter '\n' --no-run-if-empty mkosi-install
diff --git a/mkosi.conf.d/10-ubuntu/mkosi.conf b/mkosi.conf.d/10-ubuntu/mkosi.conf
index 1ffa3ab..73faafe 100644
--- a/mkosi.conf.d/10-ubuntu/mkosi.conf
+++ b/mkosi.conf.d/10-ubuntu/mkosi.conf
@@ -8,6 +8,9 @@ Release=noble
Repositories=universe
[Content]
+# Ubuntu ships /usr/bin/login from shadow instead of util-linux which doesn't support credentials so we
+# enable autologin the old-fashioned way.
+Autologin=yes
Packages=
linux-image-generic
linux-tools-common
diff --git a/mkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot b/mkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot
index 3ffde85..8d501ec 100755
--- a/mkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot
+++ b/mkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot
@@ -61,22 +61,23 @@ EOF
# Linting the PKGBUILD takes multiple seconds every build so avoid that by nuking all the linting functions.
rm /usr/share/makepkg/lint_pkgbuild/*
-if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
- TS="$(git show --no-patch --format=%ct HEAD)"
-else
- TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
-fi
+TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
sed --in-place "pkg/$PKG_SUBDIR/PKGBUILD" \
--expression "s/^_tag=.*/_tag=$(cat meson.version)/" \
--expression "s/^pkgrel=.*/pkgrel=$(date "+%Y%m%d%H%M%S" --date "@$TS")/"
+# Replace cdrom/dialout/tape groups with optical/uucp/storage. We apply this patch manually because we run
+# with --noprepare.
+patch -Np1 -i pkg/arch/0001-Use-Arch-Linux-device-access-groups.patch
+
# We get around makepkg's root check by setting EUID to something else.
# shellcheck disable=SC2046
env --chdir="pkg/$PKG_SUBDIR" \
EUID=123 \
makepkg \
--noextract \
+ --noprepare \
$( ((WITH_TESTS)) || echo --nocheck) \
--force \
_systemd_UPSTREAM=1 \
diff --git a/mkosi.images/build/mkosi.conf.d/arch/mkosi.conf b/mkosi.images/build/mkosi.conf.d/arch/mkosi.conf
index c071468..91a4d17 100644
--- a/mkosi.images/build/mkosi.conf.d/arch/mkosi.conf
+++ b/mkosi.images/build/mkosi.conf.d/arch/mkosi.conf
@@ -7,7 +7,7 @@ Distribution=arch
Environment=
GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
GIT_BRANCH=main
- GIT_COMMIT=1d577a62688419ee4af01b847e55845cd9780301
+ GIT_COMMIT=ea5f086275aeba40d878507fba8b22308c3fac01
PKG_SUBDIR=arch
Packages=
diff --git a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.build.chroot b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.build.chroot
index 466699c..9cacff6 100755
--- a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.build.chroot
+++ b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.build.chroot
@@ -9,11 +9,7 @@ if [[ ! -f "pkg/$PKG_SUBDIR/systemd.spec" ]]; then
exit 1
fi
-if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
- TS="$(git show --no-patch --format=%ct HEAD)"
-else
- TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
-fi
+TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
if [[ "$(rpm --eval "%{lua:print(rpm.vercmp('$(rpm --version | cut -d ' ' -f3)', '4.19.91'))}")" == "-1" ]]; then
# Fix the %install override so debuginfo packages are generated even when --build-in-place is used.
@@ -57,6 +53,12 @@ if ((WIPE)) && [[ -d "$BUILDDIR/meson-private" ]]; then
MKOSI_MESON_OPTIONS="$MKOSI_MESON_OPTIONS --wipe"
fi
+# Hack to work around https://github.com/rpm-software-management/rpm/issues/3216.
+# TODO: Remove when rpm 4.20 gets into Rawhide.
+mkdir -p "/var/tmp/BUILD/systemd-${VERSION/\~/_}-build"
+mkdir -p "/var/tmp/BUILD/systemd-${VERSION/\~/_}-build/SPECPARTS"
+ln -s /work/src "/var/tmp/BUILD/systemd-${VERSION/\~/_}-build/systemd-$VERSION"
+
IFS=
# TODO: Replace meson_build and meson_install overrides with "--undefine __meson_verbose" once
# https://github.com/mesonbuild/meson/pull/12835 is available.
@@ -70,12 +72,13 @@ CC_LD="$( ((LLVM)) && echo lld)" \
CXX_LD="$( ((LLVM)) && echo lld)" \
rpmbuild \
-bb \
+ --noprep \
--build-in-place \
--with upstream \
$( ((WITH_TESTS)) || echo "--nocheck") \
$( ((WITH_DOCS)) || echo "--without=docs") \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
--define "_rpmdir $OUTPUTDIR" \
${BUILDDIR:+"--define=_vpath_builddir $BUILDDIR"} \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
@@ -100,7 +103,6 @@ CXX_LD="$( ((LLVM)) && echo lld)" \
--define "__script_requires %{nil}" \
--define "_find_debuginfo_opts --unique-debug-src-base \"%{name}\"" \
--define "_find_debuginfo_dwz_opts %{nil}" \
- --define "_fixperms true" \
--undefine _package_note_flags \
--noclean \
"pkg/$PKG_SUBDIR/systemd.spec"
diff --git a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf
index f3afd55..1efca6d 100644
--- a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf
+++ b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.conf
@@ -8,7 +8,7 @@ Distribution=|fedora
Environment=
GIT_URL=https://src.fedoraproject.org/rpms/systemd.git
GIT_BRANCH=rawhide
- GIT_COMMIT=00babccdea1576d96edfdb7ab12958564cc4f1b6
+ GIT_COMMIT=a67221c3f0d0b81b9b5b3230a71d09044342f1a4
PKG_SUBDIR=fedora
Packages=
diff --git a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.prepare b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.prepare
index 6028dc3..4fef26f 100755
--- a/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.prepare
+++ b/mkosi.images/build/mkosi.conf.d/centos-fedora/mkosi.prepare
@@ -17,7 +17,7 @@ mkosi-chroot \
--query \
--buildrequires \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
"pkg/$PKG_SUBDIR/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev --regexp grubby --regexp sdubby |
sort --unique |
@@ -32,10 +32,11 @@ sed '/Source0/d' --in-place "pkg/$PKG_SUBDIR/systemd.spec"
until mkosi-chroot \
rpmbuild \
-br \
+ --noprep \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$PKG_SUBDIR/systemd.spec"
do
diff --git a/mkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot b/mkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot
index 03b3b04..0d33b10 100755
--- a/mkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot
+++ b/mkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot
@@ -18,11 +18,7 @@ rm -rf "$SRCDIR"/debian/patches/*
DEB_HOST_GNU_TYPE="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"
mount --mkdir --bind "$BUILDDIR" "$SRCDIR/obj-$DEB_HOST_GNU_TYPE"
-if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
- TS="$(git show --no-patch --format=%ct HEAD)"
-else
- TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
-fi
+TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
# Add a new changelog entry to update the version. We use a fixed date since a dynamic one causes a full
# rebuild every time.
diff --git a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot
index a1fb83c..0a5b47b 100755
--- a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot
+++ b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot
@@ -9,11 +9,7 @@ if [[ ! -f "pkg/$PKG_SUBDIR/systemd.spec" ]]; then
exit 1
fi
-if [[ -d .git/ ]] && [[ -z "$(git status --porcelain)" ]]; then
- TS="$(git show --no-patch --format=%ct HEAD)"
-else
- TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
-fi
+TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
# The openSUSE filelists hardcode the manpage compression extension. This causes rpmbuild errors since we
# disable manpage compression as the files cannot be found. Fix the issue by removing the compression
@@ -73,11 +69,12 @@ build() {
CXX_LD="$( ((LLVM)) && echo lld)" \
rpmbuild \
-bb \
+ --noprep \
--build-in-place \
--with upstream \
$( ((WITH_TESTS)) || echo "--nocheck") \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
--define "_rpmdir $OUTPUTDIR" \
${BUILDDIR:+"--define=_vpath_builddir $BUILDDIR"} \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
@@ -97,7 +94,6 @@ build() {
--define "__script_requires %{nil}" \
--define "_find_debuginfo_dwz_opts %{nil}" \
--define "_find_debuginfo_opts --unique-debug-src-base \"%{name}\"" \
- --define "_fixperms true" \
--noclean \
"$@" \
"pkg/$PKG_SUBDIR/systemd.spec"
diff --git a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.conf b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.conf
index a941457..0b17435 100644
--- a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.conf
+++ b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.conf
@@ -5,9 +5,9 @@ Distribution=opensuse
[Content]
Environment=
- GIT_URL=https://code.opensuse.org/package/systemd
- GIT_BRANCH=master
- GIT_COMMIT=6812406e52a474568744c267e7bade1496bb26a5
+ GIT_URL=https://src.opensuse.org/pool/systemd
+ GIT_BRANCH=factory
+ GIT_COMMIT=612bc16021b28ab99002fa1069f1ec97124397a25c7a207d013213b5cfb86055
PKG_SUBDIR=opensuse
Packages=
diff --git a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.prepare b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.prepare
index 24f07fd..c4a9580 100755
--- a/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.prepare
+++ b/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.prepare
@@ -20,7 +20,7 @@ mkosi-chroot \
--query \
--buildrequires \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
"pkg/$PKG_SUBDIR/systemd.spec" |
grep --invert-match --regexp systemd --regexp /bin/sh --regexp "rpmlib(" --regexp udev |
sort --unique |
@@ -30,10 +30,11 @@ mkosi-chroot \
until mkosi-chroot \
rpmbuild \
-bd \
+ --noprep \
--build-in-place \
--with upstream \
--define "_topdir /var/tmp" \
- --define "_sourcedir pkg/$PKG_SUBDIR" \
+ --define "_sourcedir $PWD/pkg/$PKG_SUBDIR" \
--define "_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" \
"pkg/$PKG_SUBDIR/systemd.spec"
do
diff --git a/mkosi.images/build/mkosi.sync b/mkosi.images/build/mkosi.sync
index febe893..4cb2b41 100755
--- a/mkosi.images/build/mkosi.sync
+++ b/mkosi.images/build/mkosi.sync
@@ -43,7 +43,7 @@ if [[ ! -e "pkg/$PKG_SUBDIR" ]] || [[ -z "$(ls --almost-all "pkg/$PKG_SUBDIR")"
# --no-cone is needed to check out only one top-level directory
git -C "pkg/$PKG_SUBDIR" sparse-checkout set --no-cone "${GIT_SUBDIR:-}"
fi
-else
+elif ! git -C "pkg/$PKG_SUBDIR" cat-file -e "$GIT_COMMIT^{commit}"; then
git -C "pkg/$PKG_SUBDIR" remote set-url origin "$GIT_URL"
git -C "pkg/$PKG_SUBDIR" fetch origin "$GIT_BRANCH"
fi
diff --git a/mkosi.presets/20-final/mkosi.extra/root/.gdbinit b/mkosi.presets/20-final/mkosi.extra/root/.gdbinit
new file mode 100644
index 0000000..1a2163e
--- /dev/null
+++ b/mkosi.presets/20-final/mkosi.extra/root/.gdbinit
@@ -0,0 +1,3 @@
+set debuginfod enabled off
+set build-id-verbose 0
+set substitute-path ../src /root/src
diff --git a/mkosi.sanitizers/mkosi.postinst b/mkosi.sanitizers/mkosi.postinst
index e0ad422..593a8f9 100755
--- a/mkosi.sanitizers/mkosi.postinst
+++ b/mkosi.sanitizers/mkosi.postinst
@@ -73,12 +73,7 @@ wrap=(
lvm
mdadm
mkfs.btrfs
- mkfs.erofs
- mkfs.ext4
- mkfs.vfat
- mkfs.xfs
mksquashfs
- mkswap
multipath
multipathd
nvme
diff --git a/src/basic/audit-util.c b/src/basic/audit-util.c
index bf96e08..7f86f84 100644
--- a/src/basic/audit-util.c
+++ b/src/basic/audit-util.c
@@ -99,7 +99,7 @@ static int try_audit_request(int fd) {
n = recvmsg_safe(fd, &mh, 0);
if (n < 0)
- return -errno;
+ return n;
if (n != NLMSG_LENGTH(sizeof(struct nlmsgerr)))
return -EIO;
diff --git a/src/basic/missing_loop.h b/src/basic/missing_loop.h
index b88501d..f83a14c 100644
--- a/src/basic/missing_loop.h
+++ b/src/basic/missing_loop.h
@@ -29,3 +29,7 @@ assert_cc(LOOP_SET_DIRECT_IO == 0x4C08);
#ifndef LOOP_SET_STATUS_SETTABLE_FLAGS
# define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN)
#endif
+
+#ifndef LOOP_SET_BLOCK_SIZE
+# define LOOP_SET_BLOCK_SIZE 0x4C09
+#endif
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index c9d968d..de5a146 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -2066,9 +2066,10 @@ int posix_spawn_wrapper(
_unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
#if HAVE_PIDFD_SPAWN
+ static bool setcgroup_supported = true;
_cleanup_close_ int cgroup_fd = -EBADF;
- if (cgroup) {
+ if (cgroup && setcgroup_supported) {
_cleanup_free_ char *resolved_cgroup = NULL;
r = cg_get_path_and_check(
@@ -2102,6 +2103,19 @@ int posix_spawn_wrapper(
_cleanup_close_ int pidfd = -EBADF;
r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
+ if (r == E2BIG && FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) {
+ /* Some kernels (e.g., 5.4) support clone3 but they do not support CLONE_INTO_CGROUP.
+ * Retry pidfd_spawn() after removing the flag. */
+ flags &= ~POSIX_SPAWN_SETCGROUP;
+ r = posix_spawnattr_setflags(&attr, flags);
+ if (r != 0)
+ return -r;
+ r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
+ /* if pidfd_spawn was successful after removing SPAWN_CGROUP,
+ * mark setcgroup_supported as false so that we do not retry every time */
+ if (r == 0)
+ setcgroup_supported = false;
+ }
if (r == 0) {
r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
if (r < 0)
@@ -2120,10 +2134,12 @@ int posix_spawn_wrapper(
/* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but need to change the
* flags to remove the cgroup one, which is what redirects to clone3() */
- flags &= ~POSIX_SPAWN_SETCGROUP;
- r = posix_spawnattr_setflags(&attr, flags);
- if (r != 0)
- return -r;
+ if (FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) {
+ flags &= ~POSIX_SPAWN_SETCGROUP;
+ r = posix_spawnattr_setflags(&attr, flags);
+ if (r != 0)
+ return -r;
+ }
#endif
pid_t pid;
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 0970350..2cb3a08 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -896,6 +896,13 @@ int running_in_chroot(void) {
* mount /proc, so all other programs can assume that if /proc is *not* available, we're in some
* chroot. */
+ r = getenv_bool("SYSTEMD_IN_CHROOT");
+ if (r >= 0)
+ return r > 0;
+ if (r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_IN_CHROOT, ignoring: %m");
+
+ /* Deprecated but kept for backwards compatibility. */
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
diff --git a/src/boot/bootctl-install.c b/src/boot/bootctl-install.c
index dc46d30..fd26b43 100644
--- a/src/boot/bootctl-install.c
+++ b/src/boot/bootctl-install.c
@@ -45,7 +45,7 @@ static int load_etc_machine_info(void) {
_cleanup_free_ char *p = NULL, *s = NULL, *layout = NULL;
int r;
- p = path_join(arg_root, "etc/machine-info");
+ p = path_join(arg_root, "/etc/machine-info");
if (!p)
return log_oom();
diff --git a/src/core/namespace.c b/src/core/namespace.c
index a9b98bc..b92bb01 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -1565,12 +1565,24 @@ static int apply_one_mount(
if (r < 0)
return log_debug_errno(r, "Failed to extract extension name from %s: %m", mount_entry_source(m));
- r = load_extension_release_pairs(mount_entry_source(m), IMAGE_SYSEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release);
+ r = load_extension_release_pairs(
+ mount_entry_source(m),
+ IMAGE_SYSEXT,
+ extension_name,
+ /* relax_extension_release_check= */ false,
+ &extension_release);
if (r == -ENOENT) {
- r = load_extension_release_pairs(mount_entry_source(m), IMAGE_CONFEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release);
+ r = load_extension_release_pairs(
+ mount_entry_source(m),
+ IMAGE_CONFEXT,
+ extension_name,
+ /* relax_extension_release_check= */ false,
+ &extension_release);
if (r >= 0)
class = IMAGE_CONFEXT;
}
+ if (r == -ENOENT && m->ignore)
+ return 0;
if (r < 0)
return log_debug_errno(r, "Failed to acquire 'extension-release' data of extension tree %s: %m", mount_entry_source(m));
@@ -1585,12 +1597,6 @@ static int apply_one_mount(
if (isempty(host_os_release_id))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "'ID' field not found or empty in 'os-release' data of OS tree '%s'.", empty_to_root(root_directory));
- r = load_extension_release_pairs(mount_entry_source(m), class, extension_name, /* relax_extension_release_check= */ false, &extension_release);
- if (r == -ENOENT && m->ignore)
- return 0;
- if (r < 0)
- return log_debug_errno(r, "Failed to parse directory %s extension-release metadata: %m", extension_name);
-
r = extension_release_validate(
extension_name,
host_os_release_id,
diff --git a/src/home/homectl.c b/src/home/homectl.c
index d9321a2..5c454f7 100644
--- a/src/home/homectl.c
+++ b/src/home/homectl.c
@@ -1243,6 +1243,8 @@ static int acquire_new_password(
if (r < 0)
return log_error_errno(r, "Failed to acquire password: %m");
+ assert(!strv_isempty(first));
+
question = mfree(question);
if (asprintf(&question, "Please enter new password for user %s (repeat):", user_name) < 0)
return log_oom();
diff --git a/src/libsystemd-network/sd-lldp-tx.c b/src/libsystemd-network/sd-lldp-tx.c
index 2b822af..01c476e 100644
--- a/src/libsystemd-network/sd-lldp-tx.c
+++ b/src/libsystemd-network/sd-lldp-tx.c
@@ -590,6 +590,7 @@ int sd_lldp_tx_stop(sd_lldp_tx *lldp_tx) {
return 1;
}
+
int sd_lldp_tx_start(sd_lldp_tx *lldp_tx) {
usec_t delay;
int r;
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index ecd030e..228b166 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -127,6 +127,7 @@ static void test_message_handler(void) {
.s_addr = htobe32(INADDR_LOOPBACK + 42),
};
static uint8_t static_lease_client_id[7] = {0x01, 'A', 'B', 'C', 'D', 'E', 'G' };
+ int r;
log_debug("/* %s */", __func__);
@@ -137,7 +138,10 @@ static void test_message_handler(void) {
assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
assert_se(sd_dhcp_server_start(server) >= 0);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_OFFER);
+ r = dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL);
+ if (r == -ENETDOWN)
+ return (void) log_tests_skipped("Network is not available");
+ assert_se(r == DHCP_OFFER);
test.end = 0;
/* TODO, shouldn't this fail? */
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
index cf19c48..c58cfc0 100644
--- a/src/libsystemd/sd-netlink/test-netlink.c
+++ b/src/libsystemd/sd-netlink/test-netlink.c
@@ -92,18 +92,24 @@ TEST(message_address) {
struct in_addr in_data;
struct ifa_cacheinfo cache;
const char *label;
+ int r;
assert_se(sd_netlink_open(&rtnl) >= 0);
ifindex = (int) if_nametoindex("lo");
assert_se(sd_rtnl_message_new_addr(rtnl, &message, RTM_GETADDR, ifindex, AF_INET) >= 0);
assert_se(sd_netlink_message_set_request_dump(message, true) >= 0);
- assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1);
- assert_se(sd_netlink_message_read_in_addr(reply, IFA_LOCAL, &in_data) >= 0);
- assert_se(sd_netlink_message_read_in_addr(reply, IFA_ADDRESS, &in_data) >= 0);
- assert_se(sd_netlink_message_read_string(reply, IFA_LABEL, &label) >= 0);
- assert_se(sd_netlink_message_read_cache_info(reply, IFA_CACHEINFO, &cache) == 0);
+ r = sd_netlink_call(rtnl, message, 0, &reply);
+ assert_se(r >= 0);
+
+ /* If the loopback device is down we won't get any results. */
+ if (r > 0) {
+ assert_se(sd_netlink_message_read_in_addr(reply, IFA_LOCAL, &in_data) >= 0);
+ assert_se(sd_netlink_message_read_in_addr(reply, IFA_ADDRESS, &in_data) >= 0);
+ assert_se(sd_netlink_message_read_string(reply, IFA_LABEL, &label) >= 0);
+ assert_se(sd_netlink_message_read_cache_info(reply, IFA_CACHEINFO, &cache) == 0);
+ }
}
TEST(message_route) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index ceff268..b0c4896 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -4264,6 +4264,7 @@ int manager_start_scope(
const char *slice,
const char *description,
const char * const *requires,
+ const char * const *wants,
const char * const *extra_after,
const char *requires_mounts_for,
sd_bus_message *more_properties,
@@ -4313,6 +4314,16 @@ int manager_start_scope(
return r;
}
+ STRV_FOREACH(i, wants) {
+ r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i);
+ if (r < 0)
+ return r;
+ }
+
STRV_FOREACH(i, extra_after) {
r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i);
if (r < 0)
@@ -4375,6 +4386,7 @@ int manager_start_scope(
slice,
description,
requires,
+ wants,
extra_after,
requires_mounts_for,
more_properties,
diff --git a/src/login/logind-dbus.h b/src/login/logind-dbus.h
index 8459d04..d965ba9 100644
--- a/src/login/logind-dbus.h
+++ b/src/login/logind-dbus.h
@@ -32,6 +32,7 @@ int manager_start_scope(
const char *slice,
const char *description,
const char * const *requires,
+ const char * const *wants,
const char * const *extra_after,
const char *requires_mounts_for,
sd_bus_message *more_properties,
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 4713aa0..4758cb9 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -746,15 +746,15 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
s->user->slice,
description,
/* These should have been pulled in explicitly in user_start(). Just to be sure. */
- STRV_MAKE_CONST(s->user->runtime_dir_unit,
- SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service_manager_unit : NULL),
+ /* requires = */ STRV_MAKE_CONST(s->user->runtime_dir_unit),
+ /* wants = */ STRV_MAKE_CONST(SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service_manager_unit : NULL),
/* We usually want to order session scopes after systemd-user-sessions.service
* since the unit is used as login session barrier for unprivileged users. However
* the barrier doesn't apply for root as sysadmin should always be able to log in
* (and without waiting for any timeout to expire) in case something goes wrong
* during the boot process. */
- STRV_MAKE_CONST("systemd-logind.service",
- SESSION_CLASS_IS_EARLY(s->class) ? NULL : "systemd-user-sessions.service"),
+ /* extra_after = */ STRV_MAKE_CONST("systemd-logind.service",
+ SESSION_CLASS_IS_EARLY(s->class) ? NULL : "systemd-user-sessions.service"),
user_record_home_directory(s->user->user_record),
properties,
error,
diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c
index f48781e..cc22fbf 100644
--- a/src/network/networkd-lldp-tx.c
+++ b/src/network/networkd-lldp-tx.c
@@ -86,6 +86,36 @@ int link_lldp_tx_configure(Link *link) {
return 0;
}
+int link_lldp_tx_update_capabilities(Link *link) {
+ int r;
+
+ assert(link);
+
+ if (!link->lldp_tx)
+ return 0; /* disabled, or not configured yet. */
+
+ r = sd_lldp_tx_set_capabilities(link->lldp_tx,
+ SD_LLDP_SYSTEM_CAPABILITIES_STATION |
+ SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE |
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
+ (link_get_ip_forwarding(link, AF_INET) > 0 || link_get_ip_forwarding(link, AF_INET6) > 0) ?
+ SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : SD_LLDP_SYSTEM_CAPABILITIES_STATION);
+ if (r < 0)
+ return r;
+
+ if (sd_lldp_tx_is_running(link->lldp_tx)) {
+ r = sd_lldp_tx_stop(link->lldp_tx);
+ if (r < 0)
+ return r;
+
+ r = sd_lldp_tx_start(link->lldp_tx);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
static const char * const lldp_multicast_mode_table[_SD_LLDP_MULTICAST_MODE_MAX] = {
[SD_LLDP_MULTICAST_MODE_NEAREST_BRIDGE] = "nearest-bridge",
[SD_LLDP_MULTICAST_MODE_NON_TPMR_BRIDGE] = "non-tpmr-bridge",
diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h
index 73757f1..346eb5c 100644
--- a/src/network/networkd-lldp-tx.h
+++ b/src/network/networkd-lldp-tx.h
@@ -6,5 +6,6 @@
typedef struct Link Link;
int link_lldp_tx_configure(Link *link);
+int link_lldp_tx_update_capabilities(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_lldp_multicast_mode);
diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c
index 68c23e0..a454322 100644
--- a/src/network/networkd-sysctl.c
+++ b/src/network/networkd-sysctl.c
@@ -7,7 +7,9 @@
#include "af-list.h"
#include "missing_network.h"
#include "networkd-link.h"
+#include "networkd-lldp-tx.h"
#include "networkd-manager.h"
+#include "networkd-ndisc.h"
#include "networkd-network.h"
#include "networkd-sysctl.h"
#include "socket-util.h"
@@ -130,7 +132,7 @@ int link_get_ip_forwarding(Link *link, int family) {
return link->manager->ip_forwarding[family == AF_INET6];
}
-static int link_set_ip_forwarding(Link *link, int family) {
+static int link_set_ip_forwarding_impl(Link *link, int family) {
int r, t;
assert(link);
@@ -151,6 +153,65 @@ static int link_set_ip_forwarding(Link *link, int family) {
return 0;
}
+static int link_reapply_ip_forwarding(Link *link, int family) {
+ int r, ret = 0;
+
+ assert(link);
+ assert(IN_SET(family, AF_INET, AF_INET6));
+
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ return 0;
+
+ (void) link_set_ip_forwarding_impl(link, family);
+
+ r = link_lldp_tx_update_capabilities(link);
+ if (r < 0)
+ RET_GATHER(ret, log_link_warning_errno(link, r, "Could not update LLDP capabilities, ignoring: %m"));
+
+ if (family == AF_INET6 && !link_ndisc_enabled(link)) {
+ r = ndisc_stop(link);
+ if (r < 0)
+ RET_GATHER(ret, log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery, ignoring: %m"));
+
+ ndisc_flush(link);
+ }
+
+ return ret;
+}
+
+static int link_set_ip_forwarding(Link *link, int family) {
+ int r;
+
+ assert(link);
+ assert(link->manager);
+ assert(link->network);
+ assert(IN_SET(family, AF_INET, AF_INET6));
+
+ if (!link_is_configured_for_family(link, family))
+ return 0;
+
+ /* When IPMasquerade= is enabled and the global setting is unset, enable _global_ IP forwarding, and
+ * re-apply per-link setting for all links. */
+ if (FLAGS_SET(link->network->ip_masquerade, family == AF_INET ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_IPV6) &&
+ link->manager->ip_forwarding[family == AF_INET6] < 0) {
+
+ link->manager->ip_forwarding[family == AF_INET6] = true;
+ manager_set_ip_forwarding(link->manager, family);
+
+ Link *other;
+ HASHMAP_FOREACH(other, link->manager->links_by_index) {
+ r = link_reapply_ip_forwarding(other, family);
+ if (r < 0)
+ link_enter_failed(other);
+ }
+
+ return 0;
+ }
+
+ /* Otherwise, apply per-link setting for _this_ link. */
+ return link_set_ip_forwarding_impl(link, family);
+}
+
static int link_set_ipv4_rp_filter(Link *link) {
assert(link);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 7d87116..c6ce36b 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2207,7 +2207,7 @@ static int copy_devnodes(const char *dest) {
/* Explicitly warn the user when /dev is already populated. */
if (errno == EEXIST)
log_notice("%s/dev/ is pre-mounted and pre-populated. If a pre-mounted /dev/ is provided it needs to be an unpopulated file system.", dest);
- if (errno != EPERM)
+ if (!ERRNO_IS_PRIVILEGE(errno) || arg_uid_shift != 0)
return log_error_errno(errno, "mknod(%s) failed: %m", to);
/* Some systems abusively restrict mknod but allow bind mounts. */
@@ -2217,12 +2217,12 @@ static int copy_devnodes(const char *dest) {
r = mount_nofollow_verbose(LOG_DEBUG, from, to, NULL, MS_BIND, NULL);
if (r < 0)
return log_error_errno(r, "Both mknod and bind mount (%s) failed: %m", to);
+ } else {
+ r = userns_lchown(to, 0, 0);
+ if (r < 0)
+ return log_error_errno(r, "chown() of device node %s failed: %m", to);
}
- r = userns_lchown(to, 0, 0);
- if (r < 0)
- return log_error_errno(r, "chown() of device node %s failed: %m", to);
-
dn = path_join("/dev", S_ISCHR(st.st_mode) ? "char" : "block");
if (!dn)
return log_oom();
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 8a5ce7e..3b7c165 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -4925,14 +4925,14 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
sfd, ".",
pfd, fn,
UID_INVALID, GID_INVALID,
- COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE,
+ COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE|COPY_RESTORE_DIRECTORY_TIMESTAMPS,
denylist, subvolumes_by_source_inode);
} else
r = copy_tree_at(
sfd, ".",
tfd, ".",
UID_INVALID, GID_INVALID,
- COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE,
+ COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE|COPY_RESTORE_DIRECTORY_TIMESTAMPS,
denylist, subvolumes_by_source_inode);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s%s' to '%s%s': %m",
@@ -8155,6 +8155,10 @@ static int run(int argc, char *argv[]) {
if (!context)
return log_oom();
+ r = context_read_seed(context, arg_root);
+ if (r < 0)
+ return r;
+
r = context_copy_from(context);
if (r < 0)
return r;
@@ -8232,10 +8236,6 @@ static int run(int argc, char *argv[]) {
return r;
}
- r = context_read_seed(context, arg_root);
- if (r < 0)
- return r;
-
/* Make sure each partition has a unique UUID and unique label */
r = context_acquire_partition_uuids_and_labels(context);
if (r < 0)
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 1b649af..a43571a 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -111,6 +111,7 @@ static inline uint8_t* DNS_PACKET_DATA(const DnsPacket *p) {
#define DNS_PACKET_AD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 5) & 1)
#define DNS_PACKET_CD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 4) & 1)
+#define DNS_PACKET_FLAG_AD (UINT16_C(1) << 5)
#define DNS_PACKET_FLAG_TC (UINT16_C(1) << 9)
static inline uint16_t DNS_PACKET_RCODE(DnsPacket *p) {
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index 23d4db9..c604a51 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -685,7 +685,8 @@ static int dns_stub_send_failure(
static int dns_stub_patch_bypass_reply_packet(
DnsPacket **ret, /* Where to place the patched packet */
DnsPacket *original, /* The packet to patch */
- DnsPacket *request) { /* The packet the patched packet shall look like a reply to */
+ DnsPacket *request, /* The packet the patched packet shall look like a reply to */
+ bool authenticated) {
_cleanup_(dns_packet_unrefp) DnsPacket *c = NULL;
int r;
@@ -725,6 +726,10 @@ static int dns_stub_patch_bypass_reply_packet(
DNS_PACKET_HEADER(c)->flags = htobe16(be16toh(DNS_PACKET_HEADER(c)->flags) | DNS_PACKET_FLAG_TC);
}
+ /* Ensure we don't pass along an untrusted ad flag for bypass packets */
+ if (!authenticated)
+ DNS_PACKET_HEADER(c)->flags = htobe16(be16toh(DNS_PACKET_HEADER(c)->flags) & ~DNS_PACKET_FLAG_AD);
+
*ret = TAKE_PTR(c);
return 0;
}
@@ -745,7 +750,8 @@ static void dns_stub_query_complete(DnsQuery *query) {
q->answer_full_packet->protocol == DNS_PROTOCOL_DNS) {
_cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
- r = dns_stub_patch_bypass_reply_packet(&reply, q->answer_full_packet, q->request_packet);
+ r = dns_stub_patch_bypass_reply_packet(&reply, q->answer_full_packet, q->request_packet,
+ FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED));
if (r < 0)
log_debug_errno(r, "Failed to patch bypass reply packet: %m");
else
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index bf79dc2..042c0ad 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -167,7 +167,16 @@ static int ask_password_keyring(const AskPasswordRequest *req, AskPasswordFlags
if (r < 0)
return r;
- return retrieve_key(serial, ret);
+ _cleanup_strv_free_erase_ char **l = NULL;
+ r = retrieve_key(serial, &l);
+ if (r < 0)
+ return r;
+
+ if (strv_isempty(l))
+ return log_debug_errno(SYNTHETIC_ERRNO(ENOKEY), "Found an empty password from keyring.");
+
+ *ret = TAKE_PTR(l);
+ return 0;
}
static int backspace_chars(int ttyfd, size_t p) {
@@ -322,8 +331,8 @@ int ask_password_plymouth(
return -ENOENT;
} else if (IN_SET(buffer[0], 2, 9)) {
+ _cleanup_strv_free_erase_ char **l = NULL;
uint32_t size;
- char **l;
/* One or more answers */
if (p < 5)
@@ -341,15 +350,16 @@ int ask_password_plymouth(
if (!l)
return -ENOMEM;
- *ret = l;
- break;
+ if (strv_isempty(l))
+ return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), "Received an empty password.");
+
+ *ret = TAKE_PTR(l);
+ return 0;
} else
/* Unknown packet */
return -EIO;
}
-
- return 0;
}
#define NO_ECHO "(no echo) "
@@ -949,8 +959,8 @@ finish:
static int ask_password_credential(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret) {
_cleanup_(erase_and_freep) char *buffer = NULL;
+ _cleanup_strv_free_erase_ char **l = NULL;
size_t size;
- char **l;
int r;
assert(req);
@@ -965,7 +975,10 @@ static int ask_password_credential(const AskPasswordRequest *req, AskPasswordFla
if (!l)
return -ENOMEM;
- *ret = l;
+ if (strv_isempty(l))
+ return log_debug_errno(SYNTHETIC_ERRNO(ENOKEY), "Found an empty password in credential.");
+
+ *ret = TAKE_PTR(l);
return 0;
}
diff --git a/src/shared/copy.c b/src/shared/copy.c
index 8389774..9b90afa 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -982,6 +982,7 @@ static int fd_copy_directory(
_cleanup_close_ int fdf = -EBADF, fdt = -EBADF;
_cleanup_closedir_ DIR *d = NULL;
+ struct stat dt_st;
bool exists;
int r;
@@ -1026,6 +1027,9 @@ static int fd_copy_directory(
if (fdt < 0)
return fdt;
+ if (exists && FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS) && fstat(fdt, &dt_st) < 0)
+ return -errno;
+
r = 0;
if (PTR_TO_INT(hashmap_get(denylist, st)) == DENY_CONTENTS) {
@@ -1125,7 +1129,9 @@ finish:
(void) copy_xattr(dirfd(d), NULL, fdt, NULL, copy_flags);
(void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
- }
+ } else if (FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS))
+ /* If the directory already exists, make sure the timestamps stay the same as before. */
+ (void) futimens(fdt, (struct timespec[]) { dt_st.st_atim, dt_st.st_mtim });
if (copy_flags & COPY_FSYNC_FULL) {
if (fsync(fdt) < 0)
diff --git a/src/shared/copy.h b/src/shared/copy.h
index b8fb28a..db95738 100644
--- a/src/shared/copy.h
+++ b/src/shared/copy.h
@@ -12,25 +12,26 @@
#include "set.h"
typedef enum CopyFlags {
- COPY_REFLINK = 1 << 0, /* Try to reflink */
- COPY_MERGE = 1 << 1, /* Merge existing trees with our new one to copy */
- COPY_REPLACE = 1 << 2, /* Replace an existing file if there's one */
- COPY_SAME_MOUNT = 1 << 3, /* Don't descend recursively into other file systems, across mount point boundaries */
- COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
- COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
- COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
- COPY_SIGTERM = 1 << 7, /* ditto, but for SIGTERM */
- COPY_MAC_CREATE = 1 << 8, /* Create files with the correct MAC label (currently SELinux only) */
- COPY_HARDLINKS = 1 << 9, /* Try to reproduce hard links */
- COPY_FSYNC = 1 << 10, /* fsync() after we are done */
- COPY_FSYNC_FULL = 1 << 11, /* fsync_full() after we are done */
- COPY_SYNCFS = 1 << 12, /* syncfs() the *top-level* dir after we are done */
- COPY_ALL_XATTRS = 1 << 13, /* Preserve all xattrs when copying, not just those in the user namespace */
- COPY_HOLES = 1 << 14, /* Copy holes */
- COPY_GRACEFUL_WARN = 1 << 15, /* Skip copying file types that aren't supported by the target filesystem */
- COPY_TRUNCATE = 1 << 16, /* Truncate to current file offset after copying */
- COPY_LOCK_BSD = 1 << 17, /* Return a BSD exclusively locked file descriptor referring to the copied image/directory. */
- COPY_VERIFY_LINKED = 1 << 18, /* Check the source file is still linked after copying. */
+ COPY_REFLINK = 1 << 0, /* Try to reflink */
+ COPY_MERGE = 1 << 1, /* Merge existing trees with our new one to copy */
+ COPY_REPLACE = 1 << 2, /* Replace an existing file if there's one */
+ COPY_SAME_MOUNT = 1 << 3, /* Don't descend recursively into other file systems, across mount point boundaries */
+ COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
+ COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
+ COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
+ COPY_SIGTERM = 1 << 7, /* ditto, but for SIGTERM */
+ COPY_MAC_CREATE = 1 << 8, /* Create files with the correct MAC label (currently SELinux only) */
+ COPY_HARDLINKS = 1 << 9, /* Try to reproduce hard links */
+ COPY_FSYNC = 1 << 10, /* fsync() after we are done */
+ COPY_FSYNC_FULL = 1 << 11, /* fsync_full() after we are done */
+ COPY_SYNCFS = 1 << 12, /* syncfs() the *top-level* dir after we are done */
+ COPY_ALL_XATTRS = 1 << 13, /* Preserve all xattrs when copying, not just those in the user namespace */
+ COPY_HOLES = 1 << 14, /* Copy holes */
+ COPY_GRACEFUL_WARN = 1 << 15, /* Skip copying file types that aren't supported by the target filesystem */
+ COPY_TRUNCATE = 1 << 16, /* Truncate to current file offset after copying */
+ COPY_LOCK_BSD = 1 << 17, /* Return a BSD exclusively locked file descriptor referring to the copied image/directory. */
+ COPY_VERIFY_LINKED = 1 << 18, /* Check the source file is still linked after copying. */
+ COPY_RESTORE_DIRECTORY_TIMESTAMPS = 1 << 19, /* Make sure existing directory timestamps don't change during copying. */
} CopyFlags;
typedef enum DenyType {
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index a9e211f..6a39010 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -3077,6 +3077,7 @@ int dissected_image_decrypt_interactively(
if (r < 0)
return log_error_errno(r, "Failed to query for passphrase: %m");
+ assert(!strv_isempty(z));
passphrase = z[0];
}
}
diff --git a/src/shared/tests.c b/src/shared/tests.c
index 9169513..a919212 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -29,6 +29,7 @@
#include "strv.h"
#include "tests.h"
#include "tmpfile-util.h"
+#include "uid-range.h"
char* setup_fake_runtime_dir(void) {
char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
@@ -166,6 +167,24 @@ bool have_namespaces(void) {
assert_not_reached();
}
+bool userns_has_single_user(void) {
+ _cleanup_(uid_range_freep) UIDRange *uidrange = NULL, *gidrange = NULL;
+
+ /* Check if we're in a user namespace with only a single user mapped in. We special case this
+ * scenario in a few tests because it's the only kind of namespace that can be created unprivileged
+ * and as such happens more often than not, so we make sure to deal with it so that all tests pass
+ * in such environments. */
+
+ if (uid_range_load_userns(NULL, UID_RANGE_USERNS_INSIDE, &uidrange) < 0)
+ return false;
+
+ if (uid_range_load_userns(NULL, GID_RANGE_USERNS_INSIDE, &gidrange) < 0)
+ return false;
+
+ return uidrange->n_entries == 1 && uidrange->entries[0].nr == 1 &&
+ gidrange->n_entries == 1 && gidrange->entries[0].nr == 1;
+}
+
bool can_memlock(void) {
/* Let's see if we can mlock() a larger blob of memory. BPF programs are charged against
* RLIMIT_MEMLOCK, hence let's first make sure we can lock memory at all, and skip the test if we
diff --git a/src/shared/tests.h b/src/shared/tests.h
index 21f00db..f904c0d 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -76,6 +76,7 @@ void test_setup_logging(int level);
int write_tmpfile(char *pattern, const char *contents);
bool have_namespaces(void);
+bool userns_has_single_user(void);
/* We use the small but non-trivial limit here */
#define CAN_MEMLOCK_SIZE (512 * 1024U)
@@ -217,6 +218,39 @@ static inline int run_test_table(void) {
} \
})
+/* For funtions that return a boolean on success and a negative errno on failure. */
+#define ASSERT_OK_POSITIVE(expr) \
+ ({ \
+ typeof(expr) _result = (expr); \
+ if (_result < 0) { \
+ log_error_errno(_result, "%s:%i: Assertion failed: expected \"%s\" to succeed but got the following error: %m", \
+ PROJECT_FILE, __LINE__, #expr); \
+ abort(); \
+ } \
+ if (_result == 0) { \
+ log_error("%s:%i: Assertion failed: expected \"%s\" to be positive, but it is zero.", \
+ PROJECT_FILE, __LINE__, #expr); \
+ abort(); \
+ } \
+ })
+
+#define ASSERT_OK_ZERO(expr) \
+ ({ \
+ typeof(expr) _result = (expr); \
+ if (_result < 0) { \
+ log_error_errno(_result, "%s:%i: Assertion failed: expected \"%s\" to succeed but got the following error: %m", \
+ PROJECT_FILE, __LINE__, #expr); \
+ abort(); \
+ } \
+ if (_result != 0) { \
+ char _sexpr[DECIMAL_STR_MAX(typeof(expr))]; \
+ xsprintf(_sexpr, DECIMAL_STR_FMT(_result), _result); \
+ log_error("%s:%i: Assertion failed: expected \"%s\" to be zero, but it is %s.", \
+ PROJECT_FILE, __LINE__, #expr, _sexpr); \
+ abort(); \
+ } \
+ })
+
#define ASSERT_OK_ERRNO(expr) \
({ \
typeof(expr) _result = (expr); \
diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
index 0cc9afc..daab75e 100644
--- a/src/test/test-acl-util.c
+++ b/src/test/test-acl-util.c
@@ -41,7 +41,7 @@ TEST_RET(add_acls_for_user) {
cmd = strjoina("getfacl -p ", fn);
assert_se(system(cmd) == 0);
- if (getuid() == 0) {
+ if (getuid() == 0 && !userns_has_single_user()) {
const char *nobody = NOBODY_USER_NAME;
r = get_user_creds(&nobody, &uid, NULL, NULL, NULL, 0);
if (r < 0)
diff --git a/src/test/test-capability.c b/src/test/test-capability.c
index 34f3a91..51bd806 100644
--- a/src/test/test-capability.c
+++ b/src/test/test-capability.c
@@ -318,10 +318,13 @@ int main(int argc, char *argv[]) {
show_capabilities();
- test_drop_privileges();
+ if (!userns_has_single_user())
+ test_drop_privileges();
+
test_update_inherited_set();
- fork_test(test_have_effective_cap);
+ if (!userns_has_single_user())
+ fork_test(test_have_effective_cap);
if (run_ambient)
fork_test(test_apply_ambient_caps);
diff --git a/src/test/test-chase.c b/src/test/test-chase.c
index 13ee702..c7ca3fd 100644
--- a/src/test/test-chase.c
+++ b/src/test/test-chase.c
@@ -183,7 +183,7 @@ TEST(chase) {
/* Paths underneath the "root" with different UIDs while using CHASE_SAFE */
- if (geteuid() == 0) {
+ if (geteuid() == 0 && !userns_has_single_user()) {
p = strjoina(temp, "/user");
ASSERT_OK(mkdir(p, 0755));
ASSERT_OK(chown(p, UID_NOBODY, GID_NOBODY));
@@ -313,7 +313,7 @@ TEST(chase) {
r = chase(p, NULL, 0, &result, NULL);
assert_se(r == -ENOENT);
- if (geteuid() == 0) {
+ if (geteuid() == 0 && !userns_has_single_user()) {
p = strjoina(temp, "/priv1");
ASSERT_OK(mkdir(p, 0755));
diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c
index 5d83f59..7558de7 100644
--- a/src/test/test-chown-rec.c
+++ b/src/test/test-chown-rec.c
@@ -153,8 +153,8 @@ TEST(chown_recursive) {
}
static int intro(void) {
- if (geteuid() != 0)
- return log_tests_skipped("not running as root");
+ if (geteuid() != 0 || userns_has_single_user())
+ return log_tests_skipped("not running as root or in userns with single user");
return EXIT_SUCCESS;
}
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index be83690..76b2af9 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -1003,6 +1003,13 @@ TEST(condition_test_group) {
condition_free(condition);
free(gid);
+ /* In an unprivileged user namespace with the current user mapped to root, all the auxiliary groups
+ * of the user will be mapped to the nobody group, which means the user in the user namespace is in
+ * both the root and the nobody group, meaning the next test can't work, so let's skip it in that
+ * case. */
+ if (in_group(NOBODY_GROUP_NAME) && in_group("root"))
+ return (void) log_tests_skipped("user is in both root and nobody group");
+
groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root");
condition = condition_new(CONDITION_GROUP, groupname, false, false);
assert_se(condition);
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index f2fa51f..09fd995 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -368,8 +368,8 @@ TEST(chmod_and_chown) {
struct stat st;
const char *p;
- if (geteuid() != 0)
- return;
+ if (geteuid() != 0 || userns_has_single_user())
+ return (void) log_tests_skipped("not running as root or in userns with single user");
BLOCK_WITH_UMASK(0000);
diff --git a/src/test/test-macro.c b/src/test/test-macro.c
index 3d5b0cf..b56f5b8 100644
--- a/src/test/test-macro.c
+++ b/src/test/test-macro.c
@@ -1117,6 +1117,18 @@ TEST(ASSERT) {
ASSERT_SIGNAL(ASSERT_OK(-1), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK(-ENOANO), SIGABRT);
+ ASSERT_OK_POSITIVE(1);
+ ASSERT_OK_POSITIVE(255);
+ ASSERT_SIGNAL(ASSERT_OK_POSITIVE(0), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_POSITIVE(-1), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_POSITIVE(-ENOANO), SIGABRT);
+
+ ASSERT_OK_ZERO(0);
+ ASSERT_SIGNAL(ASSERT_OK_ZERO(1), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_ZERO(255), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_ZERO(-1), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_OK_ZERO(-ENOANO), SIGABRT);
+
ASSERT_OK_ERRNO(0 >= 0);
ASSERT_OK_ERRNO(255 >= 0);
ASSERT_OK_ERRNO(printf("Hello world\n"));
diff --git a/src/test/test-rm-rf.c b/src/test/test-rm-rf.c
index 4c69bd2..e4a4263 100644
--- a/src/test/test-rm-rf.c
+++ b/src/test/test-rm-rf.c
@@ -89,6 +89,9 @@ static void test_rm_rf_chmod_inner(void) {
TEST(rm_rf_chmod) {
int r;
+ if (getuid() == 0 && userns_has_single_user())
+ return (void) log_tests_skipped("running as root or in userns with single user");
+
if (getuid() == 0) {
/* This test only works unpriv (as only then the access mask for the owning user matters),
* hence drop privs here */
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index e34aa10..967ba9d 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -170,7 +170,7 @@ TEST(getpeercred_getpeergroups) {
struct ucred ucred;
int pair[2] = EBADF_PAIR;
- if (geteuid() == 0) {
+ if (geteuid() == 0 && !userns_has_single_user()) {
test_uid = 1;
test_gid = 2;
test_gids = (gid_t*) gids;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 31b284b..4e62b84 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -265,9 +265,7 @@ static int process_one_password_file(const char *filename) {
return log_error_errno(r, "Failed to query password: %m");
}
- if (strv_isempty(passwords))
- return -ECANCELED;
-
+ assert(!strv_isempty(passwords));
r = send_passwords(socket_name, passwords);
if (r < 0)
return log_error_errno(r, "Failed to send: %m");
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index 322f627..5815f2c 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -79,6 +79,7 @@ int builtin_main(int argc, char *argv[], void *userdata) {
UdevBuiltinCommand cmd;
int r;
+ log_set_max_level(LOG_DEBUG);
log_setup();
r = parse_argv(argc, argv);
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index c8c23e8..58964b9 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -96,6 +96,7 @@ int test_main(int argc, char *argv[], void *userdata) {
sigset_t mask, sigmask_orig;
int r;
+ log_set_max_level(LOG_DEBUG);
log_setup();
r = parse_argv(argc, argv);
diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py
index e3d49d4..bab0b24 100755
--- a/src/ukify/test/test_ukify.py
+++ b/src/ukify/test/test_ukify.py
@@ -45,6 +45,13 @@ except ImportError as e:
sys.path.append(os.path.dirname(__file__) + '/..')
import ukify
+# Skip if we're running on an architecture that does not use UEFI.
+try:
+ ukify.guess_efi_arch()
+except ValueError as e:
+ print(str(e), file=sys.stderr)
+ sys.exit(77)
+
build_root = os.getenv('PROJECT_BUILD_ROOT')
try:
slow_tests = bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '1')))
diff --git a/test/TEST-13-NSPAWN/test.sh b/test/TEST-13-NSPAWN/test.sh
index 5c85b0c..3ab52d0 100755
--- a/test/TEST-13-NSPAWN/test.sh
+++ b/test/TEST-13-NSPAWN/test.sh
@@ -17,6 +17,8 @@ test_append_files() {
# For virtual wlan interface.
instmods mac80211_hwsim
+ # for IPMasquerade=
+ instmods "=net/netfilter"
generate_module_dependencies
# Create a dummy container "template" with a minimal toolset, which we can
diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py
index 0931043..e0a4b6e 100755
--- a/test/integration-test-wrapper.py
+++ b/test/integration-test-wrapper.py
@@ -149,7 +149,7 @@ def main():
'--runtime-scratch=no',
*args.mkosi_args,
'--qemu-firmware', args.firmware,
- '--qemu-kvm', "auto" if not bool(int(os.getenv("TEST_NO_KVM", "0"))) else "no",
+ *(['--qemu-kvm', 'no'] if int(os.getenv("TEST_NO_KVM", "0")) else []),
'--kernel-command-line-extra',
' '.join([
'systemd.hostname=H',
diff --git a/test/test-functions b/test/test-functions
index 04fe20f..69a0e58 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -1453,10 +1453,31 @@ install_missing_libraries() {
[[ -e "$libgcc_s" ]] && inst_library "$libgcc_s"
done < <(ldconfig -p | awk '/\/libgcc_s.so.1$/ { print $4 }')
- local lib path
+ local lib path libs
# A number of dependencies is now optional via dlopen, so the install
# script will not pick them up, since it looks at linkage.
- for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1 libarchive libgcrypt libkmod; do
+ libs=(
+ libarchive
+ libbpf
+ libcryptsetup
+ libdw
+ libelf
+ libfido2
+ libgcrypt
+ libidn
+ libidn2
+ libip4tc
+ libkmod
+ libqrencode
+ p11-kit-1
+ pwquality
+ tss2-esys
+ tss2-mu
+ tss2-rc
+ tss2-tcti-device
+ xkbcommon
+ )
+ for lib in "${libs[@]}"; do
ddebug "Searching for $lib via pkg-config"
if pkg-config --exists "$lib"; then
path="$(pkg-config --variable=libdir "$lib")"
diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh
index 5615c90..3fc59f6 100644
--- a/test/test-systemctl-enable.sh
+++ b/test/test-systemctl-enable.sh
@@ -3,7 +3,7 @@
set -ex
# Silence warning from running_in_chroot_or_offline()
-export SYSTEMD_IGNORE_CHROOT=1
+export SYSTEMD_IN_CHROOT=0
systemctl=${1:-systemctl}
systemd_id128=${2:-systemd-id128}
diff --git a/test/units/TEST-13-NSPAWN.nspawn.sh b/test/units/TEST-13-NSPAWN.nspawn.sh
index ee0fef8..ad11468 100755
--- a/test/units/TEST-13-NSPAWN.nspawn.sh
+++ b/test/units/TEST-13-NSPAWN.nspawn.sh
@@ -943,6 +943,17 @@ matrix_run_one() {
return 0
}
+testcase_api_vfs() {
+ local api_vfs_writable
+
+ for api_vfs_writable in yes no network; do
+ matrix_run_one no no $api_vfs_writable
+ matrix_run_one yes no $api_vfs_writable
+ matrix_run_one no yes $api_vfs_writable
+ matrix_run_one yes yes $api_vfs_writable
+ done
+}
+
testcase_check_os_release() {
# https://github.com/systemd/systemd/issues/29185
local base common_opts root
@@ -973,11 +984,46 @@ testcase_check_os_release() {
rm -fr "$root" "$base"
}
-run_testcases
+testcase_ip_masquerade() {
+ local root
+
+ if ! command -v networkctl >/dev/null; then
+ echo "This test requires systemd-networkd, skipping..."
+ return 0
+ fi
+
+ systemctl unmask systemd-networkd.service
+ systemctl edit --runtime --stdin systemd-networkd.service --drop-in=debug.conf <<EOF
+[Service]
+Environment=SYSTEMD_LOG_LEVEL=debug
+EOF
+ systemctl start systemd-networkd.service
-for api_vfs_writable in yes no network; do
- matrix_run_one no no $api_vfs_writable
- matrix_run_one yes no $api_vfs_writable
- matrix_run_one no yes $api_vfs_writable
- matrix_run_one yes yes $api_vfs_writable
-done
+ root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.ip_masquerade.XXX)"
+ create_dummy_container "$root"
+
+ systemd-run --unit=nspawn-hoge.service \
+ systemd-nspawn \
+ --register=no \
+ --directory="$root" \
+ --ephemeral \
+ --machine=hoge \
+ --network-veth \
+ bash -x -c "ip link set host0 up; sleep 30s"
+
+ /usr/lib/systemd/systemd-networkd-wait-online -i ve-hoge --timeout 30s
+
+ # Check IPMasquerade= for ve-* and friends enabled IP forwarding.
+ [[ "$(cat /proc/sys/net/ipv4/conf/all/forwarding)" == "1" ]]
+ [[ "$(cat /proc/sys/net/ipv4/conf/default/forwarding)" == "1" ]]
+ [[ "$(cat /proc/sys/net/ipv6/conf/all/forwarding)" == "1" ]]
+ [[ "$(cat /proc/sys/net/ipv6/conf/default/forwarding)" == "1" ]]
+
+ systemctl stop nspawn-hoge.service || :
+ systemctl stop systemd-networkd.service
+ systemctl mask systemd-networkd.service
+
+ rm -fr "$root"
+}
+
+run_testcases
diff --git a/test/units/TEST-58-REPART.sh b/test/units/TEST-58-REPART.sh
index f8c22ab..e5f9c1f 100755
--- a/test/units/TEST-58-REPART.sh
+++ b/test/units/TEST-58-REPART.sh
@@ -161,7 +161,7 @@ $imgs/zzz1 : start= 2048, size= 1775576, type=933AC7E1-2EB4-4F13-B844
$imgs/zzz2 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
systemd-repart --offline="$OFFLINE" \
- --definitions="$defs" \
+ --definitions="$defs" \
--empty=create \
--size=50M \
--seed="$seed" \
@@ -1288,6 +1288,49 @@ testcase_dropped_partitions() {
[[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 2 ]]
}
+testcase_random_seed() {
+ local defs imgs output
+
+ # For issue #34257
+
+ defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
+ imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
+ # shellcheck disable=SC2064
+ trap "rm -rf '$defs' '$imgs'" RETURN
+ chmod 0755 "$defs"
+
+ tee "$defs/root.conf" <<EOF
+[Partition]
+Type=root
+EOF
+
+ tee "$defs/home.conf" <<EOF
+[Partition]
+Type=home
+Label=home-first
+EOF
+
+ tee "$defs/swap.conf" <<EOF
+[Partition]
+Type=swap
+SizeMaxBytes=64M
+PaddingMinBytes=92M
+EOF
+
+ systemd-repart --offline="$OFFLINE" \
+ --definitions="$defs" \
+ --empty=create \
+ --size=1G \
+ --dry-run=no \
+ --seed=random \
+ --offline="$OFFLINE" \
+ --json=pretty \
+ "$imgs/zzz"
+
+ sfdisk -d "$imgs/zzz"
+ [[ "$(sfdisk -d "$imgs/zzz" | grep -F 'uuid=' | awk '{ print $8 }' | sort -u | wc -l)" == "3" ]]
+}
+
OFFLINE="yes"
run_testcases
diff --git a/test/units/TEST-74-AUX-UTILS.detect-virt.sh b/test/units/TEST-74-AUX-UTILS.detect-virt.sh
new file mode 100755
index 0000000..fe1db4d
--- /dev/null
+++ b/test/units/TEST-74-AUX-UTILS.detect-virt.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+SYSTEMD_IN_CHROOT=1 systemd-detect-virt --chroot
+(! SYSTEMD_IN_CHROOT=0 systemd-detect-virt --chroot)