From cd7301782acc4a23b43ae83fc5934c6f92e124fe Mon Sep 17 00:00:00 2001 From: Dmitry Savitskiy Date: Mon, 19 Feb 2024 12:25:54 +0300 Subject: [PATCH] fix(lvs): fixing issues with large number of volumes Fixing issues with exporting and importing of large number of volumes. Signed-off-by: Dmitry Savitskiy --- io-engine/tests/lvs_import.rs | 141 ++++++++++++++++++++++++++++++++++ nix/pkgs/libspdk/default.nix | 6 +- 2 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 io-engine/tests/lvs_import.rs diff --git a/io-engine/tests/lvs_import.rs b/io-engine/tests/lvs_import.rs new file mode 100644 index 0000000000..ac62a7e56b --- /dev/null +++ b/io-engine/tests/lvs_import.rs @@ -0,0 +1,141 @@ +pub mod common; + +use io_engine::{ + core::{logical_volume::LogicalVolume, MayastorCliArgs, SnapshotOps}, + lvs::Lvs, + pool_backend::PoolArgs, +}; + +use io_engine_tests::MayastorTest; + +use once_cell::sync::OnceCell; +use std::{collections::HashSet, time::Instant}; + +const DISK_SIZE: u64 = 10000; +const REPL_SIZE: u64 = 16; +const DISK_NAME: &str = "/tmp/disk0.img"; +const BDEV_NAME: &str = "aio:///tmp/disk0.img?blk_size=512"; +const POOL_NAME: &str = "pool_0"; +const POOL_UUID: &str = "40baf8b5-6256-4f29-b073-61ebf67d9b91"; + +static MAYASTOR: OnceCell = OnceCell::new(); + +fn get_ms() -> &'static MayastorTest<'static> { + MAYASTOR.get_or_init(|| { + MayastorTest::new(MayastorCliArgs { + log_format: Some("nodate,nohost,compact".parse().unwrap()), + reactor_mask: "0x3".into(), + enable_io_all_thrd_nexus_channels: true, + ..Default::default() + }) + }) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn lvs_import_many_volume() { + const REPL_CNT: u64 = 100; + const SNAP_CNT: u64 = 10; + + common::composer_init(); + + common::delete_file(&[DISK_NAME.to_string()]); + common::truncate_file_bytes(DISK_NAME, DISK_SIZE * 1024 * 1024); + + let ms = get_ms(); + + ms.spawn(async { + // Set of UUIDs of successfully created volumes (replicas and + // snapshots). + let mut created: HashSet = HashSet::new(); + + let lvs_args = PoolArgs { + name: POOL_NAME.to_string(), + disks: vec![BDEV_NAME.to_string()], + uuid: Some(POOL_UUID.to_string()), + cluster_size: None, + }; + + // Create LVS. + let lvs = Lvs::create_or_import(lvs_args.clone()).await.unwrap(); + + // Create replicas. + for i in 0 .. REPL_CNT { + let repl_name = format!("r_{i}"); + let repl_uuid = format!("45c23e54-dc86-45f6-b55b-e44d05f1{i:04}"); + + let lvol = lvs + .create_lvol( + &repl_name, + REPL_SIZE * 1024 * 1024, + Some(&repl_uuid), + true, + ) + .await + .unwrap(); + + created.insert(repl_name.clone()); + + // Create snapshots for each replicas. + for j in 0 .. SNAP_CNT { + let snap_name = format!("r_{i}_snap_{j}"); + let eid = format!("e_{i}_{j}"); + let txn_id = format!("t_{i}_{j}"); + let snap_uuid = + format!("55c23e54-dc89-45f6-b55b-e44d{i:04}{j:04}"); + + let snap_config = lvol + .prepare_snap_config(&snap_name, &eid, &txn_id, &snap_uuid) + .unwrap(); + + lvol.create_snapshot(snap_config).await.unwrap(); + created.insert(snap_name.clone()); + } + + println!( + "Replica #{i} {repl_name} '{repl_uuid}' \ + and its {SNAP_CNT} snapshots has been created" + ); + } + + println!( + "{REPL_CNT} replicas x {SNAP_CNT} snapshots = {t} \ + volumes have been created", + t = REPL_CNT * SNAP_CNT + ); + + // Export the LVS. + println!("Exporting ..."); + let t = Instant::now(); + lvs.export().await.unwrap(); + println!("Exported in {d} ms", d = t.elapsed().as_millis()); + + // Import the LVS. + println!("Importing ..."); + let t = Instant::now(); + let lvs = Lvs::create_or_import(lvs_args).await.unwrap(); + println!("Imported in {d} ms", d = t.elapsed().as_millis()); + + // Check that all volumes were properly imported. + let mut imported = HashSet::new(); + lvs.lvols().unwrap().for_each(|v| { + imported.insert(v.name()); + }); + + let diff = created.difference(&imported).collect::>(); + + assert!( + diff.is_empty(), + "Some volumes were not properly imported: {:?}", + diff + ); + + let diff = imported.difference(&created).collect::>(); + + assert!( + diff.is_empty(), + "Some additional volumes were wrongly imported: {:?}", + diff + ); + }) + .await; +} diff --git a/nix/pkgs/libspdk/default.nix b/nix/pkgs/libspdk/default.nix index c04d71d307..d2ec52393b 100644 --- a/nix/pkgs/libspdk/default.nix +++ b/nix/pkgs/libspdk/default.nix @@ -56,13 +56,13 @@ let # 7. Copy SHA256 from 'got' of the error message to 'sha256' field. # 8. 'nix-shell' build must now succeed. drvAttrs = rec { - version = "23.05-817317b"; + version = "23.05-a369379"; src = fetchFromGitHub { owner = "openebs"; repo = "spdk"; - rev = "817317bb7e7681d90cc60a2e54a98e74f06fe8d4"; - sha256 = "sha256-cEul0oWNRr9LwCUTnlGXFEoIYSeUIv3KoXhI1cR8sh8="; + rev = "a369379d2520b1b42cac2694b2e0a0c4e11664be"; + sha256 = "sha256-dR+4e/wNbU5K1iR9SUkggCD0NumTfLiD/cZ9VIHy1Wo="; fetchSubmodules = true; };