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