@@ -1055,7 +1055,7 @@ async fn test_snapshot_clone() {
1055
1055
let clones = snapshot_lvol. list_clones_by_snapshot_uuid ( ) ;
1056
1056
1057
1057
assert_eq ! ( clones. len( ) , 2 , "Number of Clones Doesn't match" ) ;
1058
- for clone in clones {
1058
+ for clone in & clones {
1059
1059
assert ! (
1060
1060
clone. is_snapshot_clone( ) . is_some( ) ,
1061
1061
"Wrongly judge as not a clone"
@@ -1066,6 +1066,10 @@ async fn test_snapshot_clone() {
1066
1066
snapshot_lvol. is_snapshot_clone( ) . is_none( ) ,
1067
1067
"Wrongly judge as clone"
1068
1068
) ;
1069
+ for clone in clones {
1070
+ clone. destroy ( ) . await . expect ( "destroy clone failed" ) ;
1071
+ }
1072
+ clean_snapshots ( Lvol :: list_all_snapshots ( ) ) . await ;
1069
1073
} )
1070
1074
. await ;
1071
1075
}
@@ -1554,3 +1558,228 @@ async fn test_snapshot_verify_restore_data() {
1554
1558
// Check the original replica and restore clone is identical.
1555
1559
validate_replicas ( & vec ! [ repl_1. clone( ) , restore_1. clone( ) ] ) . await ;
1556
1560
}
1561
+
1562
+ #[ tokio:: test]
1563
+ async fn test_snapshot_parent_usage_post_snapshot_destroy ( ) {
1564
+ let ms = get_ms ( ) ;
1565
+ const LVOL_NAME : & str = "lvol16" ;
1566
+
1567
+ ms. spawn ( async move {
1568
+ // Create a pool and lvol.
1569
+ let pool = create_test_pool (
1570
+ "pool16" ,
1571
+ "malloc:///disk16?size_mb=128" . to_string ( ) ,
1572
+ )
1573
+ . await ;
1574
+ let lvol = pool
1575
+ . create_lvol (
1576
+ LVOL_NAME ,
1577
+ 32 * 1024 * 1024 ,
1578
+ Some ( & Uuid :: new_v4 ( ) . to_string ( ) ) ,
1579
+ true ,
1580
+ )
1581
+ . await
1582
+ . expect ( "Failed to create test lvol" ) ;
1583
+ let cluster_size = pool. blob_cluster_size ( ) ;
1584
+ // Create a test snapshot.
1585
+ let entity_id = String :: from ( "lvol16_e1" ) ;
1586
+ let parent_id = lvol. uuid ( ) ;
1587
+ let txn_id = Uuid :: new_v4 ( ) . to_string ( ) ;
1588
+ let snap_name = String :: from ( "lvol16_snap1" ) ;
1589
+ let snapshot_uuid = Uuid :: new_v4 ( ) . to_string ( ) ;
1590
+
1591
+ let snapshot_params = SnapshotParams :: new (
1592
+ Some ( entity_id) ,
1593
+ Some ( parent_id) ,
1594
+ Some ( txn_id) ,
1595
+ Some ( snap_name) ,
1596
+ Some ( snapshot_uuid) ,
1597
+ Some ( Utc :: now ( ) . to_string ( ) ) ,
1598
+ false ,
1599
+ ) ;
1600
+
1601
+ bdev_io:: write_some ( LVOL_NAME , 2 * cluster_size, 16 , 0xaau8 )
1602
+ . await
1603
+ . expect ( "Failed to write data to volume" ) ;
1604
+ lvol. create_snapshot ( snapshot_params. clone ( ) )
1605
+ . await
1606
+ . expect ( "Failed to create the first snapshot for test volume" ) ;
1607
+ let snapshot_list = Lvol :: list_all_snapshots ( ) ;
1608
+ assert_eq ! ( 1 , snapshot_list. len( ) , "Snapshot Count not matched!!" ) ;
1609
+
1610
+ let snapshot_lvol = UntypedBdev :: lookup_by_uuid_str (
1611
+ snapshot_list
1612
+ . get ( 0 )
1613
+ . unwrap ( )
1614
+ . snapshot_params ( )
1615
+ . snapshot_uuid ( )
1616
+ . unwrap_or_default ( )
1617
+ . as_str ( ) ,
1618
+ )
1619
+ . map ( |b| Lvol :: try_from ( b) . expect ( "Can't create Lvol from device" ) )
1620
+ . unwrap ( ) ;
1621
+ assert_eq ! (
1622
+ lvol. usage( ) . allocated_bytes,
1623
+ 0 ,
1624
+ "Source Lvol size should be 0, after snapshot created from it"
1625
+ ) ;
1626
+
1627
+ bdev_io:: write_some ( LVOL_NAME , 3 * cluster_size, 16 , 0xbbu8 )
1628
+ . await
1629
+ . expect ( "Failed to write data to volume" ) ;
1630
+ bdev_io:: write_some ( LVOL_NAME , 4 * cluster_size, 16 , 0xccu8 )
1631
+ . await
1632
+ . expect ( "Failed to write data to volume" ) ;
1633
+ snapshot_lvol
1634
+ . destroy ( )
1635
+ . await
1636
+ . expect ( "Destroy snapshot failed" ) ;
1637
+ assert_eq ! (
1638
+ lvol. usage( ) . allocated_bytes,
1639
+ 5 * cluster_size,
1640
+ "Source Lvol size should be restored after snapshot destroy"
1641
+ ) ;
1642
+ } )
1643
+ . await ;
1644
+ }
1645
+
1646
+ #[ tokio:: test]
1647
+ async fn test_clone_snapshot_usage_post_clone_destroy ( ) {
1648
+ let ms = get_ms ( ) ;
1649
+ const LVOL_NAME : & str = "lvol17" ;
1650
+
1651
+ ms. spawn ( async move {
1652
+ // Create a pool and lvol.
1653
+ let pool = create_test_pool (
1654
+ "pool17" ,
1655
+ "malloc:///disk17?size_mb=128" . to_string ( ) ,
1656
+ )
1657
+ . await ;
1658
+ let lvol = pool
1659
+ . create_lvol (
1660
+ LVOL_NAME ,
1661
+ 32 * 1024 * 1024 ,
1662
+ Some ( & Uuid :: new_v4 ( ) . to_string ( ) ) ,
1663
+ true ,
1664
+ )
1665
+ . await
1666
+ . expect ( "Failed to create test lvol" ) ;
1667
+ let cluster_size = pool. blob_cluster_size ( ) ;
1668
+ // Create a test snapshot.
1669
+ let entity_id = String :: from ( "lvol17_e1" ) ;
1670
+ let parent_id = lvol. uuid ( ) ;
1671
+ let txn_id = Uuid :: new_v4 ( ) . to_string ( ) ;
1672
+ let snap_name = String :: from ( "lvol17_snap1" ) ;
1673
+ let snapshot_uuid = Uuid :: new_v4 ( ) . to_string ( ) ;
1674
+
1675
+ let mut snapshot_params = SnapshotParams :: new (
1676
+ Some ( entity_id) ,
1677
+ Some ( parent_id) ,
1678
+ Some ( txn_id) ,
1679
+ Some ( snap_name) ,
1680
+ Some ( snapshot_uuid) ,
1681
+ Some ( Utc :: now ( ) . to_string ( ) ) ,
1682
+ false ,
1683
+ ) ;
1684
+
1685
+ bdev_io:: write_some ( LVOL_NAME , 2 * cluster_size, 16 , 0xaau8 )
1686
+ . await
1687
+ . expect ( "Failed to write data to volume" ) ;
1688
+ lvol. create_snapshot ( snapshot_params. clone ( ) )
1689
+ . await
1690
+ . expect ( "Failed to create the first snapshot for test volume" ) ;
1691
+ let snapshot_list = Lvol :: list_all_snapshots ( ) ;
1692
+ assert_eq ! ( 1 , snapshot_list. len( ) , "Snapshot Count not matched!!" ) ;
1693
+
1694
+ let snapshot_lvol = UntypedBdev :: lookup_by_uuid_str (
1695
+ snapshot_list
1696
+ . get ( 0 )
1697
+ . unwrap ( )
1698
+ . snapshot_params ( )
1699
+ . snapshot_uuid ( )
1700
+ . unwrap_or_default ( )
1701
+ . as_str ( ) ,
1702
+ )
1703
+ . map ( |b| Lvol :: try_from ( b) . expect ( "Can't create Lvol from device" ) )
1704
+ . unwrap ( ) ;
1705
+ assert_eq ! (
1706
+ lvol. usage( ) . allocated_bytes,
1707
+ 0 ,
1708
+ "Source Lvol size should be 0, after snapshot created from it"
1709
+ ) ;
1710
+
1711
+ let clone_name = String :: from ( "lvol17_snap1_clone_1" ) ;
1712
+ let clone_uuid = Uuid :: new_v4 ( ) . to_string ( ) ;
1713
+ let source_uuid = snapshot_lvol. uuid ( ) ;
1714
+
1715
+ let clone_param = CloneParams :: new (
1716
+ Some ( clone_name) ,
1717
+ Some ( clone_uuid) ,
1718
+ Some ( source_uuid) ,
1719
+ Some ( Utc :: now ( ) . to_string ( ) ) ,
1720
+ ) ;
1721
+ let clone1 = snapshot_lvol
1722
+ . create_clone ( clone_param. clone ( ) )
1723
+ . await
1724
+ . expect ( "Failed to create a clone" ) ;
1725
+ bdev_io:: write_some ( "lvol17_snap1_clone_1" , 0 , 16 , 0xbbu8 )
1726
+ . await
1727
+ . expect ( "Failed to write data to volume" ) ;
1728
+ snapshot_params. set_parent_id ( clone1. uuid ( ) ) ;
1729
+ snapshot_params. set_entity_id ( String :: from ( "lvol17_clone1_e1" ) ) ;
1730
+ snapshot_params. set_name ( String :: from ( "lvol17_clone_1_snap1" ) ) ;
1731
+ snapshot_params. set_snapshot_uuid ( Uuid :: new_v4 ( ) . to_string ( ) ) ;
1732
+ snapshot_params. set_txn_id ( Uuid :: new_v4 ( ) . to_string ( ) ) ;
1733
+
1734
+ clone1
1735
+ . create_snapshot ( snapshot_params. clone ( ) )
1736
+ . await
1737
+ . expect ( "Failed to create the first snapshot for test volume" ) ;
1738
+ snapshot_params. set_parent_id ( clone1. uuid ( ) ) ;
1739
+ snapshot_params. set_entity_id ( String :: from ( "lvol17_clone1_e2" ) ) ;
1740
+ snapshot_params. set_name ( String :: from ( "lvol17_clone_1_snap2" ) ) ;
1741
+ snapshot_params. set_snapshot_uuid ( Uuid :: new_v4 ( ) . to_string ( ) ) ;
1742
+ snapshot_params. set_txn_id ( Uuid :: new_v4 ( ) . to_string ( ) ) ;
1743
+ bdev_io:: write_some (
1744
+ "lvol17_snap1_clone_1" ,
1745
+ 3 * cluster_size,
1746
+ 16 ,
1747
+ 0xbbu8 ,
1748
+ )
1749
+ . await
1750
+ . expect ( "Failed to write data to volume" ) ;
1751
+ clone1
1752
+ . create_snapshot ( snapshot_params. clone ( ) )
1753
+ . await
1754
+ . expect ( "Failed to create the first snapshot for test volume" ) ;
1755
+ let mut clone_snapshot: Vec < Lvol > = clone1
1756
+ . list_snapshot_by_source_uuid ( )
1757
+ . iter ( )
1758
+ . map ( |v| v. snapshot_lvol ( ) . clone ( ) )
1759
+ . collect ( ) ;
1760
+ lvol. destroy ( )
1761
+ . await
1762
+ . expect ( "Original replica destroy failed" ) ;
1763
+ clone1
1764
+ . destroy_replica ( )
1765
+ . await
1766
+ . expect ( "Destroy Clone failed" ) ;
1767
+ assert_eq ! (
1768
+ clone_snapshot. len( ) ,
1769
+ 2 ,
1770
+ "Number of Clone Snapshot not matched"
1771
+ ) ;
1772
+ assert_eq ! (
1773
+ clone_snapshot. remove( 0 ) . usage( ) . allocated_bytes,
1774
+ cluster_size,
1775
+ "Clone1 snap1 cache is not cleared"
1776
+ ) ;
1777
+ assert_eq ! (
1778
+ clone_snapshot. remove( 0 ) . usage( ) . allocated_bytes,
1779
+ cluster_size,
1780
+ "Clone1 snap2 cache is not cleared"
1781
+ ) ;
1782
+ clean_snapshots ( Lvol :: list_all_snapshots ( ) ) . await ;
1783
+ } )
1784
+ . await ;
1785
+ }
0 commit comments