Merge pull request #20276 from keszybz/rpm-restart-wip

Reload user daemons and restart user services at the end of the rpm transaction
This commit is contained in:
Luca Boccassi
2021-07-26 11:02:37 +01:00
committed by GitHub
8 changed files with 220 additions and 74 deletions
+1 -1
View File
@@ -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
+3 -1
View File
@@ -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'
@@ -255,6 +255,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'))
@@ -271,6 +272,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)
+2
View File
@@ -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',
+23 -19
View File
@@ -46,31 +46,33 @@ OrderWithRequires(postun): systemd \
%systemd_post() \
%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \
if [ $1 -eq 1 ] && [ -x %{_bindir}/systemctl ]; then \
if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
# Initial installation \
%{_bindir}/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 ] && [ -x %{_bindir}/systemctl ]; then \
if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
# Package removal, not upgrade \
if [ -d /run/systemd/system ]; then \
%{_bindir}/systemctl --no-reload disable --now %{?*} || : \
else \
%{_bindir}/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 ] && [ -x %{_bindir}/systemctl ]; then \
if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
# Package removal, not upgrade \
%{_bindir}/systemctl --global disable %{?*} || : \
{{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \
fi \
%{nil}
@@ -84,16 +86,18 @@ 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 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
# Package upgrade, not uninstall \
for unit in %{?*}; do \
%{_bindir}/systemctl set-property $unit Markers=+needs-restart || : \
done \
{{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \
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}
@@ -105,17 +109,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 - <<SYSTEMD_INLINE_EOF || : \
command -v systemd-sysusers >/dev/null && systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \
%{?*} \
SYSTEMD_INLINE_EOF\
%{nil}
+9 -4
View File
@@ -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
+116
View File
@@ -0,0 +1,116 @@
#!/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 "$@"
[ -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)
[ -d /run/systemd/system ] || exit 0
for unit in "$@"; do
systemctl set-property "$unit" Markers=+needs-restart &
done
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': $*"
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
;;
user-reload-restart|user-reload|user-restart|user-reexec)
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" =~ 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}} \
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
;;
esac
+46 -33
View File
@@ -13,20 +13,19 @@
-- 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.exec("%{_bindir}/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-restart"))
elseif pid > 0 then
posix.wait(pid)
end
pid = posix.fork()
if pid == 0 then
assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
elseif pid > 0 then
posix.wait(pid)
end
%transfiletriggerin -P 900899 -p <lua> -- {{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 <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
@@ -35,24 +34,38 @@ 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.exec("%{_bindir}/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 1000100 -p <lua> -- {{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 <lua> -- {{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.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
elseif pid > 0 then
posix.wait(pid)
end
-- 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"))
elseif pid > 0 then
posix.wait(pid)
end
%transfiletriggerpostun -P 9999 -p <lua> -- {{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 <lua> -- {{SYSUSERS_DIR}}
@@ -62,7 +75,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 +87,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 +99,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 +124,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 +136,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
+20 -16
View File
@@ -14,10 +14,10 @@
# 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
%{_bindir}/systemctl daemon-reload || :
%{_bindir}/systemctl reload-or-restart --marked || :
fi
{{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
@@ -25,36 +25,40 @@ 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
%{_bindir}/systemctl daemon-reload || :
fi
{{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.
if test -d "/run/systemd/system"; then
%{_bindir}/systemctl reload-or-restart --marked || :
fi
# 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
# 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 +75,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}}