Question

In a nutshell: wrote a Perl script using flock(). On Linux, it behaves as expected. On AIX, flock() always returns 1, even though another instance of the script, using flock(), should be holding an exclusive lock on the lockfile.

We ship a Bash script to restart our program, relying on flock(1) to prevent simultaneous restarts from making multiple processes. Recently we deployed on AIX, where flock(1) doesn't come by default and won't be provided by the admins. Hoping to keep things simple, I wrote a Perl script called flock, like this:

#!/usr/bin/perl

use Fcntl ':flock';
use Getopt::Std 'getopts';

getopts("nu:x:");

%switches = (LOCK_EX => $opt_x, LOCK_UN => $opt_u, LOCK_NB => $opt_n);

my $lockFlags = 0;

foreach $key (keys %switches) {
    if($switches{$key}) {$lockFlags |= eval($key)};
}

$fileDesc = $opt_x || $opt_u;

open(my $lockFile, ">&=$fileDesc") ||  die "Can't open file descriptor: $!";
flock($lockFile, $lockFlags) || die "Can't change lock - $!\n";;

I tested the script by running (flock -n -x 200; sleep 60)200>lockfile twice, nearly simultaneously, from two terminal tabs.

On Linux, the second run dies with "Resource temporarily unavailable", as expected.

On AIX, the second run acquires the lock, with flock() returning 1, as most definitely not expected.

I understand the flock() is implemented differently on the two systems, the Linux version using flock(1) and the AIX one using, I think, fcntl(1). I don't have enough expertise to understand how this causes my problem, and how to solve it.

Many thanks for any advice.

Was it helpful?

Solution

This isn't anything to do with AIX, the open() call in your script is incorrect.

Should should be something like:

open (my $lockfile, ">>", $fileDesc) # for LOCK_EX, must be write

You were using the "dup() previously opened file handle" syntax with >&=, but the script had not opened any files to duplicate, nor should it.

My quick tests shows the correct behavior (debugging added)

first window:
$ ./flock.pl -n -x lockfile
opened lockfile
locked
second window:
$./flock.pl -n -x lockfile
opened lockfile
Can't change lock - Resource temporarily unavailable
$

OTHER TIPS

It's not about different commands, I suppose; it's more about global differences between AIX and Linux.

In POSIX systems, file locks are advisory: each program could check the file's state and then reconsider what has to be done with it. No explicit checks = no locking.

In Linux systems, however, one can try to enforce a mandatory lock, although the doc itself states that it would be unwise to rely on it: implementation is (and probably will ever be) buggy.

Therefore, I suggest implementing such checks of advisory flags within the script itself.

More about it: man 2 fcntl, man 2 flock.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top