From 7a99d80faaedc34baf75c864278c2871f735cfc2 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Aug 24 2021 12:51:54 +0000 Subject: Version 249.4 --- diff --git a/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch b/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch new file mode 100644 index 0000000..f7b3a61 --- /dev/null +++ b/0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch @@ -0,0 +1,257 @@ +From d4bd8777a483ea834e687c1ee35dee32efe6e49f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Jul 2021 14:02:36 +0200 +Subject: [PATCH 1/5] rpm: don't specify the full path for systemctl and other + commands + +We can make things a bit simpler and more readable by not specifying the path. +Since we didn't specify the full path for all commands (including those invoked +recursively by anythign we invoke), this didn't really privide any security or +robustness benefits. I guess that full paths were used because this style of +rpm packagnig was popular in the past, with macros used for everything +possible, with special macros for common commands like %{__ln} and %{__mkdir}. + +(cherry picked from commit 7d9ee15d0fc2af87481ee371b278dbe7e68165ef) +--- + src/rpm/macros.systemd.in | 24 ++++++++++++------------ + src/rpm/triggers.systemd.in | 18 +++++++++--------- + src/rpm/triggers.systemd.sh.in | 18 +++++++++--------- + 3 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in +index 3a0169a85f..3129ab2d61 100644 +--- a/src/rpm/macros.systemd.in ++++ b/src/rpm/macros.systemd.in +@@ -46,9 +46,9 @@ OrderWithRequires(postun): systemd \ + + %systemd_post() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \ +-if [ $1 -eq 1 ] && [ -x %{_bindir}/systemctl ]; then \ ++if [ $1 -eq 1 ] && command -v systemctl >/dev/null; then \ + # Initial installation \ +- %{_bindir}/systemctl --no-reload preset %{?*} || : \ ++ systemctl --no-reload preset %{?*} || : \ + fi \ + %{nil} + +@@ -56,21 +56,21 @@ fi \ + + %systemd_preun() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \ +-if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \ ++if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \ + # Package removal, not upgrade \ + if [ -d /run/systemd/system ]; then \ +- %{_bindir}/systemctl --no-reload disable --now %{?*} || : \ ++ systemctl --no-reload disable --now %{?*} || : \ + else \ +- %{_bindir}/systemctl --no-reload disable %{?*} || : \ ++ systemctl --no-reload disable %{?*} || : \ + fi \ + fi \ + %{nil} + + %systemd_user_preun() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \ +-if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \ ++if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \ + # Package removal, not upgrade \ +- %{_bindir}/systemctl --global disable %{?*} || : \ ++ systemctl --global disable %{?*} || : \ + fi \ + %{nil} + +@@ -84,10 +84,10 @@ fi \ + + %systemd_postun_with_restart() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \ +-if [ $1 -ge 1 ] && [ -x %{_bindir}/systemctl ]; then \ ++if [ $1 -ge 1 ] && command -v systemctl >/dev/null; then \ + # Package upgrade, not uninstall \ + for unit in %{?*}; do \ +- %{_bindir}/systemctl set-property $unit Markers=+needs-restart || : \ ++ systemctl set-property $unit Markers=+needs-restart || : \ + done \ + fi \ + %{nil} +@@ -105,17 +105,17 @@ fi \ + # Deprecated. Use %tmpfiles_create_package instead + %tmpfiles_create() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# tmpfiles_create}} \ +-[ -x %{_bindir}/systemd-tmpfiles ] && %{_bindir}/systemd-tmpfiles --create %{?*} || : \ ++command -v systemd-tmpfiles >/dev/null && systemd-tmpfiles --create %{?*} || : \ + %{nil} + + # Deprecated. Use %sysusers_create_package instead + %sysusers_create() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# sysusers_create}} \ +-[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers %{?*} || : \ ++command -v systemd-sysusers >/dev/null && systemd-sysusers %{?*} || : \ + %{nil} + + %sysusers_create_inline() \ +-[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers - </dev/null && systemd-sysusers - < 0 then + posix.wait(pid) + end + + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked")) ++ assert(posix.execp("systemctl", "reload-or-restart", "--marked")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -38,7 +38,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemctl", "daemon-reload")) ++ assert(posix.execp("systemctl", "daemon-reload")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -49,7 +49,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked")) ++ assert(posix.execp("systemctl", "reload-or-restart", "--marked")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -62,7 +62,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemd-sysusers")) ++ assert(posix.execp("systemd-sysusers")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -74,7 +74,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemd-hwdb", "update")) ++ assert(posix.execp("systemd-hwdb", "update")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -86,7 +86,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/journalctl", "--update-catalog")) ++ assert(posix.execp("journalctl", "--update-catalog")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -111,7 +111,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/systemd-tmpfiles", "--create")) ++ assert(posix.execp("systemd-tmpfiles", "--create")) + elseif pid > 0 then + posix.wait(pid) + end +@@ -123,7 +123,7 @@ end + if posix.access("/run/systemd/system") then + pid = posix.fork() + if pid == 0 then +- assert(posix.exec("%{_bindir}/udevadm", "control", "--reload")) ++ assert(posix.execp("udevadm", "control", "--reload")) + elseif pid > 0 then + posix.wait(pid) + end +diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in +index 22abad9812..1631be18c9 100644 +--- a/src/rpm/triggers.systemd.sh.in ++++ b/src/rpm/triggers.systemd.sh.in +@@ -15,8 +15,8 @@ + # installed, because other cases are covered by the *un scriptlets, + # so sometimes we will reload needlessly. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemctl daemon-reload || : +- %{_bindir}/systemctl reload-or-restart --marked || : ++ systemctl daemon-reload || : ++ systemctl reload-or-restart --marked || : + fi + + %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +@@ -26,13 +26,13 @@ fi + # have been installed, but before %postun scripts in packages get + # executed. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemctl daemon-reload || : ++ systemctl daemon-reload || : + fi + + %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + # We restart remaining services that should be restarted here. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemctl reload-or-restart --marked || : ++ systemctl reload-or-restart --marked || : + fi + + %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}} +@@ -40,21 +40,21 @@ fi + # specified users automatically. The priority is set such that it + # will run before the tmpfiles file trigger. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemd-sysusers || : ++ systemd-sysusers || : + fi + + %transfiletriggerin -P 1000700 udev -- {{UDEV_HWDB_DIR}} + # This script will automatically invoke hwdb update if files have been + # installed or updated in {{UDEV_HWDB_DIR}}. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemd-hwdb update || : ++ systemd-hwdb update || : + fi + + %transfiletriggerin -P 1000700 -- {{SYSTEMD_CATALOG_DIR}} + # This script will automatically invoke journal catalog update if files + # have been installed or updated in {{SYSTEMD_CATALOG_DIR}}. + if test -d "/run/systemd/system"; then +- %{_bindir}/journalctl --update-catalog || : ++ journalctl --update-catalog || : + fi + + %transfiletriggerin -P 1000700 -- {{BINFMT_DIR}} +@@ -71,14 +71,14 @@ fi + # tmpfiles automatically. The priority is set such that it will run + # after the sysusers file trigger, but before any other triggers. + if test -d "/run/systemd/system"; then +- %{_bindir}/systemd-tmpfiles --create || : ++ systemd-tmpfiles --create || : + fi + + %transfiletriggerin -P 1000600 udev -- {{UDEV_RULES_DIR}} + # This script will automatically update udev with new rules if files + # have been installed or updated in {{UDEV_RULES_DIR}}. + if test -e /run/udev/control; then +- %{_bindir}/udevadm control --reload || : ++ udevadm control --reload || : + fi + + %transfiletriggerin -P 1000500 -- {{SYSCTL_DIR}} +-- +2.31.1 + diff --git a/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch b/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch new file mode 100644 index 0000000..32047c5 --- /dev/null +++ b/0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch @@ -0,0 +1,337 @@ +From 09e8c6aa71ee4b5ff3ee85fc4855e2c1a246a079 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 22 Jul 2021 11:22:33 +0200 +Subject: [PATCH 2/5] rpm: use a helper script to actually invoke systemctl + commands +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Instead of embedding the commands to invoke directly in the macros, +let's use a helper script as indirection. This has a couple of advantages: + +- the macro language is awkward, we need to suffix most commands by "|| :" + and "\", which is easy to get wrong. In the new scheme, the macro becomes + a single simple command. +- in the script we can use normal syntax highlighting, shellcheck, etc. +- it's also easier to test the invoked commands by invoking the helper + manually. +- most importantly, the logic is contained in the helper, i.e. we can + update systemd rpm and everything uses the new helper. Before, we would + have to rebuild all packages to update the macro definition. + +This raises the question whether it makes sense to use the lua scriptlets when +the real work is done in a bash script. I think it's OK: we still have the +efficient lua scripts that do the short scripts, and we use a single shared +implementation in bash to do the more complex stuff. + +The meson version is raised to 0.47 because that's needed for install_mode. +We were planning to raise the required version anyway… + +(cherry picked from commit 6d825ab2d42d3219e49a192bf99f9c09134a0df4) +--- + README | 2 +- + meson.build | 3 +- + src/rpm/macros.systemd.in | 30 ++++++++-------- + src/rpm/meson.build | 13 ++++--- + src/rpm/systemd-update-helper.in | 60 ++++++++++++++++++++++++++++++++ + src/rpm/triggers.systemd.in | 43 ++++++++--------------- + src/rpm/triggers.systemd.sh.in | 13 ++----- + 7 files changed, 105 insertions(+), 59 deletions(-) + create mode 100755 src/rpm/systemd-update-helper.in + +diff --git a/README b/README +index 0e5c326deb..a8f23a0d5b 100644 +--- a/README ++++ b/README +@@ -193,7 +193,7 @@ REQUIREMENTS: + python-jinja2 + python-lxml (optional, required to build the indices) + python >= 3.5 +- meson >= 0.46 (>= 0.49 is required to build position-independent executables) ++ meson >= 0.47 (>= 0.49 is required to build position-independent executables) + ninja + gcc, awk, sed, grep, and similar tools + clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs +diff --git a/meson.build b/meson.build +index 738879eb21..fb986e84f7 100644 +--- a/meson.build ++++ b/meson.build +@@ -10,7 +10,7 @@ project('systemd', 'c', + 'localstatedir=/var', + 'warning_level=2', + ], +- meson_version : '>= 0.46', ++ meson_version : '>= 0.47', + ) + + libsystemd_version = '0.32.0' +@@ -253,6 +253,7 @@ conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', join_paths(rootlib + conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH', join_paths(bindir, 'systemd-stdio-bridge')) + conf.set_quoted('SYSTEMD_TEST_DATA', join_paths(testsdir, 'testdata')) + conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent')) ++conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH', join_paths(rootlibexecdir, 'systemd-update-helper')) + conf.set_quoted('SYSTEMD_USERWORK_PATH', join_paths(rootlibexecdir, 'systemd-userwork')) + conf.set_quoted('SYSTEMD_VERITYSETUP_PATH', join_paths(rootlibexecdir, 'systemd-veritysetup')) + conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR', join_paths(pkgsysconfdir, 'system')) +diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in +index 3129ab2d61..bbdf036da7 100644 +--- a/src/rpm/macros.systemd.in ++++ b/src/rpm/macros.systemd.in +@@ -46,31 +46,33 @@ OrderWithRequires(postun): systemd \ + + %systemd_post() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \ +-if [ $1 -eq 1 ] && command -v systemctl >/dev/null; then \ ++if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Initial installation \ +- systemctl --no-reload preset %{?*} || : \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} install-system-units %{?*} || : \ + fi \ + %{nil} + +-%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}} ++%systemd_user_post() \ ++%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_post}} \ ++if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ ++ # Initial installation \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} install-user-units %{?*} || : \ ++fi \ ++%{nil} + + %systemd_preun() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \ +-if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \ ++if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package removal, not upgrade \ +- if [ -d /run/systemd/system ]; then \ +- systemctl --no-reload disable --now %{?*} || : \ +- else \ +- systemctl --no-reload disable %{?*} || : \ +- fi \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} remove-system-units %{?*} || : \ + fi \ + %{nil} + + %systemd_user_preun() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \ +-if [ $1 -eq 0 ] && command -v systemctl >/dev/null; then \ ++if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package removal, not upgrade \ +- systemctl --global disable %{?*} || : \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \ + fi \ + %{nil} + +@@ -84,11 +86,9 @@ fi \ + + %systemd_postun_with_restart() \ + %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \ +-if [ $1 -ge 1 ] && command -v systemctl >/dev/null; then \ ++if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ + # Package upgrade, not uninstall \ +- for unit in %{?*}; do \ +- systemctl set-property $unit Markers=+needs-restart || : \ +- done \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \ + fi \ + %{nil} + +diff --git a/src/rpm/meson.build b/src/rpm/meson.build +index fc72fee73c..2ad3308cc1 100644 +--- a/src/rpm/meson.build ++++ b/src/rpm/meson.build +@@ -1,9 +1,13 @@ + # SPDX-License-Identifier: LGPL-2.1-or-later + + in_files = [ +- ['macros.systemd', rpmmacrosdir != 'no'], +- ['triggers.systemd', false], +- ['triggers.systemd.sh', false]] ++ ['macros.systemd', rpmmacrosdir != 'no', rpmmacrosdir], ++ ++ # we conditionalize on rpmmacrosdir, but install into rootlibexecdir ++ ['systemd-update-helper', rpmmacrosdir != 'no', rootlibexecdir, 'rwxr-xr-x'], ++ ++ ['triggers.systemd', false], ++ ['triggers.systemd.sh', false]] + + # The last two don't get installed anywhere, one of them needs to included in + # the rpm spec file definition instead. +@@ -17,6 +21,7 @@ foreach tuple : in_files + command : [meson_render_jinja2, config_h, '@INPUT@'], + capture : true, + install : tuple[1], +- install_dir : rpmmacrosdir, ++ install_dir : tuple.length() > 2 ? tuple[2] : '', ++ install_mode : tuple.length() > 3 ? tuple[3] : false, + build_by_default : true) + endforeach +diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in +new file mode 100755 +index 0000000000..9fa49fa131 +--- /dev/null ++++ b/src/rpm/systemd-update-helper.in +@@ -0,0 +1,60 @@ ++#!/bin/bash ++set -eu ++set -o pipefail ++ ++command="${1:?}" ++shift ++ ++command -v systemctl >/dev/null || exit 0 ++ ++case "$command" in ++ install-system-units) ++ systemctl --no-reload preset "$@" ++ ;; ++ ++ install-user-units) ++ systemctl --no-reload preset --global "$@" ++ ;; ++ ++ remove-system-units) ++ if [ -d /run/systemd/system ]; then ++ systemctl --no-reload disable --now "$@" ++ else ++ systemctl --no-reload disable "$@" ++ fi ++ ;; ++ ++ remove-user-units) ++ systemctl --global disable "$@" ++ ;; ++ ++ mark-restart-system-units) ++ [ -d /run/systemd/system ] || exit 0 ++ ++ for unit in "$@"; do ++ systemctl set-property "$unit" Markers=+needs-restart || : ++ done ++ ;; ++ ++ system-reload-restart|system-reload|system-restart) ++ if [ -n "$*" ]; then ++ echo "Unexpected arguments for '$command': $*" ++ exit 2 ++ fi ++ ++ [ -d /run/systemd/system ] || exit 0 ++ ++ if [[ "$command" =~ reload ]]; then ++ systemctl daemon-reload ++ fi ++ ++ if [[ "$command" =~ restart ]]; then ++ systemctl reload-or-restart --marked ++ fi ++ ;; ++ ++ *) ++ echo "Unknown verb '$command'" ++ exit 3 ++ ;; ++esac +diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in +index 247358008a..d29cc33dfd 100644 +--- a/src/rpm/triggers.systemd.in ++++ b/src/rpm/triggers.systemd.in +@@ -13,20 +13,11 @@ + -- upgraded. We care about the case where a package is initially + -- installed, because other cases are covered by the *un scriptlets, + -- so sometimes we will reload needlessly. +-if posix.access("/run/systemd/system") then +- pid = posix.fork() +- if pid == 0 then +- assert(posix.execp("systemctl", "daemon-reload")) +- elseif pid > 0 then +- posix.wait(pid) +- end +- +- pid = posix.fork() +- if pid == 0 then +- assert(posix.execp("systemctl", "reload-or-restart", "--marked")) +- elseif pid > 0 then +- posix.wait(pid) +- end ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload-restart")) ++elseif pid > 0 then ++ posix.wait(pid) + end + + %transfiletriggerpostun -P 1000100 -p -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +@@ -35,24 +26,20 @@ end + -- On upgrade, we need to run daemon-reload after any new unit files + -- have been installed, but before %postun scripts in packages get + -- executed. +-if posix.access("/run/systemd/system") then +- pid = posix.fork() +- if pid == 0 then +- assert(posix.execp("systemctl", "daemon-reload")) +- elseif pid > 0 then +- posix.wait(pid) +- end ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload")) ++elseif pid > 0 then ++ posix.wait(pid) + end + + %transfiletriggerpostun -P 10000 -p -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + -- We restart remaining services that should be restarted here. +-if posix.access("/run/systemd/system") then +- pid = posix.fork() +- if pid == 0 then +- assert(posix.execp("systemctl", "reload-or-restart", "--marked")) +- elseif pid > 0 then +- posix.wait(pid) +- end ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart")) ++elseif pid > 0 then ++ posix.wait(pid) + end + + %transfiletriggerin -P 100700 -p -- {{SYSUSERS_DIR}} +diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in +index 1631be18c9..83cd7617f8 100644 +--- a/src/rpm/triggers.systemd.sh.in ++++ b/src/rpm/triggers.systemd.sh.in +@@ -14,10 +14,7 @@ + # upgraded. We care about the case where a package is initially + # installed, because other cases are covered by the *un scriptlets, + # so sometimes we will reload needlessly. +-if test -d "/run/systemd/system"; then +- systemctl daemon-reload || : +- systemctl reload-or-restart --marked || : +-fi ++{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || : + + %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + # On removal, we need to run daemon-reload after any units have been +@@ -25,15 +22,11 @@ fi + # On upgrade, we need to run daemon-reload after any new unit files + # have been installed, but before %postun scripts in packages get + # executed. +-if test -d "/run/systemd/system"; then +- systemctl daemon-reload || : +-fi ++{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || : + + %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + # We restart remaining services that should be restarted here. +-if test -d "/run/systemd/system"; then +- systemctl reload-or-restart --marked || : +-fi ++{{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || : + + %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}} + # This script will process files installed in {{SYSUSERS_DIR}} to create +-- +2.31.1 + diff --git a/0003-rpm-call-needs-restart-in-parallel.patch b/0003-rpm-call-needs-restart-in-parallel.patch new file mode 100644 index 0000000..4637f3e --- /dev/null +++ b/0003-rpm-call-needs-restart-in-parallel.patch @@ -0,0 +1,35 @@ +From 0a2e691b6b1fdceb4b7504870c4b792a66b5080f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 22 Jul 2021 11:28:36 +0200 +Subject: [PATCH 3/5] rpm: call +needs-restart in parallel +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some rpms install a bunch of units… It seems nicer to invoke them all in +parallel. In particular, timeouts in systemctl also run in parallel, so if +there's some communication mishap, we will wait less. + +(cherry picked from commit 3598aff4d963b2e51ac74d206161da47bfde785c) +--- + src/rpm/systemd-update-helper.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in +index 9fa49fa131..f3c75b75fa 100755 +--- a/src/rpm/systemd-update-helper.in ++++ b/src/rpm/systemd-update-helper.in +@@ -32,8 +32,9 @@ case "$command" in + [ -d /run/systemd/system ] || exit 0 + + for unit in "$@"; do +- systemctl set-property "$unit" Markers=+needs-restart || : ++ systemctl set-property "$unit" Markers=+needs-restart & + done ++ wait + ;; + + system-reload-restart|system-reload|system-restart) +-- +2.31.1 + diff --git a/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch b/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch new file mode 100644 index 0000000..eac9b89 --- /dev/null +++ b/0004-rpm-restart-user-services-at-the-end-of-the-transact.patch @@ -0,0 +1,259 @@ +From a63d5d320f81c1cbae07897a401ed5cc5374e0bf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Jul 2021 14:37:57 +0200 +Subject: [PATCH 4/5] rpm: restart user services at the end of the transaction + +This closes an important gap: so far we would reexecute the system manager and +restart system services that were configured to do so, but we wouldn't do the +same for user managers or user services. + +The scheme used for user managers is very similar to the system one, except +that there can be multiple user managers running, so we query the system +manager to get a list of them, and then tell each one to do the equivalent +operations: daemon-reload, disable --now, set-property Markers=+needs-restart, +reload-or-restart --marked. + +The total time that can be spend on this is bounded: we execute the commands in +parallel over user managers and units, and additionally set SYSTEMD_BUS_TIMEOUT +to a lower value (15 s by default). User managers should not have too many +units running, and they should be able to do all those operations very +quickly (<< 1s). The final restart operation may take longer, but it's done +asynchronously, so we only wait for the queuing to happen. + +The advantage of doing this synchronously is that we can wait for each step to +happen, and for example daemon-reloads can finish before we execute the service +restarts, etc. We can also order various steps wrt. to the phases in the rpm +transaction. + +When this was initially proposed, we discussed a more relaxed scheme with bus +property notifications. Such an approach would be more complex because a bunch +of infrastructure would have to be added to system manager to propagate +appropriate notifications to the user managers, and then the user managers +would have to wait for them. Instead, now there is no new code in the managers, +all new functionality is contained in src/rpm/. The ability to call 'systemctl +--user user@' makes this approach very easy. Also, it would be very hard to +order the user manager steps and the rpm transaction steps. + +Note: 'systemctl --user disable' is only called for a user managers that are +running. I don't see a nice way around this, and it shouldn't matter too much: +we'll just leave a dangling symlink in the case where the user enabled the +service manually. + +A follow-up for https://bugzilla.redhat.com/show_bug.cgi?id=1792468 and +fa97d2fcf64e0558054bee673f734f523373b146. + +(cherry picked from commit 36d55958ccc75fa3c91bdd7354d74c910f2f6cc7) +--- + meson.build | 1 + + meson_options.txt | 2 ++ + src/rpm/macros.systemd.in | 6 +++- + src/rpm/systemd-update-helper.in | 47 ++++++++++++++++++++++++++++++++ + src/rpm/triggers.systemd.in | 28 ++++++++++++++++++- + src/rpm/triggers.systemd.sh.in | 13 ++++++++- + 6 files changed, 94 insertions(+), 3 deletions(-) + +diff --git a/meson.build b/meson.build +index fb986e84f7..d898d9ccd0 100644 +--- a/meson.build ++++ b/meson.build +@@ -270,6 +270,7 @@ conf.set_quoted('TMPFILES_DIR', tmpfilesdir) + conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir) + conf.set_quoted('UDEV_HWDB_DIR', udevhwdbdir) + conf.set_quoted('UDEV_RULES_DIR', udevrulesdir) ++conf.set_quoted('UPDATE_HELPER_USER_TIMEOUT', get_option('update-helper-user-timeout')) + conf.set_quoted('USER_CONFIG_UNIT_DIR', join_paths(pkgsysconfdir, 'user')) + conf.set_quoted('USER_DATA_UNIT_DIR', userunitdir) + conf.set_quoted('USER_ENV_GENERATOR_DIR', userenvgeneratordir) +diff --git a/meson_options.txt b/meson_options.txt +index 163c8df87d..9383c7da6a 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -182,6 +182,8 @@ option('xinitrcdir', type : 'string', value : '', + description : 'directory for xinitrc files') + option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d', + description : 'directory for rpm macros ["no" disables]') ++option('update-helper-user-timeout', type : 'string', value : '15s', ++ description : 'how long to wait for user manager operations') + option('pamlibdir', type : 'string', + description : 'directory for PAM modules') + option('pamconfdir', type : 'string', +diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in +index bbdf036da7..caa2e45595 100644 +--- a/src/rpm/macros.systemd.in ++++ b/src/rpm/macros.systemd.in +@@ -93,7 +93,11 @@ fi \ + %{nil} + + %systemd_user_postun_with_restart() \ +-%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \ ++%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun_with_restart}} \ ++if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \ ++ # Package upgrade, not uninstall \ ++ {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-user-units %{?*} || : \ ++fi \ + %{nil} + + %udev_hwdb_update() %{nil} +diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in +index f3c75b75fa..f3466ab3c0 100755 +--- a/src/rpm/systemd-update-helper.in ++++ b/src/rpm/systemd-update-helper.in +@@ -26,6 +26,15 @@ case "$command" in + + remove-user-units) + systemctl --global disable "$@" ++ ++ [ -d /run/systemd/system ] || exit 0 ++ ++ users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') ++ for user in $users; do ++ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ ++ systemctl --user -M "$user@" disable --now "$@" & ++ done ++ wait + ;; + + mark-restart-system-units) +@@ -37,6 +46,17 @@ case "$command" in + wait + ;; + ++ mark-restart-user-units) ++ [ -d /run/systemd/system ] || exit 0 ++ ++ users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') ++ for user in $users; do ++ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ ++ systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart & ++ done ++ wait ++ ;; ++ + system-reload-restart|system-reload|system-restart) + if [ -n "$*" ]; then + echo "Unexpected arguments for '$command': $*" +@@ -54,6 +74,33 @@ case "$command" in + fi + ;; + ++ user-reload-restart|user-reload|user-restart) ++ if [ -n "$*" ]; then ++ echo "Unexpected arguments for '$command': $*" ++ exit 2 ++ fi ++ ++ [ -d /run/systemd/system ] || exit 0 ++ ++ users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') ++ ++ if [[ "$command" =~ reload ]]; then ++ for user in $users; do ++ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ ++ systemctl --user -M "$user@" daemon-reload & ++ done ++ wait ++ fi ++ ++ if [[ "$command" =~ restart ]]; then ++ for user in $users; do ++ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ ++ systemctl --user -M "$user@" reload-or-restart --marked & ++ done ++ wait ++ fi ++ ;; ++ + *) + echo "Unknown verb '$command'" + exit 3 +diff --git a/src/rpm/triggers.systemd.in b/src/rpm/triggers.systemd.in +index d29cc33dfd..8aeb2049c1 100644 +--- a/src/rpm/triggers.systemd.in ++++ b/src/rpm/triggers.systemd.in +@@ -20,6 +20,14 @@ elseif pid > 0 then + posix.wait(pid) + end + ++%transfiletriggerin -P 900899 -p -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload-restart")) ++elseif pid > 0 then ++ posix.wait(pid) ++end ++ + %transfiletriggerpostun -P 1000100 -p -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + -- On removal, we need to run daemon-reload after any units have been + -- removed. +@@ -33,8 +41,17 @@ elseif pid > 0 then + posix.wait(pid) + end + ++%transfiletriggerpostun -P 1000100 -p -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system ++-- Execute daemon-reload in user managers. ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload")) ++elseif pid > 0 then ++ posix.wait(pid) ++end ++ + %transfiletriggerpostun -P 10000 -p -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +--- We restart remaining services that should be restarted here. ++-- We restart remaining system services that should be restarted here. + pid = posix.fork() + if pid == 0 then + assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart")) +@@ -42,6 +59,15 @@ elseif pid > 0 then + posix.wait(pid) + end + ++%transfiletriggerpostun -P 9999 -p -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user ++-- We restart remaining user services that should be restarted here. ++pid = posix.fork() ++if pid == 0 then ++ assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-restart")) ++elseif pid > 0 then ++ posix.wait(pid) ++end ++ + %transfiletriggerin -P 100700 -p -- {{SYSUSERS_DIR}} + -- This script will process files installed in {{SYSUSERS_DIR}} to create + -- specified users automatically. The priority is set such that it +diff --git a/src/rpm/triggers.systemd.sh.in b/src/rpm/triggers.systemd.sh.in +index 83cd7617f8..694cd94e8d 100644 +--- a/src/rpm/triggers.systemd.sh.in ++++ b/src/rpm/triggers.systemd.sh.in +@@ -16,6 +16,9 @@ + # so sometimes we will reload needlessly. + {{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || : + ++%transfiletriggerin -P 900899 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user ++{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload-restart || : ++ + %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system + # On removal, we need to run daemon-reload after any units have been + # removed. +@@ -24,10 +27,18 @@ + # executed. + {{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || : + ++%transfiletriggerpostun -P 1000099 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user ++# Execute daemon-reload in user managers. ++{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload || : ++ + %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system +-# We restart remaining services that should be restarted here. ++# We restart remaining system services that should be restarted here. + {{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || : + ++%transfiletriggerpostun -P 9999 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user ++# We restart remaining user services that should be restarted here. ++{{SYSTEMD_UPDATE_HELPER_PATH}} user-restart || : ++ + %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}} + # This script will process files installed in {{SYSUSERS_DIR}} to create + # specified users automatically. The priority is set such that it +-- +2.31.1 + diff --git a/0005-update-helper-also-add-user-reexec-verb.patch b/0005-update-helper-also-add-user-reexec-verb.patch new file mode 100644 index 0000000..7c4f7ba --- /dev/null +++ b/0005-update-helper-also-add-user-reexec-verb.patch @@ -0,0 +1,47 @@ +From 37cd6c0fad847e5fffd9d107358a36e767c7ca42 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 23 Jul 2021 15:35:23 +0200 +Subject: [PATCH 5/5] update-helper: also add "user-reexec" verb + +This is not called from the systemd.triggers or systemd.macros files. Instead, +it would be called from the scriptlets in systemd rpm package itself, at the +place where we call systemctl daemon-reexec. + +See https://github.com/systemd/systemd/pull/20289#issuecomment-885622200 . + +(cherry picked from commit 1262e824a4d638e347ae0d39c973f1f750962533) +--- + src/rpm/systemd-update-helper.in | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in +index f3466ab3c0..0c6675a9db 100755 +--- a/src/rpm/systemd-update-helper.in ++++ b/src/rpm/systemd-update-helper.in +@@ -74,7 +74,7 @@ case "$command" in + fi + ;; + +- user-reload-restart|user-reload|user-restart) ++ user-reload-restart|user-reload|user-restart|user-reexec) + if [ -n "$*" ]; then + echo "Unexpected arguments for '$command': $*" + exit 2 +@@ -84,6 +84,14 @@ case "$command" in + + users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') + ++ if [[ "$command" =~ reexec ]]; then ++ for user in $users; do ++ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ ++ systemctl --user -M "$user@" daemon-reexec & ++ done ++ wait ++ fi ++ + if [[ "$command" =~ reload ]]; then + for user in $users; do + SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \ +-- +2.31.1 + diff --git a/sources b/sources index 823db82..6d600ac 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (systemd-249.3.tar.gz) = b929c6fb5a0d22bbbf7986a079356eea429639308ccbecbd3de7d19a0e037ca8ae4f57bdb68449170fe73e20d37c47c95134a7c0788cd74ca3db2e106a633a0e +SHA512 (systemd-249.4.tar.gz) = 5b9ec28102538bc3dcb632ee16389ff20dccf4b723186f6ae2da119a1809d84db0d8bcecf9b75c5e2da8427f5543e1da281bbed1a154e529d8a82ea5128c465c diff --git a/systemd.spec b/systemd.spec index 2090b92..7c8b041 100644 --- a/systemd.spec +++ b/systemd.spec @@ -30,7 +30,7 @@ Name: systemd Url: https://www.freedesktop.org/wiki/Software/systemd %if %{without inplace} -Version: 249.3 +Version: 249.4 Release: 1%{?dist} %else # determine the build information from local checkout @@ -91,6 +91,11 @@ GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[ # Any patches which are "in preparation" upstream should be listed # here, rather than in the next section. Packit CI will drop any # patches in this range before applying upstream pull requests. +Patch0001: 0001-rpm-don-t-specify-the-full-path-for-systemctl-and-ot.patch +Patch0002: 0002-rpm-use-a-helper-script-to-actually-invoke-systemctl.patch +Patch0003: 0003-rpm-call-needs-restart-in-parallel.patch +Patch0004: 0004-rpm-restart-user-services-at-the-end-of-the-transact.patch +Patch0005: 0005-update-helper-also-add-user-reexec-verb.patch # Downstream-only patches (5000–9999) @@ -997,6 +1002,11 @@ fi %files standalone-sysusers -f .file-list-standalone-sysusers %changelog +* Tue Aug 24 2021 Zbigniew Jędrzejewski-Szmek - 249.4-1 +- Latest bugfix release: various fixes for systemd-networkd, + systemd-resolved, systemd, systemd-boot. +- Backport of macros to restart systemd user units (#1993244) + * Fri Aug 6 2021 Zbigniew Jędrzejewski-Szmek - 249.3-1 - Latest bugfix release: improved compatibility with latest glibc, various small documentation fixes, and fixes for systemd-networkd bridging,