Tools: make file-locking aware of external exception sources
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 11 May 2017 10:40:02 +0000 (12:40 +0200)
committerFabian Gr├╝nbichler <f.gruenbichler@proxmox.com>
Fri, 12 May 2017 09:40:26 +0000 (11:40 +0200)
commitd9f86d0d87ba6ec268c54966ea937c0781c70433
treecabda6382701ddee5c2240a52ed65d1963e6ed6c
parent2d63b598e13704661c93b8d296a8a7e3f2ac9464
Tools: make file-locking aware of external exception sources

Previously an external exception (eg. caused by a SIGARLM in a code
which is already inside a run_with_timeout() call) could happen in
various places where we did not properly this situation.
For instance after calling $lock_func() but before reaching the cleanup
code. In this case a lock was leaked.
Additionally the code was broken in that it used perl's automatic hash
creation side effect ($a->{x}->{y} implicitly initializing $a->{x} with
an empty hash when it did not exist). The effect was that if our own
time out was triggered after the initial check for an existing file
handle inside $lock_func() happened (extremely rare since perl would have
to be running insanely slow), the cleanup did:

    if (my $fh = $lock_handles->{$$}->{$filename}->{fh}) {

This recreated $lock_handles->{$$}->{$filename} as an empty hash.
A subsequent call to lock_file_full() will think a file descriptor
already exists because the check simply used:

    if (!$lock_handles->{$$}->{$filename}) {

While this could have been a one-line fix for this one particular case,
we'd still not be taking external timeouts into account causing the
first issue described above.
src/PVE/Tools.pm
test/Makefile
test/lock_file.pl [new file with mode: 0755]