fixes #2991, #2528. creating a snapshot with rbd, after the syncfs finished successfully does not guarantee that the snapshot has the state of the filesystem after syncfs.
suggestion taken from #2528 (running fsfreeze -f/-u before snapshotting on the mountpoints) added helper PVE::Storage::volume_snapshot_needs_fsfreeze, to indicate which volumes need to be frozen/thawed. (and mocked it in the tests here). Added the freeze to sync_container_namespace, since it needs to run inside the container's mount namespace. unfreezing happens in a sub of its own. tests in #2991 seem to indicate that this helps to successfully create backups. needs a versioned dependency bump on pve-storage Signed-off-by: Stoiko Ivanov <s.iva...@proxmox.com> --- src/PVE/LXC/Config.pm | 28 ++++++++++++++++++++++++++++ src/test/snapshot-test.pm | 12 +++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm index 0528d51..9834866 100644 --- a/src/PVE/LXC/Config.pm +++ b/src/PVE/LXC/Config.pm @@ -2,6 +2,7 @@ package PVE::LXC::Config; use strict; use warnings; +use Fcntl qw(O_RDONLY); use PVE::AbstractConfig; use PVE::Cluster qw(cfs_register_file); @@ -131,12 +132,39 @@ sub fsfreeze_mountpoint { sub __snapshot_freeze { my ($class, $vmid, $unfreeze) = @_; + my $conf = $class->load_config($vmid); + my $storagecfg = PVE::Storage::config(); + + my $freeze_mps = []; + $class->foreach_volume($conf, sub { + my ($ms, $mountpoint) = @_; + + if (PVE::Storage::volume_snapshot_needs_fsfreeze($storagecfg, $mountpoint->{volume})) { + push @$freeze_mps, $mountpoint->{mp}; + } + }); + + my $freeze_mountpoints = sub { + my ($thaw) = @_; + + return if scalar(@$freeze_mps) == 0; + + my $pid = PVE::LXC::find_lxc_pid($vmid); + + for my $mp (@$freeze_mps) { + eval{ fsfreeze_mountpoint("/proc/${pid}/root/${mp}", $thaw); }; + warn $@ if $@; + } + }; + if ($unfreeze) { eval { PVE::LXC::thaw($vmid); }; warn $@ if $@; + $freeze_mountpoints->(1); } else { PVE::LXC::freeze($vmid); PVE::LXC::sync_container_namespace($vmid); + $freeze_mountpoints->(0); } } diff --git a/src/test/snapshot-test.pm b/src/test/snapshot-test.pm index bfb8551..91a2af9 100644 --- a/src/test/snapshot-test.pm +++ b/src/test/snapshot-test.pm @@ -113,6 +113,15 @@ sub mocked_volume_rollback_is_possible { die "volume_rollback_is_possible failed\n"; } +sub mocked_volume_snapshot_needs_fsfreeze { + my ($storecfg, $volid) = @_; + die "Storage config not mocked! aborting\n" + if defined($storecfg); + die "volid undefined\n" + if !defined($volid); + return 0; +} + sub mocked_vm_stop { if ($kill_possible) { $running = 0; @@ -386,7 +395,8 @@ $storage_module->mock('volume_snapshot', \&mocked_volume_snapshot); $storage_module->mock('volume_snapshot_delete', \&mocked_volume_snapshot_delete); $storage_module->mock('volume_snapshot_rollback', \&mocked_volume_snapshot_rollback); $storage_module->mock('volume_rollback_is_possible', \&mocked_volume_rollback_is_possible); -printf("\tconfig(), volume_snapshot(), volume_snapshot_delete(), volume_snapshot_rollback() and volume_rollback_is_possible() mocked\n"); +$storage_module->mock('volume_snapshot_needs_fsfreeze', \&mocked_volume_snapshot_needs_fsfreeze); +printf("\tconfig(), volume_snapshot(), volume_snapshot_delete(), volume_snapshot_rollback(), volume_rollback_is_possible() and volume_snapshot_needs_fsfreeze() mocked\n"); printf("\n"); printf("Setting up Mocking for PVE::Tools\n"); -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel