From 647dcb39913f1586835c33cf29c3b00cea833950 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jul 28 2020 19:21:39 +0000 Subject: import plymouth-0.9.4-3.20200615git1e36e30.el8 --- diff --git a/SOURCES/0001-src-die-during-shutdown-with-everything-else.patch b/SOURCES/0001-src-die-during-shutdown-with-everything-else.patch new file mode 100644 index 0000000..e9e5650 --- /dev/null +++ b/SOURCES/0001-src-die-during-shutdown-with-everything-else.patch @@ -0,0 +1,578 @@ +From 43b4f60da9b468ffb3e782d91b9c01c845a339af Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 17 Jul 2020 16:06:44 -0400 +Subject: [PATCH] src: die during shutdown with everything else + +plymouthd currently avoids getting killed at shutdown. This causes +filesystems to fail to remount read-only in some cases. + +This commit changes things up so that plymouthd dies with everyone else, +but spawns a process to hold open the drm device that can keep the splash +up until the very end. +--- + src/Makefile.am | 7 +++ + src/main.c | 11 ++-- + src/plugins/renderers/drm/Makefile.am | 3 +- + src/plugins/renderers/drm/plugin.c | 62 ++++++++++++++++++++++ + src/plymouthd-drm-escrow.c | 18 +++++++ + systemd-units/plymouth-halt.service.in | 1 + + systemd-units/plymouth-poweroff.service.in | 1 + + systemd-units/plymouth-reboot.service.in | 1 + + 8 files changed, 100 insertions(+), 4 deletions(-) + create mode 100644 src/plymouthd-drm-escrow.c + +diff --git a/src/Makefile.am b/src/Makefile.am +index 95ed019..78f3f78 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,52 +1,59 @@ + SUBDIRS = libply libply-splash-core libply-splash-graphics . plugins client + if ENABLE_UPSTART_MONITORING + SUBDIRS += upstart-bridge + endif + AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/libply \ + -I$(srcdir)/libply-splash-core \ + -I$(srcdir) \ ++ -DPLYMOUTH_DRM_ESCROW_DIRECTORY=\"$(libexecdir)/plymouth\" \ + -DPLYMOUTH_LOG_DIRECTORY=\"$(localstatedir)/log\" \ + -DPLYMOUTH_SPOOL_DIRECTORY=\"$(localstatedir)/spool/plymouth\" \ + -DPLYMOUTH_TIME_DIRECTORY=\"$(localstatedir)/lib/plymouth/\" \ + -DPLYMOUTH_LOGO_FILE=\"$(logofile)\" + + plymouthdbindir = $(plymouthdaemondir) + plymouthdbin_PROGRAMS = plymouthd + + plymouthd_CFLAGS = $(PLYMOUTH_CFLAGS) \ + -rdynamic \ + -DPLYMOUTH_PLUGIN_PATH=\"$(PLYMOUTH_PLUGIN_PATH)\" \ + -DPLYMOUTH_THEME_PATH=\"$(PLYMOUTH_THEME_PATH)/\" \ + -DPLYMOUTH_POLICY_DIR=\"$(PLYMOUTH_POLICY_DIR)/\" \ + -DPLYMOUTH_RUNTIME_DIR=\"$(PLYMOUTH_RUNTIME_DIR)\" \ + -DPLYMOUTH_CONF_DIR=\"$(PLYMOUTH_CONF_DIR)/\" \ + -DPLYMOUTH_RUNTIME_THEME_PATH=\"$(PLYMOUTH_RUNTIME_THEME_PATH)/\" + plymouthd_LDADD = $(PLYMOUTH_LIBS) libply/libply.la libply-splash-core/libply-splash-core.la + plymouthd_SOURCES = \ + ply-boot-protocol.h \ + ply-boot-server.h \ + ply-boot-server.c \ + plugins/splash/details/plugin.c \ + main.c + ++escrowdir = $(libexecdir)/plymouth ++escrow_PROGRAMS = plymouthd-drm-escrow ++ ++plymouthd_drm_escrow_LDFLAGS = -all-static ++plymouthd_drm_escrow_SOURCES = plymouthd-drm-escrow.c ++ + plymouthdrundir = $(localstatedir)/run/plymouth + plymouthdspooldir = $(localstatedir)/spool/plymouth + plymouthdtimedir = $(localstatedir)/lib/plymouth + + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = ply-splash-core.pc ply-splash-graphics.pc + + plymouthd_defaultsdir = $(PLYMOUTH_POLICY_DIR) + dist_plymouthd_defaults_DATA = plymouthd.defaults + + plymouthd_confdir = $(PLYMOUTH_CONF_DIR) + dist_plymouthd_conf_DATA = plymouthd.conf + + install-data-hook: + -mkdir -p $(DESTDIR)$(plymouthdrundir) + -mkdir -p $(DESTDIR)$(plymouthdspooldir) + -mkdir -p $(DESTDIR)$(plymouthdtimedir) + + EXTRA_DIST = ply-splash-core.pc.in ply-splash-graphics.pc.in + MAINTAINERCLEANFILES = Makefile.in +diff --git a/src/main.c b/src/main.c +index 8848ad0..8372f2f 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -2181,65 +2181,70 @@ main (int argc, + + if (daemon_handle == NULL) { + ply_error ("plymouthd: cannot daemonize: %m"); + return EX_UNAVAILABLE; + } + } + + if (debug) + debug_buffer = ply_buffer_new (); + + signal (SIGABRT, on_crash); + signal (SIGSEGV, on_crash); + + /* before do anything we need to make sure we have a working + * environment. + */ + if (!initialize_environment (&state)) { + if (errno == 0) { + if (daemon_handle != NULL) + ply_detach_daemon (daemon_handle, 0); + return 0; + } + + ply_error ("plymouthd: could not setup basic operating environment: %m"); + if (daemon_handle != NULL) + ply_detach_daemon (daemon_handle, EX_OSERR); + return EX_OSERR; + } + + /* 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 ++ * ++ * If the system is shutting down, we let systemd slay us because otherwise we ++ * may prevent the root fs from getting remounted read-only. + */ +- argv[0][0] = '@'; ++ if (state.mode != PLY_BOOT_SPLASH_MODE_SHUTDOWN && ++ state.mode != PLY_BOOT_SPLASH_MODE_REBOOT) { ++ argv[0][0] = '@'; ++ } + + state.boot_server = start_boot_server (&state); + + if (state.boot_server == NULL) { + ply_trace ("plymouthd is already running"); + + if (daemon_handle != NULL) + ply_detach_daemon (daemon_handle, EX_OK); + return EX_OK; + } + + state.boot_buffer = ply_buffer_new (); + + if (attach_to_session) { + state.should_be_attached = attach_to_session; + if (!attach_to_running_session (&state)) { + ply_trace ("could not redirect console session: %m"); + if (!no_daemon) + ply_detach_daemon (daemon_handle, EX_UNAVAILABLE); + return EX_UNAVAILABLE; + } + } + + state.progress = ply_progress_new (); + state.splash_delay = NAN; + state.device_timeout = NAN; + + ply_progress_load_cache (state.progress, + get_cache_file_for_mode (state.mode)); + +diff --git a/src/plugins/renderers/drm/Makefile.am b/src/plugins/renderers/drm/Makefile.am +index 271b17f..22a819b 100644 +--- a/src/plugins/renderers/drm/Makefile.am ++++ b/src/plugins/renderers/drm/Makefile.am +@@ -1,23 +1,24 @@ + if ENABLE_DRM_RENDERER + AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/../../../libply \ + -I$(srcdir)/../../../libply-splash-core \ + -I$(srcdir)/../../.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/.. \ +- -I$(srcdir) ++ -I$(srcdir) \ ++ -DPLYMOUTH_DRM_ESCROW_DIRECTORY=\"$(libexecdir)/plymouth\" + + plugindir = $(libdir)/plymouth/renderers + plugin_LTLIBRARIES = drm.la + + drm_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(DRM_CFLAGS) + + drm_la_LDFLAGS = -module -avoid-version -export-dynamic + drm_la_LIBADD = $(PLYMOUTH_LIBS) $(DRM_LIBS) \ + ../../../libply/libply.la \ + ../../../libply-splash-core/libply-splash-core.la + drm_la_SOURCES = $(srcdir)/plugin.c + + endif + + MAINTAINERCLEANFILES = Makefile.in +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index 4dbf8da..38bae36 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -131,73 +131,79 @@ typedef struct + bool connected; + bool uses_hw_rotation; + } ply_output_t; + + struct _ply_renderer_backend + { + ply_event_loop_t *loop; + ply_terminal_t *terminal; + + int device_fd; + char *device_name; + drmModeRes *resources; + + ply_renderer_input_source_t input_source; + ply_list_t *heads; + ply_hashtable_t *heads_by_controller_id; + + ply_hashtable_t *output_buffers; + + ply_output_t *outputs; + int outputs_len; + int connected_count; + + int32_t dither_red; + int32_t dither_green; + int32_t dither_blue; + + uint32_t is_active : 1; + uint32_t requires_explicit_flushing : 1; + uint32_t use_preferred_mode : 1; ++ uint32_t watching_for_termination : 1; + + int panel_width; + int panel_height; + ply_pixel_buffer_rotation_t panel_rotation; + int panel_scale; + }; + + ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void); + static bool open_input_source (ply_renderer_backend_t *backend, + ply_renderer_input_source_t *input_source); + static void flush_head (ply_renderer_backend_t *backend, + ply_renderer_head_t *head); + ++static void close_device (ply_renderer_backend_t *backend); ++ ++static void watch_for_termination (ply_renderer_backend_t *backend); ++static void stop_watching_for_termination (ply_renderer_backend_t *backend); ++ + /* A small helper to determine if we should try to keep the current mode + * or pick the best mode ourselves, we keep the current mode only if the + * user specified a specific mode using video= on the commandline. + */ + static bool + should_use_preferred_mode (void) + { + bool use_preferred_mode = true; + + if (ply_kernel_command_line_get_string_after_prefix ("video=")) + use_preferred_mode = false; + + ply_trace ("should_use_preferred_mode: %d", use_preferred_mode); + + return use_preferred_mode; + } + + static bool + ply_renderer_buffer_map (ply_renderer_backend_t *backend, + ply_renderer_buffer_t *buffer) + { + struct drm_mode_map_dumb map_dumb_buffer_request; + void *map_address; + + if (buffer->map_address != MAP_FAILED) { + buffer->map_count++; + return true; + } + + memset (&map_dumb_buffer_request, 0, sizeof(struct drm_mode_map_dumb)); +@@ -918,158 +924,214 @@ static void + destroy_backend (ply_renderer_backend_t *backend) + { + ply_trace ("destroying renderer backend for device %s", backend->device_name); + free_heads (backend); + + free (backend->device_name); + ply_hashtable_free (backend->output_buffers); + ply_hashtable_free (backend->heads_by_controller_id); + + free (backend->outputs); + free (backend); + } + + static void + activate (ply_renderer_backend_t *backend) + { + ply_renderer_head_t *head; + ply_list_node_t *node; + + ply_trace ("taking master and scanning out"); + backend->is_active = true; + + drmSetMaster (backend->device_fd); + node = ply_list_get_first_node (backend->heads); + while (node != NULL) { + head = (ply_renderer_head_t *) ply_list_node_get_data (node); + /* Flush out any pending drawing to the buffer */ + flush_head (backend, head); + node = ply_list_get_next_node (backend->heads, node); + } ++ ++ watch_for_termination (backend); + } + + static void + deactivate (ply_renderer_backend_t *backend) + { + ply_trace ("dropping master"); + drmDropMaster (backend->device_fd); + backend->is_active = false; ++ ++ stop_watching_for_termination (backend); + } + + static void + on_active_vt_changed (ply_renderer_backend_t *backend) + { + if (ply_terminal_is_active (backend->terminal)) { + ply_trace ("activating on vt change"); + activate (backend); + } else { + ply_trace ("deactivating on vt change"); + deactivate (backend); + } + } + + static bool + load_driver (ply_renderer_backend_t *backend) + { + int device_fd; + + ply_trace ("Opening '%s'", backend->device_name); + device_fd = open (backend->device_name, O_RDWR); + + if (device_fd < 0) { + ply_trace ("open failed: %m"); + return false; + } + + backend->device_fd = device_fd; + + drmDropMaster (device_fd); + + return true; + } + + static void + unload_backend (ply_renderer_backend_t *backend) + { + if (backend == NULL) + return; + + ply_trace ("unloading backend"); + + if (backend->device_fd >= 0) { + drmClose (backend->device_fd); + backend->device_fd = -1; + } + + destroy_backend (backend); + backend = NULL; + + } + ++static void ++on_term_signal (ply_renderer_backend_t *backend) ++{ ++ pid_t pid; ++ ++ ply_trace ("got SIGTERM, launching drm escrow to protect splash, and dying"); ++ ++ pid = fork(); ++ ++ if (pid == 0) { ++ const char *argv[] = { PLYMOUTH_DRM_ESCROW_DIRECTORY "/plymouthd-drm-escrow", NULL }; ++ ++ dup (backend->device_fd); ++ execve (argv[0], (char * const *) argv, NULL); ++ ++ ply_trace ("could not launch drm escrow process: %m"); ++ ++ _exit (1); ++ } ++ ++ ++ close_device (backend); ++ ++ exit (0); ++} ++ ++static void ++watch_for_termination (ply_renderer_backend_t *backend) ++{ ++ if (backend->watching_for_termination) ++ return; ++ ++ ply_trace ("watching for termination signal"); ++ ply_event_loop_watch_signal (backend->loop, SIGTERM, (ply_event_handler_t) on_term_signal, backend); ++ backend->watching_for_termination = true; ++} ++ ++static void ++stop_watching_for_termination (ply_renderer_backend_t *backend) ++{ ++ if (!backend->watching_for_termination) ++ return; ++ ++ ply_trace ("stopping watching for termination signal"); ++ ply_event_loop_stop_watching_signal (backend->loop, SIGTERM); ++ backend->watching_for_termination = false; ++} ++ + static bool + open_device (ply_renderer_backend_t *backend) + { + assert (backend != NULL); + assert (backend->device_name != NULL); + + if (!load_driver (backend)) + return false; + + if (backend->terminal == NULL) + return true; + + if (!ply_terminal_open (backend->terminal)) { + ply_trace ("could not open terminal: %m"); + return false; + } + + if (!ply_terminal_is_vt (backend->terminal)) { + ply_trace ("terminal is not a VT"); + ply_terminal_close (backend->terminal); + return false; + } + + ply_terminal_watch_for_active_vt_change (backend->terminal, + (ply_terminal_active_vt_changed_handler_t) + on_active_vt_changed, + backend); + ++ watch_for_termination (backend); ++ + return true; + } + + static void + close_device (ply_renderer_backend_t *backend) + { + ply_trace ("closing device"); + + free_heads (backend); + ++ stop_watching_for_termination (backend); ++ + if (backend->terminal != NULL) { + ply_terminal_stop_watching_for_active_vt_change (backend->terminal, + (ply_terminal_active_vt_changed_handler_t) + on_active_vt_changed, + backend); + } + + unload_backend (backend); + } + + static void + output_get_controller_info (ply_renderer_backend_t *backend, + drmModeConnector *connector, + ply_output_t *output) + { + int i; + drmModeEncoder *encoder; + + assert (backend != NULL); + + output->possible_controllers = 0xffffffff; + + for (i = 0; i < connector->count_encoders; i++) { + encoder = drmModeGetEncoder (backend->device_fd, + connector->encoders[i]); + + if (encoder == NULL) + continue; + + if (encoder->encoder_id == connector->encoder_id && encoder->crtc_id) { +diff --git a/src/plymouthd-drm-escrow.c b/src/plymouthd-drm-escrow.c +new file mode 100644 +index 0000000..9097db9 +--- /dev/null ++++ b/src/plymouthd-drm-escrow.c +@@ -0,0 +1,18 @@ ++#include ++#include ++ ++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/plymouth-halt.service.in b/systemd-units/plymouth-halt.service.in +index cb87c1f..00f7eed 100644 +--- a/systemd-units/plymouth-halt.service.in ++++ b/systemd-units/plymouth-halt.service.in +@@ -1,13 +1,14 @@ + [Unit] + Description=Show Plymouth Halt Screen + After=getty@tty1.service display-manager.service plymouth-start.service + Before=systemd-halt.service + DefaultDependencies=no + ConditionKernelCommandLine=!plymouth.enable=0 + ConditionVirtualization=!container + + [Service] + ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session + ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash ++KillMode=none + Type=forking + RemainAfterExit=yes +diff --git a/systemd-units/plymouth-poweroff.service.in b/systemd-units/plymouth-poweroff.service.in +index cf05e47..a1f78eb 100644 +--- a/systemd-units/plymouth-poweroff.service.in ++++ b/systemd-units/plymouth-poweroff.service.in +@@ -1,13 +1,14 @@ + [Unit] + Description=Show Plymouth Power Off Screen + After=getty@tty1.service display-manager.service plymouth-start.service + Before=systemd-poweroff.service + DefaultDependencies=no + ConditionKernelCommandLine=!plymouth.enable=0 + ConditionVirtualization=!container + + [Service] + ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=shutdown --attach-to-session + ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash ++KillMode=none + Type=forking + RemainAfterExit=yes +diff --git a/systemd-units/plymouth-reboot.service.in b/systemd-units/plymouth-reboot.service.in +index 3624550..8fff576 100644 +--- a/systemd-units/plymouth-reboot.service.in ++++ b/systemd-units/plymouth-reboot.service.in +@@ -1,13 +1,14 @@ + [Unit] + Description=Show Plymouth Reboot Screen + After=getty@tty1.service display-manager.service plymouth-start.service + Before=systemd-reboot.service + DefaultDependencies=no + ConditionKernelCommandLine=!plymouth.enable=0 + ConditionVirtualization=!container + + [Service] + ExecStart=@PLYMOUTH_DAEMON_DIR@/plymouthd --mode=reboot --attach-to-session + ExecStartPost=-@PLYMOUTH_CLIENT_DIR@/plymouth show-splash ++KillMode=none + Type=forking + RemainAfterExit=yes +-- +2.26.0 + diff --git a/SPECS/plymouth.spec b/SPECS/plymouth.spec index 6220fbb..ac92a6d 100644 --- a/SPECS/plymouth.spec +++ b/SPECS/plymouth.spec @@ -10,7 +10,7 @@ Summary: Graphical Boot Animation and Logger Name: plymouth Version: 0.9.4 -Release: 1.%{commitdate}git%{shortcommit}%{?dist} +Release: 3.%{commitdate}git%{shortcommit}%{?dist} License: GPLv2+ URL: http://www.freedesktop.org/wiki/Software/Plymouth Group: System Environment/Base @@ -27,6 +27,9 @@ Patch10002: 0002-throbgress-update-for-api-change.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1702764 Patch20001: ship-label-plugin-in-initrd.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1626342 +Patch30001: 0001-src-die-during-shutdown-with-everything-else.patch + BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libudev) BuildRequires: kernel-headers @@ -385,6 +388,7 @@ fi %{_libdir}/plymouth/renderers/drm* %{_libdir}/plymouth/renderers/frame-buffer* %{_libdir}/libply-splash-graphics.so.* +%{_libexecdir}/plymouth/plymouthd-drm-escrow %files scripts %{_sbindir}/plymouth-set-default-theme @@ -446,6 +450,10 @@ fi %files system-theme %changelog +* Fri Jul 17 2020 Ray Strode - 0.9.4-3.git1688935 +- Die at shutdown with everything else + Resolves: #1626342 + * Mon Jun 15 2020 Ray Strode - 0.9.4-1.git1688935 - Rebase to git snapshot Resolves: #1688935