NetBSD Problem Report #57369
From www@netbsd.org Wed Apr 19 11:04:09 2023
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 30AC81A9239
for <gnats-bugs@gnats.NetBSD.org>; Wed, 19 Apr 2023 11:04:09 +0000 (UTC)
Message-Id: <20230419110407.9A9191A923A@mollari.NetBSD.org>
Date: Wed, 19 Apr 2023 11:04:07 +0000 (UTC)
From: yamt9999@gmail.com
Reply-To: yamt9999@gmail.com
To: gnats-bugs@NetBSD.org
Subject: unexpected poll timeout on pipe
X-Send-Pr-Version: www-1.0
>Number: 57369
>Category: kern
>Synopsis: unexpected poll timeout on pipe
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 19 11:05:02 +0000 2023
>Last-Modified: Thu Apr 20 06:50:01 +0000 2023
>Originator: YAMAMOTO Takashi
>Release: NetBSD 9.3
>Organization:
>Environment:
NetBSD ushi 9.3 NetBSD 9.3 (GENERIC) #0: Thu Aug 4 15:30:37 UTC 2022 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
please see the following test code.
(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
it succeeds on macOS and ubuntu.
but on netbsd, poll times out. (returns 0)
its 9.3 GENERIC kernel + older userland if it matters.
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main()
{
int pipefds[2];
int ret;
ret = pipe(pipefds);
if (ret != 0) {
printf("pipe failed\n");
exit(1);
}
pid_t p = fork();
if (p == -1) {
printf("fork failed\n");
exit(1);
}
if (p == 0) {
/* sleep to ensure the parent starts poll before we exit */
sleep(1);
_Exit(0);
}
ret = close(pipefds[0]); /* read side */
if (ret != 0) {
printf("close failed unexpectdly\n");
exit(1);
}
struct pollfd pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.fd = pipefds[1]; /* write side */
pfd.events = POLLHUP;
ret = poll(&pfd, 1, 3000);
if (ret != 1) {
printf("poll returned unexpectd value %d\n", ret);
exit(1);
}
printf("success\n");
exit(0);
}
>How-To-Repeat:
see above
>Fix:
>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/57369: unexpected poll timeout on pipe
Date: Thu, 20 Apr 2023 06:22:36 -0000 (UTC)
yamt9999@gmail.com writes:
>please see the following test code.
>(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
>it succeeds on macOS and ubuntu.
>but on netbsd, poll times out. (returns 0)
>its 9.3 GENERIC kernel + older userland if it matters.
This can be changed with:
Index: sys/kern/sys_pipe.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
retrieving revision 1.158
diff -p -u -r1.158 sys_pipe.c
--- sys/kern/sys_pipe.c 11 Oct 2021 01:07:36 -0000 1.158
+++ sys/kern/sys_pipe.c 20 Apr 2023 06:20:45 -0000
@@ -846,7 +846,7 @@ pipe_poll(file_t *fp, int events)
revents |= POLLHUP;
if (revents == 0) {
- if (events & (POLLIN | POLLRDNORM))
+ if (events & (POLLIN | POLLHUP | POLLRDNORM))
selrecord(curlwp, &rpipe->pipe_sel);
if (events & (POLLOUT | POLLWRNORM))
But I don't see that this has ever worked. It also doesn't help (alone)
for the opposite direction.
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/57369: unexpected poll timeout on pipe
Date: Thu, 20 Apr 2023 06:48:24 -0000 (UTC)
mlelstv@serpens.de (Michael van Elst) writes:
>The following reply was made to PR kern/57369; it has been noted by GNATS.
>From: mlelstv@serpens.de (Michael van Elst)
>To: gnats-bugs@netbsd.org
>Cc:
>Subject: Re: kern/57369: unexpected poll timeout on pipe
>Date: Thu, 20 Apr 2023 06:22:36 -0000 (UTC)
> yamt9999@gmail.com writes:
>
> >please see the following test code.
> >(it's available on github as well: https://github.com/yamt/garbage/blob/master/c/poll/test.c)
> >it succeeds on macOS and ubuntu.
> >but on netbsd, poll times out. (returns 0)
> >its 9.3 GENERIC kernel + older userland if it matters.
>
>
> This can be changed with:
>
> Index: sys/kern/sys_pipe.c
> ===================================================================
> RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
> retrieving revision 1.158
> diff -p -u -r1.158 sys_pipe.c
> --- sys/kern/sys_pipe.c 11 Oct 2021 01:07:36 -0000 1.158
> +++ sys/kern/sys_pipe.c 20 Apr 2023 06:20:45 -0000
> @@ -846,7 +846,7 @@ pipe_poll(file_t *fp, int events)
> revents |= POLLHUP;
>
> if (revents == 0) {
> - if (events & (POLLIN | POLLRDNORM))
> + if (events & (POLLIN | POLLHUP | POLLRDNORM))
> selrecord(curlwp, &rpipe->pipe_sel);
>
> if (events & (POLLOUT | POLLWRNORM))
>
>
> But I don't see that this has ever worked. It also doesn't help (alone)
> for the opposite direction.
The write case is missed, because the EOF condition is set after
notifying the peer.
@@ -973,8 +973,8 @@ pipeclose(struct pipe *pipe)
* Disconnect from peer.
*/
if ((ppipe = pipe->pipe_peer) != NULL) {
- pipeselwakeup(ppipe, ppipe, POLL_HUP);
ppipe->pipe_state |= PIPE_EOF;
+ pipeselwakeup(ppipe, ppipe, POLL_HUP);
cv_broadcast(&ppipe->pipe_rcv);
ppipe->pipe_peer = NULL;
}
A few lines earlier (waking openers of the closing
side) seems to be the wrong order too.
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2023
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.