Edit report at http://bugs.php.net/bug.php?id=53076&edit=1
ID: 53076
Comment by: admin at saltwaterc dot net
Reported by: admin at saltwaterc dot net
Summary: file_put_contents doesn't release the LOCK_EX
Status: Feedback
Type: Bug
Package: Scripting Engine problem
Operating System: Irrelevant
PHP Version: 5.3.3
Block user comment: N
New Comment:
My bad. I did the bug report in a little bit hurry.
The 'actual result' is broken since I use my patch
for my PHP build, while keeping an eye on my old
strace outputs, with actual production setup:
Invision Power Board + Minify + PHP 5.3.3 (PHP-FPM)
+ Ubuntu Server 10.04. Therefore, it's kinda 'emulated'.
But it does happen with the standard PHP of doing things.
However, the lock release when the stream is closed
depends onto the filesystem implementation.
See this changelog:
http://ftp.zresearch.com/pub/gluster/glusterfs/3.0/3.0.3/GlusterFS_3.0.3_Release
_Notes.pdf
I know that usually this happens on buggy filesystems
that have issues with advisory locking, but in my
humble opinion this doesn't mean that the file_put_contents
should not include those 3 lines of code that make things
to be a little bit stable from now on such as avoiding deadlocks
when things go unplanned. As I said, this specific conditions
took down one of our production virtual hosts.
Previous Comments:
------------------------------------------------------------------------
[2010-10-16 09:52:46] cataphract@php.net
I don't get an explicit LOCK_UN either, but it should be unnecessary, as
locks are released when the file is closed.
@crrodriguez
There's no need to call php_stream_flush as that is already done when
the stream is closed. See:
http://lxr.php.net/xref/PHP_TRUNK/main/streams/streams.c#_php_stream_free
------------------------------------------------------------------------
[2010-10-16 02:20:24] crrodriguez at opensuse dot org
Patch ACK'ed , looks correct.
BUT, you should also call php_stream_flush before closing the stream..
to make it
slightly more reliable though there is still no warranty that the file
is stored
on the filesystem...
article worth reading
http://thunk.org/tytso/blog/2009/03/12/delayed-allocation-
and-the-zero-length-file-problem/ ;)
------------------------------------------------------------------------
[2010-10-16 02:12:58] rasmus@php.net
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
------------------------------------------------------------------------
[2010-10-16 02:05:13] cataphract@php.net
I can't reproduce this. I get the output "bar".
File locks are released when the file are closed. Additionally, your
'actual result' section shows an unlock:
...
write(3, "bar", 3) = 3
flock(3, LOCK_UN) = 0 <<<<<---
Am I missing something?
------------------------------------------------------------------------
[2010-10-15 17:16:19] admin at saltwaterc dot net
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;
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/bug.php?id=53076
--
Edit this bug report at http://bugs.php.net/bug.php?id=53076&edit=1