I have some results from flock() which appear to contradict the FAQ wisdom:

    whole file locking:                                     [ Programmer ]

       AFS does support advisory locking an entire file with flock().
       Processes on the same client workstation that attempt to lock
       a file obey the proper locking semantics.

       Processes on different AFS clients requesting a lock on the same
       file would get EWOULDBLOCK returned.

I ran this program on two clients that were time synchronized to the 
nearest second:

#!/afs/path/to/bin/perl -wl
use strict;
use Fcntl qw(:DEFAULT :flock);
$|++;
chomp(my $h = `hostname`);
my $f = '/afs/path/to/home/flocktmp';
system "touch $f" unless -e $f;
my $now = 972353100;
sysopen FOO, $f, O_RDWR|O_CREAT or die "$h open: $!";
print time-$now, ": $h: waiting for exclusive lock";
flock FOO, LOCK_EX or die "$h exclusive lock: $!";
print time-$now, ": $h: exclusive lock obtained, holding for 10 seconds";
sleep 10;  # Wait for peer to attempt to obtain lock
flock FOO, LOCK_UN or die "$h unlock failed: $!";
print time-$now, ": $h: unlocked";
close FOO;
sysopen FOO, $f, O_RDWR|O_CREAT or die "$h open: $!";
sleep 5;
print time-$now, ": $h: waiting for shared lock";
flock FOO, LOCK_SH or die "$h shared lock: $!";
print time-$now, ": $h: shared lock obtained, holding for 10 seconds";
sleep 10;
flock FOO, LOCK_UN or die "$h unlock failed: $!";
print time-$now, ": $h: unlocked";
close FOO;

Client A is running an old client identifying itself as "Base config ports 
1.54".
Client B is running 3.4 patch 5.  I started the program on A, waited 7 seconds,
then ran it on B (while A still had the exclusive lock).  The results:

587: A: waiting for exclusive lock
587: A: exclusive lock obtained, holding for 10 seconds
597: A: unlocked
602: A: waiting for shared lock
609: A: shared lock obtained, holding for 10 seconds
619: A: unlocked

594: B: waiting for exclusive lock
598: B: exclusive lock obtained, holding for 10 seconds
608: B: unlocked
613: B: waiting for shared lock
613: B: shared lock obtained, holding for 10 seconds
623: B: unlocked

These results look entirely consistent with the way flock() should and does 
behave when AFS isn't involved.  Can someone explain this for me 
please?  Our servers are running version 3.5.

I have further test results corroborating this.  Here is an attempt for two 
clients to grab a lock at the same time.  I ran the following script on two 
hosts simultaneously:

#!/afs/path/to/bin/perl -w
use strict;
use Fcntl qw(:DEFAULT :flock);
$|++;
chomp(my $h = `hostname`);
my $f = '/afs/path/to/home/flocktmp';
for (1..shift||10000)
{
   print "\r$_";
   sysopen FOO, $f, O_RDWR|O_CREAT or die "$h open: $!\n";
   flock FOO, LOCK_EX or die "$h exclusive lock: $!\n";
   seek FOO, 0, 0     or die "$h rewind failed: $!\n";
   truncate FOO, 0    or die "$h truncate failed: $!\n";
   print FOO "$h\n";
   seek FOO, 0, 0     or die "$h rewind failed: $!\n";
   chomp(my $read = <FOO>);
   flock FOO, LOCK_UN or die "$h unlock failed: $!\n";
   close FOO;
   die "$h: read $read instead of $h\n" if $read ne $h;
}
print "\n";

No host reported a mismatch between what was read and what was 
written.  The observed behavior was of one host counting up while the other 
one was stuck, then they would switch for a while.  This is exactly what I 
would expect with a working flock.
--
Peter Scott
[EMAIL PROTECTED]

Reply via email to