Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

With a fcntl lock, why this lsof output?

by welchavw (Pilgrim)
on Sep 23, 2005 at 21:28 UTC ( #494686=perlquestion: print w/ replies, xml ) Need Help??
welchavw has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a small program (below) to enable me to replace the /etc/sudoers file (via an RPM), while respecting visudo and its file lock. (First thing, please note that the visudo man page, at least for my distro is wrong - there is no lock on /etc/sudoers.tmp AFAICT). I am doing this on x86 FC4 (so that you may grok the pack()). Basically, this program works - when I do a visudo after acquiring the lock through this program, it behaves just like 2 visudos were contending. That is, I get a "visudo: sudoers file busy, try again later." So all is swell, except I am picky and ...

I look at the output of "lsof -p" for visudo and compare the same output for the perl program.

When visudo is running, I get...

visudo 13070 root 3uW REG 3,3 640 12835419 /etc/sudoers

When the perl program is running (having gotten lock and is looping), I get...

fcntl_loc 13091 root 3w REG 3,3 640 12835419 /etc/sudoers

See, the 3uW looks good for visudo, but where's the "W" to indicate write lock for the perl? Do I have a file lock, or is visudo failing to acquire the lock on /etc/sudoers for some other reason while this perl code is running?

So, I wonder if perhaps my pack is wrong and I am stomping on some memory. Or else something else is going on? Its too late on Friday for me to see what it is - maybe one of you monks can? (Pls don't kill me for the treatment of $rc - this code is just hacked together, thx).

Here's the program.

#!/usr/bin/perl use Fcntl qw(:DEFAULT :flock); use Errno qw(EAGAIN); use strict; use warnings; @ARGV == 1 or die "usage: $0 <filename>\n"; print "opening $ARGV[0]...\n"; open my $fh, ">>$ARGV[0]" or die "open:$!\n"; my $results = pack( "sslll", &F_WRLCK, 0, 0, 0, 0); print "locking $ARGV[0]...\n"; my $rc; while (1) { $rc = fcntl($fh, F_SETLK, $results); last if ($! != EAGAIN || (defined $rc && $rc == 0)); print "sleeping...\n"; sleep 5; print "trying again...\n"; } if ((!defined $rc) || $rc != 0) { die "fcntl:$!\n" }; print "looping forever...\n"; sleep 64*64;

Comment on With a fcntl lock, why this lsof output?
Select or Download Code
Replies are listed 'Best First'.
Re: With a fcntl lock, why this lsof output?
by traveler (Parson) on Sep 23, 2005 at 22:55 UTC
    The issue is that you use fcntl to get a byte-level write lock (the lowercase w) while visudo uses flock or lockf (depending on what you have) to lock the whole file (uppercase W). The lowercase u is because visudo opens the file read-write and you open it for append.

    HTH, --traveler

      Perfect. Thank you. I grabbed File::lockf and was indeed able to see that lockf with a "+<" mode open exactly replicates the visudo locking. I had never ventured into deeply enough into file-locking to learn of the multiple APIs and their differences.

      Regards,
      Adam

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://494686]
Approved by larryp
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (14)
As of 2015-07-30 14:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (271 votes), past polls