]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
main: Add a plymouthd-fd-escrow helper
authorRay Strode <rstrode@redhat.com>
Mon, 29 Mar 2021 20:22:40 +0000 (22:22 +0200)
committerHans de Goede <hdegoede@redhat.com>
Tue, 6 Apr 2021 11:15:05 +0000 (13:15 +0200)
When plymouth receives SIGTERM during shutdown or reboot, we must
exit cleanly to avoid keeping files open on the rootfs and to avoid
making drmModeSetCrtc () calls after the kms driver's shutdown method
has ran.

But at the same time we also want the boot-splash to stay up (in its
idle form) until the system actually reboots or powers off.
So we want to avoid the boot-splash getting replaced by e.g.
the text-console.

Add a plymouthd-fd-escrow helper which will get forked off when we
receive a SIGTERM in reboot/shutdown mode with pixel-displays active.

This helper will keep the fds for the pixel-displays open, so that
the boot-splash stays up until the end.

Changes by Hans de Goede:
- Start the escrow helper from main.c instead of from the drm plugin
- Rename the helper from plymouthd-drm-escrow to plymouthd-fd-escrow, since it
  will be used to escrow fbdev fd-s too now
- In the child of the fork, continue with quiting normally (letting the
  bootsplash become idle) instead of exiting directly
- Make plymouthd-fd-escrow a normal dynamic binary instead of a static binary,
  the initrd already contains dynamic binaries so it does not have to be static
- Split the changes adding plymouth-switch-root-initramfs.service into a
  separate patch
- Rewrite commit message

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
src/Makefile.am
src/main.c
src/plymouthd-fd-escrow.c [new file with mode: 0644]

index cbba2be446c9acd0c2bff2d5a94474131f4a1b43..ad3655d5944cebad36761cee44d9d79241a6d942 100644 (file)
@@ -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
index 1c5faa6c83ca4dd6f1818615d6238b5692daed4e..23319a1c8357aa1e84f990a7881a8162bce0ea7d 100644 (file)
@@ -2060,6 +2060,21 @@ on_crash (int signum)
         raise (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)
 {
@@ -2067,6 +2082,18 @@ on_term_signal (state_t *state)
 
         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));
 }
 
diff --git a/src/plymouthd-fd-escrow.c b/src/plymouthd-fd-escrow.c
new file mode 100644 (file)
index 0000000..89ec5b6
--- /dev/null
@@ -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;
+}