[pve-devel] [PATCH v2 container] VZDump lock update, drop lock_aquire/lock_release
Fabian Grünbichler
f.gruenbichler at proxmox.com
Wed Feb 10 12:01:17 CET 2016
Since VZDump was the only user of lock_aquire and
lock_release, and does not actually need this split,
we can drop lock_aquire and lock_release.
Since lock_file_full in PVE::Tools now uses the same
refcounting implementation that lock_aquire/release
had, lock_container can simply wrap lock_file_full.
---
Changes since v1: drop lock_container implementation
in favour of wrapping lock_file_full
src/PVE/LXC.pm | 66 ++++-----------------------------------------------
src/PVE/VZDump/LXC.pm | 57 ++++++++++++++++++++++----------------------
2 files changed, 32 insertions(+), 91 deletions(-)
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 6a3489a..23b5f72 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -624,76 +624,18 @@ sub lock_filename {
return "$lockdir/pve-config-${vmid}.lock";
}
-sub lock_aquire {
- my ($vmid, $timeout) = @_;
+sub lock_container {
+ my ($vmid, $timeout, $code, @param) = @_;
$timeout = 10 if !$timeout;
- my $mode = LOCK_EX;
my $filename = lock_filename($vmid);
mkdir $lockdir if !-d $lockdir;
- my $lock_func = sub {
- if (!$lock_handles->{$$}->{$filename}) {
- my $fh = new IO::File(">>$filename") ||
- die "can't open file - $!\n";
- $lock_handles->{$$}->{$filename} = { fh => $fh, refcount => 0};
- }
-
- if (!flock($lock_handles->{$$}->{$filename}->{fh}, $mode |LOCK_NB)) {
- print STDERR "trying to aquire lock...";
- my $success;
- while(1) {
- $success = flock($lock_handles->{$$}->{$filename}->{fh}, $mode);
- # try again on EINTR (see bug #273)
- if ($success || ($! != EINTR)) {
- last;
- }
- }
- if (!$success) {
- print STDERR " failed\n";
- die "can't aquire lock - $!\n";
- }
-
- print STDERR " OK\n";
- }
-
- $lock_handles->{$$}->{$filename}->{refcount}++;
- };
-
- eval { PVE::Tools::run_with_timeout($timeout, $lock_func); };
- my $err = $@;
- if ($err) {
- die "can't lock file '$filename' - $err";
- }
-}
-
-sub lock_release {
- my ($vmid) = @_;
-
- my $filename = lock_filename($vmid);
-
- if (my $fh = $lock_handles->{$$}->{$filename}->{fh}) {
- my $refcount = --$lock_handles->{$$}->{$filename}->{refcount};
- if ($refcount <= 0) {
- $lock_handles->{$$}->{$filename} = undef;
- close ($fh);
- }
- }
-}
-
-sub lock_container {
- my ($vmid, $timeout, $code, @param) = @_;
-
- my $res;
-
- lock_aquire($vmid, $timeout);
- eval { $res = &$code(@param) };
- my $err = $@;
- lock_release($vmid);
+ my $res = PVE::Tools::lock_file_full($filename, $timeout, 0, $code, @param);
- die $err if $err;
+ die $@ if $@;
return $res;
}
diff --git a/src/PVE/VZDump/LXC.pm b/src/PVE/VZDump/LXC.pm
index 3bd34b6..57dcbe2 100644
--- a/src/PVE/VZDump/LXC.pm
+++ b/src/PVE/VZDump/LXC.pm
@@ -94,28 +94,6 @@ my $check_mountpoint_empty = sub {
});
};
-my $lockconfig = sub {
- my ($self, $vmid) = @_;
-
- my $conf = PVE::LXC::load_config($vmid);
-
- PVE::LXC::check_lock($conf);
- $conf->{lock} = 'backup';
-
- PVE::LXC::write_config($vmid, $conf);
-};
-
-my $unlockconfig = sub {
- my ($self, $vmid) = @_;
-
- my $conf = PVE::LXC::load_config($vmid);
-
- if ($conf->{lock} && $conf->{lock} eq 'backup') {
- delete $conf->{lock};
- PVE::LXC::write_config($vmid, $conf);
- }
-};
-
sub prepare {
my ($self, $task, $vmid, $mode) = @_;
@@ -156,6 +134,8 @@ sub prepare {
die "mode failure - some volumes do not support snapshots\n";
}
+ unlock_vm($self, $vmid);
+
if ($conf->{snapshots} && $conf->{snapshots}->{vzdump}) {
$self->loginfo("found old vzdump snapshot (force removal)");
PVE::LXC::snapshot_delete($vmid, 'vzdump', 1);
@@ -168,26 +148,21 @@ sub prepare {
# set snapshot_count (freezes CT if snapshot_count > 1)
$task->{snapshot_count} = scalar(@$volid_list);
} elsif ($mode eq 'stop') {
- &$lockconfig($self, $vmid);
-
my $rootdir = $default_mount_point;
mkpath $rootdir;
&$check_mountpoint_empty($rootdir);
PVE::Storage::activate_volumes($storage_cfg, $volid_list);
} elsif ($mode eq 'suspend') {
- &$lockconfig($self, $vmid);
-
my $pid = PVE::LXC::find_lxc_pid($vmid);
foreach my $disk (@$disks) {
$disk->{dir} = "/proc/$pid/root$disk->{mp}";
}
$task->{snapdir} = $task->{tmpdir};
} else {
+ unlock_vm($self, $vmid);
die "unknown mode '$mode'\n"; # should not happen
}
- PVE::LXC::lock_release($vmid);
-
if ($mode ne 'suspend') {
# If we perform mount operations, let's unshare the mount namespace
# to not influence the running host.
@@ -198,11 +173,35 @@ sub prepare {
sub lock_vm {
my ($self, $vmid) = @_;
- PVE::LXC::lock_aquire($vmid);
+
+ my $lockconfig = sub {
+ my ($self, $vmid) = @_;
+
+ my $conf = PVE::LXC::load_config($vmid);
+
+ PVE::LXC::check_lock($conf);
+ $conf->{lock} = 'backup';
+
+ PVE::LXC::write_config($vmid, $conf);
+ };
+
+ PVE::LXC::lock_container($vmid, 10, $lockconfig, ($self, $vmid));
}
sub unlock_vm {
my ($self, $vmid) = @_;
+
+ my $unlockconfig = sub {
+ my ($self, $vmid) = @_;
+
+ my $conf = PVE::LXC::load_config($vmid);
+
+ if ($conf->{lock} && $conf->{lock} eq 'backup') {
+ delete $conf->{lock};
+ PVE::LXC::write_config($vmid, $conf);
+ }
+ };
+
PVE::LXC::lock_container($vmid, 60, $unlockconfig, ($self, $vmid));
}
--
2.1.4
More information about the pve-devel
mailing list