NetBSD Problem Report #44494
From www@NetBSD.org Mon Jan 31 00:37:25 2011
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by www.NetBSD.org (Postfix) with ESMTP id 40BA663B873
for <gnats-bugs@gnats.NetBSD.org>; Mon, 31 Jan 2011 00:37:25 +0000 (UTC)
Message-Id: <20110131003723.CD4CE63B842@www.NetBSD.org>
Date: Mon, 31 Jan 2011 00:37:23 +0000 (UTC)
From: alnsn@yandex.ru
Reply-To: alnsn@yandex.ru
To: gnats-bugs@NetBSD.org
Subject: F_GETLCK doesn't see some locks
X-Send-Pr-Version: www-1.0
>Number: 44494
>Category: kern
>Synopsis: F_GETLCK doesn't see some locks
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Jan 31 00:40:00 +0000 2011
>Closed-Date: Sat Jul 23 10:22:48 +0000 2011
>Last-Modified: Thu Aug 11 21:55:01 +0000 2011
>Originator: Alexander Nasonov
>Release: NetBSD 5.99.44 amd64
>Organization:
home sweet home
>Environment:
NetBSD nebeda.localdomain 5.99.44 NetBSD 5.99.44 (GENERIC) #0: Tue Jan 25 21:26:14 GMT 2011 root@nebeda.localdomain:/home/alnsn/src/netbsd-current/src/sys/arch/amd64/compile/obj/GENERIC amd64
>Description:
When you start processes one by one and each process locks one byte at getpid() offset for writing in a shared file (on tmpfs in case it matters) and then some process walks through the file trying to enumerate all processes it misses some. Everything is fine when pids are increasing but if a pid of some process is lower than a pid of the preceding process, the lower pid will not be enumerated.
>How-To-Repeat:
I wrote a rump test:
Index: t_vnops.c
===================================================================
RCS file: /cvsroot/src/tests/fs/vfs/t_vnops.c,v
retrieving revision 1.12
diff -u -u -r1.12 t_vnops.c
--- t_vnops.c 11 Jan 2011 14:03:38 -0000 1.12
+++ t_vnops.c 31 Jan 2011 00:21:33 -0000
@@ -33,6 +33,7 @@
#include <fcntl.h>
#include <libgen.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <rump/rump_syscalls.h>
@@ -567,6 +568,99 @@
FSTEST_EXIT();
}
+static int
+flock_compare(const void *p, const void *q)
+{
+ int a = ((const struct flock *)p)->l_start;
+ int b = ((const struct flock *)q)->l_start;
+ return a < b ? -1 : (a > b ? 1 : 0);
+}
+
+static void
+fcntl_getlock(const atf_tc_t *tc, const char *mp)
+{
+ /* test non-overlaping ranges */
+ struct flock expect[4];
+ const struct flock lock[4] = {
+ { 0, 2, 0, F_WRLCK, SEEK_SET },
+ { 2, 1, 0, F_WRLCK, SEEK_SET },
+ { 7, 5, 0, F_WRLCK, SEEK_SET },
+ { 4, 3, 0, F_WRLCK, SEEK_SET },
+ };
+
+ int fd[4];
+ struct lwp *lwp[4];
+
+ unsigned int i, j;
+ const off_t sz = 8192;
+ int omode = 0755;
+ int oflags = O_RDWR | O_CREAT;
+
+ memcpy(expect, lock, sizeof(lock));
+ qsort(expect, __arraycount(expect), sizeof(expect[0]), &flock_compare);
+
+ FSTEST_ENTER();
+
+ for(i = 0; i < __arraycount(lwp); i++) {
+ if(i != 0)
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+
+ lwp[i] = rump_pub_lwproc_curlwp();
+
+ RL(fd[i] = rump_sys_open(TESTFILE, oflags, omode));
+ oflags = O_RDWR;
+ omode = 0;
+
+ RL(rump_sys_ftruncate(fd[i], sz));
+ RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i]));
+ }
+
+ for(i = 0; i < __arraycount(lwp); i++) {
+ rump_pub_lwproc_switch(lwp[i]);
+
+ for(j = 0; j < __arraycount(lwp); j++) {
+ struct flock l;
+ l = expect[j];
+ l.l_len = sz;
+ l.l_type = F_RDLCK;
+
+ RL(rump_sys_fcntl(fd[i], F_GETLK, &l));
+
+ if(expect[j].l_start != lock[i].l_start) {
+ /* lock set by another process */
+ ATF_CHECK(l.l_type != F_UNLCK);
+ ATF_CHECK_EQ(l.l_start, expect[j].l_start);
+ ATF_CHECK_EQ(l.l_len, expect[j].l_len);
+ } else if(j != __arraycount(lwp) - 1) {
+ /* skip the lock set by the current process */
+ ATF_CHECK(l.l_type != F_UNLCK);
+ ATF_CHECK_EQ(l.l_start, expect[j+1].l_start);
+ ATF_CHECK_EQ(l.l_len, expect[j+1].l_len);
+ } else {
+ /* there are no other locks after the current process lock */
+ ATF_CHECK_EQ(l.l_type, F_UNLCK);
+ ATF_CHECK_EQ(l.l_start, expect[j].l_start);
+ ATF_CHECK_EQ(l.l_len, sz);
+ ATF_CHECK_EQ(l.l_pid, expect[j].l_pid);
+ ATF_CHECK_EQ(l.l_whence, expect[j].l_whence);
+ }
+ }
+ }
+
+ rump_pub_lwproc_switch(lwp[0]);
+ for(i = __arraycount(lwp); i > 0; i--) {
+ rump_pub_lwproc_switch(lwp[i-1]);
+ RL(rump_sys_close(fd[i-1]));
+ }
+
+ for(i = __arraycount(lwp); i > 1; i--) {
+ rump_pub_lwproc_switch(lwp[i-1]);
+ rump_pub_lwproc_releaselwp();
+ }
+
+ FSTEST_EXIT();
+}
+
ATF_TC_FSAPPLY(lookup_simple, "simple lookup (./.. on root)");
ATF_TC_FSAPPLY(lookup_complex, "lookup of non-dot entries");
ATF_TC_FSAPPLY(dir_simple, "mkdir/rmdir");
@@ -579,6 +673,7 @@
ATF_TC_FSAPPLY(symlink_zerolen, "symlink with 0-len target");
ATF_TC_FSAPPLY(attrs, "check setting attributes works");
ATF_TC_FSAPPLY(fcntl_lock, "check fcntl F_SETLK");
+ATF_TC_FSAPPLY(fcntl_getlock, "check fcntl F_GETLK");
ATF_TP_ADD_TCS(tp)
{
@@ -595,6 +690,7 @@
ATF_TP_FSAPPLY(symlink_zerolen);
ATF_TP_FSAPPLY(attrs);
ATF_TP_FSAPPLY(fcntl_lock);
+ ATF_TP_FSAPPLY(fcntl_getlock);
return atf_no_error();
}
>Fix:
>Release-Note:
>Audit-Trail:
From: "Antti Kantee" <pooka@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/44494 CVS commit: src/tests/fs/vfs
Date: Mon, 31 Jan 2011 10:01:26 +0000
Module Name: src
Committed By: pooka
Date: Mon Jan 31 10:01:26 UTC 2011
Modified Files:
src/tests/fs/vfs: t_vnops.c
Log Message:
Add test case for F_GETLK pid-oddness from PR kern/44494.
I found the test case a little difficult to understand (because of
many indices), so I added a few more comments after I think I
figured out what was going on.
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/tests/fs/vfs/t_vnops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: alnsn@NetBSD.org
State-Changed-When: Sat, 23 Jul 2011 10:22:48 +0000
State-Changed-Why:
Closing the ticket because there is an ambiguity in POSIX.
From my email to austin-group-l@opengroup.org:
It's not clear from POSIX specs whether "first lock" means a lock with
the lowest start offset or a first acquired lock in a chronological order
or even something completely different.
I've adjusted the test.
From: Bernd Ernesti <netbsd@lists.veego.de>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/44494 (F_GETLCK doesn't see some locks)
Date: Sun, 24 Jul 2011 09:56:03 +0200
On Sat, Jul 23, 2011 at 10:22:50AM +0000, alnsn@NetBSD.org wrote:
[..]
> Closing the ticket because there is an ambiguity in POSIX.
> From my email to austin-group-l@opengroup.org:
>
> It's not clear from POSIX specs whether "first lock" means a lock with
> the lowest start offset or a first acquired lock in a chronological order
> or even something completely different.
And what was the answer to your mail on that list?
Bernd
From: Alexander Nasonov <alnsn@yandex.ru>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, alnsn@yandex.ru
Subject: Re: kern/44494 (F_GETLCK doesn't see some locks)
Date: Sun, 24 Jul 2011 10:13:29 +0100
Bernd Ernesti wrote:
> And what was the answer to your mail on that list?
No answer yet.
I closed the PR not only because of ambiguity in POSIX but also
because I could achieve my goal with existing implementation.
Alex
From: Alexander Nasonov <alnsn@yandex.ru>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org
Subject: Re: kern/44494 (F_GETLCK doesn't see some locks)
Date: Thu, 11 Aug 2011 22:53:15 +0100
Alexander Nasonov wrote:
> I closed the PR not only because of ambiguity in POSIX but also
> because I could achieve my goal with existing implementation.
Further progress on the issue can be tracked in Austin group system:
http://austingroupbugs.net/view.php?id=484
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.