Commit 6800ed38 authored by Dietmar Maurer's avatar Dietmar Maurer

fix container locking (avoid multiple restore processes)

Unlike flock, LockFile::Simple does not inherit locks to child process.
So we need to do the locking inside the child process.
parent 945563d9
...@@ -319,16 +319,6 @@ __PACKAGE__->register_method({ ...@@ -319,16 +319,6 @@ __PACKAGE__->register_method({
} }
}; };
my $code = sub {
my $basecfg_fn = PVE::OpenVZ::config_file($vmid);
if ($param->{force}) {
die "cant overwrite mounted container\n" if PVE::OpenVZ::check_mounted($conf, $vmid);
} else {
die "CT $vmid already exists\n" if -f $basecfg_fn;
}
my $ostemplate = extract_param($param, 'ostemplate'); my $ostemplate = extract_param($param, 'ostemplate');
my $archive; my $archive;
...@@ -359,13 +349,27 @@ __PACKAGE__->register_method({ ...@@ -359,13 +349,27 @@ __PACKAGE__->register_method({
$param->{nameserver} = join(' ', @ns) if scalar(@ns); $param->{nameserver} = join(' ', @ns) if scalar(@ns);
} }
my $basecfg_fn = PVE::OpenVZ::config_file($vmid);
my $check_vmid_usage = sub {
if ($param->{force}) {
die "cant overwrite mounted container\n"
if PVE::OpenVZ::check_mounted($conf, $vmid);
} else {
die "CT $vmid already exists\n" if -f $basecfg_fn;
}
};
my $code = sub {
&$check_vmid_usage(); # final check after locking
PVE::OpenVZ::update_ovz_config($vmid, $conf, $param); PVE::OpenVZ::update_ovz_config($vmid, $conf, $param);
my $rawconf = PVE::OpenVZ::generate_raw_config($pve_base_ovz_config, $conf); my $rawconf = PVE::OpenVZ::generate_raw_config($pve_base_ovz_config, $conf);
PVE::Cluster::check_cfs_quorum(); PVE::Cluster::check_cfs_quorum();
my $realcmd = sub {
if ($param->{restore}) { if ($param->{restore}) {
&$restore_openvz($private, $archive, $vmid, $param->{force}); &$restore_openvz($private, $archive, $vmid, $param->{force});
...@@ -399,11 +403,12 @@ __PACKAGE__->register_method({ ...@@ -399,11 +403,12 @@ __PACKAGE__->register_method({
PVE::AccessControl::lock_user_config($addVMtoPoolFn, "can't add VM to pool") if $pool; PVE::AccessControl::lock_user_config($addVMtoPoolFn, "can't add VM to pool") if $pool;
}; };
my $realcmd = sub { PVE::OpenVZ::lock_container($vmid, 1, $code); };
&$check_vmid_usage(); # first check before locking
return $rpcenv->fork_worker($param->{restore} ? 'vzrestore' : 'vzcreate', return $rpcenv->fork_worker($param->{restore} ? 'vzrestore' : 'vzcreate',
$vmid, $authuser, $realcmd); $vmid, $authuser, $realcmd);
};
return PVE::OpenVZ::lock_container($vmid, $code);
}}); }});
my $vm_config_perm_list = [ my $vm_config_perm_list = [
...@@ -473,7 +478,7 @@ __PACKAGE__->register_method({ ...@@ -473,7 +478,7 @@ __PACKAGE__->register_method({
run_command($cmd); run_command($cmd);
}; };
PVE::OpenVZ::lock_container($vmid, $code); PVE::OpenVZ::lock_container($vmid, undef, $code);
return undef; return undef;
}}); }});
......
...@@ -1157,16 +1157,18 @@ sub generate_raw_config { ...@@ -1157,16 +1157,18 @@ sub generate_raw_config {
} }
sub create_lock_manager { sub create_lock_manager {
my ($max) = @_;
return LockFile::Simple->make(-format => '%f', return LockFile::Simple->make(-format => '%f',
-autoclean => 1, -autoclean => 1,
-max => 30, -max => defined($max) ? $max : 60,
-delay => 2, -delay => 1,
-stale => 1, -stale => 1,
-nfs => 0); -nfs => 0);
} }
sub lock_container { sub lock_container {
my ($vmid, $code, @param) = @_; my ($vmid, $max, $code, @param) = @_;
my $filename = $global_vzconf->{lockdir} . "/${vmid}.lck"; my $filename = $global_vzconf->{lockdir} . "/${vmid}.lck";
my $lock; my $lock;
...@@ -1174,12 +1176,11 @@ sub lock_container { ...@@ -1174,12 +1176,11 @@ sub lock_container {
eval { eval {
my $lockmgr = create_lock_manager(); my $lockmgr = create_lock_manager($max);
$lock = $lockmgr->lock($filename) || die "can't lock container $vmid\n"; $lock = $lockmgr->lock($filename) || die "can't lock container $vmid\n";
$res = &$code(@param); $res = &$code(@param);
}; };
my $err = $@; my $err = $@;
......
...@@ -18,7 +18,7 @@ use base qw(PVE::AbstractMigrate); ...@@ -18,7 +18,7 @@ use base qw(PVE::AbstractMigrate);
sub lock_vm { sub lock_vm {
my ($self, $vmid, $code, @param) = @_; my ($self, $vmid, $code, @param) = @_;
return PVE::OpenVZ::lock_container($vmid, $code, @param); return PVE::OpenVZ::lock_container($vmid, undef, $code, @param);
} }
sub prepare { sub prepare {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment