From owner-freebsd-hackers@FreeBSD.ORG Mon Apr 6 21:18:14 2015 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 75BADAD2 for ; Mon, 6 Apr 2015 21:18:14 +0000 (UTC) Received: from mail-pd0-x22c.google.com (mail-pd0-x22c.google.com [IPv6:2607:f8b0:400e:c02::22c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 416C9800 for ; Mon, 6 Apr 2015 21:18:14 +0000 (UTC) Received: by pdea3 with SMTP id a3so56259327pde.3 for ; Mon, 06 Apr 2015 14:18:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:content-transfer-encoding:subject:message-id:date :to:mime-version; bh=YCaIU/MfG92dliwz/gsyhjRmZqef/voRxukXQkW2HNw=; b=nUkHM1Jzyh/afyQuN8n/U3nyrN4mobob0SIg6P6tPhCInmMGMGto/uOIKJWSSsdrUo lTym3jaqYltMYTDpUE3uQ2w0M4BIvja3UqasfGWzO/pm9o2I977p8r3wyhF5a4Dibh/x f/JgIpBwADDvAiIkkiWFuFHh1vUd+BOySHl6IPyXWsAqhYnhKFJ0Agf2c3/9tOik4pVV JCz4XTzRrSVJQVU1NBYxYkxDLDMvVkS+NfChyIq2tVfPXVesG9N3/JxduFujLPjFQGJ5 kZ5/+lNtJsukGGBv4neh/NAjU0WhzhTLOEQvpsRBLkMtlaYWC3GmzWdBKYfS9scS8UUW zcLQ== X-Received: by 10.70.54.198 with SMTP id l6mr30799876pdp.74.1428355093731; Mon, 06 Apr 2015 14:18:13 -0700 (PDT) Received: from [192.168.1.188] (173-26-46-90.client.mchsi.com. [173.26.46.90]) by mx.google.com with ESMTPSA id ia3sm2328954pbc.31.2015.04.06.14.18.11 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 06 Apr 2015 14:18:12 -0700 (PDT) From: Guy Helmer Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: lockf() vs. flock() -- lockf() not locking? Message-Id: <3950D855-0F4E-49E0-A388-4C7ED102B68B@gmail.com> Date: Mon, 6 Apr 2015 16:18:09 -0500 To: FreeBSD Hackers Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) X-Mailer: Apple Mail (2.2070.6) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Apr 2015 21:18:14 -0000 Recently an application I use switched from using flock() for advisory = file locking to lockf() in the code that protects against concurrent = writes to a file that is being shared and updated by multiple processes = (not threads in a single process). The code seems reliable =E2=80=94 a = lock manager class opens the file & obtains the lock, then the = read/update method opens the file using a separate file descriptor & = reads/writes the file, flushes & closes the second file descriptor, and = then destroys the lock manager object which unlocks the file & closes = the first file descriptor. Surprisingly this simple change seems to have made the code unreliable = by allowing concurrent writers to the file and corrupting its contents: - if (flock(fd, LOCK_EX) !=3D 0) + if (lockf(fd, F_LOCK, 0) !=3D 0) throw std::runtime_error("Failed to get a lock of " + = filename); . . . if (fd !=3D -1) { - flock(fd, LOCK_EX); + lockf(fd, F_ULOCK, 0); close(fd); fd =3D -1; } =46rom my reading of the lockf(3) man page and reviewing the = implementation in lib/libc/gen/lockf.c, and corresponding code in = sys/kern/kern_descrip.c, it appears the lockf() call should be = successfully obtaining an advisory lock over the whole file like a = successful flock() did. However, I have a stress test that quickly = corrupts the target file using the lockf() implementation, and the test = fails to cause corruption using the flock() implementation. I=E2=80=99ve = instrumented the code, and it's clear that multiple processes are = simultaneously in the block of code after the =E2=80=9Clockf(fd, F_LOCK, = 0)=E2=80=9D line. Am I missing something obvious? Any ideas? Thanks, Guy