我正在寻找命令行实用程序或其他方法来测试文件锁, 具体来说POSIX 咨询锁(顺便说一下,它们不仅适用于 POSIX)在 Linux 文件系统中。
具体来说,我想确保用于持续集成测试的 Linux/Ubuntu VM 中的 simfs 中的 POSIX 咨询锁定(文件锁定)正常工作。我们遇到过文件损坏问题,只有当 30 个进程同时写入 SQLite DB 文件时才会发生这种情况。这只在一个项目中用于测试,但我们希望帮助追踪问题,以便其他人不会遇到它。
根据 SQLite 团队和文档,仅当文件系统/操作系统中的 POSIX 咨询锁正常工作时,才支持并发写入。我使用 SQLite 进行的测试在 OS X 中的 SQLite v3.7.7 中有效,但相同的测试会破坏 TravisCI 提供的 Ubuntu VM 中 SQLite v3.7.9 中的 DB 文件(由 Blue Box 托管)。SQLite 团队没有指出这两个版本之间是否有任何并发问题得到修复,因为并发性依赖于操作系统/文件系统的 POSIX 咨询锁是否正常工作。
有关我正在尝试调查的环境的其他信息:
$ sqlite3 -version
3.7.9 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e
$ uname -r
2.6.32-042stab061.2
$ cat /proc/version
Linux version 2.6.32-042stab061.2 (root@rh6-build-x64) (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Fri Aug 24 09:07:21 MSK 2012
$ lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 12.04.2 LTS
Release: 12.04
Codename: precise
(home dir it that is exhibiting the problem is within the / mount.)
$ cat /proc/mounts
/dev/simfs / simfs rw,relatime 0 0
...
$ mount
/vz/private/6062841 on / type simfs (rw)
...
我有一张提供虚拟机的人的票这里他们表示他们不使用网络文件系统,这通常与 POSIX 锁相关的问题有关,因为在这样的环境中实现 POSIX 锁非常复杂。除了上述信息之外,本新闻稿似乎表明 OpenStack 正在被使用,上面的路径在挂载中显示“vz”,使其看起来开放VZ正在使用。
至于帮助诊断 POSIX 锁故障的工具,我听说过的唯一一个是乒乓测试,它是酷刑它使用 Samba 测试 POSIX 锁定,但在这种情况下我没有使用 Samba,所以我不确定这是否有帮助。
如果没有可用的命令行测试,如果我所能提供的只是对虚拟机的有限访问(因为 sudo 不需要我的用户密码,但应该使用 sudo 输出某些内容的命令不起作用,所以我认为它被覆盖了),我将如何测试它是否正常工作?是否有命令可以让虚拟机管理员运行以收集更多信息来帮助解决此问题?
答案1
首先:文件锁和 pthread 互斥锁是完全不同的概念。文件锁用于通知当前或其他进程表示当前文件未被使用。Pthread 互斥锁用于协调线程之间的临界区仅限当前进程。
文件锁定已完成flock(2)
,而且还有一个 shell 脚本包装器。要测试文件锁定是否有效,请打开两个终端并运行以下命令:
在一号航站楼:
flock /path/to/lockfile sleep 120
当第一个终端持有锁时,另一个终端中:
if ! flock -n /tmp/foo.lock true ; then echo "flock works"; else echo "flock fails"; fi
这应该告诉您文件锁是否有效。
如果您必须在一个脚本中运行它,请尝试以下操作:
flock /path/to/lockfile sleep 120 &
if ! flock -n /tmp/foo.lock true ; then echo "flock works"; else echo "flock fails"; fi
kill $!
锁定文件的另一种方法是fcntl
系统调用。使用 ruby 进行测试相当烦人,但这个 python 代码应该可以解决问题:
import fcntl, os, time
fd = open('/tmp/test.lock', 'w')
if os.fork():
fcntl.lockf(fd, fcntl.LOCK_EX)
os.wait()
else:
time.sleep(0.1)
fcntl.lockf(fd, fcntl.LOCK_EX|fcntl.LOCK_NB)
它尝试在 2 个不同的进程中锁定同一个文件。第二个锁是非阻塞的,因此应该立即引发错误。如果 fcntl 锁正常工作,预期输出为:
Traceback (most recent call last):
File "test.py", line 12, in <module>
fcntl.lockf(fd, fcntl.LOCK_EX|fcntl.LOCK_NB)
IOError: [Errno 11] Resource temporarily unavailable
答案2
我没有 openvz vm 来进行测试,但我认为你需要阅读关于咨询锁定的这篇说明,咨询锁定需要参与进程的合作。假设进程“A”获取了 WRITE 锁定,并开始写入文件,而进程“B”无需尝试获取锁定,就可以打开文件并写入文件。此处进程“B”是非合作进程。如果进程“B”尝试获取锁定,则意味着该进程正在合作以确保“序列化”。
仅当参与进程协作时,咨询锁定才会起作用。咨询锁定有时也称为“非强制”锁定。