Commit 9dbb5bfd authored by Brian Cameron's avatar Brian Cameron

A known issue with gdmdynamic is that when a display connects to the


        A known issue with gdmdynamic is that when a display connects to
        the server it generates the gdmdynamic "ADD" and "RELEASE" commands.
        On startup, hundreds of displays could send these commands at once
        and cause the server too be flooded with sockets requests.  Hammering
        the socket like this caused me to find and fix a number of problems
        that improve socket reliability for general GDM use.  I also enhanced
        gdmdynamic so it is more sensitive to the socket being busy and no
        longer overloads it, instead sleeping and retrying if necessary.  This
        allows gdmdynamic to work if there are hundreds of displays instead of
        just a dozen or so.

        * daemon/gdm.[ch]: Added new "SERVER_BUSY" sockets command so that
          gdmdynamic can sleep before starting new slaves if the daemon is
          already busy.
        * daemon/gdm-net.[ch]: Bump up MAX_CONNECTIONS from 10 to 15.  I notice
          that this improves performance significantly when hammering the
          daemon with connections.  Added better comments for this logic and
          now debug logs when a subconnection is thrown away.  New
          gdm_connection_is_server_busy function
        * daemon/display.c: Correct DYNAMIC_REMOVE so it works and fixes bug
          #326796.  Before it wasn't really removing the displays.
        * gui/gdmdynamic.c: Quite a bit of work to make gdmdynamic avoid
          flooding the server with sockets requests.  Now it sets sockets
          retries to 1 and manages sleeping and retries itself.
        * gui/gdmconfig.c: Added gdm_config_set_comm_retries so that slaves can
          specify how many retries they want the comm logic to use.
        * gui/gdmcomm.c: Now do_command returns NULL when it gets back "",
          which happens when a subconnection was dropped by the daemon.  This
          lets the slave try the connection again.   Now error messages are
          always logged, not just when debug is turned on.  Added
          gdmcomm_did_connection_fail and gdmcomm_set_allow_sleep so
          gdmdynamic can control the behavior of how the connection works.
        * gui/gdmcommon.c, gui/gdmchooser.c, gui/gdmlogin.c, gui/greeter/greeter.c:
          Fix gdm_common_fail so it doesn't generate compile errors when building
          with GCC.  Fixes bug #330480.
        * docs/C/gdm.xml: Cleaned up section that explains sockets commands so
          that they are in alphabetical order, added info about SERVER_BUSY
          and new gdmdynamic -s and -t options.
        * config/gdm.conf: Better description of how debug works, perhaps
          I just didn't like the word "spew".
