[OT for linux-kernel] Re: Problems with starting X

Nate Eldredge (nate@cartsys.com)
Tue, 08 Jun 1999 20:06:10 -0700


Thomas Molina wrote:

> I'm not sure what is going on here, but I get a delay in starting X
> after rebooting. The attached "logs" are from capturing the output of
> "xtrace xinit". log1 is the first instance of the command where X
> starts normally. log2 is the second instance, where it takes about 30
> seconds to bring up X. My inspection of the traces show that the two
> logs are almost identical. Processor ids are different of course. The
> only other difference is the point at which the output from XFree starts
> appearing. This happens later in the output from the "normal" case than
> it does in the "problem" case.

Hi,

I think this is a bug in X (specifically xinit) that I found some time
ago. It's a race condition; xinit expects to be sent SIGUSR1 from the
X-server when it finishes starting, so it installs a handler, forks to
start the server, and enters `pause'. However, if the server finishes
before xinit reaches the `pause', the signal will arrive too soon and
`pause' will sleep until another signal arrives. This is the SIGALRM
for the 15-second timeout.

You can see from your strace that in the okay case, SIGUSR1 awakens the
`pause', but in the problem case SIGUSR1 happened earlier and SIGALRM
woke it up.

A patch I wrote follows. This was against 3.3.3, but as far as I can
tell they haven't changed anything in that arena. I *did* report it,
around the end of February it looks like, but I guess they decided not
to fix it. This blocks SIGUSR1 and uses `sigsuspend' to wait for it,
eliminating this race.

The change to `fork' from `vfork' is just pedantry; technically one
can't do the stuff they do in a `vfork' child.

Btw, I hunted it down by using strace's -T option, which shows time
spent in a system call. Also, it would be easier to interpret this if
you used an strace that groks new system calls; Debian's 3.99 is a good
one. (Yes, I've submitted code for it.)

--- xc/programs/xinit/xinit.c Mon Mar 2 03:56:37 1998
+++ xc/programs/xinit/xinit.c.new Sun Feb 28 20:56:47 1999
@@ -500,9 +500,17 @@
startServer(server)
char *server[];
{
- serverpid = vfork();
+ sigset_t s, old;
+ sigemptyset(&s);
+ sigaddset(&s, SIGUSR1);
+ sigprocmask(SIG_BLOCK, &s, &old);
+
+ serverpid = fork();
switch(serverpid) {
case 0:
+ /* Unblock */
+ sigprocmask(SIG_SETMASK, &old, NULL);
+
/*
* don't hang on read/write to control tty
*/
@@ -570,8 +578,9 @@
* you can easily adjust this value.
*/
alarm (15);
- pause ();
+ sigsuspend(&old);
alarm (0);
+ sigprocmask(SIG_SETMASK, &old, NULL);

if (waitforserver() == 0) {
Error("unable to connect to X server\r\n");


-- 

Nate Eldredge nate@cartsys.com

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/