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:

NetBSD Home
NetBSD PR Database Search

(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.