From: Fabian Grünbichler Date: Fri, 11 Mar 2016 10:44:47 +0000 (+0100) Subject: Prevent race conditions in snapshot mode backup X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=91458f714d1ba619107194c051d57e1cfbca1fa9;p=pve-container.git Prevent race conditions in snapshot mode backup Instead of dropping the 'backup' lock early on when doing snapshot backups, drop it temporarily for snapshot operations that set their own 'snapshot' lock, and protect the "unlock_vm, snapshot_XX, lock_vm" sequence by holding an flock for the config file. Before this change it was possible to interfere with the backup job by setting a different lock with another operation inbetween the call to unlock_vm and snapshot_create (or snapshot_delete). The final lock_vm is re-introduced in order to be more consistent with the other backup modes and to prevent changes to the configuration file before assemble() reloads the configuration that is included in the backup. --- diff --git a/src/PVE/VZDump/LXC.pm b/src/PVE/VZDump/LXC.pm index 1bad3fd..e7a307f 100644 --- a/src/PVE/VZDump/LXC.pm +++ b/src/PVE/VZDump/LXC.pm @@ -134,11 +134,14 @@ 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::Config->snapshot_delete($vmid, 'vzdump', 1); + PVE::LXC::Config->lock_config($vmid, sub { + $self->unlock_vm($vmid); + PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 1); + $self->lock_vm($vmid); + }); } my $rootdir = $default_mount_point; @@ -189,7 +192,11 @@ sub snapshot { $self->loginfo("create storage snapshot 'vzdump'"); # todo: freeze/unfreeze if we have more than one volid - PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot"); + PVE::LXC::Config->lock_config($vmid, sub { + $self->unlock_vm($vmid); + PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot"); + $self->lock_vm($vmid); + }); $task->{cleanup}->{remove_snapshot} = 1; # reload config