Date: Mon, 6 Apr 2015 16:18:09 -0500 From: Guy Helmer <guy.helmer@gmail.com> To: FreeBSD Hackers <freebsd-hackers@freebsd.org> Subject: lockf() vs. flock() -- lockf() not locking? Message-ID: <3950D855-0F4E-49E0-A388-4C7ED102B68B@gmail.com>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3950D855-0F4E-49E0-A388-4C7ED102B68B>