From c73979afdb3bdf59029bc2fdf54fc044905da854908bc8d58b347067e23edd7a Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 1 Jun 2023 15:56:32 +0000 Subject: [PATCH] - Reexecute user managers on package updates. For now we send signal to user instances to trigger their reexecution. It's asynchronous but it shouldn't cause any problem in practice and it's probably safer than triggering reexecution with "systemctl --user -M 1000@ daemon-reexec" command. The latter command creates a new PAM session behind the scene bringing with it the known issue (upstream issue #8598) with "(sd-pam)" helper process when the PAM session is being closed. OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=1393 --- systemd-update-helper | 27 ++++++++++++++++++--------- systemd.changes | 12 ++++++++++++ systemd.spec | 35 +++++++++++------------------------ triggers.systemd | 2 +- 4 files changed, 42 insertions(+), 34 deletions(-) diff --git a/systemd-update-helper b/systemd-update-helper index 3cc7909b..f48b6d58 100644 --- a/systemd-update-helper +++ b/systemd-update-helper @@ -121,7 +121,24 @@ case "$command" in fi ;; - user-reload-restart|user-reload|user-restart|user-reexec) + user-reexec) + if [ -n "$*" ]; then + echo >&2 "Unexpected arguments for '$command': $*" + exit 2 + fi + + [ -d /run/systemd/system ] || exit 0 + + # Reexecute user manager instances (if any). It is asynchronous but it + # shouldn't be a problem in practice because systemd main package is not + # shipping any user services currently. A problem would arise only if a + # new version of a user service relied on an option that would be only + # understood by the latest version of the user manager and the user unit + # would be restarted before the user manager get reexecuted. + systemctl kill --kill-who=main --signal=SIGRTMIN+25 "user@*.service" + ;; + + user-reload-restart|user-reload|user-restart) if [ -n "$*" ]; then echo >&2 "Unexpected arguments for '$command': $*" exit 2 @@ -131,14 +148,6 @@ 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=15s \ - systemctl --user -M "$user@" daemon-reexec & - done - wait - fi - if [[ "$command" =~ reload ]]; then for user in $users; do SYSTEMD_BUS_TIMEOUT=15s \ diff --git a/systemd.changes b/systemd.changes index 37a133b8..8585e7d1 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Thu Jun 1 15:21:54 UTC 2023 - Franck Bui + +- Reexecute user managers on package updates. + + For now we send signal to user instances to trigger their reexecution. It's + asynchronous but it shouldn't cause any problem in practice and it's probably + safer than triggering reexecution with "systemctl --user -M 1000@ + daemon-reexec" command. The latter command creates a new PAM session behind + the scene bringing with it the known issue (upstream issue #8598) with + "(sd-pam)" helper process when the PAM session is being closed. + ------------------------------------------------------------------- Tue May 9 14:25:04 UTC 2023 - Franck Bui diff --git a/systemd.spec b/systemd.spec index 2dc5ad78..256e6960 100644 --- a/systemd.spec +++ b/systemd.spec @@ -976,14 +976,18 @@ if [ $1 -gt 1 ]; then fi %post -# Make /etc/machine-id an empty file during package installation. On the first -# boot, machine-id is initialized and either committed (if /etc/ is writable) or -# the system/image runs with a transient machine ID, that changes on each boot -# (if the image is read-only). This is especially important for appliance builds -# to avoid an identical machine ID in all images. if [ $1 -eq 1 ]; then + # Make /etc/machine-id an empty file during package installation. On the + # first boot, machine-id is initialized and either committed (if /etc/ + # is writable) or the system/image runs with a transient machine ID, + # that changes on each boot (if the image is read-only). This is + # important for appliance builds to avoid an identical machine ID in all + # images. touch %{_sysconfdir}/machine-id chmod 444 %{_sysconfdir}/machine-id + + # Persistent journal is the default + mkdir -p %{_localstatedir}/log/journal fi %if %{without bootstrap} @@ -993,25 +997,8 @@ pam-config --add --systemd || : %endif systemctl daemon-reexec || : - -# Reexecute user manager instances (if any). It is asynchronous but it shouldn't -# be a problem in practice: a problem would arise only if the new version of a -# user service has a brand new option that is only understood by the latest -# version of the user manager and the user service is started before the user -# manager get reexecuted. But this case is very unlikely especially since we -# don't restart any user service for now. -# -# Before doing this, we unfortunately have to wait until users will reexec their -# user manager (by either rebooting or restarting their session) to a version -# that supports SIGRTMIN+25 otherwise sending the signal to an old version will -# kill the manager which means tearing down the user session. -# -# systemctl kill --kill-who=main --signal=SIGRTMIN+25 "user@*.service" || : - -if [ $1 -eq 1 ]; then - # Persistent journal is the default - mkdir -p %{_localstatedir}/log/journal -fi +# Reexecute the user managers (if any) +%{_systemd_util_dir}/systemd-update-helper user-reexec || : %if %{without filetriggers} # During package installation, the followings are for config files shipped by diff --git a/triggers.systemd b/triggers.systemd index 0aeea905..1c13a31e 100644 --- a/triggers.systemd +++ b/triggers.systemd @@ -1,4 +1,4 @@ -# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */ +# -*- Mode: rpm-spec; indent-tabs-mode: nil -*- # SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd.