Commit c468be80 authored by Keith Packard's avatar Keith Packard Committed by Mike Gabriel

os: Use NotifyFd interface for listen descriptors

Bundle X.org backport of these commits: commit 7ea64fb4374504bd3d524fc08c90efdab9f253ea Author: Alan Coopersmith <alan.coopersmith@oracle.com> Date: Mon Mar 9 09:55:57 2015 -0700 Clear ListenTransConns entries in CloseWellKnownConnections Since _XSERVTransClose frees the connection pointer passed to it, remove that pointer from the array, so we don't try to double free it if we come back into CloseWellKnownConnections again. Should fix https://bugzilla.yoctoproject.org/show_bug.cgi?id=6665 in which the shutdown section of the main() loop called CloseWellKnownConnections() and then moved on to ddxGiveUp(), which failed to release the VT and thus called AbortServer(), which called CloseWellKnownConnections() again. Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: 's avatarAdam Jackson <ajax@redhat.com> Signed-off-by: 's avatarPeter Hutterer <peter.hutterer@who-t.net> commit 7b02f0b87ec2fa0cc5a65307a1fd55c671cec884 Author: Keith Packard <keithp@keithp.com> Date: Wed Nov 11 22:02:17 2015 -0800 os: Use NotifyFd interface for listen descriptors Replace the custom path for dealing with new incoming connections with the general-purpose NotifyFd API. Reviewed-by: 's avatarAdam Jackson <ajax@redhat.com> Signed-off-by: 's avatarKeith Packard <keithp@keithp.com> commit ba71b69f94f00a6f6910597185610668e79c10be Author: Alan Coopersmith <alan.coopersmith@oracle.com> Date: Fri Jan 1 17:34:41 2016 -0800 Avoid segfault in CloseWellKnownConnections when using -displayfd When -displayfd is looping through the possible display ids to use, if it can't open all the listening sockets for one (say when :0 is already in use), it calls CloseWellKnownConnections to close all the ListenTransConns entries before the point that ListenTransFds was allocated & initialized, so CloseWellKnownConnections would segfault trying to read entries from a NULL ListenTransFds pointer. Introduced by commit 7b02f0b8 Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: 's avatarKeith Packard <keithp@keithp.com> Backported-to-NX-by: 's avatarMike Gabriel <mike.gabriel@das-netzwerkteam.de>
parent 3be144ff
...@@ -137,10 +137,6 @@ extern char *ClientAuthorized( ...@@ -137,10 +137,6 @@ extern char *ClientAuthorized(
unsigned int /*string_n*/, unsigned int /*string_n*/,
char* /*auth_string*/); char* /*auth_string*/);
extern Bool EstablishNewConnections(
ClientPtr /*clientUnused*/,
void * /*closure*/);
extern void CheckConnections(void); extern void CheckConnections(void);
extern void CloseDownConnection(ClientPtr /*client*/); extern void CloseDownConnection(ClientPtr /*client*/);
......
...@@ -495,10 +495,6 @@ WaitForSomething(int *pClientsReady) ...@@ -495,10 +495,6 @@ WaitForSomething(int *pClientsReady)
} }
XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
if (XFD_ANYSET(&tmp_set))
QueueWorkProc(EstablishNewConnections, NULL,
(void *)&LastSelectMask);
XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
......
...@@ -123,7 +123,6 @@ SOFTWARE. ...@@ -123,7 +123,6 @@ SOFTWARE.
int lastfdesc; /* maximum file descriptor */ int lastfdesc; /* maximum file descriptor */
fd_set WellKnownConnections; /* Listener mask */
fd_set NotifyReadFds; /* mask for other file descriptors */ fd_set NotifyReadFds; /* mask for other file descriptors */
fd_set NotifyWriteFds; /* mask for other write file descriptors */ fd_set NotifyWriteFds; /* mask for other write file descriptors */
fd_set AllSockets; /* select on this */ fd_set AllSockets; /* select on this */
...@@ -152,6 +151,9 @@ static fd_set SavedAllSockets; ...@@ -152,6 +151,9 @@ static fd_set SavedAllSockets;
static fd_set SavedClientsWithInput; static fd_set SavedClientsWithInput;
int GrabInProgress = 0; int GrabInProgress = 0;
static void
QueueNewConnections(int curconn, int ready, void *data);
#if !defined(WIN32) #if !defined(WIN32)
int *ConnectionTranslation = NULL; int *ConnectionTranslation = NULL;
#else #else
...@@ -407,8 +409,6 @@ CreateWellKnownSockets(void) ...@@ -407,8 +409,6 @@ CreateWellKnownSockets(void)
ClearConnectionTranslation(); ClearConnectionTranslation();
#endif #endif
FD_ZERO (&WellKnownConnections);
/* display is initialized to "0" by main(). It is then set to the display /* display is initialized to "0" by main(). It is then set to the display
* number if specified on the command line. */ * number if specified on the command line. */
if (NoListenAll) { if (NoListenAll) {
...@@ -442,13 +442,13 @@ CreateWellKnownSockets(void) ...@@ -442,13 +442,13 @@ CreateWellKnownSockets(void)
int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]); int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
ListenTransFds[i] = fd; ListenTransFds[i] = fd;
FD_SET(fd, &WellKnownConnections); SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
if (!_XSERVTransIsLocal(ListenTransConns[i])) if (!_XSERVTransIsLocal(ListenTransConns[i]))
DefineSelf (fd); DefineSelf (fd);
} }
if (!XFD_ANYSET (&WellKnownConnections) && !NoListenAll) if (ListenTransCount == 0 && !NoListenAll)
FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running"); FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running");
#if !defined(WIN32) #if !defined(WIN32)
OsSignal (SIGPIPE, SIG_IGN); OsSignal (SIGPIPE, SIG_IGN);
...@@ -456,7 +456,6 @@ CreateWellKnownSockets(void) ...@@ -456,7 +456,6 @@ CreateWellKnownSockets(void)
#endif #endif
OsSignal (SIGINT, GiveUp); OsSignal (SIGINT, GiveUp);
OsSignal (SIGTERM, GiveUp); OsSignal (SIGTERM, GiveUp);
XFD_COPYSET (&WellKnownConnections, &AllSockets);
ResetHosts(display); ResetHosts(display);
InitParentProcess(); InitParentProcess();
...@@ -525,7 +524,7 @@ ResetWellKnownSockets (void) ...@@ -525,7 +524,7 @@ ResetWellKnownSockets (void)
* Remove it from out list. * Remove it from out list.
*/ */
FD_CLR (ListenTransFds[i], &WellKnownConnections); RemoveNotifyFd(ListenTransFds[i]);
ListenTransFds[i] = ListenTransFds[ListenTransCount - 1]; ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
ListenTransConns[i] = ListenTransConns[ListenTransCount - 1]; ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
ListenTransCount -= 1; ListenTransCount -= 1;
...@@ -539,13 +538,14 @@ ResetWellKnownSockets (void) ...@@ -539,13 +538,14 @@ ResetWellKnownSockets (void)
int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]); int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
FD_CLR (ListenTransFds[i], &WellKnownConnections);
ListenTransFds[i] = newfd; ListenTransFds[i] = newfd;
FD_SET(newfd, &WellKnownConnections);
} }
} }
} }
for (i = 0; i < ListenTransCount; i++)
SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL);
ResetAuthorization (); ResetAuthorization ();
ResetHosts(display); ResetHosts(display);
/* /*
...@@ -561,8 +561,15 @@ CloseWellKnownConnections(void) ...@@ -561,8 +561,15 @@ CloseWellKnownConnections(void)
{ {
int i; int i;
for (i = 0; i < ListenTransCount; i++) for (i = 0; i < ListenTransCount; i++) {
_XSERVTransClose (ListenTransConns[i]); if (ListenTransConns[i] != NULL) {
_XSERVTransClose(ListenTransConns[i]);
ListenTransConns[i] = NULL;
if (ListenTransFds != NULL)
RemoveNotifyFd(ListenTransFds[i]);
}
}
ListenTransCount = 0;
} }
static void static void
...@@ -827,23 +834,18 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) ...@@ -827,23 +834,18 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
* and AllSockets. * and AllSockets.
*****************/ *****************/
/*ARGSUSED*/ static Bool
Bool
EstablishNewConnections(ClientPtr clientUnused, void * closure) EstablishNewConnections(ClientPtr clientUnused, void * closure)
{ {
fd_set readyconnections; /* set of listeners that are ready */ int curconn = (int) (intptr_t) closure;
int curconn; /* fd of listener that's ready */ int newconn; /* fd of new client */
register int newconn; /* fd of new client */
CARD32 connect_time; CARD32 connect_time;
register int i; int i;
register ClientPtr client; ClientPtr client;
register OsCommPtr oc; OsCommPtr oc;
fd_set tmask; XtransConnInfo trans_conn, new_trans_conn;
int status;
XFD_ANDSET (&tmask, (fd_set*)closure, &WellKnownConnections);
XFD_COPYSET(&tmask, &readyconnections);
if (!XFD_ANYSET(&readyconnections))
return TRUE;
connect_time = GetTimeInMillis(); connect_time = GetTimeInMillis();
/* kill off stragglers */ /* kill off stragglers */
for (i=1; i<currentMaxClients; i++) for (i=1; i<currentMaxClients; i++)
...@@ -857,59 +859,44 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) ...@@ -857,59 +859,44 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure)
CloseDownClient(client); CloseDownClient(client);
} }
} }
#ifndef WIN32 if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) return TRUE;
{
while (readyconnections.fds_bits[i])
#else
for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++)
#endif
{
XtransConnInfo trans_conn, new_trans_conn;
int status;
#ifndef WIN32
curconn = ffs (readyconnections.fds_bits[i]) - 1;
readyconnections.fds_bits[i] &= ~((fd_mask)1 << curconn);
curconn += (i * (sizeof(fd_mask)*8));
#else
curconn = XFD_FD(&readyconnections, i);
#endif
if ((trans_conn = lookup_trans_conn (curconn)) == NULL) if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
continue; return TRUE;
if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL) newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
continue;
newconn = _XSERVTransGetConnectionNumber (new_trans_conn); if (newconn < lastfdesc) {
int clientid;
if (newconn < lastfdesc)
{
int clientid;
#if !defined(WIN32) #if !defined(WIN32)
clientid = ConnectionTranslation[newconn]; clientid = ConnectionTranslation[newconn];
#else #else
clientid = GetConnectionTranslation(newconn); clientid = GetConnectionTranslation(newconn);
#endif #endif
if(clientid && (client = clients[clientid])) if (clientid && (client = clients[clientid]))
CloseDownClient(client); CloseDownClient(client);
} }
_XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
if (trans_conn->flags & TRANS_NOXAUTH)
new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
ErrorConnMax(new_trans_conn);
}
if (!AllocNewConnection (new_trans_conn, newconn, connect_time
))
{
ErrorConnMax(new_trans_conn);
}
}
#ifndef WIN32
}
#endif
return TRUE; return TRUE;
} }
static void
QueueNewConnections(int fd, int ready, void *data)
{
QueueWorkProc(EstablishNewConnections, NULL, (void *) (intptr_t) fd);
}
#define NOROOM "Maximum number of clients reached" #define NOROOM "Maximum number of clients reached"
/************ /************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment