-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(nexus): mayastor hangs when creating a nexus if there is an error…
… creating a child When creating a new nexus, as a final step, the newly created nexus is added to a global list of nexus instances. This list is required when handling bdev removal - specifically it is used by lookup_child_from_bdev() to determine the nexus child that is associated with a given bdev. The problem occurs when there is an error creating a nexus, and proper cleanup necessitates the removal of some children that may have already been successfully created. The removal code requires the owning nexus to be present in the global list in order to successfully remove the children, but the nexus has not yet been added to the list, as it has not been successfully created. The solution is to add the (partially created) nexus to the list of global instances as early as possible in the creation process. This means that we also need to ensure that it is removed again if any error is encountered. resolves CAS-757
- Loading branch information
1 parent
d9cebab
commit b250a6d
Showing
4 changed files
with
147 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use tracing::error; | ||
|
||
use once_cell::sync::OnceCell; | ||
|
||
use common::MayastorTest; | ||
use mayastor::{ | ||
bdev::{nexus_create, nexus_lookup}, | ||
core::{Bdev, MayastorCliArgs}, | ||
}; | ||
|
||
pub mod common; | ||
|
||
async fn create_nexus(size: u64) -> bool { | ||
let children = vec![ | ||
String::from("malloc:///m0?size_mb=32"), | ||
format!("malloc:///m1?size_mb={}", size), | ||
]; | ||
if let Err(error) = | ||
nexus_create("core_nexus", size * 1024 * 1024, None, &children).await | ||
{ | ||
error!("nexus_create() failed: {}", error); | ||
return false; | ||
} | ||
true | ||
} | ||
|
||
static MS: OnceCell<MayastorTest> = OnceCell::new(); | ||
|
||
fn mayastor() -> &'static MayastorTest<'static> { | ||
let ms = MS.get_or_init(|| MayastorTest::new(MayastorCliArgs::default())); | ||
&ms | ||
} | ||
|
||
#[tokio::test] | ||
async fn child_size_ok() { | ||
mayastor() | ||
.spawn(async { | ||
assert_eq!(Bdev::bdev_first().into_iter().count(), 0); | ||
assert!(create_nexus(16).await); | ||
|
||
let bdev = Bdev::lookup_by_name("core_nexus").unwrap(); | ||
assert_eq!(bdev.name(), "core_nexus"); | ||
|
||
let bdev = | ||
Bdev::lookup_by_name("m0").expect("child bdev m0 not found"); | ||
assert_eq!(bdev.name(), "m0"); | ||
|
||
let bdev = | ||
Bdev::lookup_by_name("m1").expect("child bdev m1 not found"); | ||
assert_eq!(bdev.name(), "m1"); | ||
|
||
let nexus = nexus_lookup("core_nexus").expect("nexus not found"); | ||
nexus.destroy().await.unwrap(); | ||
|
||
assert!(nexus_lookup("core_nexus").is_none()); | ||
assert!(Bdev::lookup_by_name("core_nexus").is_none()); | ||
assert!(Bdev::lookup_by_name("m0").is_none()); | ||
assert!(Bdev::lookup_by_name("m1").is_none()); | ||
assert_eq!(Bdev::bdev_first().into_iter().count(), 0); | ||
}) | ||
.await; | ||
} | ||
|
||
#[tokio::test] | ||
async fn child_too_small() { | ||
mayastor() | ||
.spawn(async { | ||
assert_eq!(Bdev::bdev_first().into_iter().count(), 0); | ||
assert!(!create_nexus(4).await); | ||
|
||
assert!(nexus_lookup("core_nexus").is_none()); | ||
assert!(Bdev::lookup_by_name("core_nexus").is_none()); | ||
assert!(Bdev::lookup_by_name("m0").is_none()); | ||
assert!(Bdev::lookup_by_name("m1").is_none()); | ||
assert_eq!(Bdev::bdev_first().into_iter().count(), 0); | ||
}) | ||
.await; | ||
} |