Skip to content

Commit daa1ab2

Browse files
mayastor-borsdsharma-dc
mayastor-bors
andcommitted
Merge #1827
1827: request encrypted pool crypto vbdev r=dsharma-dc a=dsharma-dc Given encryption related args available from create pool request, this creates a crypto vbdev based on the incoming parameters, and then requests the lvolstore creation on that crypto vbdev. Co-authored-by: Diwakar Sharma <diwakar.sharma@datacore.com>
2 parents 1b69c0b + 530851c commit daa1ab2

File tree

4 files changed

+138
-18
lines changed

4 files changed

+138
-18
lines changed

io-engine/src/bin/io-engine-client/v1/pool_cli.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ pub fn subcommands() -> Command {
130130
.short('e')
131131
.long("xts-key")
132132
.help("encryption key2 required for AES_XTS")
133-
.required_if_eq("cipher", "AES_XTS"),
133+
.required_if_eq("cipher", "AES_XTS")
134+
.required(false),
134135
);
135136

136137
let destroy = Command::new("destroy")

io-engine/src/lvs/lvs_error.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ pub enum BsError {
4949
OutOfMetadata {},
5050
#[snafu(display(": capacity overflow"))]
5151
CapacityOverflow {},
52-
#[snafu(display(": crypto vbdev error"))]
53-
LvsCryptoVbdev {},
52+
#[snafu(display(": crypto vbdev error. {source:?}"))]
53+
LvsCryptoVbdev { source: Errno },
5454
}
5555

5656
impl BsError {
@@ -103,7 +103,7 @@ impl ToErrno for BsError {
103103
Self::NoSpace {} => Errno::ENOSPC,
104104
Self::OutOfMetadata {} => Errno::EMFILE,
105105
Self::CapacityOverflow {} => Errno::EOVERFLOW,
106-
Self::LvsCryptoVbdev {} => Errno::EINVAL,
106+
Self::LvsCryptoVbdev { source } => source,
107107
}
108108
}
109109
}

io-engine/src/lvs/lvs_store.rs

+132-13
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ use url::Url;
2020
use super::{BsError, ImportErrorReason, Lvol, LvsError, LvsIter, PropName, PropValue};
2121

