Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

pesky lockfile stays locked

by traxlog (Scribe)
on May 17, 2004 at 11:36 UTC ( #353928=perlquestion: print w/ replies, xml ) Need Help??
traxlog has asked for the wisdom of the Perl Monks concerning the following question:

Monks,
I am using the locking method described in the Camel book before opening my DB_File databases
use Fcntl qw(:DEFAULT :flock); use DB_File; # demo purposes only; any db is fine $DBNAME = "/path/to/database"; $LCK = $DBNAME . ".lockfile"; # use O_RDWR if you expect to put data in the lockfile sysopen(DBLOCK, $LCK, O_RDONLY | O_CREAT) or die "can't open $LCK: $!"; # must get lock before opening database flock(DBLOCK, LOCK_SH) or die "can't LOCK_SH $LCK: $!"; tie(%hash, "DB_File", $DBNAME, O_RDWR | O_CREAT) or die "can't tie $DBNAME: $!";

At the end of the program I call :
untie %hash; # must close database before lockfile close DBLOCK; # safe to let go of lock now


Unfortunately the lock not always released thus stopping further executions of the program (and any other programs that rely on the same lock). The only way to remedy this is to ftp the server and delete the lockfile.
I've been trying tactics around this such as timing out the operation, unlinking the lockfile, exiting immediately and asking the user (very politely) to try again. No elegant tactic, I know, but nevertheless effective.
Any suggestions esteemed ones?

Comment on pesky lockfile stays locked
Select or Download Code
Re: pesky lockfile stays locked
by Joost (Canon) on May 17, 2004 at 11:47 UTC
    Unfortunately the lock not always released thus stopping further executions of the program (and any other programs that rely on the same lock). The only way to remedy this is to ftp the server and delete the lockfile.
    Does that mean the program just doesn't end, or that it ends without releasing the lock?

    If the latter, try putting the untie() and close() statements in the END block of the program.

    If the former, you might have to fork off the process and keep an eye on the time it takes to run from the parent...

    OR, you could save the PID of the program in another file, and kill it if it has run for too long (also remove the lock), the next time you have to have access to the DB.

    Ofcoure, the last 2 methods might be very unsafe for your data....

    Hope this helps,
    Joost.

Re: pesky lockfile stays locked
by TilRMan (Friar) on May 17, 2004 at 13:18 UTC
    Don't you need to unlink() the lockfile when you're done? And why not just flock() the database file itself instead?

    Update: Don't mind me, I was confusing O_CREAT with O_EXCL.

      Do not rely on locking database files if you're relying on an external library to manipulate them.

      It used to be very common advice to lock database files - it was even in the Cookbook as a recipe. The ultimate source of this advice seems to have been Berkeley DB documentation circa version 1.65.

      However since then at least some dbm applications (Berkely DB among them) in multi-user situations will sometimes close and then re-open the database behind the scenes. Because of how flock works, any close to the file, even if you have another handle to that file open (such as the one holding a lock), will lose your flock. Then you're in the worst of all possible worlds. You don't actually have a lock, but you think that you do.

Re: pesky lockfile stays locked
by Abigail-II (Bishop) on May 17, 2004 at 13:31 UTC
    This is very strange. First of all, closing a filehandle should release all locks - and so should program termination. But what's even stranger is that the lock is a shared lock. Even if a copy of the program is still around locking the file, that shouldn't prevent another copy of the program from acquiring a lock.

    Are you sure that what you are experiencing is because of file locks?

    Abigail

      I also thought that program termination released locks, that's what puzzles me most.
      My apologies, but the lock in my code is actually LOCK_EX (I copied the code directly from the book instead of from my program).
      Unfortunately I've never witnessed the last run of the program before it stops, so I've no idea how it dies. I'm just assuming that it's the lockfile because as soon as I delete it all other programs run freely again. On average it occurs once every 2 days.
      I'm going to try coding in an END block and see if that alleviates the problem...... time will tell.

      Thanks everyone for your replies.
        Are you sure the program terminates? If a program hangs for some reason, no other program can continue, but removing the lockfile will "solve" the problem (well, not the problem - just the symptom, and it might cause data corruption - you are using locking for a reason).

        If all the programs that hold the lock terminate, and the file is still locked, the fault lies in your kernel, not in perl. It should be impossible for a file to be locked, without a locking process.

        Abigail

        A better thing to do would be, the next time it hangs, to do lsof lockfile (if you're on an OS that supports this), to see what process(es) still have the lock file open. Unless you have a very screwed-up OS, a process must habe an open file descriptor on a file to hold a lock.
        My apologies, but the lock in my code is actually LOCK_EX (I copied the code directly from the book instead of from my program).
        Don't do that. Copy and paste your actual code. Your problem may be some really subtle thing in your code, not the book.

        Unfortunately I've never witnessed the last run of the program before it stops, so I've no idea how it dies. I'm just assuming that it's the lockfile because as soon as I delete it all other programs run freely again.
        Huh? What do you mean "the last run of the program before it stops"? If it doesn't stop, why do you think it closes the file? Or do you mean that there are several processes all running the same code? When you say "all other programs", do you mean all other processes running the same code, or processes running different code? If it is different code, you need to post that, too.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (11)
As of 2014-09-19 12:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (138 votes), past polls