summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2021-03-29 22:22:40 +0200
committerHans de Goede <hdegoede@redhat.com>2021-04-06 13:15:05 +0200
commita0c743c76a3436b8db088398b8fee10d902bf9fd (patch)
tree10c4bafa1f76b317fa3b74720c07e97ba64b69d1
parenta4bb4c146b8461d872136684575ba15c8ab4c8c8 (diff)
main: Add a plymouthd-fd-escrow helper
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>
-rw-r--r--src/Makefile.am6
-rw-r--r--src/main.c27
-rw-r--r--src/plymouthd-fd-escrow.c18
3 files changed, 51 insertions, 0 deletions
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/main.c b/src/main.c
index 1c5faa6c..23319a1c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2061,12 +2061,39 @@ 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));
}
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;
+}