2222
use crate::{
23-
bdev::{uri, PtplFileOps},
23+
bdev::{
24+
crypto::{create_crypto_vbdev_on_base_bdev, destroy_crypto_vbdev},
25+
uri, PtplFileOps,
26+
},
2427
bdev_api::{bdev_destroy, BdevError},
2528
core::{
2629
logical_volume::LogicalVolume, snapshot::LvolSnapshotOps, Bdev, IoType, NvmfShareProps,
@@ -316,11 +319,19 @@ impl Lvs {
316319
name: args.name.clone(),
317320
})?;
318321

322+
// If we are requesting for an encrypted pool, then we should match existing pool(if any)
323+
// by pool's bdev name as crypto bdev name.
324+
let pool_bdev_name = if let Some(c) = args.crypto_vbdev_name.as_ref() {
325+
c
326+
} else {
327+
&parsed.get_name()
328+
};
329+
319330
// At any point two pools with the same name should
320331
// not exists so returning error
321332
if let Some(pool) = Self::lookup(&args.name) {
322333
let pool_name = pool.base_bdev().name().to_string();
323-
return if pool_name.as_str() == parsed.get_name() {
334+
return if pool_name.as_str() == pool_bdev_name {
324335
Err(LvsError::Import {
325336
source: BsError::VolAlreadyExists {},
326337
name: args.name.clone(),
@@ -353,7 +364,35 @@ impl Lvs {
353364
Ok(name) => Ok(name),
354365
}?;
355366

356-
let pool = Self::import(&args.name, &bdev).await?;
367+
if let Some(ref cname) = args.crypto_vbdev_name {
368+
// Only if bdev doesn't exist. e.g. direct import path.
369+
if UntypedBdev::lookup_by_name(cname).is_none() {
370+
if let Some(e) = args.enc_key {
371+
match create_crypto_vbdev_on_base_bdev(cname, &bdev, &e) {
372+
Ok(_) => {}
373+
Err(berr) => {
374+
let _ = parsed.destroy().await.map_err(|e| {
375+
error!(
376+
"failed to delete base_bdev {bdev} after failed crypto vbdev creation. {e:?}"
377+
);
378+
});
379+
return Err(LvsError::PoolCreate {
380+
source: BsError::LvsCryptoVbdev {
381+
source: match berr {
382+
BdevError::CreateBdevFailed { source, .. } => source,
383+
_ => Errno::EINVAL,
384+
},
385+
},
386+
name: args.name.clone(),
387+
});
388+
}
389+
}
390+
}
391+
}
392+
}
393+
394+
let bsdev_name = args.crypto_vbdev_name.as_ref().unwrap_or(&bdev);
395+
let pool = Self::import(&args.name, bsdev_name).await?;
357396
// Try to destroy the pending snapshots without catching
358397
// the error.
359398
Lvol::destroy_pending_discarded_snapshot().await;
@@ -400,7 +439,11 @@ impl Lvs {
400439
let bdev = args.disks[0].clone();
401440

402441
let pool_name = args.name.clone().into_cstring();
403-
let bdev_name = bdev.into_cstring();
442+
let bdev_name = if let Some(ref c) = args.crypto_vbdev_name {
443+
c.clone().into_cstring()
444+
} else {
445+
bdev.into_cstring()
446+
};
404447

405448
let cluster_size = if let Some(cluster_size) = args.cluster_size {
406449
if cluster_size % ROUND_TO_MB == 0 {
@@ -496,17 +539,31 @@ impl Lvs {
496539
let disk = Self::parse_disk(args.disks.clone())?;
497540

498541
info!(
499-
"Creating or importing lvs '{}' from '{}'...",
500-
args.name, disk
542+
"Creating or importing {enc} lvs '{}' from '{}'...",
543+
args.name,
544+
disk,
545+
enc = if args.crypto_vbdev_name.is_some() {
546+
"encrypted"
547+
} else {
548+
"non-encrypted"
549+
}
501550
);
502551

503552
let bdev_ops = uri::parse(&disk).map_err(|e| LvsError::InvalidBdev {
504553
source: e,
505554
name: args.name.clone(),
506555
})?;
507556

557+
// If we are requesting for an encrypted pool, then we should lookup existing pool(if any)
558+
// by pool's bdev name as crypto bdev name.
559+
let pool_bdev_name = if let Some(c) = args.crypto_vbdev_name.as_ref() {
560+
c
561+
} else {
562+
&bdev_ops.get_name()
563+
};
564+
508565
if let Some(pool) = Self::lookup(&args.name) {
509-
return if pool.base_bdev().name() == bdev_ops.get_name() {
566+
return if pool.base_bdev().name() == pool_bdev_name {
510567
Err(LvsError::PoolCreate {
511568
source: BsError::VolAlreadyExists {},
512569
name: args.name.clone(),
@@ -518,7 +575,6 @@ impl Lvs {
518575
})
519576
};
520577
}
521-
522578
// Create the underlying ndev.
523579
let bdev_name = match bdev_ops.create().await {
524580
Err(e) => match e {
@@ -538,20 +594,55 @@ impl Lvs {
538594
Ok(name) => Ok(name),
539595
}?;
540596

597+
// Create crypto bdev now if required.
598+
if let Some(ref cname) = args.crypto_vbdev_name {
599+
if let Some(ref e) = args.enc_key {
600+
match create_crypto_vbdev_on_base_bdev(cname, &bdev_name, e) {
601+
Ok(_) => {}
602+
Err(berr) => {
603+
let _ = bdev_ops.destroy().await.map_err(|e| {
604+
error!(
605+
"failed to delete base_bdev {bdev_name} after failed crypto vbdev creation. {e:?}"
606+
);
607+
});
608+
return Err(LvsError::PoolCreate {
609+
source: BsError::LvsCryptoVbdev {
610+
source: match berr {
611+
BdevError::CreateBdevFailed { source, .. } => source,
612+
_ => Errno::EINVAL,
613+
},
614+
},
615+
name: args.name.clone(),
616+
});
617+
}
618+
}
619+
}
620+
}
621+
541622
match Self::import_from_args(args.clone()).await {
542623
Ok(pool) => Ok(pool),
543624
// try to create the pool
544625
Err(LvsError::Import {
545626
source: BsError::CannotImportLvs {},
546627
..
547628
}) => {
629+
let cbdev_name: Option<String> = args.crypto_vbdev_name.clone();
548630
match Self::create_from_args_inner(PoolArgs {
549631
disks: vec![bdev_name.clone()],
550632
..args
551633
})
552634
.await
553635
{
554636
Err(create) => {
637+
// destroy crypto vbdev first.
638+
if let Some(c) = cbdev_name.as_ref() {
639+
let _ = destroy_crypto_vbdev(c.clone()).await.map_err(|e| {
640+
error!(
641+
"failed to delete crypto vbdev {c} after failed pool creation. {e}"
642+
);
643+
});
644+
}
645+
555646
let _ = bdev_ops.destroy().await.map_err(|_e| {
556647
// we failed to delete the base_bdev be loud about it
557648
// there is not much we can do about it here, likely
@@ -664,7 +755,7 @@ impl Lvs {
664755
// when destroying a pool unshare all volumes
665756
self.unshare_all().await;
666757

667-
let base_bdev = self.base_bdev();
758+
let mut base_bdev = self.base_bdev();
668759

669760
let evt = self.event(EventAction::Delete);
670761

@@ -677,16 +768,44 @@ impl Lvs {
677768
name: pool.clone(),
678769
})?;
679770

680-
info!("{}: lvs destroyed successfully", self_str);
771+
info!(
772+
"{}: lvs destroyed successfully. base_bdev: {base_bdev:?}",
773+
self_str
774+
);
681775

682776
evt.generate();
683777

684-
bdev_destroy(&base_bdev.bdev_uri_original_str().unwrap())
685-
.await
686-
.map_err(|e| LvsError::Destroy {
778+
// If the base_bdev is a crypto vbdev then we need to destroy both - the crypto vbdev and it's base.
779+
if base_bdev.driver() == "crypto" {
780+
let cbdev = base_bdev.crypto_base_bdev();
781+
782+
let _ = destroy_crypto_vbdev(base_bdev.name().to_string())
783+
.await
784+
.map_err(|e| {
785+
error!(
786+
"failed to delete crypto vbdev {:?} after failed pool creation. {e}",
787+
base_bdev.name()
788+
);
789+
});
790+
791+
// A None cbdev here is highly unlikely as the vbdev can't exist in thin air.
792+
// If cbdev is somehow None anyway, then the following bdev_destroy will likely
793+
// fail, and we can let it.
794+
if let Some(c) = cbdev {
795+
base_bdev = Bdev::new(c);
796+
}
797+
}
798+
trace!(
799+
"Deleting bdev {}, uri {:?}",
800+
base_bdev.name(),
801+
base_bdev.bdev_uri_original_str()
802+
);
803+
if let Some(u) = base_bdev.bdev_uri_original_str() {
804+
bdev_destroy(&u).await.map_err(|e| LvsError::Destroy {
687805
source: e,
688806
name: base_bdev.name().to_string(),
689807
})?;
808+
}
690809

691810
if let Err(error) = ptpl.destroy() {
692811
tracing::error!(

io-engine/src/subsys/config/pool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ struct Pool {
159159
#[serde(skip_serializing)]
160160
replicas: Option<Vec<Replica>>,
161161
backend: PoolBackend,
162-
/// Is the pool enrypted.
162+
/// Is the pool encrypted.
163163
encrypted: bool,
164164
}
165165

0 commit comments

Comments
 (0)