]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #16106 from yuwata/network-tc-ets
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Jun 2020 17:04:43 +0000 (19:04 +0200)
committerGitHub <noreply@github.com>
Wed, 24 Jun 2020 17:04:43 +0000 (19:04 +0200)
network: tc: introduce ETS

170 files changed:
.github/workflows/ubuntu-build-check.sh
.travis.yml
NEWS
coccinelle/set_ensure_put.cocci [new file with mode: 0644]
docs/RANDOM_SEEDS.md
hwdb.d/60-autosuspend.hwdb [new file with mode: 0644]
hwdb.d/70-mouse.hwdb
hwdb.d/meson.build
hwdb.d/parse_hwdb.py
man/bootup.xml
man/custom-html.xsl
man/homectl.xml
man/resolved.conf.xml
man/systemd-makefs@.service.xml
man/systemd-modules-load.service.xml
man/systemd-resolved.service.xml
man/systemd.exec.xml
man/systemd.resource-control.xml
meson.build
rules.d/50-udev-default.rules.in
rules.d/60-autosuspend.rules [new file with mode: 0644]
rules.d/60-serial.rules
rules.d/61-autosuspend-manual.rules [deleted file]
rules.d/meson.build
src/analyze/analyze.c
src/basic/dlfcn-util.h [new file with mode: 0644]
src/basic/hashmap.c
src/basic/hashmap.h
src/basic/log.c
src/basic/log.h
src/basic/memory-util.h
src/basic/meson.build
src/basic/selinux-util.c
src/basic/set.h
src/busctl/busctl.c
src/cgls/cgls.c
src/cgtop/cgtop.c
src/core/automount.c
src/core/bpf-firewall.c
src/core/dbus-cgroup.c
src/core/dbus-execute.c
src/core/dbus-manager.c
src/core/emergency-action.c
src/core/execute.c
src/core/execute.h
src/core/job.c
src/core/job.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/namespace.c
src/core/namespace.h
src/core/org.freedesktop.systemd1.conf
src/core/transaction.c
src/core/unit.c
src/coredump/coredumpctl.c
src/delta/delta.c
src/detect-virt/detect-virt.c
src/dissect/dissect.c
src/escape/escape.c
src/home/homectl.c
src/hostname/hostnamectl.c
src/hostname/hostnamed.c
src/hwdb/hwdb.c
src/id128/id128.c
src/journal-remote/journal-remote-main.c
src/journal-remote/journal-upload.c
src/journal/cat.c
src/journal/journalctl.c
src/libsystemd-network/dhcp-lease-internal.h
src/libsystemd-network/network-internal.h
src/libsystemd-network/sd-dhcp-lease.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-network/sd-network.c
src/locale/localectl.c
src/locale/localed.c
src/locale/meson.build
src/login/loginctl.c
src/login/logind-brightness.c
src/login/logind.c
src/login/user-runtime-dir.c
src/machine/machinectl.c
src/network/netdev/wireguard.c
src/network/networkctl.c
src/network/networkd-address.c
src/network/networkd-dhcp-common.c
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-ndisc.c
src/network/networkd-neighbor.c
src/network/networkd-network.c
src/network/networkd-nexthop.c
src/network/networkd-route.c
src/network/networkd-routing-policy-rule.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/nss-systemd/nss-systemd.c
src/nss-systemd/nss-systemd.h [new file with mode: 0644]
src/nss-systemd/nss-systemd.sym
src/nss-systemd/userdb-glue.c
src/portable/portable.c
src/portable/portablectl.c
src/resolve/resolvectl.c
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-scope.h
src/resolve/resolved-dns-stub.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h
src/resolve/resolved-dns-trust-anchor.c
src/resolve/resolved-dns-zone.c
src/resolve/resolved-etc-hosts.c
src/resolve/resolved-gperf.gperf
src/resolve/resolved-manager.h
src/resolve/resolved.c
src/resolve/resolved.conf.in
src/shared/bus-unit-util.c
src/shared/bus-util.c
src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/seccomp-util.c
src/shared/seccomp-util.h
src/shared/userdb.c
src/shared/userdb.h
src/socket-proxy/socket-proxyd.c
src/systemctl/systemctl.c
src/systemd/sd-network.h
src/sysusers/sysusers.c
src/sysv-generator/sysv-generator.c
src/test/test-chase-symlinks.c
src/test/test-namespace.c
src/test/test-ns.c
src/test/test-set.c
src/timedate/timedatectl.c
src/timedate/timedated.c
src/tmpfiles/tmpfiles.c
src/udev/udevadm-monitor.c
src/udev/udevadm.c
src/udev/udevd.c
src/update-done/update-done.c
src/user-sessions/user-sessions.c
src/userdb/userdbctl.c
src/userdb/userwork.c
src/xdg-autostart-generator/xdg-autostart-service.c
test/TEST-21-SYSUSERS/test.sh
test/TEST-52-HONORFIRSTSHUTDOWN/Makefile [new file with mode: 0644]
test/TEST-52-HONORFIRSTSHUTDOWN/fini.sh [new file with mode: 0755]
test/TEST-52-HONORFIRSTSHUTDOWN/test.sh [new file with mode: 0755]
test/fuzz/fuzz-bus-message/zero-offset-to-null-pointer [new file with mode: 0644]
test/fuzz/fuzz-netdev-parser/wireguard-duplicated-endpoint [new file with mode: 0644]
test/fuzz/fuzz-network-parser/dns-trust-anchor-duplicate.network [new file with mode: 0644]
test/fuzz/fuzz-unit-file/directives.service
test/meson.build
test/test-functions
test/testsuite-52.units/testsuite-52.service [new file with mode: 0755]
test/testsuite-52.units/testsuite-52.sh [new file with mode: 0755]
test/units/test-honor-first-shutdown.service [new file with mode: 0644]
test/units/test-honor-first-shutdown.sh [new file with mode: 0755]
tools/make-autosuspend-rules.py
travis-ci/managers/debian.sh
travis-ci/managers/fedora.sh

index fb7c71ecb89a182f8faa0ea1c4e23ddac05cbf1e..75fc36fffb10fcf1b5664e509d294a4bfa3bdcf3 100755 (executable)
@@ -102,7 +102,7 @@ for args in "${ARGS[@]}"; do
     SECONDS=0
 
     info "Checking build with $args"
-    if ! AR="$AR" CC="$CC" CXX="$CXX" meson -Dtests=unsafe -Dslow-tests=true --werror $args build; then
+    if ! AR="$AR" CC="$CC" CXX="$CXX" CFLAGS="-Werror" CXXFLAGS="-Werror" meson -Dtests=unsafe -Dslow-tests=true --werror $args build; then
         fatal "meson failed with $args"
     fi
 
index d933ccce0620ef0ca57631d4f88fb527531760ce..a72e81552fe1c9c93fc58da41b02fa34c1fd3b18 100644 (file)
-sudo: required
+---
+# vi: ts=2 sw=2 et:
+
+language: bash
 dist: bionic
 services:
-    - docker
+  - docker
 
 env:
-    global:
-        - AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
-        - CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
-        - CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools"
-        - REPO_ROOT="$TRAVIS_BUILD_DIR"
+  global:
+    - AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
+    - CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
+    - CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools"
+    - REPO_ROOT="$TRAVIS_BUILD_DIR"
+  jobs:
+    - DEBIAN_RELEASE=testing PHASE="RUN_GCC"
+    - DEBIAN_RELEASE=testing PHASE="RUN_GCC_ASAN_UBSAN"
+    - DEBIAN_RELEASE=testing PHASE="RUN_CLANG"
+    - DEBIAN_RELEASE=testing PHASE="RUN_CLANG_ASAN_UBSAN"
 
 stages:
-    - name: Build & test
-      if: type != cron
+  # 'Test' is the default stage (for matrix jobs)
+  - name: Test
+    if: type != cron
 
     # Run Coverity periodically instead of for each commit/PR
-    - name: Coverity
-      if: type = cron
-
-jobs:
-    include:
-        - stage: Build & test
-          name: Debian Testing
-          language: bash
-          env:
-              - DEBIAN_RELEASE="testing"
-              - CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
-              - DOCKER_EXEC="docker exec -ti $CONT_NAME"
-          before_install:
-              - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
-              - docker --version
-          install:
-              - $CI_MANAGERS/debian.sh SETUP
-          script:
-              - $CI_MANAGERS/debian.sh RUN || travis_terminate 1
-          after_script:
-              - $CI_MANAGERS/debian.sh CLEANUP
+  - name: Coverity
+    if: type = cron
 
-        - name: Debian Testing (ASan+UBSan)
-          language: bash
-          env:
-              - DEBIAN_RELEASE="testing"
-              - CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
-              - DOCKER_EXEC="docker exec -ti $CONT_NAME"
-          before_install:
-              - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
-              - docker --version
-          install:
-              - $CI_MANAGERS/debian.sh SETUP
-          script:
-              - $CI_MANAGERS/debian.sh RUN_ASAN || travis_terminate 1
-          after_script:
-              - $CI_MANAGERS/debian.sh CLEANUP
+# Matrix job definition - this is run for each combination of env variables
+# from the env.jobs array above
+before_install:
+  - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
+  - docker --version
+install:
+  - $CI_MANAGERS/debian.sh SETUP
+script:
+  - $CI_MANAGERS/debian.sh $PHASE || travis_terminate 1
+after_script:
+  - $CI_MANAGERS/debian.sh CLEANUP
 
-        - name: Debian Testing (clang)
-          language: bash
-          env:
-              - DEBIAN_RELEASE="testing"
-              - CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
-              - DOCKER_EXEC="docker exec -ti $CONT_NAME"
-          before_install:
-              - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
-              - docker --version
-          install:
-              - $CI_MANAGERS/debian.sh SETUP
-          script:
-              - $CI_MANAGERS/debian.sh RUN_CLANG || travis-travis_terminate 1
-          after_script:
-              - $CI_MANAGERS/debian.sh CLEANUP
-
-        - name: Debian Testing (clang ASan+UBSan)
-          language: bash
-          env:
-              - DEBIAN_RELEASE="testing"
-              - CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
-              - DOCKER_EXEC="docker exec -ti $CONT_NAME"
-          before_install:
-              - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
-              - docker --version
-          install:
-              - $CI_MANAGERS/debian.sh SETUP
-          script:
-              - $CI_MANAGERS/debian.sh RUN_CLANG_ASAN || travis_terminate 1
-          after_script:
-              - $CI_MANAGERS/debian.sh CLEANUP
-
-        - stage: Coverity
-          language: bash
-          env:
-              - FEDORA_RELEASE="latest"
-              - CONT_NAME="coverity-fedora-$FEDORA_RELEASE"
-              - DOCKER_EXEC="docker exec -ti $CONT_NAME"
-              - TOOL_BASE="/var/tmp/coverity-scan-analysis"
-              - DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
-              # Coverity env variables
-              - PLATFORM="$(uname)"
-              - TOOL_ARCHIVE="/var/tmp/cov-analysis-$PLATFORM.tgz"
-              - SCAN_URL="https://scan.coverity.com"
-              - UPLOAD_URL="https://scan.coverity.com/builds"
-              - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
-              - COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
-              - COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH"
-              # Encrypted COVERITY_SCAN_TOKEN env variable
-              # Generated using `travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=xxxx`
-              - secure: "jKSz+Y1Mv8xMpQHh7g5lzW7E6HQGndFz/vKDJQ1CVShwFoyjV3Zu+MFS3UYKlh1236zL0Z4dvsYFx/b3Hq8nxZWCrWeZs2NdXgy/wh8LZhxwzcGYigp3sIA/cYdP5rDjFJO0MasNkl25/rml8+eZWz+8/xQic98UQHjSco/EOWtssoRcg0J0c4eDM7bGLfIQWE73NNY1Q1UtWjKmx1kekVrM8dPmHXJ9aERka7bmcbJAcKd6vabs6DQ5AfWccUPIn/EsRYqIJTRxJrFYU6XizANZ1a7Vwk/DWHZUEn2msxcZw5BbAMDTMx0TbfrNkKSHMHuvQUCu6KCBAq414i+LgkMfmQ2SWwKiIUsud1kxXX3ZPl9bxDv1HkvVdcniC/EM7lNEEVwm4meOnjuhI2lhOyOjmP3FTSlMHGP7xlK8DS2k9fqL58vn0BaSjwWgd+2+HuL2+nJmxcK1eLGzKqaostFxrk2Xs2vPZkUdV2nWY/asUrcWHml6YlWDn2eP83pfwxHYsMiEHY/rTKvxeVY+iirO/AphoO+eaYu7LvjKZU1Yx5Z4u/SnGWAiCH0yhMis0bWmgi7SCbw+sDd2uya+aoiLIGiB2ChW7hXHXCue/dif6/gLU7b+L8R00pQwnWdvKUPoIJCmZJYCluTeib4jpW+EmARB2+nR8wms2K9FGKM="
-          before_install:
-              - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
-              - docker --version
-          install:
-              # Install Coverity on the host
-              - $CI_TOOLS/get-coverity.sh
-              # Export necessary env variables for Coverity
-              - env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env
-              # Pull a Docker image and start a new container
-              - $CI_MANAGERS/fedora.sh SETUP
-          script:
-              - set -e
-              # Preconfigure with meson to prevent Coverity from capturing meson metadata
-              - $DOCKER_EXEC meson cov-build -Dman=false
-              # Run Coverity
-              - $DOCKER_EXEC tools/coverity.sh build
-              - $DOCKER_EXEC tools/coverity.sh upload
+# Inject another (single) job into the matrix for Coverity
+jobs:
+  include:
+    - stage: Coverity
+      language: bash
+      env:
+        - FEDORA_RELEASE="latest"
+        - TOOL_BASE="/var/tmp/coverity-scan-analysis"
+        - DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
+          # Coverity env variables
+        - PLATFORM="$(uname)"
+        - TOOL_ARCHIVE="/var/tmp/cov-analysis-$PLATFORM.tgz"
+        - SCAN_URL="https://scan.coverity.com"
+        - UPLOAD_URL="https://scan.coverity.com/builds"
+        - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
+        - COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
+        - COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH"
+          # Encrypted COVERITY_SCAN_TOKEN env variable
+          # Generated using `travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=xxxx`
+        - secure: "jKSz+Y1Mv8xMpQHh7g5lzW7E6HQGndFz/vKDJQ1CVShwFoyjV3Zu+MFS3UYKlh1236zL0Z4dvsYFx/b3Hq8nxZWCrWeZs2NdXgy/wh8LZhxwzcGYigp3sIA/cYdP5rDjFJO0MasNkl25/rml8+eZWz+8/xQic98UQHjSco/EOWtssoRcg0J0c4eDM7bGLfIQWE73NNY1Q1UtWjKmx1kekVrM8dPmHXJ9aERka7bmcbJAcKd6vabs6DQ5AfWccUPIn/EsRYqIJTRxJrFYU6XizANZ1a7Vwk/DWHZUEn2msxcZw5BbAMDTMx0TbfrNkKSHMHuvQUCu6KCBAq414i+LgkMfmQ2SWwKiIUsud1kxXX3ZPl9bxDv1HkvVdcniC/EM7lNEEVwm4meOnjuhI2lhOyOjmP3FTSlMHGP7xlK8DS2k9fqL58vn0BaSjwWgd+2+HuL2+nJmxcK1eLGzKqaostFxrk2Xs2vPZkUdV2nWY/asUrcWHml6YlWDn2eP83pfwxHYsMiEHY/rTKvxeVY+iirO/AphoO+eaYu7LvjKZU1Yx5Z4u/SnGWAiCH0yhMis0bWmgi7SCbw+sDd2uya+aoiLIGiB2ChW7hXHXCue/dif6/gLU7b+L8R00pQwnWdvKUPoIJCmZJYCluTeib4jpW+EmARB2+nR8wms2K9FGKM="
+      before_install:
+        - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
+        - docker --version
+      install:
+        # Install Coverity on the host
+        - $CI_TOOLS/get-coverity.sh
+          # Export necessary env variables for Coverity
+        - env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env
+          # Pull a Docker image and start a new container
+        - $CI_MANAGERS/fedora.sh SETUP
+      script:
+        - set -e
+          # Preconfigure with meson to prevent Coverity from capturing meson metadata
+        - $DOCKER_EXEC meson cov-build -Dman=false
+          # Run Coverity
+        - $DOCKER_EXEC tools/coverity.sh build
+        - $DOCKER_EXEC tools/coverity.sh upload
 
-              - set +e
-          after_script:
-              - $CI_MANAGERS/fedora.sh CLEANUP
+        - set +e
+      after_script:
+        - $CI_MANAGERS/fedora.sh CLEANUP
diff --git a/NEWS b/NEWS
index 7db370516a4d90a9a2684eef63cb6cf05462e399..8d93d0c813609e7adfce57eed49563ae1a71172a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -87,6 +87,12 @@ CHANGES WITH 246 in spe:
           used, the DNS-over-TLS certificate is validated to match the
           specified hostname.
 
+        * systemd-resolved may be configured to forward single-label DNS names.
+          This is not standard-conformant, but may make sense in setups where
+          public DNS servers are not used.
+
+        * systemd-resolved's DNS-over-TLS support gained SNI validation.
+
         * The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
           systemd-coredump to save core files for suid processes. When saving
           the core file, systemd-coredump will use the effective uid and gid of
@@ -538,8 +544,6 @@ CHANGES WITH 245:
         * systemd-sysusers gained support for creating users with the primary
           group named differently than the user.
 
-        * systemd-resolved's DNS-over-TLS support gained SNI validation.
-
         * systemd-growfs (i.e. the x-systemd.growfs mount option in /etc/fstab)
           gained support for growing XFS partitions. Previously it supported
           only ext4 and btrfs partitions.