---------------------------------------------------------------------
parent 441eb0bd
2006-02-09 Brian Cameron <brian.cameron@sun.com>
A known issue with gdmdynamic is that when a display connects to
the server it generates the gdmdynamic "ADD" and "RELEASE" commands.
On startup, hundreds of displays could send these commands at once
and cause the server too be flooded with sockets requests. Hammering
the socket like this caused me to find and fix a number of problems
that improve socket reliability for general GDM use. I also enhanced
gdmdynamic so it is more sensitive to the socket being busy and no
longer overloads it, instead sleeping and retrying if necessary. This
allows gdmdynamic to work if there are hundreds of displays instead of
just a dozen or so.
* daemon/gdm.[ch]: Added new "SERVER_BUSY" sockets command so that
gdmdynamic can sleep before starting new slaves if the daemon is
already busy.
* daemon/gdm-net.[ch]: Bump up MAX_CONNECTIONS from 10 to 15. I notice
that this improves performance significantly when hammering the
daemon with connections. Added better comments for this logic and
now debug logs when a subconnection is thrown away. New
gdm_connection_is_server_busy function
* daemon/display.c: Correct DYNAMIC_REMOVE so it works and fixes bug
#326796. Before it wasn't really removing the displays.
* gui/gdmdynamic.c: Quite a bit of work to make gdmdynamic avoid
flooding the server with sockets requests. Now it sets sockets
retries to 1 and manages sleeping and retries itself.
* gui/gdmconfig.c: Added gdm_config_set_comm_retries so that slaves can
specify how many retries they want the comm logic to use.
* gui/gdmcomm.c: Now do_command returns NULL when it gets back "",
which happens when a subconnection was dropped by the daemon. This
lets the slave try the connection again. Now error messages are
always logged, not just when debug is turned on. Added
gdmcomm_did_connection_fail and gdmcomm_set_allow_sleep so
gdmdynamic can control the behavior of how the connection works.
* gui/gdmcommon.c, gui/gdmchooser.c, gui/gdmlogin.c, gui/greeter/greeter.c:
Fix gdm_common_fail so it doesn't generate compile errors when building
with GCC. Fixes bug #330480.
* docs/C/gdm.xml: Cleaned up section that explains sockets commands so
that they are in alphabetical order, added info about SERVER_BUSY
and new gdmdynamic -s and -t options.
* config/gdm.conf: Better description of how debug works, perhaps
I just didn't like the word "spew".
2006-02-07 Brian Cameron <brian.cameron@sun.com> 2006-02-07 Brian Cameron <brian.cameron@sun.com>
* gui/gdmconfig.c: Return compiled in value if slave fails * gui/gdmconfig.c: Return compiled in value if slave fails
......
...@@ -498,9 +498,10 @@ Multicast=false ...@@ -498,9 +498,10 @@ Multicast=false
#AllowAdd=true #AllowAdd=true
[debug] [debug]
# This will enable debugging into the syslog, usually not necessary and it # This will cause GDM to send debugging information to the system log, which
# creates a LOT of spew of random stuff to the syslog. However it can be # will create a LOT of output. It is not recommended to turn this on for
# useful in determining when something is going very wrong. # normal use, but it can be useful to determine the cause when GDM is not
# working properly.
Enable=false Enable=false
# This will enable debug messages for accessibilty gesture listeners into the # This will enable debug messages for accessibilty gesture listeners into the
# syslog. This includes output about key events, mouse button events, and # syslog. This includes output about key events, mouse button events, and
......
...@@ -368,7 +368,6 @@ gdm_display_manage (GdmDisplay *d) ...@@ -368,7 +368,6 @@ gdm_display_manage (GdmDisplay *d)
* *
* Stop services for a display * Stop services for a display
*/ */
void void
gdm_display_unmanage (GdmDisplay *d) gdm_display_unmanage (GdmDisplay *d)
{ {
...@@ -387,7 +386,7 @@ gdm_display_unmanage (GdmDisplay *d) ...@@ -387,7 +386,7 @@ gdm_display_unmanage (GdmDisplay *d)
whack_old_slave (d, TRUE /* kill_connection */); whack_old_slave (d, TRUE /* kill_connection */);
d->dispstat = DISPLAY_DEAD; d->dispstat = DISPLAY_DEAD;
if (d->type != TYPE_STATIC) if (d->type != TYPE_STATIC || d->removeconf)
gdm_display_dispose (d); gdm_display_dispose (d);
gdm_debug ("gdm_display_unmanage: Display stopped"); gdm_debug ("gdm_display_unmanage: Display stopped");
......
...@@ -37,8 +37,38 @@ ...@@ -37,8 +37,38 @@
#include "gdm-net.h" #include "gdm-net.h"
#include "gdmconfig.h" #include "gdmconfig.h"
/* Kind of a weird setup, new connections whack old connections */ /*
#define MAX_CONNECTIONS 10 * Kind of a weird setup, new connections whack old connections.
*
* We may want to allow tuning of the max connections, since
* this number means that only a certain number of slaves can
* talk to the daemon at once. Note that since new connections
* whack old connections, this tends to cause traffic problems
* if the daemon is really being hammered.
*
* This is because the slaves retry a failed connection 5 times,
* though they are at least smart enough to sleep 1 second
* between retries if the connection failed on the connect()
* call. But, this means that throwing off a connection causes
* that slave to come back in another second and try to
* connect again. So if the daemon is really being hammered,
* this just causes more traffic problems. It's really faster
* to let each connection finish.
*
* This may cause problems for some setups (perhaps terminal
* servers) where lots of connections may hit the server at once
* and 15 connections may not be enough (especially since the
* console login screen may also be using one of them). Perhaps
* this number should be in gdm.conf so it can be tuned by the
* end user?
*
* If, when you turn on debug, you notice messages like this
* in the log, "Closing connection, x subconnections reached"
* and some slaves are not working properly, then bumping this
* number up is probably a reasonable fix if you can't simply
* reduce the socket load the daemon must handle.
*/
#define MAX_CONNECTIONS 15
struct _GdmConnection { struct _GdmConnection {
int fd; int fd;
...@@ -74,6 +104,21 @@ struct _GdmConnection { ...@@ -74,6 +104,21 @@ struct _GdmConnection {
GdmDisplay *disp; GdmDisplay *disp;
}; };
int
gdm_connection_is_server_busy (GdmConnection *conn) {
int max_connections = MAX_CONNECTIONS;
if (conn->n_subconnections >= (max_connections / 2)) {
gdm_debug ("Connections is %d, max is %d, busy TRUE",
conn->n_subconnections, max_connections);
return TRUE;
} else {
gdm_debug ("Connections is %d, max is %d, busy FALSE",
conn->n_subconnections, max_connections);
return FALSE;
}
}
static gboolean static gboolean
close_if_needed (GdmConnection *conn, GIOCondition cond, gboolean error) close_if_needed (GdmConnection *conn, GIOCondition cond, gboolean error)
{ {
...@@ -200,12 +245,13 @@ gdm_socket_handler (GIOChannel *source, ...@@ -200,12 +245,13 @@ gdm_socket_handler (GIOChannel *source,
GIOCondition cond, GIOCondition cond,
gpointer data) gpointer data)
{ {
int fd;
GIOChannel *unixchan; GIOChannel *unixchan;
GdmConnection *conn = data; GdmConnection *conn = data;
GdmConnection *newconn; GdmConnection *newconn;
struct sockaddr_un addr; struct sockaddr_un addr;
socklen_t addr_size = sizeof (addr); socklen_t addr_size = sizeof (addr);
int fd;
int max_connections;
if ( ! (cond & G_IO_IN)) if ( ! (cond & G_IO_IN))
return TRUE; return TRUE;
...@@ -240,8 +286,18 @@ gdm_socket_handler (GIOChannel *source, ...@@ -240,8 +286,18 @@ gdm_socket_handler (GIOChannel *source,
conn->subconnections = g_list_append (conn->subconnections, newconn); conn->subconnections = g_list_append (conn->subconnections, newconn);
conn->n_subconnections++; conn->n_subconnections++;
if (conn->n_subconnections > MAX_CONNECTIONS) {
gdm_debug ("Closing connection, %d subconnections reached", MAX_CONNECTIONS); /*
* When dynamix servers is turned on, the daemon can be flooded with
* requests and closing a subconnection will typically make the client
* just try and connect again, and worsen the flooding problem. When
* using dynamic servers, allow more clients to connect at once.
*/
max_connections = MAX_CONNECTIONS;
if (conn->n_subconnections > max_connections) {
gdm_debug ("Closing connection, %d subconnections reached",
max_connections);
GdmConnection *old = conn->subconnections->data; GdmConnection *old = conn->subconnections->data;
conn->subconnections = conn->subconnections =
g_list_remove (conn->subconnections, old); g_list_remove (conn->subconnections, old);
......
...@@ -76,16 +76,17 @@ void gdm_connection_set_user_flags (GdmConnection *conn, ...@@ -76,16 +76,17 @@ void gdm_connection_set_user_flags (GdmConnection *conn,
gdm_connection_set_user_flags (conn, _flags); \ gdm_connection_set_user_flags (conn, _flags); \
} }
GdmDisplay * gdm_connection_get_display (GdmConnection *conn); GdmDisplay * gdm_connection_get_display (GdmConnection *conn);
void gdm_connection_set_display (GdmConnection *conn, void gdm_connection_set_display (GdmConnection *conn,
GdmDisplay *disp); GdmDisplay *disp);
void gdm_kill_subconnections_with_display (GdmConnection *conn, int gdm_connection_is_server_busy (GdmConnection *conn);
GdmDisplay *disp); void gdm_kill_subconnections_with_display (GdmConnection *conn,
GdmDisplay *disp);
int gdm_connection_get_message_count (GdmConnection *conn); int gdm_connection_get_message_count (GdmConnection *conn);
void gdm_connection_close (GdmConnection *conn); void gdm_connection_close (GdmConnection *conn);
#endif /* GDM_NET_H */ #endif /* GDM_NET_H */
......
...@@ -76,10 +76,10 @@ extern GSList *displays; ...@@ -76,10 +76,10 @@ extern GSList *displays;
/* Local functions */ /* Local functions */
static void gdm_handle_message (GdmConnection *conn, static void gdm_handle_message (GdmConnection *conn,
const char *msg, const gchar *msg,
gpointer data); gpointer data);
static void gdm_handle_user_message (GdmConnection *conn, static void gdm_handle_user_message (GdmConnection *conn,
const char *msg, const gchar *msg,
gpointer data); gpointer data);
static void gdm_daemonify (void); static void gdm_daemonify (void);
static void gdm_safe_restart (void); static void gdm_safe_restart (void);
...@@ -87,13 +87,13 @@ static void gdm_try_logout_action (GdmDisplay *disp); ...@@ -87,13 +87,13 @@ static void gdm_try_logout_action (GdmDisplay *disp);
static void gdm_restart_now (void); static void gdm_restart_now (void);
static void handle_flexi_server (GdmConnection *conn, static void handle_flexi_server (GdmConnection *conn,
int type, int type,
const char *server, const gchar *server,
gboolean handled, gboolean handled,
gboolean chooser, gboolean chooser,
const char *xnest_disp, const gchar *xnest_disp,
uid_t xnest_uid, uid_t xnest_uid,
const char *xnest_auth_file, const gchar *xnest_auth_file,
const char *xnest_cookie); const gchar *xnest_cookie);
/* Global vars */ /* Global vars */
gint xdmcp_sessions = 0; /* Number of remote sessions */ gint xdmcp_sessions = 0; /* Number of remote sessions */
...@@ -118,10 +118,10 @@ GdmConnection *pipeconn = NULL; /* slavepipe (handled just like Fifo for compati ...@@ -118,10 +118,10 @@ GdmConnection *pipeconn = NULL; /* slavepipe (handled just like Fifo for compati
GdmConnection *unixconn = NULL; /* UNIX Socket connection */ GdmConnection *unixconn = NULL; /* UNIX Socket connection */
int slave_fifo_pipe_fd = -1; /* the slavepipe connection */ int slave_fifo_pipe_fd = -1; /* the slavepipe connection */
unsigned char *gdm_global_cookie = NULL; unsigned char *gdm_global_cookie = NULL;
unsigned char *gdm_global_bcookie = NULL; unsigned char *gdm_global_bcookie = NULL;
char *gdm_charset = NULL; gchar *gdm_charset = NULL;
int gdm_normal_runlevel = -1; /* runlevel on linux that gdm was started in */ int gdm_normal_runlevel = -1; /* runlevel on linux that gdm was started in */
...@@ -141,7 +141,7 @@ gboolean gdm_in_final_cleanup = FALSE; ...@@ -141,7 +141,7 @@ gboolean gdm_in_final_cleanup = FALSE;
GdmLogoutAction safe_logout_action = GDM_LOGOUT_ACTION_NONE; GdmLogoutAction safe_logout_action = GDM_LOGOUT_ACTION_NONE;
/* set in the main function */ /* set in the main function */
char **stored_argv = NULL; gchar **stored_argv = NULL;
int stored_argc = 0; int stored_argc = 0;
extern gchar *config_file; extern gchar *config_file;
...@@ -741,8 +741,11 @@ gdm_cleanup_children (void) ...@@ -741,8 +741,11 @@ gdm_cleanup_children (void)
if (d->servpid > 1) if (d->servpid > 1)
kill (d->servpid, SIGTERM); kill (d->servpid, SIGTERM);
d->servpid = 0; d->servpid = 0;
if (gdm_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS)) /* XXX - This needs to be handled better */
gdm_server_whack_lockfile (d); if (gdm_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS)) {
/* XXX - This needs to be handled better */
gdm_server_whack_lockfile (d);
}
/* race avoider */ /* race avoider */
gdm_sleep_no_signal (1); gdm_sleep_no_signal (1);
...@@ -2487,11 +2490,11 @@ dehex_cookie (const char *cookie, int *len) ...@@ -2487,11 +2490,11 @@ dehex_cookie (const char *cookie, int *len)
/* This runs as the user who owns the file */ /* This runs as the user who owns the file */
static gboolean static gboolean
check_cookie (const char *file, const char *disp, const char *cookie) check_cookie (const gchar *file, const gchar *disp, const gchar *cookie)
{ {
Xauth *xa; Xauth *xa;
char *number; gchar *number;
char *bcookie; gchar *bcookie;
int cookielen; int cookielen;
gboolean ret = FALSE; gboolean ret = FALSE;
int cnt = 0; int cnt = 0;
...@@ -2538,15 +2541,15 @@ check_cookie (const char *file, const char *disp, const char *cookie) ...@@ -2538,15 +2541,15 @@ check_cookie (const char *file, const char *disp, const char *cookie)
} }
static void static void
handle_flexi_server (GdmConnection *conn, int type, const char *server, handle_flexi_server (GdmConnection *conn, int type, const gchar *server,
gboolean handled, gboolean handled,
gboolean chooser, gboolean chooser,
const char *xnest_disp, uid_t xnest_uid, const gchar *xnest_disp, uid_t xnest_uid,
const char *xnest_auth_file, const gchar *xnest_auth_file,
const char *xnest_cookie) const gchar *xnest_cookie)
{ {
GdmDisplay *display; GdmDisplay *display;
char *bin; gchar *bin;
uid_t server_uid = 0; uid_t server_uid = 0;
gdm_debug ("server: '%s'", server); gdm_debug ("server: '%s'", server);
...@@ -2648,7 +2651,7 @@ handle_flexi_server (GdmConnection *conn, int type, const char *server, ...@@ -2648,7 +2651,7 @@ handle_flexi_server (GdmConnection *conn, int type, const char *server,
if (type == TYPE_FLEXI_XNEST) { if (type == TYPE_FLEXI_XNEST) {
GdmDisplay *parent; GdmDisplay *parent;
char *disp, *p; gchar *disp, *p;
gdm_assert (xnest_disp != NULL); gdm_assert (xnest_disp != NULL);
disp = g_strdup (xnest_disp); disp = g_strdup (xnest_disp);
...@@ -2693,12 +2696,13 @@ handle_flexi_server (GdmConnection *conn, int type, const char *server, ...@@ -2693,12 +2696,13 @@ handle_flexi_server (GdmConnection *conn, int type, const char *server,
} }
static void static void
handle_dynamic_server (GdmConnection *conn, int type, char *key) handle_dynamic_server (GdmConnection *conn, int type, gchar *key)
{ {
GdmDisplay *disp; GdmDisplay *disp;
int disp_num; int disp_num;
char *full; gchar *msg;
char *val; gchar *full;
gchar *val;
if (!(gdm_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS))) { if (!(gdm_get_value_bool (GDM_KEY_DYNAMIC_XSERVERS))) {
gdm_connection_write (conn, "ERROR 200 Dynamic Displays not allowed\n"); gdm_connection_write (conn, "ERROR 200 Dynamic Displays not allowed\n");
...@@ -2711,8 +2715,13 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key) ...@@ -2711,8 +2715,13 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key)
return; return;
} }
if ((key == NULL) || (!(isdigit (*key)))) { if (key == NULL) {
gdm_connection_write (conn, "ERROR 1 Bad display number\n"); gdm_connection_write (conn, "ERROR 1 Bad display number <NULL>\n");
return;
} else if ( !(isdigit (*key))) {
msg = g_strdup_printf ("ERROR 1 Bad display number <%s>\n", key);
gdm_connection_write (conn, msg);
g_free (msg);
return; return;
} }
disp_num = atoi (key); disp_num = atoi (key);
...@@ -2749,7 +2758,7 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key) ...@@ -2749,7 +2758,7 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key)
if (disp_num > gdm_get_high_display_num ()) if (disp_num > gdm_get_high_display_num ())
gdm_set_high_display_num (disp_num); gdm_set_high_display_num (disp_num);
gdm_connection_write (conn, "OK\n"); gdm_connection_write (conn, "OK\n");
return; return;
} }
...@@ -2769,7 +2778,8 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key) ...@@ -2769,7 +2778,8 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key)
} }
} }
gdm_connection_write (conn, "ERROR 1 Bad display number\n"); msg = g_strdup_printf ("ERROR 1 Bad display number <%d>\n", disp_num);
gdm_connection_write (conn, msg);
return; return;
} }
...@@ -2777,6 +2787,7 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key) ...@@ -2777,6 +2787,7 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key)
/* cause the newly configured X servers to actually run */ /* cause the newly configured X servers to actually run */
GSList *li; GSList *li;
GSList *nli; GSList *nli;
gboolean found = FALSE;
for (li = displays; li != NULL; li = nli) { for (li = displays; li != NULL; li = nli) {
GdmDisplay *disp = li->data; GdmDisplay *disp = li->data;
...@@ -2788,17 +2799,24 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key) ...@@ -2788,17 +2799,24 @@ handle_dynamic_server (GdmConnection *conn, int type, char *key)
if ( ! gdm_display_manage (disp)) { if ( ! gdm_display_manage (disp)) {
gdm_display_unmanage (disp); gdm_display_unmanage (disp);
} }
found = TRUE;
} }
} }
gdm_connection_write (conn, "OK\n"); if (found)
gdm_connection_write (conn, "OK\n");
else {
msg = g_strdup_printf ("ERROR 1 Bad display number <%d>\n", disp_num);
gdm_connection_write (conn, msg);
}
/* Now we wait for the server to start up (or not) */ /* Now we wait for the server to start up (or not) */
return; return;
} }
} }
static void static void
gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) gdm_handle_user_message (GdmConnection *conn, const gchar *msg, gpointer data)
{ {
gdm_debug ("Handling user message: '%s'", msg); gdm_debug ("Handling user message: '%s'", msg);
...@@ -2812,7 +2830,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2812,7 +2830,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
if (strncmp (msg, GDM_SUP_AUTH_LOCAL " ", if (strncmp (msg, GDM_SUP_AUTH_LOCAL " ",
strlen (GDM_SUP_AUTH_LOCAL " ")) == 0) { strlen (GDM_SUP_AUTH_LOCAL " ")) == 0) {
GSList *li; GSList *li;
char *cookie = g_strdup gchar *cookie = g_strdup
(&msg[strlen (GDM_SUP_AUTH_LOCAL " ")]); (&msg[strlen (GDM_SUP_AUTH_LOCAL " ")]);
g_strstrip (cookie); g_strstrip (cookie);
if (strlen (cookie) != 16*2) /* 16 bytes in hex form */ { if (strlen (cookie) != 16*2) /* 16 bytes in hex form */ {
...@@ -2839,7 +2857,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2839,7 +2857,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} }
if (gdm_global_cookie != NULL && if (gdm_global_cookie != NULL &&
g_ascii_strcasecmp ((char *) gdm_global_cookie, cookie) == 0) { g_ascii_strcasecmp ((gchar *) gdm_global_cookie, cookie) == 0) {
g_free (cookie); g_free (cookie);
GDM_CONNECTION_SET_USER_FLAG GDM_CONNECTION_SET_USER_FLAG
(conn, GDM_SUP_FLAG_AUTH_GLOBAL); (conn, GDM_SUP_FLAG_AUTH_GLOBAL);
...@@ -2870,8 +2888,8 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2870,8 +2888,8 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
NULL, 0, NULL, NULL); NULL, 0, NULL, NULL);
} else if (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ", } else if (strncmp (msg, GDM_SUP_FLEXI_XSERVER " ",
strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0) { strlen (GDM_SUP_FLEXI_XSERVER " ")) == 0) {
char *name; gchar *name;
const char *command = NULL; const gchar *command = NULL;
GdmXserver *svr; GdmXserver *svr;
/* Only allow locally authenticated connections */ /* Only allow locally authenticated connections */
...@@ -2916,7 +2934,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2916,7 +2934,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
NULL, 0, NULL, NULL); NULL, 0, NULL, NULL);
} else if (strncmp (msg, GDM_SUP_FLEXI_XNEST " ", } else if (strncmp (msg, GDM_SUP_FLEXI_XNEST " ",
strlen (GDM_SUP_FLEXI_XNEST " ")) == 0) { strlen (GDM_SUP_FLEXI_XNEST " ")) == 0) {
char *dispname = NULL, *xauthfile = NULL, *cookie = NULL; gchar *dispname = NULL, *xauthfile = NULL, *cookie = NULL;
uid_t uid; uid_t uid;
extract_dispname_uid_xauthfile_cookie (msg, &dispname, &uid, extract_dispname_uid_xauthfile_cookie (msg, &dispname, &uid,
...@@ -2953,7 +2971,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2953,7 +2971,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
strlen (GDM_SUP_CONSOLE_SERVERS)) == 0)) { strlen (GDM_SUP_CONSOLE_SERVERS)) == 0)) {
GString *retMsg; GString *retMsg;
GSList *li; GSList *li;
const char *sep = " "; const gchar *sep = " ";
char *key; char *key;
int msgLen=0; int msgLen=0;
...@@ -2993,7 +3011,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -2993,7 +3011,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strcmp (msg, GDM_SUP_ALL_SERVERS) == 0) { } else if (strcmp (msg, GDM_SUP_ALL_SERVERS) == 0) {
GString *msg; GString *msg;
GSList *li; GSList *li;
const char *sep = " "; const gchar *sep = " ";
msg = g_string_new ("OK"); msg = g_string_new ("OK");
for (li = displays; li != NULL; li = li->next) { for (li = displays; li != NULL; li = li->next) {
...@@ -3018,9 +3036,9 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3018,9 +3036,9 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strncmp (msg, GDM_SUP_GET_SERVER_DETAILS " ", } else if (strncmp (msg, GDM_SUP_GET_SERVER_DETAILS " ",
strlen (GDM_SUP_GET_SERVER_DETAILS " ")) == 0) { strlen (GDM_SUP_GET_SERVER_DETAILS " ")) == 0) {
const char *server = &msg[strlen (GDM_SUP_GET_SERVER_DETAILS " ")]; const gchar *server = &msg[strlen (GDM_SUP_GET_SERVER_DETAILS " ")];
gchar **splitstr = g_strsplit (server, " ", 2); gchar **splitstr = g_strsplit (server, " ", 2);
GdmXserver *svr = gdm_find_xserver ((char *)splitstr[0]); GdmXserver *svr = gdm_find_xserver ((gchar *)splitstr[0]);
if (svr != NULL) { if (svr != NULL) {
if (g_strcasecmp (splitstr[1], "ID") == 0) if (g_strcasecmp (splitstr[1], "ID") == 0)
...@@ -3066,7 +3084,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3066,7 +3084,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strcmp (msg, GDM_SUP_GREETERPIDS) == 0) { } else if (strcmp (msg, GDM_SUP_GREETERPIDS) == 0) {
GString *msg; GString *msg;
GSList *li; GSList *li;
const char *sep = " "; const gchar *sep = " ";
msg = g_string_new ("OK"); msg = g_string_new ("OK");
for (li = displays; li != NULL; li = li->next) { for (li = displays; li != NULL; li = li->next) {
...@@ -3082,7 +3100,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3082,7 +3100,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
g_string_free (msg, TRUE); g_string_free (msg, TRUE);
} else if (strncmp (msg, GDM_SUP_UPDATE_CONFIG " ", } else if (strncmp (msg, GDM_SUP_UPDATE_CONFIG " ",
strlen (GDM_SUP_UPDATE_CONFIG " ")) == 0) { strlen (GDM_SUP_UPDATE_CONFIG " ")) == 0) {
const char *key = const gchar *key =
&msg[strlen (GDM_SUP_UPDATE_CONFIG " ")]; &msg[strlen (GDM_SUP_UPDATE_CONFIG " ")];
if (! gdm_update_config ((gchar *)key)) if (! gdm_update_config ((gchar *)key))
...@@ -3091,7 +3109,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3091,7 +3109,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
gdm_connection_write (conn, "OK\n"); gdm_connection_write (conn, "OK\n");
} else if (strncmp (msg, GDM_SUP_GET_CONFIG " ", } else if (strncmp (msg, GDM_SUP_GET_CONFIG " ",
strlen (GDM_SUP_GET_CONFIG " ")) == 0) { strlen (GDM_SUP_GET_CONFIG " ")) == 0) {
const char *key = &msg[strlen (GDM_SUP_GET_CONFIG " ")]; const gchar *key = &msg[strlen (GDM_SUP_GET_CONFIG " ")];
gchar *retval; gchar *retval;
static gboolean done_prefetch = FALSE; static gboolean done_prefetch = FALSE;
...@@ -3125,7 +3143,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3125,7 +3143,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
gdm_connection_printf (conn, "OK %s\n", config_file); gdm_connection_printf (conn, "OK %s\n", config_file);
g_string_free (msg, TRUE); g_string_free (msg, TRUE);
} else if (strcmp (msg, GDM_SUP_QUERY_LOGOUT_ACTION) == 0) { } else if (strcmp (msg, GDM_SUP_QUERY_LOGOUT_ACTION) == 0) {
const char *sep = " "; const gchar *sep = " ";
GdmDisplay *disp; GdmDisplay *disp;
GdmLogoutAction logout_action; GdmLogoutAction logout_action;
GString *msg; GString *msg;
...@@ -3175,7 +3193,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3175,7 +3193,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
g_string_free (msg, TRUE); g_string_free (msg, TRUE);
} else if (strncmp (msg, GDM_SUP_SET_LOGOUT_ACTION " ", } else if (strncmp (msg, GDM_SUP_SET_LOGOUT_ACTION " ",
strlen (GDM_SUP_SET_LOGOUT_ACTION " ")) == 0) { strlen (GDM_SUP_SET_LOGOUT_ACTION " ")) == 0) {
const char *action = const gchar *action =
&msg[strlen (GDM_SUP_SET_LOGOUT_ACTION " ")]; &msg[strlen (GDM_SUP_SET_LOGOUT_ACTION " ")];
GdmDisplay *disp; GdmDisplay *disp;
gboolean was_ok = FALSE; gboolean was_ok = FALSE;
...@@ -3227,7 +3245,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3227,7 +3245,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} }
} else if (strncmp (msg, GDM_SUP_SET_SAFE_LOGOUT_ACTION " ", } else if (strncmp (msg, GDM_SUP_SET_SAFE_LOGOUT_ACTION " ",
strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")) == 0) { strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")) == 0) {
const char *action = const gchar *action =
&msg[strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")]; &msg[strlen (GDM_SUP_SET_SAFE_LOGOUT_ACTION " ")];
GdmDisplay *disp; GdmDisplay *disp;
gboolean was_ok = FALSE; gboolean was_ok = FALSE;
...@@ -3328,7 +3346,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3328,7 +3346,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
#endif #endif
} else if (strncmp (msg, GDM_SUP_ADD_DYNAMIC_DISPLAY " ", } else if (strncmp (msg, GDM_SUP_ADD_DYNAMIC_DISPLAY " ",
strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")) == 0) { strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")) == 0) {
char *key; gchar *key;
key = g_strdup (&msg[strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")]); key = g_strdup (&msg[strlen (GDM_SUP_ADD_DYNAMIC_DISPLAY " ")]);
g_strstrip (key); g_strstrip (key);
...@@ -3337,7 +3355,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3337,7 +3355,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strncmp (msg, GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ", } else if (strncmp (msg, GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ",
strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")) == 0) { strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")) == 0) {
char *key; gchar *key;
key = g_strdup (&msg[strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")]); key = g_strdup (&msg[strlen (GDM_SUP_REMOVE_DYNAMIC_DISPLAY " ")]);
g_strstrip (key); g_strstrip (key);
...@@ -3347,7 +3365,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3347,7 +3365,7 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strncmp (msg, GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ", } else if (strncmp (msg, GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ",
strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")) == 0) { strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")) == 0) {
char *key; gchar *key;
key = g_strdup (&msg[strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")]); key = g_strdup (&msg[strlen (GDM_SUP_RELEASE_DYNAMIC_DISPLAYS " ")]);
g_strstrip (key); g_strstrip (key);
...@@ -3356,6 +3374,11 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data) ...@@ -3356,6 +3374,11 @@ gdm_handle_user_message (GdmConnection *conn, const char *msg, gpointer data)
} else if (strcmp (msg, GDM_SUP_VERSION) == 0) { } else if (strcmp (msg, GDM_SUP_VERSION) == 0) {
gdm_connection_write (conn, "GDM " VERSION "\n"); gdm_connection_write (conn, "GDM " VERSION "\n");
} else if (strcmp (msg, GDM_SUP_SERVER_BUSY) == 0) {
if (gdm_connection_is_server_busy (unixconn))
gdm_connection_write (conn, "OK true\n");