summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2009-07-24 14:41:48 -0400
committerRay Strode <rstrode@redhat.com>2011-05-19 16:51:07 -0400
commit924a1fc94005a90a375da9a1eee03778118429c4 (patch)
tree212118ff2253b176ea2c4d8c41d1ee4453060768 /common
parent7efd04ace421b909f0de7d031e8616c98f569b83 (diff)
downloadgdm-924a1fc94005a90a375da9a1eee03778118429c4.tar.gz
daemon: kill stuck processes if they don't die on term
Some PAM modules are really slow to shut down. We need to handle them being slow to shut down better, (by not blocking login on them shutting down etc), but in the mean time force them to die immediately.
Diffstat (limited to 'common')
-rw-r--r--common/gdm-common.c48
-rw-r--r--common/gdm-common.h2
2 files changed, 47 insertions, 3 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c
index de807000..7a4e26d8 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -93,13 +93,25 @@ gdm_get_pwent_for_name (const char *name,
}
int
-gdm_wait_on_pid (int pid)
+gdm_wait_on_and_kill_pid (int pid,
+ int timeout)
{
int status;
-
+ int ret;
+ int num_tries;
+ int flags;
+
+ if (timeout > 0) {
+ flags = WNOHANG;
+ num_tries = 10 * timeout;
+ } else {
+ flags = 0;
+ num_tries = 0;
+ }
wait_again:
errno = 0;
- if (waitpid (pid, &status, 0) < 0) {
+ ret = waitpid (pid, &status, flags);
+ if (ret < 0) {
if (errno == EINTR) {
goto wait_again;
} else if (errno == ECHILD) {
@@ -107,6 +119,30 @@ gdm_wait_on_pid (int pid)
} else {
g_debug ("GdmCommon: waitpid () should not fail");
}
+ } else if (ret == 0) {
+ num_tries--;
+
+ if (num_tries > 0) {
+ g_usleep (G_USEC_PER_SEC / 10);
+ } else {
+ char *path;
+ char *command;
+
+ path = g_strdup_printf ("/proc/%ld/cmdline", (long) pid);
+ if (g_file_get_contents (path, &command, NULL, NULL)) {;
+ g_debug ("GdmCommon: process (pid:%d, command '%s') isn't dying, now killing it.",
+ (int) pid, command);
+ g_free (command);
+ } else {
+ g_debug ("GdmCommon: process (pid:%d) isn't dying, now killing it.",
+ (int) pid);
+ }
+ g_free (path);
+
+ kill (pid, SIGKILL);
+ flags = 0;
+ }
+ goto wait_again;
}
g_debug ("GdmCommon: process (pid:%d) done (%s:%d)",
@@ -122,6 +158,12 @@ gdm_wait_on_pid (int pid)
}
int
+gdm_wait_on_pid (int pid)
+{
+ return gdm_wait_on_and_kill_pid (pid, 0);
+}
+
+int
gdm_signal_pid (int pid,
int signal)
{
diff --git a/common/gdm-common.h b/common/gdm-common.h
index 8faeda5c..06300c8f 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -34,6 +34,8 @@ gboolean gdm_is_version_unstable (void);
void gdm_set_fatal_warnings_if_unstable (void);
int gdm_wait_on_pid (int pid);
+int gdm_wait_on_and_kill_pid (int pid,
+ int timeout);
int gdm_signal_pid (int pid,
int signal);
gboolean gdm_get_pwent_for_name (const char *name,