diff --git a/coccinelle/set_ensure_put.cocci b/coccinelle/set_ensure_put.cocci
new file mode 100644 (file)
index 0000000..92d7970
--- /dev/null
@@ -0,0 +1,18 @@
+@@
+local idexpression r;
+expression p, k, x;
+@@
+- r = set_ensure_allocated(&p, k);
+- if (r < 0)
+-   return ...;
+- r = set_put(p, x);
++ r = set_ensure_put(&p, k, x);
+@@
+local idexpression r;
+expression p, k, x;
+@@
+- r = set_ensure_allocated(p, k);
+- if (r < 0)
+-   return ...;
+- r = set_put(*p, x);
++ r = set_ensure_put(p, k, x);
index d3b68e967aa09d85c42633eca23cf8770610f10e..c1735b1ac9e138ee4cd4785bc94620b270f180c8 100644 (file)
@@ -118,7 +118,7 @@ requires random numbers as well, including for the following uses:
 
 * systemd maintains various hash tables internally. In order to harden them
   against [collision
-  attacks](https://rt.perl.org/Public/Bug/Display.html?CSRF_Token=165691af9ddaa95f653402f1b68de728)
+  attacks](https://www.cs.auckland.ac.nz/~mcw/Teaching/refs/misc/denial-of-service.pdf)
   they are seeded with random numbers.
 
 * At various places systemd needs random bytes for temporary file name
diff --git a/hwdb.d/60-autosuspend.hwdb b/hwdb.d/60-autosuspend.hwdb
new file mode 100644 (file)
index 0000000..0de49af
--- /dev/null
@@ -0,0 +1,44 @@
+# This file is part of systemd.
+#
+# The lookup keys are $MODALIAS strings, see udev's hwdb builtin.
+#
+# Match string formats:
+# <subsystem>:<modalias>
+#
+# pci:v<vendor>d<device>
+# usb:v<vendor>p<product>
+#
+# To add local entries, create a new file
+#   /etc/udev/hwdb.d/61-autosuspend-local.hwdb
+# and add your rules there. To load the new rules execute (as root):
+#   systemd-hwdb update
+#   udevadm trigger /dev/…
+#
+# If your changes are generally applicable, preferably send them as a pull
+# request to
+#   https://github.com/systemd/systemd
+# or create a bug report on https://github.com/systemd/systemd/issues and
+# include your new rules, a description of the device, and the output of
+#   udevadm info
+# the device.
+#
+# Allowed properties are:
+#    ID_AUTOSUSPEND=1
+
+#
+# Sort by brand, model
+
+#########################################
+# Alcor
+#########################################
+
+# AU9540 Smartcard Reader
+usb:v058Fp9540*
+ ID_AUTOSUSPEND=1
+
+#########################################
+# Wacom
+#########################################
+
+usb:v056Ap51A0*
+ ID_AUTOSUSPEND=1
index ef5a473e87ae5ea990db48d9955fa81c1f7d3acf..63ef1fba1227d893bd1956d0916d0f96fdb5479a 100644 (file)
@@ -349,6 +349,8 @@ mouse:usb:v046dpc068:name:Logitech G500:
 mouse:usb:v046dpc332:name:Logitech Gaming Mouse G502:
 # Logitech G502 HERO SE
 mouse:usb:v046dpc08b:name:Logitech G502 HERO SE:
+# Logitech G502 Hero
+mouse:usb:v046dpc08b:name:Logitech G502 HERO Gaming Mouse:
  MOUSE_DPI=1200@1000 *2400@1000 3200@1000 6400@1000
 
 # Logitech G700 Laser Mouse (Wired)
index 4df6dabf89f6ef94f11b214d08d20487c26f59fb..5c77387a26130454dfe775e5ee7c5edb62827058 100644 (file)
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
-hwdb_files = files('''
+# Those files right now are not supported by the grammar. Also,
+# they are very long but quite repetitive and the parser is not very fast.
+# So we don't "test" them.
+hwdb_files_notest = files('''
         20-pci-vendor-model.hwdb
         20-pci-classes.hwdb
         20-usb-vendor-model.hwdb
@@ -12,6 +15,10 @@ hwdb_files = files('''
         20-OUI.hwdb
         20-net-ifname.hwdb
         20-vmbus-class.hwdb
+'''.split())
+
+hwdb_files_test = files('''
+        60-autosuspend.hwdb
         60-evdev.hwdb
         60-input-id.hwdb
         60-keyboard.hwdb
@@ -23,7 +30,16 @@ hwdb_files = files('''
 '''.split())
 
 if conf.get('ENABLE_HWDB') == 1
-        install_data(hwdb_files,
+        auto_suspend_rules = custom_target(
+                '60-autosuspend-chromiumos.hwdb',
+                output : '60-autosuspend-chromiumos.hwdb',
+                command : make_autosuspend_rules_py,
+                capture : true,
+                install : true,
+                install_dir: udevhwdbdir)
+
+        install_data(hwdb_files_notest,
+                     hwdb_files_test,
                      install_dir : udevhwdbdir)
 
         meson.add_install_script('sh', '-c',
@@ -32,15 +48,15 @@ if conf.get('ENABLE_HWDB') == 1
         meson.add_install_script('sh', '-c',
                                  'test -n "$DESTDIR" || @0@/systemd-hwdb update'
                                  .format(rootbindir))
-endif
-
-############################################################
 
-parse_hwdb_py = find_program('parse_hwdb.py')
-if want_tests != 'false'
-        test('parse-hwdb',
-             parse_hwdb_py,
-             timeout : 90)
+        if want_tests != 'false'
+                parse_hwdb_py = find_program('parse_hwdb.py')
+                test('parse-hwdb',
+                     parse_hwdb_py,
+                     args : [hwdb_files_test,
+                             auto_suspend_rules],
+                     timeout : 90)
+        endif
 endif
 
 ############################################################
index abef56728fcbf86162e8cd81e1f6bc5efbac1ead..8e1b5fdafa4c600279f8c3a4288bef31610cdd82 100755 (executable)
@@ -59,6 +59,7 @@ REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER))
 SIGNED_REAL = Combine(Optional(Word('-+')) + REAL)
 UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
 
+# Those patterns are used in type-specific matches
 TYPES = {'mouse':    ('usb', 'bluetooth', 'ps2', '*'),
          'evdev':    ('name', 'atkbd', 'input'),
          'id-input': ('modalias'),
@@ -68,13 +69,27 @@ TYPES = {'mouse':    ('usb', 'bluetooth', 'ps2', '*'),
          'sensor':   ('modalias', ),
         }
 
+# Patterns that are used to set general properties on a device
+GENERAL_MATCHES = {'acpi',
+                   'bluetooth',
+                   'usb',
+                   'pci',
+                   'sdio',
+                   'vmbus',
+                   'OUI',
+                   }
+
 @lru_cache()
 def hwdb_grammar():
     ParserElement.setDefaultWhitespaceChars('')
 
     prefix = Or(category + ':' + Or(conn) + ':'
                 for category, conn in TYPES.items())
-    matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL
+
+    matchline_typed = Combine(prefix + Word(printables + ' ' + '®'))
+    matchline_general = Combine(Or(GENERAL_MATCHES) + ':' + Word(printables))
+    matchline = (matchline_typed | matchline_general) + EOL
+
     propertyline = (White(' ', exact=1).suppress() +
                     Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) +
                     EOL)
@@ -102,6 +117,7 @@ def property_grammar():
              ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER),
              ('MOUSE_WHEEL_CLICK_COUNT', INTEGER),
              ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER),
+             ('ID_AUTOSUSPEND', Literal('1')),
              ('ID_INPUT', Literal('1')),
              ('ID_INPUT_ACCELEROMETER', Literal('1')),
              ('ID_INPUT_JOYSTICK', Literal('1')),
index 8cee4b419e598b2fe0a8d5375f5aace0de9b5ab5..5770e7828d2c07373e077c4d667dc8a0cd62793e 100644 (file)
@@ -192,7 +192,7 @@ emergency.service    |              |              |
              v            graphical-session-pre.target
  (various user services)          |                       (printers)
              |                    v                           |
-             |        (services for the graphical sesion)     v
+             |       (services for the graphical session)     v
              |                    |                       printer.target
              v                    v
       <emphasis>default.target</emphasis>      graphical-session.target</programlisting>
index 7eebfdb5a142673ab433dfb338e346a3fc2220b6..57a9cc97d258b754e1b2439766715437efc9489c 100644 (file)
@@ -19,7 +19,8 @@
 <xsl:template match="citerefentry[not(@project)]">
   <a>
     <xsl:attribute name="href">
-      <xsl:value-of select="refentrytitle"/><xsl:text>.html#</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>.html#</xsl:text>
       <xsl:value-of select="refentrytitle/@target"/>
     </xsl:attribute>
     <xsl:call-template name="inline.charseq"/>
   </a>
 </xsl:template>
 
+<xsl:template match="citerefentry[@project='url']">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:value-of select="refentrytitle/@url"/>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
 <!--
   - helper template to do conflict resolution between various headings with the same inferred ID attribute/tag from the headerlink template
   - this conflict resolution is necessary to prevent malformed HTML output (multiple ID attributes with the same value)
index 14877a0cde047e24265139e170443e624e671c8a..3a4c6e5f5b1de0bd6ac8df5b0603e03ddebfcfea 100644 (file)
         independently, for example with <citerefentry
         project='man-pages'><refentrytitle>groupadd</refentrytitle><manvolnum>8</manvolnum></citerefentry>. If
         non-existent groups that are listed there are ignored. This option may be used more than once, in
-        which case all specified group lists are combined.</para></listitem>
+        which case all specified group lists are combined. If the user is currently a member of a group
+        which is not listed, the user will be removed from the group.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 9be41baaa5a5fb03f79dfa072f00d48ff088f5a9..0e9b90c1cd9c375b23a1c119b9398564d230128c 100644 (file)
 
       <varlistentry>
         <term><varname>Domains=</varname></term>
-        <listitem><para>A space-separated list of domains. These domains are used as search suffixes when resolving
-        single-label hostnames (domain names which contain no dot), in order to qualify them into fully-qualified
-        domain names (FQDNs). Search domains are strictly processed in the order they are specified, until the name
-        with the suffix appended is found. For compatibility reasons, if this setting is not specified, the search
-        domains listed in <filename>/etc/resolv.conf</filename> are used instead, if that file exists and any domains
-        are configured in it. This setting defaults to the empty list.</para>
-
-        <para>Specified domain names may optionally be prefixed with <literal>~</literal>. In this case they do not
-        define a search path, but preferably direct DNS queries for the indicated domains to the DNS servers configured
-        with the system <varname>DNS=</varname> setting (see above), in case additional, suitable per-link DNS servers
-        are known. If no per-link DNS servers are known using the <literal>~</literal> syntax has no effect. Use the
-        construct <literal>~.</literal> (which is composed of <literal>~</literal> to indicate a routing domain and
-        <literal>.</literal> to indicate the DNS root domain that is the implied suffix of all DNS domains) to use the
-        system DNS server defined with <varname>DNS=</varname> preferably for all domains.</para></listitem>
+        <listitem><para>A space-separated list of domains optionally prefixed with <literal>~</literal>,
+        used for two distinct purposes described below. Defaults to the empty list.</para>
+
+        <para>Any domains <emphasis>not</emphasis> prefixed with <literal>~</literal> are used as search
+        suffixes when resolving single-label hostnames (domain names which contain no dot), in order to
+        qualify them into fully-qualified domain names (FQDNs). These "search domains" are strictly processed
+        in the order they are specified in, until the name with the suffix appended is found. For
+        compatibility reasons, if this setting is not specified, the search domains listed in
+        <filename>/etc/resolv.conf</filename> with the <varname>search</varname> keyword are used instead, if
+        that file exists and any domains are configured in it.</para>
+
+        <para>The domains prefixed with <literal>~</literal> are called "routing domains". All domains listed
+        here (both search domains and routing domains after removing the <literal>~</literal> prefix) define
+        a search path that preferably directs DNS queries to this inteface. This search path has an effect
+        only when suitable per-link DNS servers are known. Such servers may be defined through the
+        <varname>DNS=</varname> setting (see above) and dynamically at run time, for example from DHCP
+        leases. If no per-link DNS servers are known, routing domains have no effect.</para>
+
+        <para>Use the construct <literal>~.</literal> (which is composed from <literal>~</literal> to
+        indicate a routing domain and <literal>.</literal> to indicate the DNS root domain that is the
+        implied suffix of all DNS domains) to use the DNS servers defined for this link preferably for all
+        domains.</para></listitem>
       </varlistentry>
 
       <varlistentry>
 
       <varlistentry>
         <term><varname>ReadEtcHosts=</varname></term>
-        <listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), the DNS stub resolver will read
-        <filename>/etc/hosts</filename>, and try to resolve hosts or address by using the entries in the file before
-        sending query to DNS servers.</para></listitem>
+        <listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default),
+        <command>systemd-resolved</command> will read <filename>/etc/hosts</filename>, and try to resolve
+        hosts or address by using the entries in the file before sending query to DNS servers.
+        </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>ResolveUnicastSingleLabel=</varname></term>
+        <listitem><para>Takes a boolean argument. When false (the default),
+        <command>systemd-resolved</command> will not resolve A and AAAA queries for single-label names over
+        classic DNS. Note that such names may still be resolved if search domains are specified (see
+        <varname>Domains=</varname> above), or using other mechanisms, in particular via LLMNR or from
+        <filename>/etc/hosts</filename>. When true, queries for single-label names will be forwarded to
+        global DNS servers even if no search domains are defined.
+        </para>
+
+        <para>This option is provided for compatibility with configurations where <emphasis>public DNS
+        servers are not used</emphasis>. Forwarding single-label names to servers not under your control is
+        not standard-conformant, see <ulink
+        url="https://www.iab.org/documents/correspondence-reports-documents/2013-2/iab-statement-dotless-domains-considered-harmful/">IAB
+        Statement</ulink>, and may create a privacy and security risk.</para></listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index d07d90315a4140e4c3ea117449d8dce2e8c1cbeb..9aa058588edeb3c64aa0e54715ddd9662acdb6c5 100644 (file)
@@ -51,7 +51,8 @@
     <para><filename>systemd-makefs</filename> knows very little about specific file
     systems and swap devices, and after checking that the block device does not already
     contain a file system or other content, it will execute binaries specific to
-    each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>).</para>
+    each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>
+    or <filename>/sbin/mkswap</filename>).</para>
 
     <para><filename>systemd-growfs</filename> knows very little about specific file
     systems and swap devices, and will instruct the kernel to grow the mounted
@@ -61,8 +62,7 @@
     number specific to each file system, so only certain types are supported.
     Currently:
     <citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-    btrfs (see
-    <citerefentry project='man-pages'><refentrytitle>btrfs-man5</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
+    <citerefentry project='url'><refentrytitle url='https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)'>btrfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
     <citerefentry project='man-pages'><refentrytitle>xfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
     <!-- yes, that's what the man page is called. -->
     and dm-crypt partitions (see
index ca9edef367067a781ebe21bf575e8a3ba6840e17..e960609c6cf812cc08b9ae571a9635a3ef3606c2 100644 (file)
   <refsect1>
     <title>Description</title>
 
-    <para><filename>systemd-modules-load.service</filename> is an
-    early boot service that loads kernel modules based on static
-    configuration.</para>
+    <para><filename>systemd-modules-load.service</filename> is an early boot service that loads kernel
+    modules. It reads static configuration from files in <filename>/usr</filename> and
+    <filename>/etc</filename>, but also runtime configuration from <filename>/run</filename> and the kernel
+    command line (see below).</para>
 
     <para>See
-    <citerefentry><refentrytitle>modules-load.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for information about the configuration of this service.</para>
-
+    <citerefentry><refentrytitle>modules-load.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+    information about the configuration format of this service and paths where configuration files can be
+    created.</para>
   </refsect1>
 
   <refsect1>
index 6e1ee9f4a5158229561b579277944d10ce90d49a..914607e3f8d621827dec247c19eac3144fb3a757 100644 (file)
       IPv6.</para></listitem>
 
       <listitem><para>Resolution of address records (A and AAAA) via unicast DNS (i.e. not LLMNR or
-      MulticastDNS) for non-synthesized single-label names is only allowed for non-top-level domains. This
-      means that such records can only be resolved when search domains are defined. For any interface which
-      defines search domains, such look-ups are routed to that interface, suffixed with each of the search
-      domains defined on that interface in turn. When global search domains are defined, such look-ups are
-      routed to all interfaces, suffixed by each of the global search domains in turn. The details of which
-      servers are queried and how the final reply is chosen are described below. Note that this means that
-      address queries for single-label names are never sent out to remote DNS servers, and if no search
-      domains are defined, resolution will fail.</para></listitem>
+      MulticastDNS) for non-synthesized single-label names is allowed for non-top-level domains. This means
+      that such records can be resolved when search domains are defined. For any interface which defines
+      search domains, such look-ups are routed to that interface, suffixed with each of the search domains
+      defined on that interface in turn. When global search domains are defined, such look-ups are routed to
+      all interfaces, suffixed by each of the global search domains in turn. Additionally, lookup of
+      single-label names via unicast DNS may be enabled with the
+      <varname>ResolveUnicastSingleLabel=yes</varname> setting. The details of which servers are queried and
+      how the final reply is chosen are described below. Note that this means that address queries for
+      single-label names are never sent out to remote DNS servers by default, and if no search domains are
+      defined, resolution will fail.</para></listitem>
 
       <listitem><para>Other multi-label names are routed to all local interfaces that have a DNS server
       configured, plus the globally configured DNS servers if there are any. Note that by default, lookups for
index f5db55511fda50d40ee3e55f21eb5c30e5e20da9..aa8a3f75bc547646545bdb5496589f3ea100bc8a 100644 (file)
         <xi:include href="system-only.xml" xpointer="singular"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>RootHash=</varname></term>
+
+        <listitem><para>Takes a data integrity (dm-verity) root hash specified in hexadecimal, or the path to a file
+        containing a root hash in ASCII hexadecimal format. This option enables data integrity checks using dm-verity,
+        if the used image contains the appropriate integrity data (see above) or if <varname>RootVerity=</varname> is used.
+        The specified hash must match the root hash of integrity data, and is usually at least 256 bits (and hence 64
+        formatted hexadecimal characters) long (in case of SHA256 for example). If this option is not specified, but
+        the image file carries the <literal>user.verity.roothash</literal> extended file attribute (see <citerefentry
+        project='man-pages'><refentrytitle>xattr</refentrytitle><manvolnum>7</manvolnum></citerefentry>), then the root
+        hash is read from it, also as formatted hexadecimal characters. If the extended file attribute is not found (or
+        is not supported by the underlying file system), but a file with the <filename>.roothash</filename> suffix is
+        found next to the image file, bearing otherwise the same name (except if the image has the
+        <filename>.raw</filename> suffix, in which case the root hash file must not have it in its name), the root hash
+        is read from it and automatically used, also as formatted hexadecimal characters.</para>
+
+        <xi:include href="system-only.xml" xpointer="singular"/></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>RootVerity=</varname></term>
+
+        <listitem><para>Takes the path to a data integrity (dm-verity) file. This option enables data integrity checks
+        using dm-verity, if <varname>RootImage=</varname> is used and a root-hash is passed and if the used image itself
+        does not contains the integrity data. The integrity data must be matched by the root hash. If this option is not
+        specified, but a file with the <filename>.verity</filename> suffix is found next to the image file, bearing otherwise
+        the same name (except if the image has the <filename>.raw</filename> suffix, in which case the verity data file must
+        not have it in its name), the verity data is read from it and automatically used.</para>
+
+        <para>This option is supported only for disk images that contain a single file system, without an enveloping partition
+        table. Images that contain a GPT partition table should instead include both root file system and matching Verity
+        data in the same image, implementing the
+        [Discoverable Partition Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)</para>
+
+        <xi:include href="system-only.xml" xpointer="singular"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>MountAPIVFS=</varname></term>
 
index 6d3568576cd5b90ce30c53c78073b105f3a0331a..aa368732fbbea03a2c2a26fe1af336f093e38bf9 100644 (file)
       </varlistentry>
 
       <varlistentry>
-        <term><varname>IPIngressFilterPath=<replaceable>BPF_FS_PROGRAMM_PATH</replaceable></varname></term>
-        <term><varname>IPEgressFilterPath=<replaceable>BPF_FS_PROGRAMM_PATH</replaceable></varname></term>
+        <term><varname>IPIngressFilterPath=<replaceable>BPF_FS_PROGRAM_PATH</replaceable></varname></term>
+        <term><varname>IPEgressFilterPath=<replaceable>BPF_FS_PROGRAM_PATH</replaceable></varname></term>
 
         <listitem>
           <para>Add custom network traffic filters implemented as BPF programs, applying to all IP packets
index 4a679449ce2793014afdde5823d66887d792c355..8f1d1b58971beb6b017065a2d17e5fdc1dd909cb 100644 (file)
@@ -1660,7 +1660,7 @@ test_dlopen = executable(
         build_by_default : want_tests != 'false')
 
 foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
-                 ['systemd',    'ENABLE_NSS_SYSTEMD', 'src/nss-systemd/userdb-glue.c src/nss-systemd/userdb-glue.h'],
+                 ['systemd',    'ENABLE_NSS_SYSTEMD', 'src/nss-systemd/userdb-glue.c src/nss-systemd/userdb-glue.h src/nss-systemd/nss-systemd.h'],
                  ['mymachines', 'ENABLE_NSS_MYMACHINES'],
                  ['resolve',    'ENABLE_NSS_RESOLVE']]
 
index 50747a19881d8adbe1433978123507a3f26bdcfc..cef78f9d687abb1d4f92c78c8a495f5c179c6860 100644 (file)
@@ -10,8 +10,9 @@ SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-
 SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
 SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
 
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb", GOTO="default_hwdb_imported"
 ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
+LABEL="default_hwdb_imported"
 
 ACTION!="add", GOTO="default_end"
 
diff --git a/rules.d/60-autosuspend.rules b/rules.d/60-autosuspend.rules
new file mode 100644 (file)
index 0000000..1f9ebef
--- /dev/null
@@ -0,0 +1,14 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION!="add", GOTO="autosuspend_end"
+
+# I2C rules
+SUBSYSTEM=="i2c", ATTR{name}=="cyapa", \
+  ATTR{power/control}="on", GOTO="autosuspend_end"
+
+# Enable autosuspend if hwdb says so. Here we are relying on
+# the hwdb import done earlier based on MODALIAS.
+ENV{ID_AUTOSUSPEND}=="1", TEST=="power/control", \
+  ATTR{power/control}="auto"
+
+LABEL="autosuspend_end"
index f303e27fd54cfa4c82804cf2b3486202284548d0..b1626650b7f2e4b0be4c1629958a95c83817a63a 100644 (file)
@@ -4,8 +4,9 @@ ACTION=="remove", GOTO="serial_end"
 SUBSYSTEM!="tty", GOTO="serial_end"
 
 SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
-SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
-SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+# We already ran the hwdb builtin for devices with MODALIAS in 50-default.rules.
+# Let's cover the remaining case here, where we walk up the tree to find a node with $MODALIAS.
+ENV{MODALIAS}=="", SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
 
 # /dev/serial/by-path/, /dev/serial/by-id/ for USB devices
 KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end"
diff --git a/rules.d/61-autosuspend-manual.rules b/rules.d/61-autosuspend-manual.rules
deleted file mode 100644 (file)
index 2b973af..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# This udev rule is for any devices that should enter automatic suspend
-# but are not already included in generated rules from Chromium OS via
-# tools/make-autosuspend-rules.py
-#
-
-ACTION!="add", GOTO="autosuspend_manual_end"
-SUBSYSTEM!="usb", GOTO="autosuspend_manual_end"
-
-SUBSYSTEM=="usb", GOTO="autosuspend_manual_usb"
-
-# USB rules
-LABEL="autosuspend_manual_usb"
-GOTO="autosuspend_manual_end"
-
-# Enable autosuspend
-LABEL="autosuspend_manual_enable"
-TEST=="power/control", ATTR{power/control}="auto", GOTO="autosuspend_manual_end"
-
-LABEL="autosuspend_manual_end"
index 13d1d330cf5e2c67d43479b59aacb782101a2306..ca4445d7748e08e6af3d4faf73b8373fcb906eec 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 rules = files('''
+        60-autosuspend.rules
         60-block.rules
         60-cdrom_id.rules
         60-drm.rules
@@ -14,7 +15,6 @@ rules = files('''
         60-persistent-v4l.rules
         60-sensor.rules
         60-serial.rules
-        61-autosuspend-manual.rules
         70-joystick.rules
         70-mouse.rules
         70-touchpad.rules
@@ -45,11 +45,3 @@ foreach file : rules_in
                      install_dir : udevrulesdir)
         all_rules += gen
 endforeach
-
-auto_suspend_rules = custom_target(
-        '60-autosuspend-chromiumos.rules',
-        output : '60-autosuspend-chromiumos.rules',
-        command : make_autosuspend_rules_py,
-        capture : true,
-        install : true,
-        install_dir: [udevrulesdir])
index faf50d2ac315663e9a7ab211a319765220f140c3..a8bd993cbe5f34baa5e0a9f23f098d119854c183 100644 (file)
@@ -2376,9 +2376,7 @@ static int run(int argc, char *argv[]) {
         setlocale(LC_ALL, "");
         setlocale(LC_NUMERIC, "C"); /* we want to format/parse floats in C style */
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
diff --git a/src/basic/dlfcn-util.h b/src/basic/dlfcn-util.h
new file mode 100644 (file)
index 0000000..d254afb
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <dlfcn.h>
+
+#include "macro.h"
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(void*, dlclose);
index 15c8c4723c0480a2499da376d88f8bd50eb844e8..67c439123078d154afd49e2e7b34e926b349c20e 100644 (file)
@@ -768,7 +768,7 @@ static void reset_direct_storage(HashmapBase *h) {
         memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
 }
 
-static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
+static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type  HASHMAP_DEBUG_PARAMS) {
         HashmapBase *h;
         const struct hashmap_type_info *hi = &hashmap_type_info[type];
         bool up;
@@ -808,19 +808,19 @@ static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enu
 }
 
 Hashmap *_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (Hashmap*)        hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
+        return (Hashmap*)        hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
+        return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 Set *_set_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return (Set*)            hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
+        return (Set*)            hashmap_base_new(hash_ops, HASHMAP_TYPE_SET  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops *hash_ops,
-                                         enum HashmapType type HASHMAP_DEBUG_PARAMS) {
+                                         enum HashmapType type  HASHMAP_DEBUG_PARAMS) {
         HashmapBase *q;
 
         assert(h);
@@ -828,7 +828,7 @@ static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops
         if (*h)
                 return 0;
 
-        q = hashmap_base_new(hash_ops, type HASHMAP_DEBUG_PASS_ARGS);
+        q = hashmap_base_new(hash_ops, type  HASHMAP_DEBUG_PASS_ARGS);
         if (!q)
                 return -ENOMEM;
 
@@ -837,15 +837,15 @@ static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops
 }
 
 int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
+        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
+        return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS) {
-        return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
+        return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET  HASHMAP_DEBUG_PASS_ARGS);
 }
 
 static void hashmap_free_no_clear(HashmapBase *h) {
@@ -1247,6 +1247,30 @@ int set_put(Set *s, const void *key) {
         return hashmap_put_boldly(s, hash, &swap, true);
 }
 
+int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key  HASHMAP_DEBUG_PARAMS) {
+        int r;
+
+        r = _set_ensure_allocated(s, hash_ops  HASHMAP_DEBUG_PASS_ARGS);
+        if (r < 0)
+                return r;
+
+        return set_put(*s, key);
+}
+
+int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key  HASHMAP_DEBUG_PARAMS) {
+        int r;
+
+        r = _set_ensure_put(s, hash_ops, key  HASHMAP_DEBUG_PASS_ARGS);
+        if (r <= 0) {
+                if (hash_ops && hash_ops->free_key)
+                        hash_ops->free_key(key);
+                else
+                        free(key);
+        }
+
+        return r;
+}
+
 int hashmap_replace(Hashmap *h, const void *key, void *value) {
         struct swap_entries swap;
         struct plain_hashmap_entry *e;
@@ -1687,13 +1711,13 @@ int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
         return 0;
 }
 
-HashmapBase *_hashmap_copy(HashmapBase *h) {
+HashmapBase *_hashmap_copy(HashmapBase *h  HASHMAP_DEBUG_PARAMS) {
         HashmapBase *copy;
         int r;
 
         assert(h);
 
-        copy = hashmap_base_new(h->hash_ops, h->type  HASHMAP_DEBUG_SRC_ARGS);
+        copy = hashmap_base_new(h->hash_ops, h->type  HASHMAP_DEBUG_PASS_ARGS);
         if (!copy)
                 return NULL;
 
@@ -1709,10 +1733,8 @@ HashmapBase *_hashmap_copy(HashmapBase *h) {
                 assert_not_reached("Unknown hashmap type");
         }
 
-        if (r < 0) {
-                _hashmap_free(copy, false, false);
-                return NULL;
-        }
+        if (r < 0)
+                return _hashmap_free(copy, false, false);
 
         return copy;
 }
@@ -1765,10 +1787,10 @@ int set_consume(Set *s, void *value) {
         return r;
 }
 
-int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
+int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v  HASHMAP_DEBUG_PARAMS) {
         int r;
 
-        r = hashmap_ensure_allocated(h, &string_hash_ops_free_free);
+        r = _hashmap_ensure_allocated(h, &string_hash_ops_free_free  HASHMAP_DEBUG_PASS_ARGS);
         if (r < 0)
                 return r;
 
@@ -1799,14 +1821,14 @@ int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
         return r;
 }
 
-int set_put_strdup(Set **s, const char *p) {
+int _set_put_strdup(Set **s, const char *p  HASHMAP_DEBUG_PARAMS) {
         char *c;
         int r;
 
         assert(s);
         assert(p);
 
-        r = set_ensure_allocated(s, &string_hash_ops_free);
+        r = _set_ensure_allocated(s, &string_hash_ops_free  HASHMAP_DEBUG_PASS_ARGS);
         if (r < 0)
                 return r;
 
@@ -1820,14 +1842,14 @@ int set_put_strdup(Set **s, const char *p) {
         return set_consume(*s, c);
 }
 
-int set_put_strdupv(Set **s, char **l) {
+int _set_put_strdupv(Set **s, char **l  HASHMAP_DEBUG_PARAMS) {
         int n = 0, r;
         char **i;
 
         assert(s);
 
         STRV_FOREACH(i, l) {
-                r = set_put_strdup(s, *i);
+                r = _set_put_strdup(s, *i  HASHMAP_DEBUG_PASS_ARGS);
                 if (r < 0)
                         return r;
 
index 230d322213bae8e610e1716401a9637c96a7f9a1..6009441621596c310afbabd8466631f0744a8c56 100644 (file)
@@ -128,13 +128,9 @@ static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h)
 IteratedCache *iterated_cache_free(IteratedCache *cache);
 int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
 
-HashmapBase *_hashmap_copy(HashmapBase *h);
-static inline Hashmap *hashmap_copy(Hashmap *h) {
-        return (Hashmap*) _hashmap_copy(HASHMAP_BASE(h));
-}
-static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
-        return (OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h));
-}
+HashmapBase *_hashmap_copy(HashmapBase *h  HASHMAP_DEBUG_PARAMS);
+#define hashmap_copy(h) ((Hashmap*) _hashmap_copy(HASHMAP_BASE(h)  HASHMAP_DEBUG_SRC_ARGS))
+#define ordered_hashmap_copy(h) ((OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h)  HASHMAP_DEBUG_SRC_ARGS))
 
 int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
 int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
@@ -154,7 +150,8 @@ static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *
         return hashmap_put(PLAIN_HASHMAP(h), key, value);
 }
 
-int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
+int _hashmap_put_strdup(Hashmap **h, const char *k, const char *v  HASHMAP_DEBUG_PARAMS);
+#define hashmap_put_strdup(h, k, v) _hashmap_put_strdup(h, k, v  HASHMAP_DEBUG_SRC_ARGS)
 
 int hashmap_update(Hashmap *h, const void *key, void *value);
 static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
index ca024d970e6bec9256d8ea687cd32693504417ef..c6fe20380830b9e6ff78ac869b392c213798565e 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <sys/signalfd.h>
+#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <sys/un.h>
@@ -219,6 +220,32 @@ fail:
         return r;
 }
 
+static bool stderr_is_journal(void) {
+        _cleanup_free_ char *w = NULL;
+        const char *e;
+        uint64_t dev, ino;
+        struct stat st;
+
+        e = getenv("JOURNAL_STREAM");
+        if (!e)
+                return false;
+
+        if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
+                return false;
+        if (!e)
+                return false;
+
+        if (safe_atou64(w, &dev) < 0)
+                return false;
+        if (safe_atou64(e, &ino) < 0)
+                return false;
+
+        if (fstat(STDERR_FILENO, &st) < 0)
+                return false;
+
+        return st.st_dev == dev && st.st_ino == ino;
+}
+
 int log_open(void) {
         int r;
 
@@ -238,9 +265,7 @@ int log_open(void) {
                 return 0;
         }
 
-        if (log_target != LOG_TARGET_AUTO ||
-            getpid_cached() == 1 ||
-            isatty(STDERR_FILENO) <= 0) {
+        if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) {
 
                 if (!prohibit_ipc &&
                     IN_SET(log_target, LOG_TARGET_AUTO,
@@ -1121,16 +1146,20 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
 }
 
 void log_parse_environment_realm(LogRealm realm) {
-        /* Do not call from library code. */
-
-        const char *e;
-
         if (getpid_cached() == 1 || get_ctty_devnr(0, NULL) < 0)
                 /* Only try to read the command line in daemons. We assume that anything that has a
                  * controlling tty is user stuff. For PID1 we do a special check in case it hasn't
                  * closed the console yet. */
                 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
 
+        log_parse_environment_cli_realm(realm);
+}
+
+void log_parse_environment_cli_realm(LogRealm realm) {
+        /* Do not call from library code. */
+
+        const char *e;
+
         e = getenv("SYSTEMD_LOG_TARGET");
         if (e && log_set_target_from_string(e) < 0)
                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
@@ -1405,3 +1434,11 @@ void log_setup_service(void) {
         log_parse_environment();
         (void) log_open();
 }
+
+void log_setup_cli(void) {
+        /* Sets up logging the way it is most appropriate for running a program as a CLI utility. */
+
+        log_show_color(true);
+        log_parse_environment_cli();
+        (void) log_open();
+}
index 2c1b00fb88f07d0c248e7f9fc015536238457115..15807d3029f95e76e20da8be0526223094e9b4bf 100644 (file)
@@ -84,8 +84,11 @@ void log_close(void);
 void log_forget_fds(void);
 
 void log_parse_environment_realm(LogRealm realm);
+void log_parse_environment_cli_realm(LogRealm realm);
 #define log_parse_environment() \
         log_parse_environment_realm(LOG_REALM)
+#define log_parse_environment_cli() \
+        log_parse_environment_cli_realm(LOG_REALM)
 
 int log_dispatch_internal(
                 int level,
@@ -341,3 +344,4 @@ int log_syntax_invalid_utf8_internal(
 #define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
 
 void log_setup_service(void);
+void log_setup_cli(void);
index a6a2ccdbc299bf932c9fd3ec5bf64a491a37d6e2..4f596cffb75bc2d9fd28c94df8b5d9020bcbddd3 100644 (file)
@@ -13,6 +13,7 @@
 size_t page_size(void) _pure_;
 #define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
 #define PAGE_ALIGN_DOWN(l) ((l) & ~(page_size() - 1))
+#define PAGE_OFFSET(l) ((l) & (page_size() - 1))
 
 /* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
 static inline void memcpy_safe(void *dst, const void *src, size_t n) {
index 5bb49ef4014b2cd9aa9008cc408fd21a00387c61..90924d6cb895525e1becade481fff0eb5a6600b6 100644 (file)
@@ -39,6 +39,7 @@ basic_sources = files('''
         device-nodes.h
         dirent-util.c
         dirent-util.h
+        dlfcn-util.h
         efivars.c
         efivars.h
         env-file.c
@@ -328,7 +329,8 @@ libbasic = static_library(
                         threads,
                         libcap,
                         libselinux,
-                        libm],
+                        libm,
+                        libdl],
         c_args : ['-fvisibility=default'],
         install : false)
 
index 33ff427ae7a71362b80950580a6792291b180899..80bd65b1558d1a9376b50005c8a122a687c04978 100644 (file)
@@ -39,7 +39,18 @@ static int cached_enforcing = -1;
 static struct selabel_handle *label_hnd = NULL;
 
 #define log_enforcing(...) log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __VA_ARGS__)
-#define log_enforcing_errno(r, ...) log_full_errno(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, r, __VA_ARGS__)
+
+#define log_enforcing_errno(error, ...)                                 \
+        ({                                                              \
+                bool _enforcing = mac_selinux_enforcing();              \
+                int _level = _enforcing ? LOG_ERR : LOG_WARNING;        \
+                int _e = (error);                                       \
+                                                                        \
+                int _r = (log_get_max_level() >= LOG_PRI(_level))       \
+                        ? log_internal_realm(_level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
+                        : -ERRNO_VALUE(_e);                             \
+                _enforcing ? _r : 0;                                    \
+        })
 #endif
 
 bool mac_selinux_use(void) {
@@ -59,14 +70,15 @@ bool mac_selinux_enforcing(void) {
 #if HAVE_SELINUX
         if (_unlikely_(cached_enforcing < 0)) {
                 cached_enforcing = security_getenforce();
-                if (cached_enforcing == -1)
-                        log_error_errno(errno, "Failed to get SELinux enforced status, continue in enforcing mode: %m");
-                else
-                        log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive");
+                if (cached_enforcing < 0) {
+                        log_debug_errno(errno, "Failed to get SELinux enforced status, continuing in enforcing mode: %m");
+                        return true; /* treat failure as enforcing mode */
+                }
+
+                log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive");
         }
 
-        /* treat failure as enforcing mode */
-        return (cached_enforcing != 0);
+        return cached_enforcing > 0;
 #else
         return false;
 #endif
@@ -90,11 +102,11 @@ static int setenforce_callback(int enforcing) {
 #endif
 
 int mac_selinux_init(void) {
-        int r = 0;
-
 #if HAVE_SELINUX
         usec_t before_timestamp, after_timestamp;
         struct mallinfo before_mallinfo, after_mallinfo;
+        char timespan[FORMAT_TIMESPAN_MAX];
+        int l;
 
         selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload);
         selinux_set_callback(SELINUX_CB_SETENFORCE, (union selinux_callback) setenforce_callback);
@@ -109,25 +121,20 @@ int mac_selinux_init(void) {
         before_timestamp = now(CLOCK_MONOTONIC);
 
         label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-        if (!label_hnd) {
-                log_enforcing_errno(errno, "Failed to initialize SELinux context: %m");
-                r = mac_selinux_enforcing() ? -errno : 0;
-        } else  {
-                char timespan[FORMAT_TIMESPAN_MAX];
-                int l;
+        if (!label_hnd)
+                return log_enforcing_errno(errno, "Failed to initialize SELinux labeling handle: %m");
 
-                after_timestamp = now(CLOCK_MONOTONIC);
-                after_mallinfo = mallinfo();
+        after_timestamp = now(CLOCK_MONOTONIC);
+        after_mallinfo = mallinfo();
 
-                l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
+        l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
 
-                log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
-                          format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
-                          (l+1023)/1024);
-        }
-#endif
+        log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
+                  format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
+                  (l+1023)/1024);
 
-        return r;
+#endif
+        return 0;
 }
 
 void mac_selinux_finish(void) {
@@ -226,9 +233,7 @@ int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFi
         return 0;
 
 fail:
-        log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path);
-        if (mac_selinux_enforcing())
-                return r;
+        return log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path);
 #endif
 
         return 0;
@@ -243,21 +248,17 @@ int mac_selinux_apply(const char *path, const char *label) {
         assert(path);
         assert(label);
 
-        if (setfilecon(path, label) < 0) {
-                log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
-                if (mac_selinux_enforcing())
-                        return -errno;
-        }
+        if (setfilecon(path, label) < 0)
+                return log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
 #endif
         return 0;
 }
 
 int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
-        int r = -EOPNOTSUPP;
-
 #if HAVE_SELINUX
         _cleanup_freecon_ char *mycon = NULL, *fcon = NULL;
         security_class_t sclass;
+        int r;
 
         assert(exe);
         assert(label);
@@ -280,36 +281,39 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
         r = security_compute_create_raw(mycon, fcon, sclass, label);
         if (r < 0)
                 return -errno;
-#endif
 
-        return r;
+        return 0;
+#else
+        return -EOPNOTSUPP;
+#endif
 }
 
 int mac_selinux_get_our_label(char **label) {
-        int r = -EOPNOTSUPP;
+#if HAVE_SELINUX
+        int r;
 
         assert(label);
 
-#if HAVE_SELINUX
         if (!mac_selinux_use())
                 return -EOPNOTSUPP;
 
         r = getcon_raw(label);
         if (r < 0)
                 return -errno;
-#endif
 
-        return r;
+        return 0;
+#else
+        return -EOPNOTSUPP;
+#endif
 }
 
 int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label) {
-        int r = -EOPNOTSUPP;
-
 #if HAVE_SELINUX
         _cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL;
         _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
         security_class_t sclass;
         const char *range = NULL;
+        int r;
 
         assert(socket_fd >= 0);
         assert(exe);
@@ -362,21 +366,19 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
         r = security_compute_create_raw(mycon, fcon, sclass, label);
         if (r < 0)
                 return -errno;
-#endif
 
-        return r;
+        return 0;
+#else
+        return -EOPNOTSUPP;
+#endif
 }
 
 char* mac_selinux_free(char *label) {
 
 #if HAVE_SELINUX
-        if (!label)
-                return NULL;
-
-        if (!mac_selinux_use())
-                return NULL;
-
         freecon(label);
+#else
+        assert(!label);
 #endif
 
         return NULL;
@@ -399,26 +401,21 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
                 if (errno == ENOENT)
                         return 0;
 
-                log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
-        } else {
-                if (setfscreatecon_raw(filecon) >= 0)
-                        return 0; /* Success! */
-
-                log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
+                return log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
         }
 
-        if (mac_selinux_enforcing())
-                return -errno;
+        if (setfscreatecon_raw(filecon) < 0)
+                return log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
 
         return 0;
 }
 #endif
 
 int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) {
-        int r = 0;
-
 #if HAVE_SELINUX
         _cleanup_free_ char *abspath = NULL;
+        int r;
+
 
         assert(path);
 
@@ -440,15 +437,16 @@ int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode)
                         return -ENOMEM;
         }
 
