@@ -20,7 +20,10 @@ use url::Url;
20
20
use super :: { BsError , ImportErrorReason , Lvol , LvsError , LvsIter , PropName , PropValue } ;
21
21
22
22
use crate :: {
23
- bdev:: { uri, PtplFileOps } ,
23
+ bdev:: {
24
+ crypto:: { create_crypto_vbdev_on_base_bdev, destroy_crypto_vbdev} ,
25
+ uri, PtplFileOps ,
26
+ } ,
24
27
bdev_api:: { bdev_destroy, BdevError } ,
25
28
core:: {
26
29
logical_volume:: LogicalVolume , snapshot:: LvolSnapshotOps , Bdev , IoType , NvmfShareProps ,
@@ -310,11 +313,19 @@ impl Lvs {
310
313
name : args. name . clone ( ) ,
311
314
} ) ?;
312
315
316
+ // If we are requesting for an encypted pool, then we should match existing pool(if any)
317
+ // by pool's bdev name as crypto bdev name.
318
+ let pool_bdev_name = if let Some ( c) = args. crypto_vbdev_name . as_ref ( ) {
319
+ c
320
+ } else {
321
+ & parsed. get_name ( )
322
+ } ;
323
+
313
324
// At any point two pools with the same name should
314
325
// not exists so returning error
315
326
if let Some ( pool) = Self :: lookup ( & args. name ) {
316
327
let pool_name = pool. base_bdev ( ) . name ( ) . to_string ( ) ;
317
- return if pool_name. as_str ( ) == parsed . get_name ( ) {
328
+ return if pool_name. as_str ( ) == pool_bdev_name {
318
329
Err ( LvsError :: Import {
319
330
source : BsError :: VolAlreadyExists { } ,
320
331
name : args. name . clone ( ) ,
@@ -347,7 +358,30 @@ impl Lvs {
347
358
Ok ( name) => Ok ( name) ,
348
359
} ?;
349
360
350
- let pool = Self :: import ( & args. name , & bdev) . await ?;
361
+ if let Some ( ref cname) = args. crypto_vbdev_name {
362
+ // Only if bdev doesn't exist. e.g. direct import path.
363
+ if UntypedBdev :: lookup_by_name ( cname) . is_none ( ) {
364
+ if let Some ( e) = args. enc_key {
365
+ match create_crypto_vbdev_on_base_bdev ( cname, & bdev, & e) {
366
+ Ok ( _) => { }
367
+ Err ( _) => {
368
+ let _ = parsed. destroy ( ) . await . map_err ( |_e| {
369
+ error ! (
370
+ "failed to delete base_bdev {bdev} after failed crypto vbdev creation"
371
+ ) ;
372
+ } ) ;
373
+ return Err ( LvsError :: PoolCreate {
374
+ source : BsError :: LvsCryptoVbdev { } ,
375
+ name : args. name . clone ( ) ,
376
+ } ) ;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ }
382
+
383
+ let bsdev_name = args. crypto_vbdev_name . as_ref ( ) . unwrap_or ( & bdev) ;
384
+ let pool = Self :: import ( & args. name , bsdev_name) . await ?;
351
385
// Try to destroy the pending snapshots without catching
352
386
// the error.
353
387
Lvol :: destroy_pending_discarded_snapshot ( ) . await ;
@@ -394,7 +428,11 @@ impl Lvs {
394
428
let bdev = args. disks [ 0 ] . clone ( ) ;
395
429
396
430
let pool_name = args. name . clone ( ) . into_cstring ( ) ;
397
- let bdev_name = bdev. into_cstring ( ) ;
431
+ let bdev_name = if let Some ( ref c) = args. crypto_vbdev_name {
432
+ c. clone ( ) . into_cstring ( )
433
+ } else {
434
+ bdev. into_cstring ( )
435
+ } ;
398
436
399
437
let cluster_size = if let Some ( cluster_size) = args. cluster_size {
400
438
if cluster_size % ROUND_TO_MB == 0 {
@@ -490,17 +528,31 @@ impl Lvs {
490
528
let disk = Self :: parse_disk ( args. disks . clone ( ) ) ?;
491
529
492
530
info ! (
493
- "Creating or importing lvs '{}' from '{}'..." ,
494
- args. name, disk
531
+ "Creating or importing {enc} lvs '{}' from '{}'..." ,
532
+ args. name,
533
+ disk,
534
+ enc = if args. crypto_vbdev_name. is_some( ) {
535
+ "encrypted"
536
+ } else {
537
+ "non-encrypted"
538
+ }
495
539
) ;
496
540
497
541
let bdev_ops = uri:: parse ( & disk) . map_err ( |e| LvsError :: InvalidBdev {
498
542
source : e,
499
543
name : args. name . clone ( ) ,
500
544
} ) ?;
501
545
546
+ // If we are requesting for an encypted pool, then we should lookup existing pool(if any)
547
+ // by pool's bdev name as crypto bdev name.
548
+ let pool_bdev_name = if let Some ( c) = args. crypto_vbdev_name . as_ref ( ) {
549
+ c
550
+ } else {
551
+ & bdev_ops. get_name ( )
552
+ } ;
553
+
502
554
if let Some ( pool) = Self :: lookup ( & args. name ) {
503
- return if pool. base_bdev ( ) . name ( ) == bdev_ops . get_name ( ) {
555
+ return if pool. base_bdev ( ) . name ( ) == pool_bdev_name {
504
556
Err ( LvsError :: PoolCreate {
505
557
source : BsError :: VolAlreadyExists { } ,
506
558
name : args. name . clone ( ) ,
@@ -512,7 +564,6 @@ impl Lvs {
512
564
} )
513
565
} ;
514
566
}
515
-
516
567
// Create the underlying ndev.
517
568
let bdev_name = match bdev_ops. create ( ) . await {
518
569
Err ( e) => match e {
@@ -532,20 +583,50 @@ impl Lvs {
532
583
Ok ( name) => Ok ( name) ,
533
584
} ?;
534
585
586
+ // Create crypto bdev now if required.
587
+ if let Some ( ref cname) = args. crypto_vbdev_name {
588
+ if let Some ( ref e) = args. enc_key {
589
+ match create_crypto_vbdev_on_base_bdev ( cname, & bdev_name, e) {
590
+ Ok ( _) => { }
591
+ Err ( _) => {
592
+ let _ = bdev_ops. destroy ( ) . await . map_err ( |_e| {
593
+ error ! (
594
+ "failed to delete base_bdev {bdev_name} after failed crypto vbdev creation"
595
+ ) ;
596
+ } ) ;
597
+ return Err ( LvsError :: PoolCreate {
598
+ source : BsError :: LvsCryptoVbdev { } ,
599
+ name : args. name . clone ( ) ,
600
+ } ) ;
601
+ }
602
+ }
603
+ }
604
+ }
605
+
535
606
match Self :: import_from_args ( args. clone ( ) ) . await {
536
607
Ok ( pool) => Ok ( pool) ,
537
608
// try to create the pool
538
609
Err ( LvsError :: Import {
539
610
source : BsError :: CannotImportLvs { } ,
540
611
..
541
612
} ) => {
613
+ let cbdev_name: Option < String > = args. crypto_vbdev_name . clone ( ) ;
542
614
match Self :: create_from_args_inner ( PoolArgs {
543
615
disks : vec ! [ bdev_name. clone( ) ] ,
544
616
..args
545
617
} )
546
618
. await
547
619
{
548
620
Err ( create) => {
621
+ // destroy crypto vbdev first.
622
+ if let Some ( c) = cbdev_name. as_ref ( ) {
623
+ let _ = destroy_crypto_vbdev ( c. clone ( ) ) . await . map_err ( |_e| {
624
+ error ! (
625
+ "failed to delete crypto vbdev {c} after failed pool creation"
626
+ ) ;
627
+ } ) ;
628
+ }
629
+
549
630
let _ = bdev_ops. destroy ( ) . await . map_err ( |_e| {
550
631
// we failed to delete the base_bdev be loud about it
551
632
// there is not much we can do about it here, likely
@@ -658,7 +739,7 @@ impl Lvs {
658
739
// when destroying a pool unshare all volumes
659
740
self . unshare_all ( ) . await ;
660
741
661
- let base_bdev = self . base_bdev ( ) ;
742
+ let mut base_bdev = self . base_bdev ( ) ;
662
743
663
744
let evt = self . event ( EventAction :: Delete ) ;
664
745
@@ -671,16 +752,42 @@ impl Lvs {
671
752
name : pool. clone ( ) ,
672
753
} ) ?;
673
754
674
- info ! ( "{}: lvs destroyed successfully" , self_str) ;
755
+ info ! (
756
+ "{}: lvs destroyed successfully. base_bdev: {base_bdev:?}" ,
757
+ self_str
758
+ ) ;
675
759
676
760
evt. generate ( ) ;
677
761
678
- bdev_destroy ( & base_bdev. bdev_uri_original_str ( ) . unwrap ( ) )
679
- . await
680
- . map_err ( |e| LvsError :: Destroy {
762
+ // If the base_bdev is a crypto vbdev then we need to destroy both - the crypto vbdev and it's base.
763
+ if base_bdev. driver ( ) == "crypto" {
764
+ let cbdev = base_bdev. crypto_base_bdev ( ) ;
765
+
766
+ let _ = destroy_crypto_vbdev ( base_bdev. name ( ) . to_string ( ) )
767
+ . await
768
+ . map_err ( |e| LvsError :: Destroy {
769
+ source : e,
770
+ name : self_str. clone ( ) ,
771
+ } ) ;
772
+
773
+ // A None cbdev here is highly unlikely as the vbdev can't exist in thin air.
774
+ // If cbdev is somehow None anyway, then the following bdev_destroy will likely
775
+ // fail, and we can let it.
776
+ if let Some ( c) = cbdev {
777
+ base_bdev = Bdev :: new ( c) ;
778
+ }
779
+ }
780
+ trace ! (
781
+ "Deleting bdev {}, uri {:?}" ,
782
+ base_bdev. name( ) ,
783
+ base_bdev. bdev_uri_original_str( )
784
+ ) ;
785
+ if let Some ( u) = base_bdev. bdev_uri_original_str ( ) {
786
+ bdev_destroy ( & u) . await . map_err ( |e| LvsError :: Destroy {
681
787
source : e,
682
788
name : base_bdev. name ( ) . to_string ( ) ,
683
789
} ) ?;
790
+ }
684
791
685
792
if let Err ( error) = ptpl. destroy ( ) {
686
793
tracing:: error!(
0 commit comments