]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #31730 from yuwata/network-dhcp-server-lease-file-follow-ups
authorLuca Boccassi <bluca@debian.org>
Mon, 25 Mar 2024 14:32:05 +0000 (14:32 +0000)
committerGitHub <noreply@github.com>
Mon, 25 Mar 2024 14:32:05 +0000 (14:32 +0000)
network: several follow-ups for DHCP server lease file

234 files changed:
.github/workflows/build_test.yml
.github/workflows/cflite_pr.yml
.github/workflows/cifuzz.yml
.github/workflows/development_freeze.yml
.github/workflows/gather-pr-metadata.yml
.github/workflows/unit_tests.yml
.gitmodules
NEWS
TODO
docs/CREDENTIALS.md
docs/DAEMON_SOCKET_ACTIVATION.md
docs/HACKING.md
hwdb.d/20-usb-vendor-model.hwdb
hwdb.d/60-evdev.hwdb
hwdb.d/60-keyboard.hwdb
hwdb.d/usb.ids
man/common-variables.xml
man/crypttab.xml
man/daemon.xml
man/homectl.xml
man/journalctl.xml
man/org.freedesktop.home1.xml
man/portablectl.xml
man/repart.d.xml
man/rules/meson.build
man/run0.xml [moved from man/uid0.xml with 93% similarity]
man/sd_notify.xml
man/systemd-analyze.xml
man/systemd-boot.xml
man/systemd-bsod.service.xml
man/systemd-cryptsetup.xml
man/systemd-nspawn.xml
man/systemd-pcrlock.xml
man/systemd-poweroff.service.xml
man/systemd-repart.xml
man/systemd-run.xml
man/systemd-soft-reboot.service.xml
man/systemd-storagetm.service.xml
man/systemd-sysext.xml
man/systemd-tpm2-setup.service.xml
man/systemd-vmspawn.xml
man/systemd.network.xml
man/systemd.pcrlock.xml
man/systemd.socket.xml
man/systemd.xml
man/varlinkctl.xml
man/veritytab.xml
meson.build
mkosi.conf
mkosi.images/base/mkosi.conf
mkosi.images/base/mkosi.conf.d/10-arch/mkosi.build.chroot
mkosi.images/base/mkosi.conf.d/10-centos-fedora/mkosi.conf
mkosi.images/base/mkosi.conf.d/10-debian-ubuntu/mkosi.conf
mkosi.images/base/mkosi.conf.d/10-opensuse/initrd/mkosi.postinst
mkosi.images/base/mkosi.conf.d/10-opensuse/mkosi.conf
pkg/arch
pkg/debian
pkg/fedora
po/fr.po
src/analyze/analyze-dot.c
src/analyze/analyze-security.c
src/analyze/analyze.c
src/basic/cgroup-util.c
src/basic/chase.c
src/basic/devnum-util.c
src/basic/efivars.c
src/basic/fileio.c
src/basic/format-util.c
src/basic/log.c
src/basic/log.h
src/basic/macro.h
src/basic/missing_audit.h
src/basic/missing_capability.h
src/basic/missing_drm.h
src/basic/missing_fs.h
src/basic/missing_input.h
src/basic/missing_ioprio.h
src/basic/missing_keyctl.h
src/basic/missing_loop.h
src/basic/missing_magic.h
src/basic/missing_mman.h
src/basic/missing_mount.h
src/basic/missing_prctl.h
src/basic/missing_random.h
src/basic/missing_resource.h
src/basic/missing_sched.h
src/basic/missing_timerfd.h
src/basic/missing_type.h
src/basic/missing_wait.h
src/basic/nulstr-util.c
src/basic/nulstr-util.h
src/basic/path-lookup.c
src/basic/path-util.c
src/basic/path-util.h
src/basic/proc-cmdline.c
src/basic/process-util.c
src/basic/socket-util.c
src/basic/stat-util.c
src/basic/string-util.c
src/basic/string-util.h
src/basic/terminal-util.c
src/basic/terminal-util.h
src/basic/time-util.c
src/basic/unit-name.c
src/basic/virt.c
src/boot/efi/efi.h
src/boot/efi/meson.build
src/boot/efi/secure-boot.c
src/core/automount.c
src/core/bpf-socket-bind.c
src/core/bpf/socket_bind/socket-bind-api.bpf.h
src/core/bpf/socket_bind/socket-bind.bpf.c
src/core/device.c
src/core/dynamic-user.c
src/core/exec-invoke.c
src/core/execute.c
src/core/import-creds.c
src/core/load-fragment.c
src/core/main.c
src/core/mount.c
src/core/path.c
src/core/scope.c
src/core/service.c
src/core/slice.c
src/core/socket.c
src/core/socket.h
src/core/swap.c
src/core/target.c
src/core/timer.c
src/core/unit-printf.c
src/core/unit.c
src/core/unit.h
src/coredump/coredump-vacuum.c
src/fstab-generator/fstab-generator.c
src/home/home-util.h
src/home/homectl.c
src/home/homed-home-bus.c
src/home/homed-home-bus.h
src/home/homed-home.c
src/home/homed-home.h
src/home/homed-manager-bus.c
src/home/homed-manager.c
src/home/homed-operation.h
src/home/homework-luks.c
src/home/homework-password-cache.c
src/home/homework-password-cache.h
src/home/homework.c
src/home/org.freedesktop.home1.conf
src/home/org.freedesktop.home1.policy
src/hostname/hostnamed.c
src/journal/journalctl.c
src/kernel-install/90-uki-copy.install
src/kernel-install/kernel-install.c
src/libsystemd/sd-device/device-util.c
src/libsystemd/sd-device/device-util.h
src/libsystemd/sd-journal/catalog.c
src/libsystemd/sd-journal/catalog.h
src/locale/localed.c
src/login/loginctl.c
src/login/logind-dbus.c
src/login/logind-dbus.h
src/login/logind-session-device.c
src/login/logind-session.c
src/machine/machine.c
src/machine/machinectl.c
src/network/networkctl.c
src/network/networkd-address.c
src/network/networkd-manager-varlink.c
src/network/networkd-route-metric.c
src/network/networkd-route-nexthop.c
src/nspawn/nspawn-register.c
src/nspawn/nspawn.c
src/oom/oomd-util.c
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dnssd.c
src/run/meson.build
src/run/run.c
src/run/systemd-run0.in [moved from src/run/systemd-uid0.in with 96% similarity]
src/shared/bus-unit-util.c
src/shared/bus-unit-util.h
src/shared/cryptsetup-util.c
src/shared/cryptsetup-util.h
src/shared/dissect-image.c
src/shared/ethtool-util.c
src/shared/install-printf.c
src/shared/install.c
src/shared/install.h
src/shared/libcrypt-util.c
src/shared/netif-util.c
src/shared/password-quality-util-pwquality.c
src/shared/pretty-print.c
src/shared/ptyfwd.c
src/shared/specifier.c
src/shared/tests.h
src/shared/tpm2-util.c
src/shared/varlink.c
src/ssh-generator/ssh-generator.c
src/sysusers/sysusers.c
src/test/meson.build
src/test/test-cgroup-util.c
src/test/test-compress.c
src/test/test-gpt.c
src/test/test-hashmap.c
src/test/test-hmac.c
src/test/test-label.c
src/test/test-mountpoint-util.c
src/test/test-os-util.c
src/test/test-path-util.c
src/test/test-pretty-print.c
src/test/test-recovery-key.c [new file with mode: 0644]
src/test/test-string-util.c
src/test/test-user-util.c
src/vmspawn/vmspawn-scope.c
src/vmspawn/vmspawn.c
test/README.testsuite
test/TEST-04-JOURNAL/test.sh
test/TEST-74-AUX-UTILS/test.sh
test/meson.build
test/run-integration-tests.sh
test/test-functions
test/units/testsuite-04.corrupted-journals.sh
test/units/testsuite-04.journal.sh
test/units/testsuite-07.exec-context.sh
test/units/testsuite-46.sh
test/units/testsuite-74.run.sh
tools/check-efi-alignment.py [new file with mode: 0755]
tools/dbus_exporter.py
tools/elf2efi.py
tools/git-setup.sh
units/systemd-battery-check.service.in
units/systemd-networkd.service.in

index 9ef233298003bfb918e384b7dd96410675a9220a..b6476d7045239d4853172836dd0a5cd637b0ae91 100644 (file)
@@ -34,8 +34,5 @@ jobs:
     steps:
       - name: Repository checkout
         uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
-      # FIXME: drop once https://github.com/actions/runner-images/issues/9491  is resolved
-      - name: Reduce ASLR entropy
-        run: sudo sysctl -w vm.mmap_rnd_bits=28
       - name: Build check
         run: .github/workflows/build_test.sh
index bf7a14e356ac94c2b208bff0074b23666b59433d..707ea0b6ba625996e7736b38a4dbc1fc0a1bf117 100644 (file)
@@ -23,7 +23,6 @@ jobs:
       matrix:
         sanitizer: [address, undefined, memory]
     steps:
-    - run: sudo sysctl -w vm.mmap_rnd_bits=28
     - name: Build Fuzzers
       id: build
       uses: google/clusterfuzzlite/actions/build_fuzzers@v1
index 3aaaa3fd751f6e438e3e692baa9de0ed65fef380..a12ad9335f9d00ae230ab93b44caccf1752b9799 100644 (file)
@@ -39,7 +39,6 @@ jobs:
       security-events: write
 
     steps:
-      - run: sudo sysctl -w vm.mmap_rnd_bits=28
       - name: Build Fuzzers
         id: build
         uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
index ef4f0b50e98ead584f1bd8f0ccc1f11d7e163ad0..f9738d0ffeace1b0b6afa7ad6884958358c97084 100644 (file)
@@ -8,10 +8,6 @@ on:
     types:
       - completed
 
-env:
-  PULL_REQUEST_METADATA_DIR: pull_request
-  PULL_REQUEST_METADATA_FILE: metadata
-
 permissions:
   contents: read
 
@@ -27,40 +23,11 @@ jobs:
       pull-requests: write
 
     steps:
-      - name: Download Pull Request Metadata artifact
-        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
-        with:
-          script: |
-            const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
-               owner: context.repo.owner,
-               repo: context.repo.repo,
-               run_id: ${{ github.event.workflow_run.id }},
-            });
-
-            const matchArtifact = artifacts.data.artifacts.filter((artifact) => {
-              return artifact.name == "${{ env.PULL_REQUEST_METADATA_FILE }}"
-            })[0];
-
-            const download = await github.rest.actions.downloadArtifact({
-               owner: context.repo.owner,
-               repo: context.repo.repo,
-               artifact_id: matchArtifact.id,
-               archive_format: 'zip',
-            });
-
-            const fs = require('fs');
-            fs.writeFileSync('${{ github.workspace }}/${{ env.PULL_REQUEST_METADATA_FILE }}.zip', Buffer.from(download.data));
-
-      - run: unzip ${{ env.PULL_REQUEST_METADATA_FILE }}.zip
-
-      - name: 'Get Pull Request number'
-        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+      - id: artifact
+        name: Download Pull Request Metadata artifact
+        uses: redhat-plumbers-in-action/download-artifact@463ae626ac2dd333491c7beccaa24c12c5c259b8
         with:
-          github-token: ${{ secrets.GITHUB_TOKEN }}
-          script: |
-            const fs = require('fs');
-            const pr_number = Number(fs.readFileSync('./${{ env.PULL_REQUEST_METADATA_FILE }}'));
-            core.exportVariable('pr_number', pr_number);
+          name: Pull Request Metadata
 
       - name: Repository checkout
         uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
@@ -68,7 +35,9 @@ jobs:
           fetch-depth: 0
 
       - name: Development Freezer
-        uses: redhat-plumbers-in-action/devel-freezer@67aec4a153bd9fca5322e1c4dd4d7c419fb36362
+        uses: redhat-plumbers-in-action/devel-freezer@396c94ba8cb417474e6626c83a42addea210a403
         with:
-          pr-number: ${{ env.pr_number }}
+          pr-number: ${{ fromJSON(steps.artifact.outputs.pr-metadata-json).number }}
+          # delay start of validation to allow for some milestone/labels tweaking
+          delay: 20
           token: ${{ secrets.GITHUB_TOKEN }}
index 68c88fb94bc07e316c1a3c3b9a9ec29aa23a4612..ae5921aac46f6126407cfc69dfb05e0213191932 100644 (file)
@@ -6,10 +6,6 @@ on:
   pull_request:
     branches: [ main ]
 
-env:
-  PULL_REQUEST_METADATA_DIR: pull_request
-  PULL_REQUEST_METADATA_FILE: metadata
-
 permissions:
   contents: read
 
@@ -21,17 +17,14 @@ jobs:
     steps:
       - name: Repository checkout
         uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
-        with:
-          fetch-depth: 0
 
-      - name: Store PR number in file
-        run: |
-          mkdir -p ./${{ env.PULL_REQUEST_METADATA_DIR }}
-          echo ${{ github.event.number }} >./${{ env.PULL_REQUEST_METADATA_DIR }}/${{ env.PULL_REQUEST_METADATA_FILE }}
+      - id: metadata
+        name: Gather Pull Request Metadata
+        uses: redhat-plumbers-in-action/gather-pull-request-metadata@69c703f376018c1a41c8ccce21dc2e16a79f3324
 
       - name: Upload Pull Request Metadata artifact
         uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3
         with:
-          name: ${{ env.PULL_REQUEST_METADATA_FILE }}
-          path: ${{ env.PULL_REQUEST_METADATA_DIR }}
+          name: Pull Request Metadata
+          path: ${{ steps.metadata.outputs.metadata-file }}
           retention-days: 1
index 9942df6be2cfe40600895afe9449edc7b4ce0cda..4c398e9eaeb8445b558485d3f49ee2d32474974e 100644 (file)
@@ -31,9 +31,6 @@ jobs:
     steps:
       - name: Repository checkout
         uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
-      # FIXME: drop once https://github.com/actions/runner-images/issues/9491  is resolved
-      - name: Reduce ASLR entropy
-        run: sudo sysctl -w vm.mmap_rnd_bits=28
       - name: Install build dependencies
         run: |
           # Drop XDG_* stuff from /etc/environment, so we don't get the user
index ba9f6d7f27e729618fb09ba2d811dd35331761e3..64d938fbf9989bc0c03bfe276ff9efdbc9d122a8 100644 (file)
@@ -1,10 +1,10 @@
 [submodule "pkg/fedora"]
        path = pkg/fedora
-       url = https://src.fedoraproject.org/rpms/systemd
+       url = https://src.fedoraproject.org/rpms/systemd.git
        branch = rawhide
 [submodule "pkg/opensuse"]
        path = pkg/opensuse
-       url = https://src.opensuse.org/rpm/systemd
+       url = https://src.opensuse.org/rpm/systemd.git
        branch = factory
 [submodule "pkg/debian"]
        path = pkg/debian
@@ -12,9 +12,9 @@
        branch = debian/master
 [submodule "pkg/centos"]
        path = pkg/centos
-       url = https://git.centos.org/rpms/systemd
+       url = https://git.centos.org/rpms/systemd.git
        branch = c9s-sig-hyperscale
 [submodule "pkg/arch"]
        path = pkg/arch
-       url = https://gitlab.archlinux.org/daandemeyer/systemd.git
-       branch = strip
+       url = https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git
+       branch = main
diff --git a/NEWS b/NEWS
index 1f71030ebfd82584bcd8fa9198d601309051154c..7014e7582af84316544143edf06381ae2ce76d4a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -329,7 +329,7 @@ CHANGES WITH 256 in spe:
 
         Command-line tools:
 
-        * systemd-run is now a multi-call binary. When invoked as 'uid0', it
+        * systemd-run is now a multi-call binary. When invoked as 'run0', it
           provides as interface similar to 'sudo', with all arguments starting
           at the first non-option parameter being treated the command to
           invoke as root. Unlike 'sudo' and similar tools, it does not make use
diff --git a/TODO b/TODO
index 3b76e98bdeb7906e8a43908ecdc666c61e5aa2bc..097c639d1382addf2947b56aeb88240e112ff6c4 100644 (file)
--- a/TODO
+++ b/TODO
@@ -255,7 +255,7 @@ Features:
 
 * add a new ExecStart= flag that inserts the configured user's shell as first
   word in the command line. (maybe use character '.'). Usecase: tool such as
-  uid0 can use that to spawn the target user's default shell.
+  run0 can use that to spawn the target user's default shell.
 
 * varlink: figure out how to do docs for our varlink interfaces. Idea: install
   interface files augmented with docs in /usr/share/ somewhere. And have
@@ -2277,8 +2277,6 @@ Features:
   - fingerprint authentication, pattern authentication, …
   - make sure "classic" user records can also be managed by homed
   - make size of $XDG_RUNTIME_DIR configurable in user record
-  - query password from kernel keyring first
-  - update even if record is "absent"
   - move acct mgmt stuff from pam_systemd_home to pam_systemd?
   - when "homectl --pkcs11-token-uri=" is used, synthesize ssh-authorized-keys records for all keys we have private keys on the stick for
   - make slice for users configurable (requires logind rework)
@@ -2550,7 +2548,6 @@ Features:
    - allow Name= to be specified repeatedly in the [Match] section. Maybe also
      support Name=foo*|bar*|baz ?
    - whenever uplink info changes, make DHCP server send out FORCERENEW
-   - figure out spelling: NamespaceId vs. NamespaceNSID
 
 * in networkd, when matching device types, fix up DEVTYPE rubbish the kernel passes to us
 
index ed30eacf2bffbfb01dfec800804692e27bbd1257..9c245dbf2b367fb788787719ba642c59ef025364 100644 (file)
@@ -380,7 +380,8 @@ Various services shipped with `systemd` consume credentials for tweaking behavio
   to receive a notification via VSOCK when a virtual machine has finished booting.
   Note that in case the hypervisor does not support `SOCK_DGRAM` over `AF_VSOCK`,
   `SOCK_SEQPACKET` will be tried instead. The credential payload should be in the
-  form: `vsock:<CID>:<PORT>`. Also note that this requires support for VHOST to be
+  form: `vsock:<CID>:<PORT>`. `vsock` may be replaced with `vsock-stream`, `vsock-dgram` or `vsock-seqpacket`
+  to force usage of the corresponding socket type. Also note that this requires support for VHOST to be
   built-in both the guest and the host kernels, and the kernel modules to be loaded.
 
 * [`systemd-sysusers(8)`](https://www.freedesktop.org/software/systemd/man/systemd-sysusers.html)
index 1a027a37c80de2b2585e6eb3b3ca56b7ea08683a..87328ce4cf27c2a2888b2f34f0582b28c30e8e38 100644 (file)
@@ -35,12 +35,14 @@ PrivateNetwork=true
 **/etc/systemd/system/my-nginx.socket**
 
 ```
+[Unit]
+After=network.target
+Requires=network.target
+
 [Socket]
 ListenStream=80
 ListenStream=0.0.0.0:80
 BindIPv6Only=ipv6-only
-After=network.target
-Requires=network.target
 
 [Install]
 WantedBy=sockets.target
index 6dc9489124694b465da03411d6d02e20ca9f40df..8abb5e040f21a800b59a66adeaf6b4137b26567e 100644 (file)
@@ -20,6 +20,7 @@ git correctly (running `meson` will run these commands for you automatically):
 ```shell
 $ git config submodule.recurse true
 $ git config fetch.recurseSubmodules on-demand
+$ git config push.recurseSubmodules no
 ```
 
 When adding new functionality, tests should be added. For shared functionality
index d7376b102f0094e3c1a6338c135f274c7ddd0a63..054213c9ba4bbf9258d5531d776acca2932e2517 100644 (file)
@@ -29,6 +29,12 @@ usb:v0011*
 usb:v0011p7788*
  ID_MODEL_FROM_DATABASE=counterfeit flash drive
 
+usb:v001F*
+ ID_VENDOR_FROM_DATABASE=Walmart
+
+usb:v001Fp0B21*
+ ID_MODEL_FROM_DATABASE=AB13X Headset Adapter
+
 usb:v0040*
  ID_VENDOR_FROM_DATABASE=Anyware Corporation
 
@@ -563,6 +569,9 @@ usb:v03F0p0024*
 usb:v03F0p002A*
  ID_MODEL_FROM_DATABASE=LaserJet P1102
 
+usb:v03F0p0036*
+ ID_MODEL_FROM_DATABASE=CCID Smartcard Keyboard KUS0133
+
 usb:v03F0p0053*
  ID_MODEL_FROM_DATABASE=DeskJet 2620 All-in-One Printer
 
@@ -2202,13 +2211,13 @@ usb:v03F3p009B*
  ID_MODEL_FROM_DATABASE=AVC-1410 GameBridge TV NTSC
 
 usb:v03F3p2000*
- ID_MODEL_FROM_DATABASE=USBXchange
+ ID_MODEL_FROM_DATABASE=USBXchange Firmware Loader
 
 usb:v03F3p2001*
  ID_MODEL_FROM_DATABASE=USBXchange Adapter
 
 usb:v03F3p2002*
- ID_MODEL_FROM_DATABASE=USB2-Xchange
+ ID_MODEL_FROM_DATABASE=USB2-Xchange Firmware Loader
 
 usb:v03F3p2003*
  ID_MODEL_FROM_DATABASE=USB2-Xchange Adapter
@@ -2405,6 +2414,15 @@ usb:v0403p6EE0*
 usb:v0403p6F70*
  ID_MODEL_FROM_DATABASE=HB-RF-USB
 
+usb:v0403p7150*
+ ID_MODEL_FROM_DATABASE=FT2232x wired for MPSSE+UART
+
+usb:v0403p7151*
+ ID_MODEL_FROM_DATABASE=FT2232x wired for MPSSE+UART
+
+usb:v0403p7152*
+ ID_MODEL_FROM_DATABASE=FreeCalypso dual UART with boot control
+
 usb:v0403p7BE8*
  ID_MODEL_FROM_DATABASE=FT232R
 
@@ -5090,6 +5108,9 @@ usb:v0424p4041*
 usb:v0424p4060*
  ID_MODEL_FROM_DATABASE=Ultra Fast Media Reader
 
+usb:v0424p4063*
+ ID_MODEL_FROM_DATABASE=xD/SD/MS/MMC Reader
+
 usb:v0424p4064*
  ID_MODEL_FROM_DATABASE=Ultra Fast Media Reader
 
@@ -5858,6 +5879,12 @@ usb:v043Ep9803*
 usb:v043Ep9804*
  ID_MODEL_FROM_DATABASE=DMB Receiver Control
 
+usb:v043Ep9A10*
+ ID_MODEL_FROM_DATABASE=34UC88-B
+
+usb:v043Ep9A11*
+ ID_MODEL_FROM_DATABASE=34UC88-B
+
 usb:v043Ep9A39*
  ID_MODEL_FROM_DATABASE=27UP850 - WK.AEUDCSN - External Monitor 4K
 
@@ -7118,6 +7145,12 @@ usb:v045Ep02EA*
 usb:v045Ep02FD*
  ID_MODEL_FROM_DATABASE=Xbox One S Controller [Bluetooth]
 
+usb:v045Ep02FE*
+ ID_MODEL_FROM_DATABASE=Xbox Wireless Adapter for Windows
+
+usb:v045Ep0306*
+ ID_MODEL_FROM_DATABASE=Surface Pro 7 SD Card Reader
+
 usb:v045Ep0400*
  ID_MODEL_FROM_DATABASE=Windows Powered Pocket PC 2002
 
@@ -7646,6 +7679,9 @@ usb:v045Ep0810*
 usb:v045Ep0823*
  ID_MODEL_FROM_DATABASE=Classic IntelliMouse
 
+usb:v045Ep082A*
+ ID_MODEL_FROM_DATABASE=Pro Intellimouse
+
 usb:v045Ep0900*
  ID_MODEL_FROM_DATABASE=Surface Dock Hub
 
@@ -9339,7 +9375,7 @@ usb:v046DpC52E*
  ID_MODEL_FROM_DATABASE=MK260 Wireless Combo Receiver
 
 usb:v046DpC52F*
- ID_MODEL_FROM_DATABASE=Unifying Receiver
+ ID_MODEL_FROM_DATABASE=Nano Receiver
 
 usb:v046DpC531*
  ID_MODEL_FROM_DATABASE=C-U0007 [Unifying Receiver]
@@ -9348,7 +9384,7 @@ usb:v046DpC532*
  ID_MODEL_FROM_DATABASE=Unifying Receiver
 
 usb:v046DpC534*
- ID_MODEL_FROM_DATABASE=Unifying Receiver
+ ID_MODEL_FROM_DATABASE=Nano Receiver
 
 usb:v046DpC537*
  ID_MODEL_FROM_DATABASE=Cordless Mouse Receiver
@@ -10520,6 +10556,9 @@ usb:v0483p5721*
 usb:v0483p5722*
  ID_MODEL_FROM_DATABASE=Bulk Demo
 
+usb:v0483p572A*
+ ID_MODEL_FROM_DATABASE=STM32F401 microcontroller [ARM Cortex M4] [CDC/ACM serial port]
+
 usb:v0483p5730*
  ID_MODEL_FROM_DATABASE=Audio Speaker
 
@@ -10638,7 +10677,7 @@ usb:v0489pE0CD*
  ID_MODEL_FROM_DATABASE=MediaTek Bluetooth Adapter
 
 usb:v0489pE0D8*
- ID_MODEL_FROM_DATABASE=Bluetooth Adapter
+ ID_MODEL_FROM_DATABASE=Bluetooth 5.2 Adapter [MediaTek MT7922]
 
 usb:v048A*
  ID_VENDOR_FROM_DATABASE=S-MOS Systems, Inc.
@@ -14873,6 +14912,21 @@ usb:v04BFp0321*
 usb:v04BFp0A28*
  ID_MODEL_FROM_DATABASE=INDI AV-IN Device
 
+usb:v04BFp1301*
+ ID_MODEL_FROM_DATABASE=Network Controller
+
+usb:v04BFp1302*
+ ID_MODEL_FROM_DATABASE=i3 Gateway
+
+usb:v04BFp1303*
+ ID_MODEL_FROM_DATABASE=3 Micro Module
+
+usb:v04BFp1304*
+ ID_MODEL_FROM_DATABASE=i3 Module
+
+usb:v04BFp1305*
+ ID_MODEL_FROM_DATABASE=i3 Multi Sensing Module
+
 usb:v04C1*
  ID_VENDOR_FROM_DATABASE=U.S. Robotics (3Com)
 
@@ -15041,6 +15095,9 @@ usb:v04CA*
 usb:v04CAp0020*
  ID_MODEL_FROM_DATABASE=USB Keyboard
 
+usb:v04CAp003A*
+ ID_MODEL_FROM_DATABASE=Multimedia Keyboard
+
 usb:v04CAp004B*
  ID_MODEL_FROM_DATABASE=Keyboard
 
@@ -15707,6 +15764,9 @@ usb:v04D9p1503*
 usb:v04D9p1603*
  ID_MODEL_FROM_DATABASE=Keyboard
 
+usb:v04D9p1605*
+ ID_MODEL_FROM_DATABASE=Keyboard
+
 usb:v04D9p1702*
  ID_MODEL_FROM_DATABASE=Keyboard LKS02
 
@@ -17486,6 +17546,9 @@ usb:v04F2pB71A*
 usb:v04F2pB76B*
  ID_MODEL_FROM_DATABASE=SunplusIT Inc [HP HD Camera]
 
+usb:v04F2pB7B4*
+ ID_MODEL_FROM_DATABASE=Integrated Camera (1920x1080)
+
 usb:v04F3*
  ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
 
@@ -19355,6 +19418,12 @@ usb:v04FE*
 usb:v04FEp0006*
  ID_MODEL_FROM_DATABASE=Happy Hacking Keyboard Lite2
 
+usb:v04FEp0020*
+ ID_MODEL_FROM_DATABASE=HHKB-Classic
+
+usb:v04FEp0021*
+ ID_MODEL_FROM_DATABASE=Happy Hacking Keyboard Professional HYBRID Type-S
+
 usb:v04FF*
  ID_VENDOR_FROM_DATABASE=E-CMOS Corp.
 
@@ -19556,6 +19625,9 @@ usb:v050Dp0083*
 usb:v050Dp0084*
  ID_MODEL_FROM_DATABASE=F8T003v2 Bluetooth
 
+usb:v050Dp008A*
+ ID_MODEL_FROM_DATABASE=6-in-1 Multiport Adapter
+
 usb:v050Dp0102*
  ID_MODEL_FROM_DATABASE=Flip KVM
 
@@ -20987,6 +21059,9 @@ usb:v054Cp0643*
 usb:v054Cp0689*
  ID_MODEL_FROM_DATABASE=Walkman NWZ-B173F
 
+usb:v054Cp068C*
+ ID_MODEL_FROM_DATABASE=UP-D711
+
 usb:v054Cp06BB*
  ID_MODEL_FROM_DATABASE=WALKMAN NWZ-F805
 
@@ -22151,18 +22226,39 @@ usb:v056Ap03B2*
 usb:v056Ap03B3*
  ID_MODEL_FROM_DATABASE=DTH167 [Cintiq Pro 16] touchscreen
 
+usb:v056Ap03C0*
+ ID_MODEL_FROM_DATABASE=DTH271 [Cintiq Pro 27] touchscreen
+
+usb:v056Ap03C4*
+ ID_MODEL_FROM_DATABASE=DTH172 [Cintiq Pro 17]
+
 usb:v056Ap03C5*
  ID_MODEL_FROM_DATABASE=CTL-4100WL [Intuos BT (S)]
 
 usb:v056Ap03C7*
  ID_MODEL_FROM_DATABASE=CTL-6100WL [Intuos BT (M)]
 
+usb:v056Ap03CB*
+ ID_MODEL_FROM_DATABASE=DTH134 [Wacom One 13] touchscreen
+
+usb:v056Ap03CE*
+ ID_MODEL_FROM_DATABASE=DTC121 [Wacom One 12] touchscreen
+
+usb:v056Ap03D0*
+ ID_MODEL_FROM_DATABASE=DTH227 [Cintiq Pro 22]
+
 usb:v056Ap03DC*
  ID_MODEL_FROM_DATABASE=PTH-460 [Intuos Pro (S)] tablet
 
 usb:v056Ap03DD*
  ID_MODEL_FROM_DATABASE=PTH-460 [Intuos Pro BT (S)] tablet
 
+usb:v056Ap03EC*
+ ID_MODEL_FROM_DATABASE=DTH134 [DTH134] touchscreen
+
+usb:v056Ap03ED*
+ ID_MODEL_FROM_DATABASE=DTC121 [DTC121] touchscreen
+
 usb:v056Ap0400*
  ID_MODEL_FROM_DATABASE=PenPartner 4x5
 
@@ -22221,10 +22317,10 @@ usb:v056Dp4000*
  ID_MODEL_FROM_DATABASE=FlexScan EV3237
 
 usb:v056Dp4001*
- ID_MODEL_FROM_DATABASE=Monitor
+ ID_MODEL_FROM_DATABASE=FlexScan EV2450
 
 usb:v056Dp4002*
- ID_MODEL_FROM_DATABASE=USB HID Monitor
+ ID_MODEL_FROM_DATABASE=FlexScan EV2455
 
 usb:v056Dp4014*
  ID_MODEL_FROM_DATABASE=FlexScan EV2750
@@ -22235,6 +22331,9 @@ usb:v056Dp4026*
 usb:v056Dp4027*
  ID_MODEL_FROM_DATABASE=FlexScan EV2456
 
+usb:v056Dp402B*
+ ID_MODEL_FROM_DATABASE=FlexScan EV2780
+
 usb:v056Dp4036*
  ID_MODEL_FROM_DATABASE=FlexScan EV2785
 
@@ -22253,12 +22352,18 @@ usb:v056Dp405A*
 usb:v056Dp405B*
  ID_MODEL_FROM_DATABASE=FlexScan EV2460
 
+usb:v056Dp405E*
+ ID_MODEL_FROM_DATABASE=FlexScan EV2495
+
 usb:v056Dp405F*
  ID_MODEL_FROM_DATABASE=FlexScan EV2795
 
 usb:v056Dp4065*
  ID_MODEL_FROM_DATABASE=FlexScan EV3895
 
+usb:v056Dp406A*
+ ID_MODEL_FROM_DATABASE=FlexScan EV2480
+
 usb:v056E*
  ID_VENDOR_FROM_DATABASE=Elecom Co., Ltd
 
@@ -24575,6 +24680,9 @@ usb:v059Fp1094*
 usb:v059Fp1095*
  ID_MODEL_FROM_DATABASE=Rugged
 
+usb:v059Fp1105*
+ ID_MODEL_FROM_DATABASE=Mobile Drive (RLSD: 2022)
+
 usb:v059FpA601*
  ID_MODEL_FROM_DATABASE=HardDrive
 
@@ -27026,6 +27134,9 @@ usb:v05E5*
 usb:v05E6*
  ID_VENDOR_FROM_DATABASE=Keithley Instruments
 
+usb:v05E6p3390*
+ ID_MODEL_FROM_DATABASE=3390 Arbitrary Waveform Generator
+
 usb:v05E8*
  ID_VENDOR_FROM_DATABASE=ICC, Inc.
 
@@ -27689,6 +27800,12 @@ usb:v0638p4004*
 usb:v0639*
  ID_VENDOR_FROM_DATABASE=Chrontel, Inc.
 
+usb:v0639p7213*
+ ID_MODEL_FROM_DATABASE=CH7213
+
+usb:v0639p7231*
+ ID_MODEL_FROM_DATABASE=CH7213
+
 usb:v063A*
  ID_VENDOR_FROM_DATABASE=Techwin Corp.
 
@@ -29897,6 +30014,9 @@ usb:v06CBp00C7*
 usb:v06CBp00CB*
  ID_MODEL_FROM_DATABASE=Fingerprint scanner
 
+usb:v06CBp00FC*
+ ID_MODEL_FROM_DATABASE=Prometheus Fingerprint Reader
+
 usb:v06CBp0AC3*
  ID_MODEL_FROM_DATABASE=Large Touch Screen
 
@@ -30080,9 +30200,15 @@ usb:v06D3p0393*
 usb:v06D3p0394*
  ID_MODEL_FROM_DATABASE=CP9000D/DW Port
 
+usb:v06D3p0395*
+ ID_MODEL_FROM_DATABASE=CP9000DW
+
 usb:v06D3p0398*
  ID_MODEL_FROM_DATABASE=P93D
 
+usb:v06D3p039E*
+ ID_MODEL_FROM_DATABASE=CP9500DW-S
+
 usb:v06D3p03A1*
  ID_MODEL_FROM_DATABASE=CP9550D/DW Port
 
@@ -30110,9 +30236,15 @@ usb:v06D3p0F10*
 usb:v06D3p3B10*
  ID_MODEL_FROM_DATABASE=P95D
 
+usb:v06D3p3B20*
+ ID_MODEL_FROM_DATABASE=CP9820DW Series
+
 usb:v06D3p3B21*
  ID_MODEL_FROM_DATABASE=CP-9810D/DW
 
+usb:v06D3p3B2F*
+ ID_MODEL_FROM_DATABASE=LS9820A
+
 usb:v06D3p3B30*
  ID_MODEL_FROM_DATABASE=CP-D70DW / CP-D707DW
 
@@ -33551,6 +33683,9 @@ usb:v07CEpC009*
 usb:v07CEpC010*
  ID_MODEL_FROM_DATABASE=CPB-7000
 
+usb:v07CEpC011*
+ ID_MODEL_FROM_DATABASE=ASK-2500
+
 usb:v07CF*
  ID_VENDOR_FROM_DATABASE=Casio Computer Co., Ltd
 
@@ -33957,11 +34092,20 @@ usb:v07FDp0002*
  ID_MODEL_FROM_DATABASE=MOTU Audio for 64 bit
 
 usb:v07FDp0004*
- ID_MODEL_FROM_DATABASE=MicroBook
+ ID_MODEL_FROM_DATABASE=Microbook I/II/IIc
 
 usb:v07FDp0008*
  ID_MODEL_FROM_DATABASE=M Series
 
+usb:v07FDp0009*
+ ID_MODEL_FROM_DATABASE=M Series (firmware update mode)
+
+usb:v07FDp000B*
+ ID_MODEL_FROM_DATABASE=M Series
+
+usb:v07FDp000D*
+ ID_MODEL_FROM_DATABASE=M Series (firmware update mode)
+
 usb:v07FF*
  ID_VENDOR_FROM_DATABASE=Unknown
 
@@ -34142,6 +34286,9 @@ usb:v0827*
 usb:v0828*
  ID_VENDOR_FROM_DATABASE=Sato Corp.
 
+usb:v0828pA003*
+ ID_MODEL_FROM_DATABASE=WS408 Label Printer
+
 usb:v0829*
  ID_VENDOR_FROM_DATABASE=DirecTV Broadband, Inc. (Telocity)
 
@@ -36056,6 +36203,24 @@ usb:v0908p04B3*
 usb:v0908p04B4*
  ID_MODEL_FROM_DATABASE=SCR_CCID
 
+usb:v0908p04B5*
+ ID_MODEL_FROM_DATABASE=Camera
+
+usb:v0908p04B6*
+ ID_MODEL_FROM_DATABASE=Cockpit Touchkeypad
+
+usb:v0908p04B7*
+ ID_MODEL_FROM_DATABASE=Cockpit Touchkeypad Bootloader
+
+usb:v0908p04B8*
+ ID_MODEL_FROM_DATABASE=MediSET USB4-W
+
+usb:v0908p04B9*
+ ID_MODEL_FROM_DATABASE=MediSET USB4-R
+
+usb:v0908p04BA*
+ ID_MODEL_FROM_DATABASE=MediSET USB4-G
+
 usb:v0908p2701*
  ID_MODEL_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd Spy Pen VGA
 
@@ -36110,6 +36275,9 @@ usb:v090Cp1000*
 usb:v090Cp1132*
  ID_MODEL_FROM_DATABASE=5-in-1 Card Reader
 
+usb:v090Cp2000*
+ ID_MODEL_FROM_DATABASE=Disk
+
 usb:v090Cp337B*
  ID_MODEL_FROM_DATABASE=Silicon Motion Camera
 
@@ -36374,6 +36542,9 @@ usb:v091Ep4CDB*
 usb:v0920*
  ID_VENDOR_FROM_DATABASE=Echelon Co.
 
+usb:v0920p5550*
+ ID_MODEL_FROM_DATABASE=U60 FT Network Interface
+
 usb:v0920p7500*
  ID_MODEL_FROM_DATABASE=Network Interface
 
@@ -37028,6 +37199,9 @@ usb:v0944p0117*
 usb:v0944p012F*
  ID_MODEL_FROM_DATABASE=SQ-1
 
+usb:v0944p0203*
+ ID_MODEL_FROM_DATABASE=KRONOS
+
 usb:v0944p0F03*
  ID_MODEL_FROM_DATABASE=K-Series K61P MIDI studio controller
 
@@ -37241,6 +37415,12 @@ usb:v0955p7210*
 usb:v0955p7321*
  ID_MODEL_FROM_DATABASE=Switch [Tegra Erista] recovery mode
 
+usb:v0955p7323*
+ ID_MODEL_FROM_DATABASE=T234 [Orin NX 16GB] recovery mode
+
+usb:v0955p7423*
+ ID_MODEL_FROM_DATABASE=T234 [Orin NX 8GB] recovery mode
+
 usb:v0955p7721*
  ID_MODEL_FROM_DATABASE=T210 [TX1 Tegra Erista] recovery mode
 
@@ -37277,6 +37457,12 @@ usb:v0956*
 usb:v0957*
  ID_VENDOR_FROM_DATABASE=Agilent Technologies, Inc.
 
+usb:v0957p0007*
+ ID_MODEL_FROM_DATABASE=82357A GPIB Interface Firmware loader
+
+usb:v0957p0107*
+ ID_MODEL_FROM_DATABASE=82357A GPIB Interface
+
 usb:v0957p0200*
  ID_MODEL_FROM_DATABASE=E-Video DC-350 Camera
 
@@ -37287,6 +37473,12 @@ usb:v0957p0407*
  ID_MODEL_FROM_DATABASE=33220A Waveform Generator
 
 usb:v0957p0518*
+ ID_MODEL_FROM_DATABASE=82357B GPIB Interface Firmware loader
+
+usb:v0957p0607*
+ ID_MODEL_FROM_DATABASE=34410A Multimeter
+
+usb:v0957p0718*
  ID_MODEL_FROM_DATABASE=82357B GPIB Interface
 
 usb:v0957p0A07*
@@ -37298,6 +37490,9 @@ usb:v0957p1507*
 usb:v0957p1745*
  ID_MODEL_FROM_DATABASE=Test and Measurement Device (IVI)
 
+usb:v0957p1907*
+ ID_MODEL_FROM_DATABASE=53230A Frequency Counter
+
 usb:v0957p1F01*
  ID_MODEL_FROM_DATABASE=N5181A MXG Analog Signal Generator
 
@@ -37547,6 +37742,9 @@ usb:v099Ap713A*
 usb:v099Ap7160*
  ID_MODEL_FROM_DATABASE=Hyper Slim Keyboard
 
+usb:v099Ap7202*
+ ID_MODEL_FROM_DATABASE=Enermax Aurora Micro Wireless Receiver
+
 usb:v099E*
  ID_VENDOR_FROM_DATABASE=Trimble Navigation, Ltd
 
@@ -37823,6 +38021,12 @@ usb:v09D8p0320*
 usb:v09D8p0406*
  ID_MODEL_FROM_DATABASE=TWN4 MIFARE NFC
 
+usb:v09D8p0410*
+ ID_MODEL_FROM_DATABASE=TWN4 HID
+
+usb:v09D8p0420*
+ ID_MODEL_FROM_DATABASE=TWN4 CDC
+
 usb:v09D9*
  ID_VENDOR_FROM_DATABASE=KRF Tech, Ltd
 
@@ -37847,6 +38051,9 @@ usb:v09DAp001A*
 usb:v09DAp002A*
  ID_MODEL_FROM_DATABASE=Wireless Optical Mouse NB-30
 
+usb:v09DAp0103*
+ ID_MODEL_FROM_DATABASE=Oscar X-710BK Gaming Mouse
+
 usb:v09DAp022B*
  ID_MODEL_FROM_DATABASE=Wireless Mouse (Battery Free)
 
@@ -37868,6 +38075,12 @@ usb:v09DAp1068*
 usb:v09DAp112C*
  ID_MODEL_FROM_DATABASE=Bloody V5 Mouse
 
+usb:v09DAp2268*
+ ID_MODEL_FROM_DATABASE=Keyboard (FK11)
+
+usb:v09DAp2690*
+ ID_MODEL_FROM_DATABASE=PK-635G
+
 usb:v09DAp3A60*
  ID_MODEL_FROM_DATABASE=Bloody V8M Core 2 Mouse
 
@@ -37881,11 +38094,17 @@ usb:v09DAp9066*
  ID_MODEL_FROM_DATABASE=F3 V-Track Gaming Mouse
 
 usb:v09DAp9090*
- ID_MODEL_FROM_DATABASE=XL-730K / XL-750BK / XL-755BK Mice
+ ID_MODEL_FROM_DATABASE=XL-730K / XL-747H / XL-750BK / XL-755BK Mice
 
 usb:v09DApF613*
  ID_MODEL_FROM_DATABASE=Bloody V7M Mouse
 
+usb:v09DApF6CC*
+ ID_MODEL_FROM_DATABASE=B314 Light Strike Gaming Keyboard
+
+usb:v09DApFA44*
+ ID_MODEL_FROM_DATABASE=B930 Light Strike RGB Mechanical Gaming Keyboard
+
 usb:v09DB*
  ID_VENDOR_FROM_DATABASE=Measurement Computing Corp.
 
@@ -37934,6 +38153,9 @@ usb:v09E7*
 usb:v09E8*
  ID_VENDOR_FROM_DATABASE=AKAI  Professional M.I. Corp.
 
+usb:v09E8p0029*
+ ID_MODEL_FROM_DATABASE=APC40 mkII
+
 usb:v09E8p0045*
  ID_MODEL_FROM_DATABASE=MPK Mini Mk II MIDI Controller
 
@@ -37949,6 +38171,9 @@ usb:v09E8p0071*
 usb:v09E8p0076*
  ID_MODEL_FROM_DATABASE=LPK25 MIDI Keyboard
 
+usb:v09E8p007C*
+ ID_MODEL_FROM_DATABASE=MPK Mini MIDI Controller
+
 usb:v09E9*
  ID_VENDOR_FROM_DATABASE=Chen-Source, Inc.
 
@@ -38138,6 +38363,15 @@ usb:v0A12p1011*
 usb:v0A12p1012*
  ID_MODEL_FROM_DATABASE=Bluetooth Device
 
+usb:v0A12p1243*
+ ID_MODEL_FROM_DATABASE=CSRA64210 [TaoTronics Headset BH-22 in charging mode]
+
+usb:v0A12p4007*
+ ID_MODEL_FROM_DATABASE=Mpow HC5 Headset in charging mode - HID / Mass Storage
+
+usb:v0A12p4010*
+ ID_MODEL_FROM_DATABASE=Mpow HC5 Headset in charging mode - USB Hub
+
 usb:v0A12pFFFF*
  ID_MODEL_FROM_DATABASE=USB Bluetooth Device in DFU State
 
@@ -38267,6 +38501,9 @@ usb:v0A35p002A*
 usb:v0A35p008A*
  ID_MODEL_FROM_DATABASE=SAC Hub
 
+usb:v0A38*
+ ID_VENDOR_FROM_DATABASE=IRIS sa
+
 usb:v0A39*
  ID_VENDOR_FROM_DATABASE=Gilat Satellite Networks, Ltd
 
@@ -38639,6 +38876,9 @@ usb:v0A5Cp2198*
 usb:v0A5Cp219B*
  ID_MODEL_FROM_DATABASE=Bluetooth 2.1 Device
 
+usb:v0A5Cp219C*
+ ID_MODEL_FROM_DATABASE=BCM2070 Bluetooth
+
 usb:v0A5Cp21B1*
  ID_MODEL_FROM_DATABASE=HP Bluetooth Module
 
@@ -38708,6 +38948,9 @@ usb:v0A5Cp5803*
 usb:v0A5Cp5804*
  ID_MODEL_FROM_DATABASE=BCM5880 Secure Applications Processor with fingerprint swipe sensor
 
+usb:v0A5Cp5832*
+ ID_MODEL_FROM_DATABASE=BCM5880 Secure Applications Processor Smartcard reader
+
 usb:v0A5Cp6300*
  ID_MODEL_FROM_DATABASE=Pirelli Remote NDIS Device
 
@@ -64115,6 +64358,12 @@ usb:v20A0p0006*
 usb:v20A0p4107*
  ID_MODEL_FROM_DATABASE=GPF Crypto Stick V1.2
 
+usb:v20A0p4108*
+ ID_MODEL_FROM_DATABASE=Nitrokey Pro
+
+usb:v20A0p4109*
+ ID_MODEL_FROM_DATABASE=Nitrokey Storage
+
 usb:v20A0p4123*
  ID_MODEL_FROM_DATABASE=IKALOGIC SCANALOGIC 2
 
@@ -64139,9 +64388,36 @@ usb:v20A0p4211*
 usb:v20A0p4223*
  ID_MODEL_FROM_DATABASE=ATSAMD21 [castAR]
 
+usb:v20A0p4230*
+ ID_MODEL_FROM_DATABASE=Nitrokey HSM
+
+usb:v20A0p4287*
+ ID_MODEL_FROM_DATABASE=Nitrokey FIDO U2F
+
 usb:v20A0p428D*
  ID_MODEL_FROM_DATABASE=Electrosense wideband converter
 
+usb:v20A0p42B1*
+ ID_MODEL_FROM_DATABASE=Nitrokey FIDO2
+
+usb:v20A0p42B2*
+ ID_MODEL_FROM_DATABASE=Nitrokey 3A Mini/3A NFC/3C NFC
+
+usb:v20A0p42B4*
+ ID_MODEL_FROM_DATABASE=Nitrokey Pro Bootloader
+
+usb:v20A0p42DA*
+ ID_MODEL_FROM_DATABASE=MuteMe
+
+usb:v20A0p42DD*
+ ID_MODEL_FROM_DATABASE=Nitrokey 3A NFC Bootloader/3C NFC Bootloader
+
+usb:v20A0p42E8*
+ ID_MODEL_FROM_DATABASE=Nitrokey 3A Mini Bootloader
+
+usb:v20A0p42EC*
+ ID_MODEL_FROM_DATABASE=RP2040 [PicoWifi]
+
 usb:v20B1*
  ID_VENDOR_FROM_DATABASE=XMOS Ltd
 
@@ -66303,7 +66579,7 @@ usb:v2581p1808*
  ID_MODEL_FROM_DATABASE=WinUSB Smartcard
 
 usb:v2581pF1D0*
- ID_MODEL_FROM_DATABASE=FIDO U2F Security Key
+ ID_MODEL_FROM_DATABASE=Nitrokey U2F
 
 usb:v258D*
  ID_VENDOR_FROM_DATABASE=Sequans Communications
index 43017dc00f2e565d4f09dcc2959005cd13b196cb..c603f9ca2cc4bca2bb06df22f55e9d1f8eff6861 100644 (file)
@@ -497,6 +497,11 @@ evdev:input:b0003v256Cp0068*
  EVDEV_ABS_00=::200
  EVDEV_ABS_01=::200
 
+# HUION Kamvas 19 Pro (GT-1902)
+evdev:input:b0003v256Cp006Be0110*
+ EVDEV_ABS_00=::68
+ EVDEV_ABS_01=::123
+
 #########################################
 # Lenovo
 #########################################
index 8a0693cf0d4db97b65b430222031cc058dae317d..2e1838744ba1f8db430761a07b1f97137183a7bc 100644 (file)
@@ -1941,6 +1941,16 @@ evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:
  KEYBOARD_KEY_13f=f21                                   # Touchpad toggle
  KEYBOARD_KEY_9e=wlan
 
+# Portege Z830 ACPI quickstart buttons
+evdev:name:Quickstart Button 1:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
+ 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
+
+evdev:name:Quickstart Button 3:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
+ KEYBOARD_KEY_1=f21                                    # Touchpad toggle
+
 ###########################################################
 # VIA
 ###########################################################
@@ -2086,6 +2096,11 @@ evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr
 evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnK116*
  KEYBOARD_KEY_76=f21                                    # Fn+F1 toggle touchpad
 
+# Positivo (N14NPE-N, N15NPE-N)
+evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivo*:pn*:pvr*:rvnPositivo*:rnN1[45]NPE-N*
+ KEYBOARD_KEY_76=f21                                    # Fn+F1 toggle touchpad
+ KEYBOARD_KEY_dd=search
+
 # Positivo (CG15D)
 evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCG15D*
 # Positivo Motion (N14DP6, N14DP7, N14DP7-V2, N14DP9, N14JP6, N14KP6)
index 631c1bcbf60011621eeabc2e27b97f1ddbe30c85..a1e3ea4acd1d7fca174c298f475daa1c32fec832 100644 (file)
@@ -9,8 +9,8 @@
 #      The latest version can be obtained from
 #              http://www.linux-usb.org/usb.ids
 #
-# Version: 2023.11.08
-# Date:    2023-11-08 20:34:02
+# Version: 2024.03.18
+# Date:    2024-03-18 20:34:02
 #
 
 # Vendors, devices and interfaces. Please keep sorted.
@@ -29,6 +29,8 @@
 0004  Nebraska Furniture Mart
 0011  Unknown
        7788  counterfeit flash drive
+001f  Walmart
+       0b21  AB13X Headset Adapter
 0040  Anyware Corporation
        073d  Mini Multimedia 2.4GHz Wireless Keyboard with Touch Pad
 0042  DMT
        0012  DeskJet 1125C Printer Port
        0024  KU-0316 Keyboard
        002a  LaserJet P1102
+       0036  CCID Smartcard Keyboard KUS0133
        0053  DeskJet 2620 All-in-One Printer
        0101  ScanJet 4100c
        0102  PhotoSmart S20
        008c  AVC-2310 Device
        0094  eHome Infrared Receiver
        009b  AVC-1410 GameBridge TV NTSC
-       2000  USBXchange
+       2000  USBXchange Firmware Loader
        2001  USBXchange Adapter
-       2002  USB2-Xchange
+       2002  USB2-Xchange Firmware Loader
        2003  USB2-Xchange Adapter
        4000  4-port hub
        adcc  Composite Device Support
        601f  FT601 32-bit FIFO IC
        6ee0  EZO Carrier Board
        6f70  HB-RF-USB
+       7150  FT2232x wired for MPSSE+UART
+       7151  FT2232x wired for MPSSE+UART
+       7152  FreeCalypso dual UART with boot control
        7be8  FT232R
        8028  Dev board JTAG (FT232H based)
        8040  4 Port Hub
        3fcc  RME MADIface
        4041  Hub and media card controller
        4060  Ultra Fast Media Reader
+       4063  xD/SD/MS/MMC Reader
        4064  Ultra Fast Media Reader
        4712  USB4712 high-speed hub
        4713  USB4715 high-speed hub (2 ports disabled)
        9800  Remote Control Receiver_iMON
        9803  eHome Infrared Receiver
        9804  DMB Receiver Control
+       9a10  34UC88-B
+       9a11  34UC88-B
        9a39  27UP850 - WK.AEUDCSN - External Monitor 4K
        9c01  LGE Sync
 043f  RadiSys Corp.
        02e6  Xbox Wireless Adapter for Windows
        02ea  Xbox One Controller
        02fd  Xbox One S Controller [Bluetooth]
+       02fe  Xbox Wireless Adapter for Windows
+       0306  Surface Pro 7 SD Card Reader
        0400  Windows Powered Pocket PC 2002
        0401  Windows Powered Pocket PC 2002
        0402  Windows Powered Pocket PC 2002
        0800  Wireless keyboard (All-in-One-Media)
        0810  LifeCam HD-3000
        0823  Classic IntelliMouse
+       082a  Pro Intellimouse
        0900  Surface Dock Hub
        0901  Surface Dock Hub
        0902  Surface Dock Hub
        c52b  Unifying Receiver
        c52d  R700 Remote Presenter receiver
        c52e  MK260 Wireless Combo Receiver
-       c52f  Unifying Receiver
+       c52f  Nano Receiver
        c531  C-U0007 [Unifying Receiver]
        c532  Unifying Receiver
-       c534  Unifying Receiver
+       c534  Nano Receiver
        c537  Cordless Mouse Receiver
        c539  Lightspeed Receiver
        c53a  PowerPlay Wireless Charging System
        5720  Mass Storage Device
        5721  Interrupt Demo
        5722  Bulk Demo
+       572a  STM32F401 microcontroller [ARM Cortex M4] [CDC/ACM serial port]
        5730  Audio Speaker
        5731  Microphone
        5740  Virtual COM Port
        e07a  Broadcom BCM20702A1 Bluetooth
        e0c8  MediaTek MT7921 Bluetooth
        e0cd  MediaTek Bluetooth Adapter
-       e0d8  Bluetooth Adapter
+       e0d8  Bluetooth 5.2 Adapter [MediaTek MT7922]
 048a  S-MOS Systems, Inc.
 048c  Alps Electric Ireland, Ltd
 048d  Integrated Technology Express, Inc.
        0320  Bluetooth Adapter
        0321  Bluetooth Device
        0a28  INDI AV-IN Device
+       1301  Network Controller
+       1302  i3 Gateway
+       1303  3 Micro Module
+       1304  i3 Module
+       1305  i3 Multi Sensing Module
 04c1  U.S. Robotics (3Com)
        0020  56K Voice Pro
        0022  56K Voice Pro
        072d  Revio KD410Z
 04ca  Lite-On Technology Corp.
        0020  USB Keyboard
+       003a  Multimedia Keyboard
        004b  Keyboard
        004f  SK-9020 keyboard
        008a  Acer Wired Mouse Model SM-9023
        1400  PS/2 keyboard + mouse controller
        1503  Keyboard
        1603  Keyboard
+       1605  Keyboard
        1702  Keyboard LKS02
        1818  Keyboard [Diatec Filco Majestouch 2]
        2011  Keyboard [Diatec Filco Majestouch 1]
        b681  ThinkPad T490 Webcam
        b71a  Integrated IR Camera
        b76b  SunplusIT Inc [HP HD Camera]
+       b7b4  Integrated Camera (1920x1080)
 04f3  Elan Microelectronics Corp.
        000a  Touchscreen
        0103  ActiveJet K-2024 Multimedia Keyboard
        0003  Smart Card Reader II
 04fe  PFU, Ltd
        0006  Happy Hacking Keyboard Lite2
+       0020  HHKB-Classic
+       0021  Happy Hacking Keyboard Professional HYBRID Type-S
 04ff  E-CMOS Corp.
 0500  Siam United Hi-Tech
        0001  DART Keyboard Mouse
        0081  F8T001v2 Bluetooth
        0083  Bluetooth Device
        0084  F8T003v2 Bluetooth
+       008a  6-in-1 Multiport Adapter
        0102  Flip KVM
        0103  F5U103 Serial Adapter [etek]
        0106  VideoBus II Adapter, Video
        05c4  DualShock 4 [CUH-ZCT1x]
        0643  DSC-H100 in PTP/MTP mode
        0689  Walkman NWZ-B173F
+       068c  UP-D711
        06bb  WALKMAN NWZ-F805
        06c3  RC-S380
        07c3  ILCE-6000 (aka Alpha-6000) in Mass Storage mode
        03ac  DTH-W1620 [MobileStudio Pro 16] touchscreen
        03b2  DTH167 [Cintiq Pro 16] tablet
        03b3  DTH167 [Cintiq Pro 16] touchscreen
+       03c0  DTH271 [Cintiq Pro 27] touchscreen
+       03c4  DTH172 [Cintiq Pro 17]
        03c5  CTL-4100WL [Intuos BT (S)]
        03c7  CTL-6100WL [Intuos BT (M)]
+       03cb  DTH134 [Wacom One 13] touchscreen
+       03ce  DTC121 [Wacom One 12] touchscreen
+       03d0  DTH227 [Cintiq Pro 22]
        03dc  PTH-460 [Intuos Pro (S)] tablet
        03dd  PTH-460 [Intuos Pro BT (S)] tablet
+       03ec  DTH134 [DTH134] touchscreen
+       03ed  DTC121 [DTC121] touchscreen
        0400  PenPartner 4x5
        4001  TPC4001
        4004  TPC4004
        0002  HID Monitor Controls
        0003  Device Bay Controller
        4000  FlexScan EV3237
-       4001  Monitor
-       4002  USB HID Monitor
+       4001  FlexScan EV2450
+       4002  FlexScan EV2455
        4014  FlexScan EV2750
        4026  FlexScan EV2451
        4027  FlexScan EV2456
+       402b  FlexScan EV2780
        4036  FlexScan EV2785
        4037  FlexScan EV3285
        4044  FlexScan EV2457
        4059  FlexScan EV2760
        405a  FlexScan EV2360
        405b  FlexScan EV2460
+       405e  FlexScan EV2495
        405f  FlexScan EV2795
        4065  FlexScan EV3895
+       406a  FlexScan EV2480
 056e  Elecom Co., Ltd
        0002  29UO Mouse
        0057  Micro Grast Pop M-PGDL
        1093  Rugged
        1094  Rugged THB
        1095  Rugged
+       1105  Mobile Drive (RLSD: 2022)
        a601  HardDrive
        a602  CD R/W
 05a0  Vetronix Corp.
 05e4  Red Wing Corp.
 05e5  Fuji Electric Co., Ltd
 05e6  Keithley Instruments
+       3390  3390 Arbitrary Waveform Generator
 05e8  ICC, Inc.
 05e9  Kawasaki LSI
        0008  KL5KUSB101B Ethernet [klsi]
 # typo?
        4004  Minolta Dimage Scan Elite II AF-2920 (2888)
 0639  Chrontel, Inc.
+       7213  CH7213
+       7231  CH7213
 063a  Techwin Corp.
 063b  Taugagreining HF
 063c  Yamaichi Electronics Co., Ltd (Sakura)
        00bd  Prometheus MIS Touch Fingerprint Reader
        00c7  TouchPad
        00cb  Fingerprint scanner
+       00fc  Prometheus Fingerprint Reader
        0ac3  Large Touch Screen
        2970  touchpad
 06cc  Terayon Communication Systems
        038c  CP900DW(ID) Port
        0393  CP9500D/DW Port
        0394  CP9000D/DW Port
+       0395  CP9000DW
        0398  P93D
+       039e  CP9500DW-S
        03a1  CP9550D/DW Port
        03a5  CP9550DW-S
        03a9  CP-9600DW
        03ae  CP-9800DW-S
        0f10  Hori/Namco FlightStick 2
        3b10  P95D
+       3b20  CP9820DW Series
        3b21  CP-9810D/DW
+       3b2f  LS9820A
        3b30  CP-D70DW / CP-D707DW
        3b31  CP-K60DW-S
        3b36  CP-D80DW
        c007  DPB-4000
        c009  DPB-6000
        c010  CPB-7000
+       c011  ASK-2500
 07cf  Casio Computer Co., Ltd
        1001  QV-8000SX/5700/3000EX Digicam; Exilim EX-M20
        1003  Exilim EX-S500
        0000  FastLane MIDI Interface
        0001  MIDI Interface
        0002  MOTU Audio for 64 bit
-       0004  MicroBook
+       0004  Microbook I/II/IIc
        0008  M Series
+       0009  M Series (firmware update mode)
+       000b  M Series
+       000d  M Series (firmware update mode)
 07ff  Unknown
        00ff  Portable Hard Drive
        ffff  Mad Catz Gamepad
 0826  Data Transit
 0827  BroadLogic, Inc.
 0828  Sato Corp.
+       a003  WS408 Label Printer
 0829  DirecTV Broadband, Inc. (Telocity)
 082d  Handspring
        0100  Visor
        04b2  NC interface
        04b3  keyboard front panel Cockpit
        04b4  SCR_CCID
+       04b5  Camera
+       04b6  Cockpit Touchkeypad
+       04b7  Cockpit Touchkeypad Bootloader
+       04b8  MediSET USB4-W
+       04b9  MediSET USB4-R
+       04ba  MediSET USB4-G
        2701  ShenZhen SANZHAI Technology Co.,Ltd Spy Pen VGA
 0909  Audio-Technica Corp.
        001b  ATR2100-USB
        037c  300k Pixel Camera
        1000  Flash Drive
        1132  5-in-1 Card Reader
+       2000  Disk
        337b  Silicon Motion Camera
        3710  Silicon Motion Camera
        3720  Silicon Motion Camera
        4cda  Fenix 6 Sapphire
        4cdb  Fenix 6
 0920  Echelon Co.
+       5550  U60 FT Network Interface
        7500  Network Interface
 0921  GoHubs, Inc.
        1001  GoCOM232 Serial
        010f  nanoKONTROL studio controller
        0117  nanoKONTROL2 MIDI Controller
        012f  SQ-1
+       0203  KRONOS
        0f03  K-Series K61P MIDI studio controller
 0945  Pasco Scientific
 0948  Kronauer music in digital
        7140  T124 [Tegra K1/Logan 32-bit]
        7210  SHIELD Controller
        7321  Switch [Tegra Erista] recovery mode
+       7323  T234 [Orin NX 16GB] recovery mode
+       7423  T234 [Orin NX 8GB] recovery mode
        7721  T210 [TX1 Tegra Erista] recovery mode
        7820  T20 [Tegra 2] recovery mode
        7c18  T186 [TX2 Tegra Parker] recovery mode
        cf09  SHIELD Tablet
 0956  BSquare Corp.
 0957  Agilent Technologies, Inc.
+       0007  82357A GPIB Interface Firmware loader
+       0107  82357A GPIB Interface
        0200  E-Video DC-350 Camera
        0202  E-Video DC-350 Camera
        0407  33220A Waveform Generator
-       0518  82357B GPIB Interface
+       0518  82357B GPIB Interface Firmware loader
+       0607  34410A Multimeter
+       0718  82357B GPIB Interface
        0a07  34411A Multimeter
        1507  33210A Waveform Generator
        1745  Test and Measurement Device (IVI)
+       1907  53230A Frequency Counter
        1f01  N5181A MXG Analog Signal Generator
        2918  U2702A oscilloscope
        fb18  LC Device
        6330  SANWA Supply Inc. Slim Keyboard
        713a  WK-713 Multimedia Keyboard
        7160  Hyper Slim Keyboard
+       7202  Enermax Aurora Micro Wireless Receiver
 099e  Trimble Navigation, Ltd
 09a3  PairGain Technologies
 09a4  Contech Research, Inc.
 09d8  ELATEC GmbH
        0320  TWN3 Multi125
        0406  TWN4 MIFARE NFC
+       0410  TWN4 HID
+       0420  TWN4 CDC
 09d9  KRF Tech, Ltd
 09da  A4Tech Co., Ltd.
        0006  Optical Mouse WOP-35 / Trust 450L Optical Mouse
        0018  Trust Human Interface Device
        001a  Wireless Mouse & RXM-15 Receiver
        002a  Wireless Optical Mouse NB-30
+       0103  Oscar X-710BK Gaming Mouse
        022b  Wireless Mouse (Battery Free)
        024f  RF Receiver and G6-20D Wireless Optical Mouse
        0260  KV-300H Isolation Keyboard
        09da  Bloody V8 Mouse
        1068  Bloody A90 Mouse
        112c  Bloody V5 Mouse
+       2268  Keyboard (FK11)
+       2690  PK-635G
        3a60  Bloody V8M Core 2 Mouse
        8090  X-718BK Oscar Optical Gaming Mouse
        9033  X-718BK Optical Mouse
        9066  F3 V-Track Gaming Mouse
-       9090  XL-730K / XL-750BK / XL-755BK Mice
+       9090  XL-730K / XL-747H / XL-750BK / XL-755BK Mice
        f613  Bloody V7M Mouse
+       f6cc  B314 Light Strike Gaming Keyboard
+       fa44  B930 Light Strike RGB Mechanical Gaming Keyboard
 09db  Measurement Computing Corp.
        0075  MiniLab 1008
        0076  PMD-1024
 09e6  Silutia, Inc.
 09e7  Real 3D, Inc.
 09e8  AKAI  Professional M.I. Corp.
+       0029  APC40 mkII
        0045  MPK Mini Mk II MIDI Controller
        0062  MPD16 MIDI Pad Controller Unit
        006d  EWI electronic wind instrument
        0071  MPK25 MIDI Keyboard
        0076  LPK25 MIDI Keyboard
+       007c  MPK Mini MIDI Controller
 09e9  Chen-Source, Inc.
 09eb  IM Networks, Inc.
        4331  iRhythm Tuner Remote
        1010  Bluetooth Device
        1011  Bluetooth Device
        1012  Bluetooth Device
+       1243  CSRA64210 [TaoTronics Headset BH-22 in charging mode]
+       4007  Mpow HC5 Headset in charging mode - HID / Mass Storage
+       4010  Mpow HC5 Headset in charging mode - USB Hub
        ffff  USB Bluetooth Device in DFU State
 0a13  Telebyte, Inc.
 0a14  Spacelabs Medical, Inc.
 0a35  Radikal Technologies
        002a  SAC - Software Assigned Controller
        008a  SAC Hub
+0a38  IRIS sa
 0a39  Gilat Satellite Networks, Ltd
 0a3a  PentaMedia Co., Ltd
        0163  KN-W510U 1.0 Wireless LAN Adapter
        217f  BCM2045B (BDC-2.1)
        2198  Bluetooth 3.0 Device
        219b  Bluetooth 2.1 Device
+       219c  BCM2070 Bluetooth
        21b1  HP Bluetooth Module
        21b4  BCM2070 Bluetooth 2.1 + EDR
        21b9  BCM2070 Bluetooth 2.1 + EDR
        5802  BCM5880 Secure Applications Processor with fingerprint touch sensor
        5803  BCM5880 Secure Applications Processor with secure keyboard
        5804  BCM5880 Secure Applications Processor with fingerprint swipe sensor
+       5832  BCM5880 Secure Applications Processor Smartcard reader
        6300  Pirelli Remote NDIS Device
        6410  BCM20703A1 Bluetooth 4.1 + LE
        bd11  BCM4320 802.11bg Wireless Adapter
 20a0  Clay Logic
        0006  flirc
        4107  GPF Crypto Stick V1.2
+       4108  Nitrokey Pro
+       4109  Nitrokey Storage
        4123  IKALOGIC SCANALOGIC 2
        414a  MDE SPI Interface
        415a  OpenPilot
        41e5  BlinkStick
        4211  Nitrokey Start
        4223  ATSAMD21 [castAR]
+       4230  Nitrokey HSM
+       4287  Nitrokey FIDO U2F
        428d  Electrosense wideband converter
+       42b1  Nitrokey FIDO2
+       42b2  Nitrokey 3A Mini/3A NFC/3C NFC
+       42b4  Nitrokey Pro Bootloader
+       42da  MuteMe
+       42dd  Nitrokey 3A NFC Bootloader/3C NFC Bootloader
+       42e8  Nitrokey 3A Mini Bootloader
+       42ec  RP2040 [PicoWifi]
 20b1  XMOS Ltd
        10ad  XUSB Loader
        f7d1  XTAG2 - JTAG Adapter
 2581  Plug-up
        1807  Generic HID Smartcard
        1808  WinUSB Smartcard
-       f1d0  FIDO U2F Security Key
+       f1d0  Nitrokey U2F
 258d  Sequans Communications
 259a  TriQuint Semiconductor
 25a7  Areson Technology Corp
index 0113d1b6bb259dc5b7446a78c7590df503011182..58a285c83359e2590e5d63880289348a70cb350d 100644 (file)
       <term><varname>$SYSTEMD_LOG_LEVEL</varname></term>
 
       <listitem><para id='log-level-body'>The maximum log level of emitted messages (messages with a higher
-      log level, i.e. less important ones, will be suppressed). Either one of (in order of decreasing
-      importance) <constant>emerg</constant>, <constant>alert</constant>, <constant>crit</constant>,
-      <constant>err</constant>, <constant>warning</constant>, <constant>notice</constant>,
-      <constant>info</constant>, <constant>debug</constant>, or an integer in the range 0…7. See
+      log level, i.e. less important ones, will be suppressed). Takes a comma-separated list of values. A
+      value may be either one of (in order of decreasing importance) <constant>emerg</constant>,
+      <constant>alert</constant>, <constant>crit</constant>, <constant>err</constant>,
+      <constant>warning</constant>, <constant>notice</constant>, <constant>info</constant>,
+      <constant>debug</constant>, or an integer in the range 0…7. See
       <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-      for more information.</para>
-      </listitem>
+      for more information. Each value may optionally be prefixed with one of <constant>console</constant>,
+      <constant>syslog</constant>, <constant>kmsg</constant> or <constant>journal</constant> followed by a
+      colon to set the maximum log level for that specific log target (e.g.
+      <constant>SYSTEMD_LOG_LEVEL=debug,console:info</constant> specifies to log at debug level except when
+      logging to the console which should be at info level). Note that the global maximum log level takes
+      priority over any per target maximum log levels.</para></listitem>
     </varlistentry>
 
     <varlistentry id='log-color'>
index 1d92745eb42ad9529f347193f0ebc45b74e0df78..955111fe940a2af40cc7d53ba85b8b8595a33f2c 100644 (file)
 
     <para>For the latter five mechanisms the source for the key material used for unlocking the volume is
     primarily configured in the third field of each <filename>/etc/crypttab</filename> line, but may also
-    configured in <filename>/etc/cryptsetup-keys.d/</filename> and
+    be configured in <filename>/etc/cryptsetup-keys.d/</filename> and
     <filename>/run/cryptsetup-keys.d/</filename> (see above) or in the LUKS2 JSON token header (in case of
     the latter three). Use the
     <citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     is acquired by connecting to the socket and reading the key from the connection. The connection is made
     from an <constant>AF_UNIX</constant> socket name in the abstract namespace, see <citerefentry
     project='man-pages'><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
-    details. The source socket name is chosen according the following format:</para>
+    details. The source socket name is chosen according to the following format:</para>
 
     <programlisting><constant>NUL</constant> <replaceable>RANDOM</replaceable> /cryptsetup/ <replaceable>VOLUME</replaceable></programlisting>
 
index dc51041138bf03cbffe401f7773658b4a45e1a83..42630d2782573d8c5e8d7628164b8b2a375d39f5 100644 (file)
         <listitem><para>If the service opens sockets or other files on it own, and those file descriptors
         shall survive a restart, the daemon should store them in the service manager via
         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> with
-        <varname>FDSTORE=1</varname>..</para></listitem>
+        <varname>FDSTORE=1</varname>.</para></listitem>
 
         <listitem><para>Instead of using the <function>syslog()</function> call to log directly to the system
         syslog service, a new-style daemon may choose to simply log to standard error via
index 1a0535cd4a66089dc9d5aa4bf1394010930e2ee5..f1bade205343244717b0a750679a29fa814bef1c 100644 (file)
         <xi:include href="version-info.xml" xpointer="v245"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--offline</option></term>
+
+        <listitem><para>Do not attempt to update the copy of the user record and blob directory that is embedded inside
+        of the home area. This allows for operation on home areas that are absent, or without needing to authenticate as
+        the user being modified.</para>
+
+        <xi:include href="version-info.xml" xpointer="v256"/></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="host" />
       <xi:include href="user-system-options.xml" xpointer="machine" />
 
index ea517f4ac4e08ecf3ae14f834078396af9dd8dce..7d6820064ec792922fac3999ffc41510ba56e022 100644 (file)
   <refsect1>
     <title>Commands</title>
 
-    <para>The following commands are understood. If none is specified the default is to display journal records.</para>
+    <para>The following commands are understood. If none is specified the default is to display journal records:</para>
 
     <variablelist>
       <varlistentry>
index 8ac3d96086c291af6ebec9313caf2f505e059276..9334f1a596ec82cabcc2c43e279b8da18a0d1ffb 100644 (file)
@@ -112,8 +112,6 @@ node /org/freedesktop/home1 {
                           out h send_fd);
       @org.freedesktop.systemd1.Privileged("true")
       ReleaseHome(in  s user_name);
-      InhibitSuspendHome(in  s user_name,
-                         out h send_fd);
       @org.freedesktop.systemd1.Privileged("true")
       LockAllHomes();
       @org.freedesktop.systemd1.Privileged("true")
@@ -187,8 +185,6 @@ node /org/freedesktop/home1 {
 
     <variablelist class="dbus-method" generated="True" extra-ref="ReleaseHome()"/>
 
-    <variablelist class="dbus-method" generated="True" extra-ref="InhibitSuspendHome()"/>
-
     <variablelist class="dbus-method" generated="True" extra-ref="LockAllHomes()"/>
 
     <variablelist class="dbus-method" generated="True" extra-ref="DeactivateAllHomes()"/>
@@ -208,7 +204,9 @@ node /org/freedesktop/home1 {
       the numeric UID and GID, the real name, home directory and shell. In addition it returns a state
       identifier describing the state the user's home directory is in, as well as a bus path referring to the
       bus object encapsulating the user record and home directory. This object implements the
-      <classname>org.freedesktop.home1.Home</classname> interface documented below.</para>
+      <classname>org.freedesktop.home1.Home</classname> interface documented below. This method, and most others
+      in this interface that take user names, will try to use the caller's home area if the specified user name is
+      an empty string.</para>
 
       <para><function>GetHomeByUID()</function> is similar to <function>GetHomeByName()</function> but
       acquires the information based on the numeric UID of the user.</para>
@@ -322,10 +320,10 @@ node /org/freedesktop/home1 {
       interface.</para>
 
       <para><function>UpdateHome()</function> updates a locally registered user record. Takes a fully
-      specified JSON user record as argument (including the <literal>secret</literal> section). A user with a
-      matching name and realm must be registered locally already, and the last change timestamp of the newly
-      supplied record must be newer than the previously existing user record. Note this operation updates the
-      user record only, it does not propagate passwords/authentication tokens from the user record to the
+      specified JSON user record as argument (possibly including the <literal>secret</literal> section). A user
+      with a matching name and realm must be registered locally already, and the last change timestamp of the
+      newly supplied record must be newer than the previously existing user record. Note this operation updates
+      the user record only, it does not propagate passwords/authentication tokens from the user record to the
       storage back-end, or resizes the storage back-end. Typically a home directory is first updated, and then
       the password of the underlying storage updated using <function>ChangePasswordHome()</function> as well
       as the storage resized using <function>ResizeHome()</function>. This method is equivalent to
@@ -336,17 +334,24 @@ node /org/freedesktop/home1 {
       Directories</ulink> for more info). The <varname>blobs</varname> argument works in the same way as
       <function>CreateHomeEx()</function>, so check there for details. The new blob directory contents passed into
       this method will completely replace the user's existing blob directory. The <varname>flags</varname> argument
-      may be used for future expansion, but for now pass 0. This method is equivalent to <function>UpdateEx()</function>
-      on the <classname>org.freedesktop.home1.Home</classname> interface.</para>
+      can be used to further customize the behavior of this method via flags defined as follows:</para>
+      <programlisting>
+#define SD_HOMED_UPDATE_OFFLINE (UINT64_C(1) &lt;&lt; 0)
+      </programlisting>
+      <para>When <constant>SD_HOMED_UPDATE_OFFLINE</constant> (0x01) is set, no attempt is made to update the copies
+      of the user record and blob directory that are embedded into the home directory. Changes will be stored, however,
+      and may be propagated into the home directory the next time it is reconciled (most likely when the user next logs in).
+      Note that any changes made with this flag set may be lost if the home area has a newer record, which can happen
+      if the home area is updated on another machine after this method call. This method is equivalent to
+      <function>UpdateEx()</function> on the <classname>org.freedesktop.home1.Home</classname> interface.</para>
 
       <para><function>ResizeHome()</function> resizes the storage associated with a user record. Takes a user
-      name, a disk size in bytes and a user record consisting only of the <literal>secret</literal> section
-      as argument. If the size is specified as <constant>UINT64_MAX</constant> the storage is resized to the
-      size already specified in the user record. Typically, if the user record is updated using
+      name, a disk size in bytes, and optionally a user record consisting only of the <literal>secret</literal>
+      section as arguments. If the size is specified as <constant>UINT64_MAX</constant> the storage is resized to
+      the size already specified in the user record. Typically, if the user record is updated using
       <function>UpdateHome()</function> above this is used to propagate the size configured there-in down to
-      the underlying storage back-end. This method is equivalent to
-      <function>Resize()</function> on the <classname>org.freedesktop.home1.Home</classname>
-      interface.</para>
+      the underlying storage back-end. This method is equivalent to <function>Resize()</function> on the
+      <classname>org.freedesktop.home1.Home</classname> interface.</para>
 
       <para><function>ChangePasswordHome()</function> changes the passwords/authentication tokens of a home
       directory. Takes a user name, and two JSON user record objects, each consisting only of the
@@ -387,10 +392,9 @@ node /org/freedesktop/home1 {
       re-authenticate when the system comes back from suspending. It should be set by all clients that
       implement a secure lock screen running outside of the user's context, that is brought up when the
       system comes back from suspend and can be used to re-acquire the credentials to unlock the user's home
-      directory. A home directory is locked automatically at system suspend only if all clients with open
-      references to the home directory specify that they support this functionality, and no client has
-      temporarily inhibited it (see <function>InhibitSuspendHome()</function> below); otherwise the directory
-      remains unlocked. This method is equivalent to <function>Acquire()</function> on the
+      directory. If a home directory has at least one client with an open reference to the home directory
+      that does not support this it is not suspended automatically at system suspend, otherwise it is. This
+      method is equivalent to <function>Acquire()</function> on the
       <classname>org.freedesktop.home1.Home</classname> interface.</para>
 
       <para><function>RefHome()</function> is similar to <function>AcquireHome()</function> but takes no user
@@ -412,25 +416,9 @@ node /org/freedesktop/home1 {
       triggered deactivation is completed. This method is equivalent to <function>Release()</function> on the
       <classname>org.freedesktop.home1.Home</classname> interface.</para>
 
-      <para><function>InhibitSuspendHome()</function> temporarily inhibits automatic locking during system
-      suspend for a home directory. It returns a file descriptor that inhibits this functionality for as long
-      as it is open. As mentioned above, locking a home directory requires a secure lock screen running
-      outside of the user context, and is likely to freeze any process that attempts to access the directory.
-      Thus, locking a home directory is a trade-off: it increases security, but prevents the client from
-      displaying any user content on its secure lock screen, including notifications, media controls, contact
-      information for incoming phone calls, and much more. A client may use this method to implement more
-      complicated automatic locking behavior for home directories, in order to solve some of these UX issues.
-      For instance, the client may choose to only lock the home directory and switch to the secure lock screen
-      if the device has been suspended for over 24 hours. Note that this inhibitor does not prevent clients from
-      calling <function>LockHome()</function>, and in fact clients will need to call <function>LockHome()</function>
-      manually as part of their custom behavior to lock the home directory. Clients should take care to ensure that
-      the file descriptor is closed in the event that their custom behavior fails or is disabled. This method is
-      equivalent to <function>InhibitSuspend()</function> on the <classname>org.freedesktop.home1.Home</classname>
-      interface.</para>
-
       <para><function>LockAllHomes()</function> locks all active home directories that only have references
-      that opted into automatic locking during system suspend and have no clients inhibiting this behavior.
-      This is usually invoked automatically shortly before system suspend.</para>
+      that opted into automatic suspending during system suspend. This is usually invoked automatically
+      shortly before system suspend.</para>
 
       <para><function>DeactivateAllHomes()</function> deactivates all home areas that are currently
       active. This is usually invoked automatically shortly before system shutdown.</para>
@@ -492,7 +480,6 @@ node /org/freedesktop/home1/home {
                       out h send_fd);
       @org.freedesktop.systemd1.Privileged("true")
       Release();
-      InhibitSuspend(out h send_fd);
     properties:
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s UserName = '...';
@@ -556,8 +543,6 @@ node /org/freedesktop/home1/home {
 
     <variablelist class="dbus-method" generated="True" extra-ref="Release()"/>
 
-    <variablelist class="dbus-method" generated="True" extra-ref="InhibitSuspend()"/>
-
     <variablelist class="dbus-property" generated="True" extra-ref="UserName"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="UID"/>
@@ -579,14 +564,15 @@ node /org/freedesktop/home1/home {
       <function>Update()</function>, <function>UpdateEx()</function>, <function>Resize()</function>,
       <function>ChangePassword()</function>, <function>Lock()</function>, <function>Unlock()</function>,
       <function>Acquire()</function>, <function>Ref()</function>, <function>RefUnrestricted()</function>,
-      <function>Release()</function>, <function>InhibitSuspend()</function> operate like their matching counterparts
-      on the <classname>org.freedesktop.home1.Manager</classname> interface (see above). The main difference is that
-      they are methods of the home directory objects, and hence carry no additional user name
-      parameter. Which of the two flavors of methods to call depends on the handles to the user known on the
-      client side: if only the user name is known, it's preferable to use the methods on the manager object
-      since they operate with user names only. If however the home object path was already acquired some way
-      it is preferable to operate on the <classname>org.freedesktop.home1.Home</classname> objects
-      instead.</para>
+      <function>Release()</function>,
+      operate like their matching counterparts on the <classname>org.freedesktop.home1.Manager</classname>
+      interface (see above). The main difference is that they are methods of the home directory objects, and
+      hence carry no additional user name parameter. Which of the two flavors of methods to call depends on
+      the handles to the user known on the client side: if only the user name is known, it's preferable to use
+      the methods on the manager object since they operate with user names only. Clients can also easily operate
+      on their own home area by using the methods on the manager object with an empty string as the user name.
+      If the client has the home's object path already acquired in some way, however, it is preferable to operate
+      on the <classname>org.freedesktop.home1.Home</classname> objects instead.</para>
     </refsect2>
 
     <refsect2>
@@ -611,12 +597,12 @@ node /org/freedesktop/home1/home {
     <title>History</title>
     <refsect2>
       <title>The Manager Object</title>
-      <para><function>InhibitSuspendHome()</function>, <function>ActivateHomeIfReferenced()</function>, <function>RefHomeUnrestricted()</function>,
+      <para><function>ActivateHomeIfReferenced()</function>, <function>RefHomeUnrestricted()</function>,
       <function>CreateHomeEx()</function>, and <function>UpdateHomeEx()</function> were added in version 256.</para>
     </refsect2>
     <refsect2>
       <title>Home Objects</title>
-      <para><function>InhibitSuspend()</function>, <function>ActivateIfReferenced()</function>, <function>RefUnrestricted()</function>, and
+      <para><function>ActivateIfReferenced()</function>, <function>RefUnrestricted()</function>, and
       <function>UpdateEx()</function> were added in version 256.</para>
     </refsect2>
   </refsect1>
index 5223131368fed17cbfc0e6a075165748ad62a74f..9651112f9780950b2126fdee4736b34d5df35398 100644 (file)
         multiple times, in which case the order in which images are laid down follows the rules specified in
         <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for the <varname>ExtensionImages=</varname> directive and for the
-        <citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry> and.
+        <citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry> and
         <citerefentry><refentrytitle>systemd-confext</refentrytitle><manvolnum>8</manvolnum></citerefentry> tools.
         The images must contain an <filename>extension-release</filename> file with metadata that matches
         what is defined in the <filename>os-release</filename> of <replaceable>IMAGE</replaceable>. See:
index 50a2de7c33d6500901e539ebe17f1dcaa507e179..fb32e2dc46924bcd95f04d60f716cde408856941 100644 (file)
 
         <para>The file specified here must have a size that is a multiple of the basic block size 512 and not
         be empty. If this option is used, the size allocation algorithm is slightly altered: the partition is
-        created as least as big as required to fit the data in, i.e. the data size is an additional minimum
+        created at least as big as required to fit the data in, i.e. the data size is an additional minimum
         size value taken into consideration for the allocation algorithm, similar to and in addition to the
         <varname>SizeMin=</varname> value configured above.</para>
 
         <literal>squashfs</literal> or the special value <literal>swap</literal>. If specified and the partition
         is newly created it is formatted with the specified file system (or as swap device). The file system
         UUID and label are automatically derived from the partition UUID and label. If this option is used,
-        the size allocation algorithm is slightly altered: the partition is created as least as big as
+        the size allocation algorithm is slightly altered: the partition is created at least as big as
         required for the minimal file system of the specified type (or 4KiB if the minimal size is not
         known).</para>
 
index 465ea4e4b3ece15cf278a337f50607efd8e620b1..38a0749fc75276df59a798671ec9fcea6cabc18b 100644 (file)
@@ -75,6 +75,7 @@ manpages = [
  ['repart.d', '5', [], 'ENABLE_REPART'],
  ['resolvectl', '1', ['resolvconf'], 'ENABLE_RESOLVE'],
  ['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVE'],
+ ['run0', '1', [], ''],
  ['runlevel', '8', [], 'HAVE_SYSV_COMPAT'],
  ['sd-bus-errors',
   '3',
@@ -1265,7 +1266,6 @@ manpages = [
   ''],
  ['udev_new', '3', ['udev_ref', 'udev_unref'], ''],
  ['udevadm', '8', [], ''],
- ['uid0', '1', [], ''],
  ['ukify', '1', [], 'ENABLE_UKIFY'],
  ['user@.service',
   '5',
similarity index 93%
rename from man/uid0.xml
rename to man/run0.xml
index f0bfa40b9d95c347c01d5ea5138f6e66f634dee5..09e5620cce5a39f8b79a968b32e67eeae130fb2f 100644 (file)
@@ -3,27 +3,27 @@
   "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
 <!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
 
-<refentry id="uid0"
+<refentry id="run0"
           xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
-    <title>uid0</title>
+    <title>run0</title>
     <productname>systemd</productname>
   </refentryinfo>
 
   <refmeta>
-    <refentrytitle>uid0</refentrytitle>
+    <refentrytitle>run0</refentrytitle>
     <manvolnum>1</manvolnum>
   </refmeta>
 
   <refnamediv>
-    <refname>uid0</refname>
+    <refname>run0</refname>
     <refpurpose>Elevate privileges</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
     <cmdsynopsis>
-      <command>uid0</command>
+      <command>run0</command>
       <arg choice="opt" rep="repeat">OPTIONS</arg>
       <arg choice="opt" rep="repeat">COMMAND</arg>
     </cmdsynopsis>
@@ -32,7 +32,7 @@
   <refsect1>
     <title>Description</title>
 
-    <para><command>uid0</command> may be used to temporarily and interactively acquire elevated or different
+    <para><command>run0</command> may be used to temporarily and interactively acquire elevated or different
     privileges. It serves a similar purpose as <citerefentry
     project='man-pages'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry>, but
     operates differently in a couple of key areas:</para>
     setting the <varname>NoNewPrivileges=</varname> variable in
     <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).</para>
 
-    <para>Any session invoked via <command>uid0</command> will run through the
-    <literal>systemd-uid0</literal> PAM stack.</para>
+    <para>Any session invoked via <command>run0</command> will run through the
+    <literal>systemd-run0</literal> PAM stack.</para>
 
-    <para>Note that <command>uid0</command> is implemented as an alternative multi-call invocation of
+    <para>Note that <command>run0</command> is implemented as an alternative multi-call invocation of
     <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
   </refsect1>
 
         <term><option>--slice-inherit</option></term>
 
         <listitem><para>Make the new <filename>.service</filename> unit part of the slice the
-        <command>uid0</command> itself has been invoked in. This option may be combined with
+        <command>run0</command> itself has been invoked in. This option may be combined with
         <option>--slice=</option>, in which case the slice specified via <option>--slice=</option> is placed
-        within the slice the <command>uid0</command> command is invoked in.</para>
+        within the slice the <command>run0</command> command is invoked in.</para>
 
-        <para>Example: consider <command>uid0</command> being invoked in the slice
+        <para>Example: consider <command>run0</command> being invoked in the slice
         <filename>foo.slice</filename>, and the <option>--slice=</option> argument is
         <filename>bar</filename>. The unit will then be placed under
         <filename>foo-bar.slice</filename>.</para>
   <refsect1>
     <title>Exit status</title>
 
-    <para>On success, 0 is returned. If <command>uid0</command> failed to start the session or the specified command fails, a
+    <para>On success, 0 is returned. If <command>run0</command> failed to start the session or the specified command fails, a
     non-zero return value will be returned.</para>
   </refsect1>
 
index d8fe6468a29cc8040acfbad6efb45e3ec6448ec5..1e611fe6d86e0cf37872720070e54209c6c899b6 100644 (file)
     <constant>AF_VSOCK</constant> address, which is useful for hypervisors/VMMs or other processes on the
     host to receive a notification when a virtual machine has finished booting. Note that in case the
     hypervisor does not support <constant>SOCK_DGRAM</constant> over <constant>AF_VSOCK</constant>,
-    <constant>SOCK_SEQPACKET</constant> will be used instead. The address should be in the form:
-    <literal>vsock:CID:PORT</literal>. Note that unlike other uses of vsock, the CID is mandatory and cannot
-    be <literal>VMADDR_CID_ANY</literal>.  Note that PID1 will send the VSOCK packets from a privileged port
-    (i.e.: lower than 1024), as an attempt to address concerns that unprivileged processes in the guest might
-    try to send malicious notifications to the host, driving it to make destructive decisions based on
-    them.</para>
+    <constant>SOCK_SEQPACKET</constant> will be used instead. <literal>vsock-stream</literal>,
+    <literal>vsock-dgram</literal> and <literal>vsock-seqpacket</literal> can be used instead of
+    <literal>vsock</literal> to force usage of the corresponding socket type. The address should be in the
+    form: <literal>vsock:CID:PORT</literal>. Note that unlike other uses of vsock, the CID is mandatory and
+    cannot be <literal>VMADDR_CID_ANY</literal>.  Note that PID1 will send the VSOCK packets from a
+    privileged port (i.e.: lower than 1024), as an attempt to address concerns that unprivileged processes in
+    the guest might try to send malicious notifications to the host, driving it to make destructive decisions
+    based on them.</para>
   </refsect1>
 
   <refsect1>
index 639a7231cb21eff922333ad00a190fa38ef8c5d6..ca108c5cf9d35f00c45d13764266e18d17d985e1 100644 (file)
@@ -1018,16 +1018,12 @@ x86-64      native</programlisting>
         <term><option>--order</option></term>
         <term><option>--require</option></term>
 
-        <listitem><para>When used in conjunction with the
-        <command>dot</command> command (see above), selects which
-        dependencies are shown in the dependency graph. If
-        <option>--order</option> is passed, only dependencies of type
-        <varname>After=</varname> or <varname>Before=</varname> are
-        shown. If <option>--require</option> is passed, only
-        dependencies of type <varname>Requires=</varname>,
-        <varname>Requisite=</varname>,
-        <varname>Wants=</varname> and <varname>Conflicts=</varname>
-        are shown. If neither is passed, this shows dependencies of
+        <listitem><para>When used in conjunction with the <command>dot</command> command (see above),
+        selects which dependencies are shown in the dependency graph. If <option>--order</option> is passed,
+        only dependencies of type <varname>After=</varname> or <varname>Before=</varname> are shown.
+        If <option>--require</option> is passed, only dependencies of type <varname>Requires=</varname>,
+        <varname>Requisite=</varname>, <varname>BindsTo=</varname>, <varname>Wants=</varname>, and
+        <varname>Conflicts=</varname> are shown. If neither is passed, this shows dependencies of
         all these types.</para>
 
         <xi:include href="version-info.xml" xpointer="v198"/></listitem>
index a4d1c003e0af192e22b8fe2440a239a9699c9b7f..cc4504926c85982e9fb0f26d769c78b51c4320d4 100644 (file)
     similar, to extend the native firmware support.</para>
 
     <para>Enrollment of Secure Boot variables can be performed manually or automatically if files are available
-    under <filename>/loader/keys/<replaceable>NAME</replaceable>/{db,KEK,PK}.auth</filename>, <replaceable>NAME</replaceable>
+    under <filename>/loader/keys/<replaceable>NAME</replaceable>/{db,dbx,KEK,PK}.auth</filename>, <replaceable>NAME</replaceable>
     being the display name for the set of variables in the menu. If one of the sets is named <filename>auto</filename>
     then it might be enrolled automatically depending on whether <literal>secure-boot-enroll</literal> is set
     to force or not.</para>
index 12667844853d6d9ce1e99b1756c476d05b5c81b1..e58d64c52ba699152ab23076937f8987bb5c439a 100644 (file)
@@ -19,7 +19,7 @@
   <refnamediv>
     <refname>systemd-bsod.service</refname>
     <refname>systemd-bsod</refname>
-    <refpurpose>Displays boot-time emergency log message in full screen.</refpurpose>
+    <refpurpose>Displays boot-time emergency log message in full screen</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
index 72dc56390ff17372a5ebbd0f5cb358e005a19c4b..4c139c5b45b60f316ba9a0c40bb9dd9626ba4fb1 100644 (file)
@@ -52,7 +52,7 @@
     <para><filename>systemd-cryptsetup</filename> is used to set up (with <command>attach</command>) and tear
     down (with <command>detach</command>) access to an encrypted block device. It is primarily used via
     <filename>systemd-cryptsetup@.service</filename> during early boot, but may also be be called manually.
-    The positional arguments <parameter>VOLUME</parameter>, <parameter>SOURCEDEVICE</parameter>,
+    The positional arguments <parameter>VOLUME</parameter>, <parameter>SOURCE-DEVICE</parameter>,
     <parameter>KEY-FILE</parameter>, and <parameter>CRYPTTAB-OPTIONS</parameter> have the same meaning as the
     fields in <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
     </para>
index 8f7e6d103d22dbba0b7c84d35189224f88f8b745..4b9c252784f8c13f4f0bdc873965e23d47561293 100644 (file)
@@ -1754,7 +1754,7 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
           <para>In order to embed binary data into the credential data for <option>--set-credential=</option>,
           use C-style escaping (i.e. <literal>\n</literal> to embed a newline, or <literal>\x00</literal> to
           embed a <constant>NUL</constant> byte). Note that the invoking shell might already apply unescaping
-          once, hence this might require double escaping!.</para>
+          once, hence this might require double escaping!</para>
 
           <para>The
           <citerefentry><refentrytitle>systemd-sysusers.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
index 58907f728c54f985c2a8e64dd9bc5e0941ed8788..2c674a34b4c0a94c4d8fe54853e33c5d794a510c 100644 (file)
 
         <listitem><para>Generates/removes a <filename>.pcrlock</filename> file based on raw binary data. The
         data is either read from the specified file or from STDIN (if none is specified). This requires that
-        <option>--pcrs=</option> is specified. The generated pcrlock file is written to the file specified
+        <option>--pcrs=</option> is specified. The generated .pcrlock file is written to the file specified
         via <option>--pcrlock=</option> or to STDOUT (if none is specified).</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/>
       <varlistentry>
         <term><option>--nv-index=</option></term>
 
-        <listitem><para>Specifies to NV index to store the policy in. Honoured by
+        <listitem><para>Specifies the NV index to store the policy in. Honoured by
         <command>make-policy</command>. If not specified the command will automatically pick a free NV
         index.</para>
 
index 786bb6bf1323b8ed325107b55fd9ababfbfc5439..ec7ffdeb0d362d365bf9e696119deddb95e7b251 100644 (file)
@@ -60,7 +60,7 @@
     <literal>kexec</literal>, depending on the chosen action. All executables in this directory are executed
     in parallel, and execution of the action is not continued before all executables finished. Note that
     these executables are run <emphasis>after</emphasis> all services have been shut down, and after most
-    mounts have been detached (the root file system as well as <filename>/run/</filename> and various API
+    mounts have been unmounted (the root file system as well as <filename>/run/</filename> and various API
     file systems are still around though). This means any programs dropped into this directory must be
     prepared to run in such a limited execution environment and not rely on external services or hierarchies
     such as <filename>/var/</filename> to be around (or writable).</para>
index 7e2730a33a2baf0fde1f76bea802bc6ef19665e9..e719bd9687f66df088b3e24ef1b86f2493a6972b 100644 (file)
       <title>Generate a configuration extension image</title>
 
       <para>The following creates a configuration extension DDI (confext) for an
-      <filename>/etc/motd</filename> update.</para>
+      <filename>/etc/motd</filename> update:</para>
 
       <programlisting>mkdir tree tree/etc tree/etc/extension-release.d
 echo "Hello World" > tree/etc/motd
index e891920c630e57b90d13741fe9405c811d832149..c6fd4ac20c137fd5dad6471e7d636b82f1ca7649 100644 (file)
@@ -706,7 +706,7 @@ $ systemd-run --user --wait -p SuccessExitStatus=SIGUSR1 --expand-environment=no
       <member><citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemd-mount</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
-      <member><citerefentry><refentrytitle>uid0</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
+      <member><citerefentry><refentrytitle>run0</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
     </simplelist></para>
   </refsect1>
 
index 354a24679a246943fcef23f4e77500bf4a2961d4..26717e4259270f53d841e987006598602462b53b 100644 (file)
       via <varname>SurviveFinalKillSignal=yes</varname>, and also be configured to avoid being stopped on
       isolate via <varname>IgnoreOnIsolate=yes</varname>. They also have to be configured to be stopped on
       normal shutdown, reboot and maintenance mode. Finally, they have to be ordered after
-      <constant>basic.target</constant> to ensure correct ordeering on boot. Note that in case any new or
+      <constant>basic.target</constant> to ensure correct ordering on boot. Note that in case any new or
       custom units are used to isolate to, or that implement an equivalent shutdown functionality, they will
       also have to be configured manually for correct ordering and conflicting. For example:</para>
 
index 84e91dd47a06a41eefdf98bdcc9714353e4941b6..6fdbc3dc056c6b4384085a31d486871388581f70 100644 (file)
@@ -69,7 +69,7 @@
         exposed NVMe-TCP mass storage devices. The NQN should follow the syntax described in <ulink
         url="https://nvmexpress.org/wp-content/uploads/NVM-Express-Base-Specification-2.0c-2022.10.04-Ratified.pdf">NVM
         Express Base Specification 2.0c</ulink>, section 4.5 "NVMe Qualified Names". Note that the NQN
-        specified here will be suffixed with a dot and the the block device name before it is exposed on the
+        specified here will be suffixed with a dot and the block device name before it is exposed on the
         NVMe target. If not specified defaults to
         <literal>nqn.2023-10.io.systemd:storagetm.<replaceable>ID</replaceable></literal>, where ID is
         replaced by a 128bit ID derived from
index 8e5a6a6aa1bf2c3af534147aa952dfeb22912edb..df1f10aeefb487a63ee6e7da3834f15aaf62230e 100644 (file)
     but the used architecture identifiers are the same as for <varname>ConditionArchitecture=</varname>
     described in <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
     <varname>EXTENSION_RELOAD_MANAGER=</varname> can be set to 1 if the extension requires a service manager reload after application
-    of the extension. Note that the for the reasons mentioned earlier:
+    of the extension. Note that for the reasons mentioned earlier:
     <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> remain
     the recommended way to ship system services.
 
index 245d3444b1a8b7c096e4d6b69ffa9616fcc57c62..3fa3490995470fe7a4bd1f6b71856987d183105c 100644 (file)
@@ -37,7 +37,7 @@
 
     <para>The services will store the public key of the SRK key pair in a PEM file in
     <filename>/run/systemd/tpm2-srk-public-key.pem</filename> and
-    <filename>/var/lib/systemd/tpm2-srk-public-key.pem</filename>. It will also store it in TPM2B_PUBLIC
+    <filename>/var/lib/systemd/tpm2-srk-public-key.pem</filename>. They will also store it in TPM2B_PUBLIC
     format in <filename>/run/systemd/tpm2-srk-public-key.tpm2_public</filename> and
     <filename>/var/lib/systemd/tpm2-srk-public-key.tpm2b_public</filename>.</para>
 
index ef4d3ca2b629736570093875d95a57ae27079cb8..90ddc9b6740ba3afde539932cd1eb0bd5cf660cd 100644 (file)
@@ -18,7 +18,7 @@
 
   <refnamediv>
     <refname>systemd-vmspawn</refname>
-    <refpurpose>Spawn an OS in a virtual machine.</refpurpose>
+    <refpurpose>Spawn an OS in a virtual machine</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
           <xi:include href="version-info.xml" xpointer="v256"/>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><option>--pass-ssh-key=</option><replaceable>BOOL</replaceable></term>
+
+          <listitem><para>By default an SSH key is generated to allow <command>systemd-vmspawn</command> to open
+          a D-Bus connection to the VM's systemd bus. Setting this to "no" will disable SSH key generation.</para>
+
+          <para>The generated keys are ephemeral. That is they are valid only for the current invocation of <command>systemd-vmspawn</command>,
+          and are typically not persisted.</para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><option>--ssh-key-type=</option><replaceable>TYPE</replaceable></term>
+
+          <listitem><para>Configures the type of SSH key to generate, see
+          <citerefentry><refentrytitle>ssh-keygen</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+          for more information.</para>
+
+          <para>By default <literal>ed25519</literal> keys are generated, however <literal>rsa</literal> keys
+          may also be useful if the VM has a particularly old version of <command>sshd</command></para>.
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+          </listitem>
+        </varlistentry>
       </variablelist>
     </refsect2>
 
           <para>In order to embed binary data into the credential data for <option>--set-credential=</option>,
           use C-style escaping (i.e. <literal>\n</literal> to embed a newline, or <literal>\x00</literal> to
           embed a <constant>NUL</constant> byte). Note that the invoking shell might already apply unescaping
-          once, hence this might require double escaping!.</para>
+          once, hence this might require double escaping!</para>
 
           <xi:include href="version-info.xml" xpointer="v255"/></listitem>
         </varlistentry>
index 472add2f98407329b755969fffd59ffec5b8d87c..e143aebb1bd39a59c384b074c602d9bf1768da89 100644 (file)
@@ -857,7 +857,7 @@ Table=1234</programlisting></para>
           <literal>ipv4</literal>, <literal>ipv6</literal>, <literal>both</literal>, or
           <literal>no</literal>. Defaults to <literal>no</literal>.</para>
           <para>Note. Any positive boolean values such as <literal>yes</literal> or
-          <literal>true</literal> are now deprecated. Please use one of the values in the above.</para>
+          <literal>true</literal> are now deprecated. Please use one of the values above.</para>
 
           <xi:include href="version-info.xml" xpointer="v219"/>
         </listitem>
@@ -3611,7 +3611,7 @@ Address=192.168.0.1/24
 Address=192.168.0.2/24
 [DHCPServer]
 ServerAddress=192.168.0.1/24</programlisting>
-          are equivalent to the following.
+          are equivalent to the following:
           <programlisting>[Network]
 DHCPServer=yes
 Address=192.168.0.2/24
@@ -3973,7 +3973,7 @@ ServerAddress=192.168.0.1/24</programlisting>
 
         <listitem><para>Takes a timespan. Configures the retransmit time, used by clients to retransmit Neighbor
         Solicitation messages on address resolution and the Neighbor Unreachability Detection algorithm.
-        An integer the default unit of seconds, in the range 0…4294967295 msec. Defaults to 0.</para>
+        An integer, the default unit is seconds, in the range 0…4294967295 msec. Defaults to 0.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/>
         </listitem>
@@ -4062,8 +4062,8 @@ ServerAddress=192.168.0.1/24</programlisting>
       <varlistentry>
         <term><varname>HomeAgent=</varname></term>
 
-        <listitem><para>Takes a boolean. Specifies that IPv6 router advertisements which indicates to hosts that
-        the router acts as a Home Agent and includes a Home Agent Option. Defaults to false. See
+        <listitem><para>Takes a boolean. Specifies that IPv6 router advertisements which indicate to hosts that
+        the router acts as a Home Agent and includes a Home Agent option. Defaults to false. See
         <ulink url="https://tools.ietf.org/html/rfc6275">RFC 6275</ulink> for further details.</para>
 
          <xi:include href="version-info.xml" xpointer="v255"/>
@@ -4073,7 +4073,7 @@ ServerAddress=192.168.0.1/24</programlisting>
       <varlistentry>
         <term><varname>HomeAgentLifetimeSec=</varname></term>
 
-        <listitem><para>Takes a timespan. Specifies the lifetime of the Home Agent. An integer the default unit of seconds,
+        <listitem><para>Takes a timespan. Specifies the lifetime of the Home Agent. An integer, the default unit is seconds,
         in the range 1…65535. Defaults to the value set to <varname>RouterLifetimeSec=</varname>.</para>
 
          <xi:include href="version-info.xml" xpointer="v255"/>
index 7655f2edfe12f10621b282cb9c27c18ad1833652..27ceb48652f4a61f25a1271f6e21646e51a16e3a 100644 (file)
@@ -95,7 +95,7 @@
         <term><filename>250-firmware-code-early.pcrlock</filename></term>
 
         <listitem><para>Firmware code measurements, as recorded to PCR 0 and 2, up to the separator
-        measurement (see <filename>400-secureboot-separator.pcrlock.</filename> below). May be generated via
+        measurement (see <filename>400-secureboot-separator.pcrlock</filename> below). May be generated via
         <command>systemd-pcrlock lock-firmware-code</command>.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
         <term><filename>250-firmware-config-early.pcrlock</filename></term>
 
         <listitem><para>Firmware configuration measurements, as recorded to PCR 1 and 3, up to the separator
-        measurement (see <filename>400-secureboot-separator.pcrlock.</filename> below). May be generated via
+        measurement (see <filename>400-secureboot-separator.pcrlock</filename> below). May be generated via
         <command>systemd-pcrlock lock-firmware-config</command>.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
         <term><filename>550-firmware-code-late.pcrlock</filename></term>
 
         <listitem><para>Firmware code measurements, as recorded to PCR 0 and 2, after the separator
-        measurement (see <filename>400-secureboot-separator.pcrlock.</filename> above). May be generated via
+        measurement (see <filename>400-secureboot-separator.pcrlock</filename> above). May be generated via
         <command>systemd-pcrlock lock-firmware-code</command>.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
         <term><filename>550-firmware-config-late.pcrlock</filename></term>
 
         <listitem><para>Firmware configuration measurements, as recorded to PCR 1 and 3, after the separator
-        measurement (see <filename>400-secureboot-separator.pcrlock.</filename> above). May be generated via
+        measurement (see <filename>400-secureboot-separator.pcrlock</filename> above). May be generated via
         <command>systemd-pcrlock lock-firmware-config</command>.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
         <term><filename>700-action-efi-exit-boot-services.pcrlock</filename></term>
 
         <listitem><para>The EFI action generated when <function>ExitBootServices()</function> is generated,
-        i.e. the UEFI environment is left and the OS takes over. Covers the PCR 5 measurement. Statically
+        i.e. when the UEFI environment is left and the OS takes over. Covers the PCR 5 measurement. Statically
         defined.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
index 1ac97ae137b8bf1cb1ace963d6418b257f19037d..c7166e4f643bd5b082d673bd8b02771f88fa34f5 100644 (file)
         <replaceable>x</replaceable> on a port <replaceable>y</replaceable> address in the
         <constant>AF_VSOCK</constant> family.  The CID is a unique 32-bit integer identifier in
         <constant>AF_VSOCK</constant> analogous to an IP address.  Specifying the CID is optional, and may be
-        set to the empty string.</para>
+        set to the empty string. <literal>vsock</literal> may be replaced with
+        <literal>vsock-stream</literal>, <literal>vsock-dgram</literal> or <literal>vsock-seqpacket</literal>
+        to force usage of the corresponding socket type.</para>
 
         <para>Note that <constant>SOCK_SEQPACKET</constant> (i.e.
         <varname>ListenSequentialPacket=</varname>) is only available
index b66707faba6cc96e5e7b24dc04b5e18ad4a207e3..cb798af34c0ec3b8a5c31c0211d3e6d0a92fde16 100644 (file)
           <constant>SOCK_DGRAM</constant> over <constant>AF_VSOCK</constant>,
           <constant>SOCK_SEQPACKET</constant> will be tried instead. The credential payload for
           <constant>AF_VSOCK</constant> should be a string in the form
-          <literal>vsock:CID:PORT</literal>.</para>
+          <literal>vsock:CID:PORT</literal>. <literal>vsock-stream</literal>, <literal>vsock-dgram</literal>
+          and <literal>vsock-seqpacket</literal> can be used instead of <literal>vsock</literal> to force
+          usage of the corresponding socket type.</para>
 
           <para>This feature is useful for machine managers or other processes on the host to receive a
           notification via VSOCK when a virtual machine has finished booting.</para>
index 646fea0d2479c36e1c0b7457f4a43227aeec1dc4..22add03a9d5a964c0ff6cca4357c737f30116616 100644 (file)
@@ -50,7 +50,7 @@
       <arg choice="plain">call</arg>
       <arg choice="plain"><replaceable>ADDRESS</replaceable></arg>
       <arg choice="plain"><replaceable>METHOD</replaceable></arg>
-      <arg choice="opt"><replaceable>PARAMETERS</replaceable></arg>
+      <arg choice="opt"><replaceable>ARGUMENTS</replaceable></arg>
     </cmdsynopsis>
 
     <cmdsynopsis>
         <term><command>info</command> <replaceable>ADDRESS</replaceable></term>
 
         <listitem><para>Show brief information about the specified service, including vendor name and list of
-        implemented interfaces. Expects a service address in the formats described above.</para>
+        implemented interfaces. Expects a service address in one of the formats described above.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
       </varlistentry>
         <term><command>list-interfaces</command> <replaceable>ADDRESS</replaceable></term>
 
         <listitem><para>Show list of interfaces implemented by the specified service. Expects a service
-        address in the formats described above.</para>
+        address in one of the formats described above.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
       </varlistentry>
         <term><command>introspect</command> <replaceable>ADDRESS</replaceable> <replaceable>INTERFACE</replaceable></term>
 
         <listitem><para>Show interface definition of the specified interface provided by the specified
-        service. Expects a service address in the formats described above and a Varlink interface
+        service. Expects a service address in one of the formats described above and a Varlink interface
         name.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
index 16f7491e0cbc840948b91b4dd59986913168d526..6bd09604b67eaa725c0284aee1bc0336761aed1f 100644 (file)
@@ -125,7 +125,7 @@ This is based on crypttab(5).
       <varlistentry>
         <term><option>uuid=<replaceable>UUID</replaceable></option></term>
 
-        <listitem><para>Use the provided <replaceable>UUID</replaceable> for format command instead of generating new one. The <replaceable>UUID</replaceable> must be
+        <listitem><para>Use the provided <replaceable>UUID</replaceable> instead of generating new one. The <replaceable>UUID</replaceable> must be
         provided in standard <acronym>UUID</acronym> format, e.g. <literal>12345678-1234-1234-1234-123456789abc</literal>.</para>
 
         <xi:include href="version-info.xml" xpointer="v254"/></listitem>
@@ -186,8 +186,8 @@ This is based on crypttab(5).
         <term><option>fec-device=<replaceable>PATH</replaceable></option></term>
 
         <listitem><para>Use forward error correction (<acronym>FEC</acronym>) to recover from corruption if hash verification fails. Use
-        encoding data from the specified device. The fec device argument can be block device or file image. For format,
-        if fec device path doesn't exist, it will be created as file. Note: block sizes for data and hash devices must
+        encoding data from the specified device. The fec device argument can be block device or file image.
+        If fec device path doesn't exist, it will be created as file. Note: block sizes for data and hash devices must
         match. Also, if the verity data_device is encrypted the fec_device should be too.</para>
 
         <xi:include href="version-info.xml" xpointer="v254"/></listitem>
index 0e5f40348483d71a2501cdd702ae50a88e437080..897b39386904a7e75b9dfeef374903b64c64a369 100644 (file)
@@ -738,14 +738,15 @@ if not cc.has_header('sys/capability.h')
         error('POSIX caps headers not found')
 endif
 foreach header : ['crypt.h',
+                  'linux/ioprio.h',
                   'linux/memfd.h',
+                  'linux/time_types.h',
                   'linux/vm_sockets.h',
                   'sys/auxv.h',
+                  'sys/sdt.h',
                   'threads.h',
                   'valgrind/memcheck.h',
                   'valgrind/valgrind.h',
-                  'linux/time_types.h',
-                  'sys/sdt.h',
                  ]
 
         conf.set10('HAVE_' + header.underscorify().to_upper(),
@@ -1250,7 +1251,8 @@ foreach ident : ['crypt_set_metadata_size',
                  'crypt_reencrypt_init_by_passphrase',
                  'crypt_reencrypt',
                  'crypt_set_data_offset',
-                 'crypt_set_keyring_to_link']
+                 'crypt_set_keyring_to_link',
+                 'crypt_resume_by_volume_key']
         have_ident = have and cc.has_function(
                 ident,
                 prefix : '#include <libcryptsetup.h>',
@@ -1563,7 +1565,8 @@ conf.set10('ENABLE_IMPORTD', have)
 have = get_option('homed').require(
         conf.get('HAVE_OPENSSL') == 1 and
         conf.get('HAVE_LIBFDISK') == 1 and
-        conf.get('HAVE_LIBCRYPTSETUP') == 1,
+        conf.get('HAVE_LIBCRYPTSETUP') == 1 and
+        conf.get('HAVE_CRYPT_RESUME_BY_VOLUME_KEY') == 1,
         error_message : 'openssl, fdisk and libcryptsetup required').allowed()
 conf.set10('ENABLE_HOMED', have)
 
@@ -1692,7 +1695,6 @@ if conf.get('BPF_FRAMEWORK') == 1
                 '-std=gnu11',
                 '-fno-stack-protector',
                 '-O2',
-                '-mkernel=5.2',
                 '-mcpu=v3',
                 '-mco-re',
                 '-gbtf',
@@ -1741,7 +1743,7 @@ if conf.get('BPF_FRAMEWORK') == 1
 
         bpf_o_unstripped_cmd += ['-I.']
 
-        if not meson.is_cross_build() and bpf_compiler == 'clang'
+        if not meson.is_cross_build()
                 target_triplet_cmd = run_command('gcc', '-dumpmachine', check: false)
                 if target_triplet_cmd.returncode() == 0
                         target_triplet = target_triplet_cmd.stdout().strip()
@@ -1827,6 +1829,7 @@ conf.set10('ENABLE_UKIFY', want_ukify)
 
 #####################################################################
 
+check_efi_alignment_py = find_program('tools/check-efi-alignment.py')
 check_version_history_py = find_program('tools/check-version-history.py')
 elf2efi_py = find_program('tools/elf2efi.py')
 export_dbus_interfaces_py = find_program('tools/dbus_exporter.py')
index 19a3851fd132650920a2e65b032bd729a5eee77e..a5953d7613639eccf7c34ea3414c97d2f9015836 100644 (file)
@@ -41,3 +41,5 @@ KernelCommandLineExtra=systemd.crash_shell
                        enforcing=0
                        systemd.early_core_pattern=/core
                        systemd.firstboot=no
+                       systemd.setenv=SYSTEMD_ENABLE_LOG_CONTEXT=yes
+                       SYSTEMD_ENABLE_LOG_CONTEXT=yes
index fcefc3ead2bbf106cfd152f2f8a67a0164566178..aed8bb5ba8457901057560ca538493a3430a9edb 100644 (file)
@@ -31,6 +31,7 @@ Packages=
         kexec-tools
         kmod
         less
+        man
         mtools
         nano
         nftables
index aff566f94c24fb409cce0f334bff3b760bd5fda7..1c5f582701863147d26cc1c3eb090cf1879fdbfe 100755 (executable)
@@ -23,7 +23,7 @@ mount --mkdir --rbind "$PWD/pkg/$PKG_SUBDIR" "pkg/$PKG_SUBDIR/src/"
 # tmpfs during the build script so these changes don't end up in the image itself.
 tee --append /etc/makepkg.conf >/dev/null <<EOF
 CFLAGS="$CFLAGS -Og"
-OPTIONS=(!strip docs !libtool !staticlibs emptydirs !zipman purge debug !lto)
+OPTIONS=(!strip docs !libtool !staticlibs emptydirs !zipman purge !debug !lto)
 EOF
 
 # Linting the PKGBUILD takes multiple seconds every build so avoid that by nuking all the linting functions.
@@ -35,6 +35,10 @@ else
     TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
 fi
 
+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")/"
+
 # We get around makepkg's root check by setting EUID to something else.
 # shellcheck disable=SC2046
 env --chdir="pkg/$PKG_SUBDIR" \
@@ -43,11 +47,9 @@ env --chdir="pkg/$PKG_SUBDIR" \
     --noextract \
     $( ((WITH_TESTS)) || echo --nocheck) \
     --force \
-    UPSTREAM=1 \
-    QUIET=1 \
+    _systemd_UPSTREAM=1 \
+    _systemd_QUIET=1 \
     BUILDDIR="$PWD/pkg/$PKG_SUBDIR" \
     PKGDEST="$PACKAGEDIR" \
     PKGEXT=".pkg.tar" \
-    PKGVER="$(cat meson.version)" \
-    PKGREL="$(date "+%Y%m%d%H%M%S" --date "@$TS")" \
     MESON_EXTRA_CONFIGURE_OPTIONS="-D mode=developer -D b_sanitize=${SANITIZERS:-none}"
index 4c80b0a36fd228e11a366d4c6188b27e1c850183..1cc7740194b858b53a2515ff3be1562883f726e0 100644 (file)
@@ -35,6 +35,7 @@ Packages=
         libasan
         libcap-ng-utils
         libubsan
+        man-db
         netcat
         openssh-clients
         openssh-server
index 47f3b7f488b9ebf81bca7ca10ab97b6e5f71766c..07c9b3a805c834552fc8afbc23ef157c53dfa766 100644 (file)
@@ -41,6 +41,7 @@ Packages=
         libcap-ng-utils
         libtss2-rc0
         libtss2-tcti-device0
+        man-db
         netcat-openbsd
         openssh-client
         openssh-server
index 6a60ce83e52c21e02bf84c06ddef30c715bb3352..562bebe08e855c2c960bbafc390c77925a1c1246 100755 (executable)
@@ -6,4 +6,4 @@ set -e
 # See https://github.com/openSUSE/suse-module-tools/pull/71
 rm -f "$BUILDROOT/usr/lib/modprobe.d/60-blacklist_fs-erofs.conf"
 
-mkosi-install systemd udev
+mkosi-install systemd udev systemd-experimental
index 63498c5098ed461633935fff811f9d3c072d17eb..45947a395b5371f2fe138422c74ed849077293ef 100644 (file)
@@ -39,6 +39,7 @@ Packages=
         openssh-clients
         openssh-server
         pam
+        python3-pefile
         quota
         rpm-build
         rsync
index 733045c8f6b0acf2f0cfaac207500483a678f4d2..3b86b9146b84d499789ba924a9dd4ac643d796ab 160000 (submodule)
--- a/pkg/arch
+++ b/pkg/arch
@@ -1 +1 @@
-Subproject commit 733045c8f6b0acf2f0cfaac207500483a678f4d2
+Subproject commit 3b86b9146b84d499789ba924a9dd4ac643d796ab
index 5451923e3e7f5d6cc54f78a8b1d08317a42b4109..1932e19d92daef5928a1402073ad3b5aa6fc0767 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5451923e3e7f5d6cc54f78a8b1d08317a42b4109
+Subproject commit 1932e19d92daef5928a1402073ad3b5aa6fc0767
index 2822a03dded26b9453bddbba7c6a152de8204aec..f1d38667ef013aa832f43ea7b5861efd29b09fee 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2822a03dded26b9453bddbba7c6a152de8204aec
+Subproject commit f1d38667ef013aa832f43ea7b5861efd29b09fee
index 4b4c3fb15e6aaac5afa6898cc1686be5843015c2..864ed0678787abcfe6e88c8cc85c70923cb703e7 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -6,21 +6,21 @@
 # Julien Humbert <julroy67@gmail.com>, 2020, 2021.
 # Arnaud T. <listes.00@gmail.com>, 2021.
 # blutch112 <vincent.lefebvre59@gmail.com>, 2022.
-# Pierre GRASSER <pierre.grasser@proton.me>, 2023.
+# Pierre GRASSER <pierre.grasser@proton.me>, 2023, 2024.
 msgid ""
 msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2024-03-04 10:09+0100\n"
-"PO-Revision-Date: 2023-10-12 16:36+0000\n"
+"PO-Revision-Date: 2024-03-22 10:36+0000\n"
 "Last-Translator: Pierre GRASSER <pierre.grasser@proton.me>\n"
 "Language-Team: French <https://translate.fedoraproject.org/projects/systemd/"
-"master/fr/>\n"
+"main/fr/>\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.0.2\n"
+"X-Generator: Weblate 5.4\n"
 
 #: src/core/org.freedesktop.systemd1.policy.in:22
 msgid "Send passphrase back to system"
@@ -143,26 +143,23 @@ msgstr ""
 
 #: src/home/org.freedesktop.home1.policy:73
 msgid "Inhibit automatic lock of a home area"
-msgstr ""
+msgstr "Empêcher le verrouillage automatique d'un espace personnel"
 
 #: src/home/org.freedesktop.home1.policy:74
-#, fuzzy
 msgid ""
 "Authentication is required to inhibit automatic lock of a user's home area."
 msgstr ""
-"Authentification requise pour mettre à jour l’espace personnel d’un "
-"utilisateur."
+"Authentification requise pour empêcher le verrouillage automatique de "
+"l'espace personnel d'un utilisateur."
 
 #: src/home/org.freedesktop.home1.policy:83
-#, fuzzy
 msgid "Activate a home area"
-msgstr "Créer un espace personnel"
+msgstr "Activer un espace personnel"
 
 #: src/home/org.freedesktop.home1.policy:84
-#, fuzzy
 msgid "Authentication is required to activate a user's home area."
 msgstr ""
-"Authentification requise pour créer l’espace personnel d’un utilisateur."
+"Authentification requise pour activer l’espace personnel d’un utilisateur."
 
 #: src/home/pam_systemd_home.c:293
 #, c-format
@@ -394,52 +391,39 @@ msgid "Authentication is required to get system description."
 msgstr "Authentification requise pour obtenir la description du système."
 
 #: src/import/org.freedesktop.import1.policy:22
-#, fuzzy
 msgid "Import a disk image"
-msgstr "Importer une image de machine virtuelle ou de conteneur"
+msgstr "Importer une image disque"
 
 #: src/import/org.freedesktop.import1.policy:23
-#, fuzzy
 msgid "Authentication is required to import an image"
-msgstr ""
-"Authentification requise pour importer une image de machine virtuelle ou de "
-"conteneur"
+msgstr "Authentification requise pour importer une image"
 
 #: src/import/org.freedesktop.import1.policy:32
-#, fuzzy
 msgid "Export a disk image"
-msgstr "Exporter une image de machine virtuelle ou de conteneur"
+msgstr "Exporter une image disque"
 
 #: src/import/org.freedesktop.import1.policy:33
-#, fuzzy
 msgid "Authentication is required to export disk image"
-msgstr ""
-"Authentification requise pour exporter une image de machine virtuelle ou de "
-"conteneur"
+msgstr "Authentification requise pour exporter une image disque."
 
 #: src/import/org.freedesktop.import1.policy:42
-#, fuzzy
 msgid "Download a disk image"
-msgstr "Télécharger une image de machine virtuelle (VM) ou de conteneur"
+msgstr "Télécharger une image disque"
 
 #: src/import/org.freedesktop.import1.policy:43
-#, fuzzy
 msgid "Authentication is required to download a disk image"
-msgstr ""
-"Authentification requise pour télécharger une image de machine virtuelle ou "
-"de conteneur"
+msgstr "Authentification requise pour télécharger une image disque."
 
 #: src/import/org.freedesktop.import1.policy:52
 msgid "Cancel transfer of a disk image"
-msgstr ""
+msgstr "Annuler le transfert d'une image disque"
 
 #: src/import/org.freedesktop.import1.policy:53
-#, fuzzy
 msgid ""
 "Authentication is required to cancel the ongoing transfer of a disk image"
 msgstr ""
-"Authentification requise pour changer le mot de passe de l’espace personnel "
-"d’un utilisateur."
+"Authentification requise pour annuler le transfert en cours d'une image "
+"disque."
 
 #: src/locale/org.freedesktop.locale1.policy:22
 msgid "Set system locale"
index bf8aa8148fc82ed3db1feade7abd37e9929fe380..9e92d59bceeeeb55b3318a9c20afa7cfd3255d11 100644 (file)
@@ -13,14 +13,15 @@ static int graph_one_property(
                 const UnitInfo *u,
                 const char *prop,
                 const char *color,
-                char *patterns[],
-                char *from_patterns[],
-                char *to_patterns[]) {
+                char **patterns,
+                char **from_patterns,
+                char **to_patterns) {
 
         _cleanup_strv_free_ char **units = NULL;
         bool match_patterns;
         int r;
 
+        assert(bus);
         assert(u);
         assert(prop);
         assert(color);
@@ -51,7 +52,13 @@ static int graph_one_property(
         return 0;
 }
 
-static int graph_one(sd_bus *bus, const UnitInfo *u, char *patterns[], char *from_patterns[], char *to_patterns[]) {
+static int graph_one(
+                sd_bus *bus,
+                const UnitInfo *u,
+                char **patterns,
+                char **from_patterns,
+                char **to_patterns) {
+
         int r;
 
         assert(bus);
@@ -67,12 +74,19 @@ static int graph_one(sd_bus *bus, const UnitInfo *u, char *patterns[], char *fro
                 r = graph_one_property(bus, u, "Requires", "black", patterns, from_patterns, to_patterns);
                 if (r < 0)
                         return r;
+
                 r = graph_one_property(bus, u, "Requisite", "darkblue", patterns, from_patterns, to_patterns);
                 if (r < 0)
                         return r;
+
+                r = graph_one_property(bus, u, "BindsTo", "gold", patterns, from_patterns, to_patterns);
+                if (r < 0)
+                        return r;
+
                 r = graph_one_property(bus, u, "Wants", "grey66", patterns, from_patterns, to_patterns);
                 if (r < 0)
                         return r;
+
                 r = graph_one_property(bus, u, "Conflicts", "red", patterns, from_patterns, to_patterns);
                 if (r < 0)
                         return r;
@@ -85,6 +99,9 @@ static int expand_patterns(sd_bus *bus, char **patterns, char ***ret) {
         _cleanup_strv_free_ char **expanded_patterns = NULL;
         int r;
 
+        assert(bus);
+        assert(ret);
+
         STRV_FOREACH(pattern, patterns) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_free_ char *unit = NULL, *unit_id = NULL;
@@ -110,10 +127,9 @@ static int expand_patterns(sd_bus *bus, char **patterns, char ***ret) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to get ID: %s", bus_error_message(&error, r));
 
-                if (!streq(*pattern, unit_id)) {
+                if (!streq(*pattern, unit_id))
                         if (strv_extend(&expanded_patterns, unit_id) < 0)
                                 return log_oom();
-                }
         }
 
         *ret = TAKE_PTR(expanded_patterns); /* do not free */
@@ -128,8 +144,8 @@ int verb_dot(int argc, char *argv[], void *userdata) {
         _cleanup_strv_free_ char **expanded_patterns = NULL;
         _cleanup_strv_free_ char **expanded_from_patterns = NULL;
         _cleanup_strv_free_ char **expanded_to_patterns = NULL;
-        int r;
         UnitInfo u;
+        int r;
 
         r = acquire_bus(&bus, NULL);
         if (r < 0)
@@ -170,6 +186,7 @@ int verb_dot(int argc, char *argv[], void *userdata) {
 
         log_info("   Color legend: black     = Requires\n"
                  "                 dark blue = Requisite\n"
+                 "                 gold      = BindsTo\n"
                  "                 dark grey = Wants\n"
                  "                 red       = Conflicts\n"
                  "                 green     = After\n");
index 030b206f1e0276c12e6b6c40097ce9540615a117..486143b7f0620dff04342940da9d2c06971f08c4 100644 (file)
@@ -215,20 +215,21 @@ static int assess_user(
                 uint64_t *ret_badness,
                 char **ret_description) {
 
-        _cleanup_free_ char *d = NULL;
+        const char *d;
         uint64_t b;
+        int r;
 
         assert(ret_badness);
         assert(ret_description);
 
         if (streq_ptr(info->user, NOBODY_USER_NAME)) {
-                d = strdup("Service runs under as '" NOBODY_USER_NAME "' user, which should not be used for services");
+                d = "Service runs under as '" NOBODY_USER_NAME "' user, which should not be used for services";
                 b = 9;
         } else if (info->dynamic_user && !STR_IN_SET(info->user, "0", "root")) {
-                d = strdup("Service runs under a transient non-root user identity");
+                d = "Service runs under a transient non-root user identity";
                 b = 0;
         } else if (info->user && !STR_IN_SET(info->user, "0", "root", "")) {
-                d = strdup("Service runs under a static non-root user identity");
+                d = "Service runs under a static non-root user identity";
                 b = 0;
         } else {
                 *ret_badness = 10;
@@ -236,12 +237,11 @@ static int assess_user(
                 return 0;
         }
 
-        if (!d)
-                return log_oom();
+        r = strdup_to(ret_description, d);
+        if (r < 0)
+                return r;
 
         *ret_badness = b;
-        *ret_description = TAKE_PTR(d);
-
         return 0;
 }
 
@@ -254,7 +254,6 @@ static int assess_protect_home(
 
         const char *description;
         uint64_t badness;
-        char *copy;
         int r;
 
         assert(ret_badness);
@@ -277,13 +276,11 @@ static int assess_protect_home(
                 description = "Service has no access to home directories";
         }
 
-        copy = strdup(description);
-        if (!copy)
-                return log_oom();
+        r = strdup_to(ret_description, description);
+        if (r < 0)
+                return r;
 
         *ret_badness = badness;
-        *ret_description = copy;
-
         return 0;
 }
 
@@ -296,7 +293,6 @@ static int assess_protect_system(
 
         const char *description;
         uint64_t badness;
-        char *copy;
         int r;
 
         assert(ret_badness);
@@ -319,13 +315,11 @@ static int assess_protect_system(
                 description = "Service has limited write access to the OS file hierarchy";
         }
 
-        copy = strdup(description);
-        if (!copy)
-                return log_oom();
+        r = strdup_to(ret_description, description);
+        if (r < 0)
+                return r;
 
         *ret_badness = badness;
-        *ret_description = copy;
-
         return 0;
 }
 
@@ -370,9 +364,9 @@ static int assess_umask(
                 uint64_t *ret_badness,
                 char **ret_description) {
 
-        char *copy = NULL;
         const char *d;
         uint64_t b;
+        int r;
 
         assert(ret_badness);
         assert(ret_description);
@@ -394,13 +388,11 @@ static int assess_umask(
                 b = 0;
         }
 
-        copy = strdup(d);
-        if (!copy)
-                return log_oom();
+        r = strdup_to(ret_description, d);
+        if (r < 0)
+                return r;
 
         *ret_badness = b;
-        *ret_description = copy;
-
         return 0;
 }
 
@@ -537,30 +529,30 @@ static int assess_system_call_architectures(
                 uint64_t *ret_badness,
                 char **ret_description) {
 
-        char *d;
+        const char *d;
         uint64_t b;
+        int r;
 
         assert(ret_badness);
         assert(ret_description);
 
         if (set_isempty(info->system_call_architectures)) {
                 b = 10;
-                d = strdup("Service may execute system calls with all ABIs");
+                d = "Service may execute system calls with all ABIs";
         } else if (set_contains(info->system_call_architectures, "native") &&
                    set_size(info->system_call_architectures) == 1) {
                 b = 0;
-                d = strdup("Service may execute system calls only with native ABI");
+                d = "Service may execute system calls only with native ABI";
         } else {
                 b = 8;
-                d = strdup("Service may execute system calls with multiple ABIs");
+                d = "Service may execute system calls with multiple ABIs";
         }
 
-        if (!d)
-                return log_oom();
+        r = strdup_to(ret_description, d);
+        if (r < 0)
+                return r;
 
         *ret_badness = b;
-        *ret_description = d;
-
         return 0;
 }
 
@@ -607,12 +599,12 @@ static int assess_system_call_filter(
         assert(a->parameter < _SYSCALL_FILTER_SET_MAX);
         const SyscallFilterSet *f = syscall_filter_sets + a->parameter;
 
-        _cleanup_free_ char *d = NULL;
+        char *d;
         uint64_t b;
         int r;
 
         if (!info->system_call_filter_allow_list && set_isempty(info->system_call_filter)) {
-                r = free_and_strdup(&d, "Service does not filter system calls");
+                r = strdup_to(&d, "Service does not filter system calls");
                 b = 10;
         } else {
                 bool bad;
@@ -649,8 +641,8 @@ static int assess_system_call_filter(
         if (r < 0)
                 return log_oom();
 
+        *ret_description = d;
         *ret_badness = b;
-        *ret_description = TAKE_PTR(d);
 
         return 0;
 }
@@ -664,36 +656,36 @@ static int assess_ip_address_allow(
                 uint64_t *ret_badness,
                 char **ret_description) {
 
-        char *d = NULL;
+        const char *d;
         uint64_t b;
+        int r;
 
         assert(info);
         assert(ret_badness);
         assert(ret_description);
 
         if (info->ip_filters_custom_ingress || info->ip_filters_custom_egress) {
-                d = strdup("Service defines custom ingress/egress IP filters with BPF programs");
+                d = "Service defines custom ingress/egress IP filters with BPF programs";
                 b = 0;
         } else if (!info->ip_address_deny_all) {
-                d = strdup("Service does not define an IP address allow list");
+                d = "Service does not define an IP address allow list";
                 b = 10;
         } else if (info->ip_address_allow_other) {
-                d = strdup("Service defines IP address allow list with non-localhost entries");
+                d = "Service defines IP address allow list with non-localhost entries";
                 b = 5;
         } else if (info->ip_address_allow_localhost) {
-                d = strdup("Service defines IP address allow list with only localhost entries");
+                d = "Service defines IP address allow list with only localhost entries";
                 b = 2;
         } else {
-                d = strdup("Service blocks all IP address ranges");
+                d = "Service blocks all IP address ranges";
                 b = 0;
         }
 
-        if (!d)
-                return log_oom();
+        r = strdup_to(ret_description, d);
+        if (r < 0)
+                return r;
 
         *ret_badness = b;
-        *ret_description = d;
-
         return 0;
 }
 
@@ -704,7 +696,7 @@ static int assess_device_allow(
                 uint64_t *ret_badness,
                 char **ret_description) {
 
-        char *d = NULL;
+        char *d;
         uint64_t b;
 
         assert(info);
@@ -1764,15 +1756,14 @@ static int assess(const SecurityInfo *info,
                         (void) table_set_display(details_table, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) 7);
         }
 
-        for (i = 0; i < ELEMENTSOF(security_assessor_table); i++) {
-                const struct security_assessor *a = security_assessor_table + i;
+        FOREACH_ARRAY(a, security_assessor_table, ELEMENTSOF(security_assessor_table)) {
                 _cleanup_free_ char *d = NULL;
                 uint64_t badness;
                 void *data;
                 uint64_t weight = access_weight(a, policy);
                 uint64_t range = access_range(a, policy);
 
-                data = (uint8_t *) info + a->offset;
+                data = (uint8_t*) info + a->offset;
 
                 if (a->default_dependencies_only && !info->default_dependencies) {
                         badness = UINT64_MAX;
@@ -2828,7 +2819,6 @@ static int analyze_security(sd_bus *bus,
 
                 for (;;) {
                         UnitInfo info;
-                        char *copy = NULL;
 
                         r = bus_parse_unit_info(reply, &info);
                         if (r < 0)
@@ -2842,12 +2832,11 @@ static int analyze_security(sd_bus *bus,
                         if (!GREEDY_REALLOC(list, n + 2))
                                 return log_oom();
 
-                        copy = strdup(info.id);
-                        if (!copy)
-                                return log_oom();
+                        r = strdup_to(&list[n], info.id);
+                        if (r < 0)
+                                return r;
 
-                        list[n++] = copy;
-                        list[n] = NULL;
+                        list[++n] = NULL;
                 }
 
                 strv_sort(list);
index b449e538f31e33b82d4e4763075353c10b8b68bc..cf4894a9d3bef362978b20afb06f195f94512015 100644 (file)
@@ -572,10 +572,9 @@ static int parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --threshold= is only supported for security right now.");
 
-        if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL &&
-            !STR_IN_SET(argv[optind] ?: "time", "dot", "unit-paths", "verify"))
+        if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL && !streq_ptr(argv[optind], "unit-paths"))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Option --global only makes sense with verbs dot, unit-paths, verify.");
+                                       "Option --global only makes sense with verb unit-paths.");
 
         if (streq_ptr(argv[optind], "cat-config") && arg_runtime_scope == RUNTIME_SCOPE_USER)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
index 68b1584629219f274894c61d031a57246e19a417..6991460f86e65a0b7b9a30293f6c71bba8025da6 100644 (file)
@@ -135,7 +135,7 @@ int cg_read_event(
                 return r;
 
         for (const char *p = content;;) {
-                _cleanup_free_ char *line = NULL, *key = NULL, *val = NULL;
+                _cleanup_free_ char *line = NULL, *key = NULL;
                 const char *q;
 
                 r = extract_first_word(&p, &line, "\n", 0);
@@ -154,12 +154,7 @@ int cg_read_event(
                 if (!streq(key, event))
                         continue;
 
-                val = strdup(q);
-                if (!val)
-                        return -ENOMEM;
-
-                *ret = TAKE_PTR(val);
-                return 0;
+                return strdup_to(ret, q);
         }
 }
 
@@ -234,20 +229,13 @@ int cg_read_subgroup(DIR *d, char **ret) {
         assert(ret);
 
         FOREACH_DIRENT_ALL(de, d, return -errno) {
-                char *b;
-
                 if (de->d_type != DT_DIR)
                         continue;
 
                 if (dot_or_dot_dot(de->d_name))
                         continue;
 
-                b = strdup(de->d_name);
-                if (!b)
-                        return -ENOMEM;
-
-                *ret = b;
-                return 1;
+                return strdup_to_full(ret, de->d_name);
         }
 
         *ret = NULL;
@@ -1125,44 +1113,29 @@ int cg_pid_get_path_shifted(pid_t pid, const char *root, char **ret_cgroup) {
         if (r < 0)
                 return r;
 
-        if (c == raw)
+        if (c == raw) {
                 *ret_cgroup = TAKE_PTR(raw);
-        else {
-                char *n;
-
-                n = strdup(c);
-                if (!n)
-                        return -ENOMEM;
-
-                *ret_cgroup = n;
+                return 0;
         }
 
-        return 0;
+        return strdup_to(ret_cgroup, c);
 }
 
 int cg_path_decode_unit(const char *cgroup, char **ret_unit) {
-        char *c, *s;
-        size_t n;
-
         assert(cgroup);
         assert(ret_unit);
 
-        n = strcspn(cgroup, "/");
+        size_t n = strcspn(cgroup, "/");
         if (n < 3)
                 return -ENXIO;
 
-        c = strndupa_safe(cgroup, n);
+        char *c = strndupa_safe(cgroup, n);
         c = cg_unescape(c);
 
         if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
                 return -ENXIO;
 
-        s = strdup(c);
-        if (!s)
-                return -ENOMEM;
-
-        *ret_unit = s;
-        return 0;
+        return strdup_to(ret_unit, c);
 }
 
 static bool valid_slice_name(const char *p, size_t n) {
@@ -1467,17 +1440,10 @@ int cg_path_get_session(const char *path, char **ret_session) {
         if (!session_id_valid(start))
                 return -ENXIO;
 
-        if (ret_session) {
-                char *rr;
-
-                rr = strdup(start);
-                if (!rr)
-                        return -ENOMEM;
-
-                *ret_session = rr;
-        }
+        if (!ret_session)
+                return 0;
 
-        return 0;
+        return strdup_to(ret_session, start);
 }
 
 int cg_pid_get_session(pid_t pid, char **ret_session) {
@@ -1534,34 +1500,26 @@ int cg_path_get_slice(const char *p, char **ret_slice) {
         assert(p);
         assert(ret_slice);
 
-        /* Finds the right-most slice unit from the beginning, but
-         * stops before we come to the first non-slice unit. */
+        /* Finds the right-most slice unit from the beginning, but stops before we come to
+         * the first non-slice unit. */
 
         for (;;) {
-                size_t n;
-
-                p += strspn(p, "/");
+                const char *s;
+                int n;
 
-                n = strcspn(p, "/");
-                if (!valid_slice_name(p, n)) {
-
-                        if (!e) {
-                                char *s;
-
-                                s = strdup(SPECIAL_ROOT_SLICE);
-                                if (!s)
-                                        return -ENOMEM;
+                n = path_find_first_component(&p, /* accept_dot_dot = */ false, &s);
+                if (n < 0)
+                        return n;
+                if (!valid_slice_name(s, n))
+                        break;
 
-                                *ret_slice = s;
-                                return 0;
-                        }
+                e = s;
+        }
 
-                        return cg_path_decode_unit(e, ret_slice);
-                }
+        if (e)
+                return cg_path_decode_unit(e, ret_slice);
 
-                e = p;
-                p += n;
-        }
+        return strdup_to(ret_slice, SPECIAL_ROOT_SLICE);
 }
 
 int cg_pid_get_slice(pid_t pid, char **ret_slice) {
@@ -1714,15 +1672,8 @@ int cg_slice_to_path(const char *unit, char **ret) {
         assert(unit);
         assert(ret);
 
-        if (streq(unit, SPECIAL_ROOT_SLICE)) {
-                char *x;
-
-                x = strdup("");
-                if (!x)
-                        return -ENOMEM;
-                *ret = x;
-                return 0;
-        }
+        if (streq(unit, SPECIAL_ROOT_SLICE))
+                return strdup_to(ret, "");
 
         if (!unit_name_is_valid(unit, UNIT_NAME_PLAIN))
                 return -EINVAL;
index 9f5477e4f3fe45e1e18635b6edb8676a4a6da8a4..245dd0800ef74ce3abb9c6ad57f33cf53bae3005 100644 (file)
@@ -741,12 +741,7 @@ int chase_extract_filename(const char *path, const char *root, char **ret) {
                         return r;
         }
 
-        char *fname = strdup(".");
-        if (!fname)
-                return -ENOMEM;
-
-        *ret = fname;
-        return 0;
+        return strdup_to(ret, ".");
 }
 
 int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, int open_flags, char **ret_path) {
index f82e13bdb02875449bcf2ee7d5233bd8dbb94c2a..652740cea757a1a0944e908ee5da863e262e68e0 100644 (file)
@@ -58,21 +58,18 @@ int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) {
 }
 
 int device_path_make_inaccessible(mode_t mode, char **ret) {
-        char *s;
+        const char *s;
 
         assert(ret);
 
         if (S_ISCHR(mode))
-                s = strdup("/run/systemd/inaccessible/chr");
+                s = "/run/systemd/inaccessible/chr";
         else if (S_ISBLK(mode))
-                s = strdup("/run/systemd/inaccessible/blk");
+                s = "/run/systemd/inaccessible/blk";
         else
                 return -ENODEV;
-        if (!s)
-                return -ENOMEM;
 
-        *ret = s;
-        return 0;
+        return strdup_to(ret, s);
 }
 
 int device_path_make_canonical(mode_t mode, dev_t devnum, char **ret) {
index 9011ae29a3a82d8bebf2b1f28a799e07c5a927de..fdc6c439bb85cb563080b0c7c2e947b77fb5a3a7 100644 (file)
@@ -398,16 +398,8 @@ int systemd_efi_options_variable(char **ret) {
 
         /* For testing purposes it is sometimes useful to be able to override this */
         e = secure_getenv("SYSTEMD_EFI_OPTIONS");
-        if (e) {
-                char *m;
-
-                m = strdup(e);
-                if (!m)
-                        return -ENOMEM;
-
-                *ret = m;
-                return 0;
-        }
+        if (e)
+                return strdup_to(ret, e);
 
         r = read_one_line_file(EFIVAR_CACHE_PATH(EFI_SYSTEMD_VARIABLE(SystemdOptions)), ret);
         if (r == -ENOENT)
index 3aadb4bfab99fb3944241c97cdd143ef9ac269b2..523378177fb7ecb6c84bd4c9b99659670bba5883 100644 (file)
@@ -1504,7 +1504,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
 
 int read_stripped_line(FILE *f, size_t limit, char **ret) {
         _cleanup_free_ char *s = NULL;
-        int r;
+        int r, k;
 
         assert(f);
 
@@ -1513,23 +1513,17 @@ int read_stripped_line(FILE *f, size_t limit, char **ret) {
                 return r;
 
         if (ret) {
-                const char *p;
-
-                p = strstrip(s);
+                const char *p = strstrip(s);
                 if (p == s)
                         *ret = TAKE_PTR(s);
                 else {
-                        char *copy;
-
-                        copy = strdup(p);
-                        if (!copy)
-                                return -ENOMEM;
-
-                        *ret = copy;
+                        k = strdup_to(ret, p);
+                        if (k < 0)
+                                return k;
                 }
         }
 
-        return r;
+        return r > 0;          /* Return 1 if something was read. */
 }
 
 int safe_fgetc(FILE *f, char *ret) {
index 94501853a158ac094784171f2974aaae73e42436..056c990cc77c966cc4b2fcd33355dffc64997f46 100644 (file)
@@ -25,7 +25,7 @@ int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NA
 }
 
 int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) {
-        char buf[IF_NAMESIZE], *copy;
+        char buf[IF_NAMESIZE];
         int r;
 
         assert(ret);
@@ -34,12 +34,7 @@ int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) {
         if (r < 0)
                 return r;
 
-        copy = strdup(buf);
-        if (!copy)
-                return -ENOMEM;
-
-        *ret = copy;
-        return 0;
+        return strdup_to(ret, buf);
 }
 
 char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) {
index 172a2c8ada086cbf4d3ea98c671c5b92ee4e5556..6faa6ad4fcef8de0e3f28211a388ded74f594d46 100644 (file)
@@ -49,6 +49,12 @@ static void *log_syntax_callback_userdata = NULL;
 
 static LogTarget log_target = LOG_TARGET_CONSOLE;
 static int log_max_level = LOG_INFO;
+static int log_target_max_level[] = {
+        [LOG_TARGET_CONSOLE] = INT_MAX,
+        [LOG_TARGET_KMSG]    = INT_MAX,
+        [LOG_TARGET_SYSLOG]  = INT_MAX,
+        [LOG_TARGET_JOURNAL] = INT_MAX,
+};
 static int log_facility = LOG_DAEMON;
 static bool ratelimit_kmsg = true;
 
@@ -439,6 +445,9 @@ static int write_to_console(
         if (console_fd < 0)
                 return 0;
 
+        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_CONSOLE])
+                return 0;
+
         if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
                 xsprintf(prefix, "<%i>", level);
                 iovec[n++] = IOVEC_MAKE_STRING(prefix);
@@ -523,6 +532,9 @@ static int write_to_syslog(
         if (syslog_fd < 0)
                 return 0;
 
+        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_SYSLOG])
+                return 0;
+
         xsprintf(header_priority, "<%i>", level);
 
         t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
@@ -592,6 +604,9 @@ static int write_to_kmsg(
         if (kmsg_fd < 0)
                 return 0;
 
+        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_KMSG])
+                return 0;
+
         if (ratelimit_kmsg && !ratelimit_below(&ratelimit)) {
                 if (ratelimit_num_dropped(&ratelimit) > 1)
                         return 0;
@@ -719,6 +734,9 @@ static int write_to_journal(
         if (journal_fd < 0)
                 return 0;
 
+        if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_JOURNAL])
+                return 0;
+
         iovec_len = MIN(6 + _log_context_num_fields * 2, IOVEC_MAX);
         iovec = newa(struct iovec, iovec_len);
 
@@ -988,7 +1006,7 @@ void log_assert_failed_return(
 
         PROTECT_ERRNO;
         log_assert(LOG_DEBUG, text, file, line, func,
-                   "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
+                   "Assertion '%s' failed at %s:%u, function %s(), ignoring.");
 }
 
 int log_oom_internal(int level, const char *file, int line, const char *func) {
@@ -1218,11 +1236,74 @@ int log_set_target_from_string(const char *e) {
 int log_set_max_level_from_string(const char *e) {
         int r;
 
-        r = log_level_from_string(e);
+        for (;;) {
+                _cleanup_free_ char *word = NULL, *prefix = NULL;
+                LogTarget target;
+                const char *colon;
+
+                r = extract_first_word(&e, &word, ",", 0);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                colon = strchr(word, ':');
+                if (!colon) {
+                        r = log_level_from_string(word);
+                        if (r < 0)
+                                return r;
+
+                        log_set_max_level(r);
+                        continue;
+                }
+
+                prefix = strndup(word, colon - word);
+                if (!prefix)
+                        return -ENOMEM;
+
+                target = log_target_from_string(prefix);
+                if (target < 0)
+                        return target;
+
+                if (target >= _LOG_TARGET_SINGLE_MAX)
+                        return -EINVAL;
+
+                r = log_level_from_string(colon + 1);
+                if (r < 0)
+                        return r;
+
+                log_target_max_level[target] = r;
+        }
+
+        return 0;
+}
+
+int log_max_levels_to_string(int level, char **ret) {
+        _cleanup_free_ char *s = NULL;
+        int r;
+
+        assert(ret);
+
+        r = log_level_to_string_alloc(level, &s);
         if (r < 0)
                 return r;
 
-        log_set_max_level(r);
+        for (LogTarget target = 0; target < _LOG_TARGET_SINGLE_MAX; target++) {
+                _cleanup_free_ char *l = NULL;
+
+                if (log_target_max_level[target] == INT_MAX)
+                        continue;
+
+                r = log_level_to_string_alloc(log_target_max_level[target], &l);
+                if (r < 0)
+                        return r;
+
+                r = strextendf_with_separator(&s, ",", "%s:%s", log_target_to_string(target), l);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret = TAKE_PTR(s);
         return 0;
 }
 
@@ -1265,7 +1346,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return 0;
 
                 if (log_set_target_from_string(value) < 0)
-                        log_warning("Failed to parse log target '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log target '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
 
@@ -1273,32 +1354,32 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return 0;
 
                 if (log_set_max_level_from_string(value) < 0)
-                        log_warning("Failed to parse log level '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log level setting '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
 
                 if (log_show_color_from_string(value ?: "1") < 0)
-                        log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log color setting '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
 
                 if (log_show_location_from_string(value ?: "1") < 0)
-                        log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log location setting '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_tid")) {
 
                 if (log_show_tid_from_string(value ?: "1") < 0)
-                        log_warning("Failed to parse log tid setting '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log tid setting '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
 
                 if (log_show_time_from_string(value ?: "1") < 0)
-                        log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log time setting '%s', ignoring.", value);
 
         } else if (proc_cmdline_key_streq(key, "systemd.log_ratelimit_kmsg")) {
 
                 if (log_set_ratelimit_kmsg_from_string(value ?: "1") < 0)
-                        log_warning("Failed to parse log ratelimit kmsg boolean '%s'. Ignoring.", value);
+                        log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", value);
         }
 
         return 0;
@@ -1318,31 +1399,31 @@ void log_parse_environment_variables(void) {
 
         e = getenv("SYSTEMD_LOG_TARGET");
         if (e && log_set_target_from_string(e) < 0)
-                log_warning("Failed to parse log target '%s'. Ignoring.", e);
+                log_warning("Failed to parse log target '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_LEVEL");
         if (e && log_set_max_level_from_string(e) < 0)
-                log_warning("Failed to parse log level '%s'. Ignoring.", e);
+                log_warning("Failed to parse log level '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_COLOR");
         if (e && log_show_color_from_string(e) < 0)
-                log_warning("Failed to parse log color '%s'. Ignoring.", e);
+                log_warning("Failed to parse log color '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_LOCATION");
         if (e && log_show_location_from_string(e) < 0)
-                log_warning("Failed to parse log location '%s'. Ignoring.", e);
+                log_warning("Failed to parse log location '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_TIME");
         if (e && log_show_time_from_string(e) < 0)
-                log_warning("Failed to parse log time '%s'. Ignoring.", e);
+                log_warning("Failed to parse log time '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_TID");
         if (e && log_show_tid_from_string(e) < 0)
-                log_warning("Failed to parse log tid '%s'. Ignoring.", e);
+                log_warning("Failed to parse log tid '%s', ignoring.", e);
 
         e = getenv("SYSTEMD_LOG_RATELIMIT_KMSG");
         if (e && log_set_ratelimit_kmsg_from_string(e) < 0)
-                log_warning("Failed to parse log ratelimit kmsg boolean '%s'. Ignoring.", e);
+                log_warning("Failed to parse log ratelimit kmsg boolean '%s', ignoring.", e);
 }
 
 void log_parse_environment(void) {
index 23f54b88fb0189503094c0e2f8eb979fe5018a7f..fc80902c450e2d924d715b1a917b8537ab064cda 100644 (file)
@@ -18,15 +18,16 @@ struct signalfd_siginfo;
 
 typedef enum LogTarget{
         LOG_TARGET_CONSOLE,
-        LOG_TARGET_CONSOLE_PREFIXED,
         LOG_TARGET_KMSG,
         LOG_TARGET_JOURNAL,
-        LOG_TARGET_JOURNAL_OR_KMSG,
         LOG_TARGET_SYSLOG,
+        LOG_TARGET_CONSOLE_PREFIXED,
+        LOG_TARGET_JOURNAL_OR_KMSG,
         LOG_TARGET_SYSLOG_OR_KMSG,
         LOG_TARGET_AUTO, /* console if stderr is not journal, JOURNAL_OR_KMSG otherwise */
         LOG_TARGET_NULL,
-        _LOG_TARGET_MAX,
+        _LOG_TARGET_SINGLE_MAX = LOG_TARGET_SYSLOG + 1,
+        _LOG_TARGET_MAX = LOG_TARGET_NULL + 1,
         _LOG_TARGET_INVALID = -EINVAL,
 } LogTarget;
 
@@ -59,6 +60,7 @@ void log_settle_target(void);
 void log_set_max_level(int level);
 int log_set_max_level_from_string(const char *e);
 int log_get_max_level(void) _pure_;
+int log_max_levels_to_string(int level, char **ret);
 
 void log_set_facility(int facility);
 
index fe78363b8615c9ccfa8e912c65681d861cccbaf5..d43c3cdd5ddde4cfd610773624003fc96a0704b1 100644 (file)
@@ -383,4 +383,17 @@ assert_cc(sizeof(dummy_t) == 0);
              ((long)(_current_ - _entries_) < (long)(ELEMENTSOF(_entries_) - 1)) && ({ entry = *_current_; true; }); \
              _current_++)
 
+#define DECIMAL_STR_FMT(x) _Generic((x),        \
+        char: "%c",                             \
+        bool: "%d",                             \
+        unsigned char: "%d",                    \
+        short: "%hd",                           \
+        unsigned short: "%hu",                  \
+        int: "%d",                              \
+        unsigned: "%u",                         \
+        long: "%ld",                            \
+        unsigned long: "%lu",                   \
+        long long: "%lld",                      \
+        unsigned long long: "%llu")
+
 #include "log.h"
index 62e3c292f531ef6dd733d17ee938d49f43e5aef9..3f72acf02f628ab08cc6d7273cffeda41b67f900 100644 (file)
@@ -4,21 +4,31 @@
 #include <linux/audit.h>
 
 #if HAVE_AUDIT
-#include <libaudit.h>
+#  include <libaudit.h>
 #endif
 
 #ifndef AUDIT_SERVICE_START
-#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
+#  define AUDIT_SERVICE_START 1130 /* Service (daemon) start */
+#else
+assert_cc(AUDIT_SERVICE_START == 1130);
 #endif
 
 #ifndef AUDIT_SERVICE_STOP
-#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
+#  define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */
+#else
+assert_cc(AUDIT_SERVICE_STOP == 1131);
 #endif
 
 #ifndef MAX_AUDIT_MESSAGE_LENGTH
-#define MAX_AUDIT_MESSAGE_LENGTH 8970
+#  define MAX_AUDIT_MESSAGE_LENGTH 8970
+#else
+assert_cc(MAX_AUDIT_MESSAGE_LENGTH == 8970);
 #endif
 
+/* Note: we check for AUDIT_NLGRP_MAX because it's a define, but we actually
+ * need AUDIT_NLGRP_READLOG which is an enum. */
 #ifndef AUDIT_NLGRP_MAX
-#define AUDIT_NLGRP_READLOG 1
+#  define AUDIT_NLGRP_READLOG 1
+#else
+assert_cc(AUDIT_NLGRP_READLOG == 1);
 #endif
index 5adda554e59aa539e0206024fcb99d24308f02af..c1c63a68292b1afa9f1d3b8f4b15abac6cee6d8a 100644 (file)
@@ -6,21 +6,29 @@
 /* 3a101b8de0d39403b2c7e5c23fd0b005668acf48 (3.16) */
 #ifndef CAP_AUDIT_READ
 #  define CAP_AUDIT_READ 37
+#else
+assert_cc(CAP_AUDIT_READ == 37);
 #endif
 
 /* 980737282232b752bb14dab96d77665c15889c36 (5.8) */
 #ifndef CAP_PERFMON
 #  define CAP_PERFMON 38
+#else
+assert_cc(CAP_PERFMON == 38);
 #endif
 
 /* a17b53c4a4b55ec322c132b6670743612229ee9c (5.8) */
 #ifndef CAP_BPF
 #  define CAP_BPF 39
+#else
+assert_cc(CAP_BPF == 39);
 #endif
 
 /* 124ea650d3072b005457faed69909221c2905a1f (5.9) */
 #ifndef CAP_CHECKPOINT_RESTORE
 #  define CAP_CHECKPOINT_RESTORE 40
+#else
+assert_cc(CAP_CHECKPOINT_RESTORE == 40);
 #endif
 
 #define SYSTEMD_CAP_LAST_CAP CAP_CHECKPOINT_RESTORE
@@ -34,6 +42,7 @@
 #    undef CAP_LAST_CAP
 #  endif
 #endif
+
 #ifndef CAP_LAST_CAP
 #  define CAP_LAST_CAP SYSTEMD_CAP_LAST_CAP
 #endif
index 0dec59114663a71de41b066d80f00dce7531ab0a..e4ca56f0b1b00ebfe5ef14f6c289004ed49464ae 100644 (file)
@@ -2,9 +2,9 @@
 #pragma once
 
 #ifndef DRM_IOCTL_SET_MASTER
-#define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
+#  define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
 #endif
 
 #ifndef DRM_IOCTL_DROP_MASTER
-#define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f)
+#  define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f)
 #endif
index 9b03bbac483e0dc3d0c9aa0d03329b4b5ab4cc91..ee70ae08dbcc4c02143976842267fd8dba57217c 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/types.h>
 
+#include "macro.h"
+
 /* linux/fs.h */
 #ifndef RENAME_NOREPLACE /* 0a7c3937a1f23f8cb5fc77ae01661e9968a51d0c (3.15) */
 #define RENAME_NOREPLACE (1 << 0)
@@ -28,43 +30,63 @@ struct file_clone_range {
 
 /* linux/fs.h or sys/mount.h */
 #ifndef MS_MOVE
-#define MS_MOVE 8192
+#  define MS_MOVE 8192
+#else
+assert_cc(MS_MOVE == 8192);
 #endif
 
 #ifndef MS_REC
-#define MS_REC 16384
+#  define MS_REC 16384
+#else
+assert_cc(MS_REC == 16384);
 #endif
 
 #ifndef MS_PRIVATE
-#define MS_PRIVATE      (1<<18)
+#  define MS_PRIVATE      (1<<18)
+#else
+assert_cc(MS_PRIVATE == (1<<18));
 #endif
 
 #ifndef MS_SLAVE
-#define MS_SLAVE        (1<<19)
+#  define MS_SLAVE        (1<<19)
+#else
+assert_cc(MS_SLAVE == (1<<19));
 #endif
 
 #ifndef MS_SHARED
-#define MS_SHARED       (1<<20)
+#  define MS_SHARED       (1<<20)
+#else
+assert_cc(MS_SHARED == (1<<20));
 #endif
 
 #ifndef MS_RELATIME
-#define MS_RELATIME     (1<<21)
+#  define MS_RELATIME     (1<<21)
+#else
+assert_cc(MS_RELATIME == (1<<21));
 #endif
 
 #ifndef MS_KERNMOUNT
-#define MS_KERNMOUNT    (1<<22)
+#  define MS_KERNMOUNT    (1<<22)
+#else
+assert_cc(MS_KERNMOUNT == (1<<22));
 #endif
 
 #ifndef MS_I_VERSION
-#define MS_I_VERSION    (1<<23)
+#  define MS_I_VERSION    (1<<23)
+#else
+assert_cc(MS_I_VERSION == (1<<23));
 #endif
 
 #ifndef MS_STRICTATIME
-#define MS_STRICTATIME  (1<<24)
+#  define MS_STRICTATIME  (1<<24)
+#else
+assert_cc(MS_STRICTATIME == (1 << 24));
 #endif
 
 #ifndef MS_LAZYTIME
-#define MS_LAZYTIME     (1<<25)
+#  define MS_LAZYTIME     (1<<25)
+#else
+assert_cc(MS_LAZYTIME == (1<<25));
 #endif
 
 /* Not exposed yet. Defined at fs/ext4/ext4.h */
@@ -78,10 +100,14 @@ struct file_clone_range {
 #endif
 
 #ifndef FS_PROJINHERIT_FL
-#define FS_PROJINHERIT_FL 0x20000000
+#  define FS_PROJINHERIT_FL 0x20000000
+#else
+assert_cc(FS_PROJINHERIT_FL == 0x20000000);
 #endif
 
 /* linux/fscrypt.h */
 #ifndef FS_KEY_DESCRIPTOR_SIZE
-#define FS_KEY_DESCRIPTOR_SIZE 8
+#  define FS_KEY_DESCRIPTOR_SIZE 8
+#else
+assert_cc(FS_KEY_DESCRIPTOR_SIZE == 8);
 #endif
index 6cf16ffb97b65ff31793627a0e7b7866696993c2..ee61bf99d6a7320860281765878141e0ac93fad3 100644 (file)
@@ -4,9 +4,11 @@
 #include <linux/input.h>
 #include <linux/types.h>
 
+#include "macro.h"
+
 /* linux@c7dc65737c9a607d3e6f8478659876074ad129b8 (3.12) */
 #ifndef EVIOCREVOKE
-#define EVIOCREVOKE _IOW('E', 0x91, int)
+#  define EVIOCREVOKE _IOW('E', 0x91, int)
 #endif
 
 /* linux@06a16293f71927f756dcf37558a79c0b05a91641 (4.4) */
@@ -17,29 +19,40 @@ struct input_mask {
         __u64 codes_ptr;
 };
 
-#define EVIOCGMASK _IOR('E', 0x92, struct input_mask)
-#define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
+#  define EVIOCGMASK _IOR('E', 0x92, struct input_mask)
+#  define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
 #endif
 
 /* linux@7611392fe8ff95ecae528b01a815ae3d72ca6b95 (3.17) */
 #ifndef INPUT_PROP_POINTING_STICK
-#define INPUT_PROP_POINTING_STICK 0x05
+#  define INPUT_PROP_POINTING_STICK 0x05
+#else
+assert_cc(INPUT_PROP_POINTING_STICK == 0x05);
 #endif
 
 /* linux@500d4160abe9a2e88b12e319c13ae3ebd1e18108 (4.0) */
 #ifndef INPUT_PROP_ACCELEROMETER
-#define INPUT_PROP_ACCELEROMETER  0x06
+#  define INPUT_PROP_ACCELEROMETER  0x06
+#else
+assert_cc(INPUT_PROP_ACCELEROMETER == 0x06);
 #endif
 
 /* linux@d09bbfd2a8408a995419dff0d2ba906013cf4cc9 (3.11) */
 #ifndef BTN_DPAD_UP
-#define BTN_DPAD_UP    0x220
-#define BTN_DPAD_DOWN  0x221
-#define BTN_DPAD_LEFT  0x222
-#define BTN_DPAD_RIGHT 0x223
+#  define BTN_DPAD_UP    0x220
+#  define BTN_DPAD_DOWN  0x221
+#  define BTN_DPAD_LEFT  0x222
+#  define BTN_DPAD_RIGHT 0x223
+#else
+assert_cc(BTN_DPAD_UP    == 0x220);
+assert_cc(BTN_DPAD_DOWN  == 0x221);
+assert_cc(BTN_DPAD_LEFT  == 0x222);
+assert_cc(BTN_DPAD_RIGHT == 0x223);
 #endif
 
 /* linux@358f24704f2f016af7d504b357cdf32606091d07 (3.13) */
 #ifndef KEY_ALS_TOGGLE
-#define KEY_ALS_TOGGLE 0x230
+#  fine KEY_ALS_TOGGLE 0x230
+#else
+assert_cc(KEY_ALS_TOGGLE == 0x230);
 #endif
index 9cbd17279f20a1c569ee7e96f60ee6cccbfadaf2..13ce7928a740cfe3a0c8d8e709beec2672677260 100644 (file)
@@ -1,49 +1,81 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <sched.h>
+#if HAVE_LINUX_IOPRIO_H
+#  include <linux/ioprio.h>
+#endif
+
+#include "macro.h"
 
 /* Match values uses by the kernel internally, as no public header seems to exist. */
 
 #ifndef IOPRIO_N_CLASSES
 #  define IOPRIO_N_CLASSES 8
+#else
+assert_cc(IOPRIO_N_CLASSES == 8);
 #endif
 
 #ifndef IOPRIO_BE_NR
 #  define IOPRIO_BE_NR 8
+#else
+assert_cc(IOPRIO_BE_NR == 8);
 #endif
 
 #ifndef IOPRIO_CLASS_NONE
 #  define IOPRIO_CLASS_NONE 0
+#else
+assert_cc(IOPRIO_CLASS_NONE == 0);
 #endif
 #ifndef IOPRIO_CLASS_RT
 #  define IOPRIO_CLASS_RT   1
+#else
+assert_cc(IOPRIO_CLASS_RT == 1);
 #endif
 #ifndef IOPRIO_CLASS_BE
 #  define IOPRIO_CLASS_BE   2
+#else
+assert_cc(IOPRIO_CLASS_BE == 2);
 #endif
 #ifndef IOPRIO_CLASS_IDLE
 #  define IOPRIO_CLASS_IDLE 3
+#else
+assert_cc(IOPRIO_CLASS_IDLE == 3);
 #endif
 
 #ifndef IOPRIO_WHO_PROCESS
 #  define IOPRIO_WHO_PROCESS 1
+#else
+assert_cc(IOPRIO_WHO_PROCESS == 1);
 #endif
+
 #ifndef IOPRIO_WHO_PGRP
 #  define IOPRIO_WHO_PGRP    2
+#else
+assert_cc(IOPRIO_WHO_PGRP == 2);
 #endif
+
 #ifndef IOPRIO_WHO_USER
 #  define IOPRIO_WHO_USER    3
+#else
+assert_cc(IOPRIO_WHO_USER == 3);
 #endif
 
 #ifndef IOPRIO_BITS
 #  define IOPRIO_BITS        16
+#else
+assert_cc(IOPRIO_BITS == 16);
 #endif
+
 #ifndef IOPRIO_N_CLASSES
 #  define IOPRIO_N_CLASSES    8
+#else
+assert_cc(IOPRIO_N_CLASSES == 8);
 #endif
+
 #ifndef IOPRIO_CLASS_SHIFT
 #  define IOPRIO_CLASS_SHIFT 13
+#else
+assert_cc(IOPRIO_CLASS_SHIFT == 13);
 #endif
 
 static inline int ioprio_prio_class(int value) {
index 081003a65a9a28eb63a70f00ffb62bc1be02ec9a..78795fa352b51af75cd205990e0b548f60bc3255 100644 (file)
@@ -4,40 +4,60 @@
 #include <inttypes.h>
 #include <linux/keyctl.h>
 
+#include "macro.h"
+
 #ifndef KEYCTL_JOIN_SESSION_KEYRING
-#define KEYCTL_JOIN_SESSION_KEYRING 1
+#  define KEYCTL_JOIN_SESSION_KEYRING 1
+#else
+assert_cc(KEYCTL_JOIN_SESSION_KEYRING == 1);
 #endif
 
 #ifndef KEYCTL_CHOWN
-#define KEYCTL_CHOWN 4
+#  define KEYCTL_CHOWN 4
+#else
+assert_cc(KEYCTL_CHOWN == 4);
 #endif
 
 #ifndef KEYCTL_SETPERM
-#define KEYCTL_SETPERM 5
+#  define KEYCTL_SETPERM 5
+#else
+assert_cc(KEYCTL_SETPERM == 5);
 #endif
 
 #ifndef KEYCTL_DESCRIBE
-#define KEYCTL_DESCRIBE 6
+#  define KEYCTL_DESCRIBE 6
+#else
+assert_cc(KEYCTL_DESCRIBE == 6);
 #endif
 
 #ifndef KEYCTL_LINK
-#define KEYCTL_LINK 8
+#  define KEYCTL_LINK 8
+#else
+assert_cc(KEYCTL_LINK == 8);
 #endif
 
 #ifndef KEYCTL_READ
-#define KEYCTL_READ 11
+#  define KEYCTL_READ 11
+#else
+assert_cc(KEYCTL_READ == 11);
 #endif
 
 #ifndef KEYCTL_SET_TIMEOUT
-#define KEYCTL_SET_TIMEOUT 15
+#  define KEYCTL_SET_TIMEOUT 15
+#else
+assert_cc(KEYCTL_SET_TIMEOUT == 15);
 #endif
 
 #ifndef KEY_SPEC_USER_KEYRING
-#define KEY_SPEC_USER_KEYRING -4
+#  define KEY_SPEC_USER_KEYRING -4
+#else
+assert_cc(KEY_SPEC_USER_KEYRING == -4);
 #endif
 
 #ifndef KEY_SPEC_SESSION_KEYRING
-#define KEY_SPEC_SESSION_KEYRING -3
+#  define KEY_SPEC_SESSION_KEYRING -3
+#else
+assert_cc(KEY_SPEC_SESSION_KEYRING == -3);
 #endif
 
 /* From linux/key.h */
 
 typedef int32_t key_serial_t;
 
-#define KEY_POS_VIEW    0x01000000
-#define KEY_POS_READ    0x02000000
-#define KEY_POS_WRITE   0x04000000
-#define KEY_POS_SEARCH  0x08000000
-#define KEY_POS_LINK    0x10000000
-#define KEY_POS_SETATTR 0x20000000
-#define KEY_POS_ALL     0x3f000000
-
-#define KEY_USR_VIEW    0x00010000
-#define KEY_USR_READ    0x00020000
-#define KEY_USR_WRITE   0x00040000
-#define KEY_USR_SEARCH  0x00080000
-#define KEY_USR_LINK    0x00100000
-#define KEY_USR_SETATTR 0x00200000
-#define KEY_USR_ALL     0x003f0000
-
-#define KEY_GRP_VIEW    0x00000100
-#define KEY_GRP_READ    0x00000200
-#define KEY_GRP_WRITE   0x00000400
-#define KEY_GRP_SEARCH  0x00000800
-#define KEY_GRP_LINK    0x00001000
-#define KEY_GRP_SETATTR 0x00002000
-#define KEY_GRP_ALL     0x00003f00
-
-#define KEY_OTH_VIEW    0x00000001
-#define KEY_OTH_READ    0x00000002
-#define KEY_OTH_WRITE   0x00000004
-#define KEY_OTH_SEARCH  0x00000008
-#define KEY_OTH_LINK    0x00000010
-#define KEY_OTH_SETATTR 0x00000020
-#define KEY_OTH_ALL     0x0000003f
+#  define KEY_POS_VIEW    0x01000000
+#  define KEY_POS_READ    0x02000000
+#  define KEY_POS_WRITE   0x04000000
+#  define KEY_POS_SEARCH  0x08000000
+#  define KEY_POS_LINK    0x10000000
+#  define KEY_POS_SETATTR 0x20000000
+#  define KEY_POS_ALL     0x3f000000
+
+#  define KEY_USR_VIEW    0x00010000
+#  define KEY_USR_READ    0x00020000
+#  define KEY_USR_WRITE   0x00040000
+#  define KEY_USR_SEARCH  0x00080000
+#  define KEY_USR_LINK    0x00100000
+#  define KEY_USR_SETATTR 0x00200000
+#  define KEY_USR_ALL     0x003f0000
+
+#  define KEY_GRP_VIEW    0x00000100
+#  define KEY_GRP_READ    0x00000200
+#  define KEY_GRP_WRITE   0x00000400
+#  define KEY_GRP_SEARCH  0x00000800
+#  define KEY_GRP_LINK    0x00001000
+#  define KEY_GRP_SETATTR 0x00002000
+#  define KEY_GRP_ALL     0x00003f00
+
+#  define KEY_OTH_VIEW    0x00000001
+#  define KEY_OTH_READ    0x00000002
+#  define KEY_OTH_WRITE   0x00000004
+#  define KEY_OTH_SEARCH  0x00000008
+#  define KEY_OTH_LINK    0x00000010
+#  define KEY_OTH_SETATTR 0x00000020
+#  define KEY_OTH_ALL     0x0000003f
+#else
+assert_cc(KEY_OTH_ALL == 0x0000003f);
 #endif
index 7141544b64f0256915e30c2bb60313caa2edd5c3..c29082f519bb07965646e9ed8713d29daea1c975 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/loop.h>
 
+#include "macro.h"
+
 #ifndef LOOP_CONFIGURE
 struct loop_config {
         __u32 fd;
@@ -11,14 +13,19 @@ struct loop_config {
         __u64 __reserved[8];
 };
 
-#define LOOP_CONFIGURE 0x4C0A
+#  define LOOP_CONFIGURE 0x4C0A
+#else
+assert_cc(LOOP_CONFIGURE == 0x4C0A);
 #endif
 
 #ifndef LO_FLAGS_DIRECT_IO
-#define LO_FLAGS_DIRECT_IO 16
-#define LOOP_SET_DIRECT_IO 0x4C08
+#  define LO_FLAGS_DIRECT_IO 16
+#  define LOOP_SET_DIRECT_IO 0x4C08
+#else
+assert_cc(LO_FLAGS_DIRECT_IO == 16);
+assert_cc(LO_FLAGS_DIRECT_IO == 0x4C08);
 #endif
 
 #ifndef LOOP_SET_STATUS_SETTABLE_FLAGS
-#define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN | LO_FLAGS_DIRECT_IO)
+#  define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN | LO_FLAGS_DIRECT_IO)
 #endif
index 82d71c8ad12337b3e64a25010ee8211fa93c2fd9..93a0d745772fca0a8e16852a11af69aff0117f56 100644 (file)
 
 /* 62aa81d7c4c24b90fdb61da70ac0dbbc414f9939 (4.13) */
 #ifndef OCFS2_SUPER_MAGIC
-#define OCFS2_SUPER_MAGIC 0x7461636f
+#  define OCFS2_SUPER_MAGIC 0x7461636f
+#else
+assert_cc(OCFS2_SUPER_MAGIC == 0x7461636f);
 #endif
 
 /* 67e9c74b8a873408c27ac9a8e4c1d1c8d72c93ff (4.5) */
 #ifndef CGROUP2_SUPER_MAGIC
-#define CGROUP2_SUPER_MAGIC 0x63677270
+#  define CGROUP2_SUPER_MAGIC 0x63677270
+#else
+assert_cc(CGROUP2_SUPER_MAGIC == 0x63677270);
 #endif
 
 /* 4282d60689d4f21b40692029080440cc58e8a17d (4.1) */
 #ifndef TRACEFS_MAGIC
-#define TRACEFS_MAGIC 0x74726163
+#  define TRACEFS_MAGIC 0x74726163
+#else
+assert_cc(TRACEFS_MAGIC == 0x74726163);
 #endif
 
 /* e149ed2b805fefdccf7ccdfc19eca22fdd4514ac (3.19) */
 #ifndef NSFS_MAGIC
-#define NSFS_MAGIC 0x6e736673
+#  define NSFS_MAGIC 0x6e736673
+#else
+assert_cc(NSFS_MAGIC == 0x6e736673);
 #endif
 
 /* b2197755b2633e164a439682fb05a9b5ea48f706 (4.4) */
 #ifndef BPF_FS_MAGIC
-#define BPF_FS_MAGIC 0xcafe4a11
+#  define BPF_FS_MAGIC 0xcafe4a11
+#else
+assert_cc(BPF_FS_MAGIC == 0xcafe4a11);
 #endif
 
 /* Not exposed yet (4.20). Defined at ipc/mqueue.c */
 #ifndef MQUEUE_MAGIC
-#define MQUEUE_MAGIC 0x19800202
+#  define MQUEUE_MAGIC 0x19800202
+#else
+assert_cc(MQUEUE_MAGIC == 0x19800202);
 #endif
 
 /* Not exposed yet (as of Linux 5.4). Defined in fs/xfs/libxfs/xfs_format.h */
 #ifndef XFS_SB_MAGIC
-#define XFS_SB_MAGIC 0x58465342
+#  define XFS_SB_MAGIC 0x58465342
+#else
+assert_cc(XFS_SB_MAGIC == 0x58465342);
 #endif
 
 /* dea2903719283c156b53741126228c4a1b40440f (5.17) */
 #ifndef CIFS_SUPER_MAGIC
-#define CIFS_SUPER_MAGIC 0xFF534D42
+#  define CIFS_SUPER_MAGIC 0xFF534D42
+#else
+assert_cc(CIFS_SUPER_MAGIC == 0xFF534D42);
 #endif
 
 /* dea2903719283c156b53741126228c4a1b40440f (5.17) */
 #ifndef SMB2_SUPER_MAGIC
-#define SMB2_SUPER_MAGIC 0xFE534D42
+#  define SMB2_SUPER_MAGIC 0xFE534D42
+#else
+assert_cc(SMB2_SUPER_MAGIC == 0xFE534D42);
 #endif
 
 /* 257f871993474e2bde6c497b54022c362cf398e1 (4.5) */
 #ifndef OVERLAYFS_SUPER_MAGIC
-#define OVERLAYFS_SUPER_MAGIC 0x794c7630
+#  define OVERLAYFS_SUPER_MAGIC 0x794c7630
+#else
+assert_cc(OVERLAYFS_SUPER_MAGIC == 0x794c7630);
 #endif
 
 /* 2a28900be20640fcd1e548b1e3bad79e8221fcf9 (4.7) */
 #ifndef UDF_SUPER_MAGIC
-#define UDF_SUPER_MAGIC 0x15013346
+#  define UDF_SUPER_MAGIC 0x15013346
+#else
+assert_cc(UDF_SUPER_MAGIC == 0x15013346);
 #endif
 
 /* b1123ea6d3b3da25af5c8a9d843bd07ab63213f4 (4.8) */
 #ifndef BALLOON_KVM_MAGIC
-#define BALLOON_KVM_MAGIC 0x13661366
+#  define BALLOON_KVM_MAGIC 0x13661366
+#else
+assert_cc(BALLOON_KVM_MAGIC == 0x13661366);
 #endif
 
 /* 48b4800a1c6af2cdda344ea4e2c843dcc1f6afc9 (4.8) */
 #ifndef ZSMALLOC_MAGIC
-#define ZSMALLOC_MAGIC 0x58295829
+#  define ZSMALLOC_MAGIC 0x58295829
+#else
+assert_cc(ZSMALLOC_MAGIC == 0x58295829);
 #endif
 
 /* 3bc52c45bac26bf7ed1dc8d287ad1aeaed1250b6 (4.9) */
 #ifndef DAXFS_MAGIC
-#define DAXFS_MAGIC 0x64646178
+#  define DAXFS_MAGIC 0x64646178
+#else
+assert_cc(DAXFS_MAGIC == 0x64646178);
 #endif
 
 /* 5ff193fbde20df5d80fec367cea3e7856c057320 (4.10) */
 #ifndef RDTGROUP_SUPER_MAGIC
-#define RDTGROUP_SUPER_MAGIC 0x7655821
+#  define RDTGROUP_SUPER_MAGIC 0x7655821
+#else
+assert_cc(RDTGROUP_SUPER_MAGIC == 0x7655821);
 #endif
 
 /* a481f4d917835cad86701fc0d1e620c74bb5cd5f (4.13) */
 #ifndef AAFS_MAGIC
-#define AAFS_MAGIC 0x5a3c69f0
+#  define AAFS_MAGIC 0x5a3c69f0
+#else
+assert_cc(AAFS_MAGIC == 0x5a3c69f0);
 #endif
 
 /* f044c8847bb61eff5e1e95b6f6bb950e7f4a73a4 (4.15) */
 #ifndef AFS_FS_MAGIC
-#define AFS_FS_MAGIC 0x6b414653
+#  define AFS_FS_MAGIC 0x6b414653
+#else
+assert_cc(AFS_FS_MAGIC == 0x6b414653);
 #endif
 
 /* dddde68b8f06dd83486124b8d245e7bfb15c185d (4.20) */
 #ifndef XFS_SUPER_MAGIC
-#define XFS_SUPER_MAGIC 0x58465342
+#  define XFS_SUPER_MAGIC 0x58465342
+#else
+assert_cc(XFS_SUPER_MAGIC == 0x58465342);
 #endif
 
 /* 3ad20fe393b31025bebfc2d76964561f65df48aa (5.0) */
 #ifndef BINDERFS_SUPER_MAGIC
-#define BINDERFS_SUPER_MAGIC 0x6c6f6f70
+#  define BINDERFS_SUPER_MAGIC 0x6c6f6f70
+#else
+assert_cc(BINDERFS_SUPER_MAGIC == 0x6c6f6f70);
 #endif
 
 /* ed63bb1d1f8469586006a9ca63c42344401aa2ab (5.3) */
 #ifndef DMA_BUF_MAGIC
-#define DMA_BUF_MAGIC 0x444d4142
+#  define DMA_BUF_MAGIC 0x444d4142
+#else
+assert_cc(DMA_BUF_MAGIC == 0x444d4142);
 #endif
 
 /* ea8157ab2ae5e914dd427e5cfab533b6da3819cd (5.3) */
 #ifndef Z3FOLD_MAGIC
-#define Z3FOLD_MAGIC 0x33
+#  define Z3FOLD_MAGIC 0x33
+#else
+assert_cc(Z3FOLD_MAGIC == 0x33);
 #endif
 
 /* 47e4937a4a7ca4184fd282791dfee76c6799966a (5.4) */
 #ifndef EROFS_SUPER_MAGIC_V1
-#define EROFS_SUPER_MAGIC_V1 0xe0f5e1e2
+#  define EROFS_SUPER_MAGIC_V1 0xe0f5e1e2
+#else
+assert_cc(EROFS_SUPER_MAGIC_V1 == 0xe0f5e1e2);
 #endif
 
 /* fe030c9b85e6783bc52fe86449c0a4b8aa16c753 (5.5) */
 #ifndef PPC_CMM_MAGIC
-#define PPC_CMM_MAGIC 0xc7571590
+#  define PPC_CMM_MAGIC 0xc7571590
+#else
+assert_cc(PPC_CMM_MAGIC == 0xc7571590);
 #endif
 
 /* 8dcc1a9d90c10fa4143e5c17821082e5e60e46a1 (5.6) */
 #ifndef ZONEFS_MAGIC
-#define ZONEFS_MAGIC 0x5a4f4653
+#  define ZONEFS_MAGIC 0x5a4f4653
+#else
+assert_cc(ZONEFS_MAGIC == 0x5a4f4653);
 #endif
 
 /* 3234ac664a870e6ea69ae3a57d824cd7edbeacc5 (5.8) */
 #ifndef DEVMEM_MAGIC
-#define DEVMEM_MAGIC 0x454d444d
+#  define DEVMEM_MAGIC 0x454d444d
+#else
+assert_cc(DEVMEM_MAGIC == 0x454d444d);
 #endif
 
 /* cb12fd8e0dabb9a1c8aef55a6a41e2c255fcdf4b (6.8) */
 #ifndef PID_FS_MAGIC
-#define PID_FS_MAGIC 0x50494446
+#  define PID_FS_MAGIC 0x50494446
+#else
+assert_cc(PID_FS_MAGIC == 0x50494446);
 #endif
 
 /* Not in mainline but included in Ubuntu */
 #ifndef SHIFTFS_MAGIC
-#define SHIFTFS_MAGIC 0x6a656a62
+#  define SHIFTFS_MAGIC 0x6a656a62
+#else
+assert_cc(SHIFTFS_MAGIC == 0x6a656a62);
 #endif
 
 /* 1507f51255c9ff07d75909a84e7c0d7f3c4b2f49 (5.14) */
 #ifndef SECRETMEM_MAGIC
-#define SECRETMEM_MAGIC 0x5345434d
+#  define SECRETMEM_MAGIC 0x5345434d
+#else
+assert_cc(SECRETMEM_MAGIC == 0x5345434d);
 #endif
 
 /* Not exposed yet. Defined at fs/fuse/inode.c */
 #ifndef FUSE_SUPER_MAGIC
-#define FUSE_SUPER_MAGIC 0x65735546
+#  define FUSE_SUPER_MAGIC 0x65735546
+#else
+assert_cc(FUSE_SUPER_MAGIC == 0x65735546);
 #endif
 
 /* Not exposed yet. Defined at fs/fuse/control.c */
 #ifndef FUSE_CTL_SUPER_MAGIC
-#define FUSE_CTL_SUPER_MAGIC 0x65735543
+#  define FUSE_CTL_SUPER_MAGIC 0x65735543
+#else
+assert_cc(FUSE_CTL_SUPER_MAGIC == 0x65735543);
 #endif
 
 /* Not exposed yet. Defined at fs/ceph/super.h */
 #ifndef CEPH_SUPER_MAGIC
-#define CEPH_SUPER_MAGIC 0x00c36400
+#  define CEPH_SUPER_MAGIC 0x00c36400
+#else
+assert_cc(CEPH_SUPER_MAGIC == 0x00c36400);
 #endif
 
 /* Not exposed yet. Defined at fs/orangefs/orangefs-kernel.h */
 #ifndef ORANGEFS_DEVREQ_MAGIC
-#define ORANGEFS_DEVREQ_MAGIC 0x20030529
+#  define ORANGEFS_DEVREQ_MAGIC 0x20030529
+#else
+assert_cc(ORANGEFS_DEVREQ_MAGIC == 0x20030529);
 #endif
 
 /* linux/gfs2_ondisk.h */
 #ifndef GFS2_MAGIC
-#define GFS2_MAGIC 0x01161970
+#  define GFS2_MAGIC 0x01161970
+#else
+assert_cc(GFS2_MAGIC == 0x01161970);
 #endif
 
 /* Not exposed yet. Defined at fs/configfs/mount.c */
 #ifndef CONFIGFS_MAGIC
-#define CONFIGFS_MAGIC 0x62656570
+#  define CONFIGFS_MAGIC 0x62656570
+#else
+assert_cc(CONFIGFS_MAGIC == 0x62656570);
 #endif
 
 /* Not exposed yet. Defined at fs/vboxsf/super.c */
 #ifndef VBOXSF_SUPER_MAGIC
-#define VBOXSF_SUPER_MAGIC 0x786f4256
+#  define VBOXSF_SUPER_MAGIC 0x786f4256
+#else
+assert_cc(VBOXSF_SUPER_MAGIC == 0x786f4256);
 #endif
 
 /* Not exposed yet. Defined at fs/exfat/exfat_fs.h */
 #ifndef EXFAT_SUPER_MAGIC
-#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
+#  define EXFAT_SUPER_MAGIC 0x2011BAB0UL
+#else
+assert_cc(EXFAT_SUPER_MAGIC == 0x2011BAB0UL);
 #endif
 
 /* Not exposed yet, internally actually called RPCAUTH_GSSMAGIC. Defined in net/sunrpc/rpc_pipe.c */
 #ifndef RPC_PIPEFS_SUPER_MAGIC
-#define RPC_PIPEFS_SUPER_MAGIC 0x67596969
+#  define RPC_PIPEFS_SUPER_MAGIC 0x67596969
+#else
+assert_cc(RPC_PIPEFS_SUPER_MAGIC == 0x67596969);
 #endif
 
 /* Not exposed yet, defined at fs/ntfs/ntfs.h */
 #ifndef NTFS_SB_MAGIC
-#define NTFS_SB_MAGIC 0x5346544e
+#  define NTFS_SB_MAGIC 0x5346544e
+#else
+assert_cc(NTFS_SB_MAGIC == 0x5346544e);
 #endif
 
 /* Not exposed yet, encoded literally in fs/ntfs3/super.c. */
 #ifndef NTFS3_SUPER_MAGIC
-#define NTFS3_SUPER_MAGIC 0x7366746e
+#  define NTFS3_SUPER_MAGIC 0x7366746e
+#else
+assert_cc(NTFS3_SUPER_MAGIC == 0x7366746e);
 #endif
index f48c436dca287b43382663366d7f56be8a4e3f13..d6a8b4bb9e64ef9ac294f9a8070d95feb75eb1bc 100644 (file)
@@ -3,18 +3,28 @@
 
 #include <sys/mman.h>
 
+#include "macro.h"
+
 #ifndef MFD_ALLOW_SEALING
-#define MFD_ALLOW_SEALING 0x0002U
+#  define MFD_ALLOW_SEALING 0x0002U
+#else
+assert_cc(MFD_ALLOW_SEALING == 0x0002U);
 #endif
 
 #ifndef MFD_CLOEXEC
-#define MFD_CLOEXEC 0x0001U
+#  define MFD_CLOEXEC 0x0001U
+#else
+assert_cc(MFD_CLOEXEC == 0x0001U);
 #endif
 
 #ifndef MFD_NOEXEC_SEAL
-#define MFD_NOEXEC_SEAL 0x0008U
+#  define MFD_NOEXEC_SEAL 0x0008U
+#else
+assert_cc(MFD_NOEXEC_SEAL == 0x0008U);
 #endif
 
 #ifndef MFD_EXEC
-#define MFD_EXEC 0x0010U
+#  define MFD_EXEC 0x0010U
+#else
+assert_cc(MFD_EXEC == 0x0010U);
 #endif
index 69b0bcfcbfe65c44830fe12ab1acc7d7f6e611b1..d6e16e556e50935c6e92151e91bb6c69bd6491c1 100644 (file)
@@ -3,7 +3,11 @@
 
 #include <sys/mount.h>
 
+#include "macro.h"
+
 /* dab741e0e02bd3c4f5e2e97be74b39df2523fc6e (5.10) */
 #ifndef MS_NOSYMFOLLOW
-#define MS_NOSYMFOLLOW 256
+#  define MS_NOSYMFOLLOW 256
+#else
+assert_cc(MS_NOSYMFOLLOW == 256);
 #endif
index 7d9e395c921419e17a4833a86f93835ca83db641..2c9f9f6c50ffe00802f0f11cb0b9a31a3598ae66 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/prctl.h>
 
+#include "macro.h"
+
 /* 58319057b7847667f0c9585b9de0e8932b0fdb08 (4.3) */
 #ifndef PR_CAP_AMBIENT
 #define PR_CAP_AMBIENT 47
 
 /* b507808ebce23561d4ff8c2aa1fb949fe402bc61 (6.3) */
 #ifndef PR_SET_MDWE
-#define PR_SET_MDWE 65
+#  define PR_SET_MDWE 65
+#else
+assert_cc(PR_SET_MDWE == 65);
 #endif
+
 #ifndef PR_MDWE_REFUSE_EXEC_GAIN
-#define PR_MDWE_REFUSE_EXEC_GAIN 1
+#  define PR_MDWE_REFUSE_EXEC_GAIN 1
+#else
+assert_cc(PR_MDWE_REFUSE_EXEC_GAIN == 1);
 #endif
 
 #ifndef PR_SET_MEMORY_MERGE
-#define PR_SET_MEMORY_MERGE 67
+#  define PR_SET_MEMORY_MERGE 67
+#else
+assert_cc(PR_SET_MEMORY_MERGE == 67);
 #endif
index 443b91368558934697d6d2832cd2346d8a81909d..0f8a5be0a233abdf8b5e0d0b0f3d77ec834d145a 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include "macro.h"
+
 #if USE_SYS_RANDOM_H
 #  include <sys/random.h>
 #else
 #endif
 
 #ifndef GRND_NONBLOCK
-#define GRND_NONBLOCK 0x0001
+#  define GRND_NONBLOCK 0x0001
+#else
+assert_cc(GRND_NONBLOCK == 0x0001);
 #endif
 
 #ifndef GRND_RANDOM
-#define GRND_RANDOM 0x0002
+#  define GRND_RANDOM 0x0002
+#else
+assert_cc(GRND_RANDOM == 0x0002);
 #endif
 
 #ifndef GRND_INSECURE
-#define GRND_INSECURE 0x0004
+#  define GRND_INSECURE 0x0004
+#else
+assert_cc(GRND_INSECURE == 0x0004);
 #endif
index 6e7676527be8d344afbf2ff6aa4005fcb853bc7a..18076736c7f1a899c02013d48d8854f17eb758d3 100644 (file)
@@ -3,8 +3,12 @@
 
 #include <sys/resource.h>
 
+#include "macro.h"
+
 #ifndef RLIMIT_RTTIME
-#define RLIMIT_RTTIME 15
+#  define RLIMIT_RTTIME 15
+#else
+assert_cc(RLIMIT_RTTIME == 15);
 #endif
 
 /* If RLIMIT_RTTIME is not defined, then we cannot use RLIMIT_NLIMITS as is */
index bcd5b7712060188ba6f65d26dd7072ddc840579b..b8109d30ac60fd8e38a3a628c6a0739d3a3cb649 100644 (file)
@@ -3,24 +3,35 @@
 
 #include <sched.h>
 
+#include "macro.h"
+
 #ifndef CLONE_NEWCGROUP
-#define CLONE_NEWCGROUP 0x02000000
+#  define CLONE_NEWCGROUP 0x02000000
+#else
+assert_cc(CLONE_NEWCGROUP == 0x02000000);
 #endif
 
 /* 769071ac9f20b6a447410c7eaa55d1a5233ef40c (5.8) */
 #ifndef CLONE_NEWTIME
-#define CLONE_NEWTIME 0x00000080
+#  define CLONE_NEWTIME 0x00000080
+#else
+assert_cc(CLONE_NEWTIME == 0x00000080);
 #endif
 
 /* Not exposed yet. Defined at include/linux/sched.h */
 #ifndef PF_KTHREAD
-#define PF_KTHREAD 0x00200000
+#  define PF_KTHREAD 0x00200000
+#else
+assert_cc(PF_KTHREAD == 0x00200000);
 #endif
 
-/* The maximum thread/process name length including trailing NUL byte. This mimics the kernel definition of the same
- * name, which we need in userspace at various places but is not defined in userspace currently, neither under this
- * name nor any other. */
-/* Not exposed yet. Defined at include/linux/sched.h */
+/* The maximum thread/process name length including trailing NUL byte. This mimics the kernel definition of
+ * the same name, which we need in userspace at various places but is not defined in userspace currently,
+ * neither under this name nor any other.
+ *
+ * Not exposed yet. Defined at include/linux/sched.h */
 #ifndef TASK_COMM_LEN
-#define TASK_COMM_LEN 16
+#  define TASK_COMM_LEN 16
+#else
+assert_cc(TASK_COMM_LEN == 16);
 #endif
index dba3043d2264f0e43cb1b42a224fcd0010e51a2f..a01a4eca3aa1248b42928c6c774f0c150c7b764c 100644 (file)
@@ -3,6 +3,10 @@
 
 #include <sys/timerfd.h>
 
+#include "macro.h"
+
 #ifndef TFD_TIMER_CANCEL_ON_SET
-#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#  define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#else
+assert_cc(TFD_TIMER_CANCEL_ON_SET == (1 << 1));
 #endif
index f6233090a905c195b104196e1402359d745f8733..1d17705c356b1b86ca249df3de1f20ee10596051 100644 (file)
@@ -4,9 +4,9 @@
 #include <uchar.h>
 
 #if !HAVE_CHAR32_T
-#define char32_t uint32_t
+#  define char32_t uint32_t
 #endif
 
 #if !HAVE_CHAR16_T
-#define char16_t uint16_t
+#  define char16_t uint16_t
 #endif
index a24779d977a879cfd93e4d9b1956f314103cf851..3965b5bdbfbc4debca48ad24ea6679d320699b42 100644 (file)
@@ -3,6 +3,10 @@
 
 #include <sys/wait.h>
 
+#include "macro.h"
+
 #ifndef P_PIDFD
-#define P_PIDFD 3
+#  define P_PIDFD 3
+#else
+assert_cc(P_PIDFD == 3);
 #endif
index 06fa219bd197552c8be61b07e3e9e789f016ce15..7097a2cc128da1eb5638e26ae1c9459e3d081977 100644 (file)
@@ -4,7 +4,21 @@
 #include "string-util.h"
 #include "strv.h"
 
+const char* nulstr_get(const char *nulstr, const char *needle) {
+        if (!nulstr)
+                return NULL;
+
+        NULSTR_FOREACH(i, nulstr)
+                if (streq(i, needle))
+                        return i;
+
+        return NULL;
+}
+
 char** strv_parse_nulstr_full(const char *s, size_t l, bool drop_trailing_nuls) {
+        _cleanup_strv_free_ char **v = NULL;
+        size_t c = 0, i = 0;
+
         /* l is the length of the input data, which will be split at NULs into elements of the resulting
          * strv. Hence, the number of items in the resulting strv will be equal to one plus the number of NUL
          * bytes in the l bytes starting at s, unless s[l-1] is NUL, in which case the final empty string is
@@ -13,9 +27,6 @@ char** strv_parse_nulstr_full(const char *s, size_t l, bool drop_trailing_nuls)
          * Note that contrary to a normal nulstr which cannot contain empty strings, because the input data
          * is terminated by any two consequent NUL bytes, this parser accepts empty strings in s. */
 
-        _cleanup_strv_free_ char **v = NULL;
-        size_t c = 0, i = 0;
-
         assert(s || l <= 0);
 
         if (drop_trailing_nuls)
@@ -36,7 +47,7 @@ char** strv_parse_nulstr_full(const char *s, size_t l, bool drop_trailing_nuls)
         if (!v)
                 return NULL;
 
-        for (const char *p = s; p < s + l; ) {
+        for (const char *p = s; p < s + l;) {
                 const char *e;
 
                 e = memchr(p, 0, s + l - p);
@@ -44,7 +55,6 @@ char** strv_parse_nulstr_full(const char *s, size_t l, bool drop_trailing_nuls)
                 v[i] = memdup_suffix0(p, e ? e - p : s + l - p);
                 if (!v[i])
                         return NULL;
-
                 i++;
 
                 if (!e)
@@ -74,6 +84,9 @@ char** strv_split_nulstr(const char *s) {
 }
 
 int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
+        _cleanup_free_ char *m = NULL;
+        size_t n = 0;
+
         /* Builds a nulstr and returns it together with the size. An extra NUL byte will be appended (⚠️ but
          * not included in the size! ⚠️). This is done so that the nulstr can be used both in
          * strv_parse_nulstr() and in NULSTR_FOREACH()/strv_split_nulstr() contexts, i.e. with and without a
@@ -84,21 +97,18 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
          * NUL bytes (which it will, if not empty). To ensure that this assumption *always* holds, we'll
          * return a buffer with two NUL bytes in that case, but return a size of zero. */
 
-        _cleanup_free_ char *m = NULL;
-        size_t n = 0;
-
         assert(ret);
 
         STRV_FOREACH(i, l) {
                 size_t z;
 
-                z = strlen(*i);
+                z = strlen(*i) + 1;
 
-                if (!GREEDY_REALLOC(m, n + z + 2))
+                if (!GREEDY_REALLOC(m, n + z + 1)) /* One extra NUL at the end as marker */
                         return -ENOMEM;
 
-                memcpy(m + n, *i, z + 1);
-                n += z + 1;
+                memcpy(m + n, *i, z);
+                n += z;
         }
 
         if (!m) {
@@ -109,7 +119,7 @@ int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
 
                 n = 0;
         } else
-                /* Make sure there is a second extra NUL at the end of resulting nulstr (not counted in return size) */
+                /* Extra NUL is not counted in size returned */
                 m[n] = '\0';
 
         *ret = TAKE_PTR(m);
@@ -132,14 +142,3 @@ int set_make_nulstr(Set *s, char **ret, size_t *ret_size) {
 
         return strv_make_nulstr(strv, ret, ret_size);
 }
-
-const char* nulstr_get(const char *nulstr, const char *needle) {
-        if (!nulstr)
-                return NULL;
-
-        NULSTR_FOREACH(i, nulstr)
-                if (streq(i, needle))
-                        return i;
-
-        return NULL;
-}
index d7bc5fd1ced9523ad8ce1bfc3d42136a19520237..d6f2f58e9fd5062f8bd5f8abef04570f37ff98bc 100644 (file)
@@ -15,7 +15,6 @@
         for (typeof(*(l)) *(i) = (l), *(j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
 
 const char* nulstr_get(const char *nulstr, const char *needle);
-
 static inline bool nulstr_contains(const char *nulstr, const char *needle) {
         return nulstr_get(nulstr, needle);
 }
@@ -25,9 +24,6 @@ static inline char** strv_parse_nulstr(const char *s, size_t l) {
         return strv_parse_nulstr_full(s, l, false);
 }
 char** strv_split_nulstr(const char *s);
-int strv_make_nulstr(char * const *l, char **p, size_t *n);
-int set_make_nulstr(Set *s, char **ret, size_t *ret_size);
-
 static inline int strv_from_nulstr(char ***ret, const char *nulstr) {
         char **t;
 
@@ -40,3 +36,6 @@ static inline int strv_from_nulstr(char ***ret, const char *nulstr) {
         *ret = t;
         return 0;
 }
+
+int strv_make_nulstr(char * const *l, char **p, size_t *n);
+int set_make_nulstr(Set *s, char **ret, size_t *ret_size);
index e7fc4a7f06922d0be04210bc3577b8f5dcd14022..540256b73b84300e39db52bc81e5ffcebb01c370 100644 (file)
@@ -92,7 +92,6 @@ int xdg_user_data_dir(char **ret, const char *suffix) {
 }
 
 int runtime_directory(char **ret, RuntimeScope scope, const char *suffix) {
-        _cleanup_free_ char *d = NULL;
         int r;
 
         assert(ret);
@@ -106,26 +105,20 @@ int runtime_directory(char **ret, RuntimeScope scope, const char *suffix) {
          * Return value indicates whether the suffix was applied or not */
 
         const char *e = secure_getenv("RUNTIME_DIRECTORY");
-        if (e) {
-                d = strdup(e);
-                if (!d)
-                        return -ENOMEM;
-
-                *ret = TAKE_PTR(d);
-                return false;
-        }
+        if (e)
+                return strdup_to(ret, e);
 
         if (scope == RUNTIME_SCOPE_USER) {
-                r = xdg_user_runtime_dir(&d, suffix);
+                r = xdg_user_runtime_dir(ret, suffix);
                 if (r < 0)
                         return r;
         } else {
-                d = path_join("/run", suffix);
+                char *d = path_join("/run", suffix);
                 if (!d)
                         return -ENOMEM;
+                *ret = d;
         }
 
-        *ret = TAKE_PTR(d);
         return true;
 }
 
index 05a21f8f8e271deab4a9f693d9ab478bb64a8383..4d335c64eeda287fa27c1ae2fe8b608b42ccb6f7 100644 (file)
@@ -1094,7 +1094,6 @@ int path_extract_filename(const char *path, char **ret) {
 }
 
 int path_extract_directory(const char *path, char **ret) {
-        _cleanup_free_ char *a = NULL;
         const char *c, *next = NULL;
         int r;
 
@@ -1118,14 +1117,10 @@ int path_extract_directory(const char *path, char **ret) {
                 if (*path != '/') /* filename only */
                         return -EDESTADDRREQ;
 
-                a = strdup("/");
-                if (!a)
-                        return -ENOMEM;
-                *ret = TAKE_PTR(a);
-                return 0;
+                return strdup_to(ret, "/");
         }
 
-        a = strndup(path, next - path);
+        _cleanup_free_ char *a = strndup(path, next - path);
         if (!a)
                 return -ENOMEM;
 
index 47699e6414210e7efb2f9464068019664f5beda3..6d88c54d7f0bdad66912d6f9f813ce49e85b7814 100644 (file)
@@ -105,10 +105,6 @@ static inline int path_simplify_alloc(const char *path, char **ret) {
         return 0;
 }
 
-static inline bool path_equal_ptr(const char *a, const char *b) {
-        return !!a == !!b && (!a || path_equal(a, b));
-}
-
 /* Note: the search terminates on the first NULL item. */
 #define PATH_IN_SET(p, ...) path_strv_contains(STRV_MAKE(__VA_ARGS__), p)
 
index 522d8de1f4fe65196f60ca81e74f70eace011337..ce1ba3a1eabe00a1485bf3a829cbe3fd2369759b 100644 (file)
@@ -116,16 +116,8 @@ int proc_cmdline(char **ret) {
 
         /* For testing purposes it is sometimes useful to be able to override what we consider /proc/cmdline to be */
         e = secure_getenv("SYSTEMD_PROC_CMDLINE");
-        if (e) {
-                char *m;
-
-                m = strdup(e);
-                if (!m)
-                        return -ENOMEM;
-
-                *ret = m;
-                return 0;
-        }
+        if (e)
+                return strdup_to(ret, e);
 
         if (detect_container() > 0)
                 return pid_get_cmdline(1, SIZE_MAX, 0, ret);
index 69635e65f81f9bb727e8de0f254441141c889a43..351b5e4095924fd4b63505c358940f91e8e839ca 100644 (file)
@@ -1022,7 +1022,6 @@ int kill_and_sigcont(pid_t pid, int sig) {
 
 int getenv_for_pid(pid_t pid, const char *field, char **ret) {
         _cleanup_fclose_ FILE *f = NULL;
-        char *value = NULL;
         const char *path;
         size_t sum = 0;
         int r;
@@ -1031,22 +1030,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
         assert(field);
         assert(ret);
 
-        if (pid == 0 || pid == getpid_cached()) {
-                const char *e;
-
-                e = getenv(field);
-                if (!e) {
-                        *ret = NULL;
-                        return 0;
-                }
-
-                value = strdup(e);
-                if (!value)
-                        return -ENOMEM;
-
-                *ret = value;
-                return 1;
-        }
+        if (pid == 0 || pid == getpid_cached())
+                return strdup_to_full(ret, getenv(field));
 
         if (!pid_is_valid(pid))
                 return -EINVAL;
@@ -1075,14 +1060,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
                 sum += r;
 
                 match = startswith(line, field);
-                if (match && *match == '=') {
-                        value = strdup(match + 1);
-                        if (!value)
-                                return -ENOMEM;
-
-                        *ret = value;
-                        return 1;
-                }
+                if (match && *match == '=')
+                        return strdup_to_full(ret, match + 1);
         }
 
         *ret = NULL;
index 68e6afc67fc162de913d66d5d668ab29288e20a4..5eb8e4c98855ba4585f22073064e0896e7b5ae86 100644 (file)
@@ -453,6 +453,7 @@ int sockaddr_pretty(
 
         assert(sa);
         assert(salen >= sizeof(sa->sa.sa_family));
+        assert(ret);
 
         switch (sa->sa.sa_family) {
 
@@ -634,6 +635,7 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret)
 
         assert(sa);
         assert(salen > sizeof(sa_family_t));
+        assert(ret);
 
         r = getnameinfo(sa, salen, host, sizeof(host), /* service= */ NULL, /* service_len= */ 0, IDN_FLAGS);
         if (r != 0) {
@@ -647,15 +649,7 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret)
                 return sockaddr_pretty(sa, salen, /* translate_ipv6= */ true, /* include_port= */ true, ret);
         }
 
-        if (ret) {
-                char *copy = strdup(host);
-                if (!copy)
-                        return -ENOMEM;
-
-                *ret = copy;
-        }
-
-        return 0;
+        return strdup_to(ret, host);
 }
 
 static const char* const netlink_family_table[] = {
index c208d7c59dcd3d47522bfdcb350ba77d855dab12..a833aa260cc967948bf15ef4160e1ef45fdccbeb 100644 (file)
@@ -229,7 +229,7 @@ int null_or_empty_path_with_root(const char *fn, const char *root) {
          * When looking under root_dir, we can't expect /dev/ to be mounted,
          * so let's see if the path is a (possibly dangling) symlink to /dev/null. */
 
-        if (path_equal_ptr(path_startswith(fn, root ?: "/"), "dev/null"))
+        if (path_equal(path_startswith(fn, root ?: "/"), "dev/null"))
                 return true;
 
         r = chase_and_stat(fn, root, CHASE_PREFIX_ROOT, NULL, &st);
index c1e7e6e62248b4cb371af8ced124890854150b56..7f6c87b4613fde9c2d04aeffe4a15a1a6f20905d 100644 (file)
@@ -1126,6 +1126,24 @@ int free_and_strndup(char **p, const char *s, size_t l) {
         return 1;
 }
 
+int strdup_to_full(char **ret, const char *src) {
+        if (!src) {
+                if (ret)
+                        *ret = NULL;
+
+                return 0;
+        } else {
+                if (ret) {
+                        char *t = strdup(src);
+                        if (!t)
+                                return -ENOMEM;
+                        *ret = t;
+                }
+
+                return 1;
+        }
+};
+
 bool string_is_safe(const char *p) {
         if (!p)
                 return false;
@@ -1235,36 +1253,15 @@ int string_extract_line(const char *s, size_t i, char **ret) {
                                         return -ENOMEM;
 
                                 *ret = m;
-                                return !isempty(q + 1); /* more coming? */
-                        } else {
-                                if (p == s)
-                                        *ret = NULL; /* Just use the input string */
-                                else {
-                                        char *m;
-
-                                        m = strdup(p);
-                                        if (!m)
-                                                return -ENOMEM;
-
-                                        *ret = m;
-                                }
-
-                                return 0; /* The end */
-                        }
+                                return !isempty(q + 1); /* More coming? */
+                        } else
+                                /* Tell the caller to use the input string if equal */
+                                return strdup_to(ret, p != s ? p : NULL);
                 }
 
-                if (!q) {
-                        char *m;
-
+                if (!q)
                         /* No more lines, return empty line */
-
-                        m = strdup("");
-                        if (!m)
-                                return -ENOMEM;
-
-                        *ret = m;
-                        return 0; /* The end */
-                }
+                        return strdup_to(ret, "");
 
                 p = q + 1;
                 c++;
index e162765aa7174a8113952e2b606b5c22b09cb482..a68f3c94abc4180601c885a8a28c43fc31f4217a 100644 (file)
@@ -224,6 +224,12 @@ static inline int free_and_strdup_warn(char **p, const char *s) {
 }
 int free_and_strndup(char **p, const char *s, size_t l);
 
+int strdup_to_full(char **ret, const char *src);
+static inline int strdup_to(char **ret, const char *src) {
+        int r = strdup_to_full(ASSERT_PTR(ret), src);
+        return r < 0 ? r : 0;  /* Suppress return value of 1. */
+}
+
 bool string_is_safe(const char *p) _pure_;
 
 DISABLE_WARNING_STRINGOP_TRUNCATION;
@@ -297,25 +303,4 @@ bool version_is_valid_versionspec(const char *s);
 
 ssize_t strlevenshtein(const char *x, const char *y);
 
-static inline int strdup_or_null(const char *s, char **ret) {
-        char *c;
-
-        assert(ret);
-
-        /* This is a lot like strdup(), but is happy with NULL strings, and does not treat that as error, but
-         * copies the NULL value. */
-
-        if (!s) {
-                *ret = NULL;
-                return 0;
-        }
-
-        c = strdup(s);
-        if (!c)
-                return -ENOMEM;
-
-        *ret = c;
-        return 1;
-}
-
 char *strrstr(const char *haystack, const char *needle);
index 8b5a9fa8c68ffbb266683ee95ffb1656858ee9e8..518412ec36d1d3df2600e04ecde046ea7ec1a360 100644 (file)
@@ -697,18 +697,10 @@ int vtnr_from_tty(const char *tty) {
                 tty = active;
         }
 
-        if (tty == active)
-                *ret = TAKE_PTR(active);
-        else {
-                char *tmp;
-
-                tmp = strdup(tty);
-                if (!tmp)
-                        return -ENOMEM;
-
-                *ret = tmp;
-        }
+        if (tty != active)
+                return strdup_to(ret, tty);
 
+        *ret = TAKE_PTR(active);
         return 0;
 }
 
@@ -988,7 +980,7 @@ bool on_tty(void) {
 }
 
 int getttyname_malloc(int fd, char **ret) {
-        char path[PATH_MAX], *c; /* PATH_MAX is counted *with* the trailing NUL byte */
+        char path[PATH_MAX]; /* PATH_MAX is counted *with* the trailing NUL byte */
         int r;
 
         assert(fd >= 0);
@@ -1001,12 +993,7 @@ int getttyname_malloc(int fd, char **ret) {
         if (r > 0)
                 return -r;
 
-        c = strdup(skip_dev_prefix(path));
-        if (!c)
-                return -ENOMEM;
-
-        *ret = c;
-        return 0;
+        return strdup_to(ret, skip_dev_prefix(path));
 }
 
 int getttyname_harder(int fd, char **ret) {
@@ -1111,13 +1098,9 @@ int get_ctty(pid_t pid, dev_t *ret_devnr, char **ret) {
                 return -EINVAL;
 
         if (ret) {
-                _cleanup_free_ char *b = NULL;
-
-                b = strdup(w);
-                if (!b)
-                        return -ENOMEM;
-
-                *ret = TAKE_PTR(b);
+                r = strdup_to(ret, w);
+                if (r < 0)
+                        return r;
         }
 
         if (ret_devnr)
index 2aed260526a66fed4ec6b4e00e9ee2245cf348e1..0f3175ef43f1282b0fa4a610f813758037b762cd 100644 (file)
@@ -197,7 +197,7 @@ static inline bool colors_enabled(void) {
         }
 
 static inline const char *ansi_underline(void) {
-        return underline_enabled() ? ANSI_UNDERLINE : ANSI_NORMAL;
+        return underline_enabled() ? ANSI_UNDERLINE : "";
 }
 
 static inline const char *ansi_add_underline(void) {
index 822d660fdada776cc0ad08aa9e85b67dbdc977f8..b94f37c31c31e45e7ee04f25fcd3c94c5e481b6f 100644 (file)
@@ -1606,38 +1606,24 @@ bool clock_supported(clockid_t clock) {
 
 int get_timezone(char **ret) {
         _cleanup_free_ char *t = NULL;
-        const char *e;
-        char *z;
         int r;
 
         assert(ret);
 
         r = readlink_malloc("/etc/localtime", &t);
-        if (r == -ENOENT) {
+        if (r == -ENOENT)
                 /* If the symlink does not exist, assume "UTC", like glibc does */
-                z = strdup("UTC");
-                if (!z)
-                        return -ENOMEM;
-
-                *ret = z;
-                return 0;
-        }
+                return strdup_to(ret, "UTC");
         if (r < 0)
-                return r; /* returns EINVAL if not a symlink */
+                return r; /* Return EINVAL if not a symlink */
 
-        e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
+        const char *e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
         if (!e)
                 return -EINVAL;
-
         if (!timezone_is_valid(e, LOG_DEBUG))
                 return -EINVAL;
 
-        z = strdup(e);
-        if (!z)
-                return -ENOMEM;
-
-        *ret = z;
-        return 0;
+        return strdup_to(ret, e);
 }
 
 time_t mktime_or_timegm(struct tm *tm, bool utc) {
index 06ed9054d0bed310a2ee470ebf705bb7bfa1f8a0..4e2f77c03dc28c094b0af7bace3efbff77d95c41 100644 (file)
@@ -793,19 +793,10 @@ int unit_name_mangle_with_suffix(
         return 1;
 
 good:
-        s = strdup(name);
-        if (!s)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(s);
-        return 0;
+        return strdup_to(ret, name);
 }
 
 int slice_build_parent_slice(const char *slice, char **ret) {
-        _cleanup_free_ char *s = NULL;
-        char *dash;
-        int r;
-
         assert(slice);
         assert(ret);
 
@@ -817,18 +808,16 @@ int slice_build_parent_slice(const char *slice, char **ret) {
                 return 0;
         }
 
-        s = strdup(slice);
+        _cleanup_free_ char *s = strdup(slice);
         if (!s)
                 return -ENOMEM;
 
-        dash = strrchr(s, '-');
-        if (dash)
-                strcpy(dash, ".slice");
-        else {
-                r = free_and_strdup(&s, SPECIAL_ROOT_SLICE);
-                if (r < 0)
-                        return r;
-        }
+        char *dash = strrchr(s, '-');
+        if (!dash)
+                return strdup_to_full(ret, SPECIAL_ROOT_SLICE);
+
+        /* We know that s ended with .slice before truncation, so we have enough space. */
+        strcpy(dash, ".slice");
 
         *ret = TAKE_PTR(s);
         return 1;
index b976d2af14f669c561c90bd51604cee68c1adee0..7e2c0781fe12870bcd9e4bc36488c90ce5930c13 100644 (file)
@@ -179,6 +179,7 @@ static Virtualization detect_vm_dmi_vendor(void) {
                 { "VMW",                   VIRTUALIZATION_VMWARE    },
                 { "innotek GmbH",          VIRTUALIZATION_ORACLE    },
                 { "VirtualBox",            VIRTUALIZATION_ORACLE    },
+                { "Oracle Corporation",    VIRTUALIZATION_ORACLE    }, /* Detect VirtualBox on some proprietary systems via the board_vendor */
                 { "Xen",                   VIRTUALIZATION_XEN       },
                 { "Bochs",                 VIRTUALIZATION_BOCHS     },
                 { "Parallels",             VIRTUALIZATION_PARALLELS },
index fbc5d105653cb61eb54936c4c5ec85a52a84a2b6..e8217c1836102750f3b7776e46a0f852e1df7a40 100644 (file)
@@ -140,6 +140,8 @@ typedef struct {
         GUID_DEF(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
 #define EFI_IMAGE_SECURITY_DATABASE_GUID \
         GUID_DEF(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
+#define EFI_CUSTOM_MODE_ENABLE_GUID \
+        GUID_DEF(0xc076ec0c, 0x7028, 0x4399, 0xa0, 0x72, 0x71, 0xee, 0x5c, 0x44, 0x8b, 0x9f)
 
 #define EVT_TIMER                         0x80000000U
 #define EVT_RUNTIME                       0x40000000U
index 483e0ade0ce549815b50f16c181f48786c139426..7a60b0ec7ed1be70cfff6fa12cadf8e8f43f3dcb 100644 (file)
@@ -212,7 +212,7 @@ endif
 efi_arch_c_args = {
         'aarch64'     : ['-mgeneral-regs-only'],
         'arm'         : ['-mgeneral-regs-only'],
-       # Until -mgeneral-regs-only is supported in LoongArch, use the following option instead:
+        # Until -mgeneral-regs-only is supported in LoongArch, use the following option instead:
         'loongarch64' : ['-mno-lsx', '-mno-lasx'],
         # Pass -m64/32 explicitly to make building on x32 work.
         'x86_64'      : ['-m64', '-march=x86-64', '-mno-red-zone', '-mgeneral-regs-only'],
@@ -407,6 +407,11 @@ foreach efi_elf_binary : efi_elf_binaries
         if name == 'addon@0@.efi.stub'.format(efi_arch)
                 efi_addon = exe.full_path()
         endif
+
+        test('check-alignment-@0@'.format(name),
+             check_efi_alignment_py,
+             args : exe.full_path(),
+             suite : 'efi')
 endforeach
 
 alias_target('systemd-boot', boot_targets)
index f76d2f46d75ac907d44c60bd209a92ff628a8ddc..718c44b2a6d3124d3670abfaf8c73f2e09feb252 100644 (file)
@@ -32,10 +32,46 @@ SecureBootMode secure_boot_mode(void) {
         return decode_secure_boot_mode(secure, audit, deployed, setup);
 }
 
+/*
+ * Custom mode allows to change secure boot certificate databases db, dbx, KEK and PK without the variable
+ * updates being signed. When enrolling certificates to an unconfigured system (no PK present yet) writing
+ * db, dbx and KEK updates without signature works fine even in standard mode. Writing PK updates without
+ * signature requires custom mode in any case.
+ *
+ * Enabling custom mode works only if a user is physically present. Note that OVMF has a dummy
+ * implementation for the user presence check (there is no useful way to implement a presence check for a
+ * virtual machine).
+ *
+ * FYI: Your firmware setup utility might offers the option to enroll certificates from *.crt files
+ * (DER-encoded x509 certificates) on the ESP; that uses custom mode too. Your firmware setup might also
+ * offer the option to switch the system into custom mode for the next boot.
+ */
+static bool custom_mode_enabled(void) {
+        bool enabled = false;
+
+        (void) efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_CUSTOM_MODE_ENABLE),
+                                     u"CustomMode", &enabled);
+        return enabled;
+}
+
+static EFI_STATUS set_custom_mode(bool enable) {
+        static char16_t name[] = u"CustomMode";
+        static uint32_t attr =
+                EFI_VARIABLE_NON_VOLATILE |
+                EFI_VARIABLE_BOOTSERVICE_ACCESS;
+        uint8_t mode = enable
+                ? 1   /* CUSTOM_SECURE_BOOT_MODE   */
+                : 0;  /* STANDARD_SECURE_BOOT_MODE */
+
+        return RT->SetVariable(name, MAKE_GUID_PTR(EFI_CUSTOM_MODE_ENABLE),
+                               attr, sizeof(mode), &mode);
+}
+
 EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force) {
         assert(root_dir);
         assert(path);
 
+        bool need_custom_mode = false;
         EFI_STATUS err;
 
         clear_screen(COLOR_NORMAL);
@@ -88,21 +124,47 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool
                 const char16_t *name;
                 const char16_t *filename;
                 const EFI_GUID vendor;
+                bool required;
                 char *buffer;
                 size_t size;
         } sb_vars[] = {
-                { u"db",  u"db.auth",  EFI_IMAGE_SECURITY_DATABASE_GUID, NULL, 0 },
-                { u"KEK", u"KEK.auth", EFI_GLOBAL_VARIABLE, NULL, 0 },
-                { u"PK",  u"PK.auth",  EFI_GLOBAL_VARIABLE, NULL, 0 },
+                { u"db",  u"db.auth",  EFI_IMAGE_SECURITY_DATABASE_GUID, true, NULL, 0 },
+                { u"dbx", u"dbx.auth", EFI_IMAGE_SECURITY_DATABASE_GUID, false, NULL, 0 },
+                { u"KEK", u"KEK.auth", EFI_GLOBAL_VARIABLE, true, NULL, 0 },
+                { u"PK",  u"PK.auth",  EFI_GLOBAL_VARIABLE, true, NULL, 0 },
         };
 
         /* Make sure all keys files exist before we start enrolling them by loading them from the disk first. */
         for (size_t i = 0; i < ELEMENTSOF(sb_vars); i++) {
                 err = file_read(dir, sb_vars[i].filename, 0, 0, &sb_vars[i].buffer, &sb_vars[i].size);
-                if (err != EFI_SUCCESS) {
+                if (err != EFI_SUCCESS && sb_vars[i].required) {
                         log_error_status(err, "Failed reading file %ls\\%ls: %m", path, sb_vars[i].filename);
                         goto out_deallocate;
                 }
+                if (streq16(sb_vars[i].name, u"PK") && sb_vars[i].size > 20) {
+                        assert(sb_vars[i].buffer);
+                        /*
+                         * The buffer should be EFI_TIME (16 bytes), followed by
+                         * EFI_VARIABLE_AUTHENTICATION_2 header.  First header field is the size.  If the
+                         * size covers only the header itself (8 bytes) plus the signature type guid (16
+                         * bytes), leaving no space for an actual signature, we can conclude that no
+                         * signature is present.
+                         */
+                        uint32_t *sigsize = (uint32_t*)(sb_vars[i].buffer + 16);
+                        if (*sigsize <= 24) {
+                                printf("PK is not signed (need custom mode).\n");
+                                need_custom_mode = true;
+                        }
+                }
+        }
+
+        if (need_custom_mode && !custom_mode_enabled()) {
+                err = set_custom_mode(/* enable */ true);
+                if (err != EFI_SUCCESS) {
+                        log_error_status(err, "Failed to enable custom mode: %m");
+                        goto out_deallocate;
+                }
+                printf("Custom mode enabled.\n");
         }
 
         for (size_t i = 0; i < ELEMENTSOF(sb_vars); i++) {
@@ -112,6 +174,8 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool
                         EFI_VARIABLE_RUNTIME_ACCESS |
                         EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
 
+                if (sb_vars[i].size == 0)
+                        continue;
                 err = efivar_set_raw(&sb_vars[i].vendor, sb_vars[i].name, sb_vars[i].buffer, sb_vars[i].size, sb_vars_opts);
                 if (err != EFI_SUCCESS) {
                         log_error_status(err, "Failed to write %ls secure boot variable: %m", sb_vars[i].name);
index 88a9f49b5fb2a4cc1700b93f4db0e10b1f491b9b..8c5a57588da5f0d12cc236e7255a3981ff9d9de6 100644 (file)
@@ -51,10 +51,8 @@ static void automount_stop_expire(Automount *a);
 static int automount_send_ready(Automount *a, Set *tokens, int status);
 
 static void automount_init(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
 
-        assert(a);
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         a->pipe_fd = -EBADF;
@@ -88,9 +86,7 @@ static void unmount_autofs(Automount *a) {
 }
 
 static void automount_done(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
-
-        assert(a);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
 
         unmount_autofs(a);
 
@@ -227,10 +223,9 @@ static int automount_add_extras(Automount *a) {
 }
 
 static int automount_load(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         /* Load a .automount file */
@@ -250,6 +245,7 @@ static int automount_load(Unit *u) {
 
 static void automount_set_state(Automount *a, AutomountState state) {
         AutomountState old_state;
+
         assert(a);
 
         if (a->state != state)
@@ -271,10 +267,9 @@ static void automount_set_state(Automount *a, AutomountState state) {
 }
 
 static int automount_coldplug(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(a);
         assert(a->state == AUTOMOUNT_DEAD);
 
         if (a->deserialized_state == a->state)
@@ -310,9 +305,7 @@ static int automount_coldplug(Unit *u) {
 }
 
 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
-        Automount *a = AUTOMOUNT(u);
-
-        assert(a);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
 
         fprintf(f,
                 "%sAutomount State: %s\n"
@@ -478,30 +471,22 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
         r = 0;
 
         /* Autofs thankfully does not hand out 0 as a token */
-        while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
-                int k;
-
+        while ((token = PTR_TO_UINT(set_steal_first(tokens))))
                 /* Autofs fun fact:
                  *
-                 * if you pass a positive status code here, kernels
-                 * prior to 4.12 will freeze! Yay! */
-
-                k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
-                                      ioctl_fd,
-                                      token,
-                                      status);
-                if (k < 0)
-                        r = k;
-        }
+                 * if you pass a positive status code here, kernels prior to 4.12 will freeze! Yay! */
+                RET_GATHER(r, autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
+                                                ioctl_fd,
+                                                token,
+                                                status));
 
         return r;
 }
 
 static void automount_trigger_notify(Unit *u, Unit *other) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(a);
         assert(other);
 
         /* Filter out invocations with bogus state */
@@ -697,11 +682,10 @@ static int asynchronous_expire(int dev_autofs_fd, int ioctl_fd) {
 }
 
 static int automount_dispatch_expire(sd_event_source *source, usec_t usec, void *userdata) {
+        Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
         _cleanup_close_ int ioctl_fd = -EBADF;
-        Automount *a = AUTOMOUNT(userdata);
         int r;
 
-        assert(a);
         assert(source == a->expire_event_source);
 
         ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
@@ -815,10 +799,9 @@ fail:
 }
 
 static int automount_start(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(a);
         assert(IN_SET(a->state, AUTOMOUNT_DEAD, AUTOMOUNT_FAILED));
 
         if (path_is_mount_point(a->where) > 0)
@@ -838,9 +821,8 @@ static int automount_start(Unit *u) {
 }
 
 static int automount_stop(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
 
-        assert(a);
         assert(IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING));
 
         automount_enter_dead(a, AUTOMOUNT_SUCCESS);
@@ -848,11 +830,10 @@ static int automount_stop(Unit *u) {
 }
 
 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         void *p;
         int r;
 
-        assert(a);
         assert(f);
         assert(fds);
 
@@ -873,10 +854,9 @@ static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(a);
         assert(fds);
 
         if (streq(key, "state")) {
@@ -958,13 +938,12 @@ static bool automount_may_gc(Unit *u) {
 }
 
 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
+        Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         union autofs_v5_packet_union packet;
-        Automount *a = AUTOMOUNT(userdata);
         Unit *trigger;
         int r;
 
-        assert(a);
         assert(fd == a->pipe_fd);
 
         if (events & (EPOLLHUP|EPOLLERR)) {
@@ -1048,9 +1027,7 @@ static void automount_shutdown(Manager *m) {
 }
 
 static void automount_reset_failed(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
-
-        assert(a);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
 
         if (a->state == AUTOMOUNT_FAILED)
                 automount_set_state(a, AUTOMOUNT_DEAD);
@@ -1068,11 +1045,9 @@ static bool automount_supported(void) {
 }
 
 static int automount_can_start(Unit *u) {
-        Automount *a = AUTOMOUNT(u);
+        Automount *a = ASSERT_PTR(AUTOMOUNT(u));
         int r;
 
-        assert(a);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
index 465216a7d0dfd29708ffe42b5d4d1f481fa6ac15..3008d8249c69f38bf84d1dd9ed87f258b49c7de0 100644 (file)
@@ -32,6 +32,15 @@ static int update_rules_map(
 
         assert(map_fd >= 0);
 
+        if (!head) {
+                static const struct socket_bind_rule val = {
+                        .address_family = SOCKET_BIND_RULE_AF_MATCH_NOTHING,
+                };
+
+                if (sym_bpf_map_update_elem(map_fd, &i, &val, BPF_ANY) != 0)
+                        return -errno;
+        }
+
         LIST_FOREACH(socket_bind_items, item, head) {
                 struct socket_bind_rule val = {
                         .address_family = (uint32_t) item->address_family,
index 277b9bbde25714882e993ba55b1277f270d60a73..4fe08f1f444d25a5a1939e6d921d9dfa72fb06f2 100644 (file)
@@ -7,13 +7,17 @@
  */
 
 #include <linux/types.h>
+#include <stdint.h>
 
 /*
  * Bind rule is matched with socket fields accessible to cgroup/bind{4,6} hook
  * through bpf_sock_addr struct.
- * 'address_family' is expected to be one of AF_UNSPEC, AF_INET or AF_INET6.
+ * 'address_family' is expected to be one of AF_UNSPEC, AF_INET, AF_INET6 or the
+ * magic SOCKET_BIND_RULE_AF_MATCH_NOTHING.
  * Matching by family is bypassed for rules with AF_UNSPEC set, which makes the
  * rest of a rule applicable for both IPv4 and IPv6 addresses.
+ * If SOCKET_BIND_RULE_AF_MATCH_NOTHING is set the rule fails unconditionally
+ * and other checks are skipped.
  * If matching by family is either successful or bypassed, a rule and a socket
  * are matched by ip protocol.
  * If 'protocol' is 0, matching is bypassed.
@@ -49,3 +53,4 @@ struct socket_bind_rule {
 };
 
 #define SOCKET_BIND_MAX_RULES 128
+#define SOCKET_BIND_RULE_AF_MATCH_NOTHING UINT32_MAX
index b7972a887a4c8948bc1e62512e952839bbd6a23a..da9f9d13de7803f11376c29696eb2d84e0134765 100644 (file)
@@ -55,6 +55,9 @@ static __always_inline bool match(
                 __u32 protocol,
                 __u16 port,
                 const struct socket_bind_rule *r) {
+        if (r->address_family == SOCKET_BIND_RULE_AF_MATCH_NOTHING)
+                return false;
+
         return match_af(address_family, r) &&
                 match_protocol(protocol, r) &&
                 match_user_port(port, r);
index 6b2d7c3e247f045cd111dfa60738ec943860da84..93cab92b8ce0669e8c4e20301e86a1e49f3617d3 100644 (file)
@@ -119,10 +119,9 @@ static int device_set_sysfs(Device *d, const char *sysfs) {
 }
 
 static void device_init(Unit *u) {
-        Device *d = DEVICE(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
-        assert(d);
-        assert(UNIT(d)->load_state == UNIT_STUB);
+        assert(u->load_state == UNIT_STUB);
 
         /* In contrast to all other unit types we timeout jobs waiting
          * for devices by default. This is because they otherwise wait
@@ -137,9 +136,7 @@ static void device_init(Unit *u) {
 }
 
 static void device_done(Unit *u) {
-        Device *d = DEVICE(u);
-
-        assert(d);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
         device_unset_sysfs(d);
         d->deserialized_sysfs = mfree(d->deserialized_sysfs);
@@ -258,9 +255,8 @@ static void device_update_found_by_name(Manager *m, const char *path, DeviceFoun
 }
 
 static int device_coldplug(Unit *u) {
-        Device *d = DEVICE(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
-        assert(d);
         assert(d->state == DEVICE_DEAD);
 
         /* First, let's put the deserialized state and found mask into effect, if we have it. */
@@ -336,9 +332,7 @@ static int device_coldplug(Unit *u) {
 }
 
 static void device_catchup(Unit *u) {
-        Device *d = DEVICE(u);
-
-        assert(d);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
         /* Second, let's update the state with the enumerated state */
         device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK);
@@ -405,11 +399,9 @@ static int device_found_from_string_many(const char *name, DeviceFound *ret) {
 }
 
 static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Device *d = ASSERT_PTR(DEVICE(u));
         _cleanup_free_ char *s = NULL;
-        Device *d = DEVICE(u);
 
-        assert(d);
-        assert(u);
         assert(f);
         assert(fds);
 
@@ -428,11 +420,9 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Device *d = DEVICE(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
         int r;
 
-        assert(d);
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -472,10 +462,11 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value,
 }
 
 static void device_dump(Unit *u, FILE *f, const char *prefix) {
-        Device *d = DEVICE(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
         _cleanup_free_ char *s = NULL;
 
-        assert(d);
+        assert(f);
+        assert(prefix);
 
         (void) device_found_to_string_many(d->found, &s);
 
@@ -495,15 +486,15 @@ static void device_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static UnitActiveState device_active_state(Unit *u) {
-        assert(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
-        return state_translation_table[DEVICE(u)->state];
+        return state_translation_table[d->state];
 }
 
 static const char *device_sub_state_to_string(Unit *u) {
-        assert(u);
+        Device *d = ASSERT_PTR(DEVICE(u));
 
-        return device_state_to_string(DEVICE(u)->state);
+        return device_state_to_string(d->state);
 }
 
 static int device_update_description(Unit *u, sd_device *dev, const char *path) {
@@ -538,12 +529,11 @@ static int device_update_description(Unit *u, sd_device *dev, const char *path)
 }
 
 static int device_add_udev_wants(Unit *u, sd_device *dev) {
+        Device *d = ASSERT_PTR(DEVICE(u));
         _cleanup_strv_free_ char **added = NULL;
         const char *wants, *property;
-        Device *d = DEVICE(u);
         int r;
 
-        assert(d);
         assert(dev);
 
         property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
@@ -646,6 +636,8 @@ static void device_upgrade_mount_deps(Unit *u) {
 
         /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
 
+        assert(u);
+
         HASHMAP_FOREACH_KEY(v, other, unit_get_dependencies(u, UNIT_REQUIRED_BY)) {
                 if (other->type != UNIT_MOUNT)
                         continue;
@@ -706,16 +698,18 @@ static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool
                 unit_add_to_load_queue(u);
         }
 
-        if (!DEVICE(u)->path) {
-                DEVICE(u)->path = strdup(path);
-                if (!DEVICE(u)->path)
+        Device *d = ASSERT_PTR(DEVICE(u));
+
+        if (!d->path) {
+                d->path = strdup(path);
+                if (!d->path)
                         return log_oom();
         }
 
         /* If this was created via some dependency and has not actually been seen yet ->sysfs will not be
          * initialized. Hence initialize it if necessary. */
         if (sysfs) {
-                r = device_set_sysfs(DEVICE(u), sysfs);
+                r = device_set_sysfs(d, sysfs);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Failed to set sysfs path %s: %m", sysfs);
 
@@ -730,11 +724,11 @@ static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool
          * by systemd before the device appears on its radar. In this case the device unit is partially
          * initialized and includes the deps on the mount unit but at that time the "bind mounts" flag wasn't
          * present. Fix this up now. */
-        if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
+        if (dev && device_is_bound_by_mounts(d, dev))
                 device_upgrade_mount_deps(u);
 
         if (units) {
-                r = set_ensure_put(units, NULL, DEVICE(u));
+                r = set_ensure_put(units, NULL, d);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Failed to store unit: %m");
         }
@@ -950,10 +944,7 @@ static int device_setup_units(Manager *m, sd_device *dev, Set **ready_units, Set
 }
 
 static Unit *device_following(Unit *u) {
-        Device *d = DEVICE(u);
-        Device *first = NULL;
-
-        assert(d);
+        Device *d = ASSERT_PTR(DEVICE(u)), *first = NULL;
 
         if (startswith(u->id, "sys-"))
                 return NULL;
@@ -973,16 +964,15 @@ static Unit *device_following(Unit *u) {
         return UNIT(first);
 }
 
-static int device_following_set(Unit *u, Set **_set) {
-        Device *d = DEVICE(u);
+static int device_following_set(Unit *u, Set **ret) {
+        Device *d = ASSERT_PTR(DEVICE(u));
         _cleanup_set_free_ Set *set = NULL;
         int r;
 
-        assert(d);
-        assert(_set);
+        assert(ret);
 
         if (LIST_JUST_US(same_sysfs, d)) {
-                *_set = NULL;
+                *ret = NULL;
                 return 0;
         }
 
@@ -1002,7 +992,7 @@ static int device_following_set(Unit *u, Set **_set) {
                         return r;
         }
 
-        *_set = TAKE_PTR(set);
+        *ret = TAKE_PTR(set);
         return 1;
 }
 
index 4f8f76473334ae5faafdf1f4fb26c7d69a1ca901..24ed889b61ef5fa1bb0795ee0dec50e42a0df6f8 100644 (file)
@@ -143,7 +143,6 @@ static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret)
 }
 
 static int make_uid_symlinks(uid_t uid, const char *name, bool b) {
-
         char path1[STRLEN("/run/systemd/dynamic-uid/direct:") + DECIMAL_STR_MAX(uid_t) + 1];
         const char *path2;
         int r = 0, k;
@@ -754,7 +753,6 @@ int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret) {
 
 int dynamic_creds_make(Manager *m, const char *user, const char *group, DynamicCreds **ret) {
         _cleanup_(dynamic_creds_unrefp) DynamicCreds *creds = NULL;
-        bool acquired = false;
         int r;
 
         assert(m);
@@ -777,20 +775,14 @@ int dynamic_creds_make(Manager *m, const char *user, const char *group, DynamicC
                 r = dynamic_user_acquire(m, user, &creds->user);
                 if (r < 0)
                         return r;
-
-                acquired = true;
         }
 
-        if (creds->user && (!group || streq_ptr(user, group)))
-                creds->group = dynamic_user_ref(creds->user);
-        else if (group) {
+        if (group && !streq_ptr(user, group)) {
                 r = dynamic_user_acquire(m, group, &creds->group);
-                if (r < 0) {
-                        if (acquired)
-                                creds->user = dynamic_user_unref(creds->user);
+                if (r < 0)
                         return r;
-                }
-        }
+        } else
+                creds->group = ASSERT_PTR(dynamic_user_ref(creds->user));
 
         *ret = TAKE_PTR(creds);
 
index a1401f3e4903a9586778cffadfacb0f1472c5e87..47339bddafc220cde91f5f79e672e2fbc66974cd 100644 (file)
@@ -1915,7 +1915,7 @@ static int build_environment(
                  * to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the
                  * container manager passes to PID 1 ends up all the way in the console login shown. */
 
-                if (path_equal_ptr(tty_path, "/dev/console") && getppid() == 1)
+                if (path_equal(tty_path, "/dev/console") && getppid() == 1)
                         term = getenv("TERM");
                 else if (tty_path && in_charset(skip_dev_prefix(tty_path), ALPHANUMERICAL)) {
                         _cleanup_free_ char *key = NULL;
index fb3e9b79cbeef1c6d08ed5a69be519b38c1b6443..864e3d492121937b25bd6c2294a7bc0dd7ab18fa 100644 (file)
@@ -362,7 +362,7 @@ int exec_spawn(Unit *unit,
                PidRef *ret) {
 
         char serialization_fd_number[DECIMAL_STR_MAX(int) + 1];
-        _cleanup_free_ char *subcgroup_path = NULL, *log_level = NULL, *executor_path = NULL;
+        _cleanup_free_ char *subcgroup_path = NULL, *max_log_levels = NULL, *executor_path = NULL;
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
         _cleanup_fdset_free_ FDSet *fdset = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -435,9 +435,9 @@ int exec_spawn(Unit *unit,
         /* If LogLevelMax= is specified, then let's use the specified log level at the beginning of the
          * executor process. To achieve that the specified log level is passed as an argument, rather than
          * the one for the manager process. */
-        r = log_level_to_string_alloc(context->log_level_max >= 0 ? context->log_level_max : log_get_max_level(), &log_level);
+        r = log_max_levels_to_string(context->log_level_max >= 0 ? context->log_level_max : log_get_max_level(), &max_log_levels);
         if (r < 0)
-                return log_unit_error_errno(unit, r, "Failed to convert log level to string: %m");
+                return log_unit_error_errno(unit, r, "Failed to convert max log levels to string: %m");
 
         r = fd_get_path(unit->manager->executor_fd, &executor_path);
         if (r < 0)
@@ -450,7 +450,7 @@ int exec_spawn(Unit *unit,
                         FORMAT_PROC_FD_PATH(unit->manager->executor_fd),
                         STRV_MAKE(executor_path,
                                   "--deserialize", serialization_fd_number,
-                                  "--log-level", log_level,
+                                  "--log-level", max_log_levels,
                                   "--log-target", log_target_to_string(manager_get_executor_log_target(unit->manager))),
                         environ,
                         cg_unified() > 0 ? subcgroup_path : NULL,
@@ -1403,7 +1403,7 @@ bool exec_context_maintains_privileges(const ExecContext *c) {
         if (!c->user)
                 return true;
 
-        if (streq(c->user, "root") || streq(c->user, "0"))
+        if (STR_IN_SET(c->user, "root", "0"))
                 return true;
 
         return false;
index 18e4bce67f8a0f7af960bf633811ef8e1a7a22f4..90d87e078d3a5847db26e9eed91b4254eaf66f23 100644 (file)
@@ -753,7 +753,7 @@ static int merge_credentials_trusted(const char *creds_dir) {
                 return 0;
 
         /* Do not try to merge initrd credentials into foreign credentials directories */
-        if (!path_equal_ptr(creds_dir, SYSTEM_CREDENTIALS_DIRECTORY)) {
+        if (!path_equal(creds_dir, SYSTEM_CREDENTIALS_DIRECTORY)) {
                 log_debug("Not importing initrd credentials, as foreign $CREDENTIALS_DIRECTORY has been set.");
                 return 0;
         }
index d751b3316c438d07c42610adf50f5ff520d37e40..be8907f2d192c3e565e4ff333688a4e84f956eea 100644 (file)
@@ -249,7 +249,7 @@ int unit_is_likely_recursive_template_dependency(Unit *u, const char *name, cons
 
         /* Fragment paths should also be equal as a custom fragment for a specific template instance
          * wouldn't necessarily lead to infinite recursion. */
-        if (!path_equal_ptr(u->fragment_path, fragment_path))
+        if (!path_equal(u->fragment_path, fragment_path))
                 return false;
 
         if (!contains_instance_specifier_superset(format))
index 551fb425c43e2ffb286fae8d50715671d51c7cc3..1c57cce748365d94ded08882d6eddbdf85c16076 100644 (file)
@@ -1476,7 +1476,7 @@ static int fixup_environment(void) {
                 return -errno;
 
         /* The kernels sets HOME=/ for init. Let's undo this. */
-        if (path_equal_ptr(getenv("HOME"), "/"))
+        if (path_equal(getenv("HOME"), "/"))
                 assert_se(unsetenv("HOME") == 0);
 
         return 0;
@@ -1508,32 +1508,37 @@ static int become_shutdown(int objective, int retval) {
                 [MANAGER_KEXEC]    = "kexec",
         };
 
-        char log_level[STRLEN("--log-level=") + DECIMAL_STR_MAX(int)],
-             timeout[STRLEN("--timeout=") + DECIMAL_STR_MAX(usec_t) + STRLEN("us")],
+        char timeout[STRLEN("--timeout=") + DECIMAL_STR_MAX(usec_t) + STRLEN("us")],
              exit_code[STRLEN("--exit-code=") + DECIMAL_STR_MAX(uint8_t)];
 
         _cleanup_strv_free_ char **env_block = NULL;
+        _cleanup_free_ char *max_log_levels = NULL;
         usec_t watchdog_timer = 0;
         int r;
 
         assert(objective >= 0 && objective < _MANAGER_OBJECTIVE_MAX);
         assert(table[objective]);
 
-        xsprintf(log_level, "--log-level=%d", log_get_max_level());
         xsprintf(timeout, "--timeout=%" PRI_USEC "us", arg_defaults.timeout_stop_usec);
 
-        const char* command_line[10] = {
+        const char* command_line[11] = {
                 SYSTEMD_SHUTDOWN_BINARY_PATH,
                 table[objective],
-                log_level,
                 timeout,
                 /* Note that the last position is a terminator and must contain NULL. */
         };
-        size_t pos = 4;
+        size_t pos = 3;
 
         assert(command_line[pos-1]);
         assert(!command_line[pos]);
 
+        (void) log_max_levels_to_string(log_get_max_level(), &max_log_levels);
+
+        if (max_log_levels) {
+                command_line[pos++] = "--log-level";
+                command_line[pos++] = max_log_levels;
+        }
+
         switch (log_get_target()) {
 
         case LOG_TARGET_KMSG:
index 7dbf5f48f9722bcdf13c107a3ec784ec455387a6..175af5498af37fffc62ca190ed475cae6bbdc806 100644 (file)
@@ -172,10 +172,8 @@ static bool mount_propagate_stop(Mount *m) {
 }
 
 static void mount_init(Unit *u) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
-        assert(m);
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         m->timeout_usec = u->manager->defaults.timeout_start_usec;
@@ -217,9 +215,7 @@ static void mount_parameters_done(MountParameters *p) {
 }
 
 static void mount_done(Unit *u) {
-        Mount *m = MOUNT(u);
-
-        assert(m);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         m->where = mfree(m->where);
 
@@ -245,6 +241,8 @@ static int update_parameters_proc_self_mountinfo(
         MountParameters *p;
         int r, q, w;
 
+        assert(m);
+
         p = &m->parameters_proc_self_mountinfo;
 
         r = free_and_strdup(&p->what, what);
@@ -408,9 +406,8 @@ static int mount_add_device_dependencies(Mount *m) {
 }
 
 static bool mount_is_extrinsic(Unit *u) {
+        Mount *m = ASSERT_PTR(MOUNT(u));
         MountParameters *p;
-        Mount *m = MOUNT(u);
-        assert(m);
 
         /* Returns true for all units that are "magic" and should be excluded from the usual
          * start-up and shutdown dependencies. We call them "extrinsic" here, as they are generally
@@ -629,11 +626,9 @@ static int mount_add_non_exec_dependencies(Mount *m) {
 }
 
 static int mount_add_extras(Mount *m) {
-        Unit *u = UNIT(m);
+        Unit *u = UNIT(ASSERT_PTR(m));
         int r;
 
-        assert(m);
-
         /* Note: this call might be called after we already have been loaded once (and even when it has already been
          * activated), in case data from /proc/self/mountinfo has changed. This means all code here needs to be ready
          * to run with an already set up unit. */
@@ -678,7 +673,7 @@ static int mount_add_extras(Mount *m) {
 }
 
 static void mount_load_root_mount(Unit *u) {
-        assert(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
                 return;
@@ -687,37 +682,35 @@ static void mount_load_root_mount(Unit *u) {
         u->default_dependencies = false;
 
         /* The stdio/kmsg bridge socket is on /, in order to avoid a dep loop, don't use kmsg logging for -.mount */
-        MOUNT(u)->exec_context.std_output = EXEC_OUTPUT_NULL;
-        MOUNT(u)->exec_context.std_input = EXEC_INPUT_NULL;
+        m->exec_context.std_output = EXEC_OUTPUT_NULL;
+        m->exec_context.std_input = EXEC_INPUT_NULL;
 
         if (!u->description)
                 u->description = strdup("Root Mount");
 }
 
 static int mount_load(Unit *u) {
-        Mount *m = MOUNT(u);
-        int r, q = 0;
+        Mount *m = ASSERT_PTR(MOUNT(u));
+        int r;
 
-        assert(m);
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         mount_load_root_mount(u);
 
-        bool fragment_optional = m->from_proc_self_mountinfo || u->perpetual;
-        r = unit_load_fragment_and_dropin(u, !fragment_optional);
+        bool from_kernel = m->from_proc_self_mountinfo || u->perpetual;
+
+        r = unit_load_fragment_and_dropin(u, /* fragment_required = */ !from_kernel);
 
         /* Add in some extras. Note we do this in all cases (even if we failed to load the unit) when announced by the
          * kernel, because we need some things to be set up no matter what when the kernel establishes a mount and thus
          * we need to update the state in our unit to track it. After all, consider that we don't allow changing the
          * 'slice' field for a unit once it is active. */
-        if (u->load_state == UNIT_LOADED || m->from_proc_self_mountinfo || u->perpetual)
-                q = mount_add_extras(m);
+        if (u->load_state == UNIT_LOADED || from_kernel)
+                RET_GATHER(r, mount_add_extras(m));
 
         if (r < 0)
                 return r;
-        if (q < 0)
-                return q;
+
         if (u->load_state != UNIT_LOADED)
                 return 0;
 
@@ -726,6 +719,7 @@ static int mount_load(Unit *u) {
 
 static void mount_set_state(Mount *m, MountState state) {
         MountState old_state;
+
         assert(m);
 
         if (m->state != state)
@@ -748,10 +742,9 @@ static void mount_set_state(Mount *m, MountState state) {
 }
 
 static int mount_coldplug(Unit *u) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         int r;
 
-        assert(m);
         assert(m->state == MOUNT_DEAD);
 
         if (m->deserialized_state == m->state)
@@ -780,9 +773,7 @@ static int mount_coldplug(Unit *u) {
 }
 
 static void mount_catchup(Unit *u) {
-        Mount *m = MOUNT(ASSERT_PTR(u));
-
-        assert(m);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         /* Adjust the deserialized state. See comments in mount_process_proc_self_mountinfo(). */
         if (m->from_proc_self_mountinfo)
@@ -817,10 +808,9 @@ static void mount_catchup(Unit *u) {
 }
 
 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         MountParameters *p;
 
-        assert(m);
         assert(f);
 
         p = get_mount_parameters(m);
@@ -870,7 +860,6 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static int mount_spawn(Mount *m, ExecCommand *c, PidRef *ret_pid) {
-
         _cleanup_(exec_params_shallow_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(
                         EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN);
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
@@ -1115,9 +1104,9 @@ static int mount_set_mount_command(Mount *m, ExecCommand *c, const MountParamete
 }
 
 static void mount_enter_mounting(Mount *m) {
-        int r;
         MountParameters *p;
         bool source_is_dir = true;
+        int r;
 
         assert(m);
 
@@ -1226,8 +1215,8 @@ static void mount_set_reload_result(Mount *m, MountResult result) {
 }
 
 static void mount_enter_remounting(Mount *m) {
-        int r;
         MountParameters *p;
+        int r;
 
         assert(m);
 
@@ -1295,11 +1284,9 @@ static void mount_cycle_clear(Mount *m) {
 }
 
 static int mount_start(Unit *u) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         int r;
 
-        assert(m);
-
         /* We cannot fulfill this request right now, try again later
          * please! */
         if (IN_SET(m->state,
@@ -1326,9 +1313,7 @@ static int mount_start(Unit *u) {
 }
 
 static int mount_stop(Unit *u) {
-        Mount *m = MOUNT(u);
-
-        assert(m);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         /* When we directly call umount() for a path, then the state of the corresponding mount unit may be
          * outdated. Let's re-read mountinfo now and update the state. */
@@ -1380,9 +1365,8 @@ static int mount_stop(Unit *u) {
 }
 
 static int mount_reload(Unit *u) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
-        assert(m);
         assert(m->state == MOUNT_MOUNTED);
 
         mount_enter_remounting(m);
@@ -1391,9 +1375,8 @@ static int mount_reload(Unit *u) {
 }
 
 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
-        assert(m);
         assert(f);
         assert(fds);
 
@@ -1410,11 +1393,9 @@ static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         int r;
 
-        assert(m);
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -1474,21 +1455,19 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
 }
 
 static UnitActiveState mount_active_state(Unit *u) {
-        assert(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
-        return state_translation_table[MOUNT(u)->state];
+        return state_translation_table[m->state];
 }
 
 static const char *mount_sub_state_to_string(Unit *u) {
-        assert(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
-        return mount_state_to_string(MOUNT(u)->state);
+        return mount_state_to_string(m->state);
 }
 
 static bool mount_may_gc(Unit *u) {
-        Mount *m = MOUNT(u);
-
-        assert(m);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         if (m->from_proc_self_mountinfo)
                 return false;
@@ -1497,10 +1476,9 @@ static bool mount_may_gc(Unit *u) {
 }
 
 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         MountResult f;
 
-        assert(m);
         assert(pid >= 0);
 
         if (pid != m->control_pid.pid)
@@ -1627,9 +1605,8 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 }
 
 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
-        Mount *m = MOUNT(userdata);
+        Mount *m = ASSERT_PTR(MOUNT(userdata));
 
-        assert(m);
         assert(m->timer_event_source == source);
 
         switch (m->state) {
@@ -1712,6 +1689,7 @@ static int mount_setup_new_unit(
                 Unit **ret) {
 
         _cleanup_(unit_freep) Unit *u = NULL;
+        Mount *mnt;
         int r;
 
         assert(m);
@@ -1723,24 +1701,26 @@ static int mount_setup_new_unit(
         if (r < 0)
                 return r;
 
+        mnt = ASSERT_PTR(MOUNT(u));
+
         r = free_and_strdup(&u->source_path, "/proc/self/mountinfo");
         if (r < 0)
                 return r;
 
-        r = free_and_strdup(&MOUNT(u)->where, where);
+        r = free_and_strdup(&mnt->where, where);
         if (r < 0)
                 return r;
 
-        r = update_parameters_proc_self_mountinfo(MOUNT(u), what, options, fstype);
+        r = update_parameters_proc_self_mountinfo(mnt, what, options, fstype);
         if (r < 0)
                 return r;
 
         /* This unit was generated because /proc/self/mountinfo reported it. Remember this, so that by the
          * time we load the unit file for it (and thus add in extra deps right after) we know what source to
          * attributes the deps to. */
-        MOUNT(u)->from_proc_self_mountinfo = true;
+        mnt->from_proc_self_mountinfo = true;
 
-        r = mount_add_non_exec_dependencies(MOUNT(u));
+        r = mount_add_non_exec_dependencies(mnt);
         if (r < 0)
                 return r;
 
@@ -1761,14 +1741,16 @@ static int mount_setup_existing_unit(
                 const char *fstype,
                 MountProcFlags *ret_flags) {
 
+        Mount *m = ASSERT_PTR(MOUNT(u));
         int r;
 
         assert(u);
+        assert(where);
         assert(ret_flags);
 
-        if (!MOUNT(u)->where) {
-                MOUNT(u)->where = strdup(where);
-                if (!MOUNT(u)->where)
+        if (!m->where) {
+                m->where = strdup(where);
+                if (!m->where)
                         return -ENOMEM;
         }
 
@@ -1776,10 +1758,9 @@ static int mount_setup_existing_unit(
          * for the current unit. Note that the flags field is reset on each iteration of reading
          * /proc/self/mountinfo, hence we know for sure anything already set here is from the current
          * iteration and thus worthy of taking into account. */
-        MountProcFlags flags =
-                MOUNT(u)->proc_flags | MOUNT_PROC_IS_MOUNTED;
+        MountProcFlags flags = m->proc_flags | MOUNT_PROC_IS_MOUNTED;
 
-        r = update_parameters_proc_self_mountinfo(MOUNT(u), what, options, fstype);
+        r = update_parameters_proc_self_mountinfo(m, what, options, fstype);
         if (r < 0)
                 return r;
         if (r > 0)
@@ -1792,12 +1773,12 @@ static int mount_setup_existing_unit(
          * from the serialized state), and need to catch up. Since we know that the MOUNT_MOUNTING state is
          * reached when we wait for the mount to appear we hence can assume that if we are in it, we are
          * actually seeing it established for the first time. */
-        if (!MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->state == MOUNT_MOUNTING)
+        if (!m->from_proc_self_mountinfo || m->state == MOUNT_MOUNTING)
                 flags |= MOUNT_PROC_JUST_MOUNTED;
 
-        MOUNT(u)->from_proc_self_mountinfo = true;
+        m->from_proc_self_mountinfo = true;
 
-        if (IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_ERROR)) {
+        if (UNIT_IS_LOAD_ERROR(u->load_state)) {
                 /* The unit was previously not found or otherwise not loaded. Now that the unit shows up in
                  * /proc/self/mountinfo we should reconsider it this, hence set it to UNIT_LOADED. */
                 u->load_state = UNIT_LOADED;
@@ -1809,7 +1790,7 @@ static int mount_setup_existing_unit(
         if (FLAGS_SET(flags, MOUNT_PROC_JUST_CHANGED)) {
                 /* If things changed, then make sure that all deps are regenerated. Let's
                  * first remove all automatic deps, and then add in the new ones. */
-                r = mount_add_non_exec_dependencies(MOUNT(u));
+                r = mount_add_non_exec_dependencies(m);
                 if (r < 0)
                         return r;
         }
@@ -1925,13 +1906,10 @@ static void mount_shutdown(Manager *m) {
 }
 
 static int mount_get_timeout(Unit *u, usec_t *timeout) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         usec_t t;
         int r;
 
-        assert(m);
-        assert(u);
-
         if (!m->timer_event_source)
                 return 0;
 
@@ -2301,19 +2279,15 @@ fail:
 }
 
 static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
-        Mount *m = MOUNT(u);
-
-        assert(m);
+        Mount *m = ASSERT_PTR(MOUNT(u));
 
         return exec_context_get_clean_mask(&m->exec_context, ret);
 }
 
 static int mount_can_start(Unit *u) {
-        Mount *m = MOUNT(u);
+        Mount *m = ASSERT_PTR(MOUNT(u));
         int r;
 
-        assert(m);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
index 00da301fd2225caf0dc752895c64579150acfc41..fdb6ca4cc9db22b08bac5d2b738da97cd066d2ec 100644 (file)
@@ -249,6 +249,8 @@ static bool path_spec_check_good(PathSpec *s, bool initial, bool from_trigger_no
 static void path_spec_mkdir(PathSpec *s, mode_t mode) {
         int r;
 
+        assert(s);
+
         if (IN_SET(s->type, PATH_EXISTS, PATH_EXISTS_GLOB))
                 return;
 
@@ -260,6 +262,10 @@ static void path_spec_mkdir(PathSpec *s, mode_t mode) {
 static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) {
         const char *type;
 
+        assert(s);
+        assert(f);
+        assert(prefix);
+
         assert_se(type = path_type_to_string(s->type));
         fprintf(f, "%s%s: %s\n", prefix, type, s->path);
 }
@@ -272,9 +278,8 @@ void path_spec_done(PathSpec *s) {
 }
 
 static void path_init(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         p->directory_mode = 0755;
@@ -295,9 +300,7 @@ void path_free_specs(Path *p) {
 }
 
 static void path_done(Unit *u) {
-        Path *p = PATH(u);
-
-        assert(p);
+        Path *p = ASSERT_PTR(PATH(u));
 
         p->trigger_notify_event_source = sd_event_source_disable_unref(p->trigger_notify_event_source);
         path_free_specs(p);
@@ -389,10 +392,9 @@ static int path_add_extras(Path *p) {
 }
 
 static int path_load(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
         int r;
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         r = unit_load_fragment_and_dropin(u, true);
@@ -410,11 +412,11 @@ static int path_load(Unit *u) {
 }
 
 static void path_dump(Unit *u, FILE *f, const char *prefix) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
         Unit *trigger;
 
-        assert(p);
         assert(f);
+        assert(prefix);
 
         trigger = UNIT_TRIGGER(u);
 
@@ -461,6 +463,7 @@ static int path_watch(Path *p) {
 
 static void path_set_state(Path *p, PathState state) {
         PathState old_state;
+
         assert(p);
 
         if (p->state != state)
@@ -481,9 +484,8 @@ static void path_set_state(Path *p, PathState state) {
 static void path_enter_waiting(Path *p, bool initial, bool from_trigger_notify);
 
 static int path_coldplug(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        assert(p);
         assert(p->state == PATH_DEAD);
 
         if (p->deserialized_state != p->state) {
@@ -625,10 +627,9 @@ static void path_mkdir(Path *p) {
 }
 
 static int path_start(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
         int r;
 
-        assert(p);
         assert(IN_SET(p->state, PATH_DEAD, PATH_FAILED));
 
         r = unit_test_trigger_loaded(u);
@@ -648,9 +649,8 @@ static int path_start(Unit *u) {
 }
 
 static int path_stop(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        assert(p);
         assert(IN_SET(p->state, PATH_WAITING, PATH_RUNNING));
 
         path_enter_dead(p, PATH_SUCCESS);
@@ -658,9 +658,8 @@ static int path_stop(Unit *u) {
 }
 
 static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        assert(u);
         assert(f);
         assert(fds);
 
@@ -688,9 +687,8 @@ static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int path_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -755,28 +753,24 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
 }
 
 static UnitActiveState path_active_state(Unit *u) {
-        assert(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        return state_translation_table[PATH(u)->state];
+        return state_translation_table[p->state];
 }
 
 static const char *path_sub_state_to_string(Unit *u) {
-        assert(u);
+        Path *p = ASSERT_PTR(PATH(u));
 
-        return path_state_to_string(PATH(u)->state);
+        return path_state_to_string(p->state);
 }
 
 static int path_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
-        PathSpec *s = userdata, *found = NULL;
-        Path *p;
+        PathSpec *s = ASSERT_PTR(userdata), *found = NULL;
+        Path *p = ASSERT_PTR(PATH(s->unit));
         int changed;
 
-        assert(s);
-        assert(s->unit);
         assert(fd >= 0);
 
-        p = PATH(s->unit);
-
         if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
                 return 0;
 
@@ -827,10 +821,9 @@ static int path_trigger_notify_on_defer(sd_event_source *s, void *userdata) {
 }
 
 static void path_trigger_notify_impl(Unit *u, Unit *other, bool on_defer) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
         int r;
 
-        assert(u);
         assert(other);
 
         /* Invoked whenever the unit we trigger changes state or gains or loses a job */
@@ -897,9 +890,7 @@ static void path_trigger_notify(Unit *u, Unit *other) {
 }
 
 static void path_reset_failed(Unit *u) {
-        Path *p = PATH(u);
-
-        assert(p);
+        Path *p = ASSERT_PTR(PATH(u));
 
         if (p->state == PATH_FAILED)
                 path_set_state(p, PATH_DEAD);
@@ -908,11 +899,9 @@ static void path_reset_failed(Unit *u) {
 }
 
 static int path_can_start(Unit *u) {
-        Path *p = PATH(u);
+        Path *p = ASSERT_PTR(PATH(u));
         int r;
 
-        assert(p);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
@@ -961,13 +950,11 @@ static int activation_details_path_deserialize(const char *key, const char *valu
 }
 
 static int activation_details_path_append_env(ActivationDetails *details, char ***strv) {
-        ActivationDetailsPath *p = ACTIVATION_DETAILS_PATH(details);
+        ActivationDetailsPath *p = ASSERT_PTR(ACTIVATION_DETAILS_PATH(details));
         char *s;
         int r;
 
-        assert(details);
         assert(strv);
-        assert(p);
 
         if (isempty(p->trigger_path_filename))
                 return 0;
@@ -984,12 +971,10 @@ static int activation_details_path_append_env(ActivationDetails *details, char *
 }
 
 static int activation_details_path_append_pair(ActivationDetails *details, char ***strv) {
-        ActivationDetailsPath *p = ACTIVATION_DETAILS_PATH(details);
+        ActivationDetailsPath *p = ASSERT_PTR(ACTIVATION_DETAILS_PATH(details));
         int r;
 
-        assert(details);
         assert(strv);
-        assert(p);
 
         if (isempty(p->trigger_path_filename))
                 return 0;
index 419370590956f7cd7367f8c3b4f5109d10d3bea3..edce5901547a15b47f03849be5c64643ea34b116 100644 (file)
@@ -35,9 +35,8 @@ static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 
 static void scope_init(Unit *u) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         s->runtime_max_usec = USEC_INFINITY;
@@ -48,9 +47,7 @@ static void scope_init(Unit *u) {
 }
 
 static void scope_done(Unit *u) {
-        Scope *s = SCOPE(u);
-
-        assert(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         s->controller = mfree(s->controller);
         s->controller_track = sd_bus_track_unref(s->controller_track);
@@ -84,6 +81,7 @@ static int scope_arm_timer(Scope *s, bool relative, usec_t usec) {
 
 static void scope_set_state(Scope *s, ScopeState state) {
         ScopeState old_state;
+
         assert(s);
 
         if (s->state != state)
@@ -181,10 +179,9 @@ static int scope_add_extras(Scope *s) {
 }
 
 static int scope_load(Unit *u) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
         int r;
 
-        assert(s);
         assert(u->load_state == UNIT_STUB);
 
         if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
@@ -227,10 +224,9 @@ static usec_t scope_coldplug_timeout(Scope *s) {
 }
 
 static int scope_coldplug(Unit *u) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
         int r;
 
-        assert(s);
         assert(s->state == SCOPE_DEAD);
 
         if (s->deserialized_state == s->state)
@@ -260,10 +256,10 @@ static int scope_coldplug(Unit *u) {
 }
 
 static void scope_dump(Unit *u, FILE *f, const char *prefix) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
-        assert(s);
         assert(f);
+        assert(prefix);
 
         fprintf(f,
                 "%sScope State: %s\n"
@@ -277,7 +273,7 @@ static void scope_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, FORMAT_TIMESPAN(s->runtime_rand_extra_usec, USEC_PER_SEC),
                 prefix, oom_policy_to_string(s->oom_policy));
 
-        cgroup_context_dump(UNIT(s), f, prefix);
+        cgroup_context_dump(u, f, prefix);
         kill_context_dump(&s->kill_context, f, prefix);
 }
 
@@ -346,11 +342,10 @@ fail:
 }
 
 static int scope_enter_start_chown(Scope *s) {
+        Unit *u = UNIT(ASSERT_PTR(s));
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
-        Unit *u = UNIT(s);
         int r;
 
-        assert(s);
         assert(s->user);
 
         if (!s->cgroup_runtime)
@@ -410,11 +405,9 @@ fail:
 }
 
 static int scope_enter_running(Scope *s) {
-        Unit *u = UNIT(s);
+        Unit *u = UNIT(ASSERT_PTR(s));
         int r;
 
-        assert(s);
-
         (void) bus_scope_track_controller(s);
 
         r = unit_acquire_invocation_id(u);
@@ -457,9 +450,7 @@ fail:
 }
 
 static int scope_start(Unit *u) {
-        Scope *s = SCOPE(u);
-
-        assert(s);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         if (unit_has_name(u, SPECIAL_INIT_SCOPE))
                 return -EPERM;
@@ -488,9 +479,7 @@ static int scope_start(Unit *u) {
 }
 
 static int scope_stop(Unit *u) {
-        Scope *s = SCOPE(u);
-
-        assert(s);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
                 return 0;
@@ -502,9 +491,7 @@ static int scope_stop(Unit *u) {
 }
 
 static void scope_reset_failed(Unit *u) {
-        Scope *s = SCOPE(u);
-
-        assert(s);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         if (s->state == SCOPE_FAILED)
                 scope_set_state(s, SCOPE_DEAD);
@@ -513,7 +500,7 @@ static void scope_reset_failed(Unit *u) {
 }
 
 static int scope_get_timeout(Unit *u, usec_t *timeout) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
         usec_t t;
         int r;
 
@@ -531,10 +518,9 @@ static int scope_get_timeout(Unit *u, usec_t *timeout) {
 }
 
 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
         PidRef *pid;
 
-        assert(s);
         assert(f);
         assert(fds);
 
@@ -551,10 +537,9 @@ static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
         int r;
 
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -597,8 +582,7 @@ static int scope_deserialize_item(Unit *u, const char *key, const char *value, F
 }
 
 static void scope_notify_cgroup_empty_event(Unit *u) {
-        Scope *s = SCOPE(u);
-        assert(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         log_unit_debug(u, "cgroup is empty");
 
@@ -607,7 +591,7 @@ static void scope_notify_cgroup_empty_event(Unit *u) {
 }
 
 static void scope_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
-        Scope *s = SCOPE(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         if (managed_oom)
                 log_unit_debug(u, "Process(es) of control group were killed by systemd-oomd.");
@@ -639,9 +623,7 @@ static void scope_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
 }
 
 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
-        Scope *s = SCOPE(u);
-
-        assert(s);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
         if (s->state == SCOPE_START_CHOWN) {
                 if (!is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
@@ -659,9 +641,8 @@ static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 }
 
 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
-        Scope *s = SCOPE(userdata);
+        Scope *s = ASSERT_PTR(SCOPE(userdata));
 
-        assert(s);
         assert(s->timer_event_source == source);
 
         switch (s->state) {
@@ -723,15 +704,15 @@ int scope_abandon(Scope *s) {
 }
 
 static UnitActiveState scope_active_state(Unit *u) {
-        assert(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
-        return state_translation_table[SCOPE(u)->state];
+        return state_translation_table[s->state];
 }
 
 static const char *scope_sub_state_to_string(Unit *u) {
-        assert(u);
+        Scope *s = ASSERT_PTR(SCOPE(u));
 
-        return scope_state_to_string(SCOPE(u)->state);
+        return scope_state_to_string(s->state);
 }
 
 static void scope_enumerate_perpetual(Manager *m) {
index a9047be1cafdb2a698847f4393e579a75b55f1bf..953cb2934aacaf5fc5429bbe30e1e6fef46c91d8 100644 (file)
@@ -180,6 +180,8 @@ static void service_unwatch_main_pid(Service *s) {
 }
 
 static void service_unwatch_pid_file(Service *s) {
+        assert(s);
+
         if (!s->pid_file_pathspec)
                 return;
 
@@ -450,9 +452,7 @@ static void service_release_stdio_fd(Service *s) {
 }
 
 static void service_done(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         open_file_free_many(&s->open_files);
 
@@ -865,7 +865,7 @@ static int service_add_extras(Service *s) {
 }
 
 static int service_load(Unit *u) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         int r;
 
         r = unit_load_fragment_and_dropin(u, true);
@@ -920,11 +920,9 @@ static void service_dump_fdstore(Service *s, FILE *f, const char *prefix) {
 }
 
 static void service_dump(Unit *u, FILE *f, const char *prefix) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         const char *prefix2;
 
-        assert(s);
-
         prefix = strempty(prefix);
         prefix2 = strjoina(prefix, "\t");
 
@@ -2234,6 +2232,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
 
 static bool service_good(Service *s) {
         int main_pid_ok;
+
         assert(s);
 
         if (s->type == SERVICE_DBUS && !s->bus_name_good)
@@ -2290,6 +2289,7 @@ static void service_enter_running(Service *s, ServiceResult f) {
 
 static void service_enter_start_post(Service *s) {
         int r;
+
         assert(s);
 
         service_unwatch_control_pid(s);
@@ -2784,9 +2784,7 @@ static int service_start(Unit *u) {
 }
 
 static int service_stop(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         /* Don't create restart jobs from manual stops. */
         s->forbid_restart = true;
@@ -2843,9 +2841,7 @@ static int service_stop(Unit *u) {
 }
 
 static int service_reload(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         assert(IN_SET(s->state, SERVICE_RUNNING, SERVICE_EXITED));
 
@@ -2854,9 +2850,7 @@ static int service_reload(Unit *u) {
 }
 
 static bool service_can_reload(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         return s->exec_command[SERVICE_EXEC_RELOAD] ||
                 s->type == SERVICE_NOTIFY_RELOAD;
@@ -2880,14 +2874,13 @@ static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, const
 }
 
 static int service_serialize_exec_command(Unit *u, FILE *f, const ExecCommand *command) {
+        Service *s = ASSERT_PTR(SERVICE(u));
         _cleanup_free_ char *args = NULL, *p = NULL;
-        Service *s = SERVICE(u);
         const char *type, *key;
         ServiceExecCommand id;
         size_t length = 0;
         unsigned idx;
 
-        assert(s);
         assert(f);
 
         if (!command)
@@ -2949,10 +2942,9 @@ static int service_serialize_exec_command(Unit *u, FILE *f, const ExecCommand *c
 }
 
 static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         int r;
 
-        assert(u);
         assert(f);
         assert(fds);
 
@@ -3055,14 +3047,14 @@ int service_deserialize_exec_command(
                 const char *key,
                 const char *value) {
 
-        Service *s = SERVICE(u);
-        int r;
-        unsigned idx = 0, i;
-        bool control, found = false, last = false;
-        ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
+        Service *s = ASSERT_PTR(SERVICE(u));
         ExecCommand *command = NULL;
+        ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
         _cleanup_free_ char *path = NULL;
         _cleanup_strv_free_ char **argv = NULL;
+        unsigned idx = 0, i;
+        bool control, found = false, last = false;
+        int r;
 
         enum ExecCommandState {
                 STATE_EXEC_COMMAND_TYPE,
@@ -3073,7 +3065,6 @@ int service_deserialize_exec_command(
                 _STATE_EXEC_COMMAND_INVALID = -EINVAL,
         } state;
 
-        assert(s);
         assert(key);
         assert(value);
 
@@ -3161,10 +3152,9 @@ int service_deserialize_exec_command(
 }
 
 static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         int r;
 
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -3398,13 +3388,12 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
 }
 
 static UnitActiveState service_active_state(Unit *u) {
+        Service *s = ASSERT_PTR(SERVICE(u));
         const UnitActiveState *table;
 
-        assert(u);
-
-        table = SERVICE(u)->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
+        table = s->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
 
-        return table[SERVICE(u)->state];
+        return table[s->state];
 }
 
 static const char *service_sub_state_to_string(Unit *u) {
@@ -3414,9 +3403,7 @@ static const char *service_sub_state_to_string(Unit *u) {
 }
 
 static bool service_may_gc(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         /* Never clean up services that still have a process around, even if the service is formally dead. Note that
          * unit_may_gc() already checked our cgroup for us, we just check our two additional PIDs, too, in case they
@@ -3437,6 +3424,7 @@ static bool service_may_gc(Unit *u) {
 static int service_retry_pid_file(Service *s) {
         int r;
 
+        assert(s);
         assert(s->pid_file);
         assert(IN_SET(s->state, SERVICE_START, SERVICE_START_POST));
 
@@ -3453,6 +3441,8 @@ static int service_retry_pid_file(Service *s) {
 static int service_watch_pid_file(Service *s) {
         int r;
 
+        assert(s);
+
         log_unit_debug(UNIT(s), "Setting watch for PID file %s", s->pid_file_pathspec->path);
 
         r = path_spec_watch(s->pid_file_pathspec, service_dispatch_inotify_io);
@@ -3472,6 +3462,7 @@ static int service_watch_pid_file(Service *s) {
 static int service_demand_pid_file(Service *s) {
         _cleanup_free_ PathSpec *ps = NULL;
 
+        assert(s);
         assert(s->pid_file);
         assert(!s->pid_file_pathspec);
 
@@ -3500,11 +3491,8 @@ static int service_demand_pid_file(Service *s) {
 
 static int service_dispatch_inotify_io(sd_event_source *source, int fd, uint32_t events, void *userdata) {
         PathSpec *p = ASSERT_PTR(userdata);
-        Service *s;
-
-        s = SERVICE(p->unit);
+        Service *s = ASSERT_PTR(SERVICE(p->unit));
 
-        assert(s);
         assert(fd >= 0);
         assert(IN_SET(s->state, SERVICE_START, SERVICE_START_POST));
         assert(s->pid_file_pathspec);
@@ -3530,9 +3518,7 @@ fail:
 }
 
 static int service_dispatch_exec_io(sd_event_source *source, int fd, uint32_t events, void *userdata) {
-        Service *s = SERVICE(userdata);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(userdata));
 
         log_unit_debug(UNIT(s), "got exec-fd event");
 
@@ -3583,9 +3569,7 @@ static int service_dispatch_exec_io(sd_event_source *source, int fd, uint32_t ev
 }
 
 static void service_notify_cgroup_empty_event(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         log_unit_debug(u, "Control group is empty.");
 
@@ -3662,7 +3646,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
 }
 
 static void service_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         if (managed_oom)
                 log_unit_debug(u, "Process(es) of control group were killed by systemd-oomd.");
@@ -3717,13 +3701,12 @@ static void service_notify_cgroup_oom_event(Unit *u, bool managed_oom) {
 }
 
 static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Service *s = ASSERT_PTR(SERVICE(u));
         bool notify_dbus = true;
-        Service *s = SERVICE(u);
         ServiceResult f;
         ExitClean clean_mode;
         int r;
 
-        assert(s);
         assert(pid >= 0);
 
         /* Oneshot services and non-SERVICE_EXEC_START commands should not be
@@ -4089,9 +4072,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 }
 
 static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
-        Service *s = SERVICE(userdata);
+        Service *s = ASSERT_PTR(SERVICE(userdata));
 
-        assert(s);
         assert(source == s->timer_event_source);
 
         switch (s->state) {
@@ -4288,10 +4270,9 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
 }
 
 static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata) {
-        Service *s = SERVICE(userdata);
+        Service *s = ASSERT_PTR(SERVICE(userdata));
         usec_t watchdog_usec;
 
-        assert(s);
         assert(source == s->watchdog_event_source);
 
         watchdog_usec = service_get_watchdog_usec(s);
@@ -4309,6 +4290,8 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
 }
 
 static void service_force_watchdog(Service *s) {
+        assert(s);
+
         if (!UNIT(s)->manager->service_watchdogs)
                 return;
 
@@ -4599,10 +4582,12 @@ static void service_notify_message(
 }
 
 static int service_get_timeout(Unit *u, usec_t *timeout) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         uint64_t t;
         int r;
 
+        assert(timeout);
+
         if (!s->timer_event_source)
                 return 0;
 
@@ -4617,7 +4602,7 @@ static int service_get_timeout(Unit *u, usec_t *timeout) {
 }
 
 static usec_t service_get_timeout_start_usec(Unit *u) {
-        Service *s = SERVICE(ASSERT_PTR(u));
+        Service *s = ASSERT_PTR(SERVICE(u));
         return s->timeout_start_usec;
 }
 
@@ -4637,16 +4622,14 @@ static bool pick_up_pid_from_bus_name(Service *s) {
 }
 
 static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, sd_bus_error *ret_error) {
+        Service *s = ASSERT_PTR(SERVICE(userdata));
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
         const sd_bus_error *e;
-        Unit *u = ASSERT_PTR(userdata);
         uint32_t pid;
-        Service *s;
         int r;
 
         assert(reply);
 
-        s = SERVICE(u);
         s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot);
 
         if (!s->bus_name || !pick_up_pid_from_bus_name(s))
@@ -4671,7 +4654,7 @@ static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, s
                 return 1;
         }
 
-        log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, pidref.pid);
+        log_unit_debug(UNIT(s), "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, pidref.pid);
 
         (void) service_set_main_pidref(s, &pidref);
         (void) unit_watch_pidref(UNIT(s), &s->main_pid, /* exclusive= */ false);
@@ -4679,12 +4662,9 @@ static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, s
 }
 
 static void service_bus_name_owner_change(Unit *u, const char *new_owner) {
-
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         int r;
 
-        assert(s);
-
         if (new_owner)
                 log_unit_debug(u, "D-Bus name %s now owned by %s", s->bus_name, new_owner);
         else
@@ -4742,6 +4722,7 @@ int service_set_socket_fd(
 
         assert(s);
         assert(fd >= 0);
+        assert(sock);
 
         /* This is called by the socket code when instantiating a new service for a stream socket and the socket needs
          * to be configured. We take ownership of the passed fd on success. */
@@ -4773,12 +4754,13 @@ int service_set_socket_fd(
                         return r;
         }
 
-        r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false, UNIT_DEPENDENCY_IMPLICIT);
+        r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_TRIGGERED_BY, UNIT(sock), false, UNIT_DEPENDENCY_IMPLICIT);
         if (r < 0)
-                return r;
+                return log_unit_debug_errno(UNIT(s), r,
+                                            "Failed to add After=/TriggeredBy= dependencies on socket unit: %m");
 
         s->socket_fd = fd;
-        s->socket_peer = socket_peer_ref(peer);
+        s->socket_peer = peer;
         s->socket_fd_selinux_context_net = selinux_context_net;
 
         unit_ref_set(&s->accept_socket, UNIT(s), UNIT(sock));
@@ -4786,9 +4768,7 @@ int service_set_socket_fd(
 }
 
 static void service_reset_failed(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         if (s->state == SERVICE_FAILED)
                 service_set_state(s, service_determine_dead_state(s));
@@ -4814,9 +4794,7 @@ static PidRef* service_control_pid(Unit *u) {
 }
 
 static bool service_needs_console(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         /* We provide our own implementation of this here, instead of relying of the generic implementation
          * unit_needs_console() provides, since we want to return false if we are in SERVICE_EXITED state. */
@@ -4844,9 +4822,7 @@ static bool service_needs_console(Unit *u) {
 }
 
 static int service_exit_status(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         if (s->main_exec_status.pid <= 0 ||
             !dual_timestamp_is_set(&s->main_exec_status.exit_timestamp))
@@ -4859,20 +4835,17 @@ static int service_exit_status(Unit *u) {
 }
 
 static const char* service_status_text(Unit *u) {
-        Service *s = SERVICE(u);
-
-        assert(s);
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         return s->status_text;
 }
 
 static int service_clean(Unit *u, ExecCleanMask mask) {
+        Service *s = ASSERT_PTR(SERVICE(u));
         _cleanup_strv_free_ char **l = NULL;
         bool may_clean_fdstore = false;
-        Service *s = SERVICE(u);
         int r;
 
-        assert(s);
         assert(mask != 0);
 
         if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_DEAD_RESOURCES_PINNED))
@@ -4928,11 +4901,10 @@ fail:
 }
 
 static int service_can_clean(Unit *u, ExecCleanMask *ret) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         ExecCleanMask mask = 0;
         int r;
 
-        assert(s);
         assert(ret);
 
         r = exec_context_get_clean_mask(&s->exec_context, &mask);
@@ -4946,10 +4918,12 @@ static int service_can_clean(Unit *u, ExecCleanMask *ret) {
         return 0;
 }
 
-static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
+static const char* service_finished_job(Unit *u, JobType t, JobResult result) {
+        Service *s = ASSERT_PTR(SERVICE(u));
+
         if (t == JOB_START &&
             result == JOB_DONE &&
-            SERVICE(u)->type == SERVICE_ONESHOT)
+            s->type == SERVICE_ONESHOT)
                 return "Finished %s.";
 
         /* Fall back to generic */
@@ -4957,11 +4931,9 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
 }
 
 static int service_can_start(Unit *u) {
-        Service *s = SERVICE(u);
+        Service *s = ASSERT_PTR(SERVICE(u));
         int r;
 
-        assert(s);
-
         /* Make sure we don't enter a busy loop of some kind. */
         r = unit_test_start_limit(u);
         if (r < 0) {
@@ -4973,7 +4945,7 @@ static int service_can_start(Unit *u) {
 }
 
 static void service_release_resources(Unit *u) {
-        Service *s = SERVICE(ASSERT_PTR(u));
+        Service *s = ASSERT_PTR(SERVICE(u));
 
         /* Invoked by the unit state engine, whenever it realizes that unit is dead and there's no job
          * anymore for it, and it hence is a good idea to release resources */
@@ -5007,14 +4979,9 @@ int service_determine_exec_selinux_label(Service *s, char **ret) {
 
         /* Returns the SELinux label used for execution of the main service binary */
 
-        if (s->exec_context.selinux_context) { /* Prefer the explicitly configured label if there is one */
-                char *con = strdup(s->exec_context.selinux_context);
-                if (!con)
-                        return -ENOMEM;
-
-                *ret = con;
-                return 0;
-        }
+        if (s->exec_context.selinux_context)
+                /* Prefer the explicitly configured label if there is one */
+                return strdup_to(ret, s->exec_context.selinux_context);
 
         if (s->exec_context.root_image ||
             s->exec_context.n_extension_images > 0 ||
index c38f326cba419f7f8dee4ac8c6b67586115ccf73..63ea1758b0867dd971a81bae3b4c3f4dd6d411cd 100644 (file)
@@ -29,6 +29,7 @@ static void slice_init(Unit *u) {
 
 static void slice_set_state(Slice *t, SliceState state) {
         SliceState old_state;
+
         assert(t);
 
         if (t->state != state)
@@ -47,12 +48,10 @@ static void slice_set_state(Slice *t, SliceState state) {
 }
 
 static int slice_add_parent_slice(Slice *s) {
-        Unit *u = UNIT(s);
+        Unit *u = UNIT(ASSERT_PTR(s));
         _cleanup_free_ char *a = NULL;
         int r;
 
-        assert(s);
-
         if (UNIT_GET_SLICE(u))
                 return 0;
 
@@ -151,10 +150,9 @@ static int slice_load_system_slice(Unit *u) {
 }
 
 static int slice_load(Unit *u) {
-        Slice *s = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
         int r;
 
-        assert(s);
         assert(u->load_state == UNIT_STUB);
 
         r = slice_load_root_slice(u);
@@ -196,36 +194,35 @@ static int slice_load(Unit *u) {
 }
 
 static int slice_coldplug(Unit *u) {
-        Slice *t = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        assert(t);
-        assert(t->state == SLICE_DEAD);
+        assert(s->state == SLICE_DEAD);
 
-        if (t->deserialized_state != t->state)
-                slice_set_state(t, t->deserialized_state);
+        if (s->deserialized_state != s->state)
+                slice_set_state(s, s->deserialized_state);
 
         return 0;
 }
 
 static void slice_dump(Unit *u, FILE *f, const char *prefix) {
-        Slice *t = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        assert(t);
+        assert(s);
         assert(f);
+        assert(prefix);
 
         fprintf(f,
                 "%sSlice State: %s\n",
-                prefix, slice_state_to_string(t->state));
+                prefix, slice_state_to_string(s->state));
 
-        cgroup_context_dump(UNIT(t), f, prefix);
+        cgroup_context_dump(u, f, prefix);
 }
 
 static int slice_start(Unit *u) {
-        Slice *t = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
         int r;
 
-        assert(t);
-        assert(t->state == SLICE_DEAD);
+        assert(s->state == SLICE_DEAD);
 
         r = unit_acquire_invocation_id(u);
         if (r < 0)
@@ -234,27 +231,25 @@ static int slice_start(Unit *u) {
         (void) unit_realize_cgroup(u);
         (void) unit_reset_accounting(u);
 
-        slice_set_state(t, SLICE_ACTIVE);
+        slice_set_state(s, SLICE_ACTIVE);
         return 1;
 }
 
 static int slice_stop(Unit *u) {
-        Slice *t = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        assert(t);
-        assert(t->state == SLICE_ACTIVE);
+        assert(s->state == SLICE_ACTIVE);
 
         /* We do not need to destroy the cgroup explicitly,
          * unit_notify() will do that for us anyway. */
 
-        slice_set_state(t, SLICE_DEAD);
+        slice_set_state(s, SLICE_DEAD);
         return 1;
 }
 
 static int slice_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Slice *s = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        assert(s);
         assert(f);
         assert(fds);
 
@@ -264,9 +259,8 @@ static int slice_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int slice_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Slice *s = SLICE(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -276,26 +270,26 @@ static int slice_deserialize_item(Unit *u, const char *key, const char *value, F
 
                 state = slice_state_from_string(value);
                 if (state < 0)
-                        log_debug("Failed to parse state value %s", value);
+                        log_unit_debug(u, "Failed to parse state: %s", value);
                 else
                         s->deserialized_state = state;
 
         } else
-                log_debug("Unknown serialization key '%s'", key);
+                log_unit_debug(u, "Unknown serialization key: %s", key);
 
         return 0;
 }
 
 static UnitActiveState slice_active_state(Unit *u) {
-        assert(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        return state_translation_table[SLICE(u)->state];
+        return state_translation_table[s->state];
 }
 
 static const char *slice_sub_state_to_string(Unit *u) {
-        assert(u);
+        Slice *s = ASSERT_PTR(SLICE(u));
 
-        return slice_state_to_string(SLICE(u)->state);
+        return slice_state_to_string(s->state);
 }
 
 static int slice_make_perpetual(Manager *m, const char *name, Unit **ret) {
index 9f9de2918791f79edee70b0b8e47f3677cebeb65..45656cbda77943db36676f5dd20bf403406d82ad 100644 (file)
@@ -154,11 +154,9 @@ void socket_free_ports(Socket *s) {
 }
 
 static void socket_done(Unit *u) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         SocketPeer *p;
 
-        assert(s);
-
         socket_free_ports(s);
 
         while ((p = set_steal_first(s->peers_by_address)))
@@ -254,6 +252,7 @@ static int socket_add_device_dependencies(Socket *s) {
 
 static int socket_add_default_dependencies(Socket *s) {
         int r;
+
         assert(s);
 
         if (!UNIT(s)->default_dependencies)
@@ -274,6 +273,7 @@ static int socket_add_default_dependencies(Socket *s) {
 
 static bool socket_has_exec(Socket *s) {
         unsigned i;
+
         assert(s);
 
         for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
@@ -284,11 +284,9 @@ static bool socket_has_exec(Socket *s) {
 }
 
 static int socket_add_extras(Socket *s) {
-        Unit *u = UNIT(s);
+        Unit *u = UNIT(ASSERT_PTR(s));
         int r;
 
-        assert(s);
-
         /* Pick defaults for the trigger limit, if nothing was explicitly configured. We pick a relatively high limit
          * in Accept=yes mode, and a lower limit for Accept=no. Reason: in Accept=yes mode we are invoking accept()
          * ourselves before the trigger limit can hit, thus incoming connections are taken off the socket queue quickly
@@ -451,10 +449,9 @@ static int peer_address_compare_func(const SocketPeer *x, const SocketPeer *y) {
 DEFINE_PRIVATE_HASH_OPS(peer_address_hash_ops, SocketPeer, peer_address_hash_func, peer_address_compare_func);
 
 static int socket_load(Unit *u) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         r = unit_load_fragment_and_dropin(u, true);
@@ -510,8 +507,8 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **ret) {
         }, *i;
         int r;
 
-        assert(fd >= 0);
         assert(s);
+        assert(fd >= 0);
         assert(ret);
 
         if (getpeername(fd, &key.peer.sa, &key.peer_salen) < 0)
@@ -571,10 +568,9 @@ static const char* listen_lookup(int family, int type) {
 }
 
 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         const char *prefix2, *str;
 
-        assert(s);
         assert(f);
 
         prefix = strempty(prefix);
@@ -1305,6 +1301,9 @@ static int socket_symlink(Socket *s) {
 static int usbffs_write_descs(int fd, Service *s) {
         int r;
 
+        assert(fd >= 0);
+        assert(s);
+
         if (!s->usb_function_descriptors || !s->usb_function_strings)
                 return -EINVAL;
 
@@ -1370,12 +1369,17 @@ clear:
 }
 
 int socket_load_service_unit(Socket *s, int cfd, Unit **ret) {
+        int r;
+
         /* Figure out what the unit that will be used to handle the connections on the socket looks like.
          *
          * If cfd < 0, then we don't have a connection yet. In case of Accept=yes sockets, use a fake
          * instance name.
          */
 
+        assert(s);
+        assert(ret);
+
         if (UNIT_ISSET(s->service)) {
                 *ret = UNIT_DEREF(s->service);
                 return 0;
@@ -1386,7 +1390,6 @@ int socket_load_service_unit(Socket *s, int cfd, Unit **ret) {
 
         /* Build the instance name and load the unit */
         _cleanup_free_ char *prefix = NULL, *instance = NULL, *name = NULL;
-        int r;
 
         r = unit_name_to_prefix(UNIT(s)->id, &prefix);
         if (r < 0)
@@ -1801,6 +1804,7 @@ static int socket_check_open(Socket *s) {
 
 static void socket_set_state(Socket *s, SocketState state) {
         SocketState old_state;
+
         assert(s);
 
         if (s->state != state)
@@ -1837,10 +1841,9 @@ static void socket_set_state(Socket *s, SocketState state) {
 }
 
 static int socket_coldplug(Unit *u) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(s);
         assert(s->state == SOCKET_DEAD);
 
         if (s->deserialized_state == s->state)
@@ -1897,7 +1900,6 @@ static int socket_coldplug(Unit *u) {
 }
 
 static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) {
-
         _cleanup_(exec_params_shallow_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(
                         EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN);
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
@@ -2033,6 +2035,7 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
 
 static void socket_enter_stop_post(Socket *s, SocketResult f) {
         int r;
+
         assert(s);
 
         if (s->result == SOCKET_SUCCESS)
@@ -2109,6 +2112,7 @@ fail:
 
 static void socket_enter_stop_pre(Socket *s, SocketResult f) {
         int r;
+
         assert(s);
 
         if (s->result == SOCKET_SUCCESS)
@@ -2135,6 +2139,7 @@ static void socket_enter_stop_pre(Socket *s, SocketResult f) {
 
 static void socket_enter_listening(Socket *s) {
         int r;
+
         assert(s);
 
         if (!s->accept && s->flush_pending) {
@@ -2154,6 +2159,7 @@ static void socket_enter_listening(Socket *s) {
 
 static void socket_enter_start_post(Socket *s) {
         int r;
+
         assert(s);
 
         socket_unwatch_control_pid(s);
@@ -2210,6 +2216,7 @@ fail:
 
 static void socket_enter_start_pre(Socket *s) {
         int r;
+
         assert(s);
 
         socket_unwatch_control_pid(s);
@@ -2253,7 +2260,6 @@ static void socket_enter_running(Socket *s, int cfd_in) {
         /* Note that this call takes possession of the connection fd passed. It either has to assign it
          * somewhere or close it. */
         _cleanup_close_ int cfd = cfd_in;
-
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         int r;
 
@@ -2290,8 +2296,8 @@ static void socket_enter_running(Socket *s, int cfd_in) {
 
                 if (!pending) {
                         if (!UNIT_ISSET(s->service)) {
-                                r = log_unit_warning_errno(UNIT(s), SYNTHETIC_ERRNO(ENOENT),
-                                                           "Service to activate vanished, refusing activation.");
+                                log_unit_warning(UNIT(s),
+                                                 "Service to activate vanished, refusing activation.");
                                 goto fail;
                         }
 
@@ -2335,18 +2341,15 @@ static void socket_enter_running(Socket *s, int cfd_in) {
                 }
 
                 r = socket_load_service_unit(s, cfd, &service);
-                if (r < 0) {
-                        if (ERRNO_IS_DISCONNECT(r))
-                                return;
-
-                        log_unit_warning_errno(UNIT(s), r, "Failed to load connection service unit: %m");
+                if (ERRNO_IS_NEG_DISCONNECT(r))
+                        return;
+                if (r < 0 || UNIT_IS_LOAD_ERROR(service->load_state)) {
+                        log_unit_warning_errno(UNIT(s), r < 0 ? r : service->load_error,
+                                               "Failed to load connection service unit: %m");
                         goto fail;
                 }
-
-                r = unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, service,
-                                              false, UNIT_DEPENDENCY_IMPLICIT);
-                if (r < 0) {
-                        log_unit_warning_errno(UNIT(s), r, "Failed to add Before=/Triggers= dependencies on connection unit: %m");
+                if (service->load_state == UNIT_MASKED) {
+                        log_unit_warning(UNIT(s), "Connection service unit is masked, refusing.");
                         goto fail;
                 }
 
@@ -2361,7 +2364,10 @@ static void socket_enter_running(Socket *s, int cfd_in) {
                         goto fail;
                 }
 
-                TAKE_FD(cfd); /* We passed ownership of the fd to the service now. Forget it here. */
+                /* We passed ownership of the fd and socket peer to the service now. */
+                TAKE_FD(cfd);
+                TAKE_PTR(p);
+
                 s->n_connections++;
 
                 r = manager_add_job(UNIT(s)->manager, JOB_START, service, JOB_REPLACE, NULL, &error, NULL);
@@ -2383,13 +2389,9 @@ refuse:
         return;
 
 queue_error:
-        if (ERRNO_IS_RESOURCE(r))
-                log_unit_warning(UNIT(s), "Failed to queue service startup job: %s",
-                                 bus_error_message(&error, r));
-        else
-                log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
-                                 cfd >= 0 ? "template" : "non-template",
-                                 bus_error_message(&error, r));
+        log_unit_warning_errno(UNIT(s), r, "Failed to queue service startup job%s: %s",
+                               cfd >= 0 && !ERRNO_IS_RESOURCE(r) ? " (Maybe the service is missing or is a template unit?)" : "",
+                               bus_error_message(&error, r));
 
 fail:
         socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
@@ -2422,11 +2424,9 @@ static void socket_run_next(Socket *s) {
 }
 
 static int socket_start(Unit *u) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(s);
-
         /* We cannot fulfill this request right now, try again later
          * please! */
         if (IN_SET(s->state,
@@ -2482,9 +2482,7 @@ static int socket_start(Unit *u) {
 }
 
 static int socket_stop(Unit *u) {
-        Socket *s = SOCKET(u);
-
-        assert(s);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
         /* Already on it */
         if (IN_SET(s->state,
@@ -2519,10 +2517,9 @@ static int socket_stop(Unit *u) {
 }
 
 static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(u);
         assert(f);
         assert(fds);
 
@@ -2574,10 +2571,9 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(u);
         assert(key);
         assert(value);
 
@@ -2814,9 +2810,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
 }
 
 static void socket_distribute_fds(Unit *u, FDSet *fds) {
-        Socket *s = SOCKET(u);
-
-        assert(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
         LIST_FOREACH(port, p, s->ports) {
                 int fd;
@@ -2838,15 +2832,15 @@ static void socket_distribute_fds(Unit *u, FDSet *fds) {
 }
 
 static UnitActiveState socket_active_state(Unit *u) {
-        assert(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
-        return state_translation_table[SOCKET(u)->state];
+        return state_translation_table[s->state];
 }
 
 static const char *socket_sub_state_to_string(Unit *u) {
-        assert(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
-        return socket_state_to_string(SOCKET(u)->state);
+        return socket_state_to_string(s->state);
 }
 
 int socket_port_to_address(const SocketPort *p, char **ret) {
@@ -2884,7 +2878,6 @@ int socket_port_to_address(const SocketPort *p, char **ret) {
 }
 
 const char* socket_port_type_to_string(SocketPort *p) {
-
         assert(p);
 
         switch (p->type) {
@@ -2946,9 +2939,7 @@ SocketType socket_port_type_from_string(const char *s) {
 }
 
 static bool socket_may_gc(Unit *u) {
-        Socket *s = SOCKET(u);
-
-        assert(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
         return s->n_connections == 0;
 }
@@ -3086,10 +3077,9 @@ fail:
 }
 
 static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         SocketResult f;
 
-        assert(s);
         assert(pid >= 0);
 
         if (pid != s->control_pid.pid)
@@ -3193,9 +3183,8 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 }
 
 static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
-        Socket *s = SOCKET(userdata);
+        Socket *s = ASSERT_PTR(SOCKET(userdata));
 
-        assert(s);
         assert(s->timer_event_source == source);
 
         switch (s->state) {
@@ -3267,12 +3256,11 @@ static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *use
         return 0;
 }
 
-int socket_collect_fds(Socket *s, int **fds) {
-        size_t k = 0, n = 0;
-        int *rfds;
+int socket_collect_fds(Socket *s, int **ret) {
+        size_t n = 0, k = 0;
 
         assert(s);
-        assert(fds);
+        assert(ret);
 
         /* Called from the service code for requesting our fds */
 
@@ -3282,25 +3270,25 @@ int socket_collect_fds(Socket *s, int **fds) {
                 n += p->n_auxiliary_fds;
         }
 
-        if (n <= 0) {
-                *fds = NULL;
+        if (n == 0) {
+                *ret = NULL;
                 return 0;
         }
 
-        rfds = new(int, n);
-        if (!rfds)
+        int *fds = new(int, n);
+        if (!fds)
                 return -ENOMEM;
 
         LIST_FOREACH(port, p, s->ports) {
                 if (p->fd >= 0)
-                        rfds[k++] = p->fd;
-                for (size_t i = 0; i < p->n_auxiliary_fds; ++i)
-                        rfds[k++] = p->auxiliary_fds[i];
+                        fds[k++] = p->fd;
+                FOREACH_ARRAY(i, p->auxiliary_fds, p->n_auxiliary_fds)
+                        fds[k++] = *i;
         }
 
         assert(k == n);
 
-        *fds = rfds;
+        *ret = fds;
         return (int) n;
 }
 
@@ -3331,9 +3319,8 @@ void socket_connection_unref(Socket *s) {
 }
 
 static void socket_trigger_notify(Unit *u, Unit *other) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
-        assert(u);
         assert(other);
 
         /* Filter out invocations with bogus state */
@@ -3369,7 +3356,7 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
 }
 
 static int socket_get_timeout(Unit *u, usec_t *timeout) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         usec_t t;
         int r;
 
@@ -3401,11 +3388,10 @@ static PidRef *socket_control_pid(Unit *u) {
 }
 
 static int socket_clean(Unit *u, ExecCleanMask mask) {
+        Socket *s = ASSERT_PTR(SOCKET(u));
         _cleanup_strv_free_ char **l = NULL;
-        Socket *s = SOCKET(u);
         int r;
 
-        assert(s);
         assert(mask != 0);
 
         if (s->state != SOCKET_DEAD)
@@ -3445,19 +3431,15 @@ fail:
 }
 
 static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
-        Socket *s = SOCKET(u);
-
-        assert(s);
+        Socket *s = ASSERT_PTR(SOCKET(u));
 
         return exec_context_get_clean_mask(&s->exec_context, ret);
 }
 
 static int socket_can_start(Unit *u) {
-        Socket *s = SOCKET(u);
+        Socket *s = ASSERT_PTR(SOCKET(u));
         int r;
 
-        assert(s);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
index 5efe01d2bf07ad2797f3b203786b6c277a1dafbe..973a697f86154ed10aec7a6b1562d9a536674cc0 100644 (file)
@@ -171,7 +171,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p);
 DEFINE_TRIVIAL_CLEANUP_FUNC(SocketPeer*, socket_peer_unref);
 
 /* Called from the service code when collecting fds */
-int socket_collect_fds(Socket *s, int **fds);
+int socket_collect_fds(Socket *s, int **ret);
 
 /* Called from the service code when a per-connection service ended */
 void socket_connection_unref(Socket *s);
index 709671561b757c1b3704fc160ca036d8b2b69936..9e200086f37817cd42cbb75eef383d520ef2d89b 100644 (file)
@@ -68,9 +68,7 @@ static const char *swap_sub_state_to_string(Unit *u) {
 }
 
 static bool swap_may_gc(Unit *u) {
-        Swap *s = SWAP(u);
-
-        assert(s);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
         if (s->from_proc_swaps)
                 return false;
@@ -134,10 +132,9 @@ static int swap_set_devnode(Swap *s, const char *devnode) {
 }
 
 static void swap_init(Unit *u) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
-        assert(s);
-        assert(UNIT(s)->load_state == UNIT_STUB);
+        assert(u->load_state == UNIT_STUB);
 
         s->timeout_usec = u->manager->defaults.timeout_start_usec;
 
@@ -156,9 +153,7 @@ static void swap_unwatch_control_pid(Swap *s) {
 }
 
 static void swap_done(Unit *u) {
-        Swap *s = SWAP(u);
-
-        assert(s);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
         swap_unset_proc_swaps(s);
         swap_set_devnode(s, NULL);
@@ -251,6 +246,7 @@ static int swap_verify(Swap *s) {
         _cleanup_free_ char *e = NULL;
         int r;
 
+        assert(s);
         assert(UNIT(s)->load_state == UNIT_LOADED);
 
         r = unit_name_from_path(s->what, ".swap", &e);
@@ -349,25 +345,22 @@ static int swap_add_extras(Swap *s) {
 }
 
 static int swap_load(Unit *u) {
-        Swap *s = SWAP(u);
-        int r, q = 0;
+        Swap *s = ASSERT_PTR(SWAP(u));
+        int r;
 
-        assert(s);
         assert(u->load_state == UNIT_STUB);
 
         /* Load a .swap file */
-        bool fragment_optional = s->from_proc_swaps;
-        r = unit_load_fragment_and_dropin(u, !fragment_optional);
+        r = unit_load_fragment_and_dropin(u, /* fragment_required = */ !s->from_proc_swaps);
 
         /* Add in some extras, and do so either when we successfully loaded something or when /proc/swaps is
          * already active. */
         if (u->load_state == UNIT_LOADED || s->from_proc_swaps)
-                q = swap_add_extras(s);
+                RET_GATHER(r, swap_add_extras(s));
 
         if (r < 0)
                 return r;
-        if (q < 0)
-                return q;
+
         if (u->load_state != UNIT_LOADED)
                 return 0;
 
@@ -381,11 +374,11 @@ static int swap_setup_unit(
                 int priority,
                 bool set_flags) {
 
+        _cleanup_(unit_freep) Unit *new = NULL;
         _cleanup_free_ char *e = NULL;
-        bool delete = false;
-        Unit *u = NULL;
+        Unit *u;
+        Swap *s;
         int r;
-        SwapParameters *p;
 
         assert(m);
         assert(what);
@@ -393,70 +386,61 @@ static int swap_setup_unit(
 
         r = unit_name_from_path(what, ".swap", &e);
         if (r < 0)
-                return log_unit_error_errno(u, r, "Failed to generate unit name from path: %m");
+                return log_error_errno(r, "Failed to generate unit name from path: %m");
 
         u = manager_get_unit(m, e);
-        if (u &&
-            SWAP(u)->from_proc_swaps &&
-            !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
-                return log_error_errno(SYNTHETIC_ERRNO(EEXIST),
-                                       "Swap %s appeared twice with different device paths %s and %s",
-                                       e, SWAP(u)->parameters_proc_swaps.what, what_proc_swaps);
-
-        if (!u) {
-                delete = true;
+        if (u) {
+                s = ASSERT_PTR(SWAP(u));
+
+                if (s->from_proc_swaps &&
+                    !path_equal(s->parameters_proc_swaps.what, what_proc_swaps))
+                        return log_unit_error_errno(u, SYNTHETIC_ERRNO(EEXIST),
+                                                    "Swap appeared twice with different device paths %s and %s, refusing.",
+                                                    s->parameters_proc_swaps.what, what_proc_swaps);
+        } else {
+                r = unit_new_for_name(m, sizeof(Swap), e, &new);
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to load swap unit '%s': %m", e);
 
-                r = unit_new_for_name(m, sizeof(Swap), e, &u);
-                if (r < 0) {
-                        log_unit_warning_errno(u, r, "Failed to load swap unit: %m");
-                        goto fail;
-                }
+                u = new;
+                s = ASSERT_PTR(SWAP(u));
 
-                SWAP(u)->what = strdup(what);
-                if (!SWAP(u)->what) {
-                        r = log_oom();
-                        goto fail;
-                }
+                s->what = strdup(what);
+                if (!s->what)
+                        return log_oom();
 
                 unit_add_to_load_queue(u);
-        } else
-                delete = false;
+        }
 
-        p = &SWAP(u)->parameters_proc_swaps;
+        SwapParameters *p = &s->parameters_proc_swaps;
 
         if (!p->what) {
                 p->what = strdup(what_proc_swaps);
-                if (!p->what) {
-                        r = log_oom();
-                        goto fail;
-                }
+                if (!p->what)
+                        return log_oom();
         }
 
-        /* The unit is definitely around now, mark it as loaded if it was previously referenced but could not be
-         * loaded. After all we can load it now, from the data in /proc/swaps. */
-        if (IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_ERROR)) {
+        /* The unit is definitely around now, mark it as loaded if it was previously referenced but
+         * could not be loaded. After all we can load it now, from the data in /proc/swaps. */
+        if (UNIT_IS_LOAD_ERROR(u->load_state)) {
                 u->load_state = UNIT_LOADED;
                 u->load_error = 0;
         }
 
         if (set_flags) {
-                SWAP(u)->is_active = true;
-                SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
+                s->is_active = true;
+                s->just_activated = !s->from_proc_swaps;
         }
 
-        SWAP(u)->from_proc_swaps = true;
+        s->from_proc_swaps = true;
 
         p->priority = priority;
         p->priority_set = true;
 
         unit_add_to_dbus_queue(u);
-        return 0;
-
-fail:
-        if (delete)
-                unit_free(u);
+        TAKE_PTR(new);
 
-        return r;
+        return 0;
 }
 
 static void swap_process_new(Manager *m, const char *device, int prio, bool set_flags) {
@@ -537,11 +521,10 @@ static void swap_set_state(Swap *s, SwapState state) {
 }
 
 static int swap_coldplug(Unit *u) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
         SwapState new_state = SWAP_DEAD;
         int r;
 
-        assert(s);
         assert(s->state == SWAP_DEAD);
 
         if (s->deserialized_state != s->state)
@@ -575,10 +558,9 @@ static int swap_coldplug(Unit *u) {
 }
 
 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
         SwapParameters *p;
 
-        assert(s);
         assert(f);
 
         if (s->from_proc_swaps)
@@ -629,7 +611,6 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static int swap_spawn(Swap *s, ExecCommand *c, PidRef *ret_pid) {
-
         _cleanup_(exec_params_shallow_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(
                         EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN);
         _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
@@ -902,9 +883,7 @@ static int swap_start(Unit *u) {
 }
 
 static int swap_stop(Unit *u) {
-        Swap *s = SWAP(u);
-
-        assert(s);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
         switch (s->state) {
 
@@ -938,9 +917,8 @@ static int swap_stop(Unit *u) {
 }
 
 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
-        assert(s);
         assert(f);
         assert(fds);
 
@@ -955,9 +933,8 @@ static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
-        assert(s);
         assert(fds);
 
         if (streq(key, "state")) {
@@ -998,10 +975,9 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD
 }
 
 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
         SwapResult f;
 
-        assert(s);
         assert(pid >= 0);
 
         if (pid != s->control_pid.pid)
@@ -1075,9 +1051,8 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 }
 
 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
-        Swap *s = SWAP(userdata);
+        Swap *s = ASSERT_PTR(SWAP(userdata));
 
-        assert(s);
         assert(s->timer_event_source == source);
 
         switch (s->state) {
@@ -1250,12 +1225,10 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
         return swap_process_proc_swaps(m);
 }
 
-static Unit *swap_following(Unit *u) {
-        Swap *s = SWAP(u);
+static Unitswap_following(Unit *u) {
+        Swap *s = ASSERT_PTR(SWAP(u));
         Swap *first = NULL;
 
-        assert(s);
-
         /* If the user configured the swap through /etc/fstab or
          * a device unit, follow that. */
 
@@ -1287,16 +1260,15 @@ static Unit *swap_following(Unit *u) {
         return UNIT(first);
 }
 
-static int swap_following_set(Unit *u, Set **_set) {
-        Swap *s = SWAP(u);
+static int swap_following_set(Unit *u, Set **ret) {
+        Swap *s = ASSERT_PTR(SWAP(u));
         _cleanup_set_free_ Set *set = NULL;
         int r;
 
-        assert(s);
-        assert(_set);
+        assert(ret);
 
         if (LIST_JUST_US(same_devnode, s)) {
-                *_set = NULL;
+                *ret = NULL;
                 return 0;
         }
 
@@ -1310,7 +1282,7 @@ static int swap_following_set(Unit *u, Set **_set) {
                         return r;
         }
 
-        *_set = TAKE_PTR(set);
+        *ret = TAKE_PTR(set);
         return 1;
 }
 
@@ -1411,28 +1383,22 @@ int swap_process_device_new(Manager *m, sd_device *dev) {
 
 int swap_process_device_remove(Manager *m, sd_device *dev) {
         const char *dn;
-        int r;
         Swap *s;
+        int r;
 
         r = sd_device_get_devname(dev, &dn);
         if (r < 0)
                 return 0;
 
-        while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
-                int q;
-
-                q = swap_set_devnode(s, NULL);
-                if (q < 0)
-                        r = q;
-        }
+        r = 0;
+        while ((s = hashmap_get(m->swaps_by_devnode, dn)))
+                RET_GATHER(r, swap_set_devnode(s, NULL));
 
         return r;
 }
 
 static void swap_reset_failed(Unit *u) {
-        Swap *s = SWAP(u);
-
-        assert(s);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
         if (s->state == SWAP_FAILED)
                 swap_set_state(s, SWAP_DEAD);
@@ -1442,13 +1408,10 @@ static void swap_reset_failed(Unit *u) {
 }
 
 static int swap_get_timeout(Unit *u, usec_t *timeout) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
         usec_t t;
         int r;
 
-        assert(s);
-        assert(u);
-
         if (!s->timer_event_source)
                 return 0;
 
@@ -1482,11 +1445,10 @@ static PidRef* swap_control_pid(Unit *u) {
 }
 
 static int swap_clean(Unit *u, ExecCleanMask mask) {
+        Swap *s = ASSERT_PTR(SWAP(u));
         _cleanup_strv_free_ char **l = NULL;
-        Swap *s = SWAP(u);
         int r;
 
-        assert(s);
         assert(mask != 0);
 
         if (s->state != SWAP_DEAD)
@@ -1526,19 +1488,15 @@ fail:
 }
 
 static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
-        Swap *s = SWAP(u);
-
-        assert(s);
+        Swap *s = ASSERT_PTR(SWAP(u));
 
         return exec_context_get_clean_mask(&s->exec_context, ret);
 }
 
 static int swap_can_start(Unit *u) {
-        Swap *s = SWAP(u);
+        Swap *s = ASSERT_PTR(SWAP(u));
         int r;
 
-        assert(s);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
index 3851f21442dfe2578a62541ca13b037c47eba5b4..bbaa5d313c35cc7fff9ffafee9304658d1a1be82 100644 (file)
@@ -70,11 +70,9 @@ static int target_add_default_dependencies(Target *t) {
 }
 
 static int target_load(Unit *u) {
-        Target *t = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
         int r;
 
-        assert(t);
-
         r = unit_load_fragment_and_dropin(u, true);
         if (r < 0)
                 return r;
@@ -87,9 +85,8 @@ static int target_load(Unit *u) {
 }
 
 static int target_coldplug(Unit *u) {
-        Target *t = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        assert(t);
         assert(t->state == TARGET_DEAD);
 
         if (t->deserialized_state != t->state)
@@ -99,10 +96,10 @@ static int target_coldplug(Unit *u) {
 }
 
 static void target_dump(Unit *u, FILE *f, const char *prefix) {
-        Target *t = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        assert(t);
         assert(f);
+        assert(prefix);
 
         fprintf(f,
                 "%sTarget State: %s\n",
@@ -110,10 +107,9 @@ static void target_dump(Unit *u, FILE *f, const char *prefix) {
 }
 
 static int target_start(Unit *u) {
-        Target *t = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
         int r;
 
-        assert(t);
         assert(t->state == TARGET_DEAD);
 
         r = unit_acquire_invocation_id(u);
@@ -125,9 +121,8 @@ static int target_start(Unit *u) {
 }
 
 static int target_stop(Unit *u) {
-        Target *t = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        assert(t);
         assert(t->state == TARGET_ACTIVE);
 
         target_set_state(t, TARGET_DEAD);
@@ -135,21 +130,18 @@ static int target_stop(Unit *u) {
 }
 
 static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Target *s = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        assert(s);
         assert(f);
         assert(fds);
 
-        (void) serialize_item(f, "state", target_state_to_string(s->state));
+        (void) serialize_item(f, "state", target_state_to_string(t->state));
         return 0;
 }
 
 static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Target *s = TARGET(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        assert(s);
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -159,26 +151,26 @@ static int target_deserialize_item(Unit *u, const char *key, const char *value,
 
                 state = target_state_from_string(value);
                 if (state < 0)
-                        log_debug("Failed to parse state value %s", value);
+                        log_unit_debug(u, "Failed to parse state: %s", value);
                 else
-                        s->deserialized_state = state;
+                        t->deserialized_state = state;
 
         } else
-                log_debug("Unknown serialization key '%s'", key);
+                log_unit_debug(u, "Unknown serialization key: %s", key);
 
         return 0;
 }
 
 static UnitActiveState target_active_state(Unit *u) {
-        assert(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        return state_translation_table[TARGET(u)->state];
+        return state_translation_table[t->state];
 }
 
 static const char *target_sub_state_to_string(Unit *u) {
-        assert(u);
+        Target *t = ASSERT_PTR(TARGET(u));
 
-        return target_state_to_string(TARGET(u)->state);
+        return target_state_to_string(t->state);
 }
 
 const UnitVTable target_vtable = {
index 771e134523be69768bf395e379bf547100de1b3a..0c451c020c401583451a25ef17e02352431cf2ce 100644 (file)
@@ -35,9 +35,8 @@ static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata);
 
 static void timer_init(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         t->next_elapse_monotonic_or_boottime = USEC_INFINITY;
@@ -58,9 +57,7 @@ void timer_free_values(Timer *t) {
 }
 
 static void timer_done(Unit *u) {
-        Timer *t = TIMER(u);
-
-        assert(t);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
         timer_free_values(t);
 
@@ -201,10 +198,9 @@ static uint64_t timer_get_fixed_delay_hash(Timer *t) {
 }
 
 static int timer_load(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         int r;
 
-        assert(u);
         assert(u->load_state == UNIT_STUB);
 
         r = unit_load_fragment_and_dropin(u, true);
@@ -231,9 +227,12 @@ static int timer_load(Unit *u) {
 }
 
 static void timer_dump(Unit *u, FILE *f, const char *prefix) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         Unit *trigger;
 
+        assert(f);
+        assert(prefix);
+
         trigger = UNIT_TRIGGER(u);
 
         fprintf(f,
@@ -279,6 +278,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
 
 static void timer_set_state(Timer *t, TimerState state) {
         TimerState old_state;
+
         assert(t);
 
         if (t->state != state)
@@ -303,9 +303,8 @@ static void timer_set_state(Timer *t, TimerState state) {
 static void timer_enter_waiting(Timer *t, bool time_change);
 
 static int timer_coldplug(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(t);
         assert(t->state == TIMER_DEAD);
 
         if (t->deserialized_state == t->state)
@@ -634,10 +633,9 @@ fail:
 }
 
 static int timer_start(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         int r;
 
-        assert(t);
         assert(IN_SET(t->state, TIMER_DEAD, TIMER_FAILED));
 
         r = unit_test_trigger_loaded(u);
@@ -682,9 +680,8 @@ static int timer_start(Unit *u) {
 }
 
 static int timer_stop(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(t);
         assert(IN_SET(t->state, TIMER_WAITING, TIMER_RUNNING, TIMER_ELAPSED));
 
         timer_enter_dead(t, TIMER_SUCCESS);
@@ -692,9 +689,8 @@ static int timer_stop(Unit *u) {
 }
 
 static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(u);
         assert(f);
         assert(fds);
 
@@ -711,9 +707,8 @@ static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
 }
 
 static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(u);
         assert(key);
         assert(value);
         assert(fds);
@@ -747,21 +742,19 @@ static int timer_deserialize_item(Unit *u, const char *key, const char *value, F
 }
 
 static UnitActiveState timer_active_state(Unit *u) {
-        assert(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        return state_translation_table[TIMER(u)->state];
+        return state_translation_table[t->state];
 }
 
 static const char *timer_sub_state_to_string(Unit *u) {
-        assert(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        return timer_state_to_string(TIMER(u)->state);
+        return timer_state_to_string(t->state);
 }
 
 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata) {
-        Timer *t = TIMER(userdata);
-
-        assert(t);
+        Timer *t = ASSERT_PTR(TIMER(userdata));
 
         if (t->state != TIMER_WAITING)
                 return 0;
@@ -772,9 +765,8 @@ static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata) {
 }
 
 static void timer_trigger_notify(Unit *u, Unit *other) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(u);
         assert(other);
 
         /* Filter out invocations with bogus state */
@@ -812,9 +804,7 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
 }
 
 static void timer_reset_failed(Unit *u) {
-        Timer *t = TIMER(u);
-
-        assert(t);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
         if (t->state == TIMER_FAILED)
                 timer_set_state(t, TIMER_DEAD);
@@ -823,11 +813,9 @@ static void timer_reset_failed(Unit *u) {
 }
 
 static void timer_time_change(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         usec_t ts;
 
-        assert(u);
-
         if (t->state != TIMER_WAITING)
                 return;
 
@@ -849,9 +837,7 @@ static void timer_time_change(Unit *u) {
 }
 
 static void timer_timezone_change(Unit *u) {
-        Timer *t = TIMER(u);
-
-        assert(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
         if (t->state != TIMER_WAITING)
                 return;
@@ -866,10 +852,9 @@ static void timer_timezone_change(Unit *u) {
 }
 
 static int timer_clean(Unit *u, ExecCleanMask mask) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         int r;
 
-        assert(t);
         assert(mask != 0);
 
         if (t->state != TIMER_DEAD)
@@ -892,9 +877,8 @@ static int timer_clean(Unit *u, ExecCleanMask mask) {
 }
 
 static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
 
-        assert(t);
         assert(ret);
 
         *ret = t->persistent ? EXEC_CLEAN_STATE : 0;
@@ -902,11 +886,9 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
 }
 
 static int timer_can_start(Unit *u) {
-        Timer *t = TIMER(u);
+        Timer *t = ASSERT_PTR(TIMER(u));
         int r;
 
-        assert(t);
-
         r = unit_test_start_limit(u);
         if (r < 0) {
                 timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
@@ -917,9 +899,8 @@ static int timer_can_start(Unit *u) {
 }
 
 static void activation_details_timer_serialize(ActivationDetails *details, FILE *f) {
-        ActivationDetailsTimer *t = ACTIVATION_DETAILS_TIMER(details);
+        ActivationDetailsTimer *t = ASSERT_PTR(ACTIVATION_DETAILS_TIMER(details));
 
-        assert(details);
         assert(f);
         assert(t);
 
@@ -950,10 +931,9 @@ static int activation_details_timer_deserialize(const char *key, const char *val
 }
 
 static int activation_details_timer_append_env(ActivationDetails *details, char ***strv) {
-        ActivationDetailsTimer *t = ACTIVATION_DETAILS_TIMER(details);
+        ActivationDetailsTimer *t = ASSERT_PTR(ACTIVATION_DETAILS_TIMER(details));
         int r;
 
-        assert(details);
         assert(strv);
         assert(t);
 
@@ -972,10 +952,9 @@ static int activation_details_timer_append_env(ActivationDetails *details, char
 }
 
 static int activation_details_timer_append_pair(ActivationDetails *details, char ***strv) {
-        ActivationDetailsTimer *t = ACTIVATION_DETAILS_TIMER(details);
+        ActivationDetailsTimer *t = ASSERT_PTR(ACTIVATION_DETAILS_TIMER(details));
         int r;
 
-        assert(details);
         assert(strv);
         assert(t);
 
index 40267531d12b9fb9bcdf939d980693b387dc86c2..f25e2e39861b7f0bda1416caa1fa18bfe53ec6c1 100644 (file)
@@ -91,37 +91,22 @@ static int specifier_cgroup(char specifier, const void *data, const char *root,
 
         bad_specifier(u, specifier);
 
-        if (crt && crt->cgroup_path) {
-                char *n;
-
-                n = strdup(crt->cgroup_path);
-                if (!n)
-                        return -ENOMEM;
-
-                *ret = n;
-                return 0;
-        }
+        if (crt && crt->cgroup_path)
+                return strdup_to(ret, crt->cgroup_path);
 
         return unit_default_cgroup_path(u, ret);
 }
 
 static int specifier_cgroup_root(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const Unit *u = ASSERT_PTR(userdata);
-        char *n;
 
         bad_specifier(u, specifier);
 
-        n = strdup(u->manager->cgroup_root);
-        if (!n)
-                return -ENOMEM;
-
-        *ret = n;
-        return 0;
+        return strdup_to(ret, u->manager->cgroup_root);
 }
 
 static int specifier_cgroup_slice(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const Unit *u = ASSERT_PTR(userdata), *slice;
-        char *n;
 
         bad_specifier(u, specifier);
 
@@ -130,28 +115,18 @@ static int specifier_cgroup_slice(char specifier, const void *data, const char *
                 CGroupRuntime *crt = unit_get_cgroup_runtime(slice);
 
                 if (crt && crt->cgroup_path)
-                        n = strdup(crt->cgroup_path);
-                else
-                        return unit_default_cgroup_path(slice, ret);
-        } else
-                n = strdup(u->manager->cgroup_root);
-        if (!n)
-                return -ENOMEM;
+                        return strdup_to(ret, crt->cgroup_path);
 
-        *ret = n;
-        return 0;
+                return unit_default_cgroup_path(slice, ret);
+        }
+
+        return strdup_to(ret, u->manager->cgroup_root);
 }
 
 static int specifier_special_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const Unit *u = ASSERT_PTR(userdata);
-        char *n;
 
-        n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
-        if (!n)
-                return -ENOMEM;
-
-        *ret = n;
-        return 0;
+        return strdup_to(ret, u->manager->prefix[PTR_TO_UINT(data)]);
 }
 
 static int specifier_credentials_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
index c0f802a137568db44c6e451c2967b654cfc2f007..9c0794b886737a0b5bff047d5171805c058fd666 100644 (file)
@@ -5338,7 +5338,7 @@ int unit_set_exec_params(Unit *u, ExecParameters *p) {
 
         p->runtime_scope = u->manager->runtime_scope;
 
-        r = strdup_or_null(manager_get_confirm_spawn(u->manager), &p->confirm_spawn);
+        r = strdup_to(&p->confirm_spawn, manager_get_confirm_spawn(u->manager));
         if (r < 0)
                 return r;
 
index 7134d362fe11120bea2b4e0d8fbb353b5086c0a3..0cfd90b3d4c5a174a81379f92f7bae3cf617cd98 100644 (file)
@@ -67,6 +67,10 @@ static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
         return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
 }
 
+static inline bool UNIT_IS_LOAD_ERROR(UnitLoadState t) {
+        return IN_SET(t, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_ERROR);
+}
+
 /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
  * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
  * created as a result of multiple "reasons", hence the bitmask. */
index 7e0c98cb7d45016c01c319d2320789287763d9ab..8e2febd5810bffe06927d3f2b492ec2f25553530 100644 (file)
@@ -179,18 +179,12 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
 
                         c = hashmap_get(h, UID_TO_PTR(uid));
                         if (c) {
-
                                 if (t < c->oldest_mtime) {
-                                        char *n;
-
-                                        n = strdup(de->d_name);
-                                        if (!n)
-                                                return log_oom();
-
-                                        free_and_replace(c->oldest_file, n);
+                                        r = free_and_strdup_warn(&c->oldest_file, de->d_name);
+                                        if (r < 0)
+                                                return r;
                                         c->oldest_mtime = t;
                                 }
-
                         } else {
                                 _cleanup_(vacuum_candidate_freep) VacuumCandidate *n = NULL;
 
@@ -198,10 +192,9 @@ int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
                                 if (!n)
                                         return log_oom();
 
-                                n->oldest_file = strdup(de->d_name);
-                                if (!n->oldest_file)
-                                        return log_oom();
-
+                                r = free_and_strdup_warn(&n->oldest_file, de->d_name);
+                                if (r < 0)
+                                        return r;
                                 n->oldest_mtime = t;
 
                                 r = hashmap_put(h, UID_TO_PTR(uid), n);
index e4c8c9674c044e26d00c127adb99ab4ee51afabe..b4df9d23c2a4a003174432fe89f2d8297f42a1d0 100644 (file)
@@ -498,13 +498,8 @@ static int mandatory_mount_drop_unapplicable_options(
         assert(where);
         assert(ret_options);
 
-        if (!(*flags & (MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT))) {
-                r = strdup_or_null(options, ret_options);
-                if (r < 0)
-                        return r;
-
-                return 0;
-        }
+        if (!(*flags & (MOUNT_NOAUTO|MOUNT_NOFAIL|MOUNT_AUTOMOUNT)))
+                return strdup_to(ret_options, options);
 
         log_debug("Mount '%s' is mandatory, ignoring 'noauto', 'nofail', and 'x-systemd.automount' options.",
                   where);
index f2e5787a546f578ff51460b97f5b2e70a014213f..42131b9f41ddeee4c2405fd4ccc9f091f5967c94 100644 (file)
@@ -9,6 +9,13 @@
 #include "time-util.h"
 #include "user-record.h"
 
+/* Flags supported by UpdateEx() */
+#define SD_HOMED_UPDATE_OFFLINE (UINT64_C(1) << 0)
+#define SD_HOMED_UPDATE_FLAGS_ALL (SD_HOMED_UPDATE_OFFLINE)
+
+/* Flags supported by CreateHomeEx() */
+#define SD_HOMED_CREATE_FLAGS_ALL (0)
+
 /* Put some limits on disk sizes: not less than 5M, not more than 5T */
 #define USER_DISK_SIZE_MIN (UINT64_C(5)*1024*1024)
 #define USER_DISK_SIZE_MAX (UINT64_C(5)*1024*1024*1024*1024)
index 11a138070b1fd09b2dc28bb4a9cdb88e36bd3b9d..2a7917d7f9f846e53ee90a640d345f14a24f54b4 100644 (file)
@@ -61,6 +61,7 @@ static bool arg_legend = true;
 static bool arg_ask_password = true;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static const char *arg_host = NULL;
+static bool arg_offline = false;
 static const char *arg_identity = NULL;
 static JsonVariant *arg_identity_extra = NULL;
 static JsonVariant *arg_identity_extra_privileged = NULL;
@@ -1712,6 +1713,7 @@ static int update_home(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *buffer = NULL;
         _cleanup_hashmap_free_ Hashmap *blobs = NULL;
         const char *username;
+        uint64_t flags = 0;
         int r;
 
         if (argc >= 2)
@@ -1754,6 +1756,9 @@ static int update_home(int argc, char *argv[], void *userdata) {
         if (arg_and_resize || arg_and_change_password)
                 log_info("Updating home directory.");
 
+        if (arg_offline)
+                flags |= SD_HOMED_UPDATE_OFFLINE;
+
         for (;;) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
@@ -1777,7 +1782,7 @@ static int update_home(int argc, char *argv[], void *userdata) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append(m, "t", UINT64_C(0));
+                r = sd_bus_message_append(m, "t", flags);
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -2564,6 +2569,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "     --no-pager                Do not pipe output into a pager\n"
                "     --no-legend               Do not show the headers and footers\n"
                "     --no-ask-password         Do not ask for system passwords\n"
+               "     --offline                 Don't update record embedded in home directory\n"
                "  -H --host=[USER@]HOST        Operate on remote host\n"
                "  -M --machine=CONTAINER       Operate on local container\n"
                "     --identity=PATH           Read JSON identity from file\n"
@@ -2723,6 +2729,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NO_PAGER,
                 ARG_NO_LEGEND,
                 ARG_NO_ASK_PASSWORD,
+                ARG_OFFLINE,
                 ARG_REALM,
                 ARG_EMAIL_ADDRESS,
                 ARG_DISK_SIZE,
@@ -2808,6 +2815,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "no-pager",                    no_argument,       NULL, ARG_NO_PAGER                    },
                 { "no-legend",                   no_argument,       NULL, ARG_NO_LEGEND                   },
                 { "no-ask-password",             no_argument,       NULL, ARG_NO_ASK_PASSWORD             },
+                { "offline",                     no_argument,       NULL, ARG_OFFLINE                     },
                 { "host",                        required_argument, NULL, 'H'                             },
                 { "machine",                     required_argument, NULL, 'M'                             },
                 { "identity",                    required_argument, NULL, 'I'                             },
@@ -2933,6 +2941,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_ask_password = false;
                         break;
 
+                case ARG_OFFLINE:
+                        arg_offline = true;
+                        break;
+
                 case 'H':
                         arg_transport = BUS_TRANSPORT_REMOTE;
                         arg_host = optarg;
index 368ce2d9e23d682e4861457799dde28226a80eb6..23578fe314be5cbbd961e634460c5c971fa36ddc 100644 (file)
@@ -6,6 +6,7 @@
 #include "bus-polkit.h"
 #include "fd-util.h"
 #include "format-util.h"
+#include "home-util.h"
 #include "homed-bus.h"
 #include "homed-home-bus.h"
 #include "homed-home.h"
@@ -415,7 +416,7 @@ int bus_home_method_authenticate(
         return 1;
 }
 
-int bus_home_method_update_record(
+int bus_home_update_record(
                 Home *h,
                 sd_bus_message *message,
                 UserRecord *hr,
@@ -432,8 +433,8 @@ int bus_home_method_update_record(
         if (r < 0)
                 return r;
 
-        if (flags != 0)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Provided flags are unsupported.");
+        if ((flags & ~SD_HOMED_UPDATE_FLAGS_ALL) != 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags provided.");
 
         r = home_verify_polkit_async(
                         h,
@@ -457,6 +458,8 @@ int bus_home_method_update_record(
         if (r < 0)
                 return r;
 
+        h->current_operation->call_flags = flags;
+
         return 1;
 }
 
@@ -473,7 +476,7 @@ int bus_home_method_update(
 
         assert(message);
 
-        r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_REQUIRE_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE, &hr, error);
+        r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE, &hr, error);
         if (r < 0)
                 return r;
 
@@ -487,7 +490,7 @@ int bus_home_method_update(
                         return r;
         }
 
-        return bus_home_method_update_record(h, message, hr, blobs, flags, error);
+        return bus_home_update_record(h, message, hr, blobs, flags, error);
 }
 
 int bus_home_method_resize(
@@ -521,7 +524,7 @@ int bus_home_method_resize(
         if (r == 0)
                 return 1; /* Will call us back */
 
-        r = home_resize(h, sz, secret, /* automatic= */ false, error);
+        r = home_resize(h, sz, secret, error);
         if (r < 0)
                 return r;
 
@@ -657,7 +660,7 @@ int bus_home_method_acquire(
                 return r;
 
         /* This operation might not be something we can executed immediately, hence queue it */
-        fd = home_create_fifo(h, please_suspend ? HOME_FIFO_PLEASE_SUSPEND : HOME_FIFO_DONT_SUSPEND);
+        fd = home_create_fifo(h, please_suspend);
         if (fd < 0)
                 return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);
 
@@ -716,7 +719,7 @@ int bus_home_method_ref(
                 }
         }
 
-        fd = home_create_fifo(h, please_suspend ? HOME_FIFO_PLEASE_SUSPEND : HOME_FIFO_DONT_SUSPEND);
+        fd = home_create_fifo(h, please_suspend);
         if (fd < 0)
                 return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);
 
@@ -745,51 +748,6 @@ int bus_home_method_release(
         return 1;
 }
 
-int bus_home_method_inhibit_suspend(
-                sd_bus_message *message,
-                void *userdata,
-                sd_bus_error *error) {
-
-        _cleanup_close_ int fd = -EBADF;
-        Home *h = ASSERT_PTR(userdata);
-        HomeState state;
-        int r;
-
-        r = home_verify_polkit_async(
-                        h,
-                        message,
-                        "org.freedesktop.home1.inhibit-suspend",
-                        h->uid,
-                        error);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                return 1; /* Will call us back */
-
-        state = home_get_state(h);
-        switch (state) {
-        case HOME_ABSENT:
-                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
-        case HOME_UNFIXATED:
-        case HOME_INACTIVE:
-        case HOME_DIRTY:
-                return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
-        case HOME_LOCKED:
-                return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
-        default:
-                if (HOME_STATE_IS_ACTIVE(state))
-                        break;
-
-                return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
-        }
-
-        fd = home_create_fifo(h, HOME_FIFO_INHIBIT_SUSPEND);
-        if (fd < 0)
-                return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);
-
-        return sd_bus_reply_method_return(message, "h", fd);
-}
-
 /* We map a uid_t as uint32_t bus property, let's ensure this is safe. */
 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
 
@@ -949,11 +907,6 @@ const sd_bus_vtable home_vtable[] = {
                                 bus_home_method_ref,
                                 0),
         SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
-        SD_BUS_METHOD_WITH_ARGS("InhibitSuspend",
-                                SD_BUS_NO_ARGS,
-                                SD_BUS_RESULT("h", send_fd),
-                                bus_home_method_inhibit_suspend,
-                                SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END
 };
 
index 9ba2cf1252504ec49d4aebd66acd6e8cb39e3686..1644bc8066a428b191e635b7462adf7174e8b3f1 100644 (file)
@@ -17,7 +17,6 @@ int bus_home_method_remove(sd_bus_message *message, void *userdata, sd_bus_error
 int bus_home_method_fixate(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_authenticate(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_update(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_home_method_update_record(Home *home, sd_bus_message *message, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
 int bus_home_method_resize(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_change_password(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error);
@@ -25,7 +24,8 @@ int bus_home_method_unlock(sd_bus_message *message, void *userdata, sd_bus_error
 int bus_home_method_acquire(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_home_method_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int bus_home_method_inhibit_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error);
+
+int bus_home_update_record(Home *home, sd_bus_message *message, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
 
 extern const BusObjectImplementation home_object;
 
index edde6fafd3cbb092378068b9e9933e50e9d0c450..447e8c597cadd12ca9ce33b75157d1355432fce3 100644 (file)
@@ -226,7 +226,6 @@ Home *home_free(Home *h) {
 
         h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);
         h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);
-        h->inhibit_suspend_event_source = sd_event_source_disable_unref(h->inhibit_suspend_event_source);
 
         h->pending_operations = ordered_set_free(h->pending_operations);
         h->pending_event_source = sd_event_source_disable_unref(h->pending_event_source);
@@ -956,10 +955,13 @@ static void home_create_finish(Home *h, int ret, UserRecord *hr) {
 
 static void home_change_finish(Home *h, int ret, UserRecord *hr) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        uint64_t flags;
         int r;
 
         assert(h);
 
+        flags = h->current_operation ? h->current_operation->call_flags : 0;
+
         if (ret < 0) {
                 (void) home_count_bad_authentication(h, ret, /* save= */ true);
 
@@ -970,17 +972,22 @@ static void home_change_finish(Home *h, int ret, UserRecord *hr) {
         }
 
         if (hr) {
-                r = home_set_record(h, hr);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to update home record, ignoring: %m");
-                else {
+                if (!FLAGS_SET(flags, SD_HOMED_UPDATE_OFFLINE)) {
                         r = user_record_good_authentication(h->record);
                         if (r < 0)
                                 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
+                }
 
+                r = home_set_record(h, hr);
+                if (r >= 0)
                         r = home_save_record(h);
-                        if (r < 0)
-                                log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
+                if (r < 0) {
+                        if (FLAGS_SET(flags, SD_HOMED_UPDATE_OFFLINE)) {
+                                log_error_errno(r, "Failed to update home record and write it to disk: %m");
+                                sd_bus_error_set(&error, SD_BUS_ERROR_FAILED, "Failed to cache changes to home record");
+                                goto finish;
+                        } else
+                                log_warning_errno(r, "Failed to update home record, ignoring: %m");
                 }
         }
 
@@ -1313,6 +1320,11 @@ static int home_start_work(
                                 _exit(EXIT_FAILURE);
                         }
 
+                if (setenv("SYSTEMD_HOMEWORK_UPDATE_OFFLINE", one_zero(FLAGS_SET(flags, SD_HOMED_UPDATE_OFFLINE)), 1) < 0) {
+                        log_error_errno(errno, "Failed to set $SYSTEMD_HOMEWORK_UPDATE_OFFLINE: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
                 r = setenv_systemd_exec_pid(true);
                 if (r < 0)
                         log_warning_errno(r, "Failed to update $SYSTEMD_EXEC_PID, ignoring: %m");
@@ -1784,7 +1796,9 @@ int home_update(Home *h, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_
         case HOME_UNFIXATED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
         case HOME_ABSENT:
-                return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
+                if (!FLAGS_SET(flags, SD_HOMED_UPDATE_OFFLINE))
+                        return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
+                break; /* offline updates are compatible w/ an absent home area */
         case HOME_LOCKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
         case HOME_INACTIVE:
@@ -1811,7 +1825,6 @@ int home_update(Home *h, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_
 int home_resize(Home *h,
                 uint64_t disk_size,
                 UserRecord *secret,
-                bool automatic,
                 sd_bus_error *error) {
 
         _cleanup_(user_record_unrefp) UserRecord *c = NULL;
@@ -1887,7 +1900,7 @@ int home_resize(Home *h,
                 c = TAKE_PTR(signed_c);
         }
 
-        r = home_update_internal(h, automatic ? "resize-auto" : "resize", c, secret, NULL, 0, error);
+        r = home_update_internal(h, "resize", c, secret, NULL, 0, error);
         if (r < 0)
                 return r;
 
@@ -2707,9 +2720,6 @@ static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *u
         if (h->ref_event_source_dont_suspend == s)
                 h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);
 
-        if (h->inhibit_suspend_event_source == s)
-                h->inhibit_suspend_event_source = sd_event_source_disable_unref(h->inhibit_suspend_event_source);
-
         if (home_is_referenced(h))
                 return 0;
 
@@ -2725,42 +2735,25 @@ static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *u
         return 0;
 }
 
-int home_create_fifo(Home *h, HomeFifoType type) {
-        static const struct {
-                const char *suffix;
-                const char *description;
-                size_t event_source;
-        } table[_HOME_FIFO_TYPE_MAX] = {
-                [HOME_FIFO_PLEASE_SUSPEND] = {
-                        .suffix = ".please-suspend",
-                        .description = "acquire-ref",
-                        .event_source = offsetof(Home, ref_event_source_please_suspend),
-                },
-                [HOME_FIFO_DONT_SUSPEND] = {
-                        .suffix = ".dont-suspend",
-                        .description = "acquire-ref-dont-suspend",
-                        .event_source = offsetof(Home, ref_event_source_dont_suspend),
-                },
-                [HOME_FIFO_INHIBIT_SUSPEND] = {
-                        .suffix = ".inhibit-suspend",
-                        .description = "inhibit-suspend",
-                        .event_source = offsetof(Home, inhibit_suspend_event_source),
-                },
-        };
-
+int home_create_fifo(Home *h, bool please_suspend) {
         _cleanup_close_ int ret_fd = -EBADF;
-        sd_event_source **evt;
-        const char *fn;
+        sd_event_source **ss;
+        const char *fn, *suffix;
         int r;
 
         assert(h);
-        assert(type >= 0 && type < _HOME_FIFO_TYPE_MAX);
 
-        evt = (sd_event_source**) ((uint8_t*) h + table[type].event_source);
+        if (please_suspend) {
+                suffix = ".please-suspend";
+                ss = &h->ref_event_source_please_suspend;
+        } else {
+                suffix = ".dont-suspend";
+                ss = &h->ref_event_source_dont_suspend;
+        }
 
-        fn = strjoina("/run/systemd/home/", h->user_name, table[type].suffix);
+        fn = strjoina("/run/systemd/home/", h->user_name, suffix);
 
-        if (!*evt) {
+        if (!*ss) {
                 _cleanup_close_ int ref_fd = -EBADF;
 
                 (void) mkdir("/run/systemd/home/", 0755);
@@ -2771,19 +2764,22 @@ int home_create_fifo(Home *h, HomeFifoType type) {
                 if (ref_fd < 0)
                         return log_error_errno(errno, "Failed to open FIFO %s for reading: %m", fn);
 
-                r = sd_event_add_io(h->manager->event, evt, ref_fd, 0, on_home_ref_eof, h);
+                r = sd_event_add_io(h->manager->event, ss, ref_fd, 0, on_home_ref_eof, h);
                 if (r < 0)
                         return log_error_errno(r, "Failed to allocate reference FIFO event source: %m");
 
-                (void) sd_event_source_set_description(*evt, table[type].description);
+                (void) sd_event_source_set_description(*ss, "acquire-ref");
 
-                r = sd_event_source_set_priority(*evt, SD_EVENT_PRIORITY_IDLE-1);
+                /* We need to notice dropped refs before we process new bus requests (which
+                 * might try to obtain new refs) */
+                r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_NORMAL-10);
                 if (r < 0)
                         return r;
 
-                r = sd_event_source_set_io_fd_own(*evt, true);
+                r = sd_event_source_set_io_fd_own(*ss, true);
                 if (r < 0)
                         return log_error_errno(r, "Failed to pass ownership of FIFO event fd to event source: %m");
+
                 TAKE_FD(ref_fd);
         }
 
@@ -2863,10 +2859,8 @@ bool home_is_referenced(Home *h) {
 bool home_shall_suspend(Home *h) {
         assert(h);
 
-        /* We lock the home area on suspend if... */
-        return h->ref_event_source_please_suspend && /* at least one client supports suspend, and... */
-               !h->ref_event_source_dont_suspend && /* no clients lack support for suspend, and... */
-               !h->inhibit_suspend_event_source; /* no client is temporarily inhibiting suspend */
+        /* Suspend if there's at least one client referencing this home directory that wants a suspend and none who does not. */
+        return h->ref_event_source_please_suspend && !h->ref_event_source_dont_suspend;
 }
 
 static int home_dispatch_release(Home *h, Operation *o) {
@@ -3167,7 +3161,6 @@ int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error) {
 
 static int home_get_image_path_seat(Home *h, char **ret) {
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
-        _cleanup_free_ char *c = NULL;
         const char *ip, *seat;
         struct stat st;
         int r;
@@ -3200,12 +3193,7 @@ static int home_get_image_path_seat(Home *h, char **ret) {
         else if (r < 0)
                 return r;
 
-        c = strdup(seat);
-        if (!c)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(c);
-        return 0;
+        return strdup_to(ret, seat);
 }
 
 int home_auto_login(Home *h, char ***ret_seats) {
index 0f3d1ce3251b4fb49c4a730b52be616cc0f3d118..c0f1b83debad6ea0d5ca3d0758b29dccfec56fd4 100644 (file)
@@ -139,17 +139,12 @@ struct Home {
         bool unregister_on_failure;
 
         /* The reading side of a FIFO stored in /run/systemd/home/, the writing side being used for reference
-         * counting. The references dropped to zero as soon as we see EOF. This concept exists thrice: once
-         * for clients that are fine if we lock the home directory on system suspend, once for clients
-         * that are not ok with that, and once for clients that are usually ok with it but temporarily
-         * want to opt-out so that they can implement more advanced behavior on their own. This allows
-         * us to determine for each home whether there are any clients that don't support suspend at this
-         * moment. */
+         * counting. The references dropped to zero as soon as we see EOF. This concept exists twice: once
+         * for clients that are fine if we suspend the home directory on system suspend, and once for clients
+         * that are not ok with that. This allows us to determine for each home whether there are any clients
+         * that support unsuspend. */
         sd_event_source *ref_event_source_please_suspend;
         sd_event_source *ref_event_source_dont_suspend;
-        /* This is distinct from ref_event_source_dont_suspend because it can be obtained from unprivileged
-         * code, and thus we don't count it as a reference on the home area. */
-        sd_event_source *inhibit_suspend_event_source;
 
         /* Any pending operations we still need to execute. These are for operations we want to queue if we
          * can't execute them right-away. */
@@ -197,7 +192,7 @@ int home_deactivate(Home *h, bool force, sd_bus_error *error);
 int home_create(Home *h, UserRecord *secret, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
 int home_remove(Home *h, sd_bus_error *error);
 int home_update(Home *h, UserRecord *new_record, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
-int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, bool automatic, sd_bus_error *error);
+int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *error);
 int home_passwd(Home *h, UserRecord *new_secret, UserRecord *old_secret, sd_bus_error *error);
 int home_unregister(Home *h, sd_bus_error *error);
 int home_lock(Home *h, sd_bus_error *error);
@@ -215,15 +210,7 @@ int home_killall(Home *h);
 
 int home_augment_status(Home *h, UserRecordLoadFlags flags, UserRecord **ret);
 
-typedef enum {
-        HOME_FIFO_PLEASE_SUSPEND,
-        HOME_FIFO_DONT_SUSPEND,
-        HOME_FIFO_INHIBIT_SUSPEND,
-        _HOME_FIFO_TYPE_MAX,
-        _HOME_FIFO_TYPE_INVALID = -EINVAL,
-} HomeFifoType;
-int home_create_fifo(Home *h, HomeFifoType mode);
-
+int home_create_fifo(Home *h, bool please_suspend);
 int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error);
 
 int home_auto_login(Home *h, char ***ret_seats);
index 1e63012a06f4accc822ad6b4d9e6d8df221a46b9..58cd0371057575d6559f25c3884650a1fbd77d87 100644 (file)
@@ -6,6 +6,7 @@
 #include "bus-common-errors.h"
 #include "bus-polkit.h"
 #include "format-util.h"
+#include "home-util.h"
 #include "homed-bus.h"
 #include "homed-home-bus.h"
 #include "homed-manager-bus.h"
@@ -507,8 +508,8 @@ static int method_create_home(sd_bus_message *message, void *userdata, sd_bus_er
                 r = sd_bus_message_read(message, "t", &flags);
                 if (r < 0)
                         return r;
-                if (flags != 0)
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Provided flags are unsupported.");
+                if ((flags & ~SD_HOMED_CREATE_FLAGS_ALL) != 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags provided.");
         }
 
         r = bus_verify_polkit_async(
@@ -538,6 +539,8 @@ static int method_create_home(sd_bus_message *message, void *userdata, sd_bus_er
         if (r < 0)
                 return r;
 
+        h->current_operation->call_flags = flags;
+
         return 1;
 
 fail:
@@ -592,7 +595,7 @@ static int method_update_home(sd_bus_message *message, void *userdata, sd_bus_er
         if (!h)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_HOME, "No home for user %s known", hr->user_name);
 
-        return bus_home_method_update_record(h, message, hr, blobs, flags, error);
+        return bus_home_update_record(h, message, hr, blobs, flags, error);
 }
 
 static int method_resize_home(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -623,10 +626,6 @@ static int method_release_home(sd_bus_message *message, void *userdata, sd_bus_e
         return generic_home_method(userdata, message, bus_home_method_release, error);
 }
 
-static int method_inhibit_suspend_home(sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        return generic_home_method(userdata, message, bus_home_method_inhibit_suspend, error);
-}
-
 static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_(operation_unrefp) Operation *o = NULL;
         bool waiting = false;
@@ -901,12 +900,6 @@ static const sd_bus_vtable manager_vtable[] = {
                                 method_release_home,
                                 0),
 
-        SD_BUS_METHOD_WITH_ARGS("InhibitSuspendHome",
-                                SD_BUS_ARGS("s", user_name),
-                                SD_BUS_RESULT("h", send_fd),
-                                method_inhibit_suspend_home,
-                                SD_BUS_VTABLE_UNPRIVILEGED),
-
         /* An operation that acts on all homes that allow it */
         SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0),
         SD_BUS_METHOD("DeactivateAllHomes", NULL, NULL, method_deactivate_all_homes, 0),
index 0653eeef784cfda56668cf5ae6d09f2054e76d72..5f345b3d407664db18d440d0d7ee626a9fbb1fa4 100644 (file)
@@ -991,7 +991,7 @@ static int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
 
-        r = sd_bus_attach_event(m->bus, m->event, 0);
+        r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
         if (r < 0)
                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
 
@@ -2025,7 +2025,7 @@ static int manager_rebalance_apply(Manager *m) {
 
                 h->rebalance_pending = false;
 
-                r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, /* automatic= */ true, &error);
+                r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, &error);
                 if (r < 0)
                         log_warning_errno(r, "Failed to resize home '%s' for rebalancing, ignoring: %s",
                                           h->user_name, bus_error_message(&error, r));
index 004246a4e642a9711c5f13e1d40420409937d3ac..af165bb4a5213fe231a35341328e3b231d795baf 100644 (file)
@@ -39,6 +39,7 @@ typedef struct Operation {
         sd_bus_message *message;
 
         UserRecord *secret;
+        uint64_t call_flags; /* flags passed into UpdateEx() or CreateHomeEx() */
         int send_fd;   /* pipe fd for AcquireHome() which is taken already when we start the operation */
 
         int result;    /* < 0 if not completed yet, == 0 on failure, > 0 on success */
index 9d86881d1558f8fb2c0cf5df6b0eec264021d71a..d70926fe33deae3a1a52c172216b8fafd4d656d2 100644 (file)
@@ -126,7 +126,6 @@ static int probe_file_system_by_fd(
                 sd_id128_t *ret_uuid) {
 
         _cleanup_(blkid_free_probep) blkid_probe b = NULL;
-        _cleanup_free_ char *s = NULL;
         const char *fstype = NULL, *uuid = NULL;
         sd_id128_t id;
         int r;
@@ -168,13 +167,10 @@ static int probe_file_system_by_fd(
         if (r < 0)
                 return r;
 
-        s = strdup(fstype);
-        if (!s)
-                return -ENOMEM;
-
-        *ret_fstype = TAKE_PTR(s);
+        r = strdup_to(ret_fstype, fstype);
+        if (r < 0)
+                return r;
         *ret_uuid = id;
-
         return 0;
 }
 
@@ -260,43 +256,30 @@ static int run_fsck(const char *node, const char *fstype) {
 
 DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(key_serial_t, keyring_unlink, -1);
 
-static int upload_to_keyring(
-                UserRecord *h,
-                const char *password,
-                key_serial_t *ret_key_serial) {
+static int upload_to_keyring(UserRecord *h, const void *vk, size_t vks, key_serial_t *ret) {
 
         _cleanup_free_ char *name = NULL;
         key_serial_t serial;
 
         assert(h);
-        assert(password);
-
-        /* If auto-shrink-on-logout is turned on, we need to keep the key we used to unlock the LUKS volume
-         * around, since we'll need it when automatically resizing (since we can't ask the user there
-         * again). We do this by uploading it into the kernel keyring, specifically the "session" one. This
-         * is done under the assumption systemd-homed gets its private per-session keyring (i.e. default
-         * service behaviour, given that KeyringMode=private is the default). It will survive between our
-         * systemd-homework invocations that way.
-         *
-         * If auto-shrink-on-logout is disabled we'll skip this step, to be frugal with sensitive data. */
-
-        if (user_record_auto_resize_mode(h) != AUTO_RESIZE_SHRINK_AND_GROW) {  /* Won't need it */
-                if (ret_key_serial)
-                        *ret_key_serial = -1;
-                return 0;
-        }
+        assert(vk);
+        assert(vks > 0);
+
+        /* We upload the LUKS volume key into the kernel session keyring, under the assumption that
+         * systemd-homed gets its own private session keyring (i.e. the default service behavior, given
+         * that KeyringMode=private is the default). That way, the key will survive between invocations
+         * of systemd-homework. */
 
         name = strjoin("homework-user-", h->user_name);
         if (!name)
                 return -ENOMEM;
 
-        serial = add_key("user", name, password, strlen(password), KEY_SPEC_SESSION_KEYRING);
+        serial = add_key("user", name, vk, vks, KEY_SPEC_SESSION_KEYRING);
         if (serial == -1)
                 return -errno;
 
-        if (ret_key_serial)
-                *ret_key_serial = serial;
-
+        if (ret)
+                *ret = serial;
         return 1;
 }
 
@@ -305,13 +288,14 @@ static int luks_try_passwords(
                 struct crypt_device *cd,
                 char **passwords,
                 void *volume_key,
-                size_t *volume_key_size,
-                key_serial_t *ret_key_serial) {
+                size_t *volume_key_size) {
 
         int r;
 
         assert(h);
         assert(cd);
+        assert(volume_key);
+        assert(volume_key_size);
 
         STRV_FOREACH(pp, passwords) {
                 size_t vks = *volume_key_size;
@@ -324,16 +308,6 @@ static int luks_try_passwords(
                                 *pp,
                                 strlen(*pp));
                 if (r >= 0) {
-                        if (ret_key_serial) {
-                                /* If ret_key_serial is non-NULL, let's try to upload the password that
-                                 * worked, and return its serial. */
-                                r = upload_to_keyring(h, *pp, ret_key_serial);
-                                if (r < 0) {
-                                        log_debug_errno(r, "Failed to upload LUKS password to kernel keyring, ignoring: %m");
-                                        *ret_key_serial = -1;
-                                }
-                        }
-
                         *volume_key_size = vks;
                         return 0;
                 }
@@ -344,6 +318,66 @@ static int luks_try_passwords(
         return -ENOKEY;
 }
 
+static int luks_get_volume_key(
+                UserRecord *h,
+                struct crypt_device *cd,
+                const PasswordCache *cache,
+                void *volume_key,
+                size_t *volume_key_size,
+                key_serial_t *ret_key_serial) {
+
+        char **list;
+        size_t vks;
+        int r;
+
+        assert(h);
+        assert(cd);
+        assert(volume_key);
+        assert(volume_key_size);
+
+        if (cache && cache->volume_key) {
+                /* Shortcut: If volume key was loaded from the keyring then just use it */
+                if (cache->volume_key_size > *volume_key_size)
+                        return log_error_errno(SYNTHETIC_ERRNO(ENOBUFS),
+                                               "LUKS volume key from kernel keyring too big for buffer (need %zu bytes, have %zu)",
+                                               cache->volume_key_size, *volume_key_size);
+                memcpy(volume_key, cache->volume_key, cache->volume_key_size);
+                *volume_key_size = cache->volume_key_size;
+                if (ret_key_serial)
+                        *ret_key_serial = -1; /* Key came from keyring. No need to re-upload it */
+                return 0;
+        }
+
+        vks = *volume_key_size;
+
+        FOREACH_ARGUMENT(list,
+                         cache ? cache->pkcs11_passwords : NULL,
+                         cache ? cache->fido2_passwords : NULL,
+                         h->password) {
+
+                r = luks_try_passwords(h, cd, list, volume_key, &vks);
+                if (r == -ENOKEY)
+                        continue;
+                if (r < 0)
+                        return r;
+
+                /* We got a volume key! */
+
+                if (ret_key_serial) {
+                        r = upload_to_keyring(h, volume_key, vks, ret_key_serial);
+                        if (r < 0) {
+                                log_warning_errno(r, "Failed to upload LUKS volume key to kernel keyring, ignoring: %m");
+                                *ret_key_serial = -1;
+                        }
+                }
+
+                *volume_key_size = vks;
+                return 0;
+        }
+
+        return -ENOKEY;
+}
+
 static int luks_setup(
                 UserRecord *h,
                 const char *node,
@@ -352,7 +386,6 @@ static int luks_setup(
                 const char *cipher,
                 const char *cipher_mode,
                 uint64_t volume_key_size,
-                char **passwords,
                 const PasswordCache *cache,
                 bool discard,
                 struct crypt_device **ret,
@@ -418,18 +451,7 @@ static int luks_setup(
         if (!vk)
                 return log_oom();
 
-        r = -ENOKEY;
-        char **list;
-        FOREACH_ARGUMENT(list,
-                         cache ? cache->keyring_passswords : NULL,
-                         cache ? cache->pkcs11_passwords : NULL,
-                         cache ? cache->fido2_passwords : NULL,
-                         passwords) {
-
-                r = luks_try_passwords(h, cd, list, vk, &vks, ret_key_serial ? &key_serial : NULL);
-                if (r != -ENOKEY)
-                        break;
-        }
+        r = luks_get_volume_key(h, cd, cache, vk, &vks, ret_key_serial ? &key_serial : NULL);
         if (r == -ENOKEY)
                 return log_error_errno(r, "No valid password for LUKS superblock.");
         if (r < 0)
@@ -560,18 +582,7 @@ static int luks_open(
         if (!vk)
                 return log_oom();
 
-        r = -ENOKEY;
-        char **list;
-        FOREACH_ARGUMENT(list,
-                         cache ? cache->keyring_passswords : NULL,
-                         cache ? cache->pkcs11_passwords : NULL,
-                         cache ? cache->fido2_passwords : NULL,
-                         h->password) {
-
-                r = luks_try_passwords(h, setup->crypt_device, list, vk, &vks, NULL);
-                if (r != -ENOKEY)
-                        break;
-        }
+        r = luks_get_volume_key(h, setup->crypt_device, cache, vk, &vks, NULL);
         if (r == -ENOKEY)
                 return log_error_errno(r, "No valid password for LUKS superblock.");
         if (r < 0)
@@ -1405,7 +1416,6 @@ int home_setup_luks(
                                h->luks_cipher,
                                h->luks_cipher_mode,
                                h->luks_volume_key_size,
-                               h->password,
                                cache,
                                user_record_luks_discard(h) || user_record_luks_offline_discard(h),
                                &setup->crypt_device,
@@ -3623,18 +3633,7 @@ int home_passwd_luks(
         if (!volume_key)
                 return log_oom();
 
-        r = -ENOKEY;
-        char **list;
-        FOREACH_ARGUMENT(list,
-                         cache ? cache->keyring_passswords : NULL,
-                         cache ? cache->pkcs11_passwords : NULL,
-                         cache ? cache->fido2_passwords : NULL,
-                         h->password) {
-
-                r = luks_try_passwords(h, setup->crypt_device, list, volume_key, &volume_key_size, NULL);
-                if (r != -ENOKEY)
-                        break;
-        }
+        r = luks_get_volume_key(h, setup->crypt_device, cache, volume_key, &volume_key_size, NULL);
         if (r == -ENOKEY)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Failed to unlock LUKS superblock with supplied passwords.");
         if (r < 0)
@@ -3677,11 +3676,6 @@ int home_passwd_luks(
                         return log_error_errno(r, "Failed to set up LUKS password: %m");
 
                 log_info("Updated LUKS key slot %zu.", i);
-
-                /* If we changed the password, then make sure to update the copy in the keyring, so that
-                 * auto-rebalance continues to work. We only do this if we operate on an active home dir. */
-                if (i == 0 && FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED))
-                        upload_to_keyring(h, effective_passwords[i], NULL);
         }
 
         return 1;
@@ -3719,35 +3713,10 @@ int home_lock_luks(UserRecord *h, HomeSetup *setup) {
         return 0;
 }
 
-static int luks_try_resume(
-                struct crypt_device *cd,
-                const char *dm_name,
-                char **password) {
-
-        int r;
-
-        assert(cd);
-        assert(dm_name);
-
-        STRV_FOREACH(pp, password) {
-                r = sym_crypt_resume_by_passphrase(
-                                cd,
-                                dm_name,
-                                CRYPT_ANY_SLOT,
-                                *pp,
-                                strlen(*pp));
-                if (r >= 0) {
-                        log_info("Resumed LUKS device %s.", dm_name);
-                        return 0;
-                }
-
-                log_debug_errno(r, "Password %zu didn't work for resuming device: %m", (size_t) (pp - password));
-        }
-
-        return -ENOKEY;
-}
-
 int home_unlock_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache) {
+        _cleanup_(keyring_unlinkp) key_serial_t key_serial = -1;
+        _cleanup_(erase_and_freep) void *vk = NULL;
+        size_t vks;
         int r;
 
         assert(h);
@@ -3760,22 +3729,27 @@ int home_unlock_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache
 
         log_info("Discovered used LUKS device %s.", setup->dm_node);
 
-        r = -ENOKEY;
-        char **list;
-        FOREACH_ARGUMENT(list,
-                         cache ? cache->pkcs11_passwords : NULL,
-                         cache ? cache->fido2_passwords : NULL,
-                         h->password) {
+        r = sym_crypt_get_volume_key_size(setup->crypt_device);
+        if (r <= 0)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
+        vks = (size_t) r;
 
-                r = luks_try_resume(setup->crypt_device, setup->dm_name, list);
-                if (r != -ENOKEY)
-                        break;
-        }
+        vk = malloc(vks);
+        if (!vk)
+                return log_oom();
+
+        r = luks_get_volume_key(h, setup->crypt_device, cache, vk, &vks, &key_serial);
         if (r == -ENOKEY)
                 return log_error_errno(r, "No valid password for LUKS superblock.");
+        if (r < 0)
+                return log_error_errno(r, "Failed to unlock LUKS superblock: %m");
+
+        r = sym_crypt_resume_by_volume_key(setup->crypt_device, setup->dm_name, vk, vks);
         if (r < 0)
                 return log_error_errno(r, "Failed to resume LUKS superblock: %m");
 
+        TAKE_KEY_SERIAL(key_serial); /* Leave key in kernel keyring */
+
         log_info("LUKS device resumed.");
         return 0;
 }
index 00a0f69bc91fe37c065da932529623d34afaff23..b8202ef69543ae0dde1246479e737bc9af5fc9c3 100644 (file)
@@ -9,49 +9,41 @@ void password_cache_free(PasswordCache *cache) {
         if (!cache)
                 return;
 
+        cache->volume_key = erase_and_free(cache->volume_key);
         cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords);
         cache->fido2_passwords = strv_free_erase(cache->fido2_passwords);
-        cache->keyring_passswords = strv_free_erase(cache->keyring_passswords);
 }
 
 void password_cache_load_keyring(UserRecord *h, PasswordCache *cache) {
-        _cleanup_(erase_and_freep) void *p = NULL;
         _cleanup_free_ char *name = NULL;
-        char **strv;
+        _cleanup_(erase_and_freep) void *vk = NULL;
+        size_t vks;
         key_serial_t serial;
-        size_t sz;
         int r;
 
         assert(h);
         assert(cache);
 
-        /* Loads the password we need to for automatic resizing from the kernel keyring */
-
         name = strjoin("homework-user-", h->user_name);
         if (!name)
                 return (void) log_oom();
 
         serial = request_key("user", name, NULL, 0);
-        if (serial == -1)
-                return (void) log_debug_errno(errno, "Failed to request key '%s', ignoring: %m", name);
-
-        r = keyring_read(serial, &p, &sz);
+        if (serial == -1) {
+                if (errno == ENOKEY) {
+                        log_info("Home volume key is not available in kernel keyring.");
+                        return;
+                }
+                return (void) log_warning_errno(errno, "Failed to request key '%s', ignoring: %m", name);
+        }
+
+        r = keyring_read(serial, &vk, &vks);
         if (r < 0)
-                return (void) log_debug_errno(r, "Failed to read keyring key '%s', ignoring: %m", name);
-
-        if (memchr(p, 0, sz))
-                return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Cached password contains embedded NUL byte, ignoring.");
-
-        strv = new(char*, 2);
-        if (!strv)
-                return (void) log_oom();
-
-        strv[0] = TAKE_PTR(p); /* Note that keyring_read() will NUL terminate implicitly, hence we don't have
-                                * to NUL terminate manually here: it's a valid string. */
-        strv[1] = NULL;
+                return (void) log_warning_errno(r, "Failed to read keyring key '%s', ignoring: %m", name);
 
-        strv_free_erase(cache->keyring_passswords);
-        cache->keyring_passswords = strv;
+        log_info("Successfully acquired home volume key from kernel keyring.");
 
-        log_debug("Successfully acquired home key from kernel keyring.");
+        erase_and_free(cache->volume_key);
+        cache->volume_key = TAKE_PTR(vk);
+        cache->volume_key_size = vks;
 }
index fdfbcfe4e0ccae3c61d92bdf67c21255e7ec49d9..e2d86eb9393f03776e3ad8fc767b32ac3f0d6e77 100644 (file)
@@ -5,8 +5,9 @@
 #include "user-record.h"
 
 typedef struct PasswordCache {
-        /* Passwords acquired from the kernel keyring */
-        char **keyring_passswords;
+        /* The volume key from the kernel keyring */
+        void *volume_key;
+        size_t volume_key_size;
 
         /* Decoding passwords from security tokens is expensive and typically requires user interaction,
          * hence cache any we already figured out. */
@@ -20,9 +21,12 @@ static inline bool password_cache_contains(const PasswordCache *cache, const cha
         if (!cache)
                 return false;
 
+        /* Used to decide whether or not to set a minimal PBKDF, under the assumption that if
+         * the cache contains a password then the password came from a hardware token of some kind
+         * and is thus naturally high-entropy. */
+
         return strv_contains(cache->pkcs11_passwords, p) ||
-                strv_contains(cache->fido2_passwords, p) ||
-                strv_contains(cache->keyring_passswords, p);
+                strv_contains(cache->fido2_passwords, p);
 }
 
 void password_cache_load_keyring(UserRecord *h, PasswordCache *cache);
index 531443e7576fcf47dc2b591191d019fc28f2a76f..afc114229869a89fee06ae26ab1a1a709f9bf6a0 100644 (file)
@@ -66,9 +66,25 @@ int user_record_authenticate(
          * times over the course of an operation (think: on login we authenticate the host user record, the
          * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
          * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
-         * PKCS#11/FIDO2 dance for the relevant token again and again. */
+         * PKCS#11/FIDO2 dance for the relevant token again and again.
+         *
+         * The 'cache' parameter might also contain the LUKS volume key, loaded from the kernel keyring.
+         * In this case, authentication becomes optional - if a secret section is provided it will be
+         * verified, but if missing then authentication is skipped entirely. Thus, callers should
+         * consider carefuly whether it is safe to load the volume key into 'cache' before doing so.
+         * Note that most of the time this is safe, because the home area must be active for the key
+         * to exist in the keyring, and the user would have had to authenticate when activating their
+         * home area; however, for some methods (i.e. ChangePassword, Authenticate) it makes more sense
+         * to force re-authentication. */
+
+        /* First, let's see if we already have a volume key from the keyring */
+        if (cache && cache->volume_key &&
+            json_variant_is_blank_object(json_variant_by_key(secret->json, "secret"))) {
+                log_info("LUKS volume key from keyring unlocks user record.");
+                return 1;
+        }
 
-        /* First, let's see if the supplied plain-text passwords work? */
+        /* Next, let's see if the supplied plain-text passwords work? */
         r = user_record_test_password(h, secret);
         if (r == -ENOKEY)
                 need_password = true;
@@ -101,7 +117,7 @@ int user_record_authenticate(
         else
                 log_info("None of the supplied plaintext passwords unlock the user record's hashed recovery keys.");
 
-        /* Second, test cached PKCS#11 passwords */
+        /* Next, test cached PKCS#11 passwords */
         for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++)
                 STRV_FOREACH(pp, cache->pkcs11_passwords) {
                         r = test_password_one(h->pkcs11_encrypted_key[n].hashed_password, *pp);
@@ -113,7 +129,7 @@ int user_record_authenticate(
                         }
                 }
 
-        /* Third, test cached FIDO2 passwords */
+        /* Next, test cached FIDO2 passwords */
         for (size_t n = 0; n < h->n_fido2_hmac_salt; n++)
                 /* See if any of the previously calculated passwords work */
                 STRV_FOREACH(pp, cache->fido2_passwords) {
@@ -126,7 +142,7 @@ int user_record_authenticate(
                         }
                 }
 
-        /* Fourth, let's see if any of the PKCS#11 security tokens are plugged in and help us */
+        /* Next, let's see if any of the PKCS#11 security tokens are plugged in and help us */
         for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
 #if HAVE_P11KIT
                 _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
@@ -182,7 +198,7 @@ int user_record_authenticate(
 #endif
         }
 
-        /* Fifth, let's see if any of the FIDO2 security tokens are plugged in and help us */
+        /* Next, let's see if any of the FIDO2 security tokens are plugged in and help us */
         for (size_t n = 0; n < h->n_fido2_hmac_salt; n++) {
 #if HAVE_LIBFIDO2
                 _cleanup_(erase_and_freep) char *decrypted_password = NULL;
@@ -1535,20 +1551,32 @@ static int home_remove(UserRecord *h) {
         return 0;
 }
 
-static int home_validate_update(UserRecord *h, HomeSetup *setup, HomeSetupFlags *flags) {
-        bool has_mount = false;
-        int r;
-
+static int home_basic_validate_update(UserRecord *h) {
         assert(h);
-        assert(setup);
 
         if (!h->user_name)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
+
         if (!uid_is_valid(h->uid))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
+
         if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
                 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
 
+        return 0;
+}
+
+static int home_validate_update(UserRecord *h, HomeSetup *setup, HomeSetupFlags *flags) {
+        bool has_mount = false;
+        int r;
+
+        assert(h);
+        assert(setup);
+
+        r = home_basic_validate_update(h);
+        if (r < 0)
+                return r;
+
         r = user_record_test_home_directory_and_warn(h);
         if (r < 0)
                 return r;
@@ -1594,17 +1622,31 @@ static int home_update(UserRecord *h, Hashmap *blobs, UserRecord **ret) {
         _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
         HomeSetupFlags flags = 0;
+        bool offline;
         int r;
 
         assert(h);
         assert(ret);
 
-        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
-        if (r < 0)
-                return r;
-        assert(r > 0); /* Insist that a password was verified */
+        offline = getenv_bool("SYSTEMD_HOMEWORK_UPDATE_OFFLINE") > 0;
 
-        r = home_validate_update(h, &setup, &flags);
+        if (!offline) {
+                password_cache_load_keyring(h, &cache);
+
+                r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
+                if (r < 0)
+                        return r;
+                assert(r > 0); /* Insist that a password was verified */
+
+                r = home_validate_update(h, &setup, &flags);
+        } else {
+                /* In offline mode we skip all authentication, since we're
+                 * not propagating anything into the home area. The new home
+                 * records's authentication will still be checked when the user
+                 * next logs in, so this is fine */
+
+                r = home_basic_validate_update(h);
+        }
         if (r < 0)
                 return r;
 
@@ -1612,6 +1654,11 @@ static int home_update(UserRecord *h, Hashmap *blobs, UserRecord **ret) {
         if (r < 0)
                 return r;
 
+        if (offline) {
+                log_info("Offline update requested. Not touching embedded records.");
+                return user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, ret);
+        }
+
         r = home_setup(h, flags, &setup, &cache, &header_home);
         if (r < 0)
                 return r;
@@ -1654,7 +1701,7 @@ static int home_update(UserRecord *h, Hashmap *blobs, UserRecord **ret) {
         return 0;
 }
 
-static int home_resize(UserRecord *h, bool automatic, UserRecord **ret) {
+static int home_resize(UserRecord *h, UserRecord **ret) {
         _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
         HomeSetupFlags flags = 0;
@@ -1666,25 +1713,16 @@ static int home_resize(UserRecord *h, bool automatic, UserRecord **ret) {
         if (h->disk_size == UINT64_MAX)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");
 
-        if (automatic)
-                /* In automatic mode don't want to ask the user for the password, hence load it from the kernel keyring */
-                password_cache_load_keyring(h, &cache);
-        else {
-                /* In manual mode let's ensure the user is fully authenticated */
-                r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
-                if (r < 0)
-                        return r;
-                assert(r > 0); /* Insist that a password was verified */
-        }
+        password_cache_load_keyring(h, &cache);
 
-        r = home_validate_update(h, &setup, &flags);
+        r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
         if (r < 0)
                 return r;
+        assert(r > 0); /* Insist that a password was verified */
 
-        /* In automatic mode let's skip syncing identities, because we can't validate them, since we can't
-         * ask the user for reauthentication */
-        if (automatic)
-                flags |= HOME_SETUP_RESIZE_DONT_SYNC_IDENTITIES;
+        r = home_validate_update(h, &setup, &flags);
+        if (r < 0)
+                return r;
 
         switch (user_record_storage(h)) {
 
@@ -1883,6 +1921,9 @@ static int home_lock(UserRecord *h) {
 
         unit_freezer_done(&freezer); /* Don't thaw the user session. */
 
+        /* Explicitly flush any per-user key from the keyring */
+        (void) keyring_flush(h);
+
         log_info("Everything completed.");
         return 1;
 }
@@ -2050,10 +2091,8 @@ static int run(int argc, char *argv[]) {
                 r = home_remove(home);
         else if (streq(argv[1], "update"))
                 r = home_update(home, blobs, &new_home);
-        else if (streq(argv[1], "resize")) /* Resize on user request */
-                r = home_resize(home, false, &new_home);
-        else if (streq(argv[1], "resize-auto")) /* Automatic resize */
-                r = home_resize(home, true, &new_home);
+        else if (streq(argv[1], "resize"))
+                r = home_resize(home, &new_home);
         else if (streq(argv[1], "passwd"))
                 r = home_passwd(home, &new_home);
         else if (streq(argv[1], "inspect"))
index 9ac34aea55f67227af4fd5b2008feedf1b1667dc..b8085929b0108a32b989387aed07f24f355556b7 100644 (file)
                        send_interface="org.freedesktop.home1.Manager"
                        send_member="ReleaseHome"/>
 
-                <allow send_destination="org.freedesktop.home1"
-                       send_interface="org.freedesktop.home1.Manager"
-                       send_member="InhibitSuspendHome"/>
-
                 <allow send_destination="org.freedesktop.home1"
                        send_interface="org.freedesktop.home1.Manager"
                        send_member="LockAllHomes"/>
                        send_interface="org.freedesktop.home1.Home"
                        send_member="Release"/>
 
-                <allow send_destination="org.freedesktop.home1"
-                       send_interface="org.freedesktop.home1.Home"
-                       send_member="InhibitSuspend"/>
-
                 <allow receive_sender="org.freedesktop.home1"/>
         </policy>
 
index be32b2e8e4e198dd7256f110d0c7a4b420f9bf73..3b19ed3ed5fc0a99e55964ff09b8111280c8aead 100644 (file)
                 </defaults>
         </action>
 
-        <action id="org.freedesktop.home1.inhibit-suspend">
-                <description gettext-domain="systemd">Inhibit automatic lock of a home area</description>
-                <message gettext-domain="systemd">Authentication is required to inhibit automatic lock of a user's home area.</message>
-                <defaults>
-                        <allow_any>auth_admin_keep</allow_any>
-                        <allow_inactive>auth_admin_keep</allow_inactive>
-                        <allow_active>auth_admin_keep</allow_active>
-                </defaults>
-        </action>
-
         <action id="org.freedesktop.home1.activate-home">
                 <description gettext-domain="systemd">Activate a home area</description>
                 <message gettext-domain="systemd">Authentication is required to activate a user's home area.</message>
index 83a988154feaea05dbceaba327bd3598a723f2b3..82d08803fa5b6b5123c0c425c9385a5709367d93 100644 (file)
@@ -211,7 +211,6 @@ static bool use_dmi_data(void) {
 
 static int get_dmi_data(const char *database_key, const char *regular_key, char **ret) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
-        _cleanup_free_ char *b = NULL;
         const char *s = NULL;
         int r;
 
@@ -227,17 +226,7 @@ static int get_dmi_data(const char *database_key, const char *regular_key, char
         if (!s && regular_key)
                 (void) sd_device_get_property_value(device, regular_key, &s);
 
-        if (!ret)
-                return !!s;
-
-        if (s) {
-                b = strdup(s);
-                if (!b)
-                        return -ENOMEM;
-        }
-
-        *ret = TAKE_PTR(b);
-        return !!s;
+        return strdup_to_full(ret, s);
 }
 
 static int get_hardware_vendor(char **ret) {
@@ -264,23 +253,7 @@ static int get_hardware_firmware_data(const char *sysattr, char **ret) {
 
         (void) sd_device_get_sysattr_value(device, sysattr, &s);
 
-        bool empty = isempty(s);
-
-        if (ret) {
-                if (empty)
-                        *ret = NULL;
-                else {
-                        _cleanup_free_ char *b = NULL;
-
-                        b = strdup(s);
-                        if (!b)
-                                return -ENOMEM;
-
-                        *ret = TAKE_PTR(b);
-                }
-        }
-
-        return !empty;
+        return strdup_to_full(ret, empty_to_null(s));
 }
 
 static int get_hardware_serial(char **ret) {
index 6f83585db5ffb4e2225f18ad29bb11cfe0095fce..15f3f0e025dad71eb6c4c550f7c58982f3c076e8 100644 (file)
@@ -2070,6 +2070,7 @@ static int update_cursor(sd_journal *j) {
 
 typedef struct Context {
         sd_journal *journal;
+        bool has_cursor;
         bool need_seek;
         bool since_seeked;
         bool ellipsized;
@@ -2099,11 +2100,11 @@ static int show(Context *c) {
                                 break;
                 }
 
-                if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) {
-                        /* If --lines= is set, we usually rely on the n_shown to tell us
-                         * when to stop. However, if --since= is set too, we may end up
-                         * having less than --lines= to output. In this case let's also
-                         * check if the entry is in range. */
+                if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set || c->has_cursor)) {
+                        /* If --lines= is set, we usually rely on the n_shown to tell us when to stop.
+                         * However, if --since= or one of the cursor argument is set too, we may end up
+                         * having less than --lines= to output. In this case let's also check if the entry
+                         * is in range. */
 
                         usec_t usec;
 
@@ -2712,6 +2713,7 @@ static int run(int argc, char *argv[]) {
 
         Context c = {
                 .journal = j,
+                .has_cursor = cursor,
                 .need_seek = need_seek,
                 .since_seeked = since_seeked,
         };
index c66c09719cac10857afb9632afa0d24c6fa4b34d..d443c4b40113acfd5756c061c38f8d1db6160e40 100755 (executable)
@@ -26,8 +26,6 @@ KERNEL_VERSION="${2:?}"
 ENTRY_DIR_ABS="$3"
 KERNEL_IMAGE="$4"
 
-[ "$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
-
 ENTRY_TOKEN="$KERNEL_INSTALL_ENTRY_TOKEN"
 BOOT_ROOT="$KERNEL_INSTALL_BOOT_ROOT"
 
@@ -48,6 +46,8 @@ case "$COMMAND" in
         ;;
 esac
 
+[ "$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
+
 if ! [ -d "$UKI_DIR" ]; then
     [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "creating $UKI_DIR"
     mkdir -p "$UKI_DIR"
index cf1bb5c3af16521b7044c1dcd898a36dcbfd1f14..6581e80656aa7a35c21032b375a420c4159564e4 100644 (file)
@@ -151,37 +151,37 @@ static int context_copy(const Context *source, Context *ret) {
                         return copy.rfd;
         }
 
-        r = strdup_or_null(source->layout_other, &copy.layout_other);
+        r = strdup_to(&copy.layout_other, source->layout_other);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->conf_root, &copy.conf_root);
+        r = strdup_to(&copy.conf_root, source->conf_root);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->boot_root, &copy.boot_root);
+        r = strdup_to(&copy.boot_root, source->boot_root);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->entry_token, &copy.entry_token);
+        r = strdup_to(&copy.entry_token, source->entry_token);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->entry_dir, &copy.entry_dir);
+        r = strdup_to(&copy.entry_dir, source->entry_dir);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->version, &copy.version);
+        r = strdup_to(&copy.version, source->version);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->kernel, &copy.kernel);
+        r = strdup_to(&copy.kernel, source->kernel);
         if (r < 0)
                 return r;
         r = strv_copy_unless_empty(source->initrds, &copy.initrds);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->initrd_generator, &copy.initrd_generator);
+        r = strdup_to(&copy.initrd_generator, source->initrd_generator);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->uki_generator, &copy.uki_generator);
+        r = strdup_to(&copy.uki_generator, source->uki_generator);
         if (r < 0)
                 return r;
-        r = strdup_or_null(source->staging_area, &copy.staging_area);
+        r = strdup_to(&copy.staging_area, source->staging_area);
         if (r < 0)
                 return r;
         r = strv_copy_unless_empty(source->plugins, &copy.plugins);
index 8318373fb24c53e121272c4b2b7c2bad5bb3659e..123629c35608c1174fee1c88e96f0f9767b0ec4d 100644 (file)
@@ -9,7 +9,6 @@
 
 int devname_from_devnum(mode_t mode, dev_t devnum, char **ret) {
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
-        _cleanup_free_ char *s = NULL;
         const char *devname;
         int r;
 
@@ -26,15 +25,10 @@ int devname_from_devnum(mode_t mode, dev_t devnum, char **ret) {
         if (r < 0)
                 return r;
 
-        s = strdup(devname);
-        if (!s)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(s);
-        return 0;
+        return strdup_to(ret, devname);
 }
 
-int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret) {
+int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret_devname) {
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
         _cleanup_close_ int fd = -EBADF;
         int r;
@@ -47,19 +41,16 @@ int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret) {
         if (fd < 0)
                 return fd;
 
-        if (ret) {
+        if (ret_devname) {
                 const char *devname;
-                char *s;
 
                 r = sd_device_get_devname(dev, &devname);
                 if (r < 0)
                         return r;
 
-                s = strdup(devname);
-                if (!s)
-                        return -ENOMEM;
-
-                *ret = s;
+                r = strdup_to(ret_devname, devname);
+                if (r < 0)
+                        return r;
         }
 
         return TAKE_FD(fd);
index 534a296715b360c97a75eceb104adf277cac0869..b17993d55404e628169bcc3da72975169dff4e3a 100644 (file)
@@ -100,7 +100,7 @@ static inline int devname_from_stat_rdev(const struct stat *st, char **ret) {
         assert(st);
         return devname_from_devnum(st->st_mode, st->st_rdev, ret);
 }
-int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret);
+int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret_devname);
 
 char** device_make_log_fields(sd_device *device);
 
index 826d67371aac27d569e55ce3231b020c75642a12..a0b673f65fc9721e727e5919884f4f32fbd2d36b 100644 (file)
@@ -223,10 +223,7 @@ static int catalog_entry_lang(
                 const char* deflang,
                 char **ret) {
 
-        size_t c;
-        char *z;
-
-        c = strlen(t);
+        size_t c = strlen(t);
         if (c < 2)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "[%s:%u] Language too short.", filename, line);
@@ -243,12 +240,7 @@ static int catalog_entry_lang(
                 log_warning("[%s:%u] language differs from default for file", filename, line);
         }
 
-        z = strdup(t);
-        if (!z)
-                return -ENOMEM;
-
-        *ret = z;
-        return 0;
+        return strdup_to(ret, t);
 }
 
 int catalog_import_file(OrderedHashmap *h, const char *path) {
@@ -588,15 +580,14 @@ static const char *find_id(void *p, sd_id128_t id) {
                 le64toh(f->offset);
 }
 
-int catalog_get(const char* database, sd_id128_t id, char **_text) {
+int catalog_get(const char* database, sd_id128_t id, char **ret_text) {
         _cleanup_close_ int fd = -EBADF;
         void *p = NULL;
-        struct stat st = {};
-        char *text = NULL;
+        struct stat st;
         int r;
         const char *s;
 
-        assert(_text);
+        assert(ret_text);
 
         r = open_mmap(database, &fd, &st, &p);
         if (r < 0)
@@ -608,15 +599,7 @@ int catalog_get(const char* database, sd_id128_t id, char **_text) {
                 goto finish;
         }
 
-        text = strdup(s);
-        if (!text) {
-                r = -ENOMEM;
-                goto finish;
-        }
-
-        *_text = text;
-        r = 0;
-
+        r = strdup_to(ret_text, s);
 finish:
         (void) munmap(p, st.st_size);
 
index df27869fb3281031a560253339b38cdc141a785c..b5a97fa6fbbd9455ad727fada3222b1fc3d65342 100644 (file)
@@ -11,7 +11,7 @@
 
 int catalog_import_file(OrderedHashmap *h, const char *path);
 int catalog_update(const char* database, const char* root, const char* const* dirs);
-int catalog_get(const char* database, sd_id128_t id, char **data);
+int catalog_get(const char* database, sd_id128_t id, char **ret_text);
 int catalog_list(FILE *f, const char* database, bool oneline);
 int catalog_list_items(FILE *f, const char* database, bool oneline, char **items);
 int catalog_file_lang(const char *filename, char **lang);
index 5758a2624c791107620cac0a8cfe01e815f98ad0..c0d104578d468f7ab1cc43f6146127e361019a58 100644 (file)
@@ -158,11 +158,7 @@ static int process_locale_list_item(
                 if (new_locale[p])
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name);
 
-                new_locale[p] = strdup(e);
-                if (!new_locale[p])
-                        return -ENOMEM;
-
-                return 0;
+                return strdup_to(&new_locale[p], e);
         }
 
         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment);
index 63253bd9dcf3c04b7e07e60f6dc2a671ccacacd8..8236dc2dc839fa848a314f35361aa76456538b8b 100644 (file)
@@ -1028,7 +1028,6 @@ static int get_bus_path_by_id(
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        _cleanup_free_ char *p = NULL;
         const char *path;
         int r;
 
@@ -1047,12 +1046,7 @@ static int get_bus_path_by_id(
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        p = strdup(path);
-        if (!p)
-                return log_oom();
-
-        *ret = TAKE_PTR(p);
-        return 0;
+        return strdup_to(ret, path);
 }
 
 static int show_session(int argc, char *argv[], void *userdata) {
index 27d4f72b4c009494cb594b788bf5f9edd23a2723..5d27491af3a5fbec9dd0265e93912a8f1427a829 100644 (file)
@@ -989,53 +989,41 @@ static int create_session(
                 user->gc_mode = USER_GC_BY_PIN;
 
         if (!isempty(tty)) {
-                session->tty = strdup(tty);
-                if (!session->tty) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->tty, tty);
+                if (r < 0)
                         goto fail;
-                }
 
                 session->tty_validity = TTY_FROM_PAM;
         }
 
         if (!isempty(display)) {
-                session->display = strdup(display);
-                if (!session->display) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->display, display);
+                if (r < 0)
                         goto fail;
-                }
         }
 
         if (!isempty(remote_user)) {
-                session->remote_user = strdup(remote_user);
-                if (!session->remote_user) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->remote_user, remote_user);
+                if (r < 0)
                         goto fail;
-                }
         }
 
         if (!isempty(remote_host)) {
-                session->remote_host = strdup(remote_host);
-                if (!session->remote_host) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->remote_host, remote_host);
+                if (r < 0)
                         goto fail;
-                }
         }
 
         if (!isempty(service)) {
-                session->service = strdup(service);
-                if (!session->service) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->service, service);
+                if (r < 0)
                         goto fail;
-                }
         }
 
         if (!isempty(desktop)) {
-                session->desktop = strdup(desktop);
-                if (!session->desktop) {
-                        r = -ENOMEM;
+                r = strdup_to(&session->desktop, desktop);
+                if (r < 0)
                         goto fail;
-                }
         }
 
         if (seat) {
@@ -4242,6 +4230,7 @@ int manager_start_scope(
                 Manager *manager,
                 const char *scope,
                 const PidRef *pidref,
+                bool allow_pidfd,
                 const char *slice,
                 const char *description,
                 const char * const *requires,
@@ -4311,7 +4300,7 @@ int manager_start_scope(
         if (r < 0)
                 return r;
 
-        r = bus_append_scope_pidref(m, pidref);
+        r = bus_append_scope_pidref(m, pidref, allow_pidfd);
         if (r < 0)
                 return r;
 
@@ -4342,8 +4331,27 @@ int manager_start_scope(
                 return r;
 
         r = sd_bus_call(manager->bus, m, 0, error, &reply);
-        if (r < 0)
+        if (r < 0) {
+                /* If this failed with a property we couldn't write, this is quite likely because the server
+                 * doesn't support PIDFDs yet, let's try without. */
+                if (allow_pidfd &&
+                    sd_bus_error_has_names(error, SD_BUS_ERROR_UNKNOWN_PROPERTY, SD_BUS_ERROR_PROPERTY_READ_ONLY))
+                        return manager_start_scope(
+                                        manager,
+                                        scope,
+                                        pidref,
+                                        /* allow_pidfd = */ false,
+                                        slice,
+                                        description,
+                                        requires,
+                                        extra_after,
+                                        requires_mounts_for,
+                                        more_properties,
+                                        error,
+                                        ret_job);
+
                 return r;
+        }
 
         return strdup_job(reply, ret_job);
 }
index 5c864a9bc056a867b4e4a159208b724ebbec8828..8459d048b8ed882bb7165089fe29116b850021f9 100644 (file)
@@ -28,6 +28,7 @@ int manager_start_scope(
                 Manager *manager,
                 const char *scope,
                 const PidRef *pidref,
+                bool allow_pidfd,
                 const char *slice,
                 const char *description,
                 const char * const *requires,
index cd5c0ec82dbb7a512e7d4adee67e80adf93dbbb3..c924f1e0cad21303cf04ebabe7a12ac4f896bfe6 100644 (file)
@@ -314,11 +314,7 @@ static int session_device_verify(SessionDevice *sd) {
         if (sd->device->seat != sd->session->seat)
                 return -EPERM;
 
-        sd->node = strdup(node);
-        if (!sd->node)
-                return -ENOMEM;
-
-        return 0;
+        return strdup_to(&sd->node, node);
 }
 
 int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **ret) {
index 2713215e10a47aa9b8ced28d22807cc50eb01ca8..4713aa05b55c8a6adf28bd6157a1824e1d2c04ec 100644 (file)
@@ -742,6 +742,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
                         s->manager,
                         scope,
                         &s->leader,
+                        /* allow_pidfd = */ true,
                         s->user->slice,
                         description,
                         /* These should have been pulled in explicitly in user_start(). Just to be sure. */
index af8a88f26caea134fd3a8f922092deeda7e7fb71..309bffa3c8075bbe0b0ccd5aa2008cf7cd7dedf5 100644 (file)
@@ -385,7 +385,7 @@ static int machine_start_scope(
         if (r < 0)
                 return r;
 
-        r = bus_append_scope_pidref(m, &machine->leader);
+        r = bus_append_scope_pidref(m, &machine->leader, /* allow_pidfd = */ true);
         if (r < 0)
                 return r;
 
index bab3719a495b8bc97b94137fe512a237982ce3a6..42b7fef720466e5ca0e4149f9973c6e60193e72a 100644 (file)
@@ -121,19 +121,14 @@ static OutputFlags get_output_flags(void) {
 static int call_get_os_release(sd_bus *bus, const char *method, const char *name, const char *query, ...) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        const char *k, *v, **query_res = NULL;
-        size_t count = 0, awaited_args = 0;
         va_list ap;
         int r;
 
         assert(bus);
+        assert(method);
         assert(name);
         assert(query);
 
-        NULSTR_FOREACH(iter, query)
-                awaited_args++;
-        query_res = newa0(const char *, awaited_args);
-
         r = bus_call_method(bus, bus_machine_mgr, method, &error, &reply, "s", name);
         if (r < 0)
                 return log_debug_errno(r, "Failed to call '%s()': %s", method, bus_error_message(&error, r));
@@ -142,14 +137,23 @@ static int call_get_os_release(sd_bus *bus, const char *method, const char *name
         if (r < 0)
                 return bus_log_parse_error(r);
 
+        const char **res;
+        size_t n_fields = 0;
+
+        NULSTR_FOREACH(i, query)
+                n_fields++;
+
+        res = newa0(const char*, n_fields);
+
+        const char *k, *v;
         while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
-                count = 0;
-                NULSTR_FOREACH(iter, query) {
-                        if (streq(k, iter)) {
-                                query_res[count] = v;
+                size_t c = 0;
+                NULSTR_FOREACH(i, query) {
+                        if (streq(i, k)) {
+                                res[c] = v;
                                 break;
                         }
-                        count++;
+                        c++;
                 }
         }
         if (r < 0)
@@ -159,24 +163,17 @@ static int call_get_os_release(sd_bus *bus, const char *method, const char *name
         if (r < 0)
                 return bus_log_parse_error(r);
 
+        r = 0;
+
         va_start(ap, query);
-        for (count = 0; count < awaited_args; count++) {
-                char *val, **out;
-
-                out = va_arg(ap, char **);
-                assert(out);
-                if (query_res[count]) {
-                        val = strdup(query_res[count]);
-                        if (!val) {
-                                va_end(ap);
-                                return -ENOMEM;
-                        }
-                        *out = val;
-                }
+        FOREACH_ARRAY(i, res, n_fields) {
+                r = strdup_to(va_arg(ap, char**), *i);
+                if (r < 0)
+                        break;
         }
         va_end(ap);
 
-        return 0;
+        return r;
 }
 
 static int call_get_addresses(
@@ -205,12 +202,12 @@ static int call_get_addresses(
         addresses = strdup(prefix);
         if (!addresses)
                 return log_oom();
-        prefix = "";
 
         r = sd_bus_message_enter_container(reply, 'a', "(iay)");
         if (r < 0)
                 return bus_log_parse_error(r);
 
+        prefix = "";
         while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
                 int family;
                 const void *a;
index 7ee0961fa6a00dae1694aa6ccfc2763c27d2751e..117789c6e6eb62543978a936045abcd076105847 100644 (file)
@@ -93,7 +93,7 @@ JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
 STATIC_DESTRUCTOR_REGISTER(arg_drop_in, freep);
 
 static int varlink_connect_networkd(Varlink **ret_varlink) {
-        _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+        _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
         JsonVariant *reply;
         uint64_t id;
         int r;
@@ -102,6 +102,12 @@ static int varlink_connect_networkd(Varlink **ret_varlink) {
         if (r < 0)
                 return log_error_errno(r, "Failed to connect to network service /run/systemd/netif/io.systemd.Network: %m");
 
+        (void) varlink_set_description(vl, "varlink-network");
+
+        r = varlink_set_allow_fd_passing_output(vl, true);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allow passing file descriptor through varlink: %m");
+
         r = varlink_call_and_log(vl, "io.systemd.Network.GetNamespaceId", /* parameters= */ NULL, &reply);
         if (r < 0)
                 return r;
@@ -2427,7 +2433,7 @@ static int link_status(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
-        _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+        _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
         _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
         int r, c;
 
@@ -2589,7 +2595,7 @@ static int dump_lldp_neighbors_json(JsonVariant *reply, char * const *patterns)
 }
 
 static int link_lldp_status(int argc, char *argv[], void *userdata) {
-        _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+        _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
         _cleanup_(table_unrefp) Table *table = NULL;
         JsonVariant *reply;
         uint64_t all = 0;
@@ -2930,7 +2936,7 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) {
 }
 
 static int verb_persistent_storage(int argc, char *argv[], void *userdata) {
-        _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+        _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL;
         bool ready;
         int r;
 
@@ -2943,6 +2949,20 @@ static int verb_persistent_storage(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
+        if (ready) {
+                _cleanup_close_ int fd = -EBADF;
+
+                fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY);
+                if (fd < 0)
+                        return log_error_errno(errno, "Failed to open /var/lib/systemd/network/: %m");
+
+                r = varlink_push_fd(vl, fd);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to push file descriptor of /var/lib/systemd/network/ into varlink: %m");
+
+                TAKE_FD(fd);
+        }
+
         return varlink_callb_and_log(vl, "io.systemd.Network.SetPersistentStorage", /* reply = */ NULL,
                                      JSON_BUILD_OBJECT(JSON_BUILD_PAIR_BOOLEAN("Ready", ready)));
 }
index 70fe1e50387d94cafee8b3836e19900ba5dbcc50..542298c8c3019a7460f45faca518fe8a95f25c05 100644 (file)
@@ -613,12 +613,12 @@ int address_dup(const Address *src, Address **ret) {
         dest->nft_set_context.n_sets = 0;
 
         if (src->family == AF_INET) {
-                r = strdup_or_null(src->label, &dest->label);
+                r = strdup_to(&dest->label, src->label);
                 if (r < 0)
                         return r;
         }
 
-        r = strdup_or_null(src->netlabel, &dest->netlabel);
+        r = strdup_to(&dest->netlabel, src->netlabel);
         if (r < 0)
                 return r;
 
index b1b60ac48fb77f695469d48b1e1f8b23d9630647..31aebfc389782ad78eceeb084d9c53b5134d38d0 100644 (file)
@@ -185,12 +185,18 @@ static int vl_method_set_persistent_storage(Varlink *vlink, JsonVariant *paramet
                 return r;
 
         if (ready) {
-                _cleanup_close_ int fd = -EBADF;
                 struct stat st, st_prev;
+                int fd;
 
-                fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY | O_PATH);
+                fd = varlink_peek_fd(vlink, 0);
                 if (fd < 0)
-                        return log_warning_errno(errno, "Failed to open /var/lib/systemd/network/: %m");
+                        return log_warning_errno(fd, "Failed to peek file descriptor of the persistent storage: %m");
+
+                r = fd_verify_safe_flags_full(fd, O_DIRECTORY);
+                if (r == -EREMOTEIO)
+                        return log_warning_errno(r, "Passed persistent storage fd has unexpected flags, refusing.");
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to verify flags of passed persistent storage fd: %m");
 
                 r = fd_is_read_only_fs(fd);
                 if (r < 0)
@@ -201,7 +207,11 @@ static int vl_method_set_persistent_storage(Varlink *vlink, JsonVariant *paramet
                 }
 
                 if (fstat(fd, &st) < 0)
-                        return log_warning_errno(r, "Failed to stat the persistent storage: %m");
+                        return log_warning_errno(r, "Failed to stat the passed persistent storage fd: %m");
+
+                r = stat_verify_directory(&st);
+                if (r < 0)
+                        return log_warning_errno(r, "The passed persistent storage fd is not a directory, refusing: %m");
 
                 if (manager->persistent_storage_fd >= 0 &&
                     fstat(manager->persistent_storage_fd, &st_prev) >= 0 &&
@@ -225,9 +235,9 @@ static int vl_method_set_persistent_storage(Varlink *vlink, JsonVariant *paramet
         if (ready) {
                 _cleanup_close_ int fd = -EBADF;
 
-                fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY | O_PATH);
+                fd = varlink_take_fd(vlink, 0);
                 if (fd < 0)
-                        return log_warning_errno(errno, "Failed to open /var/lib/systemd/network/: %m");
+                        return log_warning_errno(fd, "Failed to take file descriptor of the persistent storage: %m");
 
                 close_and_replace(manager->persistent_storage_fd, fd);
         } else
@@ -238,6 +248,18 @@ static int vl_method_set_persistent_storage(Varlink *vlink, JsonVariant *paramet
         return varlink_reply(vlink, NULL);
 }
 
+static int on_connect(VarlinkServer *s, Varlink *vlink, void *userdata) {
+        int r;
+
+        assert(vlink);
+
+        r = varlink_set_allow_fd_passing_input(vlink, true);
+        if (r < 0)
+                return log_warning_errno(r, "Failed to allow receiving file descriptor through varlink: %m");
+
+        return 0;
+}
+
 int manager_connect_varlink(Manager *m) {
         _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
         int r;
@@ -253,6 +275,8 @@ int manager_connect_varlink(Manager *m) {
 
         varlink_server_set_userdata(s, m);
 
+        (void) varlink_server_set_description(s, "varlink-api-network");
+
         r = varlink_server_add_interface(s, &vl_interface_io_systemd_Network);
         if (r < 0)
                 return log_error_errno(r, "Failed to add Network interface to varlink server: %m");
@@ -274,6 +298,10 @@ int manager_connect_varlink(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
 
+        r = varlink_server_bind_connect(s, on_connect);
+        if (r < 0)
+                return log_error_errno(r, "Failed to set on-connect callback for varlink: %m");
+
         m->varlink_server = TAKE_PTR(s);
         return 0;
 }
index 1bae89393467a3bc339fd9cf7754d074d98aa7ef..31a2bdea24c112124964f51d0c9e53abc2c36133 100644 (file)
@@ -39,7 +39,7 @@ int route_metric_copy(const RouteMetric *src, RouteMetric *dest) {
         } else
                 dest->metrics_set = NULL;
 
-        return strdup_or_null(src->tcp_congestion_control_algo, &dest->tcp_congestion_control_algo);
+        return strdup_to(&dest->tcp_congestion_control_algo, src->tcp_congestion_control_algo);
 }
 
 void route_metric_hash_func(const RouteMetric *metric, struct siphash *state) {
index 8ba7505987aeec42c406d258bfd627c536f7588d..11215c36c717f063bedb643f4b2241c63fd0a6e3 100644 (file)
@@ -218,7 +218,7 @@ static int route_nexthop_copy(const RouteNextHop *src, RouteNextHop *dest) {
         /* unset pointer copied in the above. */
         dest->ifname = NULL;
 
-        return strdup_or_null(src->ifindex > 0 ? NULL : src->ifname, &dest->ifname);
+        return strdup_to(&dest->ifname, src->ifindex > 0 ? NULL : src->ifname);
 }
 
 static int route_nexthop_dup(const RouteNextHop *src, RouteNextHop **ret) {
index 358958b82b3d6f1b9d8e692591915e014edc2366..b63516d13efc0d87b34825e1ad518d64080c5623 100644 (file)
@@ -297,15 +297,12 @@ int allocate_scope(
 
         description = strjoina("Container ", machine_name);
 
-        if (allow_pidfd) {
-                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
-                r = pidref_set_pid(&pidref, pid);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to allocate PID reference: %m");
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_set_pid(&pidref, pid);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate PID reference: %m");
 
-                r = bus_append_scope_pidref(m, &pidref);
-        } else
-                r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) pid);
+        r = bus_append_scope_pidref(m, &pidref, allow_pidfd);
         if (r < 0)
                 return bus_log_create_error(r);
 
index 3189c03639535eb92c2bd585204371273accecce..3d0a9a73e3d68d2f59a5d587f61587f2cc571e9d 100644 (file)
@@ -3958,7 +3958,7 @@ static int outer_child(
 
         if (dissected_image) {
                 /* Now we know the uid shift, let's now mount everything else that might be in the image. */
-                r = dissected_image_mount(
+                r = dissected_image_mount_and_warn(
                                 dissected_image,
                                 directory,
                                 arg_uid_shift,
@@ -3967,10 +3967,8 @@ static int outer_child(
                                 determine_dissect_image_flags()|
                                 DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY|
                                 (idmap ? DISSECT_IMAGE_MOUNT_IDMAPPED : 0));
-                if (r == -EUCLEAN)
-                        return log_error_errno(r, "File system check for image failed: %m");
                 if (r < 0)
-                        return log_error_errno(r, "Failed to mount image file system: %m");
+                        return r;
         }
 
         if (arg_unified_cgroup_hierarchy == CGROUP_UNIFIED_UNKNOWN) {
index 6e6678c33d990b8113bda61299848eb8436ec8cd..69d103e71f04c77921ebb7f48ca160a611bb64c0 100644 (file)
@@ -321,17 +321,16 @@ int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char
                 if (r == -ENOMEM)
                         return r; /* Treat oom as a hard error */
                 if (r < 0) {
-                        if (ret == 0)
-                                ret = r;
+                        RET_GATHER(ret, r);
                         continue; /* Try to find something else to kill */
                 }
 
                 dump_until = MAX(dump_until, i + 1);
-                char *selected = strdup(sorted[i]->path);
-                if (!selected)
-                        return -ENOMEM;
-                *ret_selected = selected;
+
                 ret = r;
+                r = strdup_to(ret_selected, sorted[i]->path);
+                if (r < 0)
+                        return r;
                 break;
         }
 
@@ -365,17 +364,16 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run,
                 if (r == -ENOMEM)
                         return r; /* Treat oom as a hard error */
                 if (r < 0) {
-                        if (ret == 0)
-                                ret = r;
+                        RET_GATHER(ret, r);
                         continue; /* Try to find something else to kill */
                 }
 
                 dump_until = MAX(dump_until, i + 1);
-                char *selected = strdup(sorted[i]->path);
-                if (!selected)
-                        return -ENOMEM;
-                *ret_selected = selected;
+
                 ret = r;
+                r = strdup_to(ret_selected, sorted[i]->path);
+                if (r < 0)
+                        return r;
                 break;
         }
 
@@ -442,9 +440,9 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
                         return log_debug_errno(r, "Error converting pgscan value to uint64_t: %m");
         }
 
-        ctx->path = strdup(empty_to_root(path));
-        if (!ctx->path)
-                return -ENOMEM;
+        r = strdup_to(&ctx->path, empty_to_root(path));
+        if (r < 0)
+                return r;
 
         *ret = TAKE_PTR(ctx);
         return 0;
index ca30508ff4c456611e87a0c3f42d37cda4c46313..2739bed41a3e56515a9e8971c5ddee492f9a9829 100644 (file)
@@ -182,6 +182,23 @@ bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key) {
                 dns_name_endswith(dns_resource_key_name(key), "_udp.local");
 }
 
+bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key) {
+        assert(key);
+
+        /* Check if this is a PTR resource key used in Service Instance
+         * Enumeration as described in RFC6763 § 4.1, excluding selective
+         * service names described in RFC6763 § 7.1. */
+
+        if (key->type != DNS_TYPE_PTR)
+                return false;
+
+        const char *name = dns_resource_key_name(key);
+        if (dns_name_parent(&name) <= 0)
+                return false;
+
+        return dns_name_equal(name, "_tcp.local") || dns_name_equal(name, "_udp.local");
+}
+
 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
         int r;
 
index 8ad4009ebf73683c16849f57fe0766c69520f4fa..156fa01873564e465a253c0d7e184daec7029a05 100644 (file)
@@ -334,6 +334,7 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
 const char* dns_resource_key_name(const DnsResourceKey *key);
 bool dns_resource_key_is_address(const DnsResourceKey *key);
 bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key);
+bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key);
 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
 int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
 int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
index b1ae36e3909c96cd41e7b554213955e735c2a58c..17bc8231962c78ea07706c2b8bf81d1ff85f3fcc 100644 (file)
@@ -1504,9 +1504,10 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
                         continue;
                 }
 
-                /* Collect service types for _services._dns-sd._udp.local RRs in a set */
+                /* Collect service types for _services._dns-sd._udp.local RRs in a set. Only two-label names
+                 * (not selective names) are considered according to RFC6763 § 9. */
                 if (!scope->announced &&
-                    dns_resource_key_is_dnssd_ptr(z->rr->key)) {
+                    dns_resource_key_is_dnssd_two_label_ptr(z->rr->key)) {
                         if (!set_contains(types, dns_resource_key_name(z->rr->key))) {
                                 r = set_ensure_put(&types, &dns_name_hash_ops, dns_resource_key_name(z->rr->key));
                                 if (r < 0)
index 5af550bc592715f73dba31ff45bb433d764113bc..2e3af0c445e10808786a6e008b77142b2a912f25 100644 (file)
@@ -2301,7 +2301,7 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
         return 1;
 }
 
-static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
+static int dns_transaction_request_dnssec_rr_full(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL;
         DnsTransaction *aux;
         int r;
@@ -2332,11 +2332,19 @@ static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *
                 r = dns_transaction_go(aux);
                 if (r < 0)
                         return r;
+                if (ret)
+                        *ret = aux;
         }
 
         return 1;
 }
 
+static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
+        assert(t);
+        assert(key);
+        return dns_transaction_request_dnssec_rr_full(t, key, NULL);
+}
+
 static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) {
         int r;
 
@@ -2437,6 +2445,8 @@ static bool dns_transaction_dnssec_supported_full(DnsTransaction *t) {
 int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
         DnsResourceRecord *rr;
 
+        /* Have we already requested a record that would be sufficient to validate an insecure delegation? */
+        bool chased_insecure = false;
         int r;
 
         assert(t);
@@ -2449,11 +2459,11 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
          * - For RRSIG we get the matching DNSKEY
          * - For DNSKEY we get the matching DS
          * - For unsigned SOA/NS we get the matching DS
-         * - For unsigned CNAME/DNAME/DS we get the parent SOA RR
-         * - For other unsigned RRs we get the matching SOA RR
+         * - For unsigned CNAME/DNAME/DS we get the parent DS RR
+         * - For other unsigned RRs we get the matching DS RR
          * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR
-         * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR
-         * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR
+         * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's DS RR
+         * - For other queries with no matching response RRs, and no NSEC/NSEC3, the DS RR
          */
 
         if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO)
@@ -2480,6 +2490,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                 case DNS_TYPE_RRSIG: {
                         /* For each RRSIG we request the matching DNSKEY */
                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL;
+                        DnsTransaction *aux = NULL;
 
                         /* If this RRSIG is about a DNSKEY RR and the
                          * signer is the same as the owner, then we
@@ -2516,9 +2527,20 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
 
                         log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").",
                                   t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag);
-                        r = dns_transaction_request_dnssec_rr(t, dnskey);
+                        r = dns_transaction_request_dnssec_rr_full(t, dnskey, &aux);
                         if (r < 0)
                                 return r;
+
+                        /* If we are requesting a DNSKEY, we can anticipate that we will want the matching DS
+                         * in the near future. Let's request it in advance so we don't have to wait in the
+                         * common case. */
+                        if (aux) {
+                                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds =
+                                        dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(dnskey));
+                                r = dns_transaction_request_dnssec_rr(t, ds);
+                                if (r < 0)
+                                        return r;
+                        }
                         break;
                 }
 
@@ -2593,6 +2615,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                         if (r > 0)
                                 continue;
 
+                        chased_insecure = true;
                         ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
                         if (!ds)
                                 return -ENOMEM;
@@ -2609,11 +2632,11 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                 case DNS_TYPE_DS:
                 case DNS_TYPE_CNAME:
                 case DNS_TYPE_DNAME: {
-                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
+                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
                         const char *name;
 
                         /* CNAMEs and DNAMEs cannot be located at a
-                         * zone apex, hence ask for the parent SOA for
+                         * zone apex, hence ask for the parent DS for
                          * unsigned CNAME/DNAME RRs, maybe that's the
                          * apex. But do all that only if this is
                          * actually a response to our original
@@ -2647,13 +2670,13 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                         if (r == 0)
                                 continue;
 
-                        soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name);
-                        if (!soa)
+                        ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, name);
+                        if (!ds)
                                 return -ENOMEM;
 
-                        log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
+                        log_debug("Requesting parent DS to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).",
                                   t->id, dns_resource_key_name(rr->key));
-                        r = dns_transaction_request_dnssec_rr(t, soa);
+                        r = dns_transaction_request_dnssec_rr(t, ds);
                         if (r < 0)
                                 return r;
 
@@ -2661,11 +2684,11 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                 }
 
                 default: {
-                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
+                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
 
                         /* For other unsigned RRsets (including
                          * NSEC/NSEC3!), look for proof the zone is
-                         * unsigned, by requesting the SOA RR of the
+                         * unsigned, by requesting the DS RR of the
                          * zone. However, do so only if they are
                          * directly relevant to our original
                          * question. */
@@ -2682,13 +2705,13 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
                         if (r > 0)
                                 continue;
 
-                        soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key));
-                        if (!soa)
+                        ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key));
+                        if (!ds)
                                 return -ENOMEM;
 
-                        log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
+                        log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).",
                                   t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr));
-                        r = dns_transaction_request_dnssec_rr(t, soa);
+                        r = dns_transaction_request_dnssec_rr(t, ds);
                         if (r < 0)
                                 return r;
                         break;
@@ -2703,49 +2726,38 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
         if (r < 0)
                 return r;
         if (r > 0) {
-                const char *name, *signed_status;
-                uint16_t type = 0;
-
-                name = dns_resource_key_name(dns_transaction_key(t));
-                signed_status = dns_answer_contains_nsec_or_nsec3(t->answer) ? "signed" : "unsigned";
-
-                /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this
-                 * could also be used as indication that we are not at a zone apex, but in real world setups there are
-                 * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even
-                 * though they have further children. If this was a DS request, then it's signed when the parent zone
-                 * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR,
-                 * to see if that is signed. */
+                const char *name = dns_resource_key_name(dns_transaction_key(t));
+                bool was_signed = dns_answer_contains_nsec_or_nsec3(t->answer);
 
-                if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
-                        r = dns_name_parent(&name);
-                        if (r > 0) {
-                                type = DNS_TYPE_SOA;
-                                log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty DS response).",
-                                          special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id,
-                                          dns_resource_key_name(dns_transaction_key(t)), signed_status);
-                        } else
+                /* If the response is empty, seek the DS for this name, just in case we're at a zone cut
+                 * already, unless we just requested the DS, in which case we have to ask the parent to make
+                 * progress.
+                 *
+                 * If this was an SOA or NS request, we could also skip to the parent, but in real world
+                 * setups there are too many broken DNS servers (Hello, incapdns.net!) where non-terminal
+                 * zones return NXDOMAIN even though they have further children. */
+
+                if (chased_insecure || was_signed)
+                        /* In this case we already requested what we need above. */
+                        name = NULL;
+                else if (dns_transaction_key(t)->type == DNS_TYPE_DS)
+                        /* If the DS response is empty, we'll walk up the dns labels requesting DS until we
+                         * find a referral to the SOA or hit it anyway and get a positive DS response. */
+                        if (dns_name_parent(&name) <= 0)
                                 name = NULL;
 
-                } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS)) {
-
-                        type = DNS_TYPE_DS;
-                        log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16 " (%s, %s empty SOA/NS response).",
-                                  special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status);
-
-                } else {
-                        type = DNS_TYPE_SOA;
-                        log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty non-SOA/NS/DS response).",
-                                  special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status);
-                }
-
                 if (name) {
-                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL;
+                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL;
 
-                        soa = dns_resource_key_new(dns_transaction_key(t)->class, type, name);
-                        if (!soa)
+                        log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16 " (%s empty response).",
+                                  special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id,
+                                  dns_resource_key_name(dns_transaction_key(t)));
+
+                        ds = dns_resource_key_new(dns_transaction_key(t)->class, DNS_TYPE_DS, name);
+                        if (!ds)
                                 return -ENOMEM;
 
-                        r = dns_transaction_request_dnssec_rr(t, soa);
+                        r = dns_transaction_request_dnssec_rr(t, ds);
                         if (r < 0)
                                 return r;
                 }
@@ -2825,7 +2837,6 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
                 DnsTransaction *dt;
 
                 /* For SOA or NS RRs we look for a matching DS transaction */
-
                 SET_FOREACH(dt, t->dnssec_transactions) {
 
                         if (dns_transaction_key(dt)->class != rr->key->class)
@@ -2833,7 +2844,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
                         if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
                                 continue;
 
-                        r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
+                        r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(dns_transaction_key(dt)));
                         if (r < 0)
                                 return r;
                         if (r == 0)
@@ -2862,16 +2873,16 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
                 DnsTransaction *dt;
 
                 /*
-                 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA.
+                 * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent DS.
                  *
-                 * DS RRs are signed if the parent is signed, hence also look at the parent SOA
+                 * DS RRs are signed if the parent is signed, hence also look at the parent DS
                  */
 
                 SET_FOREACH(dt, t->dnssec_transactions) {
 
                         if (dns_transaction_key(dt)->class != rr->key->class)
                                 continue;
-                        if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
+                        if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
                                 continue;
 
                         if (!parent) {
@@ -2889,7 +2900,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
                                 }
                         }
 
-                        r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), parent);
+                        r = dns_name_endswith(parent, dns_resource_key_name(dns_transaction_key(dt)));
                         if (r < 0)
                                 return r;
                         if (r == 0)
@@ -2904,25 +2915,26 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord *
         default: {
                 DnsTransaction *dt;
 
-                /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */
+                /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our DS lookup was authenticated */
 
                 SET_FOREACH(dt, t->dnssec_transactions) {
-
                         if (dns_transaction_key(dt)->class != rr->key->class)
                                 continue;
-                        if (dns_transaction_key(dt)->type != DNS_TYPE_SOA)
+                        if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
                                 continue;
 
-                        r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key));
+                        r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(dns_transaction_key(dt)));
                         if (r < 0)
                                 return r;
                         if (r == 0)
                                 continue;
 
-                        /* We found the transaction that was supposed to find the SOA RR for us. It was
-                         * successful, but found no RR for us. This means we are not at a zone cut. In this
-                         * case, we require authentication if the SOA lookup was authenticated too. */
-                        return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
+                        if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
+                                return false;
+
+                        /* We expect this to be signed when the DS record exists, and don't expect it to be
+                         * signed when the DS record is proven not to exist. */
+                        return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
                 }
 
                 return true;
@@ -2992,7 +3004,6 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
         DnsTransaction *dt;
         const char *name;
-        uint16_t type = 0;
         int r;
 
         assert(t);
@@ -3027,43 +3038,37 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
 
         name = dns_resource_key_name(dns_transaction_key(t));
 
-        if (dns_transaction_key(t)->type == DNS_TYPE_DS) {
-
-                /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed,
-                 * hence check the parent SOA in this case. */
-
+        if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_DS, DNS_TYPE_CNAME, DNS_TYPE_DNAME)) {
+                /* We got a negative reply for this DS/CNAME/DNAME lookup? Check the parent in this case to
+                 * see if this answer should have been signed. */
                 r = dns_name_parent(&name);
                 if (r < 0)
                         return r;
                 if (r == 0)
                         return true;
+        }
 
-                type = DNS_TYPE_SOA;
-
-        } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS))
-                /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */
-                type = DNS_TYPE_DS;
-        else
-                /* For all other negative replies, check for the SOA lookup */
-                type = DNS_TYPE_SOA;
-
-        /* For all other RRs we check the SOA on the same level to see
+        /* For all other RRs we check the DS on the same level to see
          * if it's signed. */
 
         SET_FOREACH(dt, t->dnssec_transactions) {
-
                 if (dns_transaction_key(dt)->class != dns_transaction_key(t)->class)
                         continue;
-                if (dns_transaction_key(dt)->type != type)
+                if (dns_transaction_key(dt)->type != DNS_TYPE_DS)
                         continue;
 
-                r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), name);
+                r = dns_name_endswith(name, dns_resource_key_name(dns_transaction_key(dt)));
                 if (r < 0)
                         return r;
                 if (r == 0)
                         continue;
 
-                return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED);
+                if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
+                        return false;
+
+                /* We expect this to be signed when the DS record exists, and don't expect it to be signed
+                 * when the DS record is proven not to exist. */
+                return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL);
         }
 
         /* If in doubt, require NSEC/NSEC3 */
index 404c290eeceaa332e1f2d0cf8e9a4f10bb7d96e8..8790755d3b6044ad6abe158a86a4848bddbe06bc 100644 (file)
@@ -140,16 +140,10 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
 
 static int specifier_dnssd_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const Manager *m = ASSERT_PTR(userdata);
-        char *n;
 
         assert(m->llmnr_hostname);
 
-        n = strdup(m->llmnr_hostname);
-        if (!n)
-                return -ENOMEM;
-
-        *ret = n;
-        return 0;
+        return strdup_to(ret, m->llmnr_hostname);
 }
 
 int dnssd_render_instance_name(Manager *m, DnssdService *s, char **ret) {
index 95336b86fe5a7143ec1ead09b56317f853e313a9..221b441fac82df4770447ee037044b95c1b70897 100644 (file)
@@ -12,12 +12,12 @@ install_emptydir(bindir)
 
 meson.add_install_script(sh, '-c',
                              ln_s.format(bindir / 'systemd-run',
-                                         bindir / 'uid0'))
+                                         bindir / 'run0'))
 
 custom_target(
-        'systemd-uid0',
-        input : 'systemd-uid0.in',
-        output : 'systemd-uid0',
+        'systemd-run0',
+        input : 'systemd-run0.in',
+        output : 'systemd-run0',
         command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : pamconfdir != 'no',
         install_dir : pamconfdir)
index c0c65b2ea1fa12eb5faf8129a7a3f550a9c57003..93e061a3c311f2d1e9f84cec1750e6a914b34754 100644 (file)
@@ -159,7 +159,7 @@ static int help_sudo_mode(void) {
         _cleanup_free_ char *link = NULL;
         int r;
 
-        r = terminal_urlify_man("uid0", "1", &link);
+        r = terminal_urlify_man("run0", "1", &link);
         if (r < 0)
                 return log_oom();
 
@@ -743,7 +743,7 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
                 ARG_BACKGROUND,
         };
 
-        /* If invoked as "uid0" binary, let's expose a more sudo-like interface. We add various extensions
+        /* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions
          * though (but limit the extension to long options). */
 
         static const struct option options[] = {
@@ -943,7 +943,7 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
         if (strv_extendf(&arg_property, "LogExtraFields=ELEVATED_USER=%s", un) < 0)
                 return log_oom();
 
-        if (strv_extend(&arg_property, "PAMName=systemd-uid0") < 0)
+        if (strv_extend(&arg_property, "PAMName=systemd-run0") < 0)
                 return log_oom();
 
         if (!arg_background && arg_stdio == ARG_STDIO_PTY) {
@@ -1265,18 +1265,13 @@ static int transient_scope_set_properties(sd_bus_message *m, bool allow_pidfd) {
         if (r < 0)
                 return r;
 
-        if (allow_pidfd) {
-                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
 
-                r = pidref_set_self(&pidref);
-                if (r < 0)
-                        return r;
+        r = pidref_set_self(&pidref);
+        if (r < 0)
+                return r;
 
-                r = bus_append_scope_pidref(m, &pidref);
-        } else
-                r = sd_bus_message_append(
-                                m, "(sv)",
-                                "PIDs", "au", 1, getpid_cached());
+        r = bus_append_scope_pidref(m, &pidref, allow_pidfd);
         if (r < 0)
                 return bus_log_create_error(r);
 
@@ -2262,7 +2257,7 @@ static int run(int argc, char* argv[]) {
         log_parse_environment();
         log_open();
 
-        if (invoked_as(argv, "uid0"))
+        if (invoked_as(argv, "run0"))
                 r = parse_argv_sudo_mode(argc, argv);
         else
                 r = parse_argv(argc, argv);
similarity index 96%
rename from src/run/systemd-uid0.in
rename to src/run/systemd-run0.in
index 57bd5e38b92a97b53b1a0dcba8ca8a14affb368d..11f830b7b08fa6cc948c5412dd549d6c84e3a2af 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 # This file is part of systemd.
 #
-# Used by uid0 sessions
+# Used by run0 sessions
 
 {% if ENABLE_HOMED %}
 -account sufficient pam_systemd_home.so
index 7d847b94252f79fd5324f166c60562aec11c5259..2fcfb1d3b96c9affc9f93dd4176c58f0e8713be5 100644 (file)
@@ -2821,13 +2821,13 @@ int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char
         return 0;
 }
 
-int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref) {
+int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref, bool allow_pidfd) {
         assert(m);
 
         if (!pidref_is_set(pidref))
                 return -ESRCH;
 
-        if (pidref->fd >= 0)
+        if (pidref->fd >= 0 && allow_pidfd)
                 return sd_bus_message_append(
                                 m, "(sv)",
                                 "PIDFDs", "ah", 1, pidref->fd);
index a1518158ff4691f8551064ea8a7db6151fc5eb6f..e4168a44254116ff24cc89f3a001db40afa3f5dc 100644 (file)
@@ -26,7 +26,7 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
 int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const char *assignment);
 int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char **l);
 
-int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref);
+int bus_append_scope_pidref(sd_bus_message *m, const PidRef *pidref, bool allow_pidfd);
 
 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet);
 
index 77ac85965f8d0be50ea57a1f033d8c4b3a1a5841..cbbc85a5cc52a8f5f41dc904088a7f91bcf41b7f 100644 (file)
@@ -33,7 +33,9 @@ DLSYM_FUNCTION(crypt_keyslot_destroy);
 DLSYM_FUNCTION(crypt_keyslot_max);
 DLSYM_FUNCTION(crypt_load);
 DLSYM_FUNCTION(crypt_resize);
-DLSYM_FUNCTION(crypt_resume_by_passphrase);
+#if HAVE_CRYPT_RESUME_BY_VOLUME_KEY
+DLSYM_FUNCTION(crypt_resume_by_volume_key);
+#endif
 DLSYM_FUNCTION(crypt_set_data_device);
 DLSYM_FUNCTION(crypt_set_debug_level);
 DLSYM_FUNCTION(crypt_set_log_callback);
@@ -276,7 +278,9 @@ int dlopen_cryptsetup(void) {
                         DLSYM_ARG(crypt_keyslot_max),
                         DLSYM_ARG(crypt_load),
                         DLSYM_ARG(crypt_resize),
-                        DLSYM_ARG(crypt_resume_by_passphrase),
+#if HAVE_CRYPT_RESUME_BY_VOLUME_KEY
+                        DLSYM_ARG(crypt_resume_by_volume_key),
+#endif
                         DLSYM_ARG(crypt_set_data_device),
                         DLSYM_ARG(crypt_set_debug_level),
                         DLSYM_ARG(crypt_set_log_callback),
index 8a4416b4fcbe39e1e9698aa004b4a2e7447fc652..f00ac367b6078dbea88e9ad9c47c5912c2c2f0db 100644 (file)
@@ -41,7 +41,9 @@ DLSYM_PROTOTYPE(crypt_keyslot_destroy);
 DLSYM_PROTOTYPE(crypt_keyslot_max);
 DLSYM_PROTOTYPE(crypt_load);
 DLSYM_PROTOTYPE(crypt_resize);
-DLSYM_PROTOTYPE(crypt_resume_by_passphrase);
+#if HAVE_CRYPT_RESUME_BY_VOLUME_KEY
+DLSYM_PROTOTYPE(crypt_resume_by_volume_key);
+#endif
 DLSYM_PROTOTYPE(crypt_set_data_device);
 DLSYM_PROTOTYPE(crypt_set_debug_level);
 DLSYM_PROTOTYPE(crypt_set_log_callback);
index eac3641abd56196af2c8a32367c61b51c87c349f..a0832c98281faffdbd3dbbc9ac24141b86d6f0b4 100644 (file)
@@ -268,16 +268,8 @@ int probe_filesystem_full(
         (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
 
         if (fstype) {
-                char *t;
-
                 log_debug("Probed fstype '%s' on partition %s.", fstype, path);
-
-                t = strdup(fstype);
-                if (!t)
-                        return -ENOMEM;
-
-                *ret_fstype = t;
-                return 1;
+                return strdup_to_full(ret_fstype, fstype);
         }
 
 not_found:
@@ -2286,19 +2278,19 @@ int dissected_image_mount_and_warn(
 
         r = dissected_image_mount(m, where, uid_shift, uid_range, userns_fd, flags);
         if (r == -ENXIO)
-                return log_error_errno(r, "Not root file system found in image.");
+                return log_error_errno(r, "Failed to mount image: No root file system found in image.");
         if (r == -EMEDIUMTYPE)
-                return log_error_errno(r, "No suitable os-release/extension-release file in image found.");
+                return log_error_errno(r, "Failed to mount image: No suitable os-release/extension-release file in image found.");
         if (r == -EUNATCH)
-                return log_error_errno(r, "Encrypted file system discovered, but decryption not requested.");
+                return log_error_errno(r, "Failed to mount image: Encrypted file system discovered, but decryption not requested.");
         if (r == -EUCLEAN)
-                return log_error_errno(r, "File system check on image failed.");
+                return log_error_errno(r, "Failed to mount image: File system check on image failed.");
         if (r == -EBUSY)
-                return log_error_errno(r, "File system already mounted elsewhere.");
+                return log_error_errno(r, "Failed to mount image: File system already mounted elsewhere.");
         if (r == -EAFNOSUPPORT)
-                return log_error_errno(r, "File system type not supported or not known.");
+                return log_error_errno(r, "Failed to mount image: File system type not supported or not known.");
         if (r == -EIDRM)
-                return log_error_errno(r, "File system is too uncommon, refused.");
+                return log_error_errno(r, "Failed to mount image: File system is too uncommon, refused.");
         if (r < 0)
                 return log_error_errno(r, "Failed to mount image: %m");
 
index dce9e005fee495924740772e2b7f1d19c0b70d49..1e100c35ef530299230d767df15b7e99c4e7fe9c 100644 (file)
@@ -182,7 +182,6 @@ int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret) {
         struct ifreq ifr = {
                 .ifr_data = (void*) &ecmd,
         };
-        char *d;
         int r;
 
         assert(ethtool_fd);
@@ -201,12 +200,7 @@ int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret) {
         if (isempty(ecmd.driver))
                 return -ENODATA;
 
-        d = strdup(ecmd.driver);
-        if (!d)
-                return -ENOMEM;
-
-        *ret = d;
-        return 0;
+        return strdup_to(ret, ecmd.driver);
 }
 
 int ethtool_get_link_info(
index 3cc709308da87e1db775b1a9530aec86e0eff6cc..bdb44b348fbe58d5c56154ea3f085b9405780685 100644 (file)
@@ -37,16 +37,11 @@ static int specifier_prefix_and_instance(char specifier, const void *data, const
 
 static int specifier_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const InstallInfo *i = ASSERT_PTR(userdata);
-        char *ans;
 
         if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
                 return unit_name_replace_instance(i->name, i->default_instance, ret);
 
-        ans = strdup(i->name);
-        if (!ans)
-                return -ENOMEM;
-        *ret = ans;
-        return 0;
+        return strdup_to(ret, i->name);
 }
 
 static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
@@ -86,14 +81,10 @@ static int specifier_last_component(char specifier, const void *data, const char
                 return r;
 
         dash = strrchr(prefix, '-');
-        if (dash) {
-                dash = strdup(dash + 1);
-                if (!dash)
-                        return -ENOMEM;
-                *ret = dash;
-        } else
-                *ret = TAKE_PTR(prefix);
+        if (dash)
+                return strdup_to(ret, dash + 1);
 
+        *ret = TAKE_PTR(prefix);
         return 0;
 }
 
index 12bf083a2e60d625ed24eb03d35547ceeb64739e..15cab9a6127e5b31de6492fd69ecb8682a6fa800 100644 (file)
@@ -162,9 +162,10 @@ static int path_is_generator(const LookupPaths *lp, const char *path) {
         if (r < 0)
                 return r;
 
-        return path_equal_ptr(parent, lp->generator) ||
-               path_equal_ptr(parent, lp->generator_early) ||
-               path_equal_ptr(parent, lp->generator_late);
+        return PATH_IN_SET(parent,
+                           lp->generator,
+                           lp->generator_early,
+                           lp->generator_late);
 }
 
 static int path_is_transient(const LookupPaths *lp, const char *path) {
@@ -178,7 +179,7 @@ static int path_is_transient(const LookupPaths *lp, const char *path) {
         if (r < 0)
                 return r;
 
-        return path_equal_ptr(parent, lp->transient);
+        return path_equal(parent, lp->transient);
 }
 
 static int path_is_control(const LookupPaths *lp, const char *path) {
@@ -192,8 +193,9 @@ static int path_is_control(const LookupPaths *lp, const char *path) {
         if (r < 0)
                 return r;
 
-        return path_equal_ptr(parent, lp->persistent_control) ||
-               path_equal_ptr(parent, lp->runtime_control);
+        return PATH_IN_SET(parent,
+                           lp->persistent_control,
+                           lp->runtime_control);
 }
 
 static int path_is_config(const LookupPaths *lp, const char *path, bool check_parent) {
@@ -214,8 +216,9 @@ static int path_is_config(const LookupPaths *lp, const char *path, bool check_pa
                 path = parent;
         }
 
-        return path_equal_ptr(path, lp->persistent_config) ||
-               path_equal_ptr(path, lp->runtime_config);
+        return PATH_IN_SET(path,
+                           lp->persistent_config,
+                           lp->runtime_config);
 }
 
 static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_parent) {
@@ -241,12 +244,13 @@ static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_p
                 path = parent;
         }
 
-        return path_equal_ptr(path, lp->runtime_config) ||
-               path_equal_ptr(path, lp->generator) ||
-               path_equal_ptr(path, lp->generator_early) ||
-               path_equal_ptr(path, lp->generator_late) ||
-               path_equal_ptr(path, lp->transient) ||
-               path_equal_ptr(path, lp->runtime_control);
+        return PATH_IN_SET(path,
+                           lp->runtime_config,
+                           lp->generator,
+                           lp->generator_early,
+                           lp->generator_late,
+                           lp->transient,
+                           lp->runtime_control);
 }
 
 static int path_is_vendor_or_generator(const LookupPaths *lp, const char *path) {
@@ -1038,7 +1042,7 @@ static int find_symlinks_in_scope(
                 if (r > 0) {
                         /* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
 
-                        if (path_equal_ptr(*p, lp->persistent_config)) {
+                        if (path_equal(*p, lp->persistent_config)) {
                                 /* This is the best outcome, let's return it immediately. */
                                 *state = UNIT_FILE_ENABLED;
                                 return 1;
@@ -1059,7 +1063,7 @@ static int find_symlinks_in_scope(
                                 enabled_at_all = true;
 
                 } else if (same_name_link) {
-                        if (path_equal_ptr(*p, lp->persistent_config))
+                        if (path_equal(*p, lp->persistent_config))
                                 same_name_link_config = true;
                         else {
                                 r = path_is_runtime(lp, *p, false);
@@ -3042,17 +3046,16 @@ int unit_file_set_default(
 int unit_file_get_default(
                 RuntimeScope scope,
                 const char *root_dir,
-                char **name) {
+                char **ret) {
 
         _cleanup_(lookup_paths_done) LookupPaths lp = {};
         _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
         InstallInfo *info;
-        char *n;
         int r;
 
         assert(scope >= 0);
         assert(scope < _RUNTIME_SCOPE_MAX);
-        assert(name);
+        assert(ret);
 
         r = lookup_paths_init(&lp, scope, 0, root_dir);
         if (r < 0)
@@ -3063,12 +3066,7 @@ int unit_file_get_default(
         if (r < 0)
                 return r;
 
-        n = strdup(info->name);
-        if (!n)
-                return -ENOMEM;
-
-        *name = n;
-        return 0;
+        return strdup_to(ret, info->name);
 }
 
 int unit_file_lookup_state(
@@ -3221,11 +3219,9 @@ int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char
         if (ret_path) {
                 assert(info);
 
-                _cleanup_free_ char *p = strdup(info->path);
-                if (!p)
-                        return -ENOMEM;
-
-                *ret_path = TAKE_PTR(p);
+                r = strdup_to(ret_path, info->path);
+                if (r < 0)
+                        return r;
         }
 
         return 1;
index a09557f69f244c1d6dfd407120c2015d2240b90b..8cce6dddfe2adff1af147ad296e89ad0e98d8ba2 100644 (file)
@@ -175,7 +175,7 @@ int unit_file_set_default(
 int unit_file_get_default(
                 RuntimeScope scope,
                 const char *root_dir,
-                char **name);
+                char **ret);
 int unit_file_add_dependency(
                 RuntimeScope scope,
                 UnitFileFlags flags,
index 81e6f1754c4f8973fb3d5cc99f0a29dbe7d151e6..2f3abe4e89438aee55975a00cef395f80352a99a 100644 (file)
@@ -140,7 +140,7 @@ static char* systemd_crypt_ra(const char *phrase, const char *setting, void **da
 int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret) {
         _cleanup_free_ char *salt = NULL;
         _cleanup_(erase_and_freep) void *_cd_data = NULL;
-        char *p;
+        const char *p;
         int r, _cd_size = 0;
 
         assert(!!cd_data == !!cd_size);
@@ -155,12 +155,7 @@ int hash_password_full(const char *password, void **cd_data, int *cd_size, char
                 return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)),
                                        CRYPT_RA_NAME "() failed: %m");
 
-        p = strdup(p);
-        if (!p)
-                return -ENOMEM;
-
-        *ret = p;
-        return 0;
+        return strdup_to(ret, p);
 }
 
 bool looks_like_hashed_password(const char *s) {
index f56c5646c100002568c7b1fade8eb8b9a846bd9d..c9a14b4739bef8101a408403d06cd54c27c93af4 100644 (file)
@@ -32,14 +32,8 @@ int net_get_type_string(sd_device *device, uint16_t iftype, char **ret) {
 
         if (device &&
             sd_device_get_devtype(device, &t) >= 0 &&
-            !isempty(t)) {
-                p = strdup(t);
-                if (!p)
-                        return -ENOMEM;
-
-                *ret = p;
-                return 0;
-        }
+            !isempty(t))
+                return strdup_to(ret, t);
 
         t = arphrd_to_name(iftype);
         if (!t)
index 87e7d285c534d78f6cb3f8d7cb238fba6a9b56ba..e070f9636c66cd54f8f589c6529efd30b71a1d3c 100644 (file)
@@ -101,7 +101,6 @@ int suggest_passwords(void) {
         _cleanup_strv_free_erase_ char **suggestions = NULL;
         _cleanup_(erase_and_freep) char *joined = NULL;
         char buf[PWQ_MAX_ERROR_MESSAGE_LEN];
-        size_t i;
         int r;
 
         r = pwq_allocate_context(&pwq);
@@ -115,7 +114,7 @@ int suggest_passwords(void) {
         if (!suggestions)
                 return log_oom();
 
-        for (i = 0; i < N_SUGGESTIONS; i++) {
+        for (size_t i = 0; i < N_SUGGESTIONS; i++) {
                 r = sym_pwquality_generate(pwq, 64, suggestions + i);
                 if (r < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate password, ignoring: %s",
@@ -145,13 +144,10 @@ int check_password_quality(const char *password, const char *old, const char *us
         r = sym_pwquality_check(pwq, password, old, username, &auxerror);
         if (r < 0) {
                 if (ret_error) {
-                        _cleanup_free_ char *e = NULL;
-
-                        e = strdup(sym_pwquality_strerror(buf, sizeof(buf), r, auxerror));
-                        if (!e)
-                                return -ENOMEM;
-
-                        *ret_error = TAKE_PTR(e);
+                        r = strdup_to(ret_error,
+                                      sym_pwquality_strerror(buf, sizeof(buf), r, auxerror));
+                        if (r < 0)
+                                return r;
                 }
 
                 return 0; /* all bad */
index c551ed62e3d59e58b267c1a8d0b976333083e808..85c599c5c657493b91d869f01de120d56936624d 100644 (file)
@@ -141,16 +141,8 @@ int terminal_urlify_path(const char *path, const char *text, char **ret) {
         if (isempty(text))
                 text = path;
 
-        if (!urlify_enabled()) {
-                char *n;
-
-                n = strdup(text);
-                if (!n)
-                        return -ENOMEM;
-
-                *ret = n;
-                return 0;
-        }
+        if (!urlify_enabled())
+                return strdup_to(ret, text);
 
         r = file_url_from_path(path, &url);
         if (r < 0)
index a514428ef2c75d6f484aaa0a0569c956102880de..bdbd79087ca27238f0ec412d20d83342b4983c0d 100644 (file)
@@ -266,7 +266,7 @@ static int insert_string(PTYForward *f, size_t offset, const char *s) {
         return (int) l;
 }
 
-static int insert_newline_color_erase(PTYForward *f, size_t offset) {
+static int insert_background_color(PTYForward *f, size_t offset) {
         _cleanup_free_ char *s = NULL;
 
         assert(f);
@@ -274,29 +274,6 @@ static int insert_newline_color_erase(PTYForward *f, size_t offset) {
         if (!f->background_color)
                 return 0;
 
-        /* When we see a newline (ASCII 10) then this sets the background color to the desired one, and erase the rest
-         * of the line with it */
-
-        s = background_color_sequence(f);
-        if (!s)
-                return -ENOMEM;
-
-        if (!strextend(&s, ANSI_ERASE_TO_END_OF_LINE))
-                return -ENOMEM;
-
-        return insert_string(f, offset, s);
-}
-
-static int insert_carriage_return_color(PTYForward *f, size_t offset) {
-        _cleanup_free_ char *s = NULL;
-
-        assert(f);
-
-        if (!f->background_color)
-                return 0;
-
-        /* When we see a carriage return (ASCII 13) then this sets only the background */
-
         s = background_color_sequence(f);
         if (!s)
                 return -ENOMEM;
@@ -430,29 +407,19 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
                 case ANSI_COLOR_STATE_TEXT:
                         break;
 
-                case ANSI_COLOR_STATE_NEWLINE: {
-                        /* Immediately after a newline insert an ANSI sequence to erase the line with a background color */
-
-                        r = insert_newline_color_erase(f, i);
-                        if (r < 0)
-                                return r;
-
-                        i += r;
-                        break;
-                }
-
-                case ANSI_COLOR_STATE_CARRIAGE_RETURN: {
-                        /* Immediately after a carriage return insert an ANSI sequence set the background color back */
+                case ANSI_COLOR_STATE_NEWLINE:
+                case ANSI_COLOR_STATE_CARRIAGE_RETURN:
+                        /* Immediately after a newline (ASCII 10) or carriage return (ASCII 13) insert an
+                         * ANSI sequence set the background color back. */
 
-                        r = insert_carriage_return_color(f, i);
+                        r = insert_background_color(f, i);
                         if (r < 0)
                                 return r;
 
                         i += r;
                         break;
-                }
 
-                case ANSI_COLOR_STATE_ESC: {
+                case ANSI_COLOR_STATE_ESC:
 
                         if (c == '[') {
                                 f->ansi_color_state = ANSI_COLOR_STATE_CSI_SEQUENCE;
@@ -461,11 +428,9 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
                                 f->ansi_color_state = ANSI_COLOR_STATE_OSC_SEQUENCE;
                                 continue;
                         }
-
                         break;
-                }
 
-                case ANSI_COLOR_STATE_CSI_SEQUENCE: {
+                case ANSI_COLOR_STATE_CSI_SEQUENCE:
 
                         if (c >= 0x20 && c <= 0x3F) {
                                 /* If this is a "parameter" or "intermediary" byte (i.e. ranges 0x20…0x2F and
@@ -493,11 +458,9 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
                                 f->csi_sequence = mfree(f->csi_sequence);
                                 f->ansi_color_state = ANSI_COLOR_STATE_TEXT;
                         }
-
                         continue;
-                }
 
-                case ANSI_COLOR_STATE_OSC_SEQUENCE: {
+                case ANSI_COLOR_STATE_OSC_SEQUENCE:
 
                         if ((uint8_t) c >= ' ') {
                                 if (strlen_ptr(f->osc_sequence) >= 64) {
@@ -526,9 +489,7 @@ static int pty_forward_ansi_process(PTYForward *f, size_t offset) {
                                 f->osc_sequence = mfree(f->osc_sequence);
                                 f->ansi_color_state = ANSI_COLOR_STATE_TEXT;
                         }
-
                         continue;
-                }
 
                 default:
                         assert_not_reached();
index a56b8365fb4bd9569683c3d7576e235ec30c9df4..f6739f2c662a066610aa756ab1580d8fa4bb5157 100644 (file)
@@ -111,18 +111,7 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
 /* Generic handler for simple string replacements */
 
 int specifier_string(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
-        char *n = NULL;
-
-        assert(ret);
-
-        if (!isempty(data)) {
-                n = strdup(data);
-                if (!n)
-                        return -ENOMEM;
-        }
-
-        *ret = n;
-        return 0;
+        return strdup_to(ASSERT_PTR(ret), empty_to_null(data));
 }
 
 int specifier_real_path(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
@@ -249,32 +238,18 @@ int specifier_pretty_hostname(char specifier, const void *data, const char *root
 
 int specifier_kernel_release(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         struct utsname uts;
-        char *n;
 
         assert(ret);
 
         if (uname(&uts) < 0)
                 return -errno;
 
-        n = strdup(uts.release);
-        if (!n)
-                return -ENOMEM;
-
-        *ret = n;
-        return 0;
+        return strdup_to(ret, uts.release);
 }
 
 int specifier_architecture(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
-        char *t;
-
-        assert(ret);
-
-        t = strdup(architecture_to_string(uname_architecture()));
-        if (!t)
-                return -ENOMEM;
-
-        *ret = t;
-        return 0;
+        return strdup_to(ASSERT_PTR(ret),
+                         architecture_to_string(uname_architecture()));
 }
 
 /* Note: fields in /etc/os-release might quite possibly be missing, even if everything is entirely valid
@@ -420,7 +395,6 @@ int specifier_user_shell(char specifier, const void *data, const char *root, con
 
 int specifier_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const char *p;
-        char *copy;
         int r;
 
         assert(ret);
@@ -432,17 +406,12 @@ int specifier_tmp_dir(char specifier, const void *data, const char *root, const
                 if (r < 0)
                         return r;
         }
-        copy = strdup(p);
-        if (!copy)
-                return -ENOMEM;
 
-        *ret = copy;
-        return 0;
+        return strdup_to(ret, p);
 }
 
 int specifier_var_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
         const char *p;
-        char *copy;
         int r;
 
         assert(ret);
@@ -454,12 +423,8 @@ int specifier_var_tmp_dir(char specifier, const void *data, const char *root, co
                 if (r < 0)
                         return r;
         }
-        copy = strdup(p);
-        if (!copy)
-                return -ENOMEM;
 
-        *ret = copy;
-        return 0;
+        return strdup_to(ret, p);
 }
 
 int specifier_escape_strv(char **l, char ***ret) {
index 9c7d24c0d6de107d0205006c840c16db4aa9fe9b..85f9463f9b5c5f1a2bcc69c4e6d8eabe4c2244a7 100644 (file)
@@ -200,3 +200,153 @@ static inline int run_test_table(void) {
         DEFINE_TEST_MAIN_FULL(log_level, intro, NULL)
 #define DEFINE_TEST_MAIN(log_level)                     \
         DEFINE_TEST_MAIN_FULL(log_level, NULL, NULL)
+
+#define ASSERT_OK(expr)                                                                                         \
+        ({                                                                                                      \
+                typeof(expr) _result = (expr);                                                                  \
+                if (_result < 0) {                                                                              \
+                        log_error_errno(_result, "%s:%i: Assertion failed: %s: %m",                             \
+                                        PROJECT_FILE, __LINE__, #expr);                                         \
+                        abort();                                                                                \
+                }                                                                                               \
+         })
+
+#define ASSERT_TRUE(expr)                                                                                       \
+        ({                                                                                                      \
+                if (!(expr)) {                                                                                  \
+                        log_error("%s:%i: Assertion failed: expected \"%s\" to be true",                        \
+                                  PROJECT_FILE, __LINE__, #expr);                                               \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_FALSE(expr)                                                                                      \
+        ({                                                                                                      \
+                if ((expr)) {                                                                                   \
+                        log_error("%s:%i: Assertion failed: expected \"%s\" to be false",                       \
+                                  PROJECT_FILE, __LINE__, #expr);                                               \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_NULL(expr)                                                                                       \
+        ({                                                                                                      \
+                if ((expr) != NULL) {                                                                           \
+                        log_error("%s:%i: Assertion failed: expected \"%s\" to be NULL",                        \
+                                  PROJECT_FILE, __LINE__, #expr);                                               \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_NOT_NULL(expr)                                                                                   \
+        ({                                                                                                      \
+                if ((expr) == NULL) {                                                                           \
+                        log_error("%s:%i: Assertion failed: expected \"%s\" to be not NULL",                    \
+                                  PROJECT_FILE, __LINE__, #expr);                                               \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_STREQ(expr1, expr2)                                                                              \
+        ({                                                                                                      \
+                const char* _expr1 = (expr1);                                                                   \
+                const char* _expr2 = (expr2);                                                                   \
+                if (strcmp(_expr1, _expr2) != 0) {                                                              \
+                        log_error("%s:%i: Assertion failed: expected \"%s == %s\", but \"%s != %s\"",           \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _expr1, _expr2);                      \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+/* DECIMAL_STR_FMT() uses _Generic which cannot be used in string concatenation so we have to format the
+ * input into strings first and then format those into the final assertion message. */
+
+#define ASSERT_EQ(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (_expr1 != _expr2) {                                                                         \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s == %s\", but \"%s != %s\"",           \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_GE(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (_expr1 < _expr2) {                                                                          \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s >= %s\", but \"%s < %s\"",            \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_LE(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (_expr1 > _expr2) {                                                                          \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s <= %s\", but \"%s > %s\"",            \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_NE(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (_expr1 == _expr2) {                                                                         \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s != %s\", but \"%s == %s\"",           \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_GT(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (!(_expr1 > _expr2)) {                                                                       \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s > %s\", but \"%s <= %s\"",            \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
+
+#define ASSERT_LT(expr1, expr2)                                                                                 \
+        ({                                                                                                      \
+                typeof(expr1) _expr1 = (expr1);                                                                 \
+                typeof(expr2) _expr2 = (expr2);                                                                 \
+                if (!(_expr1 < _expr2)) {                                                                       \
+                        char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))];                                           \
+                        char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))];                                           \
+                        xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1);                                     \
+                        xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2);                                     \
+                        log_error("%s:%i: Assertion failed: expected \"%s < %s\", but \"%s >= %s\"",            \
+                                  PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2);                    \
+                        abort();                                                                                \
+                }                                                                                               \
+        })
index 666dd970e6f0e2bad7543cccde491a150dbb4e40..203cf5fb3adcd5a42eafb5b221c577399df212ed 100644 (file)
@@ -5525,13 +5525,13 @@ int tpm2_unseal(Tpm2Context *c,
         if (r < 0)
                 return r;
 
-        _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
-        r = tpm2_make_encryption_session(c, primary_handle, hmac_key, &encryption_session);
-        if (r < 0)
-                return r;
-
         _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
         for (unsigned i = RETRY_UNSEAL_MAX;; i--) {
+                _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
+                r = tpm2_make_encryption_session(c, primary_handle, hmac_key, &encryption_session);
+                if (r < 0)
+                        return r;
+
                 _cleanup_(tpm2_handle_freep) Tpm2Handle *policy_session = NULL;
                 _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
                 r = tpm2_make_policy_session(
index 6c107c53fa88dbd6055e945a45255d0a0c0b2a03..d4072ec398281508392fd0b31905f835a72cff8a 100644 (file)
@@ -3377,7 +3377,7 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret)
         }
 
         _cleanup_free_ char *desc = NULL;
-        if (asprintf(&desc, "%s-%i", server->description ?: "varlink", v->fd) >= 0)
+        if (asprintf(&desc, "%s-%i", varlink_server_description(server), v->fd) >= 0)
                 v->description = TAKE_PTR(desc);
 
         /* Link up the server and the connection, and take reference in both directions. Note that the
index 613e88dd194f699535fd85221a6cb053f894f17f..5e037835435501060e8292b01b11ffa984e64800 100644 (file)
@@ -108,8 +108,9 @@ static int make_sshd_template_unit(
                         "Description=OpenSSH Per-Connection Server Daemon\n"
                         "Documentation=man:systemd-ssh-generator(8) man:sshd(8)\n"
                         "[Service]\n"
-                        "ExecStart=-%s -i\n"
-                        "StandardInput=socket",
+                        "ExecStart=-%s -i -o \"AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys\"\n"
+                        "StandardInput=socket\n"
+                        "ImportCredential=ssh.ephemeral-authorized_keys-all",
                         sshd_binary);
 
                 r = fflush_and_check(f);
index b071623780a7d5076464ce0d865e1f3fb2b39558..52f4a47aa1f5aec8281743e46b94c27aa6df752a 100644 (file)
@@ -1642,7 +1642,7 @@ static int item_equivalent(Item *a, Item *b) {
 
         const char *a_shell = pick_shell(a),
                    *b_shell = pick_shell(b);
-        if (!path_equal_ptr(a_shell, b_shell) &&
+        if (!path_equal(a_shell, b_shell) &&
             !(is_nologin_shell(a_shell) && is_nologin_shell(b_shell))) {
                 _cleanup_free_ char *pa = NULL, *pb = NULL;
 
index d43fee156bfb18891521b9ad1ec5636eee0a3ef8..571d966ca0049b7c49cfd493444b0ec672790902 100644 (file)
@@ -148,6 +148,7 @@ simple_tests += files(
         'test-psi-util.c',
         'test-ratelimit.c',
         'test-raw-clone.c',
+        'test-recovery-key.c',
         'test-recurse-dir.c',
         'test-replace-var.c',
         'test-rlimit-util.c',
index cb5a981dc3c0871fa528dc0d2a52c8fd0226bf45..4e7805b40a5db2f275a8b72792390d501437bf68 100644 (file)
@@ -328,12 +328,13 @@ TEST(shift_path) {
 
 TEST(mask_supported, .sd_booted = true) {
         CGroupMask m;
-        CGroupController c;
 
         assert_se(cg_mask_supported(&m) >= 0);
 
-        for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++)
-                printf("'%s' is supported: %s\n", cgroup_controller_to_string(c), yes_no(m & CGROUP_CONTROLLER_TO_MASK(c)));
+        for (CGroupController c = 0; c < _CGROUP_CONTROLLER_MAX; c++)
+                printf("'%s' is supported: %s\n",
+                       cgroup_controller_to_string(c),
+                       yes_no(m & CGROUP_CONTROLLER_TO_MASK(c)));
 }
 
 TEST(is_cgroup_fs, .sd_booted = true) {
@@ -392,7 +393,7 @@ TEST(cg_tests) {
 TEST(cg_get_keyed_attribute) {
         _cleanup_free_ char *val = NULL;
         char *vals3[3] = {}, *vals3a[3] = {};
-        int i, r;
+        int r;
 
         r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val);
         if (IN_SET(r, -ENOMEDIUM, -ENOENT) || ERRNO_IS_PRIVILEGE(r)) {
@@ -430,7 +431,7 @@ TEST(cg_get_keyed_attribute) {
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
                                          STRV_MAKE("usage_usec", "user_usec", "system_usec"), vals3) == 0);
-        for (i = 0; i < 3; i++)
+        for (size_t i = 0; i < 3; i++)
                 free(vals3[i]);
 
         assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
@@ -440,7 +441,7 @@ TEST(cg_get_keyed_attribute) {
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
                                          STRV_MAKE("system_usec", "user_usec", "usage_usec"), vals3a) == 0);
-        for (i = 0; i < 3; i++)
+        for (size_t i = 0; i < 3; i++)
                 free(vals3a[i]);
 
         assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat",
@@ -448,7 +449,7 @@ TEST(cg_get_keyed_attribute) {
         log_info("cpu /init.scope cpu.stat [system_usec user_usec usage_usec] → \"%s\", \"%s\", \"%s\"",
                  vals3a[0], vals3a[1], vals3a[2]);
 
-        for (i = 0; i < 3; i++) {
+        for (size_t i = 0; i < 3; i++) {
                 free(vals3[i]);
                 free(vals3a[i]);
         }
index 57cd77d4e506ec2aa471f79a3d0216f4b234fd24..868b862dc7acda93f7cda0974399c0136ac9a9d0 100644 (file)
@@ -188,13 +188,13 @@ _unused_ static void test_compress_stream(const char *compression,
 
         log_debug("/* create source from %s */", srcfile);
 
-        assert_se((src = open(srcfile, O_RDONLY|O_CLOEXEC)) >= 0);
+        ASSERT_OK((src = open(srcfile, O_RDONLY|O_CLOEXEC)));
 
         log_debug("/* test compression */");
 
         assert_se((dst = mkostemp_safe(pattern)) >= 0);
 
-        assert_se(compress(src, dst, -1, &uncompressed_size) >= 0);
+        ASSERT_OK(compress(src, dst, -1, &uncompressed_size));
 
         if (cat) {
                 assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
index fa5923eb2777212aba948e4480312524bd28f4a0..825aac65080db8fe9f0c454474a908360240ba8d 100644 (file)
@@ -34,15 +34,15 @@ TEST(gpt_types_against_architectures) {
                                 printf("%s %s\n", GREEN_CHECK_MARK(), joined);
 
                                 if (streq(prefix, "root-") && streq(suffix, ""))
-                                        assert_se(type.designator == PARTITION_ROOT);
+                                        ASSERT_EQ(type.designator, PARTITION_ROOT);
                                 if (streq(prefix, "root-") && streq(suffix, "-verity"))
-                                        assert_se(type.designator == PARTITION_ROOT_VERITY);
+                                        ASSERT_EQ(type.designator, PARTITION_ROOT_VERITY);
                                 if (streq(prefix, "usr-") && streq(suffix, ""))
-                                        assert_se(type.designator == PARTITION_USR);
+                                        ASSERT_EQ(type.designator, PARTITION_USR);
                                 if (streq(prefix, "usr-") && streq(suffix, "-verity"))
-                                        assert_se(type.designator == PARTITION_USR_VERITY);
+                                        ASSERT_EQ(type.designator, PARTITION_USR_VERITY);
 
-                                assert_se(type.arch == a);
+                                ASSERT_EQ(type.arch, a);
                         }
 }
 
@@ -72,38 +72,38 @@ TEST(type_alias_same) {
                 GptPartitionType x, y;
 
                 x = gpt_partition_type_from_uuid(t->uuid);                   /* search first by uuid */
-                assert_se(gpt_partition_type_from_string(t->name, &y) >= 0); /* search first by name */
+                ASSERT_GE(gpt_partition_type_from_string(t->name, &y), 0); /* search first by name */
 
-                assert_se(t->arch == x.arch);
-                assert_se(t->arch == y.arch);
-                assert_se(t->designator == x.designator);
-                assert_se(t->designator == y.designator);
+                ASSERT_EQ(t->arch, x.arch);
+                ASSERT_EQ(t->arch, y.arch);
+                ASSERT_EQ(t->designator, x.designator);
+                ASSERT_EQ(t->designator, y.designator);
         }
 }
 
 TEST(override_architecture) {
         GptPartitionType x, y;
 
-        assert_se(gpt_partition_type_from_string("root-x86-64", &x) >= 0);
-        assert_se(x.arch == ARCHITECTURE_X86_64);
+        ASSERT_GE(gpt_partition_type_from_string("root-x86-64", &x), 0);
+        ASSERT_EQ(x.arch, ARCHITECTURE_X86_64);
 
-        assert_se(gpt_partition_type_from_string("root-arm64", &y) >= 0);
-        assert(y.arch == ARCHITECTURE_ARM64);
+        ASSERT_GE(gpt_partition_type_from_string("root-arm64", &y), 0);
+        ASSERT_EQ(y.arch, ARCHITECTURE_ARM64);
 
         x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64);
-        assert_se(x.arch == y.arch);
-        assert_se(x.designator == y.designator);
+        ASSERT_EQ(x.arch, y.arch);
+        ASSERT_EQ(x.designator, y.designator);
         assert_se(sd_id128_equal(x.uuid, y.uuid));
         assert_se(streq(x.name, y.name));
 
         /* If the partition type does not have an architecture, nothing should change. */
 
-        assert_se(gpt_partition_type_from_string("esp", &x) >= 0);
+        ASSERT_GE(gpt_partition_type_from_string("esp", &x), 0);
         y = x;
 
         x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64);
-        assert_se(x.arch == y.arch);
-        assert_se(x.designator == y.designator);
+        ASSERT_EQ(x.arch, y.arch);
+        ASSERT_EQ(x.designator, y.designator);
         assert_se(sd_id128_equal(x.uuid, y.uuid));
         assert_se(streq(x.name, y.name));
 }
index 5daa0e64f6542d40a24882a5fadf39601de71402..cf4fca27e3f7aef5b55cf9658004d449eddff689 100644 (file)
@@ -42,7 +42,7 @@ TEST(trivial_compare_func) {
 }
 
 TEST(string_compare_func) {
-        assert_se(string_compare_func("fred", "wilma") != 0);
+        ASSERT_NE(string_compare_func("fred", "wilma"), 0);
         assert_se(string_compare_func("fred", "fred") == 0);
 }
 
index 1b788b191c0b76cf5c6106d095e38e29aa137d00..18c81adbcdbfbdb9df3a792be946561f11c10597 100644 (file)
@@ -19,7 +19,7 @@ TEST(hmac) {
                               "",
                               result);
         hex_result = hexmem(result, sizeof(result));
-        assert_se(streq_ptr(hex_result, "cadd5e42114351181f3abff477641d88efb57d2b5641a1e5c6d623363a6d3bad"));
+        ASSERT_STREQ(hex_result, "cadd5e42114351181f3abff477641d88efb57d2b5641a1e5c6d623363a6d3bad");
         hex_result = mfree(hex_result);
 
         hmac_sha256_by_string("waldo",
index c8dc91f9843f33b22837ee6a716da10c21a6f7c6..9d7ac18ba9a0dc10d015d011f8e497e89507f1d1 100644 (file)
@@ -66,7 +66,7 @@ static int get_dir_fd(const char *dir_path, mode_t mode) {
         assert(dir_path);
         dir_fd = RET_NERRNO(open_mkdir_at(AT_FDCWD, dir_path, O_CLOEXEC, mode));
         if (dir_fd < 0)
-                return log_error_errno(dir_fd, "Error occured while opening directory =>: %m");
+                return log_error_errno(dir_fd, "Error occurred while opening directory =>: %m");
 
         return dir_fd;
 }
@@ -91,7 +91,7 @@ static int labelling_op(int dir_fd, const char *text, const char *path, mode_t m
         /* Write data to the file*/
         count = RET_NERRNO(write(write_fd, text, strlen(text)));
         if (count < 0)
-                return log_error_errno(count, "Error occured while opening file for writing =>: %m");
+                return log_error_errno(count, "Error occurred while opening file for writing =>: %m");
         return 0;
 }
 
index 6d784a9ae83cc422d810a28ca5017e1376853346..affcaccc007fa8f961cb76f5808eb47565b792dd 100644 (file)
@@ -152,7 +152,7 @@ TEST(path_is_mount_point) {
          */
 
         /* file mountpoints */
-        assert_se(mkdtemp(tmp_dir) != NULL);
+        ASSERT_NOT_NULL(mkdtemp(tmp_dir));
         file1 = path_join(tmp_dir, "file1");
         assert_se(file1);
         file2 = path_join(tmp_dir, "file2");
index 84e55e175445bfc63cbb5b5354d7ef5f4484f0b5..e51ab9d29086bb28f7543e3f88e1bd683962cbeb 100644 (file)
 #include "tmpfile-util.h"
 
 TEST(path_is_os_tree) {
-        assert_se(path_is_os_tree("/") > 0);
-        assert_se(path_is_os_tree("/etc") == 0);
+        ASSERT_GT(path_is_os_tree("/"), 0);
+        ASSERT_EQ(path_is_os_tree("/etc"), 0);
         assert_se(path_is_os_tree("/idontexist") == -ENOENT);
 }
 
 TEST(parse_os_release) {
         /* Let's assume that we're running in a valid system, so os-release is available */
         _cleanup_free_ char *id = NULL, *id2 = NULL, *name = NULL, *foobar = NULL;
-        assert_se(parse_os_release(NULL, "ID", &id) == 0);
+        ASSERT_EQ(parse_os_release(NULL, "ID", &id), 0);
         log_info("ID: %s", id);
 
-        assert_se(setenv("SYSTEMD_OS_RELEASE", "/dev/null", 1) == 0);
-        assert_se(parse_os_release(NULL, "ID", &id2) == 0);
+        ASSERT_EQ(setenv("SYSTEMD_OS_RELEASE", "/dev/null", 1), 0);
+        ASSERT_EQ(parse_os_release(NULL, "ID", &id2), 0);
         log_info("ID: %s", strnull(id2));
 
         _cleanup_(unlink_tempfilep) char tmpfile[] = "/tmp/test-os-util.XXXXXX";
-        assert_se(write_tmpfile(tmpfile,
+        ASSERT_EQ(write_tmpfile(tmpfile,
                                 "ID=the-id  \n"
-                                "NAME=the-name") == 0);
+                                "NAME=the-name"), 0);
 
-        assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1) == 0);
-        assert_se(parse_os_release(NULL, "ID", &id, "NAME", &name) == 0);
+        ASSERT_EQ(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1), 0);
+        ASSERT_EQ(parse_os_release(NULL, "ID", &id, "NAME", &name), 0);
         log_info("ID: %s NAME: %s", id, name);
         assert_se(streq(id, "the-id"));
         assert_se(streq(name, "the-name"));
 
         _cleanup_(unlink_tempfilep) char tmpfile2[] = "/tmp/test-os-util.XXXXXX";
-        assert_se(write_tmpfile(tmpfile2,
+        ASSERT_EQ(write_tmpfile(tmpfile2,
                                 "ID=\"ignored\"  \n"
                                 "ID=\"the-id\"  \n"
-                                "NAME='the-name'") == 0);
+                                "NAME='the-name'"), 0);
 
-        assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile2, 1) == 0);
-        assert_se(parse_os_release(NULL, "ID", &id, "NAME", &name) == 0);
+        ASSERT_EQ(setenv("SYSTEMD_OS_RELEASE", tmpfile2, 1), 0);
+        ASSERT_EQ(parse_os_release(NULL, "ID", &id, "NAME", &name), 0);
         log_info("ID: %s NAME: %s", id, name);
         assert_se(streq(id, "the-id"));
         assert_se(streq(name, "the-name"));
 
-        assert_se(parse_os_release(NULL, "FOOBAR", &foobar) == 0);
+        ASSERT_EQ(parse_os_release(NULL, "FOOBAR", &foobar), 0);
         log_info("FOOBAR: %s", strnull(foobar));
-        assert_se(foobar == NULL);
+        ASSERT_NULL(foobar);
 
         assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);
 }
@@ -70,6 +70,7 @@ TEST(parse_extension_release) {
 
         assert_se(a = path_join(tempdir, "/usr/lib/extension-release.d/extension-release.test"));
         assert_se(mkdir_parents(a, 0777) >= 0);
+        ASSERT_GE(mkdir_parents(a, 0777), 0);
 
         r = write_string_file(a, "ID=the-id  \n VERSION_ID=the-version-id", WRITE_STRING_FILE_CREATE);
         if (r < 0)
@@ -87,42 +88,42 @@ TEST(parse_extension_release) {
         if (r < 0)
                 log_error_errno(r, "Failed to write file: %m");
 
-        assert_se(parse_extension_release(tempdir, IMAGE_CONFEXT, "tester", false, "ID", &id, "VERSION_ID", &version_id) == 0);
+        ASSERT_EQ(parse_extension_release(tempdir, IMAGE_CONFEXT, "tester", false, "ID", &id, "VERSION_ID", &version_id), 0);
         log_info("ID: %s VERSION_ID: %s", id, version_id);
         assert_se(streq(id, "the-id"));
         assert_se(streq(version_id, "the-version-id"));
 
         assert_se(parse_extension_release(tempdir, IMAGE_CONFEXT, "tester", false, "FOOBAR", &foobar) == 0);
         log_info("FOOBAR: %s", strnull(foobar));
-        assert_se(foobar == NULL);
+        ASSERT_NULL(foobar);
 
         assert_se(parse_extension_release(tempdir, IMAGE_SYSEXT, "test", false, "FOOBAR", &foobar) == 0);
         log_info("FOOBAR: %s", strnull(foobar));
-        assert_se(foobar == NULL);
+        ASSERT_NULL(foobar);
 }
 
 TEST(load_os_release_pairs) {
         _cleanup_(unlink_tempfilep) char tmpfile[] = "/tmp/test-os-util.XXXXXX";
-        assert_se(write_tmpfile(tmpfile,
+        ASSERT_EQ(write_tmpfile(tmpfile,
                                 "ID=\"ignored\"  \n"
                                 "ID=\"the-id\"  \n"
-                                "NAME='the-name'") == 0);
+                                "NAME='the-name'"), 0);
 
-        assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1) == 0);
+        ASSERT_EQ(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1), 0);
 
         _cleanup_strv_free_ char **pairs = NULL;
-        assert_se(load_os_release_pairs(NULL, &pairs) == 0);
+        ASSERT_EQ(load_os_release_pairs(NULL, &pairs), 0);
         assert_se(strv_equal(pairs, STRV_MAKE("ID", "the-id",
                                               "NAME", "the-name")));
 
-        assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);
+        ASSERT_EQ(unsetenv("SYSTEMD_OS_RELEASE"), 0);
 }
 
 TEST(os_release_support_ended) {
         int r;
 
-        assert_se(os_release_support_ended("1999-01-01", false, NULL) == true);
-        assert_se(os_release_support_ended("2037-12-31", false, NULL) == false);
+        ASSERT_TRUE(os_release_support_ended("1999-01-01", false, NULL));
+        ASSERT_FALSE(os_release_support_ended("2037-12-31", false, NULL));
         assert_se(os_release_support_ended("-1-1-1", true, NULL) == -EINVAL);
 
         r = os_release_support_ended(NULL, false, NULL);
index ca11bf3a29c854073bc031f1e9dd9d3c9fde252e..5f36ae49f05ff3e7f9fc7ab10c0e11aa14836044 100644 (file)
@@ -23,7 +23,7 @@ TEST(print_paths) {
 }
 
 TEST(path) {
-        assert_se(path_is_absolute("/"));
+        assert_se( path_is_absolute("/"));
         assert_se(!path_is_absolute("./"));
 
         assert_se(streq(basename("./aa/bb/../file.da."), "file.da."));
@@ -31,17 +31,19 @@ TEST(path) {
         assert_se(streq(basename("/aa///file..."), "file..."));
         assert_se(streq(basename("file.../"), ""));
 
-        assert_se(PATH_IN_SET("/bin", "/", "/bin", "/foo"));
-        assert_se(PATH_IN_SET("/bin", "/bin"));
-        assert_se(PATH_IN_SET("/bin", "/foo/bar", "/bin"));
-        assert_se(PATH_IN_SET("/", "/", "/", "/foo/bar"));
+        assert_se( PATH_IN_SET("/bin", "/", "/bin", "/foo"));
+        assert_se( PATH_IN_SET("/bin", "/bin"));
+        assert_se( PATH_IN_SET("/bin", "/foo/bar", "/bin"));
+        assert_se( PATH_IN_SET("/", "/", "/", "/foo/bar"));
         assert_se(!PATH_IN_SET("/", "/abc", "/def"));
 
-        assert_se(path_equal_ptr(NULL, NULL));
-        assert_se(path_equal_ptr("/a", "/a"));
-        assert_se(!path_equal_ptr("/a", "/b"));
-        assert_se(!path_equal_ptr("/a", NULL));
-        assert_se(!path_equal_ptr(NULL, "/a"));
+        assert_se( path_equal(NULL, NULL));
+        assert_se( path_equal("/a", "/a"));
+        assert_se(!path_equal("/a", "/b"));
+        assert_se(!path_equal("/a", NULL));
+        assert_se(!path_equal(NULL, "/a"));
+        assert_se(!path_equal("a", NULL));
+        assert_se(!path_equal(NULL, "a"));
 }
 
 TEST(is_path) {
@@ -506,24 +508,24 @@ TEST(prefixes) {
                 log_error("---%s---", s);
                 assert_se(streq(s, values[i++]));
         }
-        assert_se(values[i] == NULL);
+        ASSERT_NULL(values[i]);
 
         i = 1;
         PATH_FOREACH_PREFIX(s, "/a/b/c/d") {
                 log_error("---%s---", s);
                 assert_se(streq(s, values[i++]));
         }
-        assert_se(values[i] == NULL);
+        ASSERT_NULL(values[i]);
 
         i = 0;
         PATH_FOREACH_PREFIX_MORE(s, "////a////b////c///d///////")
                 assert_se(streq(s, values[i++]));
-        assert_se(values[i] == NULL);
+        ASSERT_NULL(values[i]);
 
         i = 1;
         PATH_FOREACH_PREFIX(s, "////a////b////c///d///////")
                 assert_se(streq(s, values[i++]));
-        assert_se(values[i] == NULL);
+        ASSERT_NULL(values[i]);
 
         PATH_FOREACH_PREFIX(s, "////")
                 assert_not_reached();
@@ -759,11 +761,11 @@ static void test_prefix_root_one(const char *r, const char *p, const char *expec
         const char *t;
 
         assert_se(s = path_join(r, p));
-        assert_se(path_equal_ptr(s, expected));
+        assert_se(path_equal(s, expected));
 
         t = prefix_roota(r, p);
         assert_se(t);
-        assert_se(path_equal_ptr(t, expected));
+        assert_se(path_equal(t, expected));
 }
 
 TEST(prefix_root) {
index 52b2bc861e8a8e8b6bf4a89e23acdf0709295621..9ab52c60129f168f9a4f6e5bdcee7dbf05fb63ef 100644 (file)
@@ -22,7 +22,7 @@ static void test_draw_cylon_one(unsigned pos) {
 
         memset(buf, 0xff, sizeof(buf));
         draw_cylon(buf, sizeof(buf), CYLON_WIDTH, pos);
-        assert_se(strlen(buf) < sizeof(buf));
+        ASSERT_LE(strlen(buf), sizeof(buf));
 }
 
 TEST(draw_cylon) {
diff --git a/src/test/test-recovery-key.c b/src/test/test-recovery-key.c
new file mode 100644 (file)
index 0000000..2e901dc
--- /dev/null
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <string.h>
+
+#include "memory-util.h"
+#include "random-util.h"
+#include "recovery-key.h"
+#include "tests.h"
+
+TEST(make_recovery_key) {
+        _cleanup_(erase_and_freep) char *recovery_key = NULL;
+        size_t length;
+        const size_t num_test = 10;
+        char *generated_keys[num_test];
+        int r;
+
+        /* Check for successful recovery-key creation */
+        r = make_recovery_key(&recovery_key);
+        assert_se(r == 0);
+        ASSERT_NOT_NULL(recovery_key);
+
+        /* Check that length of formatted key is 72 with 64 modhex characters */
+        length = strlen(recovery_key);
+        assert_se(length == RECOVERY_KEY_MODHEX_FORMATTED_LENGTH - 1);
+        /* Check modhex characters in formatted key with dashes */
+        for (size_t i = 0; i < length; i++) {
+                assert_se((recovery_key[i] >= 'a' && recovery_key[i] <= 'v') || recovery_key[i] == '-');
+                if (i % 9 == 8)
+                        /* confirm '-' is after every 8 characters */
+                        assert_se(recovery_key[i] == '-');
+        }
+        /* Repeat tests to determine randomness of generated keys */
+        for (size_t test = 0; test < num_test; ++test) {
+                r = make_recovery_key(&generated_keys[test]);
+                assert_se(r == 0);
+                length = strlen(generated_keys[test]);
+                assert_se(length == RECOVERY_KEY_MODHEX_FORMATTED_LENGTH - 1);
+                for (size_t i = 0; i < length; i++) {
+                        assert_se((generated_keys[test][i] >= 'a' && generated_keys[test][i] <= 'v')
+                                || generated_keys[test][i] == '-');
+                        if (i % 9 == 8)
+                                assert_se(generated_keys[test][i] == '-');
+                }
+                /* Check for uniqueness of each generated recovery key */
+                for (size_t prev = 0; prev < test; ++prev)
+                        assert_se(!streq(generated_keys[test], generated_keys[prev]));
+        }
+        for (size_t i = 0; i < num_test; i++)
+                free(generated_keys[i]);
+}
+
+TEST(decode_modhex_char) {
+
+        assert_se(decode_modhex_char('c') == 0);
+        assert_se(decode_modhex_char('C') == 0);
+        assert_se(decode_modhex_char('b') == 1);
+        assert_se(decode_modhex_char('B') == 1);
+        assert_se(decode_modhex_char('d') == 2);
+        assert_se(decode_modhex_char('D') == 2);
+        assert_se(decode_modhex_char('e') == 3);
+        assert_se(decode_modhex_char('E') == 3);
+        assert_se(decode_modhex_char('f') == 4);
+        assert_se(decode_modhex_char('F') == 4);
+        assert_se(decode_modhex_char('g') == 5);
+        assert_se(decode_modhex_char('G') == 5);
+        assert_se(decode_modhex_char('h') == 6);
+        assert_se(decode_modhex_char('H') == 6);
+        assert_se(decode_modhex_char('i') == 7);
+        assert_se(decode_modhex_char('I') == 7);
+        assert_se(decode_modhex_char('j') == 8);
+        assert_se(decode_modhex_char('J') == 8);
+        assert_se(decode_modhex_char('k') == 9);
+        assert_se(decode_modhex_char('K') == 9);
+        assert_se(decode_modhex_char('l') == 10);
+        assert_se(decode_modhex_char('L') == 10);
+        assert_se(decode_modhex_char('n') == 11);
+        assert_se(decode_modhex_char('N') == 11);
+        assert_se(decode_modhex_char('r') == 12);
+        assert_se(decode_modhex_char('R') == 12);
+        assert_se(decode_modhex_char('t') == 13);
+        assert_se(decode_modhex_char('T') == 13);
+        assert_se(decode_modhex_char('u') == 14);
+        assert_se(decode_modhex_char('U') == 14);
+        assert_se(decode_modhex_char('v') == 15);
+        assert_se(decode_modhex_char('V') == 15);
+        assert_se(decode_modhex_char('a') == -EINVAL);
+        assert_se(decode_modhex_char('A') == -EINVAL);
+        assert_se(decode_modhex_char('x') == -EINVAL);
+        assert_se(decode_modhex_char('.') == -EINVAL);
+        assert_se(decode_modhex_char('/') == -EINVAL);
+        assert_se(decode_modhex_char('\0') == -EINVAL);
+}
+
+TEST(normalize_recovery_key) {
+        _cleanup_(erase_and_freep) char *normalized_key1 = NULL;
+        _cleanup_(erase_and_freep) char *normalized_key2 = NULL;
+        _cleanup_(erase_and_freep) char *normalized_key3 = NULL;
+        int r;
+
+        /* Case 1: Normalization without dashes */
+        r = normalize_recovery_key("cdefghijcdefghijcdefghijcdefghijcdefghijcdefghijcdefghijcdefghij",
+                        &normalized_key1);
+        assert(r == 0);
+        assert(streq(normalized_key1, "cdefghij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghij"));
+
+        /* Case 2: Normalization with dashes */
+        r = normalize_recovery_key("cdefVhij-cDefghij-cdefkhij-cdufghij-cdefgdij-cidefIhj-cdefNijR-cdVfguij",
+                        &normalized_key2);
+        assert_se(r == 0);
+        assert_se(streq(normalized_key2, "cdefvhij-cdefghij-cdefkhij-cdufghij-cdefgdij-cidefihj-cdefnijr-cdvfguij"));
+
+        /* Case 3: Invalid password length */
+        r = normalize_recovery_key("1234-5678-90AB-CDEF-1234-5678-90AB-CDEF", &normalized_key1);
+        assert(r == -EINVAL);
+
+        /* Case 4: Invalid password format(missing dash) */
+        r = normalize_recovery_key("cdefghij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghijcdefghij",
+                        &normalized_key1);
+        assert_se(r == -EINVAL);
+
+        /* Case 5: Normalization of Upper cases password without dashes */
+        r = normalize_recovery_key("BFGHICEHHIUVLKJIHFHEDlntruvcdefjiTUVKLNIJVTUTKJIHDFBCBGHIJHHFDBC",
+                        &normalized_key3);
+        assert(r == 0);
+        assert_se(streq(normalized_key3, "bfghiceh-hiuvlkji-hfhedlnt-ruvcdefj-ituvklni-jvtutkji-hdfbcbgh-ijhhfdbc"));
+
+        /* Case 6: Minimum password length */
+        r = normalize_recovery_key("", &normalized_key1);
+        assert_se(r == -EINVAL);
+
+        /* Case 7: Invalid characters and numbers in password */
+        r = normalize_recovery_key("cde123hi-cdefgzij-cdefghij-cdefghij-cdefghij-cdefghij-cdefghijcdefghij",
+                        &normalized_key1);
+        assert_se(r == -EINVAL);
+}
+
+DEFINE_TEST_MAIN(LOG_INFO);
index 92f1083a4c5047b2958fea1f17dfcef216ae91fc..3b003e885f0d3af249d40b0014c3a1674f068cc4 100644 (file)
@@ -88,6 +88,35 @@ TEST(free_and_strndup) {
         }
 }
 
+TEST(strdup_to_full) {
+        _cleanup_free_ char *dst;
+
+        assert_se(strdup_to_full(NULL, NULL) == 0);
+        assert_se(strdup_to_full(&dst, NULL) == 0);
+
+        assert_se(strdup_to_full(NULL, "") == 1);
+        assert_se(strdup_to_full(&dst, "") == 1);
+        assert_se(streq_ptr(dst, ""));
+        dst = mfree(dst);
+
+        assert_se(strdup_to_full(NULL, "x") == 1);
+        assert_se(strdup_to_full(&dst, "x") == 1);
+        assert_se(streq_ptr(dst, "x"));
+}
+
+TEST(strdup_to) {
+        _cleanup_free_ char *dst;
+
+        assert_se(strdup_to(&dst, NULL) == 0);
+
+        assert_se(strdup_to(&dst, "") == 0);
+        assert_se(streq_ptr(dst, ""));
+        dst = mfree(dst);
+
+        assert_se(strdup_to(&dst, "x") == 0);
+        assert_se(streq_ptr(dst, "x"));
+}
+
 TEST(ascii_strcasecmp_n) {
         assert_se(ascii_strcasecmp_n("", "", 0) == 0);
         assert_se(ascii_strcasecmp_n("", "", 1) == 0);
index db76cde0a263c4b301b6cff11d64f35d595b8b52..f115a477738e67f5b7712cb640be6e272a8b26c0 100644 (file)
@@ -137,8 +137,8 @@ TEST(parse_uid) {
 }
 
 TEST(uid_ptr) {
-        assert_se(UID_TO_PTR(0) != NULL);
-        assert_se(UID_TO_PTR(1000) != NULL);
+        ASSERT_NOT_NULL(UID_TO_PTR(0));
+        ASSERT_NOT_NULL(UID_TO_PTR(1000));
 
         assert_se(PTR_TO_UID(UID_TO_PTR(0)) == 0);
         assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
index ff986b09d65f94d55ae7d1d71f66bd9e3aa4ab48..a8d27afa113e50618a296d980cd3a54edaa17857 100644 (file)
@@ -61,15 +61,12 @@ int start_transient_scope(sd_bus *bus, const char *machine_name, bool allow_pidf
                                   "AddRef",      "b",  1,
                                   "CollectMode", "s",  "inactive-or-failed");
 
-        if (allow_pidfd) {
-                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
-                r = pidref_set_pid(&pidref, getpid_cached());
-                if (r < 0)
-                        return log_error_errno(r, "Failed to allocate PID reference: %m");
+        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+        r = pidref_set_self(&pidref);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate PID reference: %m");
 
-                r = bus_append_scope_pidref(m, &pidref);
-        } else
-                r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, getpid_cached());
+        r = bus_append_scope_pidref(m, &pidref, allow_pidfd);
         if (r < 0)
                 return bus_log_create_error(r);
 
index 5ab0053be9142e27a48e2ce431d72875286a9048..8d2348d74872846d863cd5ba6a98b601785b80d2 100644 (file)
@@ -13,6 +13,7 @@
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "discover-image.h"
+#include "pidref.h"
 #include "sd-daemon.h"
 #include "sd-event.h"
 #include "sd-id128.h"
@@ -33,6 +34,7 @@
 #include "gpt.h"
 #include "hexdecoct.h"
 #include "hostname-util.h"
+#include "io-util.h"
 #include "kernel-image.h"
 #include "log.h"
 #include "machine-credential.h"
@@ -54,6 +56,7 @@
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "time-util.h"
 #include "tmpfile-util.h"
 #include "unit-name.h"
 #include "vmspawn-mount.h"
@@ -92,6 +95,8 @@ static sd_id128_t arg_uuid = {};
 static char **arg_kernel_cmdline_extra = NULL;
 static char **arg_extra_drives = NULL;
 static char *arg_background = NULL;
+static bool arg_pass_ssh_key = true;
+static char *arg_ssh_key_type = NULL;
 
 STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@@ -107,6 +112,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_forward_journal, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline_extra, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_extra_drives, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_background, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_ssh_key_type, freep);
 
 static int help(void) {
         _cleanup_free_ char *link = NULL;
@@ -158,6 +164,8 @@ static int help(void) {
                "\n%3$sIntegration:%4$s\n"
                "     --forward-journal=FILE|DIR\n"
                "                           Forward the VM's journal to the host\n"
+               "     --pass-ssh-key=BOOL   Create an SSH key to access the VM\n"
+               "     --ssh-key-type=TYPE   Choose what type of SSH key to pass\n"
                "\n%3$sInput/Output:%4$s\n"
                "     --console=MODE        Console mode (interactive, native, gui)\n"
                "     --background=COLOR    Set ANSI color for background\n"
@@ -200,6 +208,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SECURE_BOOT,
                 ARG_PRIVATE_USERS,
                 ARG_FORWARD_JOURNAL,
+                ARG_PASS_SSH_KEY,
+                ARG_SSH_KEY_TYPE,
                 ARG_SET_CREDENTIAL,
                 ARG_LOAD_CREDENTIAL,
                 ARG_FIRMWARE,
@@ -239,6 +249,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "secure-boot",       required_argument, NULL, ARG_SECURE_BOOT       },
                 { "private-users",     required_argument, NULL, ARG_PRIVATE_USERS     },
                 { "forward-journal",   required_argument, NULL, ARG_FORWARD_JOURNAL   },
+                { "pass-ssh-key",      required_argument, NULL, ARG_PASS_SSH_KEY      },
+                { "ssh-key-type",      required_argument, NULL, ARG_SSH_KEY_TYPE      },
                 { "set-credential",    required_argument, NULL, ARG_SET_CREDENTIAL    },
                 { "load-credential",   required_argument, NULL, ARG_LOAD_CREDENTIAL   },
                 { "firmware",          required_argument, NULL, ARG_FIRMWARE          },
@@ -442,6 +454,23 @@ static int parse_argv(int argc, char *argv[]) {
                                 return r;
                         break;
 
+                case ARG_PASS_SSH_KEY:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --pass-ssh-key= argument: %s", optarg);
+
+                        arg_pass_ssh_key = r;
+                        break;
+
+                case ARG_SSH_KEY_TYPE:
+                        if (!string_is_safe(optarg))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid value for --arg-ssh-key-type=: %s", optarg);
+
+                        r = free_and_strdup_warn(&arg_ssh_key_type, optarg);
+                        if (r < 0)
+                                return r;
+                        break;
+
                 case ARG_SET_CREDENTIAL: {
                         r = machine_credential_set(&arg_credentials, optarg);
                         if (r < 0)
@@ -1100,11 +1129,55 @@ static void set_window_title(PTYForward *f) {
         if (dot)
                 (void) pty_forward_set_title_prefix(f, dot);
 }
+static int generate_ssh_keypair(const char *key_path, const char *key_type) {
+        _cleanup_free_ char *ssh_keygen = NULL;
+        _cleanup_strv_free_ char **cmdline = NULL;
+        int r;
+
+        assert(key_path);
+
+        r = find_executable("ssh-keygen", &ssh_keygen);
+        if (r < 0)
+                return log_error_errno(r, "Failed to find ssh-keygen: %m");
+
+        cmdline = strv_new(ssh_keygen, "-f", key_path, /* don't encrypt the key */ "-N", "");
+        if (!cmdline)
+                return log_oom();
+
+        if (key_type) {
+                r = strv_extend_many(&cmdline, "-t", key_type);
+                if (r < 0)
+                        return log_oom();
+        }
+
+        if (DEBUG_LOGGING) {
+                _cleanup_free_ char *joined = quote_command_line(cmdline, SHELL_ESCAPE_EMPTY);
+                if (!joined)
+                        return log_oom();
+
+                log_debug("Executing: %s", joined);
+        }
+
+        r = safe_fork(
+                        ssh_keygen,
+                        FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO,
+                        NULL);
+        if (r < 0)
+                return r;
+        if (r == 0) {
+                execv(ssh_keygen, cmdline);
+                log_error_errno(errno, "Failed to execve %s: %m", ssh_keygen);
+                _exit(EXIT_FAILURE);
+        }
+
+        return 0;
+}
 
 static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
         _cleanup_(ovmf_config_freep) OvmfConfig *ovmf_config = NULL;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_free_ char *machine = NULL, *qemu_binary = NULL, *mem = NULL, *trans_scope = NULL, *kernel = NULL;
+        _cleanup_(rm_rf_physical_and_freep) char *ssh_private_key_path = NULL, *ssh_public_key_path = NULL;
         _cleanup_close_ int notify_sock_fd = -EBADF;
         _cleanup_strv_free_ char **cmdline = NULL;
         _cleanup_free_ int *pass_fds = NULL;
@@ -1683,6 +1756,46 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
                         return r;
         }
 
+        if (arg_pass_ssh_key) {
+                _cleanup_free_ char *scope_prefix = NULL, *privkey_path = NULL, *pubkey_path = NULL;
+                const char *key_type = arg_ssh_key_type ?: "ed25519";
+
+                r = unit_name_to_prefix(trans_scope, &scope_prefix);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+
+                privkey_path = strjoin(arg_runtime_directory, "/", scope_prefix, "-", key_type);
+                if (!privkey_path)
+                        return log_oom();
+
+                pubkey_path = strjoin(privkey_path, ".pub");
+                if (!pubkey_path)
+                        return log_oom();
+
+                r = generate_ssh_keypair(privkey_path, key_type);
+                if (r < 0)
+                        return r;
+
+                ssh_private_key_path = TAKE_PTR(privkey_path);
+                ssh_public_key_path = TAKE_PTR(pubkey_path);
+        }
+
+        if (ssh_public_key_path && ssh_private_key_path) {
+                _cleanup_free_ char *scope_prefix = NULL, *cred_path = NULL;
+
+                cred_path = strjoin("ssh.ephemeral-authorized_keys-all:", ssh_public_key_path);
+                if (!cred_path)
+                        return log_oom();
+
+                r = machine_credential_load(&arg_credentials, cred_path);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to load credential %s: %m", cred_path);
+
+                r = unit_name_to_prefix(trans_scope, &scope_prefix);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");
+        }
+
         if (ARCHITECTURE_SUPPORTS_SMBIOS)
                 FOREACH_ARRAY(cred, arg_credentials.credentials, arg_credentials.n_credentials) {
                         _cleanup_free_ char *cred_data_b64 = NULL;
index 48c871f5e818521d2bc60f26d5075c1e3a59f95a..0b5fec7d3fec31ab58ebf5001e219d71138385a0 100644 (file)
@@ -149,6 +149,19 @@ failed run, can be downloaded from the artifacts.tar.gz archive which will be
 reachable in the same URL parent directory as the logs.gz that gets linked on
 the Github CI status.
 
+The log URL can be derived following a simple algorithm, however the test
+completion timestamp is needed and it's not easy to find without access to the
+log itself. For example, a noble s390x job started on 2024-03-23 at 02:09:11
+will be stored at the following URL:
+
+https://autopkgtest.ubuntu.com/results/autopkgtest-noble-upstream-systemd-ci-systemd-ci/noble/s390x/s/systemd-upstream/20240323_020911_e8e88@/log.gz
+
+The 5 characters at the end of the last directory are not random, but the first
+5 characters of a SHA1 hash generated based on the set of parameters given to
+the build plus the completion timestamp, such as:
+
+$ echo -n 'systemd-upstream {"build-git": "https://salsa.debian.org/systemd-team/systemd.git#debian/master", "env": ["UPSTREAM_REPO=https://github.com/systemd/systemd.git", "CFLAGS=-O0", "DEB_BUILD_PROFILES=pkg.systemd.upstream noudeb", "TEST_UPSTREAM=1", "CONFFLAGS_UPSTREAM=--werror -Dslow-tests=true", "UPSTREAM_PULL_REQUEST=31444", "GITHUB_STATUSES_URL=https://api.github.com/repos/systemd/systemd/statuses/c27f600a1c47f10b22964eaedfb5e9f0d4279cd9"], "ppas": ["upstream-systemd-ci/systemd-ci"], "submit-time": "2024-02-27 17:06:27", "uuid": "02cd262f-af22-4f82-ac91-53fa5a9e7811"}' | sha1sum | cut -c1-5
+
 To add new dependencies or new binaries to the packages used during the tests,
 a merge request can be sent to: https://salsa.debian.org/systemd-team/systemd
 targeting the 'upstream-ci' branch.
index 42574ce8ea7cfecf782f179132f0359efa1c95df..f8f3a4b3e32cf3f521b3e44ece906004497dbe57 100755 (executable)
@@ -11,9 +11,6 @@ test_append_files() {
     local workspace="${1:?}"
     local dropin_dir
 
-    mkdir -p "$workspace/test-journals/"
-    cp -av "${TEST_BASE_DIR:?}/test-journals/"* "$workspace/test-journals/"
-
     image_install curl setterm unzstd
     image_install -o openssl
     # Necessary for RH-based systems, otherwise MHD fails with:
index d870d57dccf104f123db7f92302fa75c6b624f7a..2ee4a7533abff7a512fcec4845619f54f397f28f 100755 (executable)
@@ -8,9 +8,6 @@ NSPAWN_ARGUMENTS="--private-network"
 # shellcheck source=test/test-functions
 . "${TEST_BASE_DIR:?}/test-functions"
 
-# (Hopefully) a temporary workaround for https://github.com/systemd/systemd/issues/30573
-KERNEL_APPEND="${KERNEL_APPEND:-} SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_BURST=100"
-
 # Make sure vsock is available in the VM
 CID=$((RANDOM + 3))
 QEMU_OPTIONS+=" -device vhost-vsock-pci,guest-cid=$CID"
index b47fa612b15d13d5d54fcccd49ae4b06ee903da4..aadf37a139ea610050bdb9dc1b437782d5c513cf 100644 (file)
@@ -4,6 +4,7 @@ if install_tests
         foreach subdir : [
                 'auxv',
                 'journal-data',
+                'test-journals',
                 'units',
                 'test-execute',
                 'test-fstab-generator',
index 833f6093aae832090e1406352ac877718286037e..e1c0c0ae9c00554f8f9b9aa9e0892114abb29768 100755 (executable)
@@ -118,14 +118,12 @@ if [[ ${#ARGS[@]} -ne 0 ]]; then
         RESULTS["$test"]="$result"
         TIMES["$test"]="$SECONDS"
 
-        [[ "$result" -ne 0 ]] && FAILURES=$((FAILURES + 1))
-    done
-fi
-
-# Run clean-again, if requested, and if no tests failed
-if [[ $FAILURES -eq 0 && $CLEAN_AGAIN -eq 1 ]]; then
-    for test in "${!RESULTS[@]}"; do
-        test_run "$test" make -C "$test" clean-again
+        # Run clean-again here to free up space, if requested, and if the test succeeded
+        if [[ "$result" -ne 0 ]]; then
+            FAILURES=$((FAILURES + 1))
+        elif [[ $CLEAN_AGAIN -eq 1 ]]; then
+            test_run "$test" make -C "$test" clean-again
+        fi
     done
 fi
 
index b99580bfd84a8e6f69efee274220bcd81d9f133a..0c0ffa1545edcceea60ee99a2d4dfc65286fcceb 100644 (file)
@@ -3338,6 +3338,13 @@ test_cleanup_again() {
     [ -n "$TESTDIR" ] || return
     rm -rf "$TESTDIR/unprivileged-nspawn-root"
     [[ -n "$initdir" ]] && _umount_dir "$initdir"
+    # Test specific images are not reused, so delete them or we run out of disk space
+    if [[ -n "$IMAGE_PUBLIC" ]] && [ "$(basename "$IMAGE_PUBLIC")" != "default.img" ]; then
+        rm -vf "$IMAGE_PUBLIC"
+    fi
+    if [[ -n "$IMAGE_PRIVATE" ]] && [ "$(basename "$IMAGE_PRIVATE")" != "default.img" ]; then
+        rm -vf "$IMAGE_PRIVATE"
+    fi
 }
 
 test_create_image() {
index 2123b10152893758f4141564c25e4785b04d901f..479011ea78f43b81d0c162f281f30357ea67ba06 100755 (executable)
@@ -6,11 +6,11 @@ set -o pipefail
 JOURNAL_DIR="$(mktemp -d)"
 REMOTE_OUT="$(mktemp -d)"
 # tar on C8S doesn't support the --zstd option
-unzstd --stdout "/test-journals/afl-corrupted-journals.tar.zst" | tar -xC "$JOURNAL_DIR/"
+unzstd --stdout "/usr/lib/systemd/tests/testdata/test-journals/afl-corrupted-journals.tar.zst" | tar -xC "$JOURNAL_DIR/"
 while read -r file; do
     filename="${file##*/}"
     unzstd "$file" -o "$JOURNAL_DIR/${filename%*.zst}"
-done < <(find /test-journals/corrupted/ -name "*.zst")
+done < <(find /usr/lib/systemd/tests/testdata/test-journals/corrupted/ -name "*.zst")
 # First, try each of them sequentially. Skip this part when running with plain
 # QEMU, as it is excruciatingly slow
 # Note: we care only about exit code 124 (timeout) and special bash exit codes
index 2c0c50f5b83efbc7d33e1e8ad5506cb5804afb33..90d865cdf571c74f4dbbe30015e7bad84ec49660 100755 (executable)
@@ -244,7 +244,7 @@ JOURNAL_DIR="$(mktemp -d)"
 while read -r file; do
     filename="${file##*/}"
     unzstd "$file" -o "$JOURNAL_DIR/${filename%*.zst}"
-done < <(find /test-journals/no-rtc -name "*.zst")
+done < <(find /usr/lib/systemd/tests/testdata/test-journals/no-rtc -name "*.zst")
 
 journalctl --directory="$JOURNAL_DIR" --list-boots --output=json >/tmp/lb1
 diff -u /tmp/lb1 - <<'EOF'
@@ -275,3 +275,11 @@ hello
 world
 EOF
 rm -f "$CURSOR_FILE"
+
+# Check that --until works with --after-cursor and --lines/-n
+# See: https://github.com/systemd/systemd/issues/31776
+CURSOR_FILE="$(mktemp)"
+journalctl -q -n 0 --cursor-file="$CURSOR_FILE"
+TIMESTAMP="$(journalctl -q -n 1 --cursor="$(<"$CURSOR_FILE")" --output=short-unix | cut -d ' ' -f 1 | cut -d '.' -f 1)"
+[[ -z "$(journalctl -q -n 10 --after-cursor="$(<"$CURSOR_FILE")" --until "@$((TIMESTAMP - 3))")" ]]
+rm -f "$CURSOR_FILE"
index e1e4367cc63f5234038486790edf8a7669d8508c..10388d8526b1e59da0abe9179761899d075ac811 100755 (executable)
@@ -195,6 +195,8 @@ if ! systemd-detect-virt -cq; then
             bash -xec 'timeout 1s nc -6 -u -l ::1 9999; exit 42'
         systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
             bash -xec 'timeout 1s nc -4 -l 127.0.0.1 6666; exit 42'
+        systemd-run --wait -p SuccessExitStatus="1 2" --pipe -p SocketBindDeny=any \
+            bash -xec 'timeout 1s nc -l 127.0.0.1 9999; exit 42'
         # Consequently, we should succeed when binding to a socket on the allow list
         # and keep listening on it until we're killed by `timeout` (EC 124)
         systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
index 4bf9922ef3aec57b7ac69206284c674827491673..b20b39d762b97fce1ed9c7999982838e3430a073 100755 (executable)
@@ -42,13 +42,16 @@ mount -t tmpfs tmpfs /home -o size=290M
 
 # we enable --luks-discard= since we run our tests in a tight VM, hence don't
 # needlessly pressure for storage. We also set the cheapest KDF, since we don't
-# want to waste CI CPU cycles on it.
+# want to waste CI CPU cycles on it. We also effectively disable rate-limiting on
+# the user by allowing 1000 logins per second
 NEWPASSWORD=xEhErW0ndafV4s homectl create test-user \
            --disk-size=min \
            --luks-discard=yes \
            --image-path=/home/test-user.home \
            --luks-pbkdf-type=pbkdf2 \
-           --luks-pbkdf-time-cost=1ms
+           --luks-pbkdf-time-cost=1ms \
+           --rate-limit-interval=1s \
+           --rate-limit-burst=1000
 inspect test-user
 
 PASSWORD=xEhErW0ndafV4s homectl authenticate test-user
@@ -74,13 +77,19 @@ inspect test-user
 homectl deactivate test-user
 inspect test-user
 
+homectl update test-user --real-name "Offline test" --offline
+inspect test-user
+
 PASSWORD=xEhErW0ndafV4s homectl activate test-user
 inspect test-user
 
+# Ensure that the offline changes were propagated in
+grep "Offline test" /home/test-user/.identity
+
 homectl deactivate test-user
 inspect test-user
 
-PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Offline test"
+PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Inactive test"
 inspect test-user
 
 PASSWORD=xEhErW0ndafV4s homectl activate test-user
@@ -89,6 +98,37 @@ inspect test-user
 homectl deactivate test-user
 inspect test-user
 
+# Do some keyring tests, but only on real kernels, since keyring access inside of containers will fail
+# (See: https://github.com/systemd/systemd/issues/17606)
+if ! systemd-detect-virt -cq ; then
+        PASSWORD=xEhErW0ndafV4s homectl activate test-user
+        inspect test-user
+
+        # Key should now be in the keyring
+        homectl update test-user --real-name "Keyring Test"
+        inspect test-user
+
+        # These commands shouldn't use the keyring
+        (! timeout 5s homectl authenticate test-user )
+        (! NEWPASSWORD="foobar" timeout 5s homectl passwd test-user )
+
+        homectl lock test-user
+        inspect test-user
+
+        # Key should be gone from keyring
+        (! timeout 5s homectl update test-user --real-name "Keyring Test 2" )
+
+        PASSWORD=xEhErW0ndafV4s homectl unlock test-user
+        inspect test-user
+
+        # Key should have been re-instantiated into the keyring
+        homectl update test-user --real-name "Keyring Test 3"
+        inspect test-user
+
+        homectl deactivate test-user
+        inspect test-user
+fi
+
 # Do some resize tests, but only if we run on real kernels, as quota inside of containers will fail
 if ! systemd-detect-virt -cq ; then
     # grow while inactive
@@ -131,7 +171,9 @@ if ! systemd-detect-virt -cq ; then
            --luks-discard=yes \
            --image-path=/home/test-user2.home \
            --luks-pbkdf-type=pbkdf2 \
-           --luks-pbkdf-time-cost=1ms
+           --luks-pbkdf-time-cost=1ms \
+           --rate-limit-interval=1s \
+           --rate-limit-burst=1000
     inspect test-user2
 
     # activate second user
@@ -150,24 +192,24 @@ if ! systemd-detect-virt -cq ; then
     homectl rebalance
     inspect test-user
     inspect test-user2
+
+    wait_for_state test-user2 active
+    homectl deactivate test-user2
+    wait_for_state test-user2 inactive
+    homectl remove test-user2
 fi
 
 PASSWORD=xEhErW0ndafV4s homectl with test-user -- test ! -f /home/test-user/xyz
 (! PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz)
 PASSWORD=xEhErW0ndafV4s homectl with test-user -- touch /home/test-user/xyz
 PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz
-# CAREFUL adding more `homectl with` tests here. Auth can get rate-limited and cause the tests to fail.
+PASSWORD=xEhErW0ndafV4s homectl with test-user -- rm /home/test-user/xyz
+PASSWORD=xEhErW0ndafV4s homectl with test-user -- test ! -f /home/test-user/xyz
+(! PASSWORD=xEhErW0ndafV4s homectl with test-user -- test -f /home/test-user/xyz)
 
 wait_for_state test-user inactive
 homectl remove test-user
 
-if ! systemd-detect-virt -cq ; then
-    wait_for_state test-user2 active
-    homectl deactivate test-user2
-    wait_for_state test-user2 inactive
-    homectl remove test-user2
-fi
-
 # blob directory tests
 # See docs/USER_RECORD_BLOB_DIRS.md
 checkblob() {
@@ -196,6 +238,7 @@ dd if=/dev/urandom of=/tmp/external-toobig bs=1M count=65
 NEWPASSWORD=EMJuc3zQaMibJo homectl create blob-user \
            --disk-size=min --luks-discard=yes \
            --luks-pbkdf-type=pbkdf2 --luks-pbkdf-time-cost=1ms \
+           --rate-limit-interval=1s --rate-limit-burst=1000 \
            --uid=12345 \
            --blob=/tmp/blob1
 inspect blob-user
@@ -297,6 +340,16 @@ checkblob barely-fits /tmp/external-barely-fits
 (! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b файл=/tmp/external-test3 )
 (! PASSWORD=EMJuc3zQaMibJo homectl update blob-user -b special@chars=/tmp/external-test3 )
 
+# Make sure offline updates to blobs get propagated in
+homectl deactivate blob-user
+inspect blob-user
+homectl update blob-user --offline -b barely-fits= -b propagated=/tmp/external-test3
+inspect blob-user
+PASSWORD=EMJuc3zQaMibJo homectl activate blob-user
+inspect blob-user
+(! checkblob barely-fits /tmp/external-barely-fits )
+checkblob propagated /tmp/external-test3
+
 homectl deactivate blob-user
 wait_for_state blob-user inactive
 homectl remove blob-user
@@ -466,6 +519,8 @@ if command -v ssh &>/dev/null && command -v sshd &>/dev/null && ! [[ -v ASAN_OPT
                        --luks-discard=yes \
                        --luks-pbkdf-type=pbkdf2 \
                        --luks-pbkdf-time-cost=1ms \
+                       --rate-limit-interval=1s \
+                       --rate-limit-burst=1000 \
                        --enforce-password-policy=no \
                        --ssh-authorized-keys=@/tmp/homed.id_ecdsa.pub \
                        --stop-delay=0 \
index a94776eadd1f6fb9541546b9f07e6f96f04044c4..4f3c967e2cf249617f1b5b6d995e1f1f3c6bf00f 100755 (executable)
@@ -231,15 +231,15 @@ assert_eq "$KVER" "$UNIT_KVER"
 umount /proc/version
 rm -f "$TMP_KVER"
 
-# Check that invoking the tool under the uid0 alias name works
-uid0 ls /
-assert_eq "$(uid0 echo foo)" "foo"
+# Check that invoking the tool under the run0 alias name works
+run0 ls /
+assert_eq "$(run0 echo foo)" "foo"
 # Check if we set some expected environment variables
 for arg in "" "--user=root" "--user=testuser"; do
-    assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_USER')" "$USER"
-    assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_UID')" "$(id -u "$USER")"
-    assert_eq "$(uid0 ${arg:+"$arg"} bash -c 'echo $SUDO_GID')" "$(id -u "$USER")"
+    assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_USER')" "$USER"
+    assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_UID')" "$(id -u "$USER")"
+    assert_eq "$(run0 ${arg:+"$arg"} bash -c 'echo $SUDO_GID')" "$(id -u "$USER")"
 done
-# Let's chain a couple of uid0 calls together, for fun
-readarray -t cmdline < <(printf "%.0suid0\n" {0..31})
+# Let's chain a couple of run0 calls together, for fun
+readarray -t cmdline < <(printf "%.0srun0\n" {0..31})
 assert_eq "$("${cmdline[@]}" bash -c 'echo $SUDO_USER')" "$USER"
diff --git a/tools/check-efi-alignment.py b/tools/check-efi-alignment.py
new file mode 100755 (executable)
index 0000000..bb33ac0
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# vi: set tw=110 sw=4 ts=4 et:
+
+import sys
+
+import pefile
+
+
+def main():
+    pe = pefile.PE(sys.argv[1], fast_load=True)
+
+    for section in pe.sections:
+        name = section.Name.rstrip(b"\x00").decode()
+        file_addr = section.PointerToRawData
+        virt_addr = section.VirtualAddress
+        print(f"{name:10s} file=0x{file_addr:08x} virt=0x{virt_addr:08x}")
+
+        if file_addr % 512 != 0:
+            print(f"File address of {name} section is not aligned to 512 bytes", file=sys.stderr)
+            return 1
+
+        if virt_addr % 512 != 0:
+            print(f"Virt address of {name} section is not aligned to 512 bytes", file=sys.stderr)
+            return 1
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print(f"Usage: {sys.argv[0]} pe-image")
+        sys.exit(1)
+
+    sys.exit(main())
index 819584dcbab0de5518b09f2a9e8317587c5ec47f..db95a58950d96649eaa3d5e6e6014cfbeb2eac85 100755 (executable)
@@ -36,6 +36,8 @@ def main():
     args = parser.parse_args()
 
     args.output.mkdir(exist_ok=True)
+    # Make sure we don't inherit any setgid/setuid bit or such.
+    args.output.chmod(mode=0o755)
     for exe in args.executables:
         extract_interfaces_xml(args.output, exe)
 
index 5411a023411b14662ba7a300ede6584a8f4afa23..cb1a284a601020373dd74a8d66ab99543d8ebf3f 100755 (executable)
@@ -26,6 +26,7 @@ import hashlib
 import io
 import os
 import pathlib
+import sys
 import time
 import typing
 from ctypes import (
@@ -55,26 +56,26 @@ from elftools.elf.relocation import (
 
 class PeCoffHeader(LittleEndianStructure):
     _fields_ = (
-        ("Machine", c_uint16),
-        ("NumberOfSections", c_uint16),
-        ("TimeDateStamp", c_uint32),
+        ("Machine",              c_uint16),
+        ("NumberOfSections",     c_uint16),
+        ("TimeDateStamp",        c_uint32),
         ("PointerToSymbolTable", c_uint32),
-        ("NumberOfSymbols", c_uint32),
+        ("NumberOfSymbols",      c_uint32),
         ("SizeOfOptionalHeader", c_uint16),
-        ("Characteristics", c_uint16),
+        ("Characteristics",      c_uint16),
     )
 
 
 class PeDataDirectory(LittleEndianStructure):
     _fields_ = (
         ("VirtualAddress", c_uint32),
-        ("Size", c_uint32),
+        ("Size",           c_uint32),
     )
 
 
 class PeRelocationBlock(LittleEndianStructure):
     _fields_ = (
-        ("PageRVA", c_uint32),
+        ("PageRVA",   c_uint32),
         ("BlockSize", c_uint32),
     )
 
@@ -86,62 +87,62 @@ class PeRelocationBlock(LittleEndianStructure):
 class PeRelocationEntry(LittleEndianStructure):
     _fields_ = (
         ("Offset", c_uint16, 12),
-        ("Type", c_uint16, 4),
+        ("Type",   c_uint16, 4),
     )
 
 
 class PeOptionalHeaderStart(LittleEndianStructure):
     _fields_ = (
-        ("Magic", c_uint16),
-        ("MajorLinkerVersion", c_uint8),
-        ("MinorLinkerVersion", c_uint8),
-        ("SizeOfCode", c_uint32),
-        ("SizeOfInitializedData", c_uint32),
+        ("Magic",                   c_uint16),
+        ("MajorLinkerVersion",      c_uint8),
+        ("MinorLinkerVersion",      c_uint8),
+        ("SizeOfCode",              c_uint32),
+        ("SizeOfInitializedData",   c_uint32),
         ("SizeOfUninitializedData", c_uint32),
-        ("AddressOfEntryPoint", c_uint32),
-        ("BaseOfCode", c_uint32),
+        ("AddressOfEntryPoint",     c_uint32),
+        ("BaseOfCode",              c_uint32),
     )
 
 
 class PeOptionalHeaderMiddle(LittleEndianStructure):
     _fields_ = (
-        ("SectionAlignment", c_uint32),
-        ("FileAlignment", c_uint32),
+        ("SectionAlignment",            c_uint32),
+        ("FileAlignment",               c_uint32),
         ("MajorOperatingSystemVersion", c_uint16),
         ("MinorOperatingSystemVersion", c_uint16),
-        ("MajorImageVersion", c_uint16),
-        ("MinorImageVersion", c_uint16),
-        ("MajorSubsystemVersion", c_uint16),
-        ("MinorSubsystemVersion", c_uint16),
-        ("Win32VersionValue", c_uint32),
-        ("SizeOfImage", c_uint32),
-        ("SizeOfHeaders", c_uint32),
-        ("CheckSum", c_uint32),
-        ("Subsystem", c_uint16),
-        ("DllCharacteristics", c_uint16),
+        ("MajorImageVersion",           c_uint16),
+        ("MinorImageVersion",           c_uint16),
+        ("MajorSubsystemVersion",       c_uint16),
+        ("MinorSubsystemVersion",       c_uint16),
+        ("Win32VersionValue",           c_uint32),
+        ("SizeOfImage",                 c_uint32),
+        ("SizeOfHeaders",               c_uint32),
+        ("CheckSum",                    c_uint32),
+        ("Subsystem",                   c_uint16),
+        ("DllCharacteristics",          c_uint16),
     )
 
 
 class PeOptionalHeaderEnd(LittleEndianStructure):
     _fields_ = (
-        ("LoaderFlags", c_uint32),
-        ("NumberOfRvaAndSizes", c_uint32),
-        ("ExportTable", PeDataDirectory),
-        ("ImportTable", PeDataDirectory),
-        ("ResourceTable", PeDataDirectory),
-        ("ExceptionTable", PeDataDirectory),
-        ("CertificateTable", PeDataDirectory),
-        ("BaseRelocationTable", PeDataDirectory),
-        ("Debug", PeDataDirectory),
-        ("Architecture", PeDataDirectory),
-        ("GlobalPtr", PeDataDirectory),
-        ("TLSTable", PeDataDirectory),
-        ("LoadConfigTable", PeDataDirectory),
-        ("BoundImport", PeDataDirectory),
-        ("IAT", PeDataDirectory),
+        ("LoaderFlags",           c_uint32),
+        ("NumberOfRvaAndSizes",   c_uint32),
+        ("ExportTable",           PeDataDirectory),
+        ("ImportTable",           PeDataDirectory),
+        ("ResourceTable",         PeDataDirectory),
+        ("ExceptionTable",        PeDataDirectory),
+        ("CertificateTable",      PeDataDirectory),
+        ("BaseRelocationTable",   PeDataDirectory),
+        ("Debug",                 PeDataDirectory),
+        ("Architecture",          PeDataDirectory),
+        ("GlobalPtr",             PeDataDirectory),
+        ("TLSTable",              PeDataDirectory),
+        ("LoadConfigTable",       PeDataDirectory),
+        ("BoundImport",           PeDataDirectory),
+        ("IAT",                   PeDataDirectory),
         ("DelayImportDescriptor", PeDataDirectory),
-        ("CLRRuntimeHeader", PeDataDirectory),
-        ("Reserved", PeDataDirectory),
+        ("CLRRuntimeHeader",      PeDataDirectory),
+        ("Reserved",              PeDataDirectory),
     )
 
 
@@ -152,44 +153,44 @@ class PeOptionalHeader(LittleEndianStructure):
 class PeOptionalHeader32(PeOptionalHeader):
     _anonymous_ = ("Start", "Middle", "End")
     _fields_ = (
-        ("Start", PeOptionalHeaderStart),
-        ("BaseOfData", c_uint32),
-        ("ImageBase", c_uint32),
-        ("Middle", PeOptionalHeaderMiddle),
+        ("Start",              PeOptionalHeaderStart),
+        ("BaseOfData",         c_uint32),
+        ("ImageBase",          c_uint32),
+        ("Middle",             PeOptionalHeaderMiddle),
         ("SizeOfStackReserve", c_uint32),
-        ("SizeOfStackCommit", c_uint32),
-        ("SizeOfHeapReserve", c_uint32),
-        ("SizeOfHeapCommit", c_uint32),
-        ("End", PeOptionalHeaderEnd),
+        ("SizeOfStackCommit",  c_uint32),
+        ("SizeOfHeapReserve",  c_uint32),
+        ("SizeOfHeapCommit",   c_uint32),
+        ("End",                PeOptionalHeaderEnd),
     )
 
 
 class PeOptionalHeader32Plus(PeOptionalHeader):
     _anonymous_ = ("Start", "Middle", "End")
     _fields_ = (
-        ("Start", PeOptionalHeaderStart),
-        ("ImageBase", c_uint64),
-        ("Middle", PeOptionalHeaderMiddle),
+        ("Start",              PeOptionalHeaderStart),
+        ("ImageBase",          c_uint64),
+        ("Middle",             PeOptionalHeaderMiddle),
         ("SizeOfStackReserve", c_uint64),
-        ("SizeOfStackCommit", c_uint64),
-        ("SizeOfHeapReserve", c_uint64),
-        ("SizeOfHeapCommit", c_uint64),
-        ("End", PeOptionalHeaderEnd),
+        ("SizeOfStackCommit",  c_uint64),
+        ("SizeOfHeapReserve",  c_uint64),
+        ("SizeOfHeapCommit",   c_uint64),
+        ("End",                PeOptionalHeaderEnd),
     )
 
 
 class PeSection(LittleEndianStructure):
     _fields_ = (
-        ("Name", c_char * 8),
-        ("VirtualSize", c_uint32),
-        ("VirtualAddress", c_uint32),
-        ("SizeOfRawData", c_uint32),
-        ("PointerToRawData", c_uint32),
+        ("Name",                 c_char * 8),
+        ("VirtualSize",          c_uint32),
+        ("VirtualAddress",       c_uint32),
+        ("SizeOfRawData",        c_uint32),
+        ("PointerToRawData",     c_uint32),
         ("PointerToRelocations", c_uint32),
         ("PointerToLinenumbers", c_uint32),
-        ("NumberOfRelocations", c_uint16),
-        ("NumberOfLinenumbers", c_uint16),
-        ("Characteristics", c_uint32),
+        ("NumberOfRelocations",  c_uint16),
+        ("NumberOfLinenumbers",  c_uint16),
+        ("Characteristics",      c_uint32),
     )
 
     def __init__(self):
@@ -206,12 +207,13 @@ assert sizeof(PeOptionalHeader32Plus) == 240
 
 PE_CHARACTERISTICS_RX = 0x60000020  # CNT_CODE|MEM_READ|MEM_EXECUTE
 PE_CHARACTERISTICS_RW = 0xC0000040  # CNT_INITIALIZED_DATA|MEM_READ|MEM_WRITE
-PE_CHARACTERISTICS_R = 0x40000040  # CNT_INITIALIZED_DATA|MEM_READ
+PE_CHARACTERISTICS_R  = 0x40000040  # CNT_INITIALIZED_DATA|MEM_READ
 
 IGNORE_SECTIONS = [
     ".eh_frame",
     ".eh_frame_hdr",
     ".ARM.exidx",
+    ".relro_padding",
 ]
 
 IGNORE_SECTION_TYPES = [
@@ -246,9 +248,12 @@ def align_down(x: int, align: int) -> int:
 
 
 def next_section_address(sections: typing.List[PeSection]) -> int:
-    return align_to(
-        sections[-1].VirtualAddress + sections[-1].VirtualSize, SECTION_ALIGNMENT
-    )
+    return align_to(sections[-1].VirtualAddress + sections[-1].VirtualSize,
+                    SECTION_ALIGNMENT)
+
+
+class BadSectionError(ValueError):
+    "One of the sections is in a bad state"
 
 
 def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]:
@@ -261,8 +266,9 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]:
     relro = None
     for elf_seg in elf.iter_segments():
         if elf_seg["p_type"] == "PT_LOAD" and elf_seg["p_align"] != SECTION_ALIGNMENT:
-            raise RuntimeError("ELF segments are not properly aligned.")
-        elif elf_seg["p_type"] == "PT_GNU_RELRO":
+            raise BadSectionError(f"ELF segment {elf_seg['p_type']} is not properly aligned"
+                                  f" ({elf_seg['p_align']} != {SECTION_ALIGNMENT})")
+        if elf_seg["p_type"] == "PT_GNU_RELRO":
             relro = elf_seg
 
     for elf_s in elf.iter_sections():
@@ -270,10 +276,14 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]:
             elf_s["sh_flags"] & SH_FLAGS.SHF_ALLOC == 0
             or elf_s["sh_type"] in IGNORE_SECTION_TYPES
             or elf_s.name in IGNORE_SECTIONS
+            or elf_s["sh_size"] == 0
         ):
             continue
         if elf_s["sh_type"] not in ["SHT_PROGBITS", "SHT_NOBITS"]:
-            raise RuntimeError(f"Unknown section {elf_s.name}.")
+            raise BadSectionError(f"Unknown section {elf_s.name} with type {elf_s['sh_type']}")
+        if elf_s.name == '.got':
+            # FIXME: figure out why those sections are inserted
+            print("WARNING: Non-empty .got section", file=sys.stderr)
 
         if elf_s["sh_flags"] & SH_FLAGS.SHF_EXECINSTR:
             rwx = PE_CHARACTERISTICS_RX
@@ -305,7 +315,7 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]:
 
 
 def convert_sections(elf: ELFFile, opt: PeOptionalHeader) -> typing.List[PeSection]:
-    last_vma = 0
+    last_vma = (0, 0)
     sections = []
 
     for pe_s in iter_copy_sections(elf):
@@ -325,10 +335,11 @@ def convert_sections(elf: ELFFile, opt: PeOptionalHeader) -> typing.List[PeSecti
             PE_CHARACTERISTICS_R: b".rodata",
         }[pe_s.Characteristics]
 
-        # This can happen if not building with `-z separate-code`.
-        if pe_s.VirtualAddress < last_vma:
-            raise RuntimeError("Overlapping PE sections.")
-        last_vma = pe_s.VirtualAddress + pe_s.VirtualSize
+        # This can happen if not building with '-z separate-code'.
+        if pe_s.VirtualAddress < sum(last_vma):
+            raise BadSectionError(f"Section {pe_s.Name.decode()!r} @0x{pe_s.VirtualAddress:x} overlaps"
+                                  f" previous section @0x{last_vma[0]:x}+0x{last_vma[1]:x}=@0x{sum(last_vma):x}")
+        last_vma = (pe_s.VirtualAddress, pe_s.VirtualSize)
 
         if pe_s.Name == b".text":
             opt.BaseOfCode = pe_s.VirtualAddress
@@ -355,9 +366,9 @@ def copy_sections(
         if not elf_s:
             continue
         if elf_s.data_alignment > 1 and SECTION_ALIGNMENT % elf_s.data_alignment != 0:
-            raise RuntimeError(f"ELF section {name} is not aligned.")
+            raise BadSectionError(f"ELF section {name} is not aligned")
         if elf_s["sh_flags"] & (SH_FLAGS.SHF_EXECINSTR | SH_FLAGS.SHF_WRITE) != 0:
-            raise RuntimeError(f"ELF section {name} is not read-only data.")
+            raise BadSectionError(f"ELF section {name} is not read-only data")
 
         pe_s = PeSection()
         pe_s.Name = name.encode()
@@ -376,12 +387,8 @@ def apply_elf_relative_relocation(
     sections: typing.List[PeSection],
     addend_size: int,
 ):
-    # fmt: off
-    [target] = [
-        pe_s for pe_s in sections
-        if pe_s.VirtualAddress <= reloc["r_offset"] < pe_s.VirtualAddress + len(pe_s.data)
-    ]
-    # fmt: on
+    [target] = [pe_s for pe_s in sections
+                if pe_s.VirtualAddress <= reloc["r_offset"] < pe_s.VirtualAddress + len(pe_s.data)]
 
     addend_offset = reloc["r_offset"] - target.VirtualAddress
 
@@ -425,9 +432,10 @@ def convert_elf_reloc_table(
             continue
 
         if reloc["r_info_type"] == RELATIVE_RELOC:
-            apply_elf_relative_relocation(
-                reloc, elf_image_base, sections, elf.elfclass // 8
-            )
+            apply_elf_relative_relocation(reloc,
+                                          elf_image_base,
+                                          sections,
+                                          elf.elfclass // 8)
 
             # Now that the ELF relocation has been applied, we can create a PE relocation.
             block_rva = reloc["r_offset"] & ~0xFFF
@@ -442,7 +450,7 @@ def convert_elf_reloc_table(
 
             continue
 
-        raise RuntimeError(f"Unsupported relocation {reloc}")
+        raise BadSectionError(f"Unsupported relocation {reloc}")
 
 
 def convert_elf_relocations(
@@ -453,27 +461,25 @@ def convert_elf_relocations(
 ) -> typing.Optional[PeSection]:
     dynamic = elf.get_section_by_name(".dynamic")
     if dynamic is None:
-        raise RuntimeError("ELF .dynamic section is missing.")
+        raise BadSectionError("ELF .dynamic section is missing")
 
     [flags_tag] = dynamic.iter_tags("DT_FLAGS_1")
     if not flags_tag["d_val"] & ENUM_DT_FLAGS_1["DF_1_PIE"]:
-        raise RuntimeError("ELF file is not a PIE.")
+        raise ValueError("ELF file is not a PIE")
 
     # This checks that the ELF image base is 0.
     symtab = elf.get_section_by_name(".symtab")
     if symtab:
         exe_start = symtab.get_symbol_by_name("__executable_start")
         if exe_start and exe_start[0]["st_value"] != 0:
-            raise RuntimeError("Unexpected ELF image base.")
-
-    opt.SizeOfHeaders = align_to(
-        PE_OFFSET
-        + len(PE_MAGIC)
-        + sizeof(PeCoffHeader)
-        + sizeof(opt)
-        + sizeof(PeSection) * max(len(sections) + 1, minimum_sections),
-        FILE_ALIGNMENT,
-    )
+            raise ValueError("Unexpected ELF image base")
+
+    opt.SizeOfHeaders = align_to(PE_OFFSET
+                                 + len(PE_MAGIC)
+                                 + sizeof(PeCoffHeader)
+                                 + sizeof(opt)
+                                 + sizeof(PeSection) * max(len(sections) + 1, minimum_sections),
+                                 FILE_ALIGNMENT)
 
     # We use the basic VMA layout from the ELF image in the PE image. This could cause the first
     # section to overlap the PE image headers during runtime at VMA 0. We can simply apply a fixed
@@ -482,9 +488,8 @@ def convert_elf_relocations(
     # the ELF portions of the image.
     segment_offset = 0
     if sections[0].VirtualAddress < opt.SizeOfHeaders:
-        segment_offset = align_to(
-            opt.SizeOfHeaders - sections[0].VirtualAddress, SECTION_ALIGNMENT
-        )
+        segment_offset = align_to(opt.SizeOfHeaders - sections[0].VirtualAddress,
+                                  SECTION_ALIGNMENT)
 
     opt.AddressOfEntryPoint = elf["e_entry"] + segment_offset
     opt.BaseOfCode += segment_offset
@@ -494,10 +499,12 @@ def convert_elf_relocations(
     pe_reloc_blocks: typing.Dict[int, PeRelocationBlock] = {}
     for reloc_type, reloc_table in dynamic.get_relocation_tables().items():
         if reloc_type not in ["REL", "RELA"]:
-            raise RuntimeError("Unsupported relocation type {elf_reloc_type}.")
-        convert_elf_reloc_table(
-            elf, reloc_table, opt.ImageBase + segment_offset, sections, pe_reloc_blocks
-        )
+            raise BadSectionError(f"Unsupported relocation type {reloc_type}")
+        convert_elf_reloc_table(elf,
+                                reloc_table,
+                                opt.ImageBase + segment_offset,
+                                sections,
+                                pe_reloc_blocks)
 
     for pe_s in sections:
         pe_s.VirtualAddress += segment_offset
@@ -517,9 +524,7 @@ def convert_elf_relocations(
             block.entries.append(PeRelocationEntry())
 
         block.PageRVA += segment_offset
-        block.BlockSize = (
-            sizeof(PeRelocationBlock) + sizeof(PeRelocationEntry) * n_relocs
-        )
+        block.BlockSize = sizeof(PeRelocationBlock) + sizeof(PeRelocationEntry) * n_relocs
         data += block
         for entry in sorted(block.entries, key=lambda e: e.Offset):
             data += entry
@@ -539,7 +544,10 @@ def convert_elf_relocations(
 
 
 def write_pe(
-    file, coff: PeCoffHeader, opt: PeOptionalHeader, sections: typing.List[PeSection]
+    file,
+    coff: PeCoffHeader,
+    opt: PeOptionalHeader,
+    sections: typing.List[PeSection],
 ):
     file.write(b"MZ")
     file.seek(0x3C, io.SEEK_SET)
@@ -552,7 +560,8 @@ def write_pe(
     offset = opt.SizeOfHeaders
     for pe_s in sorted(sections, key=lambda s: s.VirtualAddress):
         if pe_s.VirtualAddress < opt.SizeOfHeaders:
-            raise RuntimeError(f"Section {pe_s.Name} overlapping PE headers.")
+            raise BadSectionError(f"Section {pe_s.Name} @0x{pe_s.VirtualAddress:x} overlaps"
+                                  " PE headers ending at 0x{opt.SizeOfHeaders:x}")
 
         pe_s.PointerToRawData = offset
         file.write(pe_s)
@@ -570,9 +579,9 @@ def write_pe(
 def elf2efi(args: argparse.Namespace):
     elf = ELFFile(args.ELF)
     if not elf.little_endian:
-        raise RuntimeError("ELF file is not little-endian.")
+        raise ValueError("ELF file is not little-endian")
     if elf["e_type"] not in ["ET_DYN", "ET_EXEC"]:
-        raise RuntimeError("Unsupported ELF type.")
+        raise ValueError(f"Unsupported ELF type {elf['e_type']}")
 
     pe_arch = {
         "EM_386": 0x014C,
@@ -583,7 +592,7 @@ def elf2efi(args: argparse.Namespace):
         "EM_X86_64": 0x8664,
     }.get(elf["e_machine"])
     if pe_arch is None:
-        raise RuntimeError(f"Unsupported ELF arch {elf['e_machine']}")
+        raise ValueError(f"Unsupported ELF architecture {elf['e_machine']}")
 
     coff = PeCoffHeader()
     opt = PeOptionalHeader32() if elf.elfclass == 32 else PeOptionalHeader32Plus()
@@ -636,7 +645,7 @@ def elf2efi(args: argparse.Namespace):
     write_pe(args.PE, coff, opt, sections)
 
 
-def main():
+def create_parser() -> argparse.ArgumentParser:
     parser = argparse.ArgumentParser(description="Convert ELF binaries to PE/EFI")
     parser.add_argument(
         "--version-major",
@@ -690,7 +699,11 @@ def main():
         default="",
         help="Copy these sections if found",
     )
+    return parser
+
 
+def main():
+    parser = create_parser()
     elf2efi(parser.parse_args())
 
 
index 2f7be5ccd693f4806e254654e0226515f7630804..4b49ab9c45f9d48547b93d3827038809b0550bfe 100755 (executable)
@@ -7,6 +7,7 @@ cd "${MESON_SOURCE_ROOT:?}"
 if [ -e .git ]; then
     git config submodule.recurse true
     git config fetch.recurseSubmodules on-demand
+    git config push.recurseSubmodules no
 fi
 
 if [ ! -f .git/hooks/pre-commit.sample ] || [ -f .git/hooks/pre-commit ]; then
index 0f826041078a8735550dc8c98382c1e6f34b65e4..ee87118a074b033d80f9d34503cc018d5f56f1b7 100644 (file)
@@ -13,6 +13,7 @@ Documentation=man:systemd-battery-check.service(8)
 ConditionVirtualization=no
 ConditionDirectoryNotEmpty=/sys/class/power_supply/
 ConditionKernelCommandLine=!systemd.battery_check=0
+ConditionKernelCommandLine=!systemd.battery-check=0
 AssertPathExists=/etc/initrd-release
 DefaultDependencies=no
 After=plymouth-start.service
index bfbc0b193e143b368d643482ab0237c86533e628..6141fdbb6d78ab2570468a9cb6ead309aa942d12 100644 (file)
@@ -27,7 +27,6 @@ DeviceAllow=char-* rw
 ExecStart=!!{{LIBEXECDIR}}/systemd-networkd
 FileDescriptorStoreMax=512
 ImportCredential=network.wireguard.*
-InaccessiblePaths=-/boot -/efi
 LockPersonality=yes
 MemoryDenyWriteExecute=yes
 NoNewPrivileges=yes
@@ -37,7 +36,7 @@ ProtectControlGroups=yes
 ProtectHome=yes
 ProtectKernelLogs=yes
 ProtectKernelModules=yes
-ProtectSystem=full
+ProtectSystem=strict
 Restart=on-failure
 RestartKillSignal=SIGUSR2
 RestartSec=0