summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2003-07-08 08:40:56 +0000
committerGeorge Lebl <jirka@src.gnome.org>2003-07-08 08:40:56 +0000
commitf59c87e558652241ea40e5b674129e5f91d75389 (patch)
tree958bc573f214bfafc7008883fa85acd87f1936af
parent034edd9f55728ad515a46b4578f1cda4c10a44f5 (diff)
downloadgdm-f59c87e558652241ea40e5b674129e5f91d75389.tar.gz
If a greeter crashes within 10 seconds of the display being managed, we
Tue Jul 08 01:38:34 2003 George Lebl <jirka@5z.com> * daemon/gdm.[ch], daemon/slave.c, daemon/display.c: If a greeter crashes within 10 seconds of the display being managed, we assume it's unusable, pop up a dialog box and run a different greeter, and next time try the old one over again. This is mostly in place to catch gdmgreeter crashing (such as currently on my system with a libart bug). The user can then run the setup and select a different greeter or try to reinstall or upgrade or whatever. Better then a flickering display.
-rw-r--r--ChangeLog11
-rw-r--r--NEWS3
-rw-r--r--daemon/display.c2
-rw-r--r--daemon/gdm.c12
-rw-r--r--daemon/gdm.h4
-rw-r--r--daemon/slave.c42
6 files changed, 72 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d1fc940a..3edc1a2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Jul 08 01:38:34 2003 George Lebl <jirka@5z.com>
+
+ * daemon/gdm.[ch], daemon/slave.c, daemon/display.c: If a greeter
+ crashes within 10 seconds of the display being managed, we assume
+ it's unusable, pop up a dialog box and run a different greeter,
+ and next time try the old one over again. This is mostly in
+ place to catch gdmgreeter crashing (such as currently on my
+ system with a libart bug). The user can then run the setup and
+ select a different greeter or try to reinstall or upgrade
+ or whatever. Better then a flickering display.
+
Tue Jul 08 01:07:08 2003 George Lebl <jirka@5z.com>
* daemon/auth.c: minor leak fixes in case auth file writes fail
diff --git a/NEWS b/NEWS
index 053ba2e9..7d9b8667 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,9 @@ Ahh news...
- Fix DNS lookup stuff in XDMCP for places without DNS. Also cache
last result of DNS lookup to cut down traffic during session setup.
+- If a greeter crashes within 10 seconds of display start, try
+ running a different greeter (and telling the user that)
+
- Checking for free display numbers was only taking into account
servers listening on tcp.
diff --git a/daemon/display.c b/daemon/display.c
index b67fe3a0..1be22553 100644
--- a/daemon/display.c
+++ b/daemon/display.c
@@ -196,6 +196,8 @@ gdm_display_manage (GdmDisplay *d)
d->slavepid = 0;
gdm_sigchld_block_pop ();
+ d->managetime = time (NULL);
+
/* Fork slave process */
gdm_sigchld_block_push ();
gdm_sigterm_block_push ();
diff --git a/daemon/gdm.c b/daemon/gdm.c
index d710516a..0ac89498 100644
--- a/daemon/gdm.c
+++ b/daemon/gdm.c
@@ -1171,6 +1171,18 @@ gdm_cleanup_children (void)
status = DISPLAY_REMANAGE;
}
+ if (status == DISPLAY_GREETERFAILED) {
+ if (d->managetime + 10 >= time (NULL)) {
+ d->try_different_greeter = TRUE;
+ } else {
+ d->try_different_greeter = FALSE;
+ }
+ /* now just remanage */
+ status = DISPLAY_REMANAGE;
+ } else {
+ d->try_different_greeter = FALSE;
+ }
+
/* checkout if we can actually do stuff */
switch (status) {
case DISPLAY_REBOOT:
diff --git a/daemon/gdm.h b/daemon/gdm.h
index 1cfbb822..89ea8653 100644
--- a/daemon/gdm.h
+++ b/daemon/gdm.h
@@ -62,6 +62,7 @@
restart display */
#define DISPLAY_RUN_CHOOSER 30 /* Run chooser */
#define DISPLAY_XFAILED 64 /* X failed */
+#define DISPLAY_GREETERFAILED 65 /* greeter failed (crashed) */
#define DISPLAY_RESTARTGREETER 127 /* Restart greeter */
#define DISPLAY_RESTARTGDM 128 /* Restart GDM */
@@ -319,6 +320,7 @@ struct _GdmDisplay {
guint16 dispnum;
guint8 servstat;
time_t starttime;
+ time_t managetime;
guint8 type;
pid_t greetpid;
pid_t servpid;
@@ -344,6 +346,8 @@ struct _GdmDisplay {
time_t last_x_failed;
int x_faileds;
+ gboolean try_different_greeter;
+
gboolean disabled;
gboolean logged_in; /* TRUE if someone is logged in */
diff --git a/daemon/slave.c b/daemon/slave.c
index fc0cb420..022ab343 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -1811,7 +1811,37 @@ gdm_slave_greeter (void)
argv = ve_split (GdmGreeter);
else
argv = ve_split (GdmRemoteGreeter);
- if (GdmAddGtkModules && !(ve_string_empty(GdmGtkModulesList))) {
+
+ if (d->try_different_greeter) {
+ /* FIXME: we should also really be able to do standalone failsafe
+ login, but that requires some work and is perhaps an overkill. */
+ /* This should handle mostly the case where gdmgreeter is crashing
+ and we'd want to start gdmlogin for the user so that at least
+ something works instead of a flickering screen */
+ gdm_error_box (d,
+ GTK_MESSAGE_ERROR,
+ _("The greeter program appears to be crashing.\n"
+ "I will attempt to use a different one."));
+ if (strstr (argv[0], "gdmlogin") != NULL) {
+ /* in case it is gdmlogin that's crashing
+ try the graphical greeter for luck */
+ argv = g_new0 (char *, 2);
+ argv[0] = EXPANDED_BINDIR "/gdmgreeter";
+ argv[1] = NULL;
+ } else {
+ /* in all other cases, try the gdmlogin (standard greeter)
+ proggie */
+ argv = g_new0 (char *, 2);
+ argv[0] = EXPANDED_BINDIR "/gdmlogin";
+ argv[1] = NULL;
+ }
+ }
+
+ if (GdmAddGtkModules &&
+ !(ve_string_empty(GdmGtkModulesList)) &&
+ /* don't add modules if we're trying to prevent crashes,
+ perhaps it's the modules causing the problem in the first place */
+ ! d->try_different_greeter) {
gchar *modules = g_strdup_printf("--gtk-module=%s", GdmGtkModulesList);
execl (argv[0], argv[0], modules, NULL);
/* Something went wrong */
@@ -3387,7 +3417,15 @@ gdm_slave_child_handler (int sig)
WEXITSTATUS (status) == DISPLAY_RESTARTGDM)) {
gdm_slave_quick_exit (WEXITSTATUS (status));
} else {
- gdm_slave_quick_exit (DISPLAY_REMANAGE);
+ if (WIFSIGNALED (status) &&
+ (WTERMSIG (status) == SIGSEGV ||
+ WTERMSIG (status) == SIGABRT ||
+ WTERMSIG (status) == SIGPIPE ||
+ WTERMSIG (status) == SIGBUS)) {
+ gdm_slave_quick_exit (DISPLAY_GREETERFAILED);
+ } else {
+ gdm_slave_quick_exit (DISPLAY_REMANAGE);
+ }
}
} else if (pid != 0 && pid == d->sesspid) {
d->sesspid = 0;