|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-12-06 13:12 UTC] eric dot saintetienne at gmail dot com
Description: ------------ Locking exclusively via flock a file opened for writing doesn't trigger a mandatory lock. The python script below could trigger the mandatory lock. Maybe it's because PHP flock() is built on the C function call flock(): "When a program attempts to lock a file with lockf or fcntl that has mandatory locking set, the kernel will prevent all other programs from accessing the file. Processes which use flock will not trigger a mandatory lock." source: http://www.hackinglinuxexposed.com/articles/20030623.html Python script: #!/usr/bin/python import os, fcntl fd = os.open('mandlock-file', os.O_RDWR, 0755) print 'fd=', fd fcntl.lockf(fd, fcntl.LOCK_EX) a = raw_input() # during that time, any attempt to open the file will hang os.write(fd, a+'\n') fcntl.lockf(fd, fcntl.LOCK_UN) # now any attempt to open the file will succeed os.close(fd) # eof Test script: --------------- <?php define('FILENAME', 'mandlock-file'); /* first create a file with a mandatory lock: * $ touch mandlock-file * $ chmod g+s,g-x mandlock-file * $ sudo mount -o remount,mand / # my file is inside the '/' mountpoint */ function openlockedfile($filename) { $fp = fopen($filename, 'w+'); while (($fp === false) || (flock($fp, LOCK_EX) !== true)) { sleep(1); echo "spin lock\n"; if ($fp === false) $fp = fopen($filename, 'w+'); } return $fp; } $fd = openlockedfile(FILENAME); // open + lock EX sleep(10); /* During this sleep time, accessing the file should hang until the * php script releases the exclusive lock: * $ cat mandlock-file # should hang until php script termination * Practically, cat doesn't hang (and works) proving the file isn't * exclusively locked by the PHP script. */ closefile($fd); // unlock + close /* eof */ ?> Expected result: ---------------- once the file is created and the mandatory lock setup for it: during the 10 sec timer, opening the file (with or without explicit locking) should hand until the php script terminates. Actual result: -------------- it's possible to opening the locked file during the 10s timer for reading and writing. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 21:00:01 2025 UTC |
I am puzzled, what can the current behavior be possibly used for? If the lock is not really locking (and it does not -- neither on Linux nor on FreeBSD), then why bother with it at all? And if nobody bothers, then why not fix it properly? BTW, at least, on BSD the different locking mechanisms create compatible locks: The flock(), fcntl(2), and lockf(3) locks are compatible. Processes using different locking interfaces can cooperate over the same file safely. However, only one of such interfaces should be used within the same process. If a file is locked by a process through flock(), any record within the file will be seen as locked from the viewpoint of another process using fcntl(2) or lockf(3), and vice versa.This is my test case: <?php function warn($message) { global $argv; fputs(STDERR, "$argv[0]: $message\n"); } function add_dir($dir) { $lname = $dir . '/distd.pid'; $lock = fopen($lname, 'c+'); if (!$lock) { warn("$lname: can not open"); return FALSE; } if (!flock($lock, LOCK_EX|LOCK_NB)) { warn("$lname: can not lock"); return FALSE; } warn(getmypid() . " ". date('H:i:s') . " $lname successfully locked"); return (fputs($lock, getmypid() . "\n". gethostname() . "\n") != FALSE); } date_default_timezone_set('America/New_York'); add_dir('/tmp'); sleep(3); warn(getmypid() . " ". date('H:i:s') . " exiting in peace"); ?> Running TWO of the above in parallel: % ( php t.php < /dev/null & php t.php < /dev/null ) >& l I see BOTH of them claim to have "successfully" gotten the lock: % cat l [1] 26815 t.php: 26815 21:48:34 /tmp/distd.pid successfully locked t.php: 26814 21:48:34 /tmp/distd.pid successfully locked t.php: 26815 21:48:37 exiting in peace t.php: 26814 21:48:37 exiting in peace