Edit report at https://bugs.php.net/bug.php?id=63709&edit=1

 ID:                 63709
 Comment by:         mi+php at aldan dot algebra dot com
 Reported by:        eric dot saintetienne at gmail dot com
 Summary:            flock() doesn't trigger mandatory locks on linux
 Status:             Analyzed
 Type:               Bug
 Package:            Filesystem function related
 Operating System:   Linux
 PHP Version:        5.3.19
 Block user comment: N
 Private report:     N

 New Comment:

Eric, I'm confused. Are you saying, the problem I am illustrating with my test 
case is different? Should I file a separate bug-report?


Previous Comments:
------------------------------------------------------------------------
[2013-04-04 08:32:28] eric dot saintetienne at gmail dot com

I appreciate your code and efforts but please stay focus on the topic: 
MANDATORY 
locks only. The issue is that PHP doesn't provide a standard way of triggering 
a 
mandatory lock.

MANDATORY locks are specific to Linux and occurs on a volume that is mounted 
with the "-o mand" mount flag.
ADVISORY locks exist on any system via flock() or lockf() calls and are not the 
subject of this thread.

Now I'm speaking to PHP developpers: how do you plan to fill in the gap?

Thanks

------------------------------------------------------------------------
[2013-04-04 01:49:17] mi+php at aldan dot algebra dot com

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

------------------------------------------------------------------------
[2013-04-02 07:58:42] eric dot saintetienne at gmail dot com

I hope we're still speaking of MANDATORY locks (the ones provided by "mount -o 
mand") and not standard file locks? Other locks (advisory) behave as expected.

So what's the solution you chose to allow locking a file with a MANDATORY lock 
using PHP?

------------------------------------------------------------------------
[2013-04-01 23:01:23] mi+php at aldan dot algebra dot com

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.

------------------------------------------------------------------------
[2012-12-07 09:43:12] eric dot saintetienne at gmail dot com

You're right, Python is smart and the trick is simple: fnctl module functions 
are coded such that they detect the type of the object they're given as 
argument. If it's an integer they assume it is a file descriptor otherwise they 
call its fileno() method to retrieve the file descriptor integer.

So it's a matter of adding your own fileno() method to the PHP standard file 
object and making the dio_* routines calling it, when not provided with an 
integer.

Does that makes sense to you?

It's a suggestion, at the end of the day it's your decision of how to handle 
this issue, even though it seems to, I'm actually not pushing to get direct io 
integrated at any cost (I don't have any stake) but I just feel it's the way to 
go.

------------------------------------------------------------------------


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

    https://bugs.php.net/bug.php?id=63709


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=63709&edit=1

Reply via email to