Preceptor has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I'm hoping this isn't too stupid a question. I have been trying to test (for a new system) locking files on NFS. My problem is - I'm having a real difficulty untangling what is a good way of accomplishing it - I've tracked down fcntl, and flock.

So is anyone able to give me a pointer in how this is done 'right'? All I really need is to be able to create and lock a test file (twice, so I can check if the lock is 'working'), and can run on multiple instances/hosts. I am aware that this is implementation dependent - but this is as much to test if I _can_ on our implementation, as anything else.

Thus far, I've got as my tests:

#!/usr/bin/env perl use strict; use warnings; use Fcntl qw ( :flock ); open ( my $lock_this, '>', 'lockfile_flock' ) or die $!; print "Enter to lock\n"; <>; print "Requesting EX lock\n"; flock ( $lock_this, LOCK_EX ); print "Lock acquired\n"; print "Enter to release\n"; <>; flock ( $lock_this, LOCK_UN ); print "Lock released\n";

I'm trying to do the same with fcntl, but am being flummoxed a bit by references to pack and flags. Is anyone able to give me an example of how using "fcntl" to lock a file is supposed to look in perl?

Replies are listed 'Best First'.
Re: NFS locking with Fcntl
by Preceptor (Deacon) on May 10, 2016 at 11:25 UTC

    Of course, shortly after posting - I found the answer, in this answer

    use strict; use Fcntl qw(SEEK_SET F_WRLCK F_UNLCK F_SETLKW); my($pack); open(FILE,">a"); $pack = pack('s s l l s', F_WRLCK, SEEK_SET, 0, 1, 0); print(fcntl(FILE, F_SETLKW, $pack) . "\n"); sleep(20); $pack = pack('s s l l s', F_UNLCK, SEEK_SET, 0, 1, 0); print(fcntl(FILE, F_SETLKW, $pack) . "\n"); close(FILE);

    This worked for me on my Linux implementation, to test whether locking over NFS works.

        Nor I. However, my requirement isn't to use it, it's to test whether it actually works at all. Further test may follow.

Re: NFS locking with Fcntl
by taint (Chaplain) on May 10, 2016 at 13:19 UTC
    Greetings, Preceptor.

    While I've never been particularly excited about the way the nfs protocol is implemented. It's your project. :)

    So I asked cpan about fcntl. Given the description: "Set / reset locks using fcntl", IPC::SRLock::Fcntl might be a good candidate. If you're implementing this on UNIX, or a UNIX-like system, POSIX::1003::Fcntl might also be of value. If for no other reason, than to provide some insight into the inner workings of the related functions. Lastly, perlfunc would be a good reference for you. :)


    λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH

      Well, no, it isn't. It's my storage array, and I'm being asked to test locking functionality. I know locking in general (and NFS specifically) are a bit of a 'fuzzy area' when it comes to file locking. And there's huge caveats on the relative interoperability. I'm trying to avoid specific perl modules, simply because this _should_ be language independent. I don't mind knocking up my test cases in C, if that's necessary - but I thought it _should_ be possible using perl built in hooks into C calls.

        It's only going to ever be, as good as the OS's implementation of it. So you're mileage will vary greatly, depending on what, and where it's implemented. Version is also a variable to consider. They're all based on the BSD/SUN implementation (links to follow(1, 2)) which dates back to the late 70's to the early 80's, and hasn't changed much, since then. My point being; your results won't have absolute returns -- they all pretty much suck. The client side/implementation is also a factor. Are/will you be testing on/for that, as well?

        The references I provided were just as good for use as modules, as they were for references for a better understanding of the underlying protocol(s). You could have just as easily "cobbled" up something that suites your needs using the code/references therein.

        You also might be interested in mmap for more efficient use of reading/writing of data from/to memory, from disk.


        1) unix history repo
        2) berkeley software distribution

        λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH

Re: NFS locking with Fcntl
by mr_mischief (Monsignor) on May 10, 2016 at 22:04 UTC

    What exactly is wrong with File::NFSLock that you have to find an alternative?

    What type of locking do you need or want? Do you want atomic, mandatory locking? Do you want advisory locking for a single application?

    Why are you using a filesystem that's long been known to have problems with this sort of thing when there are many shared filesystems and clustered, more reliable filesystems that don't?

      +1, mr_mischief.

      Thanks for saying that, as it got me to thinking that maybe Preceptor might be even better off trying something like Fuse. I think it matches his requirements to-the-letter. Albeit completely without nfs; it's written in Perl, and is OS agnostic. Well tested, and requires little effort on his part.

      Seems a perfect fit! :)


      λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH

        There's alternatives, but my actual requirement was to verify whether 'filesystem locking' works on NFS. Which is really vague, I know. But that was why I was seeking a system call based option, as that gives me a basis to say "it works" in at least an approximately language agnostic way.

        FWIW - on a 2.6.12+ Linux kernel, both flock and fcntl work. You will still have platform specific issues doing it regardless, but that isn't a new storage when it comes to NFS.