[pve-devel] [RFC PATCH common] Implement refcounting for flocks
Fabian Grünbichler
f.gruenbichler at proxmox.com
Wed Feb 10 08:25:23 CET 2016
This was already implemented in PVE::LXC::lock_aquire() and
lock_release(). Enabling refcounting in the general
PVE::Tools::lock_file() and lock_file_full() methods allows
us to use one code base for flocking.
Furthermore, we could get rid of various xx_no_lock methods
that were required because the old non-refcounting version
did not support nested flocks (the inner most flock would
close the file handle and thus release the flock).
---
A manual code review found no issues regarding nesting, and the refcounting
code is already used by the LXC codebase.
This should allow the LXC codebase to drop lock_aquire and lock_release, and
is a first step towards moving a lot of the duplicated config file handling
code in the LXC and Qemu codebases into pve-common.
src/PVE/Tools.pm | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
index 9f08aa6..60ba8aa 100644
--- a/src/PVE/Tools.pm
+++ b/src/PVE/Tools.pm
@@ -126,15 +126,16 @@ sub lock_file_full {
my $lock_func = sub {
if (!$lock_handles->{$$}->{$filename}) {
- $lock_handles->{$$}->{$filename} = new IO::File (">>$filename") ||
- die "can't open file - $!\n";
+ my $fh = new IO::File(">>$filename") ||
+ die "can't open file - $!\n";
+ $lock_handles->{$$}->{$filename} = { fh => $fh, refcount => 0};
}
- if (!flock ($lock_handles->{$$}->{$filename}, $mode|LOCK_NB)) {
+ if (!flock($lock_handles->{$$}->{$filename}->{fh}, $mode|LOCK_NB)) {
print STDERR "trying to acquire lock...";
my $success;
while(1) {
- $success = flock($lock_handles->{$$}->{$filename}, $mode);
+ $success = flock($lock_handles->{$$}->{$filename}->{fh}, $mode);
# try again on EINTR (see bug #273)
if ($success || ($! != EINTR)) {
last;
@@ -146,6 +147,7 @@ sub lock_file_full {
}
print STDERR " OK\n";
}
+ $lock_handles->{$$}->{$filename}->{refcount}++;
};
my $res;
@@ -159,9 +161,12 @@ sub lock_file_full {
$err = $@;
}
- if (my $fh = $lock_handles->{$$}->{$filename}) {
- $lock_handles->{$$}->{$filename} = undef;
- close ($fh);
+ if (my $fh = $lock_handles->{$$}->{$filename}->{fh}) {
+ my $refcount = --$lock_handles->{$$}->{$filename}->{refcount};
+ if ($refcount <= 0) {
+ $lock_handles->{$$}->{$filename} = undef;
+ close ($fh);
+ }
}
if ($err) {
--
2.1.4
More information about the pve-devel
mailing list