RE: [Patch] Fix a race condition in pty.c

From: Lu, Hongjiu
Date: Fri Dec 17 2004 - 12:16:42 EST


Sorry I didn't mention that my testcase hang:

11540 pts/0 S 0:00 ./pty
11541 ? Zs 0:00 [true] <defunct>

Both parent and child are sleeping. They will never wake up. I updated
my bug report

http://bugzilla.kernel.org/show_bug.cgi?id=3894

with the config file for P4 SMP machine.


H.J. Lu
Intel Corporation


>-----Original Message-----
>From: Andrew Morton [mailto:akpm@xxxxxxxx]
>Sent: Friday, December 17, 2004 12:36 AM
>To: Zou, Nanhai
>Cc: linux-kernel@xxxxxxxxxxxxxxx; Lu, Hongjiu
>Subject: Re: [Patch] Fix a race condition in pty.c
>
>"Zou, Nanhai" <nanhai.zou@xxxxxxxxx> wrote:
>>
>> <<pty_close-race-fix.patch>> There is a race condition int pty.c
>> when pty_close wakes up waiter on its pair device before set
>> TTY_OTHER_CLOSED flag.
>>
>> It is possible on SMP or preempt kernel, waiter wakes up too early
>that
>> it will not get TTY_OTHER_CLOSED flag then fall into sleep again.
>>
>> Lu hong jiu report this bug will hang some expect scripts on SMP
>> machines.
>
>The patch looks good (apart from the application/octet-stream encoding.
>grr.)
>
>But on my test box it still doesn't fix the testcase which hj attached
>to
>bug 3894:
>
>select (3) returns: 1
>Read -1 characters.
>errno: Input/output error
>334
>select (3) returns: 1
>Read -1 characters.
>errno: Input/output error
>335
>
>In fact the same happens on a non-preempt uniprocessor kernel, so I
>must be
>seeing something different.
>
>#include <sys/types.h>
>#include <sys/select.h>
>#include <stdio.h>
>#include <unistd.h>
>#include <pty.h>
>
>int
>main ()
>{
> pid_t pid;
> int fd;
> char slave_name [20];
> char buffer [1000];
> int count;
> fd_set readfds;
> int ret;
>
> pid = forkpty (&fd, slave_name, NULL, NULL);
> switch (pid)
> {
> case 0: /* Child process. */
> if (execlp ("true", "true", NULL))
> perror ("execlp");
> return 1;
> break;
>
> default: /* Parent process. */
> break;
> }
>
> FD_ZERO (&readfds);
> FD_SET (fd, &readfds);
> ret = select (1024, &readfds, NULL, NULL, NULL);
> printf ("select (%d) returns: %d\n", fd, ret);
> if (ret < 0)
> perror ("select");
> else if (FD_ISSET (fd, &readfds))
> {
> count = read (fd, buffer, 999);
> printf ("Read %d characters.\n", count);
> perror("errno");
> }
> return 0;
>}

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