Do not chew up all available VT numbers when multiple sessions are reserved and time out in series

pull/2/head
Timothy Pearson 10 years ago
parent 5b260a9627
commit 4cadf198ca

@ -51,6 +51,8 @@ from the copyright holder.
# include <sys/vt.h> # include <sys/vt.h>
#endif #endif
#define MAX_VT_NUMBER 16
static void SigHandler( int n ); static void SigHandler( int n );
static int ScanConfigs( int force ); static int ScanConfigs( int force );
static void StartDisplays( void ); static void StartDisplays( void );
@ -511,7 +513,7 @@ StopToTTY( struct display *d )
if ((d->displayType & d_location) == dLocal) if ((d->displayType & d_location) == dLocal)
switch (d->status) { switch (d->status) {
default: default:
rStopDisplay( d, DS_TEXTMODE | 0x100 ); rStopDisplay(d, DS_TEXTMODE | 0x100);
case reserve: case reserve:
case textMode: case textMode:
break; break;
@ -523,9 +525,11 @@ CheckTTYMode( void )
{ {
struct display *d; struct display *d;
for (d = displays; d; d = d->next) for (d = displays; d; d = d->next) {
if (d->status == zombie) if (d->status == zombie) {
return; return;
}
}
SwitchToTty(); SwitchToTty();
} }
@ -793,12 +797,12 @@ processGPipe( struct display *d )
case G_Console: case G_Console:
#ifdef HAVE_VTS #ifdef HAVE_VTS
if (*consoleTTYs) { /* sanity check against greeter */ if (*consoleTTYs) { /* sanity check against greeter */
ForEachDisplay( StopToTTY ); ForEachDisplay(StopToTTY);
CheckTTYMode(); CheckTTYMode();
} }
#else #else
if (*d->console) /* sanity check against greeter */ if (*d->console) /* sanity check against greeter */
rStopDisplay( d, DS_TEXTMODE ); rStopDisplay(d, DS_TEXTMODE);
#endif #endif
break; break;
default: default:
@ -860,12 +864,11 @@ ReapChildren( void )
struct display *d; struct display *d;
waitType status; waitType status;
while ((pid = waitpid( -1, &status, WNOHANG )) > 0) while ((pid = waitpid( -1, &status, WNOHANG)) > 0) {
{
Debug( "manager wait returns pid %d sig %d core %d code %d\n", Debug( "manager wait returns pid %d sig %d core %d code %d\n",
pid, waitSig( status ), waitCore( status ), waitCode( status ) ); pid, waitSig( status ), waitCore( status ), waitCode( status ) );
/* SUPPRESS 560 */ /* SUPPRESS 560 */
if ((d = FindDisplayByPid( pid ))) { if ((d = FindDisplayByPid(pid))) {
d->pid = -1; d->pid = -1;
UnregisterInput( d->pipe.rfd ); UnregisterInput( d->pipe.rfd );
GClosen (&d->pipe); GClosen (&d->pipe);
@ -953,32 +956,38 @@ ReapChildren( void )
if (d->follower) { if (d->follower) {
d->follower->serverVT = d->serverVT; d->follower->serverVT = d->serverVT;
d->follower = 0; d->follower = 0;
} else { }
int con = open( "/dev/console", O_RDONLY ); else {
int con = open("/dev/console", O_RDONLY);
if (con >= 0) { if (con >= 0) {
struct vt_stat vtstat; struct vt_stat vtstat;
ioctl( con, VT_GETSTATE, &vtstat ); ioctl( con, VT_GETSTATE, &vtstat );
if (vtstat.v_active == d->serverVT) { if (vtstat.v_active == d->serverVT) {
int vt = 1; int vt = 1;
struct display *di; struct display *di;
for (di = displays; di; di = di->next) for (di = displays; di; di = di->next) {
if (di != d && di->serverVT) if (di != d && di->serverVT) {
vt = di->serverVT; vt = di->serverVT;
for (di = displays; di; di = di->next) }
}
for (di = displays; di; di = di->next) {
if (di != d && di->serverVT && if (di != d && di->serverVT &&
(di->userSess >= 0 || (di->userSess >= 0 ||
di->status == remoteLogin)) di->status == remoteLogin)) {
vt = di->serverVT; vt = di->serverVT;
ioctl( con, VT_ACTIVATE, vt );
} }
ioctl( con, VT_DISALLOCATE, d->serverVT ); }
close( con ); ioctl(con, VT_ACTIVATE, vt);
}
ioctl(con, VT_DISALLOCATE, d->serverVT);
close(con);
} }
} }
d->serverVT = 0; d->serverVT = 0;
d->status = notRunning;
} }
#endif #endif
rStopDisplay( d, d->zstatus ); rStopDisplay(d, d->zstatus);
break; break;
case phoenix: case phoenix:
Debug( "phoenix X server arises, restarting display %s\n", Debug( "phoenix X server arises, restarting display %s\n",
@ -1032,11 +1041,14 @@ wouldShutdown( void )
struct display *d; struct display *d;
if (sdRec.force != SHUT_CANCEL) { if (sdRec.force != SHUT_CANCEL) {
if (sdRec.force == SHUT_FORCEMY) if (sdRec.force == SHUT_FORCEMY) {
for (d = displays; d; d = d->next) for (d = displays; d; d = d->next) {
if (d->status == remoteLogin || if (d->status == remoteLogin ||
(d->userSess >= 0 && d->userSess != sdRec.uid)) (d->userSess >= 0 && d->userSess != sdRec.uid)) {
return 0; return 0;
}
}
}
return 1; return 1;
} }
return !AnyActiveDisplays(); return !AnyActiveDisplays();
@ -1078,7 +1090,9 @@ SigHandler( int n )
int olderrno = errno; int olderrno = errno;
char buf = (char)n; char buf = (char)n;
/* Debug( "caught signal %d\n", n ); this hangs in syslog() */ /* Debug( "caught signal %d\n", n ); this hangs in syslog() */
write( signalFds[1], &buf, 1 ); if (write(signalFds[1], &buf, 1) != 1) {
// ERROR
}
#ifdef __EMX__ #ifdef __EMX__
(void)Signal( n, SigHandler ); (void)Signal( n, SigHandler );
#endif #endif
@ -1178,23 +1192,27 @@ MainLoop( void )
break; break;
case SIGCHLD: case SIGCHLD:
ReapChildren(); ReapChildren();
if (!Stopping && autoRescan) if (!Stopping && autoRescan) {
RescanConfigs( FALSE ); RescanConfigs( FALSE );
}
break; break;
case SIGUSR1: case SIGUSR1:
if (startingServer && if (startingServer &&
startingServer->serverStatus == starting) startingServer->serverStatus == starting) {
StartServerSuccess(); StartServerSuccess();
}
break; break;
} }
continue; continue;
} }
#ifdef XDMCP #ifdef XDMCP
if (ProcessListenSockets( &reads )) if (ProcessListenSockets( &reads )) {
continue; continue;
}
#endif /* XDMCP */ #endif /* XDMCP */
if (handleCtrl( &reads, 0 )) if (handleCtrl( &reads, 0 )) {
continue; continue;
}
/* Must be last (because of the breaks)! */ /* Must be last (because of the breaks)! */
again: again:
for (d = displays; d; d = d->next) { for (d = displays; d; d = d->next) {
@ -1216,18 +1234,21 @@ MainLoop( void )
static void static void
CheckDisplayStatus( struct display *d ) CheckDisplayStatus( struct display *d )
{ {
if ((d->displayType & d_origin) == dFromFile && !d->stillThere) if ((d->displayType & d_origin) == dFromFile && !d->stillThere) {
StopDisplay( d ); StopDisplay( d );
}
else if ((d->displayType & d_lifetime) == dReserve && else if ((d->displayType & d_lifetime) == dReserve &&
d->status == running && d->userSess < 0 && !d->idleTimeout) d->status == running && d->userSess < 0 && !d->idleTimeout) {
rStopDisplay( d, DS_RESERVE ); rStopDisplay(d, DS_RESERVE);
else if (d->status == notRunning) }
else if (d->status == notRunning) {
if (LoadDisplayResources( d ) < 0) { if (LoadDisplayResources( d ) < 0) {
LogError( "Unable to read configuration for display %s; " LogError( "Unable to read configuration for display %s; "
"stopping it.\n", d->name ); "stopping it.\n", d->name );
StopDisplay( d ); StopDisplay( d );
return; return;
} }
}
} }
static void static void
@ -1260,7 +1281,7 @@ GetBusyVTs( void )
} }
static void static void
AllocateVT( struct display *d ) AllocateVT(struct display *d)
{ {
struct display *cd; struct display *cd;
int i, tvt, volun; int i, tvt, volun;
@ -1268,31 +1289,37 @@ AllocateVT( struct display *d )
if ((d->displayType & d_location) == dLocal && if ((d->displayType & d_location) == dLocal &&
d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0)
{ {
if (d->reqSrvVT && d->reqSrvVT < 16) if (d->reqSrvVT && d->reqSrvVT < MAX_VT_NUMBER) {
d->serverVT = d->reqSrvVT; d->serverVT = d->reqSrvVT;
}
else { else {
for (i = tvt = 0;;) { for (i = tvt = 0;;) {
if (serverVTs[i]) { if (serverVTs[i]) {
tvt = atoi( serverVTs[i++] ); tvt = atoi(serverVTs[i++]);
volun = 0; volun = 0;
if (tvt < 0) { if (tvt < 0) {
tvt = -tvt; tvt = -tvt;
volun = 1; volun = 1;
} }
if (!tvt || tvt >= 16) if (!tvt || tvt >= MAX_VT_NUMBER) {
continue; continue;
} else { }
if (++tvt >= 16) }
else {
if (++tvt >= MAX_VT_NUMBER) {
break; break;
}
volun = 1; volun = 1;
} }
for (cd = displays; cd; cd = cd->next) { for (cd = displays; cd; cd = cd->next) {
if (cd->reqSrvVT == tvt && /* protect from lusers */ if (cd->reqSrvVT == tvt && /* protect from lusers */
(cd->status != zombie || cd->zstatus != DS_REMOVE)) (cd->status != zombie || cd->zstatus != DS_REMOVE)) {
goto next; goto next;
}
if (cd->serverVT == tvt) { if (cd->serverVT == tvt) {
if (cd->status != zombie || cd->zstatus == DS_REMOTE) if (cd->status != zombie || cd->zstatus == DS_REMOTE) {
goto next; goto next;
}
if (!cd->follower) { if (!cd->follower) {
d->serverVT = -1; d->serverVT = -1;
cd->follower = d; cd->follower = d;
@ -1426,27 +1453,34 @@ rStopDisplay( struct display *d, int endState )
AbortStartServer( d ); AbortStartServer( d );
d->idleTimeout = 0; d->idleTimeout = 0;
if (d->serverPid != -1 || d->pid != -1) { if (d->serverPid != -1 || d->pid != -1) {
if (d->pid != -1) if (d->pid != -1) {
TerminateProcess( d->pid, SIGTERM ); TerminateProcess( d->pid, SIGTERM );
if (d->serverPid != -1) }
if (d->serverPid != -1) {
TerminateProcess( d->serverPid, d->termSignal ); TerminateProcess( d->serverPid, d->termSignal );
}
d->status = zombie; d->status = zombie;
d->zstatus = endState & 0xff; d->zstatus = endState & 0xff;
Debug( " zombiefied\n" ); Debug( " zombiefied\n" );
} else if (endState == DS_TEXTMODE) { }
else if (endState == DS_TEXTMODE) {
#ifdef HAVE_VTS #ifdef HAVE_VTS
d->status = textMode; d->status = textMode;
CheckTTYMode(); CheckTTYMode();
} else if (endState == (DS_TEXTMODE | 0x100)) { }
else if (endState == (DS_TEXTMODE | 0x100)) {
d->status = textMode; d->status = textMode;
#else #else
SwitchToTty( d ); SwitchToTty( d );
#endif #endif
} else if (endState == DS_RESERVE) }
else if (endState == DS_RESERVE) {
d->status = reserve; d->status = reserve;
}
#ifdef XDMCP #ifdef XDMCP
else if (endState == DS_REMOTE) else if (endState == DS_REMOTE) {
StartRemoteLogin( d ); StartRemoteLogin( d );
}
#endif #endif
else { else {
#ifndef HAVE_VTS #ifndef HAVE_VTS
@ -1459,7 +1493,7 @@ rStopDisplay( struct display *d, int endState )
void void
StopDisplay( struct display *d ) StopDisplay( struct display *d )
{ {
rStopDisplay( d, DS_REMOVE ); rStopDisplay(d, DS_REMOVE);
} }
static void static void
@ -1511,18 +1545,19 @@ ExitDisplay(
he->sdRec.osname = 0; he->sdRec.osname = 0;
} }
} }
if (d->status == zombie) if (d->status == zombie) {
rStopDisplay( d, d->zstatus ); rStopDisplay(d, d->zstatus);
}
else { else {
if (Stopping) { if (Stopping) {
StopDisplay( d ); StopDisplay( d );
return; return;
} }
if (endState != DS_RESTART || if (endState != DS_RESTART ||
(d->displayType & d_origin) != dFromFile) (d->displayType & d_origin) != dFromFile) {
{ rStopDisplay(d, endState);
rStopDisplay( d, endState ); }
} else { else {
if (serverCmd == XS_RETRY) { if (serverCmd == XS_RETRY) {
if ((d->displayType & d_location) == dLocal) { if ((d->displayType & d_location) == dLocal) {
if (he->lastExit - d->lastStart < 120) { if (he->lastExit - d->lastStart < 120) {

Loading…
Cancel
Save