-        r = selinux_create_file_prepare_abspath(path, mode);
+        return selinux_create_file_prepare_abspath(path, mode);
+#else
+        return 0;
 #endif
-        return r;
 }
 
 int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
-        int r = 0;
-
 #if HAVE_SELINUX
+        int r;
+
         _cleanup_free_ char *abspath = NULL;
 
         assert(path);
@@ -460,9 +458,10 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
         if (r < 0)
                 return r;
 
-        r = selinux_create_file_prepare_abspath(abspath, mode);
+        return selinux_create_file_prepare_abspath(abspath, mode);
+#else
+        return 0;
 #endif
-        return r;
 }
 
 void mac_selinux_create_file_clear(void) {
@@ -480,17 +479,13 @@ void mac_selinux_create_file_clear(void) {
 int mac_selinux_create_socket_prepare(const char *label) {
 
 #if HAVE_SELINUX
-        if (!mac_selinux_use())
-                return 0;
-
         assert(label);
 
-        if (setsockcreatecon(label) < 0) {
-                log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
+        if (!mac_selinux_use())
+                return 0;
 
-                if (mac_selinux_enforcing())
-                        return -errno;
-        }
+        if (setsockcreatecon(label) < 0)
+                return log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
 #endif
 
         return 0;
@@ -561,15 +556,14 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
                 if (errno == ENOENT)
                         goto skipped;
 
-                log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
-                if (mac_selinux_enforcing())
-                        return -errno;
-
+                r = log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
+                if (r < 0)
+                        return r;
         } else {
                 if (setfscreatecon_raw(fcon) < 0) {
-                        log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
-                        if (mac_selinux_enforcing())
-                                return -errno;
+                        r = log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
+                        if (r < 0)
+                                return r;
                 } else
                         context_changed = true;
         }
@@ -577,7 +571,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
         r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
 
         if (context_changed)
-                setfscreatecon_raw(NULL);
+                (void) setfscreatecon_raw(NULL);
 
         return r;
 
index 621e83bf2773a6b1d40e03d6fb8d173b9f8f0e4a..e4fc1e3c4a01755fbd76873f8a45efee8879c782 100644 (file)
@@ -26,9 +26,7 @@ static inline Set *set_free_free(Set *s) {
 
 /* no set_free_free_free */
 
-static inline Set *set_copy(Set *s) {
-        return (Set*) _hashmap_copy(HASHMAP_BASE(s));
-}
+#define set_copy(s) ((Set*) _hashmap_copy(HASHMAP_BASE(h)  HASHMAP_DEBUG_SRC_ARGS))
 
 int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
 #define set_ensure_allocated(h, ops) _set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
@@ -120,9 +118,19 @@ static inline char **set_get_strv(Set *s) {
         return _hashmap_get_strv(HASHMAP_BASE(s));
 }
 
+int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key  HASHMAP_DEBUG_PARAMS);
+#define set_ensure_put(s, hash_ops, key) _set_ensure_put(s, hash_ops, key  HASHMAP_DEBUG_SRC_ARGS)
+
+int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key  HASHMAP_DEBUG_PARAMS);
+#define set_ensure_consume(s, hash_ops, key) _set_ensure_consume(s, hash_ops, key  HASHMAP_DEBUG_SRC_ARGS)
+
 int set_consume(Set *s, void *value);
-int set_put_strdup(Set **s, const char *p);
-int set_put_strdupv(Set **s, char **l);
+
+int _set_put_strdup(Set **s, const char *p  HASHMAP_DEBUG_PARAMS);
+#define set_put_strdup(s, p) _set_put_strdup(s, p  HASHMAP_DEBUG_SRC_ARGS)
+int _set_put_strdupv(Set **s, char **l  HASHMAP_DEBUG_PARAMS);
+#define set_put_strdupv(s, l) _set_put_strdupv(s, l  HASHMAP_DEBUG_SRC_ARGS)
+
 int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
 
 #define SET_FOREACH(e, s, i) \
index 8e000ee1196b98b0e20ab3dadb04386e441c41bc..3ab90de63e2ae6090987f55dff0f854bb1f98caf 100644 (file)
@@ -2598,9 +2598,7 @@ static int busctl_main(int argc, char *argv[]) {
 static int run(int argc, char *argv[]) {
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index b55d7299cabf03529f44669af5a8d6578d01c6d2..939a391e21cc85edcf17031101ea81aa0da3465a 100644 (file)
@@ -164,9 +164,7 @@ static void show_cg_info(const char *controller, const char *path) {
 static int run(int argc, char *argv[]) {
         int r, output_flags;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index de25aaae5d1db02df04b08a60596ab30e139eb6d..e6c09d1b38bcc193e3b94af10e1c8bcff32c6abc 100644 (file)
@@ -908,9 +908,7 @@ static int run(int argc, char *argv[]) {
         CGroupMask mask;
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 566b56eb349ee667ea537b45fb9cc6af1db392ea..77420b929fd39c0d60b6e52783d7b699a29a28ba 100644 (file)
@@ -912,13 +912,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
                 if (safe_atou(value, &token) < 0)
                         log_unit_debug(u, "Failed to parse token value: %s", value);
                 else {
-                        r = set_ensure_allocated(&a->tokens, NULL);
-                        if (r < 0) {
-                                log_oom();
-                                return 0;
-                        }
-
-                        r = set_put(a->tokens, UINT_TO_PTR(token));
+                        r = set_ensure_put(&a->tokens, NULL, UINT_TO_PTR(token));
                         if (r < 0)
                                 log_unit_error_errno(u, r, "Failed to add token to set: %m");
                 }
@@ -928,13 +922,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
                 if (safe_atou(value, &token) < 0)
                         log_unit_debug(u, "Failed to parse token value: %s", value);
                 else {
-                        r = set_ensure_allocated(&a->expire_tokens, NULL);
-                        if (r < 0) {
-                                log_oom();
-                                return 0;
-                        }
-
-                        r = set_put(a->expire_tokens, UINT_TO_PTR(token));
+                        r = set_ensure_put(&a->expire_tokens, NULL, UINT_TO_PTR(token));
                         if (r < 0)
                                 log_unit_error_errno(u, r, "Failed to add expire token to set: %m");
                 }
@@ -1010,13 +998,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
                 } else
                         log_unit_debug(UNIT(a), "Got direct mount request on %s", a->where);
 
-                r = set_ensure_allocated(&a->tokens, NULL);
-                if (r < 0) {
-                        log_unit_error(UNIT(a), "Failed to allocate token set.");
-                        goto fail;
-                }
-
-                r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
+                r = set_ensure_put(&a->tokens, NULL, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
                 if (r < 0) {
                         log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
                         goto fail;
@@ -1030,13 +1012,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
 
                 automount_stop_expire(a);
 
-                r = set_ensure_allocated(&a->expire_tokens, NULL);
-                if (r < 0) {
-                        log_unit_error(UNIT(a), "Failed to allocate token set.");
-                        goto fail;
-                }
-
-                r = set_put(a->expire_tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
+                r = set_ensure_put(&a->expire_tokens, NULL, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
                 if (r < 0) {
                         log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
                         goto fail;
index 96c1a28b4fd02adb70e939b564afec32c54c11fb..2ec274df018bfe498981fbe6a208cdb0b8eb37f3 100644 (file)
@@ -595,7 +595,7 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
         set_clear(*set);
 
         STRV_FOREACH(bpf_fs_path, filter_paths) {
-                _cleanup_free_ BPFProgram *prog = NULL;
+                _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
                 int r;
 
                 r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &prog);
@@ -606,14 +606,9 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Loading of ingress BPF program %s failed: %m", *bpf_fs_path);
 
-                r = set_ensure_allocated(set, &filter_prog_hash_ops);
-                if (r < 0)
-                        return log_unit_error_errno(u, r, "Can't allocate BPF program set: %m");
-
-                r = set_put(*set, prog);
+                r = set_ensure_consume(set, &filter_prog_hash_ops, TAKE_PTR(prog));
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m");
-                TAKE_PTR(prog);
         }
 
         return 0;
@@ -662,12 +657,9 @@ static int attach_custom_bpf_progs(Unit *u, const char *path, int attach_type, S
                 r = bpf_program_cgroup_attach(prog, attach_type, path, BPF_F_ALLOW_MULTI);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Attaching custom egress BPF program to cgroup %s failed: %m", path);
-                /* Remember that these BPF programs are installed now. */
-                r = set_ensure_allocated(set_installed, &filter_prog_hash_ops);
-                if (r < 0)
-                        return log_unit_error_errno(u, r, "Can't allocate BPF program set: %m");
 
-                r = set_put(*set_installed, prog);
+                /* Remember that these BPF programs are installed now. */
+                r = set_ensure_put(set_installed, &filter_prog_hash_ops, prog);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m");
                 bpf_program_ref(prog);
index 8587a712e20b62a80aa6d8dd048f487e2b9956a2..080f6fb1aed0225f450f750f1bad96a6fa25d47f 100644 (file)
@@ -707,112 +707,14 @@ static int bus_cgroup_set_boolean(
                 return 1;                                               \
         }
 
-#define BUS_DEFINE_SET_CGROUP_PROTECTION(function, mask, scale)         \
-        static int bus_cgroup_set_##function(                           \
-                        Unit *u,                                        \
-                        const char *name,                               \
-                        uint64_t *p,                                    \
-                        bool *s,                                        \
-                        sd_bus_message *message,                        \
-                        UnitWriteFlags flags,                           \
-                        sd_bus_error *error) {                          \
-                                                                        \
-                uint64_t v = CGROUP_LIMIT_MIN;                          \
-                bool nonempty = true;                                   \
-                char type;                                              \
-                int r;                                                  \
-                                                                        \
-                assert(p);                                              \
-                assert(s);                                              \
-                                                                        \
-                r = sd_bus_message_peek_type(message, &type, NULL);     \
-                if (r < 0)                                              \
-                        return r;                                       \
-                if (type == SD_BUS_TYPE_BOOLEAN) {                      \
-                        r = sd_bus_message_read(message, "b", &nonempty); \
-                        if (r < 0)                                      \
-                                return r;                               \
-                        /* Bool is used to denote empty value only */   \
-                        if (nonempty)                                   \
-                                return -EINVAL;                         \
-                } else if (type != SD_BUS_TYPE_UINT64) {                \
-                        return -EINVAL;                                 \
-                } else {                                                \
-                        r = sd_bus_message_read(message, "t", &v);      \
-                        if (r < 0)                                      \
-                                return r;                               \
-                }                                                       \
-                                                                        \
-                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {                    \
-                        *p = v;                                         \
-                        unit_invalidate_cgroup(u, mask);                \
-                        if (!nonempty) {                                \
-                                *s = false;                             \
-                                unit_write_settingf(u, flags, name,     \
-                                                    "%s=", name);       \
-                        } else if (v == CGROUP_LIMIT_MAX) {             \
-                                *s = true;                              \
-                                unit_write_settingf(u, flags, name,     \
-                                                    "%s=infinity", name); \
-                        } else {                                        \
-                                *s = true;                              \
-                                unit_write_settingf(u, flags, name,     \
-                                                    "%s=%" PRIu64, name, v); \
-                        }                                               \
-                }                                                       \
-                                                                        \
-                return 1;                                               \
-        }                                                               \
-        static int bus_cgroup_set_##function##_scale(                   \
-                        Unit *u,                                        \
-                        const char *name,                               \
-                        uint64_t *p,                                    \
-                        bool *s,                                        \
-                        sd_bus_message *message,                        \
-                        UnitWriteFlags flags,                           \
-                        sd_bus_error *error) {                          \
-                                                                        \
-                uint64_t v;                                             \
-                uint32_t raw;                                           \
-                int r;                                                  \
-                                                                        \
-                assert(p);                                              \
-                assert(s);                                              \
-                                                                        \
-                r = sd_bus_message_read(message, "u", &raw);            \
-                if (r < 0)                                              \
-                        return r;                                       \
-                                                                        \
-                v = scale(raw, UINT32_MAX);                             \
-                if (v >= UINT64_MAX)                                    \
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
-                                                 "Value specified in %s is out of range", name); \
-                                                                        \
-                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {                    \
-                        *p = v;                                         \
-                        unit_invalidate_cgroup(u, mask);                \
-                                                                        \
-                        /* Prepare to chop off suffix */                \
-                        assert_se(endswith(name, "Scale"));             \
-                                                                        \
-                        uint32_t scaled = DIV_ROUND_UP((uint64_t) raw * 1000, (uint64_t) UINT32_MAX); \
-                        unit_write_settingf(u, flags, name, "%.*s=%" PRIu32 ".%" PRIu32 "%%", \
-                                            (int)(strlen(name) - strlen("Scale")), name, \
-                                            scaled / 10, scaled % 10);  \
-                }                                                       \
-                                                                        \
-                *s = true;                                              \
-                return 1;                                               \
-        }
-
 DISABLE_WARNING_TYPE_LIMITS;
 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID);
 BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
 BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID);
 BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
+BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
 BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
-BUS_DEFINE_SET_CGROUP_PROTECTION(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale);
 REENABLE_WARNING;
 
 static int bus_cgroup_set_tasks_max(
@@ -938,17 +840,33 @@ int bus_cgroup_set_property(
         if (streq(name, "MemoryAccounting"))
                 return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error);
 
-        if (streq(name, "MemoryMin"))
-                return bus_cgroup_set_memory_protection(u, name, &c->memory_min, &c->memory_min_set, message, flags, error);
+        if (streq(name, "MemoryMin")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error);
+                if (r > 0)
+                        c->memory_min_set = true;
+                return r;
+        }
 
-        if (streq(name, "MemoryLow"))
-                return bus_cgroup_set_memory_protection(u, name, &c->memory_low, &c->memory_low_set, message, flags, error);
+        if (streq(name, "MemoryLow")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error);
+                if (r > 0)
+                        c->memory_low_set = true;
+                return r;
+        }
 
-        if (streq(name, "DefaultMemoryMin"))
-                return bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, &c->default_memory_min_set, message, flags, error);
+        if (streq(name, "DefaultMemoryMin")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error);
+                if (r > 0)
+                        c->default_memory_min_set = true;
+                return r;
+        }
 
-        if (streq(name, "DefaultMemoryLow"))
-                return bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, &c->default_memory_low_set, message, flags, error);
+        if (streq(name, "DefaultMemoryLow")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error);
+                if (r > 0)
+                        c->default_memory_low_set = true;
+                return r;
+        }
 
         if (streq(name, "MemoryHigh"))
                 return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
@@ -962,17 +880,33 @@ int bus_cgroup_set_property(
         if (streq(name, "MemoryLimit"))
                 return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
 
-        if (streq(name, "MemoryMinScale"))
-                return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, &c->memory_min_set, message, flags, error);
+        if (streq(name, "MemoryMinScale")) {
+                r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error);
+                if (r > 0)
+                        c->memory_min_set = true;
+                return r;
+        }
 
-        if (streq(name, "MemoryLowScale"))
-                return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, &c->memory_low_set, message, flags, error);
+        if (streq(name, "MemoryLowScale")) {
+                r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error);
+                if (r > 0)
+                        c->memory_low_set = true;
+                return r;
+        }
 
-        if (streq(name, "DefaultMemoryMinScale"))
-                return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, &c->default_memory_min_set, message, flags, error);
+        if (streq(name, "DefaultMemoryMinScale")) {
+                r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error);
+                if (r > 0)
+                        c->default_memory_min_set = true;
+                return r;
+        }
 
-        if (streq(name, "DefaultMemoryLowScale"))
-                return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, &c->default_memory_low_set, message, flags, error);
+        if (streq(name, "DefaultMemoryLowScale")) {
+                r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error);
+                if (r > 0)
+                        c->default_memory_low_set = true;
+                return r;
+        }
 
         if (streq(name, "MemoryHighScale"))
                 return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
index 06b6b95d6962966e1c2b2d4c92966e10cdeb3eb6..68ce395c56ff6d58dbac77fa7d5967330ea5dfe6 100644 (file)
@@ -746,6 +746,25 @@ static int property_get_log_extra_fields(
         return sd_bus_message_close_container(reply);
 }
 
+static int property_get_root_hash(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        ExecContext *c = userdata;
+
+        assert(bus);
+        assert(c);
+        assert(property);
+        assert(reply);
+
+        return sd_bus_message_append_array(reply, 'y', c->root_hash, c->root_hash_size);
+}
+
 const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -788,6 +807,9 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RootVerity", "s", NULL, offsetof(ExecContext, root_verity), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1258,6 +1280,55 @@ int bus_exec_context_set_transient_property(
         if (streq(name, "RootImage"))
                 return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
 
+        if (streq(name, "RootHash")) {
+                const void *roothash_decoded;
+                size_t roothash_decoded_size;
+
+                r = sd_bus_message_read_array(message, 'y', &roothash_decoded, &roothash_decoded_size);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        _cleanup_free_ char *encoded = NULL;
+
+                        if (roothash_decoded_size == 0) {
+                                c->root_hash_path = mfree(c->root_hash_path);
+                                c->root_hash = mfree(c->root_hash);
+                                c->root_hash_size = 0;
+
+                                unit_write_settingf(u, flags, name, "RootHash=");
+                        } else {
+                                _cleanup_free_ void *p;
+
+                                encoded = hexmem(roothash_decoded, roothash_decoded_size);
+                                if (!encoded)
+                                        return -ENOMEM;
+
+                                p = memdup(roothash_decoded, roothash_decoded_size);
+                                if (!p)
+                                        return -ENOMEM;
+
+                                free_and_replace(c->root_hash, p);
+                                c->root_hash_size = roothash_decoded_size;
+                                c->root_hash_path = mfree(c->root_hash_path);
+
+                                unit_write_settingf(u, flags, name, "RootHash=%s", encoded);
+                        }
+                }
+
+                return 1;
+        }
+
+        if (streq(name, "RootHashPath")) {
+                c->root_hash_size = 0;
+                c->root_hash = mfree(c->root_hash);
+
+                return bus_set_transient_path(u, "RootHash", &c->root_hash_path, message, flags, error);
+        }
+
+        if (streq(name, "RootVerity"))
+                return bus_set_transient_path(u, name, &c->root_verity, message, flags, error);
+
         if (streq(name, "RootDirectory"))
                 return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
 
@@ -1697,10 +1768,6 @@ int bus_exec_context_set_transient_property(
                         else {
                                 char **s;
 
-                                r = set_ensure_allocated(&c->syscall_archs, NULL);
-                                if (r < 0)
-                                        return r;
-
                                 STRV_FOREACH(s, l) {
                                         uint32_t a;
 
@@ -1708,7 +1775,7 @@ int bus_exec_context_set_transient_property(
                                         if (r < 0)
                                                 return r;
 
-                                        r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
+                                        r = set_ensure_put(&c->syscall_archs, NULL, UINT32_TO_PTR(a + 1));
                                         if (r < 0)
                                                 return r;
                                 }
index 2a3c8e776ac9b5a4f86a5370dc5b4c5c69203d58..5cb06867cb31b75cfb10e05a5cb5267afc2df509 100644 (file)
@@ -234,14 +234,12 @@ static int property_get_show_status(
                 sd_bus_error *error) {
 
         Manager *m = userdata;
-        int b;
 
+        assert(m);
         assert(bus);
         assert(reply);
-        assert(m);
 
-        b = IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
-        return sd_bus_message_append_basic(reply, 'b', &b);
+        return sd_bus_message_append(reply, "b", manager_get_show_status_on(m));
 }
 
 static int property_get_runtime_watchdog(
@@ -311,7 +309,7 @@ static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *
         if (r < 0)
                 return r;
 
-        return manager_set_watchdog_overridden(m, type, timeout);
+        return manager_override_watchdog(m, type, timeout);
 }
 
 static int property_set_runtime_watchdog(
@@ -2452,6 +2450,30 @@ static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_
         return bus_scope_method_abandon(message, u, error);
 }
 
+static int method_set_show_status(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Manager *m = userdata;
+        ShowStatus mode = _SHOW_STATUS_INVALID;
+        const char *t;
+        int r;
+
+        assert(m);
+        assert(message);
+
+        r = sd_bus_message_read(message, "s", &t);
+        if (r < 0)
+                return r;
+
+        if (!isempty(t)) {
+                mode = show_status_from_string(t);
+                if (mode < 0)
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid show status '%s'", t);
+        }
+
+        manager_override_show_status(m, mode, "bus");
+
+        return sd_bus_reply_method_return(message, NULL);
+}
+
 const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_VTABLE_START(0),
 
@@ -2786,6 +2808,12 @@ const sd_bus_vtable bus_manager_vtable[] = {
                       NULL,
                       method_reset_failed,
                       SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("SetShowStatus",
+                                 "s",
+                                 SD_BUS_PARAM(mode),
+                                 NULL,,
+                                 method_set_show_status,
+                                 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_ADMIN)),
         SD_BUS_METHOD_WITH_NAMES("ListUnits",
                                  NULL,,
                                  "a(ssssssouso)",
index 4330c0f2c1cd25e367d9f33f57ccdacce14433fd..1565a799270c01c2d988dfb648d4fb024a1c486e 100644 (file)
 #include "terminal-util.h"
 #include "virt.h"
 
+static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
+        [EMERGENCY_ACTION_NONE] =               "none",
+        [EMERGENCY_ACTION_REBOOT] =             "reboot",
+        [EMERGENCY_ACTION_REBOOT_FORCE] =       "reboot-force",
+        [EMERGENCY_ACTION_REBOOT_IMMEDIATE] =   "reboot-immediate",
+        [EMERGENCY_ACTION_POWEROFF] =           "poweroff",
+        [EMERGENCY_ACTION_POWEROFF_FORCE] =     "poweroff-force",
+        [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate",
+        [EMERGENCY_ACTION_EXIT] =               "exit",
+        [EMERGENCY_ACTION_EXIT_FORCE] =         "exit-force",
+};
+
 static void log_and_status(Manager *m, bool warn, const char *message, const char *reason) {
         log_full(warn ? LOG_WARNING : LOG_DEBUG, "%s: %s", message, reason);
         if (warn)
@@ -28,10 +40,22 @@ void emergency_action(
                 int exit_status,
                 const char *reason) {
 
+        Unit *u;
+
         assert(m);
         assert(action >= 0);
         assert(action < _EMERGENCY_ACTION_MAX);
 
+        /* Is the special shutdown target active or queued? If so, we are in shutdown state */
+        if (IN_SET(action, EMERGENCY_ACTION_REBOOT, EMERGENCY_ACTION_POWEROFF, EMERGENCY_ACTION_EXIT)) {
+                u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
+                if (u && unit_active_or_pending(u)) {
+                        log_notice("Shutdown is already active. Skipping emergency action request %s.",
+                                   emergency_action_table[action]);
+                        return;
+                }
+        }
+
         if (action == EMERGENCY_ACTION_NONE)
                 return;
 
@@ -126,17 +150,6 @@ void emergency_action(
         }
 }
 
-static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
-        [EMERGENCY_ACTION_NONE] = "none",
-        [EMERGENCY_ACTION_REBOOT] = "reboot",
-        [EMERGENCY_ACTION_REBOOT_FORCE] = "reboot-force",
-        [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
-        [EMERGENCY_ACTION_POWEROFF] = "poweroff",
-        [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
-        [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate",
-        [EMERGENCY_ACTION_EXIT] = "exit",
-        [EMERGENCY_ACTION_EXIT_FORCE] = "exit-force",
-};
 DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);
 
 int parse_emergency_action(
index aa253a5ddff0aaebf059c75bf3b5c13c6c9c954f..e0835f9b92ca778ad1f86e4861bfac5ae645badb 100644 (file)
@@ -54,6 +54,7 @@
 #include "format-util.h"
 #include "fs-util.h"
 #include "glob-util.h"
+#include "hexdecoct.h"
 #include "io-util.h"
 #include "ioprio.h"
 #include "label.h"
@@ -2666,6 +2667,7 @@ static int apply_mount_namespace(
                             needs_sandboxing ? context->protect_home : PROTECT_HOME_NO,
                             needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO,
                             context->mount_flags,
+                            context->root_hash, context->root_hash_size, context->root_hash_path, context->root_verity,
                             DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
                             error_path);
 
@@ -4195,6 +4197,10 @@ void exec_context_done(ExecContext *c) {
         c->working_directory = mfree(c->working_directory);
         c->root_directory = mfree(c->root_directory);
         c->root_image = mfree(c->root_image);
+        c->root_hash = mfree(c->root_hash);
+        c->root_hash_size = 0;
+        c->root_hash_path = mfree(c->root_hash_path);
+        c->root_verity = mfree(c->root_verity);
         c->tty_path = mfree(c->tty_path);
         c->syslog_identifier = mfree(c->syslog_identifier);
         c->user = mfree(c->user);
@@ -4599,6 +4605,19 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
         if (c->root_image)
                 fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
 
+        if (c->root_hash) {
+                _cleanup_free_ char *encoded = NULL;
+                encoded = hexmem(c->root_hash, c->root_hash_size);
+                if (encoded)
+                        fprintf(f, "%sRootHash: %s\n", prefix, encoded);
+        }
+
+        if (c->root_hash_path)
+                fprintf(f, "%sRootHash: %s\n", prefix, c->root_hash_path);
+
+        if (c->root_verity)
+                fprintf(f, "%sRootVerity: %s\n", prefix, c->root_verity);
+
         STRV_FOREACH(e, c->environment)
                 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
 
index 7e1015631f1ffe35748b82f987fab66edae602b7..7c9d63c5e414b51b399451326524e9a0950807d4 100644 (file)
@@ -155,7 +155,9 @@ struct ExecContext {
         char **unset_environment;
 
         struct rlimit *rlimit[_RLIMIT_MAX];
-        char *working_directory, *root_directory, *root_image;
+        char *working_directory, *root_directory, *root_image, *root_verity, *root_hash_path;
+        void *root_hash;
+        size_t root_hash_size;
         bool working_directory_missing_ok:1;
         bool working_directory_home:1;
 
index d518ac896936971ccf9b6db4c18096b5d3aedda3..ff49136d70350f65f17fc1f22de79aa36be24ca7 100644 (file)
@@ -387,62 +387,25 @@ JobType job_type_lookup_merge(JobType a, JobType b) {
         return job_merging_table[(a - 1) * a / 2 + b];
 }
 
-bool job_later_link_matters(Job *j, JobType type, unsigned generation) {
-        JobDependency *l;
-
-        assert(j);
-
-        j->generation = generation;
-
-        LIST_FOREACH(subject, l, j->subject_list) {
-                UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
-
-                /* Have we seen this before? */
-                if (l->object->generation == generation)
-                        continue;
-
-                state = unit_active_state(l->object->unit);
-                switch (type) {
-
-                case JOB_START:
-                        return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) ||
-                               job_later_link_matters(l->object, type, generation);
-
-                case JOB_STOP:
-                        return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) ||
-                               job_later_link_matters(l->object, type, generation);
-
-                default:
-                        assert_not_reached("Invalid job type");
-                }
-        }
-
-        return false;
-}
-
-bool job_is_redundant(Job *j, unsigned generation) {
-
-        assert(j);
-
-        UnitActiveState state = unit_active_state(j->unit);
-        switch (j->type) {
+bool job_type_is_redundant(JobType a, UnitActiveState b) {
+        switch (a) {
 
         case JOB_START:
-                return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) && !job_later_link_matters(j, JOB_START, generation);
+                return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
 
         case JOB_STOP:
-                return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) && !job_later_link_matters(j, JOB_STOP, generation);
+                return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
 
         case JOB_VERIFY_ACTIVE:
-                return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING);
+                return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
 
         case JOB_RELOAD:
                 return
-                        state == UNIT_RELOADING;
+                        b == UNIT_RELOADING;
 
         case JOB_RESTART:
                 return
-                        state == UNIT_ACTIVATING;
+                        b == UNIT_ACTIVATING;
 
         case JOB_NOP:
                 return true;
index 02b057ee0641709d7c26c3a3ea331628c4ed3536..03ad640618e7bf047f9139a2d9df59fa4134dd76 100644 (file)
@@ -196,8 +196,7 @@ _pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
         return a == job_type_lookup_merge(a, b);
 }
 
-bool job_later_link_matters(Job *j, JobType type, unsigned generation);
-bool job_is_redundant(Job *j, unsigned generation);
+bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
 
 /* Collapses a state-dependent job type into a simpler type by observing
  * the state of the unit which it is going to be applied to. */
index 69598e8430c1a00906ea003458eb61d7988527dc..9cf959edd57432fb603c35e6ce7f2da14ee8e76c 100644 (file)
@@ -23,6 +23,8 @@ m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
 `$1.WorkingDirectory,            config_parse_working_directory,     0,                             offsetof($1, exec_context)
 $1.RootDirectory,                config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_directory)
 $1.RootImage,                    config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_image)
+$1.RootHash,                     config_parse_exec_root_hash,        0,                             offsetof($1, exec_context)
+$1.RootVerity,                   config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_verity)
 $1.User,                         config_parse_user_group_compat,     0,                             offsetof($1, exec_context.user)
 $1.Group,                        config_parse_user_group_compat,     0,                             offsetof($1, exec_context.group)
 $1.SupplementaryGroups,          config_parse_user_group_strv_compat, 0,                            offsetof($1, exec_context.supplementary_groups)
index c1a4eb96cb884b3f4b8b2d389fd319fb4cc2edd3..c3186f38243897f478233f36643e0e22ebb60de8 100644 (file)
@@ -29,6 +29,7 @@
 #include "errno-list.h"
 #include "escape.h"
 #include "fd-util.h"
+#include "fileio.h"
 #include "fs-util.h"
 #include "hexdecoct.h"
 #include "io-util.h"
@@ -1413,6 +1414,64 @@ int config_parse_exec_cpu_sched_prio(const char *unit,
         return 0;
 }
 
+int config_parse_exec_root_hash(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ void *roothash_decoded = NULL;
+        ExecContext *c = data;
+        size_t roothash_decoded_size = 0;
+        int r;
+
+        assert(data);
+        assert(filename);
+        assert(line);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                /* Reset if the empty string is assigned */
+                c->root_hash_path = mfree(c->root_hash_path);
+                c->root_hash = mfree(c->root_hash);
+                c->root_hash_size = 0;
+                return 0;
+        }
+
+        if (path_is_absolute(rvalue)) {
+                /* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
+                _cleanup_free_ char *p = NULL;
+
+                p = strdup(rvalue);
+                if (!p)
+                        return -ENOMEM;
+
+                free_and_replace(c->root_hash_path, p);
+                c->root_hash = mfree(c->root_hash);
+                c->root_hash_size = 0;
+                return 0;
+        }
+
+        /* We have a roothash to decode, eg: RootHash=012345789abcdef */
+        r = unhexmem(rvalue, strlen(rvalue), &roothash_decoded, &roothash_decoded_size);
+        if (r < 0)
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode RootHash=, ignoring: %s", rvalue);
+        if (roothash_decoded_size < sizeof(sd_id128_t))
+                return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "RootHash= is too short, ignoring: %s", rvalue);
+
+        free_and_replace(c->root_hash, roothash_decoded);
+        c->root_hash_size = roothash_decoded_size;
+        c->root_hash_path = mfree(c->root_hash_path);
+
+        return 0;
+}
+
 int config_parse_exec_cpu_affinity(const char *unit,
                                    const char *filename,
                                    unsigned line,
@@ -3043,10 +3102,6 @@ int config_parse_syscall_archs(
                 return 0;
         }
 
-        r = set_ensure_allocated(archs, NULL);
-        if (r < 0)
-                return log_oom();
-
         for (;;) {
                 _cleanup_free_ char *word = NULL;
                 uint32_t a;
@@ -3069,7 +3124,7 @@ int config_parse_syscall_archs(
                         continue;
                 }
 
-                r = set_put(*archs, UINT32_TO_PTR(a + 1));
+                r = set_ensure_put(archs, NULL, UINT32_TO_PTR(a + 1));
                 if (r < 0)
                         return log_oom();
         }
@@ -3397,8 +3452,6 @@ int config_parse_memory_limit(
                 }
         }
 
-        /* Keep Memory{Low,Min} unset with empty assignment so that we fall back to DefaultMemory* which in
-         * contrast means zeroing the property. */
         if (streq(lvalue, "DefaultMemoryLow")) {
                 c->default_memory_low = bytes;
                 c->default_memory_low_set = true;
@@ -3407,10 +3460,10 @@ int config_parse_memory_limit(
                 c->default_memory_min_set = true;
         } else if (streq(lvalue, "MemoryMin")) {
                 c->memory_min = bytes;
-                c->memory_min_set = !isempty(rvalue);
+                c->memory_min_set = true;
         } else if (streq(lvalue, "MemoryLow")) {
                 c->memory_low = bytes;
-                c->memory_low_set = !isempty(rvalue);
+                c->memory_low_set = true;
         } else if (streq(lvalue, "MemoryHigh"))
                 c->memory_high = bytes;
         else if (streq(lvalue, "MemoryMax"))
index 9c30b6f882b30fb85672c93160d8a9a04b61baf7..f0e109da3ac3f729a151d0aa03539b7f83760b52 100644 (file)
@@ -44,6 +44,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_policy);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash);
 CONFIG_PARSER_PROTOTYPE(config_parse_capability_set);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags);
 CONFIG_PARSER_PROTOTYPE(config_parse_timer);
index 6e606d412af07b8e13aa223b0c400f5ec8abdd85..a2ff71fa71103736192034ddcd779216aa884d9e 100644 (file)
@@ -2559,7 +2559,7 @@ int main(int argc, char *argv[]) {
                         }
 
                         if (mac_selinux_init() < 0) {
-                                error_message = "Failed to initialize SELinux policy";
+                                error_message = "Failed to initialize SELinux support";
                                 goto finish;
                         }
 
@@ -2603,6 +2603,11 @@ int main(int argc, char *argv[]) {
                 /* clear the kernel timestamp,
                  * because we are not PID 1 */
                 kernel_timestamp = DUAL_TIMESTAMP_NULL;
+
+                if (mac_selinux_init() < 0) {
+                        error_message = "Failed to initialize SELinux support";
+                        goto finish;
+                }
         }
 
         if (arg_system) {
index 72dd93fa9542a4de7388b9d59e176b1a880b981c..ab3d0b1192c1b39ca33f9b021e7bf3710bb50836 100644 (file)
@@ -779,6 +779,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
                 .watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
                 .watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
 
+                .show_status_overridden = _SHOW_STATUS_INVALID,
+
                 .notify_fd = -1,
                 .cgroups_agent_fd = -1,
                 .signal_fd = -1,
@@ -2759,11 +2761,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                 switch (sfsi.ssi_signo - SIGRTMIN) {
 
                 case 20:
-                        manager_set_show_status(m, SHOW_STATUS_YES, "signal");
+                        manager_override_show_status(m, SHOW_STATUS_YES, "signal");
                         break;
 
                 case 21:
-                        manager_set_show_status(m, SHOW_STATUS_NO, "signal");
+                        manager_override_show_status(m, SHOW_STATUS_NO, "signal");
                         break;
 
                 case 22:
@@ -3219,9 +3221,9 @@ int manager_serialize(
         /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
         (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
 
-        t = show_status_to_string(m->show_status);
-        if (t)
-                (void) serialize_item(f, "show-status", t);
+        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+                (void) serialize_item(f, "show-status-overridden",
+                                      show_status_to_string(m->show_status_overridden));
 
         if (m->log_level_overridden)
                 (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
@@ -3399,7 +3401,7 @@ void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
                 m->watchdog[t] = timeout;
 }
 
-int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout) {
+int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
         int r = 0;
 
         assert(m);
@@ -3568,14 +3570,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         else
                                 m->honor_device_enumeration = b;
 
-                } else if ((val = startswith(l, "show-status="))) {
+                } else if ((val = startswith(l, "show-status-overridden="))) {
                         ShowStatus s;
 
                         s = show_status_from_string(val);
                         if (s < 0)
-                                log_notice("Failed to parse show-status flag '%s', ignoring.", val);
+                                log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
                         else
-                                manager_set_show_status(m, s, "deserialization");
+                                manager_override_show_status(m, s, "deserialize");
 
                 } else if ((val = startswith(l, "log-level-override="))) {
                         int level;
@@ -3601,7 +3603,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         if (deserialize_usec(val, &t) < 0)
                                 log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
                         else
-                                manager_set_watchdog_overridden(m, WATCHDOG_RUNTIME, t);
+                                manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
 
                 } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
                         usec_t t;
@@ -3609,7 +3611,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         if (deserialize_usec(val, &t) < 0)
                                 log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
                         else
-                                manager_set_watchdog_overridden(m, WATCHDOG_REBOOT, t);
+                                manager_override_watchdog(m, WATCHDOG_REBOOT, t);
 
                 } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
                         usec_t t;
@@ -3617,7 +3619,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         if (deserialize_usec(val, &t) < 0)
                                 log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
                         else
-                                manager_set_watchdog_overridden(m, WATCHDOG_KEXEC, t);
+                                manager_override_watchdog(m, WATCHDOG_KEXEC, t);
 
                 } else if (startswith(l, "env=")) {
                         r = deserialize_environment(l + 4, &m->client_environment);
@@ -4264,49 +4266,78 @@ void manager_recheck_journal(Manager *m) {
         log_open();
 }
 
+static ShowStatus manager_get_show_status(Manager *m) {
+        assert(m);
+
+        if (MANAGER_IS_USER(m))
+                return _SHOW_STATUS_INVALID;
+
+        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+                return m->show_status_overridden;
+
+        return m->show_status;
+}
+
+bool manager_get_show_status_on(Manager *m) {
+        assert(m);
+
+        return show_status_on(manager_get_show_status(m));
+}
+
+static void set_show_status_marker(bool b) {
+        if (b)
+                (void) touch("/run/systemd/show-status");
+        else
+                (void) unlink("/run/systemd/show-status");
+}
+
 void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) {
         assert(m);
+        assert(reason);
         assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
 
-        if (!MANAGER_IS_SYSTEM(m))
+        if (MANAGER_IS_USER(m))
                 return;
 
         if (mode == m->show_status)
                 return;
 
-        bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
-        log_debug("%s (%s) showing of status (%s).",
-                  enabled ? "Enabling" : "Disabling",
-                  strna(show_status_to_string(mode)),
-                  reason);
-        m->show_status = mode;
+        if (m->show_status_overridden == _SHOW_STATUS_INVALID) {
+                bool enabled;
 
-        if (enabled)
-                (void) touch("/run/systemd/show-status");
-        else
-                (void) unlink("/run/systemd/show-status");
+                enabled = show_status_on(mode);
+                log_debug("%s (%s) showing of status (%s).",
+                          enabled ? "Enabling" : "Disabling",
+                          strna(show_status_to_string(mode)),
+                          reason);
+
+                set_show_status_marker(enabled);
+        }
+
+        m->show_status = mode;
 }
 
-static bool manager_get_show_status(Manager *m, StatusType type) {
+void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason) {
         assert(m);
+        assert(mode < _SHOW_STATUS_MAX);
 
-        if (!MANAGER_IS_SYSTEM(m))
-                return false;
+        if (MANAGER_IS_USER(m))
+                return;
 
-        if (m->no_console_output)
-                return false;
+        if (mode == m->show_status_overridden)
+                return;
 
-        if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
-                return false;
+        m->show_status_overridden = mode;
 
-        /* If we cannot find out the status properly, just proceed. */
-        if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
-                return false;
+        if (mode == _SHOW_STATUS_INVALID)
+                mode = m->show_status;
 
-        if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
-                return true;
+        log_debug("%s (%s) showing of status (%s).",
+                  m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring",
+                  strna(show_status_to_string(mode)),
+                  reason);
 
-        return show_status_on(m->show_status);
+        set_show_status_marker(show_status_on(mode));
 }
 
 const char *manager_get_confirm_spawn(Manager *m) {
@@ -4381,12 +4412,34 @@ bool manager_is_confirm_spawn_disabled(Manager *m) {
         return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
 }
 
+static bool manager_should_show_status(Manager *m, StatusType type) {
+        assert(m);
+
+        if (!MANAGER_IS_SYSTEM(m))
+                return false;
+
+        if (m->no_console_output)
+                return false;
+
+        if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
+                return false;
+
+        /* If we cannot find out the status properly, just proceed. */
+        if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
+                return false;
+
+        if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
+                return true;
+
+        return manager_get_show_status_on(m);
+}
+
 void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
         va_list ap;
 
         /* If m is NULL, assume we're after shutdown and let the messages through. */
 
-        if (m && !manager_get_show_status(m, type))
+        if (m && !manager_should_show_status(m, type))
                 return;
 
         /* XXX We should totally drop the check for ephemeral here
@@ -4421,12 +4474,9 @@ int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
         size = set_size(m->failed_units);
 
         if (failed) {
-                r = set_ensure_allocated(&m->failed_units, NULL);
+                r = set_ensure_put(&m->failed_units, NULL, u);
                 if (r < 0)
                         return log_oom();
-
-                if (set_put(m->failed_units, u) < 0)
-                        return log_oom();
         } else
                 (void) set_remove(m->failed_units, u);
 
index a29d976eae531cab80715d9cebb77bf906f514ac..2cd0dacdb03d52559b642adc56c2ce2999ca20d5 100644 (file)
@@ -335,6 +335,7 @@ struct Manager {
         uint8_t return_value;
 
         ShowStatus show_status;
+        ShowStatus show_status_overridden;
         StatusUnitFormat status_unit_format;
         char *confirm_spawn;
         bool no_console_output;
@@ -512,7 +513,10 @@ void disable_printk_ratelimit(void);
 void manager_recheck_dbus(Manager *m);
 void manager_recheck_journal(Manager *m);
 
+bool manager_get_show_status_on(Manager *m);
 void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason);
+void manager_override_show_status(Manager *m, ShowStatus mode, const char *reason);
+
 void manager_set_first_boot(Manager *m, bool b);
 
 void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
@@ -553,7 +557,7 @@ ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s);
 
 usec_t manager_get_watchdog(Manager *m, WatchdogType t);
 void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout);
-int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout);
+int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout);
 
 const char* oom_policy_to_string(OOMPolicy i) _const_;
 OOMPolicy oom_policy_from_string(const char *s) _pure_;
index 6bfc266dc00f57cc4e80b739dad7e0b4bdb0145f..423a47c7b8ce855c81c1ea6f099ea505cc476100 100644 (file)
@@ -1257,16 +1257,20 @@ int setup_namespace(
                 ProtectHome protect_home,
                 ProtectSystem protect_system,
                 unsigned long mount_flags,
+                const void *root_hash,
+                size_t root_hash_size,
+                const char *root_hash_path,
+                const char *root_verity,
                 DissectImageFlags dissect_image_flags,
                 char **error_path) {
 
         _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
         _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
         _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
-        _cleanup_free_ void *root_hash = NULL;
+        _cleanup_free_ void *root_hash_decoded = NULL;
         _cleanup_free_ char *verity_data = NULL;
         MountEntry *m = NULL, *mounts = NULL;
-        size_t n_mounts, root_hash_size = 0;
+        size_t n_mounts;
         bool require_prefix = false;
         const char *root;
         int r = 0;
@@ -1295,16 +1299,16 @@ int setup_namespace(
                 if (r < 0)
                         return log_debug_errno(r, "Failed to create loop device for root image: %m");
 
-                r = verity_metadata_load(root_image, &root_hash, &root_hash_size, &verity_data);
+                r = verity_metadata_load(root_image, root_hash_path, root_hash ? NULL : &root_hash_decoded, root_hash ? NULL : &root_hash_size, root_verity ? NULL : &verity_data);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to load root hash: %m");
-                dissect_image_flags |= verity_data ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0;
+                dissect_image_flags |= root_verity || verity_data ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0;
 
-                r = dissect_image(loop_device->fd, root_hash, root_hash_size, verity_data, dissect_image_flags, &dissected_image);
+                r = dissect_image(loop_device->fd, root_hash ?: root_hash_decoded, root_hash_size, root_verity ?: verity_data, dissect_image_flags, &dissected_image);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to dissect image: %m");
 
-                r = dissected_image_decrypt(dissected_image, NULL, root_hash, root_hash_size, verity_data, dissect_image_flags, &decrypted_image);
+                r = dissected_image_decrypt(dissected_image, NULL, root_hash ?: root_hash_decoded, root_hash_size, root_verity ?: verity_data, dissect_image_flags, &decrypted_image);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to decrypt dissected image: %m");
         }
index ef6c9bdc9bdcaa8bb3c68b93ff4e6ee42164d1ef..a687be5bfda92776dfefbf67690c5cf46f0a778d 100644 (file)
@@ -88,6 +88,10 @@ int setup_namespace(
                 ProtectHome protect_home,
                 ProtectSystem protect_system,
                 unsigned long mount_flags,
+                const void *root_hash,
+                size_t root_hash_size,
+                const char *root_hash_path,
+                const char *root_verity,
                 DissectImageFlags dissected_image_flags,
                 char **error_path);
 
index 415b3f5d84f8759e0cd903412828b51d2c9a836c..9a5912c10f3e2caccca84b83bad045bce34271b1 100644 (file)
                        send_interface="org.freedesktop.systemd1.Manager"
                        send_member="AddDependencyUnitFiles"/>
 
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="SetShowStatus"/>
+
                 <!-- Managed via polkit or other criteria: org.freedesktop.systemd1.Job interface -->
 
                 <allow send_destination="org.freedesktop.systemd1"
index 0fb52372f16a02561e2fe7a93e4975f17856a5f6..ef6470656ce22ec5a242a6ee2adf8c1862d8b7fe 100644 (file)
@@ -279,7 +279,7 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
         return 0;
 }
 
-static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
+static void transaction_drop_redundant(Transaction *tr) {
         bool again;
 
         /* Goes through the transaction and removes all jobs of the units whose jobs are all noops. If not
@@ -299,7 +299,7 @@ static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
 
                         LIST_FOREACH(transaction, k, j)
                                 if (tr->anchor_job == k ||
-                                    !job_is_redundant(k, generation) ||
+                                    !job_type_is_redundant(k->type, unit_active_state(k->unit)) ||
                                     (k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type))) {
                                         keep = true;
                                         break;
@@ -735,7 +735,7 @@ int transaction_activate(
                 transaction_minimize_impact(tr);
 
         /* Third step: Drop redundant jobs */
-        transaction_drop_redundant(tr, generation++);
+        transaction_drop_redundant(tr);
 
         for (;;) {
                 /* Fourth step: Let's remove unneeded jobs that might
@@ -777,7 +777,7 @@ int transaction_activate(
         }
 
         /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
-        transaction_drop_redundant(tr, generation++);
+        transaction_drop_redundant(tr);
 
         /* Ninth step: check whether we can actually apply this */
         r = transaction_is_destructive(tr, mode, e);
index e50080cd97ac70533ce5e1fdbed549af9e485fae..8e59fafc1145974107e9a4f749b09e2a16fab262 100644 (file)
@@ -1591,7 +1591,6 @@ static int unit_add_mount_dependencies(Unit *u) {
 
 static int unit_add_startup_units(Unit *u) {
         CGroupContext *c;
-        int r;
 
         c = unit_get_cgroup_context(u);
         if (!c)
@@ -1602,11 +1601,7 @@ static int unit_add_startup_units(Unit *u) {
             c->startup_blockio_weight == CGROUP_BLKIO_WEIGHT_INVALID)
                 return 0;
 
-        r = set_ensure_allocated(&u->manager->startup_units, NULL);
-        if (r < 0)
-                return r;
-
-        return set_put(u->manager->startup_units, u);
+        return set_ensure_put(&u->manager->startup_units, NULL, u);
 }
 
 int unit_load(Unit *u) {
index ed4d06e9866dd1e4af044bc99d33e4d3b1b10139..eceb7927afa79333f77f68b664b06791560a171c 100644 (file)
@@ -1091,9 +1091,7 @@ static int run(int argc, char *argv[]) {
         int r, units_active;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         /* The journal merging logic potentially needs a lot of fds. */
         (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
index 2d80d3a664b3871edcb4c190fba3c5f152c8a6e8..29e5120375e22d52c4892ad191dcde9ee5c323eb 100644 (file)
@@ -643,9 +643,7 @@ static int parse_argv(int argc, char *argv[]) {
 static int run(int argc, char *argv[]) {
         int r, k, n_found = 0;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 7fb80ca138abe6d68f97eb1e7506d7fd22c1080b..4f38de8e29fb8315bcae96c45222e9c7402441d6 100644 (file)
@@ -128,9 +128,7 @@ static int run(int argc, char *argv[]) {
          * to detect whether we are being run in a virtualized
          * environment or not */
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 9ae632f226700fa62bfcbcbd2b23d9abed3b3f96..2a8eaca5bd10945de87700b4792ccbb8791c28fa 100644 (file)
@@ -201,7 +201,7 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return log_error_errno(r, "Failed to set up loopback device: %m");
 
-        r = verity_metadata_load(arg_image, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
+        r = verity_metadata_load(arg_image, NULL, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
                            arg_verity_data ? NULL : &arg_verity_data);
         if (r < 0)
                 return log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);
index 9066c30853bc8bfd682d69c3e2d06a34551febb2..0c543a90f6b7994267f42f28ebe32af9642ff398 100644 (file)
@@ -159,9 +159,7 @@ static int run(int argc, char *argv[]) {
         char **i;
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index f7237d22d83bce46a5a6448f0b48c58670dbb4b2..7a473b791b1df86766917a5949c90174bb49b399 100644 (file)
@@ -3489,9 +3489,7 @@ static int run(int argc, char *argv[]) {
 
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 5596846ed26cd415036fb0657916d2d67d5f9586..e08ab15acd13226fb410694f5e3e2b1cd74e257c 100644 (file)
@@ -436,9 +436,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index e694a95a0411327e422b3001904f2f59c0904356..36229f3c9bb5a045cfac55c37af398f45ef0554d 100644 (file)
@@ -801,7 +801,10 @@ static int run(int argc, char *argv[]) {
                 return r;
 
         umask(0022);
-        mac_selinux_init();
+
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
 
         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
 
index 651647b3f0dd95972187c549710258f6da2317bb..eb038a8b55ea8d833b4b5b6dd6cbee78d927f9fd 100644 (file)
@@ -125,7 +125,9 @@ static int run(int argc, char *argv[]) {
         if (r <= 0)
                 return r;
 
-        mac_selinux_init();
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
 
         return hwdb_main(argc, argv);
 }
index 19435f80fea40726960b69848872e6dff57741fa..13996573ab6661ef080f2a43eb7bc2228e027763 100644 (file)
@@ -249,9 +249,7 @@ static int id128_main(int argc, char *argv[]) {
 static int run(int argc, char *argv[]) {
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 948b2d2fce60583117021410966d2859aec6a782..69a111afeadc73d0e63bc9de81b40cc135ed1b9c 100644 (file)
@@ -1110,7 +1110,7 @@ static int run(int argc, char **argv) {
         int r;
 
         log_show_color(true);
-        log_parse_environment();
+        log_parse_environment_cli();
 
         /* The journal merging logic potentially needs a lot of fds. */
         (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
index bd58fdbcdfb7f0ee3263998513776b93a3c1b290..e169a27eb3c7df8440c0a48507510cfbb3a383f5 100644 (file)
@@ -821,7 +821,7 @@ static int run(int argc, char **argv) {
         int r;
 
         log_show_color(true);
-        log_parse_environment();
+        log_parse_environment_cli();
 
         /* The journal merging logic potentially needs a lot of fds. */
         (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
index 500b6745050f25b7b5524200bd0737d667c61c16..2faaa2e28488d77149b78942125ee0f8a6f3a4ad 100644 (file)
@@ -129,9 +129,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_close_ int outfd = -1, errfd = -1, saved_stderr = -1;
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 859f4bbd44a9b9a26c722b3242b4c9f8f13ffc3f..8d4897b942f778807e168415deecec262bec92cf 100644 (file)
@@ -875,12 +875,7 @@ static int parse_argv(int argc, char *argv[]) {
                                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                                "Bad --facility= argument \"%s\".", fac);
 
-                                r = set_ensure_allocated(&arg_facilities, NULL);
-                                if (r < 0)
-                                        return log_oom();
-
-                                r = set_put(arg_facilities, INT_TO_PTR(num));
-                                if (r < 0)
+                                if (set_ensure_put(&arg_facilities, NULL, INT_TO_PTR(num)) < 0)
                                         return log_oom();
                         }
 
@@ -2115,9 +2110,7 @@ int main(int argc, char *argv[]) {
         int n_shown = 0, r, poll_fd = -1;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         /* Increase max number of open files if we can, we might needs this when browsing journal files, which might be
          * split up into many files. */
index aed30d6118b0e034a865f69f2538f31f77acb1fd..66222eaddbbe1c0564029a6ac36194b5644df788 100644 (file)
@@ -82,6 +82,3 @@ int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const vo
 int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
 
 int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len);
-
-int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
-int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);
index aa61bc2614dbf3b4471b5353c3b28d0bffbf5830..e4c11235b62f2f4f85ae189cb20f52f988fc80bb 100644 (file)
@@ -61,9 +61,13 @@ int deserialize_in6_addrs(struct in6_addr **addresses, const char *string);
 
 /* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */
 struct sd_dhcp_route;
+struct sd_dhcp_lease;
 
 void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
 int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
 
 /* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
 int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
+
+int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
+int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);
index 8582302cb48c5997405dbf449e39665c2d34e6e9..0bc5fa321018da09e37dbdee413d9b6471506c77 100644 (file)
@@ -1076,7 +1076,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
                            "ADDRESS", &address,
                            "ROUTER", &router,
                            "NETMASK", &netmask,
-                           "SERVER_IDENTIFIER", &server_address,
+                           "SERVER_ADDRESS", &server_address,
                            "NEXT_SERVER", &next_server,
                            "BROADCAST", &broadcast,
                            "DNS", &dns,
index 97b732ae425274585e4b5bb0cbd05698b58a987b..55e35cd902ee960e20bb13271aa69ce0e0df89c5 100644 (file)
@@ -451,7 +451,7 @@ int bus_message_from_header(
         if (!IN_SET(h->version, 1, 2))
                 return -EBADMSG;
 
-        if (h->type <= _SD_BUS_MESSAGE_TYPE_INVALID || h->type >= _SD_BUS_MESSAGE_TYPE_MAX)
+        if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
                 return -EBADMSG;
 
         if (!IN_SET(h->endian, BUS_LITTLE_ENDIAN, BUS_BIG_ENDIAN))
@@ -589,7 +589,8 @@ _public_ int sd_bus_message_new(
         assert_return(bus = bus_resolve(bus), -ENOPKG);
         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(m, -EINVAL);
-        assert_return(type > _SD_BUS_MESSAGE_TYPE_INVALID && type < _SD_BUS_MESSAGE_TYPE_MAX, -EINVAL);
+        /* Creation of messages with _SD_BUS_MESSAGE_TYPE_INVALID is allowed. */
+        assert_return(type < _SD_BUS_MESSAGE_TYPE_MAX, -EINVAL);
 
         sd_bus_message *t = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
         if (!t)
@@ -3021,7 +3022,7 @@ int bus_body_part_map(struct bus_body_part *part) {
                 return 0;
         }
 
-        shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
+        shift = PAGE_OFFSET(part->memfd_offset);
         psz = PAGE_ALIGN(part->size + shift);
 
         if (part->memfd >= 0)
@@ -3158,7 +3159,8 @@ static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t s
                                 return NULL;
 
                         if (p)
-                                *p = (uint8_t*) part->data + index - begin;
+                                *p = part->data ? (uint8_t*) part->data + index - begin
+                                        : NULL; /* Avoid dereferencing a NULL pointer. */
 
                         m->cached_rindex_part = part;
                         m->cached_rindex_part_begin = begin;
@@ -5497,9 +5499,6 @@ int bus_message_parse_fields(sd_bus_message *m) {
                 if (m->reply_cookie == 0 || !m->error.name)
                         return -EBADMSG;
                 break;
-
-        default:
-                assert_not_reached("Bad message type");
         }
 
         /* Refuse non-local messages that claim they are local */
index ee8005833dee58354bd79541c68cd1b100b6a16c..ffec11bbd35c981b1109ed391b772609f52297e0 100644 (file)
@@ -759,30 +759,13 @@ _public_ int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_moni
 }
 
 _public_ int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
         assert_return(m, -EINVAL);
         assert_return(tag, -EINVAL);
 
-        t = strdup(tag);
-        if (!t)
-                return -ENOMEM;
-
-        r = set_ensure_allocated(&m->tag_filter, &string_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(m->tag_filter, t);
-        if (r == -EEXIST)
-                return 0;
-        if (r < 0)
-                return r;
-
-        TAKE_PTR(t);
-        m->filter_uptodate = false;
-
-        return 0;
+        int r = set_put_strdup(&m->tag_filter, tag);
+        if (r > 0)
+                m->filter_uptodate = false;
+        return r;
 }
 
 _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) {
index fb9db47105c06c01b5c5b396a9e064d6bfc2bca8..860eb048ff5be1975a3fdfb140fbaa25587dacb7 100644 (file)
@@ -1450,10 +1450,6 @@ _public_ int sd_event_add_post(
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        r = set_ensure_allocated(&e->post_sources, NULL);
-        if (r < 0)
-                return r;
-
         s = source_new(e, !ret, SOURCE_POST);
         if (!s)
                 return -ENOMEM;
@@ -1462,9 +1458,10 @@ _public_ int sd_event_add_post(
         s->userdata = userdata;
         s->enabled = SD_EVENT_ON;
 
-        r = set_put(e->post_sources, s);
+        r = set_ensure_put(&e->post_sources, NULL, s);
         if (r < 0)
                 return r;
+        assert(r > 0);
 
         if (ret)
                 *ret = s;
index 30f47244ada090405e823bc64cddeebf3ecf0dbf..ce6ae846c5041e828cd2ef0a4cb85af53e755a65 100644 (file)
@@ -168,10 +168,6 @@ _public_ int sd_network_link_get_address_state(int ifindex, char **state) {
         return network_link_get_string(ifindex, "ADDRESS_STATE", state);
 }
 
-_public_ int sd_network_link_get_dhcp4_client_id_string(int ifindex, char **client_id) {
-        return network_link_get_string(ifindex, "DHCP4_CLIENT_ID", client_id);
-}
-
 _public_ int sd_network_link_get_dhcp6_client_iaid_string(int ifindex, char **iaid) {
         return network_link_get_string(ifindex, "DHCP6_CLIENT_IAID", iaid);
 }
@@ -236,14 +232,6 @@ _public_ int sd_network_link_get_dnssec_negative_trust_anchors(int ifindex, char
         return network_link_get_strv(ifindex, "DNSSEC_NTA", nta);
 }
 
-_public_ int sd_network_link_get_timezone(int ifindex, char **ret) {
-        return network_link_get_string(ifindex, "TIMEZONE", ret);
-}
-
-_public_ int sd_network_link_get_dhcp4_address(int ifindex, char **ret) {
-        return network_link_get_string(ifindex, "DHCP4_ADDRESS", ret);
-}
-
 _public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
         return network_link_get_strv(ifindex, "DNS", ret);
 }
index b7548a0f7f561c69382f90858a98d30a349400a8..96fc09a5702273728b1059bd7f90970bad69a5d0 100644 (file)
@@ -502,9 +502,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 8ffcf306b5b74aec4de5593f0ea8e86d2e403e5b..715ce5cac7e07c5bbcedc5552ab1eee3269561b7 100644 (file)
@@ -18,6 +18,7 @@
 #include "bus-message.h"
 #include "bus-polkit.h"
 #include "def.h"
+#include "dlfcn-util.h"
 #include "keymap-util.h"
 #include "locale-util.h"
 #include "macro.h"
@@ -530,7 +531,7 @@ static int verify_xkb_rmlvo(const char *model, const char *layout, const char *v
         };
         struct xkb_context *ctx = NULL;
         struct xkb_keymap *km = NULL;
-        void *dl;
+        _cleanup_(dlclosep) void *dl = NULL;
         int r;
 
         /* Compile keymap from RMLVO information to check out its validity */
@@ -582,7 +583,6 @@ finish:
         if (symbol_xkb_context_unref && ctx)
                 symbol_xkb_context_unref(ctx);
 
-        (void) dlclose(dl);
         return r;
 }
 
@@ -788,7 +788,10 @@ static int run(int argc, char *argv[]) {
                 return r;
 
         umask(0022);
-        mac_selinux_init();
+
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
 
         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
 
index e87a10ebeb51fbfc08628b4bf2ef7b61c8a61b59..314b0a3d3799de5c2bdf97790962a0999f5e9f5b 100644 (file)
@@ -34,5 +34,5 @@ tests += [
           'src/locale/keymap-util.c',
           'src/locale/keymap-util.h'],
          [libshared],
-         [libdl]],
+         []],
 ]
index 7805863d8ddfb8f63a074af800516ce9580cedf5..9216224bfc879b6727982d6d1d2e577d1b854a4b 100644 (file)
@@ -1460,9 +1460,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         /* The journal merging logic potentially needs a lot of fds. */
         (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
index 3f4b65e1fdf16ab9333c1454d27b056e0a96cd92..450ec320443a4cf63bc3b28a01e6b7ec3713a4df 100644 (file)
@@ -174,15 +174,11 @@ static int set_add_message(Set **set, sd_bus_message *message) {
         if (r <= 0)
                 return r;
 
-        r = set_ensure_allocated(set, &bus_message_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*set, message);
-        if (r < 0)
+        r = set_ensure_put(set, &bus_message_hash_ops, message);
+        if (r <= 0)
                 return r;
-
         sd_bus_message_ref(message);
+
         return 1;
 }
 
index dc746a2c9edef1ff39227809a6fcd9f09fa69bff..377fba25cfab8c33d058e5d6772aefe9c74c31ee 100644 (file)
@@ -1173,7 +1173,7 @@ static int run(int argc, char *argv[]) {
 
         r = mac_selinux_init();
         if (r < 0)
-                return log_error_errno(r, "Could not initialize labelling: %m");
+                return r;
 
         /* Always create the directories people can create inotify watches in. Note that some applications might check
          * for the existence of /run/systemd/seats/ to determine whether logind is available, so please always make
index fdf0124c4168f06331db6d0049b01a54c9edaa94..38058d7b2a3f918ff60c0cd039e3216cd44625d5 100644 (file)
@@ -192,11 +192,11 @@ static int run(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "First argument must be either \"start\" or \"stop\".");
 
+        umask(0022);
+
         r = mac_selinux_init();
         if (r < 0)
-                return log_error_errno(r, "Could not initialize labelling: %m\n");
-
-        umask(0022);
+                return r;
 
         if (streq(argv[1], "start"))
                 return do_mount(argv[2]);
index d88b2651d2c5118bf57ee7648aa85dac8dad82f3..d8f4526644def61e6d11e70bd331c363c84593ad 100644 (file)
@@ -2882,9 +2882,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         /* The journal merging logic potentially needs a lot of fds. */
         (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
index 713cdaa8847ad8eec72e40db81479c572fed311b..bff778179c42e3895ef51429f11e8b2719c316e0 100644 (file)
@@ -348,14 +348,7 @@ static int wireguard_resolve_handler(sd_resolve_query *q,
         if (ret != 0) {
                 log_netdev_error(netdev, "Failed to resolve host '%s:%s': %s", peer->endpoint_host, peer->endpoint_port, gai_strerror(ret));
 
-                r = set_ensure_allocated(&w->peers_with_failed_endpoint, NULL);
-                if (r < 0) {
-                        log_oom();
-                        peer->section->invalid = true;
-                        goto resolve_next;
-                }
-
-                r = set_put(w->peers_with_failed_endpoint, peer);
+                r = set_ensure_put(&w->peers_with_failed_endpoint, NULL, peer);
                 if (r < 0) {
                         log_netdev_error(netdev, "Failed to save a peer, dropping the peer: %m");
                         peer->section->invalid = true;
@@ -580,7 +573,7 @@ int config_parse_wireguard_preshared_key(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
+        WireguardPeer *peer;
         Wireguard *w;
         int r;
 
@@ -592,12 +585,7 @@ int config_parse_wireguard_preshared_key(
         if (r < 0)
                 return r;
 
-        r = wireguard_decode_key_and_warn(rvalue, peer->preshared_key, unit, filename, line, lvalue);
-        if (r < 0)
-                return r;
-
-        TAKE_PTR(peer);
-        return 0;
+        return wireguard_decode_key_and_warn(rvalue, peer->preshared_key, unit, filename, line, lvalue);
 }
 
 int config_parse_wireguard_preshared_key_file(
@@ -766,10 +754,6 @@ int config_parse_wireguard_endpoint(
         w = WIREGUARD(data);
         assert(w);
 
-        r = wireguard_peer_new_static(w, filename, section_line, &peer);
-        if (r < 0)
-                return r;
-
         if (rvalue[0] == '[') {
                 begin = &rvalue[1];
                 end = strchr(rvalue, ']');
@@ -801,6 +785,10 @@ int config_parse_wireguard_endpoint(
                 ++end;
         }
 
+        r = wireguard_peer_new_static(w, filename, section_line, &peer);
+        if (r < 0)
+                return r;
+
         r = free_and_strndup(&peer->endpoint_host, begin, len);
         if (r < 0)
                 return log_oom();
@@ -809,15 +797,11 @@ int config_parse_wireguard_endpoint(
         if (r < 0)
                 return log_oom();
 
-        r = set_ensure_allocated(&w->peers_with_unresolved_endpoint, NULL);
+        r = set_ensure_put(&w->peers_with_unresolved_endpoint, NULL, peer);
         if (r < 0)
                 return log_oom();
+        TAKE_PTR(peer); /* The peer may already have been in the hash map, that is fine too. */
 
-        r = set_put(w->peers_with_unresolved_endpoint, peer);
-        if (r < 0)
-                return r;
-
-        TAKE_PTR(peer);
         return 0;
 }
 
@@ -833,7 +817,7 @@ int config_parse_wireguard_keepalive(
                 void *data,
                 void *userdata) {
 
-        _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
+        WireguardPeer *peer;
         uint16_t keepalive = 0;
         Wireguard *w;
         int r;
@@ -854,15 +838,13 @@ int config_parse_wireguard_keepalive(
                 r = safe_atou16(rvalue, &keepalive);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "The persistent keepalive interval must be 0-65535. Ignore assignment: %s",
+                                   "Failed to parse \"%s\" as keepalive interval (range 0–65535), ignoring assignment: %m",
                                    rvalue);
                         return 0;
                 }
         }
 
         peer->persistent_keepalive_interval = keepalive;
-
-        TAKE_PTR(peer);
         return 0;
 }
 
index bf663146d6d585970525712bdfd050e333e0a782..8b7cf292fa056a0157e82f2b9df67b7119be92d9 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
+#include <arpa/inet.h>
 #include <getopt.h>
 #include <linux/if_addrlabel.h>
 #include <net/if.h>
@@ -930,12 +931,13 @@ static int dump_gateways(
 
 static int dump_addresses(
                 sd_netlink *rtnl,
+                sd_dhcp_lease *lease,
                 Table *table,
                 int ifindex) {
 
         _cleanup_free_ struct local_address *local = NULL;
-        _cleanup_free_ char *dhcp4_address = NULL;
         _cleanup_strv_free_ char **buf = NULL;
+        struct in_addr dhcp4_address = {};
         int r, n, i;
 
         assert(rtnl);
@@ -945,7 +947,8 @@ static int dump_addresses(
         if (n <= 0)
                 return n;
 
-        (void) sd_network_link_get_dhcp4_address(ifindex, &dhcp4_address);
+        if (lease)
+                (void) sd_dhcp_lease_get_address(lease, &dhcp4_address);
 
         for (i = 0; i < n; i++) {
                 _cleanup_free_ char *pretty = NULL;
@@ -955,13 +958,19 @@ static int dump_addresses(
                 if (r < 0)
                         return r;
 
-                if (dhcp4_address && streq(pretty, dhcp4_address)) {
-                        _cleanup_free_ char *p = NULL;
+                if (local[i].family == AF_INET && in4_addr_equal(&local[i].address.in, &dhcp4_address)) {
+                        struct in_addr server_address;
+                        char *p, s[INET_ADDRSTRLEN];
 
-                        p = pretty;
-                        pretty = strjoin(pretty , " (DHCP4)");
-                        if (!pretty)
+                        r = sd_dhcp_lease_get_server_identifier(lease, &server_address);
+                        if (r >= 0 && inet_ntop(AF_INET, &server_address, s, sizeof(s)))
+                                p = strjoin(pretty, " (DHCP4 via ", s, ")");
+                        else
+                                p = strjoin(pretty, " (DHCP4)");
+                        if (!p)
                                 return log_oom();
+
+                        free_and_replace(pretty, p);
                 }
 
                 r = strv_extendf(&buf, "%s%s%s",
@@ -1379,12 +1388,12 @@ static int link_status_one(
                 const LinkInfo *info) {
 
         _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL;
-        _cleanup_free_ char *t = NULL, *network = NULL, *client_id = NULL, *iaid = NULL, *duid = NULL;
-        const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
-        _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
-        const char *on_color_operational, *off_color_operational,
-                *on_color_setup, *off_color_setup;
+        _cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL,
+                *setup_state = NULL, *operational_state = NULL, *lease_file = NULL;
+        const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL,
+                *on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup;
         _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
+        _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
         _cleanup_(table_unrefp) Table *table = NULL;
         TableCell *cell;
         int r;
@@ -1425,6 +1434,11 @@ static int link_status_one(
         (void) sd_network_link_get_carrier_bound_to(info->ifindex, &carrier_bound_to);
         (void) sd_network_link_get_carrier_bound_by(info->ifindex, &carrier_bound_by);
 
+        if (asprintf(&lease_file, "/run/systemd/netif/leases/%d", info->ifindex) < 0)
+                return log_oom();
+
+        (void) dhcp_lease_load(&lease, lease_file);
+
         table = table_new("dot", "key", "value");
         if (!table)
                 return log_oom();
@@ -2022,7 +2036,7 @@ static int link_status_one(
                 }
         }
 
-        r = dump_addresses(rtnl, table, info->ifindex);
+        r = dump_addresses(rtnl, lease, table, info->ifindex);
         if (r < 0)
                 return r;
         r = dump_gateways(rtnl, hwdb, table, info->ifindex);
@@ -2050,24 +2064,35 @@ static int link_status_one(
         if (r < 0)
                 return r;
 
-        (void) sd_network_link_get_timezone(info->ifindex, &tz);
-        if (tz) {
-                r = table_add_many(table,
-                                   TABLE_EMPTY,
-                                   TABLE_STRING, "Time Zone:",
-                                   TABLE_STRING, tz);
-                if (r < 0)
-                        return table_log_add_error(r);
-        }
+        if (lease) {
+                const void *client_id;
+                size_t client_id_len;
+                const char *tz;
 
-        r = sd_network_link_get_dhcp4_client_id_string(info->ifindex, &client_id);
-        if (r >= 0) {
-                r = table_add_many(table,
-                                   TABLE_EMPTY,
-                                   TABLE_STRING, "DHCP4 Client ID:",
-                                   TABLE_STRING, client_id);
-                if (r < 0)
-                        return table_log_add_error(r);
+                r = sd_dhcp_lease_get_timezone(lease, &tz);
+                if (r >= 0) {
+                        r = table_add_many(table,
+                                           TABLE_EMPTY,
+                                           TABLE_STRING, "Time Zone:",
+                                           TABLE_STRING, tz);
+                        if (r < 0)
+                                return table_log_add_error(r);
+                }
+
+                r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len);
+                if (r >= 0) {
+                        _cleanup_free_ char *id = NULL;
+
+                        r = sd_dhcp_client_id_to_string(client_id, client_id_len, &id);
+                        if (r >= 0) {
+                                r = table_add_many(table,
+                                                   TABLE_EMPTY,
+                                                   TABLE_STRING, "DHCP4 Client ID:",
+                                                   TABLE_STRING, id);
+                                if (r < 0)
+                                        return table_log_add_error(r);
+                        }
+                }
         }
 
         r = sd_network_link_get_dhcp6_client_iaid_string(info->ifindex, &iaid);
@@ -2147,7 +2172,7 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
         if (r < 0)
                 return table_log_add_error(r);
 
-        r = dump_addresses(rtnl, table, 0);
+        r = dump_addresses(rtnl, NULL, table, 0);
         if (r < 0)
                 return r;
         r = dump_gateways(rtnl, hwdb, table, 0);
@@ -2793,9 +2818,7 @@ static void warn_networkd_missing(void) {
 static int run(int argc, char* argv[]) {
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 9b78530334a08f0cb2adececb5d98f962badd5fe..44e317e9909ff2911945a48a010229fa6745351a 100644 (file)
@@ -266,11 +266,7 @@ static int address_add_internal(Link *link, Set **addresses,
         /* Consider address tentative until we get the real flags from the kernel */
         address->flags = IFA_F_TENTATIVE;
 
-        r = set_ensure_allocated(addresses, &address_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*addresses, address);
+        r = set_ensure_put(addresses, &address_hash_ops, address);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -280,9 +276,7 @@ static int address_add_internal(Link *link, Set **addresses,
 
         if (ret)
                 *ret = address;
-
-        address = NULL;
-
+        TAKE_PTR(address);
         return 0;
 }
 
@@ -302,11 +296,7 @@ int address_add(Link *link, int family, const union in_addr_union *in_addr, unsi
                         return r;
         } else if (r == 0) {
                 /* Take over a foreign address */
-                r = set_ensure_allocated(&link->addresses, &address_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(link->addresses, address);
+                r = set_ensure_put(&link->addresses, &address_hash_ops, address);
                 if (r < 0)
                         return r;
 
index 606ae9f3c2f9f7a5865cf73ea4506689ee735f94..5b1acde297c6b1c0df445f0458b5ee0227b3bbd5 100644 (file)
@@ -664,17 +664,8 @@ int config_parse_dhcp_request_options(
                         continue;
                 }
 
-                if (ltype == AF_INET)
-                        r = set_ensure_allocated(&network->dhcp_request_options, NULL);
-                else
-                        r = set_ensure_allocated(&network->dhcp6_request_options, NULL);
-                if (r < 0)
-                        return log_oom();
-
-                if (ltype == AF_INET)
-                        r = set_put(network->dhcp_request_options, UINT32_TO_PTR(i));
-                else
-                        r = set_put(network->dhcp6_request_options, UINT32_TO_PTR(i));
+                r = set_ensure_put(ltype == AF_INET ? &network->dhcp_request_options : &network->dhcp6_request_options,
+                                   NULL, UINT32_TO_PTR(i));
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, r,
                                    "Failed to store DHCP request option '%s', ignoring assignment: %m", n);
index b3ed4a8cea28297ef62997130c297eb7ee7892ae..6f25c9fc969223485f31682dadd4e847c8226a75 100644 (file)
@@ -116,7 +116,7 @@ static int link_push_uplink_to_dhcp_server(
         case SD_DHCP_LEASE_LPR:
                 /* For the other server types we currently do not allow local configuration of server data,
                  * since there are typically no local consumers of the data. */
-                ;
+                break;
 
         default:
                 assert_not_reached("Unexpected server type");
index 8e2c775fcf420418faa0d9c383c7f49fda091d66..6103792771865d15d033ad6e90f14ab907ee468e 100644 (file)
@@ -1564,7 +1564,6 @@ int config_parse_dhcp_black_listed_ip_address(
                 void *userdata) {
 
         Network *network = data;
-        const char *p;
         int r;
 
         assert(filename);
@@ -1577,7 +1576,7 @@ int config_parse_dhcp_black_listed_ip_address(
                 return 0;
         }
 
-        for (p = rvalue;;) {
+        for (const char *p = rvalue;;) {
                 _cleanup_free_ char *n = NULL;
                 union in_addr_union ip;
 
@@ -1598,11 +1597,7 @@ int config_parse_dhcp_black_listed_ip_address(
                         continue;
                 }
 
-                r = set_ensure_allocated(&network->dhcp_black_listed_ip, NULL);
-                if (r < 0)
-                        return log_oom();
-
-                r = set_put(network->dhcp_black_listed_ip, UINT32_TO_PTR(ip.in.s_addr));
+                r = set_ensure_put(&network->dhcp_black_listed_ip, NULL, UINT32_TO_PTR(ip.in.s_addr));
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, r,
                                    "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n);
index f0766f0af7644b9e58cd7e39233f45128168fc33..27b74407af60cc0184b2c730b14782a675fe6468 100644 (file)
@@ -1065,7 +1065,7 @@ static int dhcp6_assign_delegated_prefix(Link *link,
         address->in_addr.in6 = *prefix;
 
         if (!in_addr_is_null(AF_INET6, &link->network->dhcp6_delegation_prefix_token))
-                memcpy(&address->in_addr.in6.s6_addr + 8, &link->network->dhcp6_delegation_prefix_token.in6.s6_addr + 8, 8);
+                memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_delegation_prefix_token.in6.s6_addr + 8, 8);
         else {
                 r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
                 if (r < 0)
index afeb36d315bbff0fb449417e454ba51fd8b3911f..06a467d15b1c062479d95715c8a3fb5841381062 100644 (file)
@@ -2125,11 +2125,7 @@ static int link_append_to_master(Link *link, NetDev *netdev) {
         if (r < 0)
                 return r;
 
-        r = set_ensure_allocated(&master->slaves, NULL);
-        if (r < 0)
-                return r;
-
-        r = set_put(master->slaves, link);
+        r = set_ensure_put(&master->slaves, NULL, link);
         if (r <= 0)
                 return r;
 
@@ -3133,12 +3129,12 @@ static int link_configure_duid(Link *link) {
                 r = set_put(m->links_requesting_uuid, link);
                 if (r < 0)
                         return log_oom();
+                if (r > 0)
+                        link_ref(link);
 
                 r = set_put(m->duids_requesting_uuid, duid);
                 if (r < 0)
                         return log_oom();
-
-                link_ref(link);
         }
 
         return 0;
@@ -4351,33 +4347,6 @@ int link_save(Link *link) {
         print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
 
         if (link->dhcp_lease) {
-                struct in_addr address;
-                const char *tz = NULL;
-                size_t client_id_len;
-                const void *client_id;
-
-                assert(link->network);
-
-                r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
-                if (r >= 0)
-                        fprintf(f, "TIMEZONE=%s\n", tz);
-
-                r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
-                if (r >= 0) {
-                        fputs("DHCP4_ADDRESS=", f);
-                        serialize_in_addrs(f, &address, 1, NULL, NULL);
-                        fputc('\n', f);
-                }
-
-                r = sd_dhcp_lease_get_client_id(link->dhcp_lease, &client_id, &client_id_len);
-                if (r >= 0) {
-                        _cleanup_free_ char *id = NULL;
-
-                        r = sd_dhcp_client_id_to_string(client_id, client_id_len, &id);
-                        if (r >= 0)
-                                fprintf(f, "DHCP4_CLIENT_ID=%s\n", id);
-                }
-
                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
                 if (r < 0)
                         goto fail;
@@ -4440,16 +4409,10 @@ void link_dirty(Link *link) {
         /* mark manager dirty as link is dirty */
         manager_dirty(link->manager);
 
-        r = set_ensure_allocated(&link->manager->dirty_links, NULL);
-        if (r < 0)
-                /* allocation errors are ignored */
-                return;
-
-        r = set_put(link->manager->dirty_links, link);
+        r = set_ensure_put(&link->manager->dirty_links, NULL, link);
         if (r <= 0)
-                /* don't take another ref if the link was already dirty */
+                /* Ignore allocation errors and don't take another ref if the link was already dirty */
                 return;
-
         link_ref(link);
 }
 
index 8692b9411e2a1bbdb2c890acdd61bf329a37ba8d..08666fd92d195495d38062e98a894afab3ed8177 100644 (file)
@@ -2309,23 +2309,15 @@ int manager_request_product_uuid(Manager *m, Link *link) {
 
                 assert_se(duid = link_get_duid(link));
 
-                r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
+                r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
                 if (r < 0)
                         return log_oom();
+                if (r > 0)
+                        link_ref(link);
 
-                r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
+                r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
                 if (r < 0)
                         return log_oom();
-
-                r = set_put(m->links_requesting_uuid, link);
-                if (r < 0)
-                        return log_oom();
-
-                r = set_put(m->duids_requesting_uuid, duid);
-                if (r < 0)
-                        return log_oom();
-
-                link_ref(link);
         }
 
         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
index 19a655b2d7af1398792ce5827f00136878e75587..7889bfb19198fb5b56d28d51b2989a0a9c465225 100644 (file)
@@ -591,10 +591,6 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
                         continue;
                 }
 
-                r = set_ensure_allocated(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops);
-                if (r < 0)
-                        return log_oom();
-
                 x = new(NDiscRDNSS, 1);
                 if (!x)
                         return log_oom();
@@ -604,13 +600,11 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
                         .valid_until = time_now + lifetime * USEC_PER_SEC,
                 };
 
-                r = set_put(link->ndisc_rdnss, x);
+                r = set_ensure_consume(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops, TAKE_PTR(x));
                 if (r < 0)
                         return log_oom();
-
-                TAKE_PTR(x);
-
                 assert(r > 0);
+
                 link_dirty(link);
         }
 
@@ -686,22 +680,15 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
                         continue;
                 }
 
-                r = set_ensure_allocated(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops);
-                if (r < 0) {
-                        log_oom();
-                        return;
-                }
-
                 s->valid_until = time_now + lifetime * USEC_PER_SEC;
 
-                r = set_put(link->ndisc_dnssl, s);
+                r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s));
                 if (r < 0) {
                         log_oom();
                         return;
                 }
-
-                s = NULL;
                 assert(r > 0);
+
                 link_dirty(link);
         }
 }
@@ -979,22 +966,13 @@ int config_parse_ndisc_black_listed_prefix(
                 if (set_contains(network->ndisc_black_listed_prefix, &ip.in6))
                         continue;
 
-                r = set_ensure_allocated(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops);
-                if (r < 0)
-                        return log_oom();
-
                 a = newdup(struct in6_addr, &ip.in6, 1);
                 if (!a)
                         return log_oom();
 
-                r = set_put(network->ndisc_black_listed_prefix, a);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to store NDISC black listed prefix '%s', ignoring assignment: %m", n);
-                        continue;
-                }
-
-                TAKE_PTR(a);
+                r = set_ensure_consume(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops, TAKE_PTR(a));
+                if (r < 0)
+                        return log_oom();
         }
 
         return 0;
index fd6219fccea59c5dcefdfd5408a03786e2d486d4..6d91f7051125aef5a2cbcb50b88e6e48dfa416fc 100644 (file)
@@ -300,11 +300,7 @@ static int neighbor_add_internal(Link *link, Set **neighbors, int family, const
                 .lladdr_size = lladdr_size,
         };
 
-        r = set_ensure_allocated(neighbors, &neighbor_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*neighbors, neighbor);
+        r = set_ensure_put(neighbors, &neighbor_hash_ops, neighbor);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -314,8 +310,7 @@ static int neighbor_add_internal(Link *link, Set **neighbors, int family, const
 
         if (ret)
                 *ret = neighbor;
-
-        neighbor = NULL;
+        TAKE_PTR(neighbor);
 
         return 0;
 }
@@ -332,11 +327,7 @@ int neighbor_add(Link *link, int family, const union in_addr_union *addr, const
                         return r;
         } else if (r == 0) {
                 /* Neighbor is foreign, claim it as recognized */
-                r = set_ensure_allocated(&link->neighbors, &neighbor_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(link->neighbors, neighbor);
+                r = set_ensure_put(&link->neighbors, &neighbor_hash_ops, neighbor);
                 if (r < 0)
                         return r;
 
index 0e68b35e897c91c0326e1f206d9eaafe17b52745..8478fe8c9efabfc33a342bf41f86fe36b6ef770e 100644 (file)
@@ -1269,15 +1269,9 @@ int config_parse_dnssec_negative_trust_anchors(
                         continue;
                 }
 
-                r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
+                r = set_ensure_consume(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops, TAKE_PTR(w));
                 if (r < 0)
                         return log_oom();
-
-                r = set_put(n->dnssec_negative_trust_anchors, w);
-                if (r < 0)
-                        return log_oom();
-                if (r > 0)
-                        w = NULL;
         }
 
         return 0;
index 45c13ca88f3245e4caeef569c84f9e8ae5ac3515..5d91d791d17f21b4b60cbe48157347499b21c0c1 100644 (file)
@@ -209,11 +209,7 @@ static int nexthop_add_internal(Link *link, Set **nexthops, NextHop *in, NextHop
         nexthop->family = in->family;
         nexthop->gw = in->gw;
 
-        r = set_ensure_allocated(nexthops, &nexthop_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*nexthops, nexthop);
+        r = set_ensure_put(nexthops, &nexthop_hash_ops, nexthop);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -245,11 +241,7 @@ int nexthop_add(Link *link, NextHop *in, NextHop **ret) {
                         return r;
         } else if (r == 0) {
                 /* Take over a foreign nexthop */
-                r = set_ensure_allocated(&link->nexthops, &nexthop_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(link->nexthops, nexthop);
+                r = set_ensure_put(&link->nexthops, &nexthop_hash_ops, nexthop);
                 if (r < 0)
                         return r;
 
index de532eee7aa128bf7ff840512914694cc3e222f6..c93bf9feacd035e7339d2deb09a0453df725a001 100644 (file)
@@ -331,11 +331,7 @@ static int route_add_internal(Link *link, Set **routes, Route *in, Route **ret)
         route->initrwnd = in->initrwnd;
         route->lifetime = in->lifetime;
 
-        r = set_ensure_allocated(routes, &route_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*routes, route);
+        r = set_ensure_put(routes, &route_hash_ops, route);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -368,11 +364,7 @@ int route_add(Link *link, Route *in, Route **ret) {
                         return r;
         } else if (r == 0) {
                 /* Take over a foreign route */
-                r = set_ensure_allocated(&link->routes, &route_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(link->routes, route);
+                r = set_ensure_put(&link->routes, &route_hash_ops, route);
                 if (r < 0)
                         return r;
 
index 641f8840845c66d76c8468df0d810f9d25f1808e..c4124c0906dc214a5ac77501188c72c9326f7f80 100644 (file)
@@ -263,11 +263,7 @@ int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) {
         if (set_contains(m->rules_foreign, rule)) {
                 set_remove(m->rules_foreign, rule);
 
-                r = set_ensure_allocated(&m->rules, &routing_policy_rule_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(m->rules, rule);
+                r = set_ensure_put(&m->rules, &routing_policy_rule_hash_ops, rule);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -295,11 +291,7 @@ static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPoli
         if (r < 0)
                 return r;
 
-        r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(*rules, rule);
+        r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1328,10 +1320,6 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
         if (!l)
                 return -ENOMEM;
 
-        r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
-        if (r < 0)
-                return r;
-
         STRV_FOREACH(i, l) {
                 _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
 
@@ -1461,7 +1449,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
                         }
                 }
 
-                r = set_put(*rules, rule);
+                r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);
                 if (r < 0) {
                         log_warning_errno(r, "Failed to add RPDB rule to saved DB, ignoring: %s", p);
                         continue;
index eb80c2960bd34da907834d52d9f465d6905a050a..2fbaf656925a3ecb639c2f124bc8f7c365177dfe 100644 (file)
@@ -619,9 +619,9 @@ int mount_all(const char *dest,
 
 #if HAVE_SELINUX
                 { "/sys/fs/selinux", "/sys/fs/selinux", NULL,    NULL,                             MS_BIND,
-                  0 },  /* Bind mount first */
+                  MOUNT_MKDIR },  /* Bind mount first (mkdir/chown the mount point in case /sys/ is mounted as minimal skeleton tmpfs) */
                 { NULL,              "/sys/fs/selinux", NULL,    NULL,                             MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
-                  0 },  /* Then, make it r/o */
+                  0 },            /* Then, make it r/o (don't mkdir/chown the mount point here, the previous entry already did that) */
 #endif
         };
 
index f3a3ee8a171e9d848dd5059baba8120380fabc98..ae6828f2bf29e04229b3137d5b1a37a5f8a5bc24 100644 (file)
@@ -5141,7 +5141,7 @@ static int run(int argc, char *argv[]) {
                                 goto finish;
                         }
 
-                        r = verity_metadata_load(arg_image, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
+                        r = verity_metadata_load(arg_image, NULL, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
                                         arg_verity_data ? NULL : &arg_verity_data);
                         if (r < 0) {
                                 log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);
index 6a2d9c885ed7b211f329a59790402c6a920dd6fa..5dc5aacdff200a37fdb2829e4c0814c2472323b4 100644 (file)
@@ -8,6 +8,7 @@
 #include "fd-util.h"
 #include "group-record-nss.h"
 #include "macro.h"
+#include "nss-systemd.h"
 #include "nss-util.h"
 #include "pthread-util.h"
 #include "signal-util.h"
@@ -299,7 +300,7 @@ enum nss_status _nss_systemd_setpwent(int stayopen) {
         PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
-        if (userdb_nss_compat_is_enabled() <= 0)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
@@ -323,7 +324,7 @@ enum nss_status _nss_systemd_setgrent(int stayopen) {
         PROTECT_ERRNO;
         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
 
-        if (userdb_nss_compat_is_enabled() <= 0)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
@@ -353,13 +354,7 @@ enum nss_status _nss_systemd_getpwent_r(
         assert(result);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                UNPROTECT_ERRNO;
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
@@ -406,14 +401,8 @@ enum nss_status _nss_systemd_getgrent_r(
         assert(result);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                UNPROTECT_ERRNO;
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
-                return NSS_STATUS_UNAVAIL;
+        if (_nss_systemd_is_blocked())
+                return NSS_STATUS_NOTFOUND;
 
         _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
 
@@ -459,7 +448,7 @@ enum nss_status _nss_systemd_getgrent_r(
         }
 
         if (getgrent_data.by_membership) {
-                _cleanup_close_ int lock_fd = -1;
+                _cleanup_(_nss_systemd_unblockp) bool blocked = false;
 
                 for (;;) {
                         _cleanup_free_ char *user_name = NULL, *group_name = NULL;
@@ -479,13 +468,15 @@ enum nss_status _nss_systemd_getgrent_r(
                                 continue;
 
                         /* We are about to recursively call into NSS, let's make sure we disable recursion into our own code. */
-                        if (lock_fd < 0) {
-                                lock_fd = userdb_nss_compat_disable();
-                                if (lock_fd < 0 && lock_fd != -EBUSY) {
+                        if (!blocked) {
+                                r = _nss_systemd_block(true);
+                                if (r < 0) {
                                         UNPROTECT_ERRNO;
-                                        *errnop = -lock_fd;
+                                        *errnop = -r;
                                         return NSS_STATUS_UNAVAIL;
                                 }
+
+                                blocked = true;
                         }
 
                         r = nss_group_record_by_name(group_name, false, &gr);
@@ -549,13 +540,7 @@ enum nss_status _nss_systemd_initgroups_dyn(
         if (STR_IN_SET(user_name, root_passwd.pw_name, nobody_passwd.pw_name))
                 return NSS_STATUS_NOTFOUND;
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                UNPROTECT_ERRNO;
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         r = membershipdb_by_user(user_name, nss_glue_userdb_flags(), &iterator);
@@ -581,7 +566,7 @@ enum nss_status _nss_systemd_initgroups_dyn(
                 /* The group might be defined via traditional NSS only, hence let's do a full look-up without
                  * disabling NSS. This means we are operating recursively here. */
 
-                r = groupdb_by_name(group_name, nss_glue_userdb_flags() & ~USERDB_AVOID_NSS, &g);
+                r = groupdb_by_name(group_name, (nss_glue_userdb_flags() & ~USERDB_AVOID_NSS) | USERDB_AVOID_SHADOW, &g);
                 if (r == -ESRCH)
                         continue;
                 if (r < 0) {
@@ -627,3 +612,29 @@ enum nss_status _nss_systemd_initgroups_dyn(
 
         return any ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND;
 }
+
+static thread_local unsigned _blocked = 0;
+
+_public_ int _nss_systemd_block(bool b) {
+
+        /* This blocks recursively: it's blocked for as many times this function is called with `true` until
+         * it is called an equal time with `false`. */
+
+        if (b) {
+                if (_blocked >= UINT_MAX)
+                        return -EOVERFLOW;
+
+                _blocked++;
+        } else {
+                if (_blocked <= 0)
+                        return -EOVERFLOW;
+
+                _blocked--;
+        }
+
+        return b; /* Return what is passed in, i.e. the new state from the PoV of the caller */
+}
+
+_public_ bool _nss_systemd_is_blocked(void) {
+        return _blocked > 0;
+}
diff --git a/src/nss-systemd/nss-systemd.h b/src/nss-systemd/nss-systemd.h
new file mode 100644 (file)
index 0000000..ffa75c1
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdbool.h>
+
+int _nss_systemd_block(bool b);
+bool _nss_systemd_is_blocked(void);
+
+/* For use with the _cleanup_() macro */
+static inline void _nss_systemd_unblockp(bool *b) {
+        if (*b)
+                assert_se(_nss_systemd_block(false) >= 0);
+}
index 77e1fbe93f227e6e878c7847bb9f773b9dfa7769..f86d7643d1a412dc316c1f5633187c4b8c55a760 100644 (file)
@@ -20,5 +20,9 @@ global:
         _nss_systemd_setgrent;
         _nss_systemd_getgrent_r;
         _nss_systemd_initgroups_dyn;
+
+        /* These two are not used by glibc, but can be used by apps to explicitly disable nss-systemd for the calling thread. */
+        _nss_systemd_block;
+        _nss_systemd_is_blocked;
 local: *;
 };
index da1248a132a8c19ce4a89c218276513dd94e7bd4..8e5b3eba6c08076eb533aff60bb25fdb9efad976 100644 (file)
@@ -3,6 +3,7 @@
 #include "env-util.h"
 #include "fd-util.h"
 #include "group-record-nss.h"
+#include "nss-systemd.h"
 #include "strv.h"
 #include "user-record.h"
 #include "userdb-glue.h"
@@ -74,12 +75,7 @@ enum nss_status userdb_getpwnam(
         assert(pwd);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         r = userdb_by_name(name, nss_glue_userdb_flags(), &hr);
@@ -112,12 +108,7 @@ enum nss_status userdb_getpwuid(
         assert(pwd);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         r = userdb_by_uid(uid, nss_glue_userdb_flags(), &hr);
@@ -214,12 +205,7 @@ enum nss_status userdb_getgrnam(
         assert(gr);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         r = groupdb_by_name(name, nss_glue_userdb_flags(), &g);
@@ -235,7 +221,7 @@ enum nss_status userdb_getgrnam(
         }
 
         if (!g) {
-                _cleanup_close_ int lock_fd = -1;
+                _cleanup_(_nss_systemd_unblockp) bool blocked = false;
 
                 if (strv_isempty(members))
                         return NSS_STATUS_NOTFOUND;
@@ -245,11 +231,13 @@ enum nss_status userdb_getgrnam(
                  * acquire it, so that we can extend it (that's because glibc's group merging feature will
                  * merge groups only if both GID and name match and thus we need to have both first). It
                  * sucks behaving recursively likely this, but it's apparently what everybody does. We break
-                 * the recursion for ourselves via the userdb_nss_compat_disable() lock. */
+                 * the recursion for ourselves via the _nss_systemd_block_nss() lock. */
+
+                r = _nss_systemd_block(true);
+                if (r < 0)
+                        return r;
 
-                lock_fd = userdb_nss_compat_disable();
-                if (lock_fd < 0 && lock_fd != -EBUSY)
-                        return lock_fd;
+                blocked = true;
 
                 r = nss_group_record_by_name(name, false, &g);
                 if (r == -ESRCH)
@@ -285,12 +273,7 @@ enum nss_status userdb_getgrgid(
         assert(gr);
         assert(errnop);
 
-        r = userdb_nss_compat_is_enabled();
-        if (r < 0) {
-                *errnop = -r;
-                return NSS_STATUS_UNAVAIL;
-        }
-        if (!r)
+        if (_nss_systemd_is_blocked())
                 return NSS_STATUS_NOTFOUND;
 
         r = groupdb_by_gid(gid, nss_glue_userdb_flags(), &g);
@@ -300,20 +283,21 @@ enum nss_status userdb_getgrgid(
         }
 
         if (!g) {
-                _cleanup_close_ int lock_fd = -1;
+                _cleanup_(_nss_systemd_unblockp) bool blocked = false;
 
                 /* So, quite possibly we have to extend an existing group record with additional members. But
                  * to do this we need to know the group name first. The group didn't exist via non-NSS
                  * queries though, hence let's try to acquire it here recursively via NSS. */
 
-                lock_fd = userdb_nss_compat_disable();
-                if (lock_fd < 0 && lock_fd != -EBUSY)
-                        return lock_fd;
+                r = _nss_systemd_block(true);
+                if (r < 0)
+                        return r;
+
+                blocked = true;
 
                 r = nss_group_record_by_gid(gid, false, &g);
                 if (r == -ESRCH)
                         return NSS_STATUS_NOTFOUND;
-
                 if (r < 0) {
                         *errnop = -r;
                         return NSS_STATUS_UNAVAIL;
index 7917ea3902e860d73f4737d2ce5628913d1552cd..3dc6d9e4220b3844290c36019c9170e58acc7fd1 100644 (file)
@@ -1125,7 +1125,7 @@ int portable_detach(
                 sd_bus_error *error) {
 
         _cleanup_(lookup_paths_free) LookupPaths paths = {};
-        _cleanup_set_free_free_ Set *unit_files = NULL, *markers = NULL;
+        _cleanup_set_free_ Set *unit_files = NULL, *markers = NULL;
         _cleanup_closedir_ DIR *d = NULL;
         const char *where, *item;
         Iterator iterator;
@@ -1149,10 +1149,6 @@ int portable_detach(
                 return log_debug_errno(errno, "Failed to open '%s' directory: %m", where);
         }
 
-        markers = set_new(&path_hash_ops);
-        if (!markers)
-                return -ENOMEM;
-
         FOREACH_DIRENT(de, d, return log_debug_errno(errno, "Failed to enumerate '%s' directory: %m", where)) {
                 _cleanup_free_ char *marker = NULL;
                 UnitFileState state;
@@ -1193,15 +1189,9 @@ int portable_detach(
                 if (path_is_absolute(marker) &&
                     !image_in_search_path(IMAGE_PORTABLE, marker)) {
 
-                        r = set_ensure_allocated(&markers, &path_hash_ops);
+                        r = set_ensure_consume(&markers, &path_hash_ops_free, TAKE_PTR(marker));
                         if (r < 0)
                                 return r;
-
-                        r = set_put(markers, marker);
-                        if (r >= 0)
-                                marker = NULL;
-                        else if (r != -EEXIST)
-                                return r;
                 }
         }
 
index 1bde30e90f1ab7b2a1c7bbbe8cf2731b89085f71..01614b6684a98eb662acef602f3c3e377af8188c 100644 (file)
@@ -1119,9 +1119,7 @@ static int run(int argc, char *argv[]) {
 
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 3cadac76395c8b587fa173e64cc5bf71d8e9783c..a80b450bc0e821302324b717ef3db51e489955dc 100644 (file)
@@ -3174,9 +3174,7 @@ static int run(int argc, char **argv) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         if (streq(program_invocation_short_name, "resolvconf"))
                 r = resolvconf_parse_argv(argc, argv);
index d6eca6dfdd75d1bf93901ac793e281bedff9a380..906158c5cedba892e6503d7c92ac0662da4e3669 100644 (file)
@@ -94,7 +94,7 @@ static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
 }
 
 static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResourceKey *key) {
-        DnsTransaction *t;
+        _cleanup_(dns_transaction_gcp) DnsTransaction *t = NULL;
         int r;
 
         assert(c);
@@ -105,39 +105,26 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
                 r = dns_transaction_new(&t, c->scope, key);
                 if (r < 0)
                         return r;
-        } else {
-                if (set_contains(c->transactions, t))
-                        return 0;
-        }
-
-        r = set_ensure_allocated(&c->transactions, NULL);
-        if (r < 0)
-                goto gc;
-
-        r = set_ensure_allocated(&t->notify_query_candidates, NULL);
-        if (r < 0)
-                goto gc;
+        } else if (set_contains(c->transactions, t))
+                return 0;
 
         r = set_ensure_allocated(&t->notify_query_candidates_done, NULL);
         if (r < 0)
-                goto gc;
+                return r;
 
-        r = set_put(t->notify_query_candidates, c);
+        r = set_ensure_put(&t->notify_query_candidates, NULL, c);
         if (r < 0)
-                goto gc;
+                return r;
 
-        r = set_put(c->transactions, t);
+        r = set_ensure_put(&c->transactions, NULL, t);
         if (r < 0) {
                 (void) set_remove(t->notify_query_candidates, c);
-                goto gc;
+                return r;
         }
 
         t->clamp_ttl = c->query->clamp_ttl;
+        TAKE_PTR(t);
         return 1;
-
-gc:
-        dns_transaction_gc(t);
-        return r;
 }
 
 static int dns_query_candidate_go(DnsQueryCandidate *c) {
@@ -513,7 +500,7 @@ static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
 }
 
 static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
-        DnsQueryCandidate *c;
+        _cleanup_(dns_query_candidate_freep) DnsQueryCandidate *c = NULL;
         int r;
 
         assert(q);
@@ -524,24 +511,21 @@ static int dns_query_add_candidate(DnsQuery *q, DnsScope *s) {
                 return r;
 
         /* If this a single-label domain on DNS, we might append a suitable search domain first. */
-        if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0 &&
-            dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna))) {
-                /* OK, we need a search domain now. Let's find one for this scope */
+        if (!FLAGS_SET(q->flags, SD_RESOLVED_NO_SEARCH) &&
+            dns_scope_name_wants_search_domain(s, dns_question_first_name(q->question_idna))) {
+                /* OK, we want a search domain now. Let's find one for this scope */
 
                 r = dns_query_candidate_next_search_domain(c);
-                if (r <= 0) /* if there's no search domain, then we won't add any transaction. */
-                        goto fail;
+                if (r < 0)
+                        return r;
         }
 
         r = dns_query_candidate_setup_transactions(c);
         if (r < 0)
-                goto fail;
+                return r;
 
+        TAKE_PTR(c);
         return 0;
-
-fail:
-        dns_query_candidate_free(c);
-        return r;
 }
 
 static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
index fc7ccf553e9adb0580a134aea481bba9e9b4ec07..fe8a21955714a323a686eefb54837c9a48321c77 100644 (file)
@@ -102,6 +102,8 @@ enum {
 };
 
 DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_free);
+
 void dns_query_candidate_notify(DnsQueryCandidate *c);
 
 int dns_query_new(Manager *m, DnsQuery **q, DnsQuestion *question_utf8, DnsQuestion *question_idna, int family, uint64_t flags);
index d06e428011b276938864804cf63faadcf7d79e24..764ccee0e0ef523137135eb3f135845aac717e9c 100644 (file)
@@ -619,7 +619,7 @@ DnsScopeMatch dns_scope_good_domain(
                      manager_is_own_hostname(s->manager, domain) <= 0))  /* never resolve the local hostname via LLMNR */
                         return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative
                                                         * for single-label names, i.e. one label. This is
-                                                        * particular relevant as it means a "." route on some
+                                                        * particularly relevant as it means a "." route on some
                                                         * other scope won't pull all traffic away from
                                                         * us. (If people actually want to pull traffic away
                                                         * from us they should turn off LLMNR on the
@@ -651,20 +651,21 @@ bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key) {
 
         if (s->protocol == DNS_PROTOCOL_DNS) {
 
-                /* On classic DNS, looking up non-address RRs is always
-                 * fine. (Specifically, we want to permit looking up
-                 * DNSKEY and DS records on the root and top-level
-                 * domains.) */
+                /* On classic DNS, looking up non-address RRs is always fine. (Specifically, we want to
+                 * permit looking up DNSKEY and DS records on the root and top-level domains.) */
                 if (!dns_resource_key_is_address(key))
                         return true;
 
-                /* However, we refuse to look up A and AAAA RRs on the
-                 * root and single-label domains, under the assumption
-                 * that those should be resolved via LLMNR or search
-                 * path only, and should not be leaked onto the
-                 * internet. */
-                return !(dns_name_is_single_label(dns_resource_key_name(key)) ||
-                         dns_name_is_root(dns_resource_key_name(key)));
+                /* Unless explicitly overridden, we refuse to look up A and AAAA RRs on the root and
+                 * single-label domains, under the assumption that those should be resolved via LLMNR or
+                 * search path only, and should not be leaked onto the internet. */
+                const char* name = dns_resource_key_name(key);
+
+                if (!s->manager->resolve_unicast_single_label &&
+                    dns_name_is_single_label(name))
+                        return false;
+
+                return !dns_name_is_root(name);
         }
 
         /* On mDNS and LLMNR, send A and AAAA queries only on the
@@ -1169,7 +1170,7 @@ DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s) {
         return s->manager->search_domains;
 }
 
-bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) {
+bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name) {
         assert(s);
 
         if (s->protocol != DNS_PROTOCOL_DNS)
@@ -1253,11 +1254,7 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
                 if (!scope->announced &&
                     dns_resource_key_is_dnssd_ptr(z->rr->key)) {
                         if (!set_contains(types, dns_resource_key_name(z->rr->key))) {
-                                r = set_ensure_allocated(&types, &dns_name_hash_ops);
-                                if (r < 0)
-                                        return log_debug_errno(r, "Failed to allocate set: %m");
-
-                                r = set_put(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)
                                         return log_debug_errno(r, "Failed to add item to set: %m");
                         }
index 974692be5b170380050082dab3ec05f72a147148..b356b92120546eeda2358d79973d849d788ff07b 100644 (file)
@@ -99,7 +99,7 @@ void dns_scope_dump(DnsScope *s, FILE *f);
 
 DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s);
 
-bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
+bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name);
 
 bool dns_scope_network_good(DnsScope *s);
 
index ce994a7ee0b213c0fa525d1547cc141c85e7e69a..03edbe26dc0d245ae7011288be8126c7a946c5b9 100644 (file)
@@ -278,7 +278,7 @@ static int dns_stub_stream_complete(DnsStream *s, int error) {
 }
 
 static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
-        DnsQuery *q = NULL;
+        _cleanup_(dns_query_freep) DnsQuery *q = NULL;
         int r;
 
         assert(m);
@@ -289,52 +289,52 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
             in_addr_is_localhost(p->family, &p->destination) <= 0) {
                 log_error("Got packet on unexpected IP range, refusing.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
-                goto fail;
+                return;
         }
 
         r = dns_packet_extract(p);
         if (r < 0) {
                 log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_FORMERR, false);
-                goto fail;
+                return;
         }
 
         if (!DNS_PACKET_VERSION_SUPPORTED(p)) {
                 log_debug("Got EDNS OPT field with unsupported version number.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_BADVERS, false);
-                goto fail;
+                return;
         }
 
         if (dns_type_is_obsolete(p->question->keys[0]->type)) {
                 log_debug("Got message with obsolete key type, refusing.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
-                goto fail;
+                return;
         }
 
         if (dns_type_is_zone_transer(p->question->keys[0]->type)) {
                 log_debug("Got request for zone transfer, refusing.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
-                goto fail;
+                return;
         }
 
         if (!DNS_PACKET_RD(p))  {
                 /* If the "rd" bit is off (i.e. recursion was not requested), then refuse operation */
                 log_debug("Got request with recursion disabled, refusing.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_REFUSED, false);
-                goto fail;
+                return;
         }
 
         if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
                 log_debug("Got request with DNSSEC CD bit set, refusing.");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
-                goto fail;
+                return;
         }
 
         r = dns_query_new(m, &q, p->question, p->question, 0, SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_SEARCH);
         if (r < 0) {
                 log_error_errno(r, "Failed to generate query object: %m");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
-                goto fail;
+                return;
         }
 
         /* Request that the TTL is corrected by the cached time for this lookup, so that we return vaguely useful TTLs */
@@ -348,30 +348,23 @@ static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
                 /* Remember which queries belong to this stream, so that we can cancel them when the stream
                  * is disconnected early */
 
-                r = set_ensure_allocated(&s->queries, &trivial_hash_ops);
+                r = set_ensure_put(&s->queries, NULL, q);
                 if (r < 0) {
                         log_oom();
-                        goto fail;
-                }
-
-                if (set_put(s->queries, q) < 0) {
-                        log_oom();
-                        goto fail;
+                        return;
                 }
+                assert(r > 0);
         }
 
         r = dns_query_go(q);
         if (r < 0) {
                 log_error_errno(r, "Failed to start query: %m");
                 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
-                goto fail;
+                return;
         }
 
         log_debug("Processing query...");
-        return;
-
-fail:
-        dns_query_free(q);
+        TAKE_PTR(q);
 }
 
 static int on_dns_stub_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
index 5898308d5fa46f6060d0c83c4743028ce49dee86..cd5a0e3dd91b769c5a51d77360ff80ac03de2d03 100644 (file)
@@ -1501,11 +1501,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
                 add_known_answers = true;
 
         if (t->key->type == DNS_TYPE_ANY) {
-                r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
-                if (r < 0)
-                        return r;
-
-                r = set_put(keys, t->key);
+                r = set_ensure_put(&keys, &dns_resource_key_hash_ops, t->key);
                 if (r < 0)
                         return r;
         }
@@ -1571,11 +1567,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
                         add_known_answers = true;
 
                 if (other->key->type == DNS_TYPE_ANY) {
-                        r = set_ensure_allocated(&keys, &dns_resource_key_hash_ops);
-                        if (r < 0)
-                                return r;
-
-                        r = set_put(keys, other->key);
+                        r = set_ensure_put(&keys, &dns_resource_key_hash_ops, other->key);
                         if (r < 0)
                                 return r;
                 }
@@ -1800,7 +1792,7 @@ static int dns_transaction_find_cyclic(DnsTransaction *t, DnsTransaction *aux) {
 }
 
 static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) {
-        DnsTransaction *aux;
+        _cleanup_(dns_transaction_gcp) DnsTransaction *aux = NULL;
         int r;
 
         assert(t);
@@ -1833,34 +1825,22 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource
                 }
         }
 
-        r = set_ensure_allocated(&t->dnssec_transactions, NULL);
-        if (r < 0)
-                goto gc;
-
-        r = set_ensure_allocated(&aux->notify_transactions, NULL);
-        if (r < 0)
-                goto gc;
-
         r = set_ensure_allocated(&aux->notify_transactions_done, NULL);
         if (r < 0)
-                goto gc;
+                return r;
 
-        r = set_put(t->dnssec_transactions, aux);
+        r = set_ensure_put(&t->dnssec_transactions, NULL, aux);
         if (r < 0)
-                goto gc;
+                return r;;
 
-        r = set_put(aux->notify_transactions, t);
+        r = set_ensure_put(&aux->notify_transactions, NULL, t);
         if (r < 0) {
                 (void) set_remove(t->dnssec_transactions, aux);
-                goto gc;
+                return r;
         }
 
-        *ret = aux;
+        *ret = TAKE_PTR(aux);
         return 1;
-
-gc:
-        dns_transaction_gc(aux);
-        return r;
 }
 
 static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) {
index b1d4348409fc41aab1fa41e4b756acbf195078fb..167541806a28eaa5f0deac78cc7664bf271ba1e8 100644 (file)
@@ -138,6 +138,8 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key);
 DnsTransaction* dns_transaction_free(DnsTransaction *t);
 
 bool dns_transaction_gc(DnsTransaction *t);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_gc);
+
 int dns_transaction_go(DnsTransaction *t);
 
 void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p);
index 843f4c0f45fb6b6d6f8f5aa44137dbbe1c1eb4e3..d68d0c3ba16cb47609ae5be7cfe92249ca2ad40e 100644 (file)
@@ -393,15 +393,9 @@ static int dns_trust_anchor_load_negative(DnsTrustAnchor *d, const char *path, u
                 return -EINVAL;
         }
 
-        r = set_ensure_allocated(&d->negative_by_name, &dns_name_hash_ops);
-        if (r < 0)
-                return log_oom();
-
-        r = set_put(d->negative_by_name, domain);
+        r = set_ensure_consume(&d->negative_by_name, &dns_name_hash_ops, TAKE_PTR(domain));
         if (r < 0)
                 return log_oom();
-        if (r > 0)
-                domain = NULL;
 
         return 0;
 }
@@ -592,11 +586,7 @@ static int dns_trust_anchor_revoked_put(DnsTrustAnchor *d, DnsResourceRecord *rr
 
         assert(d);
 
-        r = set_ensure_allocated(&d->revoked_by_rr, &dns_resource_record_hash_ops);
-        if (r < 0)
-                return r;
-
-        r = set_put(d->revoked_by_rr, rr);
+        r = set_ensure_put(&d->revoked_by_rr, &dns_resource_record_hash_ops, rr);
         if (r < 0)
                 return r;
         if (r > 0)
index 0ef4c892f7066f9d9d64771935074866dc20299a..33879d6142ef2dbea9c7aeb5e00f70d0eb1a5f93 100644 (file)
@@ -162,7 +162,7 @@ static int dns_zone_link_item(DnsZone *z, DnsZoneItem *i) {
 }
 
 static int dns_zone_item_probe_start(DnsZoneItem *i)  {
-        DnsTransaction *t;
+        _cleanup_(dns_transaction_gcp) DnsTransaction *t = NULL;
         int r;
 
         assert(i);
@@ -183,25 +183,20 @@ static int dns_zone_item_probe_start(DnsZoneItem *i)  {
                         return r;
         }
 
-        r = set_ensure_allocated(&t->notify_zone_items, NULL);
-        if (r < 0)
-                goto gc;
-
         r = set_ensure_allocated(&t->notify_zone_items_done, NULL);
         if (r < 0)
-                goto gc;
+                return r;
 
-        r = set_put(t->notify_zone_items, i);
+        r = set_ensure_put(&t->notify_zone_items, NULL, i);
         if (r < 0)
-                goto gc;
+                return r;
 
-        i->probe_transaction = t;
         t->probing = true;
+        i->probe_transaction = TAKE_PTR(t);
 
-        if (t->state == DNS_TRANSACTION_NULL) {
-
+        if (i->probe_transaction->state == DNS_TRANSACTION_NULL) {
                 i->block_ready++;
-                r = dns_transaction_go(t);
+                r = dns_transaction_go(i->probe_transaction);
                 i->block_ready--;
 
                 if (r < 0) {
@@ -212,10 +207,6 @@ static int dns_zone_item_probe_start(DnsZoneItem *i)  {
 
         dns_zone_item_notify(i);
         return 0;
-
-gc:
-        dns_transaction_gc(t);
-        return r;
 }
 
 int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
index 2cb06c098da929f1b3ad4c63395226d22fd39fee..6a7f7499572cfc9592e64ab7233468960e9654ee 100644 (file)
@@ -120,15 +120,10 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) {
                         /* Optimize the case where we don't need to store any addresses, by storing
                          * only the name in a dedicated Set instead of the hashmap */
 
-                        r = set_ensure_allocated(&hosts->no_address, &dns_name_hash_ops);
-                        if (r < 0)
-                                return log_oom();
-
-                        r = set_put(hosts->no_address, name);
+                        r = set_ensure_consume(&hosts->no_address, &dns_name_hash_ops, TAKE_PTR(name));
                         if (r < 0)
                                 return r;
 
-                        TAKE_PTR(name);
                         continue;
                 }
 
index 4a451ccc4c7f9c36aa584b9b171345bde160315d..553da8d251826a01f234324617454de67a578d55 100644 (file)
@@ -18,13 +18,14 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Resolve.DNS,             config_parse_dns_servers,            DNS_SERVER_SYSTEM,   0
-Resolve.FallbackDNS,     config_parse_dns_servers,            DNS_SERVER_FALLBACK, 0
-Resolve.Domains,         config_parse_search_domains,         0,                   0
-Resolve.LLMNR,           config_parse_resolve_support,        0,                   offsetof(Manager, llmnr_support)
-Resolve.MulticastDNS,    config_parse_resolve_support,        0,                   offsetof(Manager, mdns_support)
-Resolve.DNSSEC,          config_parse_dnssec_mode,            0,                   offsetof(Manager, dnssec_mode)
-Resolve.DNSOverTLS,      config_parse_dns_over_tls_mode,      0,                   offsetof(Manager, dns_over_tls_mode)
-Resolve.Cache,           config_parse_dns_cache_mode,         DNS_CACHE_MODE_YES,  offsetof(Manager, enable_cache)
-Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0,                   offsetof(Manager, dns_stub_listener_mode)
-Resolve.ReadEtcHosts,    config_parse_bool,                   0,                   offsetof(Manager, read_etc_hosts)
+Resolve.DNS,                       config_parse_dns_servers,            DNS_SERVER_SYSTEM,   0
+Resolve.FallbackDNS,               config_parse_dns_servers,            DNS_SERVER_FALLBACK, 0
+Resolve.Domains,                   config_parse_search_domains,         0,                   0
+Resolve.LLMNR,                     config_parse_resolve_support,        0,                   offsetof(Manager, llmnr_support)
+Resolve.MulticastDNS,              config_parse_resolve_support,        0,                   offsetof(Manager, mdns_support)
+Resolve.DNSSEC,                    config_parse_dnssec_mode,            0,                   offsetof(Manager, dnssec_mode)
+Resolve.DNSOverTLS,                config_parse_dns_over_tls_mode,      0,                   offsetof(Manager, dns_over_tls_mode)
+Resolve.Cache,                     config_parse_dns_cache_mode,         DNS_CACHE_MODE_YES,  offsetof(Manager, enable_cache)
+Resolve.DNSStubListener,           config_parse_dns_stub_listener_mode, 0,                   offsetof(Manager, dns_stub_listener_mode)
+Resolve.ReadEtcHosts,              config_parse_bool,                   0,                   offsetof(Manager, read_etc_hosts)
+Resolve.ResolveUnicastSingleLabel, config_parse_bool,                   0,                   offsetof(Manager, resolve_unicast_single_label)
index 6fa5e734bbb024c06bdd5d4e9d8c0b681bf31db8..59944df7469081639d100a6f4268f18a2492b171 100644 (file)
@@ -70,9 +70,10 @@ struct Manager {
         LIST_HEAD(DnsSearchDomain, search_domains);
         unsigned n_search_domains;
 
-        bool need_builtin_fallbacks:1;
+        bool need_builtin_fallbacks;
+        bool read_resolv_conf;
+        bool resolve_unicast_single_label;
 
-        bool read_resolv_conf:1;
         struct stat resolv_conf_stat;
 
         DnsTrustAnchor trust_anchor;
index 50989a6b0a33ff63f76ea36e0b0925606a010187..566b950a637a1f486bdc7f7f0a610d28fb5d37ae 100644 (file)
@@ -40,7 +40,7 @@ static int run(int argc, char *argv[]) {
 
         r = mac_selinux_init();
         if (r < 0)
-                return log_error_errno(r, "SELinux setup failed: %m");
+                return r;
 
         /* Drop privileges, but only if we have been started as root. If we are not running as root we assume most
          * privileges are already dropped and we can't create our directory. */
index 85822e316c1fe3838806cbc2a888ca35eab0e6d6..082ad7162610993c8098fcefa01d8c464ec00f07 100644 (file)
@@ -22,3 +22,4 @@
 #Cache=yes
 #DNSStubListener=yes
 #ReadEtcHosts=yes
+#ResolveUnicastSingleLabel=no
index 4b1145a6ba3cc29d869e10ded3369b0703fa94e4..d93d5d601334928624465234d93ab31917f28ef4 100644 (file)
@@ -13,6 +13,7 @@
 #include "escape.h"
 #include "exec-util.h"
 #include "exit-status.h"
+#include "fileio.h"
 #include "hexdecoct.h"
 #include "hostname-util.h"
 #include "in-addr-util.h"
@@ -24,6 +25,7 @@
 #include "nsflags.h"
 #include "numa-util.h"
 #include "parse-util.h"
+#include "path-util.h"
 #include "process-util.h"
 #include "rlimit-util.h"
 #include "securebits-util.h"
@@ -494,18 +496,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                         if (r < 0)
                                 return bus_log_create_error(r);
                         return 1;
-                } else if (isempty(eq) && STR_IN_SET(field, "DefaultMemoryLow",
-                                                            "DefaultMemoryMin",
-                                                            "MemoryLow",
-                                                            "MemoryMin")) {
-                        /* We can't use CGROUP_LIMIT_MIN nor CGROUP_LIMIT_MAX to convey the empty assignment
-                         * so marshall specially as a boolean. */
-                        r = sd_bus_message_append(m, "(sv)", field, "b", 0);
-                        if (r < 0)
-                                return bus_log_create_error(r);
-                        return 1;
                 } else if (isempty(eq)) {
-                        r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
+                        uint64_t empty_value = STR_IN_SET(field,
+                                                          "DefaultMemoryLow",
+                                                          "DefaultMemoryMin",
+                                                          "MemoryLow",
+                                                          "MemoryMin") ?
+                                               CGROUP_LIMIT_MIN :
+                                               CGROUP_LIMIT_MAX;
+
+                        r = sd_bus_message_append(m, "(sv)", field, "t", empty_value);
                         if (r < 0)
                                 return bus_log_create_error(r);
                         return 1;
@@ -849,6 +849,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                               "ProtectHome",
                               "SELinuxContext",
                               "RootImage",
+                              "RootVerity",
                               "RuntimeDirectoryPreserve",
                               "Personality",
                               "KeyringMode",
@@ -1415,6 +1416,24 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                 return 1;
         }
 
+        if (streq(field, "RootHash")) {
+                _cleanup_free_ void *roothash_decoded = NULL;
+                size_t roothash_decoded_size = 0;
+
+                /* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
+                if (path_is_absolute(eq))
+                        return bus_append_string(m, "RootHashPath", eq);
+
+                /* We have a roothash to decode, eg: RootHash=012345789abcdef */
+                r = unhexmem(eq, strlen(eq), &roothash_decoded, &roothash_decoded_size);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to decode RootHash= '%s': %m", eq);
+                if (roothash_decoded_size < sizeof(sd_id128_t))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RootHash= '%s' is too short: %m", eq);
+
+                return bus_append_byte_array(m, field, roothash_decoded, roothash_decoded_size);
+        }
+
         return 0;
 }
 
index a61f8e70da0b18dfdc4eabce7ad6644766bd0424..f64e200731dc42484361f0bca206b1305a90d89f 100644 (file)
@@ -613,13 +613,9 @@ int bus_message_print_all_properties(
                         return r;
 
                 if (found_properties) {
-                        r = set_ensure_allocated(found_properties, &string_hash_ops);
+                        r = set_ensure_put(found_properties, &string_hash_ops, name);
                         if (r < 0)
                                 return log_oom();
-
-                        r = set_put(*found_properties, name);
-                        if (r < 0 && r != -EEXIST)
-                                return log_oom();
                 }
 
                 name_with_equal = strjoin(name, "=");
index 2c8a5d85bfec01ff228060ccabd08d490cc639b5..e576518c6b8e4aa5c566aad3df5d5e187b3fa679 100644 (file)
@@ -1421,7 +1421,7 @@ int decrypted_image_relinquish(DecryptedImage *d) {
         return 0;
 }
 
-int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) {
+int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) {
         _cleanup_free_ char *verity_filename = NULL;
         _cleanup_free_ void *roothash_decoded = NULL;
         size_t roothash_decoded_size = 0;
@@ -1465,24 +1465,31 @@ int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roo
                 _cleanup_free_ char *text = NULL;
                 assert(ret_roothash_size);
 
-                r = getxattr_malloc(image, "user.verity.roothash", &text, true);
-                if (r < 0) {
-                        char *fn, *e, *n;
-
-                        if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
+                if (root_hash_path) {
+                        /* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
+                        r = read_one_line_file(root_hash_path, &text);
+                        if (r < 0)
                                 return r;
+                } else {
+                        r = getxattr_malloc(image, "user.verity.roothash", &text, true);
+                        if (r < 0) {
+                                char *fn, *e, *n;
+
+                                if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
+                                        return r;
 
-                        fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
-                        n = stpcpy(fn, image);
-                        e = endswith(fn, ".raw");
-                        if (e)
-                                n = e;
+                                fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
+                                n = stpcpy(fn, image);
+                                e = endswith(fn, ".raw");
+                                if (e)
+                                        n = e;
 
-                        strcpy(n, ".roothash");
+                                strcpy(n, ".roothash");
 
-                        r = read_one_line_file(fn, &text);
-                        if (r < 0 && r != -ENOENT)
-                                return r;
+                                r = read_one_line_file(fn, &text);
+                                if (r < 0 && r != -ENOENT)
+                                        return r;
+                        }
                 }
 
                 if (text) {
index 92d223cfec5708a4a3e811512d92dbf22b397ff6..6a53b949486fb52ee55f3004d969745da97bc592 100644 (file)
@@ -100,6 +100,6 @@ int decrypted_image_relinquish(DecryptedImage *d);
 const char* partition_designator_to_string(int i) _const_;
 int partition_designator_from_string(const char *name) _pure_;
 
-int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data);
+int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data);
 bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator);
 bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator);
index 6a3cfe770ca416fc175efc470c535d1b4a48e542..de05fb092cd171b69cff0db2e7cbcd3b86a9e593 100644 (file)
@@ -1742,17 +1742,13 @@ int seccomp_restrict_archs(Set *archs) {
         return 0;
 }
 
-int parse_syscall_archs(char **l, Set **archs) {
-        _cleanup_set_free_ Set *_archs = NULL;
+int parse_syscall_archs(char **l, Set **ret_archs) {
+        _cleanup_set_free_ Set *archs = NULL;
         char **s;
         int r;
 
         assert(l);
-        assert(archs);
-
-        r = set_ensure_allocated(&_archs, NULL);
-        if (r < 0)
-                return r;
+        assert(ret_archs);
 
         STRV_FOREACH(s, l) {
                 uint32_t a;
@@ -1761,13 +1757,12 @@ int parse_syscall_archs(char **l, Set **archs) {
                 if (r < 0)
                         return -EINVAL;
 
-                r = set_put(_archs, UINT32_TO_PTR(a + 1));
+                r = set_ensure_put(&archs, NULL, UINT32_TO_PTR(a + 1));
                 if (r < 0)
                         return -ENOMEM;
         }
 
-        *archs = TAKE_PTR(_archs);
-
+        *ret_archs = TAKE_PTR(archs);
         return 0;
 }
 
index 0b48e74a87fe15e5abca7adb8a30d6ce26b0f4d4..9580f9268d978fa9ce8801e0811f5ed97f18a97a 100644 (file)
@@ -105,6 +105,6 @@ extern const uint32_t seccomp_local_archs[];
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(scmp_filter_ctx, seccomp_release);
 
-int parse_syscall_archs(char **l, Set **archs);
+int parse_syscall_archs(char **l, Set **ret_archs);
 
 uint32_t scmp_act_kill_process(void);
index c3a6e02e5a1e1b5e31d24b7edda95cdf0e5cf7fa..6fedbd6ebe62904de61a3385eee0a20f3210d876 100644 (file)
@@ -3,6 +3,7 @@
 #include <sys/auxv.h>
 
 #include "dirent-util.h"
+#include "dlfcn-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "group-record-nss.h"
@@ -32,8 +33,8 @@ struct UserDBIterator {
         bool nss_iterating:1;
         bool synthesize_root:1;
         bool synthesize_nobody:1;
+        bool nss_systemd_blocked:1;
         int error;
-        int nss_lock;
         unsigned n_found;
         sd_event *event;
         UserRecord *found_user;                   /* when .what == LOOKUP_USER */
@@ -85,7 +86,9 @@ UserDBIterator* userdb_iterator_free(UserDBIterator *iterator) {
         }
 
         sd_event_unref(iterator->event);
-        safe_close(iterator->nss_lock);
+
+        if (iterator->nss_systemd_blocked)
+                assert_se(userdb_block_nss_systemd(false) >= 0);
 
         return mfree(iterator);
 }
@@ -102,12 +105,27 @@ static UserDBIterator* userdb_iterator_new(LookupWhat what) {
 
         *i = (UserDBIterator) {
                 .what = what,
-                .nss_lock = -1,
         };
 
         return i;
 }
 
+static int userdb_iterator_block_nss_systemd(UserDBIterator *iterator) {
+        int r;
+
+        assert(iterator);
+
+        if (iterator->nss_systemd_blocked)
+                return 0;
+
+        r = userdb_block_nss_systemd(true);
+        if (r < 0)
+                return r;
+
+        iterator->nss_systemd_blocked = true;
+        return 1;
+}
+
 struct user_group_data {
         JsonVariant *record;
         bool incomplete;
@@ -359,15 +377,9 @@ static int userdb_connect(
         if (r < 0)
                 return log_debug_errno(r, "Failed to invoke varlink method: %m");
 
-        r = set_ensure_allocated(&iterator->links, &link_hash_ops);
-        if (r < 0)
-                return log_debug_errno(r, "Failed to allocate set: %m");
-
-        r = set_put(iterator->links, vl);
+        r = set_ensure_consume(&iterator->links, &link_hash_ops, TAKE_PTR(vl));
         if (r < 0)
                 return log_debug_errno(r, "Failed to add varlink connection to set: %m");
-
-        TAKE_PTR(vl);
         return r;
 }
 
@@ -606,13 +618,11 @@ int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) {
                         return r;
         }
 
-        if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !(iterator && iterator->nss_covered)) {
-                /* Make sure the NSS lookup doesn't recurse back to us. (EBUSY is fine here, it just means we
-                 * already took the lock from our thread, which is totally OK.) */
-                r = userdb_nss_compat_disable();
-                if (r >= 0 || r == -EBUSY) {
-                        iterator->nss_lock = r;
+        if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !iterator->nss_covered) {
+                /* Make sure the NSS lookup doesn't recurse back to us. */
 
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r >= 0) {
                         /* Client-side NSS fallback */
                         r = nss_user_record_by_name(name, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret);
                         if (r >= 0)
@@ -655,11 +665,9 @@ int userdb_by_uid(uid_t uid, UserDBFlags flags, UserRecord **ret) {
                         return r;
         }
 
-        if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !(iterator && iterator->nss_covered)) {
-                r = userdb_nss_compat_disable();
-                if (r >= 0 || r == -EBUSY) {
-                        iterator->nss_lock = r;
-
+        if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !iterator->nss_covered) {
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r >= 0) {
                         /* Client-side NSS fallback */
                         r = nss_user_record_by_uid(uid, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret);
                         if (r >= 0)
@@ -693,9 +701,9 @@ int userdb_all(UserDBFlags flags, UserDBIterator **ret) {
         r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", true, NULL, flags);
 
         if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && (r < 0 || !iterator->nss_covered)) {
-                iterator->nss_lock = userdb_nss_compat_disable();
-                if (iterator->nss_lock < 0 && iterator->nss_lock != -EBUSY)
-                        return iterator->nss_lock;
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r < 0)
+                        return r;
 
                 setpwent();
                 iterator->nss_iterating = true;
@@ -815,10 +823,8 @@ int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) {
         }
 
         if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !(iterator && iterator->nss_covered)) {
-                r = userdb_nss_compat_disable();
-                if (r >= 0 || r == -EBUSY) {
-                        iterator->nss_lock = r;
-
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r >= 0) {
                         r = nss_group_record_by_name(name, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret);
                         if (r >= 0)
                                 return r;
@@ -861,10 +867,8 @@ int groupdb_by_gid(gid_t gid, UserDBFlags flags, GroupRecord **ret) {
         }
 
         if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && !(iterator && iterator->nss_covered)) {
-                r = userdb_nss_compat_disable();
-                if (r >= 0 || r == -EBUSY) {
-                        iterator->nss_lock = r;
-
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r >= 0) {
                         r = nss_group_record_by_gid(gid, !FLAGS_SET(flags, USERDB_AVOID_SHADOW), ret);
                         if (r >= 0)
                                 return r;
@@ -897,9 +901,9 @@ int groupdb_all(UserDBFlags flags, UserDBIterator **ret) {
         r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetGroupRecord", true, NULL, flags);
 
         if (!FLAGS_SET(flags, USERDB_AVOID_NSS) && (r < 0 || !iterator->nss_covered)) {
-                iterator->nss_lock = userdb_nss_compat_disable();
-                if (iterator->nss_lock < 0 && iterator->nss_lock != -EBUSY)
-                        return iterator->nss_lock;
+                r = userdb_iterator_block_nss_systemd(iterator);
+                if (r < 0)
+                        return r;
 
                 setgrent();
                 iterator->nss_iterating = true;
@@ -998,9 +1002,9 @@ int membershipdb_by_user(const char *name, UserDBFlags flags, UserDBIterator **r
         if ((r >= 0 && iterator->nss_covered) || FLAGS_SET(flags, USERDB_AVOID_NSS))
                 goto finish;
 
-        iterator->nss_lock = userdb_nss_compat_disable();
-        if (iterator->nss_lock < 0 && iterator->nss_lock != -EBUSY)
-                return iterator->nss_lock;
+        r = userdb_iterator_block_nss_systemd(iterator);
+        if (r < 0)
+                return r;
 
         iterator->filter_user_name = strdup(name);
         if (!iterator->filter_user_name)
@@ -1041,9 +1045,9 @@ int membershipdb_by_group(const char *name, UserDBFlags flags, UserDBIterator **
         if ((r >= 0 && iterator->nss_covered) || FLAGS_SET(flags, USERDB_AVOID_NSS))
                 goto finish;
 
-        iterator->nss_lock = userdb_nss_compat_disable();
-        if (iterator->nss_lock < 0 && iterator->nss_lock != -EBUSY)
-                return iterator->nss_lock;
+        r = userdb_iterator_block_nss_systemd(iterator);
+        if (r < 0)
+                return r;
 
         /* We ignore all errors here, since the group might be defined by a userdb native service, and we queried them already above. */
         (void) nss_group_record_by_name(name, false, &gr);
@@ -1082,9 +1086,9 @@ int membershipdb_all(UserDBFlags flags, UserDBIterator **ret) {
         if ((r >= 0 && iterator->nss_covered) || FLAGS_SET(flags, USERDB_AVOID_NSS))
                 goto finish;
 
-        iterator->nss_lock = userdb_nss_compat_disable();
-        if (iterator->nss_lock < 0 && iterator->nss_lock != -EBUSY)
-                return iterator->nss_lock;
+        r = userdb_iterator_block_nss_systemd(iterator);
+        if (r < 0)
+                return r;
 
         setgrent();
         iterator->nss_iterating = true;
@@ -1221,115 +1225,24 @@ int membershipdb_by_group_strv(const char *name, UserDBFlags flags, char ***ret)
         return 0;
 }
 
-static int userdb_thread_sockaddr(struct sockaddr_un *ret_sa, socklen_t *ret_salen) {
-        static const uint8_t
-                k1[16] = { 0x35, 0xc1, 0x1f, 0x41, 0x59, 0xc6, 0xa0, 0xf9, 0x33, 0x4b, 0x17, 0x3d, 0xb9, 0xf6, 0x14, 0xd9 },
-                k2[16] = { 0x6a, 0x11, 0x4c, 0x37, 0xe5, 0xa3, 0x8c, 0xa6, 0x93, 0x55, 0x64, 0x8c, 0x93, 0xee, 0xa1, 0x7b };
-
-        struct siphash sh;
-        uint64_t x, y;
-        pid_t tid;
-        void *p;
-
-        assert(ret_sa);
-        assert(ret_salen);
-
-        /* This calculates an AF_UNIX socket address in the abstract namespace whose existence works as an
-         * indicator whether to emulate NSS records for complex user records that are also available via the
-         * varlink protocol. The name of the socket is picked in a way so that:
-         *
-         *     â†’ it is per-thread (by hashing from the TID)
-         *
-         *     â†’ is not guessable for foreign processes (by hashing from the â€” hopefully secret â€” AT_RANDOM
-         *       value every process gets passed from the kernel
-         *
-         * By using a socket the NSS emulation can be nicely turned off for limited amounts of time only,
-         * simply controlled by the lifetime of the fd itself. By using an AF_UNIX socket in the abstract
-         * namespace the lock is automatically cleaned up when the process dies abnormally.
-         *
-         */
-
-        p = ULONG_TO_PTR(getauxval(AT_RANDOM));
-        if (!p)
-                return -EIO;
-
-        tid = gettid();
-
-        siphash24_init(&sh, k1);
-        siphash24_compress(p, 16, &sh);
-        siphash24_compress(&tid, sizeof(tid), &sh);
-        x = siphash24_finalize(&sh);
-
-        siphash24_init(&sh, k2);
-        siphash24_compress(p, 16, &sh);
-        siphash24_compress(&tid, sizeof(tid), &sh);
-        y = siphash24_finalize(&sh);
-
-        *ret_sa = (struct sockaddr_un) {
-                .sun_family = AF_UNIX,
-        };
-
-        sprintf(ret_sa->sun_path + 1, "userdb-%016" PRIx64 "%016" PRIx64, x, y);
-        *ret_salen = offsetof(struct sockaddr_un, sun_path) + 1 + 7 + 32;
-
-        return 0;
-}
-
-int userdb_nss_compat_is_enabled(void) {
-        _cleanup_close_ int fd = -1;
-        union sockaddr_union sa;
-        socklen_t salen;
-        int r;
-
-        /* Tests whether the NSS compatibility logic is currently turned on for the invoking thread. Returns
-         * true if NSS compatibility is turned on, i.e. whether NSS records shall be synthesized from complex
-         * user records. */
-
-        r = userdb_thread_sockaddr(&sa.un, &salen);
-        if (r < 0)
-                return r;
-
-        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
-        if (fd < 0)
-                return -errno;
+int userdb_block_nss_systemd(int b) {
+        _cleanup_(dlclosep) void *dl = NULL;
+        int (*call)(bool b);
 
-        /* Try to connect(). This doesn't do anything really, except that it checks whether the socket
-         * address is bound at all. */
-        if (connect(fd, &sa.sa, salen) < 0) {
-                if (errno == ECONNREFUSED) /* the socket is not bound, hence NSS emulation shall be done */
-                        return true;
+        /* Note that we might be called from libnss_systemd.so.2 itself, but that should be fine, really. */
 
-                return -errno;
+        dl = dlopen(ROOTLIBDIR "libnss_systemd.so.2", RTLD_LAZY|RTLD_NODELETE);
+        if (!dl) {
+                /* If the file isn't installed, don't complain loudly */
+                log_debug("Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dlerror());
+                return 0;
         }
 
-        return false;
-}
-
-int userdb_nss_compat_disable(void) {
-        _cleanup_close_ int fd = -1;
-        union sockaddr_union sa;
-        socklen_t salen;
-        int r;
-
-        /* Turn off the NSS compatibility logic for the invoking thread. By default NSS records are
-         * synthesized for all complex user records looked up via NSS. If this call is invoked this is
-         * disabled for the invoking thread, but only for it. A caller that natively supports the varlink
-         * user record protocol may use that to turn off the compatibility for NSS lookups. */
-
-        r = userdb_thread_sockaddr(&sa.un, &salen);
-        if (r < 0)
-                return r;
-
-        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
-        if (fd < 0)
-                return -errno;
-
-        if (bind(fd, &sa.sa, salen) < 0) {
-                if (errno == EADDRINUSE) /* lock already taken, convert this into a recognizable error */
-                        return -EBUSY;
-
-                return -errno;
-        }
+        call = (int (*)(bool b)) dlsym(dl, "_nss_systemd_block");
+        if (!call)
+                /* If the file is is installed but lacks the symbol we expect, things are weird, let's complain */
+                return log_debug_errno(SYNTHETIC_ERRNO(ELIBBAD),
+                                       "Unable to find symbol _nss_systemd_block in libnss_systemd.so.2: %s", dlerror());
 
-        return TAKE_FD(fd);
+        return call(b);
 }
index 8af31aa86c62a810b05ee7ee772baa2690de6ec9..2464f54c3e22e1dd2d79639d9d28c58e35d89293 100644 (file)
@@ -38,5 +38,4 @@ int membershipdb_all(UserDBFlags flags, UserDBIterator **ret);
 int membershipdb_iterator_get(UserDBIterator *iterator, char **user, char **group);
 int membershipdb_by_group_strv(const char *name, UserDBFlags flags, char ***ret);
 
-int userdb_nss_compat_is_enabled(void);
-int userdb_nss_compat_disable(void);
+int userdb_block_nss_systemd(int b);
index 7b548c50768d5a4e50b12477d3ccf30ffb4ebd9c..b461aead60cd9bc459e4604af001d25c24562d3d 100644 (file)
@@ -480,25 +480,21 @@ static int add_connection_socket(Context *context, int fd) {
                         log_warning_errno(r, "Unable to disable idle timer, continuing: %m");
         }
 
-        r = set_ensure_allocated(&context->connections, NULL);
-        if (r < 0) {
-                log_oom();
-                return 0;
-        }
-
-        c = new0(Connection, 1);
+        c = new(Connection, 1);
         if (!c) {
                 log_oom();
                 return 0;
         }
 
-        c->context = context;
-        c->server_fd = fd;
-        c->client_fd = -1;
-        c->server_to_client_buffer[0] = c->server_to_client_buffer[1] = -1;
-        c->client_to_server_buffer[0] = c->client_to_server_buffer[1] = -1;
+        *c = (Connection) {
+               .context = context,
+               .server_fd = fd,
+               .client_fd = -1,
+               .server_to_client_buffer = {-1, -1},
+               .client_to_server_buffer = {-1, -1},
+        };
 
-        r = set_put(context->connections, c);
+        r = set_ensure_put(&context->connections, NULL, c);
         if (r < 0) {
                 free(c);
                 log_oom();
@@ -550,12 +546,6 @@ static int add_listen_socket(Context *context, int fd) {
         assert(context);
         assert(fd >= 0);
 
-        r = set_ensure_allocated(&context->listen, NULL);
-        if (r < 0) {
-                log_oom();
-                return r;
-        }
-
         r = sd_is_socket(fd, 0, SOCK_STREAM, 1);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine socket type: %m");
@@ -571,7 +561,7 @@ static int add_listen_socket(Context *context, int fd) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add event source: %m");
 
-        r = set_put(context->listen, source);
+        r = set_ensure_put(&context->listen, NULL, source);
         if (r < 0) {
                 log_error_errno(r, "Failed to add source to set: %m");
                 sd_event_source_unref(source);
index ad7400bacc233fc49d4e84821685812a409e558e..681992b7e5508b29dc4f3102a8f83343d3790874 100644 (file)
@@ -9207,7 +9207,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_parse_environment();
+        log_parse_environment_cli();
         log_open();
 
         /* The journal merging logic potentially needs a lot of fds. */
index edb40850b160e8bd7e7a21a3404df6de00551893..42bcd74b745885b2f0875d35a65e5cf208e545d1 100644 (file)
@@ -110,10 +110,6 @@ int sd_network_link_get_network_file(int ifindex, char **filename);
  * IP addresses */
 int sd_network_link_get_dns(int ifindex, char ***ret);
 
-/* Get DHCP4 address for a given link. This is string representations of
- * IPv4 address */
-int sd_network_link_get_dhcp4_address(int ifindex, char **ret);
-
 /* Get NTP entries for a given link. These are domain names or string
  * representations of IP addresses */
 int sd_network_link_get_ntp(int ifindex, char ***ret);
@@ -173,12 +169,6 @@ int sd_network_link_get_carrier_bound_to(int ifindex, int **ifindexes);
 /* Get the CARRIERS that are bound to current link. */
 int sd_network_link_get_carrier_bound_by(int ifindex, int **ifindexes);
 
-/* Get the timezone that was learnt on a specific link. */
-int sd_network_link_get_timezone(int ifindex, char **timezone);
-
-/* Get DHCPv4 client id for a given link. */
-int sd_network_link_get_dhcp4_client_id_string(int ifindex, char **client_id);
-
 /* Get DHCPv6 client IAID for a given link. */
 int sd_network_link_get_dhcp6_client_iaid_string(int ifindex, char **iaid);
 
index 6fbd5985d365b3bb00b56502084d9c9f7ed966f9..b5e7e08eee969c34c4617b6599ff12e0ac921da2 100644 (file)
@@ -1898,7 +1898,7 @@ static int run(int argc, char *argv[]) {
 
         r = mac_selinux_init();
         if (r < 0)
-                return log_error_errno(r, "SELinux setup failed: %m");
+                return r;
 
         /* If command line arguments are specified along with --replace, read all
          * configuration files and insert the positional arguments at the specified
index eb6b2d084ef486f5097141d28d75d79ceefb383a..a2c72d1009d720b5cf6f66d3a94e5c0f0688490c 100644 (file)
@@ -817,7 +817,6 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
         _cleanup_strv_free_ char **sysvrcnd_path = NULL;
         SysvStub *service;
-        unsigned i;
         Iterator j;
         char **p;
         int r;
@@ -828,9 +827,8 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         if (r < 0)
                 return r;
 
-        STRV_FOREACH(p, sysvrcnd_path) {
-                for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
-
+        STRV_FOREACH(p, sysvrcnd_path)
+                for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
                         _cleanup_closedir_ DIR *d = NULL;
                         _cleanup_free_ char *path = NULL;
                         struct dirent *de;
@@ -885,22 +883,15 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
 
                                 service->sysv_start_priority = MAX(a*10 + b, service->sysv_start_priority);
 
-                                r = set_ensure_allocated(&runlevel_services[i], NULL);
-                                if (r < 0) {
-                                        log_oom();
-                                        goto finish;
-                                }
-
-                                r = set_put(runlevel_services[i], service);
+                                r = set_ensure_put(&runlevel_services[i], NULL, service);
                                 if (r < 0) {
                                         log_oom();
                                         goto finish;
                                 }
                         }
                 }
-        }
 
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
+        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
                 SET_FOREACH(service, runlevel_services[i], j) {
                         r = strv_extend(&service->before, rcnd_table[i].target);
                         if (r < 0) {
@@ -917,7 +908,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         r = 0;
 
 finish:
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
+        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
                 set_free(runlevel_services[i]);
 
         return r;
index 0b7dd8764f0d941e40df4c4bcc0b6d636d146932..f7b3dd5e00509b873bd0d397e43eab7211747b41 100644 (file)
@@ -84,9 +84,7 @@ static int parse_argv(int argc, char *argv[]) {
 static int run(int argc, char **argv) {
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index f2bfc6c62bc9c3f5724e725549cb2932a1bee767..d0b4ec27644710d161cacc2d85e4742944c878f2 100644 (file)
@@ -152,6 +152,10 @@ static void test_protect_kernel_logs(void) {
                                     PROTECT_HOME_NO,
                                     PROTECT_SYSTEM_NO,
                                     0,
+                                    NULL,
+                                    0,
+                                    NULL,
+                                    NULL,
                                     0,
                                     NULL);
                 assert_se(r == 0);
index cf8b08ba9be55dd5dbbf2c255514e0c622beebc7..ba2c2ed53b77b40c4431707b7136344af6d23b99 100644 (file)
@@ -76,6 +76,10 @@ int main(int argc, char *argv[]) {
                             PROTECT_HOME_NO,
                             PROTECT_SYSTEM_NO,
                             0,
+                            NULL,
+                            0,
+                            NULL,
+                            NULL,
                             0,
                             NULL);
         if (r < 0) {
index 9c93685dbce975ac1c52069a1ccfd3c6f4b5824d..d3e6de79789c685b3a4ef06914ecab3f96792dce 100644 (file)
@@ -107,6 +107,49 @@ static void test_set_put_strdupv(void) {
         assert_se(set_size(m) == 3);
 }
 
+static void test_set_ensure_allocated(void) {
+        _cleanup_set_free_ Set *m = NULL;
+
+        assert_se(set_ensure_allocated(&m, &string_hash_ops) == 1);
+        assert_se(set_ensure_allocated(&m, &string_hash_ops) == 0);
+        assert_se(set_ensure_allocated(&m, NULL) == 0);
+        assert_se(set_size(m) == 0);
+}
+
+static void test_set_ensure_put(void) {
+        _cleanup_set_free_ Set *m = NULL;
+
+        assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 1);
+        assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 0);
+        assert_se(set_ensure_put(&m, NULL, "a") == 0);
+        assert_se(set_ensure_put(&m, &string_hash_ops, "b") == 1);
+        assert_se(set_ensure_put(&m, &string_hash_ops, "b") == 0);
+        assert_se(set_ensure_put(&m, &string_hash_ops, "a") == 0);
+        assert_se(set_size(m) == 2);
+}
+
+static void test_set_ensure_consume(void) {
+        _cleanup_set_free_ Set *m = NULL;
+        char *s, *t;
+
+        assert_se(s = strdup("a"));
+        assert_se(set_ensure_consume(&m, &string_hash_ops_free, s) == 1);
+
+        assert_se(t = strdup("a"));
+        assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
+
+        assert_se(t = strdup("a"));
+        assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
+
+        assert_se(t = strdup("b"));
+        assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 1);
+
+        assert_se(t = strdup("b"));
+        assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
+
+        assert_se(set_size(m) == 2);
+}
+
 int main(int argc, const char *argv[]) {
         test_set_steal_first();
         test_set_free_with_destructor();
@@ -114,6 +157,9 @@ int main(int argc, const char *argv[]) {
         test_set_put();
         test_set_put_strdup();
         test_set_put_strdupv();
+        test_set_ensure_allocated();
+        test_set_ensure_put();
+        test_set_ensure_consume();
 
         return 0;
 }
index 3f34a91a7e1943872721d0aeaa8c9ecae2fff3b2..285eba802bb2a7f0bbe648ef1d43e6c2c5f1c946 100644 (file)
@@ -1052,9 +1052,7 @@ static int run(int argc, char *argv[]) {
         int r;
 
         setlocale(LC_ALL, "");
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index da59dd33148601b412c4cf49e7673bcdbf340909..afe593ff64564387134c41f9b58ad82de1afbd73 100644 (file)
@@ -377,7 +377,10 @@ static int context_write_data_local_rtc(Context *c) {
                 }
         }
 
-        mac_selinux_init();
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
+
         return write_string_file_atomic_label("/etc/adjtime", w);
 }
 
index e827de1b06159c20f717bf8d8a5c355c86cea9e2..7ad6f13b66b58b95d07a46f9c5bd00ee3fa17925 100644 (file)
@@ -3196,11 +3196,7 @@ static int link_parent(ItemArray *a) {
                 if (!j)
                         j = ordered_hashmap_get(globs, prefix);
                 if (j) {
-                        r = set_ensure_allocated(&j->children, NULL);
-                        if (r < 0)
-                                return log_oom();
-
-                        r = set_put(j->children, a);
+                        r = set_ensure_put(&j->children, NULL, a);
                         if (r < 0)
                                 return log_oom();
 
@@ -3262,7 +3258,9 @@ static int run(int argc, char *argv[]) {
 
         umask(0022);
 
-        mac_selinux_init();
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
 
         items = ordered_hashmap_new(&item_array_hash_ops);
         globs = ordered_hashmap_new(&item_array_hash_ops);
index 2ca98a729f01541486e43cc3304cce3e897734d4..8cd8ed1a1ee6c2e052eb29530eda25446552d7aa 100644 (file)
@@ -169,24 +169,13 @@ static int parse_argv(int argc, char *argv[]) {
                         subsystem = devtype = NULL;
                         break;
                 }
-                case 't': {
-                        _cleanup_free_ char *tag = NULL;
-
-                        r = set_ensure_allocated(&arg_tag_filter, &string_hash_ops);
+                case 't':
+                        /* optarg is stored in argv[], so we don't need to copy it */
+                        r = set_ensure_put(&arg_tag_filter, &string_hash_ops, optarg);
                         if (r < 0)
                                 return r;
-
-                        tag = strdup(optarg);
-                        if (!tag)
-                                return -ENOMEM;
-
-                        r = set_put(arg_tag_filter, tag);
-                        if (r < 0)
-                                return r;
-
-                        tag = NULL;
                         break;
-                }
+
                 case 'V':
                         return print_version();
                 case 'h':
@@ -260,7 +249,7 @@ int monitor_main(int argc, char *argv[], void *userdata) {
 
 finalize:
         hashmap_free_free_free(arg_subsystem_filter);
-        set_free_free(arg_tag_filter);
+        set_free(arg_tag_filter);
 
         return r;
 }
index f1115bff7a3ebe3c09ad6e677a27e0bad444972c..e476f88f00812db5a3abc907493291683c737a0a 100644 (file)
@@ -124,7 +124,10 @@ static int run(int argc, char *argv[]) {
 
         log_set_max_level_realm(LOG_REALM_SYSTEMD, log_get_max_level());
 
-        mac_selinux_init();
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
+
         return udevadm_main(argc, argv);
 }
 
index d86c1484c3e925f1b80c4c45c2cf5c092b1fbc99..8db19e4f89ca80a60dba6a0eea0916e86b61f640 100644 (file)
@@ -1863,7 +1863,7 @@ int run_udevd(int argc, char *argv[]) {
 
         r = mac_selinux_init();
         if (r < 0)
-                return log_error_errno(r, "Could not initialize labelling: %m");
+                return r;
 
         r = mkdir_errno_wrapper("/run/udev", 0755);
         if (r < 0 && r != -EEXIST)
index bbd14165d5ad4b4199c5a554911bffdb81b58e9f..c001802dc910b93eb347ef51f39b7917ecf6559d 100644 (file)
@@ -49,10 +49,8 @@ int main(int argc, char *argv[]) {
         }
 
         r = mac_selinux_init();
-        if (r < 0) {
-                log_error_errno(r, "SELinux setup failed: %m");
+        if (r < 0)
                 return EXIT_FAILURE;
-        }
 
         r = apply_timestamp("/etc/.updated", &st.st_mtim);
         q = apply_timestamp("/var/.updated", &st.st_mtim);
index c24142951709eadd0e59606c03655f1f663a8f02..cd92b696c0c20733599deea4c37ecce3fa587f52 100644 (file)
@@ -25,7 +25,9 @@ static int run(int argc, char *argv[]) {
 
         umask(0022);
 
-        mac_selinux_init();
+        r = mac_selinux_init();
+        if (r < 0)
+                return r;
 
         if (streq(argv[1], "start")) {
                 r = unlink_or_warn("/run/nologin");
index 4b5eb34ca6225d7a2473bae1029ce217f745e59b..648eacd02341ca122177242ae8bfe333bd1f3469 100644 (file)
@@ -761,9 +761,7 @@ static int run(int argc, char *argv[]) {
 
         int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup_cli();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
index 732063f6c72e4230555790af3fd6f78312725bfc..d7202099be29071fca360e3a9ff5dc04475350a1 100644 (file)
@@ -660,7 +660,6 @@ static int process_connection(VarlinkServer *server, int fd) {
 static int run(int argc, char *argv[]) {
         usec_t start_time, listen_idle_usec, last_busy_usec = USEC_INFINITY;
         _cleanup_(varlink_server_unrefp) VarlinkServer *server = NULL;
-        _cleanup_close_ int lock = -1;
         unsigned n_iterations = 0;
         int m, listen_fd, r;
 
@@ -697,8 +696,8 @@ static int run(int argc, char *argv[]) {
                 return log_error_errno(r, "Failed to parse USERDB_FIXED_WORKER: %m");
         listen_idle_usec = r ? USEC_INFINITY : LISTEN_IDLE_USEC;
 
-        lock = userdb_nss_compat_disable();
-        if (lock < 0)
+        r = userdb_block_nss_systemd(true);
+        if (r < 0)
                 return log_error_errno(r, "Failed to disable userdb NSS compatibility: %m");
 
         start_time = now(CLOCK_MONOTONIC);
index 6d10d7052b5b7c88477450b0be4167138ac86bcd..0d33c70401244ade9abe49fa6ccc1567fad5b0bb 100644 (file)
@@ -496,7 +496,7 @@ int xdg_autostart_service_generate_unit(
 
         /* Nothing to do if type is not Application. */
         if (!streq_ptr(service->type, "Application")) {
-                log_info("Not generating service for XDG autostart %s, it is hidden.", service->name);
+                log_info("Not generating service for XDG autostart %s, only Type=Application is supported.", service->name);
                 return 0;
         }
 
@@ -527,8 +527,9 @@ int xdg_autostart_service_generate_unit(
                 return 0;
         }
 
-        if (streq_ptr(service->gnome_autostart_phase, "EarlyInitialization")) {
-                log_info("Not generating service for XDG autostart %s, EarlyInitialization needs to be handled separately.",
+        if (service->gnome_autostart_phase) {
+                /* There is no explicit value for the "Application" phase. */
+                log_info("Not generating service for XDG autostart %s, startup phases are not supported.",
                          service->name);
                 return 0;
         }
@@ -563,10 +564,7 @@ int xdg_autostart_service_generate_unit(
                 fprintf(f, "Description=%s\n", t);
         }
 
-        /* Only start after the session is ready.
-         * XXX: GNOME has an autostart order which we may want to support.
-         *      It is not clear how this can be implemented reliably, which
-         *      is why it is skipped for now. */
+        /* Only start after the session is ready. */
         fprintf(f,
                 "After=graphical-session.target\n");
 
index 527db85b072a9e6e0c242bf8a685d573e1fa58b1..2992beaa0b88213775bce9618860d3d7be42e132 100755 (executable)
@@ -115,9 +115,7 @@ test_run() {
         echo "*** Running test $f"
         prepare_testdir ${f%.input}
         cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
-        systemd-sysusers --root=$TESTDIR 2> /dev/null
-        journalctl --sync
-        journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err
+        systemd-sysusers --root=$TESTDIR 2>&1 | tail -n1 > $TESTDIR/tmp/err
         if ! diff -u $TESTDIR/tmp/err  ${f%.*}.expected-err; then
             echo "**** Unexpected error output for $f"
             cat $TESTDIR/tmp/err
diff --git a/test/TEST-52-HONORFIRSTSHUTDOWN/Makefile b/test/TEST-52-HONORFIRSTSHUTDOWN/Makefile
new file mode 100644 (file)
index 0000000..a48af97
--- /dev/null
@@ -0,0 +1,16 @@
+BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
+
+all setup run clean clean-again:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
+
+# finish option is used to run checks that can only be run outside of
+# the test execution. Example case, honor first shutdown, proof is obtained
+# from the console output as the image shuts down. This does not show up in
+# the journal so the output from the do_test is captured in a file in /tmp.
+# Without the use of finish the test will still pass because if it fails
+# the test will loop and will be terminated via a command timeout.
+# This just provides concrete confirmation.
+finish:
+       @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./fini.sh --$@
+
+.PHONY: all setup run clean clean-again
diff --git a/test/TEST-52-HONORFIRSTSHUTDOWN/fini.sh b/test/TEST-52-HONORFIRSTSHUTDOWN/fini.sh
new file mode 100755 (executable)
index 0000000..993ada0
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash
+TEST_DESCRIPTION="test honor first shutdown"
+
+if grep -q "Shutdown is already active. Skipping emergency action request" /tmp/honorfirstshutdown.log; then
+    echo "$TEST_DESCRIPTION [pass]"
+    exit 0
+else
+    echo "$TEST_DESCRIPTION [fail]"
+    exit 1
+fi
diff --git a/test/TEST-52-HONORFIRSTSHUTDOWN/test.sh b/test/TEST-52-HONORFIRSTSHUTDOWN/test.sh
new file mode 100755 (executable)
index 0000000..a0848ef
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+set -e
+. $TEST_BASE_DIR/test-functions
+TEST_REQUIRE_INSTALL_TESTS=0
+TEST_DESCRIPTION="testing honor first shutdown"
+#INTERACTIVE_DEBUG=1
+TEST_NO_QEMU=1
+
+#Using timeout because if the test fails it can loop.
+# The reason is because the poweroff executed by end.service
+# could turn into a reboot if the test fails.
+NSPAWN_TIMEOUT=20
+
+#Remove this file if it exists. this is used along with
+# the make target "finish". Since concrete confirmaion is
+# only found from the console during the poweroff.
+rm -f /tmp/honorfirstshutdown.log >/dev/null
+
+do_test "$@" 52 > /tmp/honorfirstshutdown.log
diff --git a/test/fuzz/fuzz-bus-message/zero-offset-to-null-pointer b/test/fuzz/fuzz-bus-message/zero-offset-to-null-pointer
new file mode 100644 (file)
index 0000000..c138044
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/zero-offset-to-null-pointer differ
diff --git a/test/fuzz/fuzz-netdev-parser/wireguard-duplicated-endpoint b/test/fuzz/fuzz-netdev-parser/wireguard-duplicated-endpoint
new file mode 100644 (file)
index 0000000..adff4c1
--- /dev/null
@@ -0,0 +1,6 @@
+[NetDev]
+Name=w
+Kind=wireguard
+[WireGuardPeer]
+Endpoint=:0
+Endpoint=:8
\ No newline at end of file
diff --git a/test/fuzz/fuzz-network-parser/dns-trust-anchor-duplicate.network b/test/fuzz/fuzz-network-parser/dns-trust-anchor-duplicate.network
new file mode 100644 (file)
index 0000000..ed7bdab
--- /dev/null
@@ -0,0 +1,2 @@
+[Network]
+DNSSECNegativeTrustAnchors=i i
\ No newline at end of file
index 7435d7abec0ee1ba7ae406ec3da6f5fbb6f65c8a..492d2a033bb3d078cddb92ea065649b0969372a4 100644 (file)
@@ -196,6 +196,8 @@ ReusePort=
 RootDirectory=
 RootDirectoryStartOnly=
 RootImage=
+RootHash=
+RootVerity=
 RuntimeMaxSec=
 SELinuxContextFromNet=
 SecureBits=
index 404b923467058569d2b9e1e946d1a5fadac9f04f..8bda38a2e27d1b169dfa9397ed443c34d1d9afcb 100644 (file)
@@ -28,6 +28,8 @@ install_subdir('testsuite-28.units',
                install_dir : testdata_dir)
 install_subdir('testsuite-30.units',
                install_dir : testdata_dir)
+install_subdir('testsuite-52.units',
+               install_dir : testdata_dir)
 
 testsuite08_dir = testdata_dir + '/testsuite-08.units'
 install_data('testsuite-08.units/-.mount',
index df87261ea2f32eef1e176490e93c23502e3ff252..f7f604aec3abe87386146626097e76d56e57cf3a 100644 (file)
@@ -935,7 +935,7 @@ install_config_files() {
     inst /etc/login.defs
     inst /etc/group
     inst /etc/shells
-    inst /etc/nsswitch.conf
+    inst_any /etc/nsswitch.conf /usr/etc/nsswitch.conf
     inst /etc/pam.conf || :
     inst /etc/os-release
     inst /etc/localtime
diff --git a/test/testsuite-52.units/testsuite-52.service b/test/testsuite-52.units/testsuite-52.service
new file mode 100755 (executable)
index 0000000..93f847f
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/usr/lib/systemd/tests/testdata/%N.units/%N.sh
+Type=oneshot
diff --git a/test/testsuite-52.units/testsuite-52.sh b/test/testsuite-52.units/testsuite-52.sh
new file mode 100755 (executable)
index 0000000..9cccf1b
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -ex
+set -o pipefail
+
+if ! test -x /usr/lib/systemd/tests/testdata/units/test-honor-first-shutdown.sh ; then
+        echo "honor-first-shutdown script not found - FAIL" > /testok
+        exit 0
+fi
+
+systemd-analyze log-level debug
+systemd-analyze log-target console
+
+systemctl enable test-honor-first-shutdown.service
+systemctl start test-honor-first-shutdown.service
+
+echo OK > /testok
+
+exit 0
diff --git a/test/units/test-honor-first-shutdown.service b/test/units/test-honor-first-shutdown.service
new file mode 100644 (file)
index 0000000..374f1e6
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Honor First Shutdown feature
+After=multi-user.target
+
+[Service]
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+ExecStop=sh -c 'kill -SIGKILL $MAINPID'
+FailureAction=reboot
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/test/units/test-honor-first-shutdown.sh b/test/units/test-honor-first-shutdown.sh
new file mode 100755 (executable)
index 0000000..17c1ec9
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/bash
+echo "Honor first shutdown test script"
+sleep infinity;
index 25b261ea0d4a09b0e78543b404089b693211c31b..e13ca33f6fc5fcb2cff17aa6d872085717b8c387 100755 (executable)
@@ -1,14 +1,24 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: LGPL-2.1+
 
-# Generate autosuspend rules for devices that have been whitelisted (IE tested)
-# by the Chromium OS team. Please keep this script in sync with:
+# Generate autosuspend rules for devices that have been tested to work properly
+# with autosuspend by the Chromium OS team. Based on
 # https://chromium.googlesource.com/chromiumos/platform2/+/master/power_manager/udev/gen_autosuspend_rules.py
 
-import sys
 import chromiumos.gen_autosuspend_rules
 
-if __name__ == '__main__':
-    if len(sys.argv) > 1:
-        sys.stdout = open(sys.argv[1], 'w')
-    chromiumos.gen_autosuspend_rules.main()
+print('# pci:v<00VENDOR>d<00DEVICE> (8 uppercase hexadecimal digits twice)')
+for entry in chromiumos.gen_autosuspend_rules.PCI_IDS:
+    vendor, device = entry.split(':')
+    vendor = int(vendor, 16)
+    device = int(device, 16)
+    print('pci:v{:08X}d{:08X}*'.format(vendor, device))
+
+print('# usb:v<VEND>p<PROD> (4 uppercase hexadecimal digits twice')
+for entry in chromiumos.gen_autosuspend_rules.USB_IDS:
+    vendor, product = entry.split(':')
+    vendor = int(vendor, 16)
+    product = int(product, 16)
+    print('usb:v{:04X}p{:04X}*'.format(vendor, product))
+
+print(' ID_AUTOSUSPEND=1')
index 60f6237606f6269d8edc7bdb3254ae6ab731820a..a2a987d8fd407fa2cfa56b9ef8b54bfe50252bb4 100755 (executable)
@@ -9,23 +9,25 @@
 # export CONT_NAME="my-fancy-container"
 # travis-ci/managers/debian.sh SETUP RUN CLEANUP
 
-PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
+PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP})
 DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}"
-CONT_NAME="${CONT_NAME:-debian-$DEBIAN_RELEASE-$RANDOM}"
+CONT_NAME="${CONT_NAME:-systemd-debian-$DEBIAN_RELEASE}"
 DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
 DOCKER_RUN="${DOCKER_RUN:-docker run}"
 REPO_ROOT="${REPO_ROOT:-$PWD}"
-ADDITIONAL_DEPS=(python3-libevdev
-                 python3-pyparsing
-                 clang
-                 perl
-                 libpwquality-dev
-                 fdisk
-                 libfdisk-dev
-                 libp11-kit-dev
-                 libssl-dev
-                 libzstd-dev
-                 zstd)
+ADDITIONAL_DEPS=(
+    clang
+    fdisk
+    libfdisk-dev
+    libp11-kit-dev
+    libpwquality-dev
+    libssl-dev
+    libzstd-dev
+    perl
+    python3-libevdev
+    python3-pyparsing
+    zstd
+)
 
 function info() {
     echo -e "\033[33;1m$1\033[0m"
@@ -54,7 +56,7 @@ for phase in "${PHASES[@]}"; do
             $DOCKER_EXEC apt-get -y build-dep systemd
             $DOCKER_EXEC apt-get -y install "${ADDITIONAL_DEPS[@]}"
             ;;
-        RUN|RUN_CLANG)
+        RUN|RUN_GCC|RUN_CLANG)
             if [[ "$phase" = "RUN_CLANG" ]]; then
                 ENV_VARS="-e CC=clang -e CXX=clang++"
             fi
@@ -62,8 +64,8 @@ for phase in "${PHASES[@]}"; do
             $DOCKER_EXEC ninja -v -C build
             docker exec -e "TRAVIS=$TRAVIS" -it $CONT_NAME ninja -C build test
             ;;
-        RUN_ASAN|RUN_CLANG_ASAN)
-            if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
+        RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN)
+            if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then
                 ENV_VARS="-e CC=clang -e CXX=clang++"
                 # Build fuzzer regression tests only with clang (for now),
                 # see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604
index b3c85ebd09276c3aa9cd98d91b51008519a39d59..cc665021d4b6bd79d1a7f8836c6021cdf6d64db9 100755 (executable)
@@ -9,38 +9,32 @@
 # export CONT_NAME="my-fancy-container"
 # travis-ci/managers/fedora.sh SETUP RUN CLEANUP
 
-PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
+PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP})
 FEDORA_RELEASE="${FEDORA_RELEASE:-rawhide}"
-CONT_NAME="${CONT_NAME:-fedora-$FEDORA_RELEASE-$RANDOM}"
+CONT_NAME="${CONT_NAME:-systemd-fedora-$FEDORA_RELEASE}"
 DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
 DOCKER_RUN="${DOCKER_RUN:-docker run}"
 REPO_ROOT="${REPO_ROOT:-$PWD}"
-ADDITIONAL_DEPS=(dnf-plugins-core
-                 jq iputils
-                 hostname libasan
-                 python3-pyparsing
-                 python3-evdev
-                 libubsan
-                 clang
-                 llvm
-                 perl
-                 libfdisk-devel
-                 libpwquality-devel
-                 openssl-devel
-                 p11-kit-devel)
+ADDITIONAL_DEPS=(
+    clang
+    dnf-plugins-core
+    hostname libasan
+    jq iputils
+    libfdisk-devel
+    libpwquality-devel
+    libubsan
+    llvm
+    openssl-devel
+    p11-kit-devel
+    perl
+    python3-evdev
+    python3-pyparsing
+)
 
 info() {
     echo -e "\033[33;1m$1\033[0m"
 }
 
-error() {
-    echo >&2 -e "\033[31;1m$1\033[0m"
-}
-
-success() {
-    echo >&2 -e "\033[32;1m$1\033[0m"
-}
-
 # Simple wrapper which retries given command up to five times
 _retry() {
     local EC=1
@@ -94,8 +88,8 @@ for phase in "${PHASES[@]}"; do
             $DOCKER_EXEC ninja -v -C build
             $DOCKER_EXEC ninja -C build test
             ;;
-        RUN_ASAN|RUN_CLANG_ASAN)
-            if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
+        RUN_ASAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN)
+            if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then
                 ENV_VARS="-e CC=clang -e CXX=clang++"
                 MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
             fi
@@ -110,46 +104,6 @@ for phase in "${PHASES[@]}"; do
                 -t $CONT_NAME \
                 meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
             ;;
-        RUN_BUILD_CHECK_GCC|RUN_BUILD_CHECK_CLANG)
-            ARGS=(
-                "--optimization=0"
-                "--optimization=2"
-                "--optimization=3"
-                "--optimization=s"
-                "-Db_lto=true"
-                "-Db_ndebug=true"
-            )
-
-            if [[ "$phase" = "RUN_BUILD_CHECK_CLANG" ]]; then
-                ENV_VARS="-e CC=clang -e CXX=clang++"
-                $DOCKER_EXEC clang --version
-            else
-                $DOCKER_EXEC gcc --version
-            fi
-
-            for args in "${ARGS[@]}"; do
-                SECONDS=0
-                info "Checking build with $args"
-                # Redirect meson/ninja logs into separate files, otherwise we
-                # would trip over Travis' log size limit
-                if ! docker exec $ENV_VARS -it $CONT_NAME meson --werror $args build &> meson.log; then
-                    cat meson.log
-                    error "meson failed with $args"
-                    exit 1
-                fi
-
-                if ! $DOCKER_EXEC ninja -v -C build &> ninja.log; then
-                    cat ninja.log
-                    error "ninja failed with $args"
-                    exit 1
-                fi
-
-                $DOCKER_EXEC rm -fr build
-                rm -f meson.log ninja.log
-                success "Build with $args passed in $SECONDS seconds"
-            done
-
-            ;;
         CLEANUP)
             info "Cleanup phase"
             docker stop $CONT_NAME