File bsc#1220229-0001-Fix-tools-make-crm_mon-exit-upon-loss-of-the-attache.patch of Package pacemaker.34780
From 6f78cf724539bf8c4e957ba11c725b1c473c4288 Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Mon, 22 Apr 2024 18:49:27 +0200
Subject: [PATCH] Fix: tools: make crm_mon exit upon loss of the attached
pseudo-terminal
Previously when crm_mon was running in console mode, if the attached
pseudo-terminal got lost, crm_mon would persist in the background and
raise the CPU usage to 100%.
The situation triggers if `use_pty` is enabled for `sudo`, in which case
it creates a separate pseudo-terminal device for its child process.
A producer:
- Enable `use_pty` by adding `Defaults use_pty` to /etc/sudoers
- Open a console and execute:
> sudo su -
# crm_mon
- Open another console, find the PID of crm_mon's bash parent and kill
it:
# kill -9 $(ps -C crm_mon -o ppid=)
The pty device created by `sudo` from the first console is basically
deleted, but crm_mon continues running in the background and raises the
CPU usage.
This commit fixes it by watching more conditions from stdin and exiting upon
(G_IO_ERR | G_IO_HUP).
The similar was reported and fixed for the `more` command:
https://github.com/util-linux/util-linux/pull/2635
https://github.com/util-linux/util-linux/pull/2795
The `tail` command is also impacted but hasn't been fixed so far.
There's the relevant discussion here:
https://github.com/sudo-project/sudo/issues/367
Fixes T16
---
tools/crm_mon.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
Index: pacemaker-2.1.2+20211124.ada5c3b36/tools/crm_mon.c
===================================================================
--- pacemaker-2.1.2+20211124.ada5c3b36.orig/tools/crm_mon.c
+++ pacemaker-2.1.2+20211124.ada5c3b36/tools/crm_mon.c
@@ -1070,6 +1070,28 @@ detect_user_input(GIOChannel *channel, G
{
int c;
gboolean config_mode = FALSE;
+ gboolean rc = G_SOURCE_CONTINUE;
+
+ /* If the attached pty device (pseudo-terminal) has been closed/deleted,
+ * the condition (G_IO_IN | G_IO_ERR | G_IO_HUP) occurs.
+ * Exit with an error, otherwise the process would persist in the
+ * background and significantly raise the CPU usage.
+ */
+ if ((condition & G_IO_ERR) && (condition & G_IO_HUP)) {
+ rc = G_SOURCE_REMOVE;
+ clean_up(CRM_EX_IOERR);
+ }
+
+ /* The connection/fd has been closed. Refresh the screen and remove this
+ * event source hence ignore stdin.
+ */
+ if (condition & (G_IO_HUP | G_IO_NVAL)) {
+ rc = G_SOURCE_REMOVE;
+ }
+
+ if ((condition & G_IO_IN) == 0) {
+ return rc;
+ }
while (1) {
@@ -1175,7 +1197,7 @@ detect_user_input(GIOChannel *channel, G
refresh:
refresh_after_event(FALSE, TRUE);
- return TRUE;
+ return rc;
}
#endif
@@ -1685,7 +1707,8 @@ main(int argc, char **argv)
ncurses_winch_handler = NULL;
io_channel = g_io_channel_unix_new(STDIN_FILENO);
- g_io_add_watch(io_channel, G_IO_IN, detect_user_input, NULL);
+ g_io_add_watch(io_channel, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+ detect_user_input, NULL);
}
#endif
@@ -1697,10 +1720,6 @@ main(int argc, char **argv)
g_main_loop_run(mainloop);
g_main_loop_unref(mainloop);
- if (io_channel != NULL) {
- g_io_channel_shutdown(io_channel, TRUE, NULL);
- }
-
crm_info("Exiting %s", crm_system_name);
return clean_up(CRM_EX_OK);
@@ -2368,6 +2387,10 @@ clean_up(crm_exit_t exit_code)
/* Quitting crm_mon is much more complicated than it ought to be. */
/* (1) Close connections, free things, etc. */
+ if (io_channel != NULL) {
+ g_io_channel_shutdown(io_channel, TRUE, NULL);
+ }
+
clean_up_cib_connection();
clean_up_fencing_connection();
free(options.neg_location_prefix);