From 7cffec1d26a065c9dbbc662b09110c28a2549c36 Mon Sep 17 00:00:00 2001 From: Edwin Eefting Date: Tue, 26 Sep 2023 16:16:32 +0200 Subject: [PATCH] check guid of common snapshot, fix #218 --- tests/test_zfsautobackup32.py | 101 ++++++++++++++++++++++++++++++++++ zfs_autobackup/ZfsDataset.py | 17 +++++- 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 tests/test_zfsautobackup32.py diff --git a/tests/test_zfsautobackup32.py b/tests/test_zfsautobackup32.py new file mode 100644 index 0000000..ed1109d --- /dev/null +++ b/tests/test_zfsautobackup32.py @@ -0,0 +1,101 @@ +from basetest import * +import time + +class TestZfsAutobackup32(unittest2.TestCase): + """various new 3.2 features""" + + def setUp(self): + prepare_zpools() + self.longMessage=True + + def test_invalid_common_snapshot(self): + + with patch('time.strftime', return_value="test-20101111000000"): + self.assertFalse(ZfsAutobackup("test test_target1 --no-progress --verbose --allow-empty".split(" ")).run()) + + #create 2 snapshots with the same name, which are invalid as common snapshot + shelltest("zfs snapshot test_source1/fs1@invalid") + shelltest("zfs snapshot test_target1/test_source1/fs1@invalid") + + with patch('time.strftime', return_value="test-20101111000001"): + self.assertFalse(ZfsAutobackup("test test_target1 --no-progress --verbose --allow-empty".split(" ")).run()) + + r=shelltest("zfs list -H -o name -r -t all "+TEST_POOLS) + self.assertMultiLineEqual(r,""" +test_source1 +test_source1/fs1 +test_source1/fs1@test-20101111000000 +test_source1/fs1@invalid +test_source1/fs1@test-20101111000001 +test_source1/fs1/sub +test_source1/fs1/sub@test-20101111000000 +test_source1/fs1/sub@test-20101111000001 +test_source2 +test_source2/fs2 +test_source2/fs2/sub +test_source2/fs2/sub@test-20101111000000 +test_source2/fs2/sub@test-20101111000001 +test_source2/fs3 +test_source2/fs3/sub +test_target1 +test_target1/test_source1 +test_target1/test_source1/fs1 +test_target1/test_source1/fs1@test-20101111000000 +test_target1/test_source1/fs1@invalid +test_target1/test_source1/fs1@test-20101111000001 +test_target1/test_source1/fs1/sub +test_target1/test_source1/fs1/sub@test-20101111000000 +test_target1/test_source1/fs1/sub@test-20101111000001 +test_target1/test_source2 +test_target1/test_source2/fs2 +test_target1/test_source2/fs2/sub +test_target1/test_source2/fs2/sub@test-20101111000000 +test_target1/test_source2/fs2/sub@test-20101111000001 +""") + + def test_invalid_common_snapshot_with_data(self): + + with patch('time.strftime', return_value="test-20101111000000"): + self.assertFalse(ZfsAutobackup("test test_target1 --no-progress --verbose --allow-empty".split(" ")).run()) + + #create 2 snapshots with the same name, which are invalid as common snapshot + shelltest("zfs snapshot test_source1/fs1@invalid") + shelltest("zfs mount test_target1/test_source1/fs1") + shelltest("touch /test_target1/test_source1/fs1/shouldnotbeHere") + shelltest("zfs snapshot test_target1/test_source1/fs1@invalid") + + with patch('time.strftime', return_value="test-20101111000001"): + self.assertFalse(ZfsAutobackup("test test_target1 --no-progress --verbose --allow-empty --destroy-incompatible".split(" ")).run()) + + r=shelltest("zfs list -H -o name -r -t all "+TEST_POOLS) + self.assertMultiLineEqual(r,""" +test_source1 +test_source1/fs1 +test_source1/fs1@test-20101111000000 +test_source1/fs1@invalid +test_source1/fs1@test-20101111000001 +test_source1/fs1/sub +test_source1/fs1/sub@test-20101111000000 +test_source1/fs1/sub@test-20101111000001 +test_source2 +test_source2/fs2 +test_source2/fs2/sub +test_source2/fs2/sub@test-20101111000000 +test_source2/fs2/sub@test-20101111000001 +test_source2/fs3 +test_source2/fs3/sub +test_target1 +test_target1/test_source1 +test_target1/test_source1/fs1 +test_target1/test_source1/fs1@test-20101111000000 +test_target1/test_source1/fs1@test-20101111000001 +test_target1/test_source1/fs1/sub +test_target1/test_source1/fs1/sub@test-20101111000000 +test_target1/test_source1/fs1/sub@test-20101111000001 +test_target1/test_source2 +test_target1/test_source2/fs2 +test_target1/test_source2/fs2/sub +test_target1/test_source2/fs2/sub@test-20101111000000 +test_target1/test_source2/fs2/sub@test-20101111000001 +""") + diff --git a/zfs_autobackup/ZfsDataset.py b/zfs_autobackup/ZfsDataset.py index 06cf613..cbea0dc 100644 --- a/zfs_autobackup/ZfsDataset.py +++ b/zfs_autobackup/ZfsDataset.py @@ -58,6 +58,13 @@ class ZfsDataset: """ self.zfs_node.error("{}: {}".format(self.name, txt)) + def warning(self, txt): + """ + Args: + :type txt: str + """ + self.zfs_node.warning("{}: {}".format(self.name, txt)) + def debug(self, txt): """ Args: @@ -822,9 +829,13 @@ class ZfsDataset: return None else: for source_snapshot in reversed(self.snapshots): - if target_dataset.find_snapshot(source_snapshot): - source_snapshot.debug("common snapshot") - return source_snapshot + target_snapshot=target_dataset.find_snapshot(source_snapshot) + if target_snapshot: + if source_snapshot.properties['guid']!=target_snapshot.properties['guid']: + source_snapshot.warning("Common snapshot has invalid guid, ignoring.") + else: + source_snapshot.debug("common snapshot") + return source_snapshot target_dataset.error("Cant find common snapshot with source.") raise (Exception("You probably need to delete the target dataset to fix this."))