summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <jwrdegoede@fedoraproject.org>2021-04-06 11:53:40 +0000
committerHans de Goede <jwrdegoede@fedoraproject.org>2021-04-06 11:53:40 +0000
commite55447500fa95a0cc59c741296030ed91a2986dc (patch)
tree770d8e8cccbf65e4a78c6d6ba6f260b772a46fd3
parentfbe2b79da56cf0a4b7ed5ca4754449ab4875b40f (diff)
parent2a7755febb2daa92f785abb710aee00d48cb7e3a (diff)
Merge branch 'rework-shutdown-handling' into 'master'
Rework shutdown handling See merge request plymouth/plymouth!138
-rw-r--r--configure.ac1
-rwxr-xr-xscripts/plymouth-populate-initrd.in2
-rw-r--r--src/Makefile.am6
-rw-r--r--src/libply-splash-core/ply-device-manager.c11
-rw-r--r--src/main.c66
-rw-r--r--src/plymouthd-fd-escrow.c18
-rw-r--r--systemd-units/Makefile.am37
-rw-r--r--systemd-units/plymouth-switch-root-initramfs.service.in15
8 files changed, 136 insertions, 20 deletions
diff --git a/configure.ac b/configure.ac
index a7b92994..9c9a3e13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -342,6 +342,7 @@ AC_CONFIG_FILES([Makefile po/Makefile.in
systemd-units/plymouth-reboot.service
systemd-units/plymouth-start.service
systemd-units/plymouth-switch-root.service
+ systemd-units/plymouth-switch-root-initramfs.service
systemd-units/systemd-ask-password-plymouth.path
systemd-units/systemd-ask-password-plymouth.service
systemd-units/Makefile
diff --git a/scripts/plymouth-populate-initrd.in b/scripts/plymouth-populate-initrd.in
index 616ecc4e..0ff1f124 100755
--- a/scripts/plymouth-populate-initrd.in
+++ b/scripts/plymouth-populate-initrd.in
@@ -22,6 +22,7 @@
[ -z "$PLYMOUTH_POLICYDIR" ] && PLYMOUTH_POLICYDIR="@PLYMOUTH_POLICY_DIR@"
[ -z "$PLYMOUTH_DAEMON_PATH" ] && PLYMOUTH_DAEMON_PATH="@PLYMOUTH_DAEMON_DIR@/plymouthd"
[ -z "$PLYMOUTH_CLIENT_PATH" ] && PLYMOUTH_CLIENT_PATH="@PLYMOUTH_CLIENT_DIR@/plymouth"
+[ -z "$PLYMOUTH_DRM_ESCROW_PATH" ] && PLYMOUTH_DRM_ESCROW_PATH="@PLYMOUTH_LIBEXECDIR@/plymouth/plymouthd-fd-escrow"
[ -z "$SYSTEMD_UNIT_DIR" ] && SYSTEMD_UNIT_DIR="@SYSTEMD_UNIT_DIR@"
# Generic substring function. If $2 is in $1, return 0.
@@ -416,6 +417,7 @@ ddebug "Running with PLYMOUTH_LDD_PATH=$PLYMOUTH_LDD_PATH"
mkdir -p ${INITRDDIR}${PLYMOUTH_DATADIR}/plymouth/themes
inst ${PLYMOUTH_DAEMON_PATH} $INITRDDIR
inst ${PLYMOUTH_CLIENT_PATH} $INITRDDIR
+inst ${PLYMOUTH_DRM_ESCROW_PATH} $INITRDDIR
inst ${PLYMOUTH_DATADIR}/plymouth/themes/text/text.plymouth $INITRDDIR
inst ${PLYMOUTH_PLUGIN_PATH}/text.so $INITRDDIR
inst ${PLYMOUTH_DATADIR}/plymouth/themes/details/details.plymouth $INITRDDIR
diff --git a/src/Makefile.am b/src/Makefile.am
index cbba2be4..ad3655d5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = -I$(top_srcdir) \
-I$(srcdir)/libply-splash-core \
-I$(srcdir) \
-DPLYMOUTH_LOCALE_DIRECTORY=\"$(localedir)\" \
+ -DPLYMOUTH_DRM_ESCROW_DIRECTORY=\"$(libexecdir)/plymouth\" \
-DPLYMOUTH_LOG_DIRECTORY=\"$(localstatedir)/log\" \
-DPLYMOUTH_SPOOL_DIRECTORY=\"$(localstatedir)/spool/plymouth\" \
-DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" \
@@ -31,6 +32,11 @@ plymouthd_SOURCES = \
plugins/splash/details/plugin.c \
main.c
+escrowdir = $(libexecdir)/plymouth
+escrow_PROGRAMS = plymouthd-fd-escrow
+
+plymouthd_fd_escrow_SOURCES = plymouthd-fd-escrow.c
+
plymouthdrundir = $(localstatedir)/run/plymouth
plymouthdspooldir = $(localstatedir)/spool/plymouth
plymouthdtimedir = $(localstatedir)/lib/plymouth
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
index db843fc7..aed7bac2 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -189,11 +189,16 @@ free_devices_from_device_path (ply_device_manager_t *manager,
ply_hashtable_remove (manager->renderers, (void *) device_path);
free (key);
- if (manager->renderers_activated)
- ply_renderer_deactivate (renderer);
+ /*
+ * Close is false when called from ply_device_manager_free (), in this
+ * case we don't deactivate / close for retain-splash purposes.
+ */
+ if (close) {
+ if (manager->renderers_activated)
+ ply_renderer_deactivate (renderer);
- if (close)
ply_renderer_close (renderer);
+ }
ply_renderer_free (renderer);
}
diff --git a/src/main.c b/src/main.c
index 122cb734..aa6f90b8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -158,6 +158,7 @@ static void on_quit (state_t *state,
static bool sh_is_init (state_t *state);
static void cancel_pending_delayed_show (state_t *state);
static void prepare_logging (state_t *state);
+static void dump_debug_buffer_to_file (void);
static void
on_session_output (state_t *state,
@@ -653,6 +654,12 @@ on_newroot (state_t *state,
}
ply_trace ("new root mounted at \"%s\", switching to it", root_dir);
+
+ if (!strcmp (root_dir, "/run/initramfs") && debug_buffer != NULL) {
+ ply_trace ("switching back to initramfs, dumping debug-buffer now");
+ dump_debug_buffer_to_file ();
+ }
+
chdir (root_dir);
chroot (".");
chdir ("/");
@@ -1875,8 +1882,13 @@ check_verbosity (state_t *state)
}
if (debug_buffer != NULL) {
- if (debug_buffer_path == NULL)
- debug_buffer_path = strdup (PLYMOUTH_LOG_DIRECTORY "/plymouth-debug.log");
+ if (debug_buffer_path == NULL) {
+ if (state->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN ||
+ state->mode == PLY_BOOT_SPLASH_MODE_REBOOT)
+ debug_buffer_path = strdup (PLYMOUTH_LOG_DIRECTORY "/plymouth-shutdown-debug.log");
+ else
+ debug_buffer_path = strdup (PLYMOUTH_LOG_DIRECTORY "/plymouth-debug.log");
+ }
ply_logger_add_filter (ply_logger_get_error_default (),
(ply_logger_filter_handler_t)
@@ -2056,6 +2068,43 @@ on_crash (int signum)
}
static void
+start_plymouthd_fd_escrow (void)
+{
+ pid_t pid;
+
+ pid = fork ();
+ if (pid == 0) {
+ const char *argv[] = { PLYMOUTH_DRM_ESCROW_DIRECTORY "/plymouthd-fd-escrow", NULL };
+
+ execve (argv[0], (char * const *) argv, NULL);
+ ply_trace ("could not launch fd escrow process: %m");
+ _exit (1);
+ }
+}
+
+static void
+on_term_signal (state_t *state)
+{
+ bool retain_splash = false;
+
+ ply_trace ("received SIGTERM");
+
+ /*
+ * On shutdown/reboot with pixel-displays active, start the plymouthd-fd-escrow
+ * helper to hold on to the pixel-displays fds until the end.
+ */
+ if ((state->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN ||
+ state->mode == PLY_BOOT_SPLASH_MODE_REBOOT) &&
+ !state->is_inactive && state->boot_splash &&
+ ply_boot_splash_uses_pixel_displays (state->boot_splash)) {
+ start_plymouthd_fd_escrow ();
+ retain_splash = true;
+ }
+
+ on_quit (state, retain_splash, ply_trigger_new (NULL));
+}
+
+static void
write_pid_file (const char *filename)
{
FILE *fp;
@@ -2214,11 +2263,18 @@ main (int argc,
}
/* Make the first byte in argv be '@' so that we can survive systemd's killing
- * spree when going from initrd to /, and so we stay alive all the way until
- * the power is killed at shutdown.
+ * spree when going from initrd to /
* http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
+ * Note ply_file_exists () does not work here because /etc/initrd-release
+ * is a symlink when using a dracut generated initrd.
*/
- argv[0][0] = '@';
+ if (state.mode == PLY_BOOT_SPLASH_MODE_BOOT_UP &&
+ access ("/etc/initrd-release", F_OK) >= 0)
+ argv[0][0] = '@';
+
+ /* Catch SIGTERM for clean shutdown on poweroff/reboot */
+ ply_event_loop_watch_signal (state.loop, SIGTERM,
+ (ply_event_handler_t) on_term_signal, &state);
state.boot_server = start_boot_server (&state);
diff --git a/src/plymouthd-fd-escrow.c b/src/plymouthd-fd-escrow.c
new file mode 100644
index 00000000..89ec5b68
--- /dev/null
+++ b/src/plymouthd-fd-escrow.c
@@ -0,0 +1,18 @@
+#include <signal.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+ signal (SIGTERM, SIG_IGN);
+
+ /* Make the first byte in argv be '@' so that we can survive systemd's killing
+ * spree until the power is killed at shutdown.
+ * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
+ */
+ argv[0][0] = '@';
+
+ while (pause());
+
+ return 0;
+}
diff --git a/systemd-units/Makefile.am b/systemd-units/Makefile.am
index b1d843b6..cd2d7be5 100644
--- a/systemd-units/Makefile.am
+++ b/systemd-units/Makefile.am
@@ -1,5 +1,6 @@
systemd_unit_templates = \
plymouth-switch-root.service.in \
+ plymouth-switch-root-initramfs.service.in \
plymouth-start.service.in \
plymouth-read-write.service.in \
plymouth-quit.service.in \
@@ -37,17 +38,25 @@ install-data-hook:
$(LN_S) ../plymouth-quit.service && \
$(LN_S) ../plymouth-quit-wait.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/reboot.target.wants && \
- rm -f plymouth-reboot.service && \
- $(LN_S) ../plymouth-reboot.service)
+ rm -f plymouth-reboot.service \
+ plymouth-switch-root-initramfs.service && \
+ $(LN_S) ../plymouth-reboot.service && \
+ $(LN_S) ../plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/kexec.target.wants && \
- rm -f plymouth-kexec.service && \
- $(LN_S) ../plymouth-kexec.service)
+ rm -f plymouth-kexec.service \
+ plymouth-switch-root-initramfs.service && \
+ $(LN_S) ../plymouth-kexec.service && \
+ $(LN_S) ../plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/poweroff.target.wants && \
- rm -f plymouth-poweroff.service && \
- $(LN_S) ../plymouth-poweroff.service)
+ rm -f plymouth-poweroff.service \
+ plymouth-switch-root-initramfs.service && \
+ $(LN_S) ../plymouth-poweroff.service && \
+ $(LN_S) ../plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/halt.target.wants && \
- rm -f plymouth-halt.service && \
- $(LN_S) ../plymouth-halt.service)
+ rm -f plymouth-halt.service \
+ plymouth-switch-root-initramfs.service && \
+ $(LN_S) ../plymouth-halt.service && \
+ $(LN_S) ../plymouth-switch-root-initramfs.service)
uninstall-hook:
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/initrd-switch-root.target.wants && \
@@ -57,13 +66,17 @@ uninstall-hook:
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/multi-user.target.wants && \
rm -f plymouth-quit.service plymouth-quit-wait.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/reboot.target.wants && \
- rm -f plymouth-reboot.service)
+ rm -f plymouth-reboot.service \
+ plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/kexec.target.wants && \
- rm -f plymouth-kexec.service)
+ rm -f plymouth-kexec.service \
+ plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/poweroff.target.wants && \
- rm -f plymouth-poweroff.service)
+ rm -f plymouth-poweroff.service \
+ plymouth-switch-root-initramfs.service)
(cd $(DESTDIR)$(SYSTEMD_UNIT_DIR)/halt.target.wants && \
- rm -f plymouth-halt.service)
+ rm -f plymouth-halt.service \
+ plymouth-switch-root-initramfs.service)
rmdir --ignore-fail-on-non-empty \
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/sysinit.target.wants \
$(DESTDIR)$(SYSTEMD_UNIT_DIR)/multi-user.target.wants \
diff --git a/systemd-units/plymouth-switch-root-initramfs.service.in b/systemd-units/plymouth-switch-root-initramfs.service.in
new file mode 100644
index 00000000..0610803c
--- /dev/null
+++ b/systemd-units/plymouth-switch-root-initramfs.service.in
@@ -0,0 +1,15 @@
+[Unit]
+Description=Tell Plymouth To Jump To initramfs
+DefaultDependencies=no
+# dracut-shutdown.service restores the initramfs when it is _stopped_
+# use Conflicts to make sure its ExecStop has run before we do
+Conflicts=dracut-shutdown.service
+After=plymouth-halt.service plymouth-reboot.service plymouth-poweroff.service plymouth-kexec.service dracut-shutdown.service
+ConditionPathExists=/run/initramfs/bin/sh
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=-@PLYMOUTH_CLIENT_DIR@/plymouth update-root-fs --new-root-dir=/run/initramfs
+Type=oneshot
+RemainAfterExit=yes