|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-10-15 17:12 UTC] admin at saltwaterc dot net
Description:
------------
The name is pretty self explanatory. When the file_put_content function is used along with the LOCK_EX flag, the file descriptor / file handle doesn't get unlocked. Most of the time this won't be an issue, but depending on the underlying file system, it could lead to severe application crash. Such example is the GlusterFS version packaged for the Ubuntu 10.04 which would block the PHP process in uninterruptible sleep. I know that most of the time this situation won't affect real life scenarios, but it already took down a virtual host from our production cluster, based onto the above setup.
Test script:
---------------
<?php
file_put_contents('foo', 'bar', LOCK_EX);
$fh = fopen($file, 'rb');
flock($fh, LOCK_SH);
$file_contents = stream_get_contents($fh);
flock($fh, LOCK_UN);
fclose($fh);
echo $file_contents.PHP_EOL;
Expected result:
----------------
output: bar
strace:
getcwd("/media/glusterfs01/gluster-bug", 4096) = 31
lstat("/media/glusterfs01/gluster-bug/foo", {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
open("/media/glusterfs01/gluster-bug/foo", O_WRONLY|O_CREAT, 0666) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
flock(3, LOCK_EX) = 0
ftruncate(3, 0) = 0
write(3, "bar", 3) = 3
flock(3, LOCK_UN) = 0
close(3) = 0
getcwd("/media/glusterfs01/gluster-bug", 4096) = 31
open("/media/glusterfs01/gluster-bug/foo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
flock(3, LOCK_SH) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
read(3, "bar", 8192) = 3
read(3, "", 8192) = 0
read(3, "", 8192) = 0
flock(3, LOCK_UN) = 0
close(3) = 0
Actual result:
--------------
output: none
strace:
getcwd("/media/glusterfs01/gluster-bug", 4096) = 31
lstat("/media/glusterfs01/gluster-bug/foo", {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
open("/media/glusterfs01/gluster-bug/foo", O_WRONLY|O_CREAT, 0666) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
flock(3, LOCK_EX) = 0
ftruncate(3, 0) = 0
write(3, "bar", 3) = 3
flock(3, LOCK_UN) = 0
close(3) = 0
getcwd("/media/glusterfs01/gluster-bug", 4096) = 31
open("/media/glusterfs01/gluster-bug/foo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
flock(3, LOCK_SH
And then it blocks here ...
Patchesfile_put_contents.patch (last revision 2010-10-15 15:14 UTC by admin at saltwaterc dot net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Dec 03 11:00:01 2025 UTC |
Test script: --------------- <?php file_put_contents('foo', 'bar', LOCK_EX); $fh = fopen('foo', 'rb'); // there, I messed up the first time flock($fh, LOCK_SH); $file_contents = stream_get_contents($fh); flock($fh, LOCK_UN); fclose($fh); echo $file_contents.PHP_EOL;Note the example code does an explicit unlock. Are you sure that isn't what you are seeing there? If you try: strace php -r 'file_put_contents('foo', 'bar', LOCK_EX);' Do you see an unlock still? I get: open("/home/rasmus/foo", O_WRONLY|O_CREAT, 0666) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 lseek(3, 0, SEEK_CUR) = 0 flock(3, LOCK_EX) = 0 ftruncate(3, 0) = 0 write(3, "bar", 3) = 3 close(3) = 0